aboutsummaryrefslogtreecommitdiffstats
path: root/fdk-aac
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2019-11-11 11:38:02 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2019-11-11 11:38:02 +0100
commit0e5af65c467b2423a0b857ae3ad98c91acc1e190 (patch)
treed07f69550d8886271e44fe79c4dcfb299cafbd38 /fdk-aac
parentefe406d9724f959c8bc2a31802559ca6d41fd897 (diff)
downloadODR-AudioEnc-0e5af65c467b2423a0b857ae3ad98c91acc1e190.tar.gz
ODR-AudioEnc-0e5af65c467b2423a0b857ae3ad98c91acc1e190.tar.bz2
ODR-AudioEnc-0e5af65c467b2423a0b857ae3ad98c91acc1e190.zip
Include patched FDK-AAC in the repository
The initial idea was to get the DAB+ patch into upstream, but since that follows the android source releases, there is no place for a custom DAB+ patch there. So instead of having to maintain a patched fdk-aac that has to have the same .so version as the distribution package on which it is installed, we prefer having a separate fdk-aac-dab library to avoid collision. At that point, there's no reason to keep fdk-aac in a separate repository, as odr-audioenc is the only tool that needs DAB+ encoding support. Including it here simplifies installation, and makes it consistent with toolame-dab, also shipped in this repository. DAB+ decoding support (needed by ODR-SourceCompanion, dablin, etisnoop, welle.io and others) can be done using upstream FDK-AAC.
Diffstat (limited to 'fdk-aac')
-rw-r--r--fdk-aac/.clang-format4
-rw-r--r--fdk-aac/.gitignore29
-rw-r--r--fdk-aac/Android.bp53
-rw-r--r--fdk-aac/ChangeLog48
-rw-r--r--fdk-aac/MODULE_LICENSE_FRAUNHOFER0
-rw-r--r--fdk-aac/Makefile.am297
-rw-r--r--fdk-aac/Makefile.vc321
-rw-r--r--fdk-aac/NOTICE92
-rw-r--r--fdk-aac/OWNERS2
-rw-r--r--fdk-aac/README.md7
-rw-r--r--fdk-aac/aac-enc.c237
-rwxr-xr-xfdk-aac/autogen.sh2
-rwxr-xr-xfdk-aac/bootstrap4
-rw-r--r--fdk-aac/configure.ac38
-rw-r--r--fdk-aac/documentation/aacDecoder.pdfbin0 -> 500827 bytes
-rw-r--r--fdk-aac/documentation/aacEncoder.pdfbin0 -> 461225 bytes
-rw-r--r--fdk-aac/fdk-aac.pc.in11
-rw-r--r--fdk-aac/fdk-aac.sym18
-rw-r--r--fdk-aac/libAACdec/include/aacdecoder_lib.h1090
-rw-r--r--fdk-aac/libAACdec/src/FDK_delay.cpp173
-rw-r--r--fdk-aac/libAACdec/src/FDK_delay.h152
-rw-r--r--fdk-aac/libAACdec/src/aac_ram.cpp185
-rw-r--r--fdk-aac/libAACdec/src/aac_ram.h147
-rw-r--r--fdk-aac/libAACdec/src/aac_rom.cpp3428
-rw-r--r--fdk-aac/libAACdec/src/aac_rom.h237
-rw-r--r--fdk-aac/libAACdec/src/aacdec_drc.cpp1355
-rw-r--r--fdk-aac/libAACdec/src/aacdec_drc.h192
-rw-r--r--fdk-aac/libAACdec/src/aacdec_drc_types.h220
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcr.cpp1498
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcr.h128
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcr_bit.cpp164
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcr_bit.h114
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcr_types.h432
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcrs.cpp1551
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcrs.h176
-rw-r--r--fdk-aac/libAACdec/src/aacdec_pns.cpp361
-rw-r--r--fdk-aac/libAACdec/src/aacdec_pns.h129
-rw-r--r--fdk-aac/libAACdec/src/aacdec_tns.cpp361
-rw-r--r--fdk-aac/libAACdec/src/aacdec_tns.h149
-rw-r--r--fdk-aac/libAACdec/src/aacdecoder.cpp3464
-rw-r--r--fdk-aac/libAACdec/src/aacdecoder.h465
-rw-r--r--fdk-aac/libAACdec/src/aacdecoder_lib.cpp2035
-rw-r--r--fdk-aac/libAACdec/src/arm/block_arm.cpp142
-rw-r--r--fdk-aac/libAACdec/src/block.cpp1260
-rw-r--r--fdk-aac/libAACdec/src/block.h345
-rw-r--r--fdk-aac/libAACdec/src/channel.cpp924
-rw-r--r--fdk-aac/libAACdec/src/channel.h160
-rw-r--r--fdk-aac/libAACdec/src/channelinfo.cpp297
-rw-r--r--fdk-aac/libAACdec/src/channelinfo.h564
-rw-r--r--fdk-aac/libAACdec/src/conceal.cpp2095
-rw-r--r--fdk-aac/libAACdec/src/conceal.h152
-rw-r--r--fdk-aac/libAACdec/src/conceal_types.h203
-rw-r--r--fdk-aac/libAACdec/src/ldfiltbank.cpp276
-rw-r--r--fdk-aac/libAACdec/src/ldfiltbank.h112
-rw-r--r--fdk-aac/libAACdec/src/overlapadd.h120
-rw-r--r--fdk-aac/libAACdec/src/pulsedata.cpp164
-rw-r--r--fdk-aac/libAACdec/src/pulsedata.h150
-rw-r--r--fdk-aac/libAACdec/src/rvlc.cpp1217
-rw-r--r--fdk-aac/libAACdec/src/rvlc.h153
-rw-r--r--fdk-aac/libAACdec/src/rvlc_info.h204
-rw-r--r--fdk-aac/libAACdec/src/rvlcbit.cpp148
-rw-r--r--fdk-aac/libAACdec/src/rvlcbit.h111
-rw-r--r--fdk-aac/libAACdec/src/rvlcconceal.cpp787
-rw-r--r--fdk-aac/libAACdec/src/rvlcconceal.h127
-rw-r--r--fdk-aac/libAACdec/src/stereo.cpp1250
-rw-r--r--fdk-aac/libAACdec/src/stereo.h211
-rw-r--r--fdk-aac/libAACdec/src/usacdec_ace_d4t64.cpp439
-rw-r--r--fdk-aac/libAACdec/src/usacdec_ace_d4t64.h117
-rw-r--r--fdk-aac/libAACdec/src/usacdec_ace_ltp.cpp229
-rw-r--r--fdk-aac/libAACdec/src/usacdec_ace_ltp.h128
-rw-r--r--fdk-aac/libAACdec/src/usacdec_acelp.cpp1296
-rw-r--r--fdk-aac/libAACdec/src/usacdec_acelp.h281
-rw-r--r--fdk-aac/libAACdec/src/usacdec_const.h203
-rw-r--r--fdk-aac/libAACdec/src/usacdec_fac.cpp745
-rw-r--r--fdk-aac/libAACdec/src/usacdec_fac.h191
-rw-r--r--fdk-aac/libAACdec/src/usacdec_lpc.cpp1194
-rw-r--r--fdk-aac/libAACdec/src/usacdec_lpc.h190
-rw-r--r--fdk-aac/libAACdec/src/usacdec_lpd.cpp2029
-rw-r--r--fdk-aac/libAACdec/src/usacdec_lpd.h198
-rw-r--r--fdk-aac/libAACdec/src/usacdec_rom.cpp1504
-rw-r--r--fdk-aac/libAACdec/src/usacdec_rom.h154
-rw-r--r--fdk-aac/libAACenc/include/aacenc_lib.h1733
-rw-r--r--fdk-aac/libAACenc/src/aacEnc_ram.cpp208
-rw-r--r--fdk-aac/libAACenc/src/aacEnc_ram.h249
-rw-r--r--fdk-aac/libAACenc/src/aacEnc_rom.cpp2486
-rw-r--r--fdk-aac/libAACenc/src/aacEnc_rom.h217
-rw-r--r--fdk-aac/libAACenc/src/aacenc.cpp1057
-rw-r--r--fdk-aac/libAACenc/src/aacenc.h394
-rw-r--r--fdk-aac/libAACenc/src/aacenc_lib.cpp2575
-rw-r--r--fdk-aac/libAACenc/src/aacenc_pns.cpp541
-rw-r--r--fdk-aac/libAACenc/src/aacenc_pns.h124
-rw-r--r--fdk-aac/libAACenc/src/aacenc_tns.cpp1210
-rw-r--r--fdk-aac/libAACenc/src/aacenc_tns.h213
-rw-r--r--fdk-aac/libAACenc/src/adj_thr.cpp2924
-rw-r--r--fdk-aac/libAACenc/src/adj_thr.h166
-rw-r--r--fdk-aac/libAACenc/src/adj_thr_data.h175
-rw-r--r--fdk-aac/libAACenc/src/band_nrg.cpp361
-rw-r--r--fdk-aac/libAACenc/src/band_nrg.h142
-rw-r--r--fdk-aac/libAACenc/src/bandwidth.cpp360
-rw-r--r--fdk-aac/libAACenc/src/bandwidth.h114
-rw-r--r--fdk-aac/libAACenc/src/bit_cnt.cpp950
-rw-r--r--fdk-aac/libAACenc/src/bit_cnt.h200
-rw-r--r--fdk-aac/libAACenc/src/bitenc.cpp1362
-rw-r--r--fdk-aac/libAACenc/src/bitenc.h184
-rw-r--r--fdk-aac/libAACenc/src/block_switch.cpp582
-rw-r--r--fdk-aac/libAACenc/src/block_switch.h162
-rw-r--r--fdk-aac/libAACenc/src/channel_map.cpp664
-rw-r--r--fdk-aac/libAACenc/src/channel_map.h136
-rw-r--r--fdk-aac/libAACenc/src/chaosmeasure.cpp191
-rw-r--r--fdk-aac/libAACenc/src/chaosmeasure.h112
-rw-r--r--fdk-aac/libAACenc/src/dyn_bits.cpp665
-rw-r--r--fdk-aac/libAACenc/src/dyn_bits.h160
-rw-r--r--fdk-aac/libAACenc/src/grp_data.cpp264
-rw-r--r--fdk-aac/libAACenc/src/grp_data.h123
-rw-r--r--fdk-aac/libAACenc/src/intensity.cpp810
-rw-r--r--fdk-aac/libAACenc/src/intensity.h121
-rw-r--r--fdk-aac/libAACenc/src/interface.h168
-rw-r--r--fdk-aac/libAACenc/src/line_pe.cpp234
-rw-r--r--fdk-aac/libAACenc/src/line_pe.h148
-rw-r--r--fdk-aac/libAACenc/src/metadata_compressor.cpp1579
-rw-r--r--fdk-aac/libAACenc/src/metadata_compressor.h255
-rw-r--r--fdk-aac/libAACenc/src/metadata_main.cpp1191
-rw-r--r--fdk-aac/libAACenc/src/metadata_main.h226
-rw-r--r--fdk-aac/libAACenc/src/mps_main.cpp529
-rw-r--r--fdk-aac/libAACenc/src/mps_main.h270
-rw-r--r--fdk-aac/libAACenc/src/ms_stereo.cpp295
-rw-r--r--fdk-aac/libAACenc/src/ms_stereo.h117
-rw-r--r--fdk-aac/libAACenc/src/noisedet.cpp235
-rw-r--r--fdk-aac/libAACenc/src/noisedet.h116
-rw-r--r--fdk-aac/libAACenc/src/pns_func.h138
-rw-r--r--fdk-aac/libAACenc/src/pnsparam.cpp574
-rw-r--r--fdk-aac/libAACenc/src/pnsparam.h149
-rw-r--r--fdk-aac/libAACenc/src/pre_echo_control.cpp176
-rw-r--r--fdk-aac/libAACenc/src/pre_echo_control.h118
-rw-r--r--fdk-aac/libAACenc/src/psy_configuration.cpp801
-rw-r--r--fdk-aac/libAACenc/src/psy_configuration.h171
-rw-r--r--fdk-aac/libAACenc/src/psy_const.h169
-rw-r--r--fdk-aac/libAACenc/src/psy_data.h169
-rw-r--r--fdk-aac/libAACenc/src/psy_main.cpp1348
-rw-r--r--fdk-aac/libAACenc/src/psy_main.h161
-rw-r--r--fdk-aac/libAACenc/src/qc_data.h299
-rw-r--r--fdk-aac/libAACenc/src/qc_main.cpp1555
-rw-r--r--fdk-aac/libAACenc/src/qc_main.h158
-rw-r--r--fdk-aac/libAACenc/src/quantize.cpp401
-rw-r--r--fdk-aac/libAACenc/src/quantize.h127
-rw-r--r--fdk-aac/libAACenc/src/sf_estim.cpp1292
-rw-r--r--fdk-aac/libAACenc/src/sf_estim.h124
-rw-r--r--fdk-aac/libAACenc/src/spreading.cpp125
-rw-r--r--fdk-aac/libAACenc/src/spreading.h113
-rw-r--r--fdk-aac/libAACenc/src/tns_func.h129
-rw-r--r--fdk-aac/libAACenc/src/tonality.cpp219
-rw-r--r--fdk-aac/libAACenc/src/tonality.h115
-rw-r--r--fdk-aac/libAACenc/src/transform.cpp294
-rw-r--r--fdk-aac/libAACenc/src/transform.h163
-rw-r--r--fdk-aac/libArithCoding/include/ac_arith_coder.h142
-rw-r--r--fdk-aac/libArithCoding/src/ac_arith_coder.cpp785
-rw-r--r--fdk-aac/libDRCdec/include/FDK_drcDecLib.h313
-rw-r--r--fdk-aac/libDRCdec/src/FDK_drcDecLib.cpp891
-rw-r--r--fdk-aac/libDRCdec/src/drcDec_gainDecoder.cpp445
-rw-r--r--fdk-aac/libDRCdec/src/drcDec_gainDecoder.h264
-rw-r--r--fdk-aac/libDRCdec/src/drcDec_reader.cpp2029
-rw-r--r--fdk-aac/libDRCdec/src/drcDec_reader.h130
-rw-r--r--fdk-aac/libDRCdec/src/drcDec_rom.cpp323
-rw-r--r--fdk-aac/libDRCdec/src/drcDec_rom.h120
-rw-r--r--fdk-aac/libDRCdec/src/drcDec_selectionProcess.cpp3099
-rw-r--r--fdk-aac/libDRCdec/src/drcDec_selectionProcess.h217
-rw-r--r--fdk-aac/libDRCdec/src/drcDec_tools.cpp371
-rw-r--r--fdk-aac/libDRCdec/src/drcDec_tools.h146
-rw-r--r--fdk-aac/libDRCdec/src/drcDec_types.h428
-rw-r--r--fdk-aac/libDRCdec/src/drcDecoder.h142
-rw-r--r--fdk-aac/libDRCdec/src/drcGainDec_init.cpp344
-rw-r--r--fdk-aac/libDRCdec/src/drcGainDec_init.h120
-rw-r--r--fdk-aac/libDRCdec/src/drcGainDec_preprocess.cpp715
-rw-r--r--fdk-aac/libDRCdec/src/drcGainDec_preprocess.h111
-rw-r--r--fdk-aac/libDRCdec/src/drcGainDec_process.cpp532
-rw-r--r--fdk-aac/libDRCdec/src/drcGainDec_process.h119
-rw-r--r--fdk-aac/libFDK/include/FDK_archdef.h270
-rw-r--r--fdk-aac/libFDK/include/FDK_bitbuffer.h177
-rw-r--r--fdk-aac/libFDK/include/FDK_bitstream.h642
-rw-r--r--fdk-aac/libFDK/include/FDK_core.h122
-rw-r--r--fdk-aac/libFDK/include/FDK_crc.h225
-rw-r--r--fdk-aac/libFDK/include/FDK_decorrelate.h314
-rw-r--r--fdk-aac/libFDK/include/FDK_hybrid.h255
-rw-r--r--fdk-aac/libFDK/include/FDK_lpc.h218
-rw-r--r--fdk-aac/libFDK/include/FDK_matrixCalloc.h230
-rw-r--r--fdk-aac/libFDK/include/FDK_qmf_domain.h416
-rw-r--r--fdk-aac/libFDK/include/FDK_tools_rom.h398
-rw-r--r--fdk-aac/libFDK/include/FDK_trigFcts.h258
-rw-r--r--fdk-aac/libFDK/include/abs.h136
-rw-r--r--fdk-aac/libFDK/include/arm/clz_arm.h164
-rw-r--r--fdk-aac/libFDK/include/arm/cplx_mul_arm.h201
-rw-r--r--fdk-aac/libFDK/include/arm/fixmadd_arm.h220
-rw-r--r--fdk-aac/libFDK/include/arm/fixmul_arm.h198
-rw-r--r--fdk-aac/libFDK/include/arm/scale_arm.h163
-rw-r--r--fdk-aac/libFDK/include/arm/scramble_arm.h174
-rw-r--r--fdk-aac/libFDK/include/autocorr2nd.h137
-rw-r--r--fdk-aac/libFDK/include/clz.h205
-rw-r--r--fdk-aac/libFDK/include/common_fix.h449
-rw-r--r--fdk-aac/libFDK/include/cplx_mul.h266
-rw-r--r--fdk-aac/libFDK/include/dct.h171
-rw-r--r--fdk-aac/libFDK/include/fft.h263
-rw-r--r--fdk-aac/libFDK/include/fft_rad2.h121
-rw-r--r--fdk-aac/libFDK/include/fixmadd.h333
-rw-r--r--fdk-aac/libFDK/include/fixminmax.h131
-rw-r--r--fdk-aac/libFDK/include/fixmul.h298
-rw-r--r--fdk-aac/libFDK/include/fixpoint_math.h921
-rw-r--r--fdk-aac/libFDK/include/huff_nodes.h258
-rw-r--r--fdk-aac/libFDK/include/mdct.h253
-rw-r--r--fdk-aac/libFDK/include/mips/abs_mips.h125
-rw-r--r--fdk-aac/libFDK/include/mips/clz_mips.h134
-rw-r--r--fdk-aac/libFDK/include/mips/cplx_mul_mips.h133
-rw-r--r--fdk-aac/libFDK/include/mips/fixmul_mips.h130
-rw-r--r--fdk-aac/libFDK/include/mips/scale_mips.h122
-rw-r--r--fdk-aac/libFDK/include/mips/scramble_mips.h133
-rw-r--r--fdk-aac/libFDK/include/nlc_dec.h187
-rw-r--r--fdk-aac/libFDK/include/ppc/clz_ppc.h102
-rw-r--r--fdk-aac/libFDK/include/ppc/fixmul_ppc.h115
-rw-r--r--fdk-aac/libFDK/include/qmf.h301
-rw-r--r--fdk-aac/libFDK/include/qmf_pcm.h405
-rw-r--r--fdk-aac/libFDK/include/scale.h298
-rw-r--r--fdk-aac/libFDK/include/scramble.h153
-rw-r--r--fdk-aac/libFDK/include/x86/abs_x86.h123
-rw-r--r--fdk-aac/libFDK/include/x86/clz_x86.h165
-rw-r--r--fdk-aac/libFDK/include/x86/fixmul_x86.h187
-rw-r--r--fdk-aac/libFDK/include/x86/fixpoint_math_x86.h208
-rw-r--r--fdk-aac/libFDK/src/FDK_bitbuffer.cpp489
-rw-r--r--fdk-aac/libFDK/src/FDK_core.cpp145
-rw-r--r--fdk-aac/libFDK/src/FDK_crc.cpp526
-rw-r--r--fdk-aac/libFDK/src/FDK_decorrelate.cpp1746
-rw-r--r--fdk-aac/libFDK/src/FDK_hybrid.cpp813
-rw-r--r--fdk-aac/libFDK/src/FDK_lpc.cpp487
-rw-r--r--fdk-aac/libFDK/src/FDK_matrixCalloc.cpp315
-rw-r--r--fdk-aac/libFDK/src/FDK_qmf_domain.cpp1018
-rw-r--r--fdk-aac/libFDK/src/FDK_tools_rom.cpp7274
-rw-r--r--fdk-aac/libFDK/src/FDK_trigFcts.cpp340
-rw-r--r--fdk-aac/libFDK/src/arm/fft_rad2_arm.cpp321
-rw-r--r--fdk-aac/libFDK/src/arm/scale_arm.cpp174
-rw-r--r--fdk-aac/libFDK/src/autocorr2nd.cpp293
-rw-r--r--fdk-aac/libFDK/src/dct.cpp568
-rw-r--r--fdk-aac/libFDK/src/fft.cpp1922
-rw-r--r--fdk-aac/libFDK/src/fft_rad2.cpp324
-rw-r--r--fdk-aac/libFDK/src/fixpoint_math.cpp900
-rw-r--r--fdk-aac/libFDK/src/huff_nodes.cpp1084
-rw-r--r--fdk-aac/libFDK/src/mdct.cpp730
-rw-r--r--fdk-aac/libFDK/src/mips/fft_rad2_mips.cpp165
-rw-r--r--fdk-aac/libFDK/src/mips/mips_fft_twiddles.cpp931
-rw-r--r--fdk-aac/libFDK/src/mips/scale_mips.cpp133
-rw-r--r--fdk-aac/libFDK/src/nlc_dec.cpp1071
-rw-r--r--fdk-aac/libFDK/src/qmf.cpp1135
-rw-r--r--fdk-aac/libFDK/src/scale.cpp720
-rw-r--r--fdk-aac/libMpegTPDec/include/tp_data.h466
-rw-r--r--fdk-aac/libMpegTPDec/include/tpdec_lib.h664
-rw-r--r--fdk-aac/libMpegTPDec/src/tp_version.h118
-rw-r--r--fdk-aac/libMpegTPDec/src/tpdec_adif.cpp158
-rw-r--r--fdk-aac/libMpegTPDec/src/tpdec_adif.h134
-rw-r--r--fdk-aac/libMpegTPDec/src/tpdec_adts.cpp392
-rw-r--r--fdk-aac/libMpegTPDec/src/tpdec_adts.h234
-rw-r--r--fdk-aac/libMpegTPDec/src/tpdec_asc.cpp2592
-rw-r--r--fdk-aac/libMpegTPDec/src/tpdec_drm.cpp148
-rw-r--r--fdk-aac/libMpegTPDec/src/tpdec_drm.h202
-rw-r--r--fdk-aac/libMpegTPDec/src/tpdec_latm.cpp676
-rw-r--r--fdk-aac/libMpegTPDec/src/tpdec_latm.h191
-rw-r--r--fdk-aac/libMpegTPDec/src/tpdec_lib.cpp1820
-rw-r--r--fdk-aac/libMpegTPEnc/include/tp_data.h466
-rw-r--r--fdk-aac/libMpegTPEnc/include/tpenc_lib.h339
-rw-r--r--fdk-aac/libMpegTPEnc/src/tp_version.h118
-rw-r--r--fdk-aac/libMpegTPEnc/src/tpenc_adif.cpp186
-rw-r--r--fdk-aac/libMpegTPEnc/src/tpenc_adif.h146
-rw-r--r--fdk-aac/libMpegTPEnc/src/tpenc_adts.cpp319
-rw-r--r--fdk-aac/libMpegTPEnc/src/tpenc_adts.h208
-rw-r--r--fdk-aac/libMpegTPEnc/src/tpenc_asc.cpp996
-rw-r--r--fdk-aac/libMpegTPEnc/src/tpenc_asc.h147
-rw-r--r--fdk-aac/libMpegTPEnc/src/tpenc_dab.cpp467
-rw-r--r--fdk-aac/libMpegTPEnc/src/tpenc_dab.h217
-rw-r--r--fdk-aac/libMpegTPEnc/src/tpenc_latm.cpp850
-rw-r--r--fdk-aac/libMpegTPEnc/src/tpenc_latm.h274
-rw-r--r--fdk-aac/libMpegTPEnc/src/tpenc_lib.cpp713
-rw-r--r--fdk-aac/libPCMutils/include/limiter.h281
-rw-r--r--fdk-aac/libPCMutils/include/pcm_utils.h131
-rw-r--r--fdk-aac/libPCMutils/include/pcmdmx_lib.h460
-rw-r--r--fdk-aac/libPCMutils/src/limiter.cpp570
-rw-r--r--fdk-aac/libPCMutils/src/pcm_utils.cpp195
-rw-r--r--fdk-aac/libPCMutils/src/pcmdmx_lib.cpp2662
-rw-r--r--fdk-aac/libPCMutils/src/version.h119
-rw-r--r--fdk-aac/libSACdec/include/sac_dec_errorcodes.h157
-rw-r--r--fdk-aac/libSACdec/include/sac_dec_lib.h477
-rw-r--r--fdk-aac/libSACdec/src/sac_bitdec.cpp2167
-rw-r--r--fdk-aac/libSACdec/src/sac_bitdec.h161
-rw-r--r--fdk-aac/libSACdec/src/sac_calcM1andM2.cpp848
-rw-r--r--fdk-aac/libSACdec/src/sac_calcM1andM2.h129
-rw-r--r--fdk-aac/libSACdec/src/sac_dec.cpp1509
-rw-r--r--fdk-aac/libSACdec/src/sac_dec.h539
-rw-r--r--fdk-aac/libSACdec/src/sac_dec_conceal.cpp392
-rw-r--r--fdk-aac/libSACdec/src/sac_dec_conceal.h187
-rw-r--r--fdk-aac/libSACdec/src/sac_dec_interface.h335
-rw-r--r--fdk-aac/libSACdec/src/sac_dec_lib.cpp1995
-rw-r--r--fdk-aac/libSACdec/src/sac_dec_ssc_struct.h283
-rw-r--r--fdk-aac/libSACdec/src/sac_process.cpp1066
-rw-r--r--fdk-aac/libSACdec/src/sac_process.h297
-rw-r--r--fdk-aac/libSACdec/src/sac_qmf.cpp156
-rw-r--r--fdk-aac/libSACdec/src/sac_qmf.h143
-rw-r--r--fdk-aac/libSACdec/src/sac_reshapeBBEnv.cpp680
-rw-r--r--fdk-aac/libSACdec/src/sac_reshapeBBEnv.h114
-rw-r--r--fdk-aac/libSACdec/src/sac_rom.cpp709
-rw-r--r--fdk-aac/libSACdec/src/sac_rom.h230
-rw-r--r--fdk-aac/libSACdec/src/sac_smoothing.cpp295
-rw-r--r--fdk-aac/libSACdec/src/sac_smoothing.h114
-rw-r--r--fdk-aac/libSACdec/src/sac_stp.cpp548
-rw-r--r--fdk-aac/libSACdec/src/sac_stp.h115
-rw-r--r--fdk-aac/libSACdec/src/sac_tsd.cpp353
-rw-r--r--fdk-aac/libSACdec/src/sac_tsd.h167
-rw-r--r--fdk-aac/libSACenc/include/sacenc_lib.h405
-rw-r--r--fdk-aac/libSACenc/src/sacenc_bitstream.cpp826
-rw-r--r--fdk-aac/libSACenc/src/sacenc_bitstream.h296
-rw-r--r--fdk-aac/libSACenc/src/sacenc_const.h126
-rw-r--r--fdk-aac/libSACenc/src/sacenc_delay.cpp472
-rw-r--r--fdk-aac/libSACenc/src/sacenc_delay.h175
-rw-r--r--fdk-aac/libSACenc/src/sacenc_dmx_tdom_enh.cpp639
-rw-r--r--fdk-aac/libSACenc/src/sacenc_dmx_tdom_enh.h134
-rw-r--r--fdk-aac/libSACenc/src/sacenc_filter.cpp207
-rw-r--r--fdk-aac/libSACenc/src/sacenc_filter.h133
-rw-r--r--fdk-aac/libSACenc/src/sacenc_framewindowing.cpp568
-rw-r--r--fdk-aac/libSACenc/src/sacenc_framewindowing.h181
-rw-r--r--fdk-aac/libSACenc/src/sacenc_huff_tab.cpp997
-rw-r--r--fdk-aac/libSACenc/src/sacenc_huff_tab.h222
-rw-r--r--fdk-aac/libSACenc/src/sacenc_lib.cpp2042
-rw-r--r--fdk-aac/libSACenc/src/sacenc_nlc_enc.cpp1442
-rw-r--r--fdk-aac/libSACenc/src/sacenc_nlc_enc.h141
-rw-r--r--fdk-aac/libSACenc/src/sacenc_onsetdetect.cpp381
-rw-r--r--fdk-aac/libSACenc/src/sacenc_onsetdetect.h154
-rw-r--r--fdk-aac/libSACenc/src/sacenc_paramextract.cpp725
-rw-r--r--fdk-aac/libSACenc/src/sacenc_paramextract.h214
-rw-r--r--fdk-aac/libSACenc/src/sacenc_staticgain.cpp446
-rw-r--r--fdk-aac/libSACenc/src/sacenc_staticgain.h177
-rw-r--r--fdk-aac/libSACenc/src/sacenc_tree.cpp488
-rw-r--r--fdk-aac/libSACenc/src/sacenc_tree.h168
-rw-r--r--fdk-aac/libSACenc/src/sacenc_vectorfunctions.cpp450
-rw-r--r--fdk-aac/libSACenc/src/sacenc_vectorfunctions.h488
-rw-r--r--fdk-aac/libSBRdec/include/sbrdecoder.h401
-rw-r--r--fdk-aac/libSBRdec/src/HFgen_preFlat.cpp993
-rw-r--r--fdk-aac/libSBRdec/src/HFgen_preFlat.h132
-rw-r--r--fdk-aac/libSBRdec/src/arm/lpp_tran_arm.cpp159
-rw-r--r--fdk-aac/libSBRdec/src/env_calc.cpp3158
-rw-r--r--fdk-aac/libSBRdec/src/env_calc.h182
-rw-r--r--fdk-aac/libSBRdec/src/env_dec.cpp873
-rw-r--r--fdk-aac/libSBRdec/src/env_dec.h119
-rw-r--r--fdk-aac/libSBRdec/src/env_extr.cpp1728
-rw-r--r--fdk-aac/libSBRdec/src/env_extr.h415
-rw-r--r--fdk-aac/libSBRdec/src/hbe.cpp2202
-rw-r--r--fdk-aac/libSBRdec/src/hbe.h200
-rw-r--r--fdk-aac/libSBRdec/src/huff_dec.cpp137
-rw-r--r--fdk-aac/libSBRdec/src/huff_dec.h117
-rw-r--r--fdk-aac/libSBRdec/src/lpp_tran.cpp1471
-rw-r--r--fdk-aac/libSBRdec/src/lpp_tran.h275
-rw-r--r--fdk-aac/libSBRdec/src/psbitdec.cpp594
-rw-r--r--fdk-aac/libSBRdec/src/psbitdec.h116
-rw-r--r--fdk-aac/libSBRdec/src/psdec.cpp722
-rw-r--r--fdk-aac/libSBRdec/src/psdec.h333
-rw-r--r--fdk-aac/libSBRdec/src/psdec_drm.cpp108
-rw-r--r--fdk-aac/libSBRdec/src/psdec_drm.h113
-rw-r--r--fdk-aac/libSBRdec/src/psdecrom_drm.cpp108
-rw-r--r--fdk-aac/libSBRdec/src/pvc_dec.cpp683
-rw-r--r--fdk-aac/libSBRdec/src/pvc_dec.h238
-rw-r--r--fdk-aac/libSBRdec/src/sbr_crc.cpp192
-rw-r--r--fdk-aac/libSBRdec/src/sbr_crc.h138
-rw-r--r--fdk-aac/libSBRdec/src/sbr_deb.cpp108
-rw-r--r--fdk-aac/libSBRdec/src/sbr_deb.h113
-rw-r--r--fdk-aac/libSBRdec/src/sbr_dec.cpp1480
-rw-r--r--fdk-aac/libSBRdec/src/sbr_dec.h204
-rw-r--r--fdk-aac/libSBRdec/src/sbr_ram.cpp191
-rw-r--r--fdk-aac/libSBRdec/src/sbr_ram.h186
-rw-r--r--fdk-aac/libSBRdec/src/sbr_rom.cpp1705
-rw-r--r--fdk-aac/libSBRdec/src/sbr_rom.h216
-rw-r--r--fdk-aac/libSBRdec/src/sbrdec_drc.cpp528
-rw-r--r--fdk-aac/libSBRdec/src/sbrdec_drc.h149
-rw-r--r--fdk-aac/libSBRdec/src/sbrdec_freq_sca.cpp835
-rw-r--r--fdk-aac/libSBRdec/src/sbrdec_freq_sca.h127
-rw-r--r--fdk-aac/libSBRdec/src/sbrdecoder.cpp2023
-rw-r--r--fdk-aac/libSBRdec/src/transcendent.h372
-rw-r--r--fdk-aac/libSBRenc/include/sbr_encoder.h483
-rw-r--r--fdk-aac/libSBRenc/src/bit_sbr.cpp1049
-rw-r--r--fdk-aac/libSBRenc/src/bit_sbr.h267
-rw-r--r--fdk-aac/libSBRenc/src/cmondata.h127
-rw-r--r--fdk-aac/libSBRenc/src/code_env.cpp602
-rw-r--r--fdk-aac/libSBRenc/src/code_env.h161
-rw-r--r--fdk-aac/libSBRenc/src/env_bit.cpp257
-rw-r--r--fdk-aac/libSBRenc/src/env_bit.h135
-rw-r--r--fdk-aac/libSBRenc/src/env_est.cpp1986
-rw-r--r--fdk-aac/libSBRenc/src/env_est.h223
-rw-r--r--fdk-aac/libSBRenc/src/fram_gen.cpp1965
-rw-r--r--fdk-aac/libSBRenc/src/fram_gen.h343
-rw-r--r--fdk-aac/libSBRenc/src/invf_est.cpp610
-rw-r--r--fdk-aac/libSBRenc/src/invf_est.h181
-rw-r--r--fdk-aac/libSBRenc/src/mh_det.cpp1396
-rw-r--r--fdk-aac/libSBRenc/src/mh_det.h204
-rw-r--r--fdk-aac/libSBRenc/src/nf_est.cpp612
-rw-r--r--fdk-aac/libSBRenc/src/nf_est.h185
-rw-r--r--fdk-aac/libSBRenc/src/ps_bitenc.cpp624
-rw-r--r--fdk-aac/libSBRenc/src/ps_bitenc.h173
-rw-r--r--fdk-aac/libSBRenc/src/ps_const.h150
-rw-r--r--fdk-aac/libSBRenc/src/ps_encode.cpp1031
-rw-r--r--fdk-aac/libSBRenc/src/ps_encode.h185
-rw-r--r--fdk-aac/libSBRenc/src/ps_main.cpp606
-rw-r--r--fdk-aac/libSBRenc/src/ps_main.h270
-rw-r--r--fdk-aac/libSBRenc/src/resampler.cpp444
-rw-r--r--fdk-aac/libSBRenc/src/resampler.h159
-rw-r--r--fdk-aac/libSBRenc/src/sbr.h194
-rw-r--r--fdk-aac/libSBRenc/src/sbr_def.h276
-rw-r--r--fdk-aac/libSBRenc/src/sbr_encoder.cpp2577
-rw-r--r--fdk-aac/libSBRenc/src/sbr_misc.cpp265
-rw-r--r--fdk-aac/libSBRenc/src/sbr_misc.h127
-rw-r--r--fdk-aac/libSBRenc/src/sbrenc_freq_sca.cpp674
-rw-r--r--fdk-aac/libSBRenc/src/sbrenc_freq_sca.h132
-rw-r--r--fdk-aac/libSBRenc/src/sbrenc_ram.cpp249
-rw-r--r--fdk-aac/libSBRenc/src/sbrenc_ram.h199
-rw-r--r--fdk-aac/libSBRenc/src/sbrenc_rom.cpp910
-rw-r--r--fdk-aac/libSBRenc/src/sbrenc_rom.h145
-rw-r--r--fdk-aac/libSBRenc/src/ton_corr.cpp891
-rw-r--r--fdk-aac/libSBRenc/src/ton_corr.h258
-rw-r--r--fdk-aac/libSBRenc/src/tran_det.cpp1092
-rw-r--r--fdk-aac/libSBRenc/src/tran_det.h191
-rw-r--r--fdk-aac/libSYS/include/FDK_audio.h827
-rw-r--r--fdk-aac/libSYS/include/genericStds.h584
-rw-r--r--fdk-aac/libSYS/include/machine_type.h411
-rw-r--r--fdk-aac/libSYS/include/syslib_channelMapDescr.h202
-rw-r--r--fdk-aac/libSYS/src/genericStds.cpp419
-rw-r--r--fdk-aac/libSYS/src/syslib_channelMapDescr.cpp315
-rw-r--r--fdk-aac/m4/.gitkeep0
-rw-r--r--fdk-aac/wavreader.c193
-rw-r--r--fdk-aac/wavreader.h37
-rw-r--r--fdk-aac/win32/getopt.h904
431 files changed, 218009 insertions, 0 deletions
diff --git a/fdk-aac/.clang-format b/fdk-aac/.clang-format
new file mode 100644
index 0000000..caeb773
--- /dev/null
+++ b/fdk-aac/.clang-format
@@ -0,0 +1,4 @@
+BasedOnStyle: Google
+SortIncludes: false
+# Do not reformat the Doxygen-style comments in the code
+CommentPragmas : "^ * \\\\"
diff --git a/fdk-aac/.gitignore b/fdk-aac/.gitignore
new file mode 100644
index 0000000..263e5aa
--- /dev/null
+++ b/fdk-aac/.gitignore
@@ -0,0 +1,29 @@
+*.o
+*.lo
+*.la
+.deps
+.libs
+.dirstamp
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache
+configure
+fdk-aac.pc
+config.guess
+config.log
+config.status
+config.sub
+depcomp
+install-sh
+libtool
+ltmain.sh
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
+missing
+stamp-h1
+aac-enc
+compile
diff --git a/fdk-aac/Android.bp b/fdk-aac/Android.bp
new file mode 100644
index 0000000..dce6fdd
--- /dev/null
+++ b/fdk-aac/Android.bp
@@ -0,0 +1,53 @@
+cc_library_static {
+ name: "libFraunhoferAAC",
+ vendor_available: true,
+ srcs: [
+ "libAACdec/src/*.cpp",
+ "libAACenc/src/*.cpp",
+ "libPCMutils/src/*.cpp",
+ "libFDK/src/*.cpp",
+ "libSYS/src/*.cpp",
+ "libMpegTPDec/src/*.cpp",
+ "libMpegTPEnc/src/*.cpp",
+ "libSBRdec/src/*.cpp",
+ "libSBRenc/src/*.cpp",
+ "libArithCoding/src/*.cpp",
+ "libDRCdec/src/*.cpp",
+ "libSACdec/src/*.cpp",
+ "libSACenc/src/*.cpp",
+ ],
+ cflags: [
+ "-Werror",
+ "-Wno-unused-parameter",
+ "-Wno-#warnings",
+ "-Wuninitialized",
+ "-Wno-self-assign",
+ "-Wno-implicit-fallthrough",
+ ],
+ sanitize: {
+ misc_undefined:[
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ "bounds",
+ ],
+ cfi: true,
+ },
+ shared_libs: [
+ "liblog",
+ ],
+ export_include_dirs: [
+ "libAACdec/include",
+ "libAACenc/include",
+ "libPCMutils/include",
+ "libFDK/include",
+ "libSYS/include",
+ "libMpegTPDec/include",
+ "libMpegTPEnc/include",
+ "libSBRdec/include",
+ "libSBRenc/include",
+ "libArithCoding/include",
+ "libDRCdec/include",
+ "libSACdec/include",
+ "libSACenc/include",
+ ],
+}
diff --git a/fdk-aac/ChangeLog b/fdk-aac/ChangeLog
new file mode 100644
index 0000000..2675878
--- /dev/null
+++ b/fdk-aac/ChangeLog
@@ -0,0 +1,48 @@
+2.0.0
+ - Major update in the upstream source base, with support for new
+ profiles and features, and numerous crash/fuzz fixes. The new
+ upstream version is referred to as FDKv2, thus skipping the
+ major version 1 and syncing the fdk-aac major version number to 2.
+
+0.1.6
+ - Lots of minor assorted crash/fuzz fixes, mostly for the decoder but
+ also some for the encoder
+
+0.1.5
+ - Updated upstream sources
+ - Fixed building with GCC 3.3 and 3.4
+ - Fixed building with GCC 6
+ - AArch64 optimizations
+ - Makefiles for building with MSVC
+ - Support building the code in C++11 mode
+
+0.1.4
+ - Updated upstream sources, with minor changes to the decoder API
+ breaking the ABI. (Calling code using AUDIO_CHANNEL_TYPE may need to
+ be updated. A new option AAC_PCM_LIMITER_ENABLE has been added, enabled
+ by default, which incurs extra decoding delay.)
+ - PowerPC optimizations, fixes for building on AIX
+ - Support for reading streamed wav files in the encoder example
+ - Fix VBR encoding of sample rates over 64 kHz
+
+0.1.3
+ - Updated upstream sources, with a number of crash fixes and new features
+ (including support for encoding 7.1)
+
+0.1.2
+ - Fix a few more crashes
+ - Include dependency libs (such as -lm) in the pkg-config file
+
+0.1.1
+ - Updated to a new upstream version from Android 4.2, fixing a lot of crashes
+ - Cleanup of autotools usage
+ - Make sure the shared library links to libm if necessary
+ - Performance improvements on x86
+ - Added support for WG4/DVD audio channel mappings
+ - Minimized the differences to upstream
+ - Added an example encoder tool
+
+0.1.0
+ - Initial release of fdk-aac
+ - autotools based build system
+ - Enable setting VBR bitrate modes
diff --git a/fdk-aac/MODULE_LICENSE_FRAUNHOFER b/fdk-aac/MODULE_LICENSE_FRAUNHOFER
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/fdk-aac/MODULE_LICENSE_FRAUNHOFER
diff --git a/fdk-aac/Makefile.am b/fdk-aac/Makefile.am
new file mode 100644
index 0000000..9404f8d
--- /dev/null
+++ b/fdk-aac/Makefile.am
@@ -0,0 +1,297 @@
+ACLOCAL_AMFLAGS = -I m4
+AUTOMAKE_OPTIONS = subdir-objects
+
+AM_CPPFLAGS = \
+ -I./libAACdec/include \
+ -I./libAACenc/include \
+ -I./libArithCoding/include \
+ -I./libDRCdec/include \
+ -I./libSACdec/include \
+ -I./libSACenc/include \
+ -I./libSBRdec/include \
+ -I./libSBRenc/include \
+ -I./libMpegTPDec/include \
+ -I./libMpegTPEnc/include \
+ -I./libSYS/include \
+ -I./libFDK/include \
+ -I./libPCMutils/include
+
+AM_CXXFLAGS = -fno-exceptions -fno-rtti
+libfdk_aac_dab_la_LINK = $(LINK) $(libfdk_aac_dab_la_LDFLAGS)
+# Mention a dummy pure C file to trigger generation of the $(LINK) variable
+nodist_EXTRA_libfdk_aac_dab_la_SOURCES = dummy.c
+
+fdk_aac_dabincludedir = $(includedir)/fdk-aac-dab
+fdk_aac_dabinclude_HEADERS = \
+ ./libSYS/include/machine_type.h \
+ ./libSYS/include/genericStds.h \
+ ./libSYS/include/FDK_audio.h \
+ ./libSYS/include/syslib_channelMapDescr.h \
+ ./libAACenc/include/aacenc_lib.h \
+ ./libAACdec/include/aacdecoder_lib.h
+
+#pkgconfigdir = $(libdir)/pkgconfig
+#pkgconfig_DATA = fdk-aac.pc
+
+lib_LTLIBRARIES = libfdk-aac-dab.la
+
+libfdk_aac_dab_la_LDFLAGS = -version-info @FDK_AAC_VERSION@ -no-undefined \
+ -export-symbols ./fdk-aac.sym
+
+if EXAMPLE
+bin_PROGRAMS = aac-enc$(EXEEXT)
+
+aac_enc_LDADD = libfdk-aac-dab.la
+aac_enc_SOURCES = aac-enc.c wavreader.c
+
+noinst_HEADERS = wavreader.h
+endif
+
+AACDEC_SRC = \
+ libAACdec/src/FDK_delay.cpp \
+ libAACdec/src/aac_ram.cpp \
+ libAACdec/src/aac_rom.cpp \
+ libAACdec/src/aacdec_drc.cpp \
+ libAACdec/src/aacdec_hcr.cpp \
+ libAACdec/src/aacdec_hcr_bit.cpp \
+ libAACdec/src/aacdec_hcrs.cpp \
+ libAACdec/src/aacdec_pns.cpp \
+ libAACdec/src/aacdec_tns.cpp \
+ libAACdec/src/aacdecoder.cpp \
+ libAACdec/src/aacdecoder_lib.cpp \
+ libAACdec/src/block.cpp \
+ libAACdec/src/channel.cpp \
+ libAACdec/src/channelinfo.cpp \
+ libAACdec/src/conceal.cpp \
+ libAACdec/src/ldfiltbank.cpp \
+ libAACdec/src/pulsedata.cpp \
+ libAACdec/src/rvlc.cpp \
+ libAACdec/src/rvlcbit.cpp \
+ libAACdec/src/rvlcconceal.cpp \
+ libAACdec/src/stereo.cpp \
+ libAACdec/src/usacdec_ace_d4t64.cpp \
+ libAACdec/src/usacdec_ace_ltp.cpp \
+ libAACdec/src/usacdec_acelp.cpp \
+ libAACdec/src/usacdec_fac.cpp \
+ libAACdec/src/usacdec_lpc.cpp \
+ libAACdec/src/usacdec_lpd.cpp \
+ libAACdec/src/usacdec_rom.cpp
+
+AACENC_SRC = \
+ libAACenc/src/aacEnc_ram.cpp \
+ libAACenc/src/aacEnc_rom.cpp \
+ libAACenc/src/aacenc.cpp \
+ libAACenc/src/aacenc_lib.cpp \
+ libAACenc/src/aacenc_pns.cpp \
+ libAACenc/src/aacenc_tns.cpp \
+ libAACenc/src/adj_thr.cpp \
+ libAACenc/src/band_nrg.cpp \
+ libAACenc/src/bandwidth.cpp \
+ libAACenc/src/bit_cnt.cpp \
+ libAACenc/src/bitenc.cpp \
+ libAACenc/src/block_switch.cpp \
+ libAACenc/src/channel_map.cpp \
+ libAACenc/src/chaosmeasure.cpp \
+ libAACenc/src/dyn_bits.cpp \
+ libAACenc/src/grp_data.cpp \
+ libAACenc/src/intensity.cpp \
+ libAACenc/src/line_pe.cpp \
+ libAACenc/src/metadata_compressor.cpp \
+ libAACenc/src/metadata_main.cpp \
+ libAACenc/src/mps_main.cpp \
+ libAACenc/src/ms_stereo.cpp \
+ libAACenc/src/noisedet.cpp \
+ libAACenc/src/pnsparam.cpp \
+ libAACenc/src/pre_echo_control.cpp \
+ libAACenc/src/psy_configuration.cpp \
+ libAACenc/src/psy_main.cpp \
+ libAACenc/src/qc_main.cpp \
+ libAACenc/src/quantize.cpp \
+ libAACenc/src/sf_estim.cpp \
+ libAACenc/src/spreading.cpp \
+ libAACenc/src/tonality.cpp \
+ libAACenc/src/transform.cpp
+
+ARITHCODING_SRC = \
+ libArithCoding/src/ac_arith_coder.cpp
+
+DRCDEC_SRC = \
+ libDRCdec/src/FDK_drcDecLib.cpp \
+ libDRCdec/src/drcDec_gainDecoder.cpp \
+ libDRCdec/src/drcDec_reader.cpp \
+ libDRCdec/src/drcDec_rom.cpp \
+ libDRCdec/src/drcDec_selectionProcess.cpp \
+ libDRCdec/src/drcDec_tools.cpp \
+ libDRCdec/src/drcGainDec_init.cpp \
+ libDRCdec/src/drcGainDec_preprocess.cpp \
+ libDRCdec/src/drcGainDec_process.cpp
+
+FDK_SRC = \
+ libFDK/src/FDK_bitbuffer.cpp \
+ libFDK/src/FDK_core.cpp \
+ libFDK/src/FDK_crc.cpp \
+ libFDK/src/FDK_decorrelate.cpp \
+ libFDK/src/FDK_hybrid.cpp \
+ libFDK/src/FDK_lpc.cpp \
+ libFDK/src/FDK_matrixCalloc.cpp \
+ libFDK/src/FDK_qmf_domain.cpp \
+ libFDK/src/FDK_tools_rom.cpp \
+ libFDK/src/FDK_trigFcts.cpp \
+ libFDK/src/autocorr2nd.cpp \
+ libFDK/src/dct.cpp \
+ libFDK/src/fft.cpp \
+ libFDK/src/fft_rad2.cpp \
+ libFDK/src/fixpoint_math.cpp \
+ libFDK/src/huff_nodes.cpp \
+ libFDK/src/mdct.cpp \
+ libFDK/src/nlc_dec.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 \
+ libMpegTPEnc/src/tpenc_dab.cpp
+
+PCMUTILS_SRC = \
+ libPCMutils/src/limiter.cpp \
+ libPCMutils/src/pcm_utils.cpp \
+ libPCMutils/src/pcmdmx_lib.cpp
+
+SACDEC_SRC = \
+ libSACdec/src/sac_bitdec.cpp \
+ libSACdec/src/sac_calcM1andM2.cpp \
+ libSACdec/src/sac_dec.cpp \
+ libSACdec/src/sac_dec_conceal.cpp \
+ libSACdec/src/sac_dec_lib.cpp \
+ libSACdec/src/sac_process.cpp \
+ libSACdec/src/sac_qmf.cpp \
+ libSACdec/src/sac_reshapeBBEnv.cpp \
+ libSACdec/src/sac_rom.cpp \
+ libSACdec/src/sac_smoothing.cpp \
+ libSACdec/src/sac_stp.cpp \
+ libSACdec/src/sac_tsd.cpp
+
+SACENC_SRC = \
+ libSACenc/src/sacenc_bitstream.cpp \
+ libSACenc/src/sacenc_delay.cpp \
+ libSACenc/src/sacenc_dmx_tdom_enh.cpp \
+ libSACenc/src/sacenc_filter.cpp \
+ libSACenc/src/sacenc_framewindowing.cpp \
+ libSACenc/src/sacenc_huff_tab.cpp \
+ libSACenc/src/sacenc_lib.cpp \
+ libSACenc/src/sacenc_nlc_enc.cpp \
+ libSACenc/src/sacenc_onsetdetect.cpp \
+ libSACenc/src/sacenc_paramextract.cpp \
+ libSACenc/src/sacenc_staticgain.cpp \
+ libSACenc/src/sacenc_tree.cpp \
+ libSACenc/src/sacenc_vectorfunctions.cpp
+
+SBRDEC_SRC = \
+ libSBRdec/src/HFgen_preFlat.cpp \
+ libSBRdec/src/env_calc.cpp \
+ libSBRdec/src/env_dec.cpp \
+ libSBRdec/src/env_extr.cpp \
+ libSBRdec/src/hbe.cpp \
+ libSBRdec/src/huff_dec.cpp \
+ libSBRdec/src/lpp_tran.cpp \
+ libSBRdec/src/psbitdec.cpp \
+ libSBRdec/src/psdec.cpp \
+ libSBRdec/src/psdec_drm.cpp \
+ libSBRdec/src/psdecrom_drm.cpp \
+ libSBRdec/src/pvc_dec.cpp \
+ libSBRdec/src/sbr_crc.cpp \
+ libSBRdec/src/sbr_deb.cpp \
+ libSBRdec/src/sbr_dec.cpp \
+ libSBRdec/src/sbr_ram.cpp \
+ libSBRdec/src/sbr_rom.cpp \
+ libSBRdec/src/sbrdec_drc.cpp \
+ libSBRdec/src/sbrdec_freq_sca.cpp \
+ libSBRdec/src/sbrdecoder.cpp
+
+SBRENC_SRC = \
+ libSBRenc/src/bit_sbr.cpp \
+ libSBRenc/src/code_env.cpp \
+ libSBRenc/src/env_bit.cpp \
+ libSBRenc/src/env_est.cpp \
+ libSBRenc/src/fram_gen.cpp \
+ libSBRenc/src/invf_est.cpp \
+ libSBRenc/src/mh_det.cpp \
+ libSBRenc/src/nf_est.cpp \
+ libSBRenc/src/ps_bitenc.cpp \
+ libSBRenc/src/ps_encode.cpp \
+ libSBRenc/src/ps_main.cpp \
+ libSBRenc/src/resampler.cpp \
+ libSBRenc/src/sbr_encoder.cpp \
+ libSBRenc/src/sbr_misc.cpp \
+ libSBRenc/src/sbrenc_freq_sca.cpp \
+ libSBRenc/src/sbrenc_ram.cpp \
+ libSBRenc/src/sbrenc_rom.cpp \
+ libSBRenc/src/ton_corr.cpp \
+ libSBRenc/src/tran_det.cpp
+
+SYS_SRC = \
+ libSYS/src/genericStds.cpp \
+ libSYS/src/syslib_channelMapDescr.cpp
+
+libfdk_aac_dab_la_SOURCES = \
+ $(AACDEC_SRC) $(AACENC_SRC) \
+ $(ARITHCODING_SRC) \
+ $(DRCDEC_SRC) \
+ $(MPEGTPDEC_SRC) $(MPEGTPENC_SRC) \
+ $(SACDEC_SRC) $(SACENC_SRC) \
+ $(SBRDEC_SRC) $(SBRENC_SRC) \
+ $(PCMUTILS_SRC) $(FDK_SRC) $(SYS_SRC)
+
+EXTRA_DIST = \
+ ./.clang-format \
+ ./autogen.sh \
+ ./MODULE_LICENSE_FRAUNHOFER \
+ ./NOTICE \
+ ./OWNERS \
+ ./Android.bp \
+ ./fdk-aac.sym \
+ ./Makefile.vc \
+ ./documentation/*.pdf \
+ ./libAACdec/src/*.h \
+ ./libAACdec/src/arm/*.cpp \
+ ./libAACenc/src/*.h \
+ ./libArithCoding/include/*.h \
+ ./libDRCdec/include/*.h \
+ ./libDRCdec/src/*.h \
+ ./libSACdec/include/*.h \
+ ./libSACdec/src/*.h \
+ ./libSACenc/include/*.h \
+ ./libSACenc/src/*.h \
+ ./libSBRenc/src/*.h \
+ ./libSBRenc/include/*.h \
+ ./libSBRdec/src/*.h \
+ ./libSBRdec/src/arm/*.cpp \
+ ./libSBRdec/include/*.h \
+ ./libSYS/include/*.h \
+ ./libPCMutils/include/*.h \
+ ./libPCMutils/src/*.h \
+ ./libMpegTPEnc/include/*.h \
+ ./libMpegTPEnc/src/*.h \
+ ./libMpegTPDec/include/*.h \
+ ./libMpegTPDec/src/*.h \
+ ./libFDK/include/*.h \
+ ./libFDK/include/arm/*.h \
+ ./libFDK/include/mips/*.h \
+ ./libFDK/include/ppc/*.h \
+ ./libFDK/include/x86/*.h \
+ ./libFDK/src/arm/*.cpp \
+ ./libFDK/src/mips/*.cpp \
+ ./win32/*.h
+
diff --git a/fdk-aac/Makefile.vc b/fdk-aac/Makefile.vc
new file mode 100644
index 0000000..a90b530
--- /dev/null
+++ b/fdk-aac/Makefile.vc
@@ -0,0 +1,321 @@
+#
+# Options:
+# prefix=\path\to\install
+#
+# Compiling: nmake -f Makefile.vc
+# Installing: nmake -f Makefile.vc prefix=\path\to\x install
+#
+
+# 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 \
+ -IlibArithCoding/include \
+ -IlibDRCdec/include \
+ -IlibSACdec/include \
+ -IlibSACenc/include \
+ -IlibSBRdec/include \
+ -IlibSBRenc/include \
+ -IlibMpegTPDec/include \
+ -IlibMpegTPEnc/include \
+ -IlibSYS/include \
+ -IlibFDK/include \
+ -IlibPCMutils/include
+
+AACDEC_SRC = \
+ libAACdec/src/FDK_delay.cpp \
+ libAACdec/src/aac_ram.cpp \
+ libAACdec/src/aac_rom.cpp \
+ libAACdec/src/aacdec_drc.cpp \
+ libAACdec/src/aacdec_hcr.cpp \
+ libAACdec/src/aacdec_hcr_bit.cpp \
+ libAACdec/src/aacdec_hcrs.cpp \
+ libAACdec/src/aacdec_pns.cpp \
+ libAACdec/src/aacdec_tns.cpp \
+ libAACdec/src/aacdecoder.cpp \
+ libAACdec/src/aacdecoder_lib.cpp \
+ libAACdec/src/block.cpp \
+ libAACdec/src/channel.cpp \
+ libAACdec/src/channelinfo.cpp \
+ libAACdec/src/conceal.cpp \
+ libAACdec/src/ldfiltbank.cpp \
+ libAACdec/src/pulsedata.cpp \
+ libAACdec/src/rvlc.cpp \
+ libAACdec/src/rvlcbit.cpp \
+ libAACdec/src/rvlcconceal.cpp \
+ libAACdec/src/stereo.cpp \
+ libAACdec/src/usacdec_ace_d4t64.cpp \
+ libAACdec/src/usacdec_ace_ltp.cpp \
+ libAACdec/src/usacdec_acelp.cpp \
+ libAACdec/src/usacdec_fac.cpp \
+ libAACdec/src/usacdec_lpc.cpp \
+ libAACdec/src/usacdec_lpd.cpp \
+ libAACdec/src/usacdec_rom.cpp
+
+AACENC_SRC = \
+ libAACenc/src/aacEnc_ram.cpp \
+ libAACenc/src/aacEnc_rom.cpp \
+ libAACenc/src/aacenc.cpp \
+ libAACenc/src/aacenc_lib.cpp \
+ libAACenc/src/aacenc_pns.cpp \
+ libAACenc/src/aacenc_tns.cpp \
+ libAACenc/src/adj_thr.cpp \
+ libAACenc/src/band_nrg.cpp \
+ libAACenc/src/bandwidth.cpp \
+ libAACenc/src/bit_cnt.cpp \
+ libAACenc/src/bitenc.cpp \
+ libAACenc/src/block_switch.cpp \
+ libAACenc/src/channel_map.cpp \
+ libAACenc/src/chaosmeasure.cpp \
+ libAACenc/src/dyn_bits.cpp \
+ libAACenc/src/grp_data.cpp \
+ libAACenc/src/intensity.cpp \
+ libAACenc/src/line_pe.cpp \
+ libAACenc/src/metadata_compressor.cpp \
+ libAACenc/src/metadata_main.cpp \
+ libAACenc/src/mps_main.cpp \
+ libAACenc/src/ms_stereo.cpp \
+ libAACenc/src/noisedet.cpp \
+ libAACenc/src/pnsparam.cpp \
+ libAACenc/src/pre_echo_control.cpp \
+ libAACenc/src/psy_configuration.cpp \
+ libAACenc/src/psy_main.cpp \
+ libAACenc/src/qc_main.cpp \
+ libAACenc/src/quantize.cpp \
+ libAACenc/src/sf_estim.cpp \
+ libAACenc/src/spreading.cpp \
+ libAACenc/src/tonality.cpp \
+ libAACenc/src/transform.cpp
+
+ARITHCODING_SRC = \
+ libArithCoding/src/ac_arith_coder.cpp
+
+DRCDEC_SRC = \
+ libDRCdec/src/FDK_drcDecLib.cpp \
+ libDRCdec/src/drcDec_gainDecoder.cpp \
+ libDRCdec/src/drcDec_reader.cpp \
+ libDRCdec/src/drcDec_rom.cpp \
+ libDRCdec/src/drcDec_selectionProcess.cpp \
+ libDRCdec/src/drcDec_tools.cpp \
+ libDRCdec/src/drcGainDec_init.cpp \
+ libDRCdec/src/drcGainDec_preprocess.cpp \
+ libDRCdec/src/drcGainDec_process.cpp
+
+FDK_SRC = \
+ libFDK/src/FDK_bitbuffer.cpp \
+ libFDK/src/FDK_core.cpp \
+ libFDK/src/FDK_crc.cpp \
+ libFDK/src/FDK_decorrelate.cpp \
+ libFDK/src/FDK_hybrid.cpp \
+ libFDK/src/FDK_lpc.cpp \
+ libFDK/src/FDK_matrixCalloc.cpp \
+ libFDK/src/FDK_qmf_domain.cpp \
+ libFDK/src/FDK_tools_rom.cpp \
+ libFDK/src/FDK_trigFcts.cpp \
+ libFDK/src/autocorr2nd.cpp \
+ libFDK/src/dct.cpp \
+ libFDK/src/fft.cpp \
+ libFDK/src/fft_rad2.cpp \
+ libFDK/src/fixpoint_math.cpp \
+ libFDK/src/huff_nodes.cpp \
+ libFDK/src/mdct.cpp \
+ libFDK/src/nlc_dec.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/pcm_utils.cpp \
+ libPCMutils/src/pcmdmx_lib.cpp
+
+SACDEC_SRC = \
+ libSACdec/src/sac_bitdec.cpp \
+ libSACdec/src/sac_calcM1andM2.cpp \
+ libSACdec/src/sac_dec.cpp \
+ libSACdec/src/sac_dec_conceal.cpp \
+ libSACdec/src/sac_dec_lib.cpp \
+ libSACdec/src/sac_process.cpp \
+ libSACdec/src/sac_qmf.cpp \
+ libSACdec/src/sac_reshapeBBEnv.cpp \
+ libSACdec/src/sac_rom.cpp \
+ libSACdec/src/sac_smoothing.cpp \
+ libSACdec/src/sac_stp.cpp \
+ libSACdec/src/sac_tsd.cpp
+
+SACENC_SRC = \
+ libSACenc/src/sacenc_bitstream.cpp \
+ libSACenc/src/sacenc_delay.cpp \
+ libSACenc/src/sacenc_dmx_tdom_enh.cpp \
+ libSACenc/src/sacenc_filter.cpp \
+ libSACenc/src/sacenc_framewindowing.cpp \
+ libSACenc/src/sacenc_huff_tab.cpp \
+ libSACenc/src/sacenc_lib.cpp \
+ libSACenc/src/sacenc_nlc_enc.cpp \
+ libSACenc/src/sacenc_onsetdetect.cpp \
+ libSACenc/src/sacenc_paramextract.cpp \
+ libSACenc/src/sacenc_staticgain.cpp \
+ libSACenc/src/sacenc_tree.cpp \
+ libSACenc/src/sacenc_vectorfunctions.cpp
+
+SBRDEC_SRC = \
+ libSBRdec/src/HFgen_preFlat.cpp \
+ libSBRdec/src/env_calc.cpp \
+ libSBRdec/src/env_dec.cpp \
+ libSBRdec/src/env_extr.cpp \
+ libSBRdec/src/hbe.cpp \
+ libSBRdec/src/huff_dec.cpp \
+ libSBRdec/src/lpp_tran.cpp \
+ libSBRdec/src/psbitdec.cpp \
+ libSBRdec/src/psdec.cpp \
+ libSBRdec/src/psdec_drm.cpp \
+ libSBRdec/src/psdecrom_drm.cpp \
+ libSBRdec/src/pvc_dec.cpp \
+ libSBRdec/src/sbr_crc.cpp \
+ libSBRdec/src/sbr_deb.cpp \
+ libSBRdec/src/sbr_dec.cpp \
+ libSBRdec/src/sbr_ram.cpp \
+ libSBRdec/src/sbr_rom.cpp \
+ libSBRdec/src/sbrdec_drc.cpp \
+ libSBRdec/src/sbrdec_freq_sca.cpp \
+ libSBRdec/src/sbrdecoder.cpp
+
+SBRENC_SRC = \
+ libSBRenc/src/bit_sbr.cpp \
+ libSBRenc/src/code_env.cpp \
+ libSBRenc/src/env_bit.cpp \
+ libSBRenc/src/env_est.cpp \
+ libSBRenc/src/fram_gen.cpp \
+ libSBRenc/src/invf_est.cpp \
+ libSBRenc/src/mh_det.cpp \
+ libSBRenc/src/nf_est.cpp \
+ libSBRenc/src/ps_bitenc.cpp \
+ libSBRenc/src/ps_encode.cpp \
+ libSBRenc/src/ps_main.cpp \
+ libSBRenc/src/resampler.cpp \
+ libSBRenc/src/sbr_encoder.cpp \
+ libSBRenc/src/sbr_misc.cpp \
+ libSBRenc/src/sbrenc_freq_sca.cpp \
+ libSBRenc/src/sbrenc_ram.cpp \
+ libSBRenc/src/sbrenc_rom.cpp \
+ libSBRenc/src/ton_corr.cpp \
+ libSBRenc/src/tran_det.cpp
+
+SYS_SRC = \
+ libSYS/src/genericStds.cpp \
+ libSYS/src/syslib_channelMapDescr.cpp
+
+libfdk_aac_SOURCES = \
+ $(AACDEC_SRC) $(AACENC_SRC) \
+ $(ARITHCODING_SRC) \
+ $(DRCDEC_SRC) \
+ $(MPEGTPDEC_SRC) $(MPEGTPENC_SRC) \
+ $(SACDEC_SRC) $(SACENC_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 libArithCoding\src\*.obj 2>NUL
+ del /f libDRCdec\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 libSACdec\src\*.obj 2>NUL
+ del /f libSACenc\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 libSYS\include\syslib_channelMapDescr.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)
diff --git a/fdk-aac/NOTICE b/fdk-aac/NOTICE
new file mode 100644
index 0000000..05b32bd
--- /dev/null
+++ b/fdk-aac/NOTICE
@@ -0,0 +1,92 @@
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+
diff --git a/fdk-aac/OWNERS b/fdk-aac/OWNERS
new file mode 100644
index 0000000..ffd753e
--- /dev/null
+++ b/fdk-aac/OWNERS
@@ -0,0 +1,2 @@
+jmtrivi@google.com
+gkasten@android.com
diff --git a/fdk-aac/README.md b/fdk-aac/README.md
new file mode 100644
index 0000000..d427e96
--- /dev/null
+++ b/fdk-aac/README.md
@@ -0,0 +1,7 @@
+A patched version of fdk-aac with DAB+ support
+==============================================
+
+This is a modified version of fdk-aac that supports the AOTs
+required for DAB+ encoding.
+
+See http://www.opendigitalradio.org for more
diff --git a/fdk-aac/aac-enc.c b/fdk-aac/aac-enc.c
new file mode 100644
index 0000000..c90ff12
--- /dev/null
+++ b/fdk-aac/aac-enc.c
@@ -0,0 +1,237 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 2011 Martin Storsjo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ * -------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#if defined(_MSC_VER)
+#include <getopt.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <stdlib.h>
+#include "libAACenc/include/aacenc_lib.h"
+#include "wavreader.h"
+
+void usage(const char* name) {
+ fprintf(stderr, "%s [-r bitrate] [-t aot] [-a afterburner] [-s sbr] [-v vbr] in.wav out.aac\n", name);
+ fprintf(stderr, "Supported AOTs:\n");
+ fprintf(stderr, "\t2\tAAC-LC\n");
+ fprintf(stderr, "\t5\tHE-AAC\n");
+ fprintf(stderr, "\t29\tHE-AAC v2\n");
+ fprintf(stderr, "\t23\tAAC-LD\n");
+ fprintf(stderr, "\t39\tAAC-ELD\n");
+}
+
+int main(int argc, char *argv[]) {
+ int bitrate = 64000;
+ int ch;
+ const char *infile, *outfile;
+ FILE *out;
+ void *wav;
+ int format, sample_rate, channels, bits_per_sample;
+ int input_size;
+ uint8_t* input_buf;
+ int16_t* convert_buf;
+ int aot = 2;
+ int afterburner = 1;
+ int eld_sbr = 0;
+ int vbr = 0;
+ HANDLE_AACENCODER handle;
+ CHANNEL_MODE mode;
+ AACENC_InfoStruct info = { 0 };
+ while ((ch = getopt(argc, argv, "r:t:a:s:v:")) != -1) {
+ switch (ch) {
+ case 'r':
+ bitrate = atoi(optarg);
+ break;
+ case 't':
+ aot = atoi(optarg);
+ break;
+ case 'a':
+ afterburner = atoi(optarg);
+ break;
+ case 's':
+ eld_sbr = atoi(optarg);
+ break;
+ case 'v':
+ vbr = atoi(optarg);
+ break;
+ case '?':
+ default:
+ usage(argv[0]);
+ return 1;
+ }
+ }
+ if (argc - optind < 2) {
+ usage(argv[0]);
+ return 1;
+ }
+ infile = argv[optind];
+ outfile = argv[optind + 1];
+
+ wav = wav_read_open(infile);
+ if (!wav) {
+ fprintf(stderr, "Unable to open wav file %s\n", infile);
+ return 1;
+ }
+ if (!wav_get_header(wav, &format, &channels, &sample_rate, &bits_per_sample, NULL)) {
+ fprintf(stderr, "Bad wav file %s\n", infile);
+ return 1;
+ }
+ if (format != 1) {
+ fprintf(stderr, "Unsupported WAV format %d\n", format);
+ return 1;
+ }
+ if (bits_per_sample != 16) {
+ fprintf(stderr, "Unsupported WAV sample depth %d\n", bits_per_sample);
+ return 1;
+ }
+ switch (channels) {
+ case 1: mode = MODE_1; break;
+ case 2: mode = MODE_2; break;
+ case 3: mode = MODE_1_2; break;
+ case 4: mode = MODE_1_2_1; break;
+ case 5: mode = MODE_1_2_2; break;
+ case 6: mode = MODE_1_2_2_1; break;
+ default:
+ fprintf(stderr, "Unsupported WAV channels %d\n", channels);
+ return 1;
+ }
+ if (aacEncOpen(&handle, 0, channels) != AACENC_OK) {
+ fprintf(stderr, "Unable to open encoder\n");
+ return 1;
+ }
+ if (aacEncoder_SetParam(handle, AACENC_AOT, aot) != AACENC_OK) {
+ fprintf(stderr, "Unable to set the AOT\n");
+ return 1;
+ }
+ if (aot == 39 && eld_sbr) {
+ if (aacEncoder_SetParam(handle, AACENC_SBR_MODE, 1) != AACENC_OK) {
+ fprintf(stderr, "Unable to set SBR mode for ELD\n");
+ return 1;
+ }
+ }
+ if (aacEncoder_SetParam(handle, AACENC_SAMPLERATE, sample_rate) != AACENC_OK) {
+ fprintf(stderr, "Unable to set the AOT\n");
+ return 1;
+ }
+ if (aacEncoder_SetParam(handle, AACENC_CHANNELMODE, mode) != AACENC_OK) {
+ fprintf(stderr, "Unable to set the channel mode\n");
+ return 1;
+ }
+ if (aacEncoder_SetParam(handle, AACENC_CHANNELORDER, 1) != AACENC_OK) {
+ fprintf(stderr, "Unable to set the wav channel order\n");
+ return 1;
+ }
+ if (vbr) {
+ if (aacEncoder_SetParam(handle, AACENC_BITRATEMODE, vbr) != AACENC_OK) {
+ fprintf(stderr, "Unable to set the VBR bitrate mode\n");
+ return 1;
+ }
+ } else {
+ if (aacEncoder_SetParam(handle, AACENC_BITRATE, bitrate) != AACENC_OK) {
+ fprintf(stderr, "Unable to set the bitrate\n");
+ return 1;
+ }
+ }
+ if (aacEncoder_SetParam(handle, AACENC_TRANSMUX, TT_MP4_ADTS) != AACENC_OK) {
+ fprintf(stderr, "Unable to set the ADTS transmux\n");
+ return 1;
+ }
+ if (aacEncoder_SetParam(handle, AACENC_AFTERBURNER, afterburner) != AACENC_OK) {
+ fprintf(stderr, "Unable to set the afterburner mode\n");
+ return 1;
+ }
+ if (aacEncEncode(handle, NULL, NULL, NULL, NULL) != AACENC_OK) {
+ fprintf(stderr, "Unable to initialize the encoder\n");
+ return 1;
+ }
+ if (aacEncInfo(handle, &info) != AACENC_OK) {
+ fprintf(stderr, "Unable to get the encoder info\n");
+ return 1;
+ }
+
+ out = fopen(outfile, "wb");
+ if (!out) {
+ perror(outfile);
+ return 1;
+ }
+
+ input_size = channels*2*info.frameLength;
+ input_buf = (uint8_t*) malloc(input_size);
+ convert_buf = (int16_t*) malloc(input_size);
+
+ while (1) {
+ AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 };
+ AACENC_InArgs in_args = { 0 };
+ AACENC_OutArgs out_args = { 0 };
+ int in_identifier = IN_AUDIO_DATA;
+ int in_size, in_elem_size;
+ int out_identifier = OUT_BITSTREAM_DATA;
+ int out_size, out_elem_size;
+ int read, i;
+ void *in_ptr, *out_ptr;
+ uint8_t outbuf[20480];
+ AACENC_ERROR err;
+
+ read = wav_read_data(wav, input_buf, input_size);
+ for (i = 0; i < read/2; i++) {
+ const uint8_t* in = &input_buf[2*i];
+ convert_buf[i] = in[0] | (in[1] << 8);
+ }
+ in_ptr = convert_buf;
+ in_size = read;
+ in_elem_size = 2;
+
+ in_args.numInSamples = read <= 0 ? -1 : read/2;
+ in_buf.numBufs = 1;
+ in_buf.bufs = &in_ptr;
+ in_buf.bufferIdentifiers = &in_identifier;
+ in_buf.bufSizes = &in_size;
+ in_buf.bufElSizes = &in_elem_size;
+
+ out_ptr = outbuf;
+ out_size = sizeof(outbuf);
+ out_elem_size = 1;
+ out_buf.numBufs = 1;
+ out_buf.bufs = &out_ptr;
+ out_buf.bufferIdentifiers = &out_identifier;
+ out_buf.bufSizes = &out_size;
+ out_buf.bufElSizes = &out_elem_size;
+
+ if ((err = aacEncEncode(handle, &in_buf, &out_buf, &in_args, &out_args)) != AACENC_OK) {
+ if (err == AACENC_ENCODE_EOF)
+ break;
+ fprintf(stderr, "Encoding failed\n");
+ return 1;
+ }
+ if (out_args.numOutBytes == 0)
+ continue;
+ fwrite(outbuf, 1, out_args.numOutBytes, out);
+ }
+ free(input_buf);
+ free(convert_buf);
+ fclose(out);
+ wav_read_close(wav);
+ aacEncClose(&handle);
+
+ return 0;
+}
+
diff --git a/fdk-aac/autogen.sh b/fdk-aac/autogen.sh
new file mode 100755
index 0000000..210ccb8
--- /dev/null
+++ b/fdk-aac/autogen.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+autoreconf -fiv
diff --git a/fdk-aac/bootstrap b/fdk-aac/bootstrap
new file mode 100755
index 0000000..a3394ab
--- /dev/null
+++ b/fdk-aac/bootstrap
@@ -0,0 +1,4 @@
+#! /bin/sh
+
+autoreconf --install && \
+ echo "You can call ./configure now"
diff --git a/fdk-aac/configure.ac b/fdk-aac/configure.ac
new file mode 100644
index 0000000..9c714d7
--- /dev/null
+++ b/fdk-aac/configure.ac
@@ -0,0 +1,38 @@
+dnl -*- Autoconf -*-
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT([fdk-aac], [2.0.0], [http://sourceforge.net/projects/opencore-amr/])
+AC_CONFIG_AUX_DIR(.)
+AC_CONFIG_MACRO_DIR([m4])
+AM_INIT_AUTOMAKE([tar-ustar foreign])
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+dnl Various options for configure
+AC_ARG_ENABLE([example],
+ [AS_HELP_STRING([--enable-example],
+ [enable example encoding program (default is no)])],
+ [example=$enableval], [example=no])
+
+dnl Automake conditionals to set
+AM_CONDITIONAL(EXAMPLE, test x$example = xyes)
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_CXX
+LT_INIT
+
+AC_SEARCH_LIBS([sin], [m])
+
+dnl soname version to use
+dnl goes by ‘current[:revision[:age]]’ with the soname ending up as
+dnl current.age.revision
+FDK_AAC_VERSION=2:0:0
+
+AS_IF([test x$enable_shared = xyes], [LIBS_PRIVATE=$LIBS], [LIBS_PUBLIC=$LIBS])
+AC_SUBST(FDK_AAC_VERSION)
+AC_SUBST(LIBS_PUBLIC)
+AC_SUBST(LIBS_PRIVATE)
+
+AC_CONFIG_FILES([Makefile
+ fdk-aac.pc])
+AC_OUTPUT
diff --git a/fdk-aac/documentation/aacDecoder.pdf b/fdk-aac/documentation/aacDecoder.pdf
new file mode 100644
index 0000000..1dec334
--- /dev/null
+++ b/fdk-aac/documentation/aacDecoder.pdf
Binary files differ
diff --git a/fdk-aac/documentation/aacEncoder.pdf b/fdk-aac/documentation/aacEncoder.pdf
new file mode 100644
index 0000000..e438e27
--- /dev/null
+++ b/fdk-aac/documentation/aacEncoder.pdf
Binary files differ
diff --git a/fdk-aac/fdk-aac.pc.in b/fdk-aac/fdk-aac.pc.in
new file mode 100644
index 0000000..2edac45
--- /dev/null
+++ b/fdk-aac/fdk-aac.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Fraunhofer FDK AAC Codec Library
+Description: AAC codec library
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lfdk-aac @LIBS_PUBLIC@
+Libs.private: @LIBS_PRIVATE@
+Cflags: -I${includedir}
diff --git a/fdk-aac/fdk-aac.sym b/fdk-aac/fdk-aac.sym
new file mode 100644
index 0000000..2a06c41
--- /dev/null
+++ b/fdk-aac/fdk-aac.sym
@@ -0,0 +1,18 @@
+aacDecoder_AncDataGet
+aacDecoder_AncDataInit
+aacDecoder_Close
+aacDecoder_ConfigRaw
+aacDecoder_DecodeFrame
+aacDecoder_Fill
+aacDecoder_GetFreeBytes
+aacDecoder_GetLibInfo
+aacDecoder_GetStreamInfo
+aacDecoder_Open
+aacDecoder_SetParam
+aacEncClose
+aacEncEncode
+aacEncGetLibInfo
+aacEncInfo
+aacEncOpen
+aacEncoder_GetParam
+aacEncoder_SetParam
diff --git a/fdk-aac/libAACdec/include/aacdecoder_lib.h b/fdk-aac/libAACdec/include/aacdecoder_lib.h
new file mode 100644
index 0000000..5f0dd02
--- /dev/null
+++ b/fdk-aac/libAACdec/include/aacdecoder_lib.h
@@ -0,0 +1,1090 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef AACDECODER_LIB_H
+#define AACDECODER_LIB_H
+
+/**
+ * \file aacdecoder_lib.h
+ * \brief FDK AAC decoder library interface header file.
+ *
+
+\page INTRO Introduction
+
+
+\section SCOPE Scope
+
+This document describes the high-level application interface and usage of the
+ISO/MPEG-2/4 AAC Decoder library developed by the Fraunhofer Institute for
+Integrated Circuits (IIS). Depending on the library configuration, decoding of
+AAC-LC (Low-Complexity), HE-AAC (High-Efficiency AAC v1 and v2), AAC-LD
+(Low-Delay) and AAC-ELD (Enhanced Low-Delay) is implemented.
+
+All references to SBR (Spectral Band Replication) are only applicable to HE-AAC
+and AAC-ELD configurations of the FDK library. All references to PS (Parametric
+Stereo) are only applicable to HE-AAC v2 decoder configuration of the library.
+
+\section DecoderBasics Decoder Basics
+
+This document can only give a rough overview about the ISO/MPEG-2, ISO/MPEG-4
+AAC audio and MPEG-D USAC coding standards. To understand all details referenced
+in this document, you are encouraged to read the following documents.
+
+- ISO/IEC 13818-7 (MPEG-2 AAC) Standard, defines the syntax of MPEG-2 AAC audio
+bitstreams.
+- ISO/IEC 14496-3 (MPEG-4 AAC, subpart 1 and 4) Standard, defines the syntax of
+MPEG-4 AAC audio bitstreams.
+- ISO/IEC 23003-3 (MPEG-D USAC), defines MPEG-D USAC unified speech and audio
+codec.
+- Lutzky, Schuller, Gayer, Kr&auml;mer, Wabnik, "A guideline to audio codec
+delay", 116th AES Convention, May 8, 2004
+
+In short, MPEG Advanced Audio Coding is based on a time-to-frequency mapping of
+the signal. The signal is partitioned into overlapping time portions and
+transformed into frequency domain. The spectral components are then quantized
+and coded using a highly efficient coding scheme.\n Encoded MPEG-2 and MPEG-4
+AAC audio bitstreams are composed of frames. Contrary to MPEG-1/2 Layer-3 (mp3),
+the length of individual frames is not restricted to a fixed number of bytes,
+but can take any length between 1 and 768 bytes.
+
+In addition to the above mentioned frequency domain coding mode, MPEG-D USAC
+also employs a time domain Algebraic Code-Excited Linear Prediction (ACELP)
+speech coder core. This operating mode is selected by the encoder in order to
+achieve the optimum audio quality for different content type. Several
+enhancements allow achieving higher quality at lower bit rates compared to
+MPEG-4 HE-AAC.
+
+
+\page LIBUSE Library Usage
+
+
+\section InterfaceDescritpion API Description
+
+All API header files are located in the folder /include of the release package.
+The contents of each file is described in detail in this document. All header
+files are provided for usage in specific C/C++ programs. The main AAC decoder
+library API functions are located in aacdecoder_lib.h header file.
+
+In binary releases the decoder core resides in statically linkable libraries,
+for example libAACdec.a.
+
+
+\section Calling_Sequence Calling Sequence
+
+The following sequence is necessary for proper decoding of ISO/MPEG-2/4 AAC,
+HE-AAC v2, or MPEG-D USAC bitstreams. In the following description, input stream
+read and output write function details are left out, since they may be
+implemented in a variety of configurations depending on the user's specific
+requirements. The example implementation uses file-based input/output, and in
+such case one may call mpegFileRead_Open() to open an input file and to allocate
+memory for the required structures, and the corresponding mpegFileRead_Close()
+to close opened files and to de-allocate associated structures.
+mpegFileRead_Open() will attempt to detect the bitstream format and in case of
+MPEG-4 file format or Raw Packets file format (a proprietary Fraunhofer IIS file
+format suitable only for testing) it will read the Audio Specific Config data
+(ASC). An unsuccessful attempt to recognize the bitstream format requires the
+user to provide this information manually. For any other bitstream formats that
+are usually applicable in streaming applications, the decoder itself will try to
+synchronize and parse the given bitstream fragment using the FDK transport
+library. Hence, for streaming applications (without file access) this step is
+not necessary.
+
+
+-# Call aacDecoder_Open() to open and retrieve a handle to a new AAC decoder
+instance. \code aacDecoderInfo = aacDecoder_Open(transportType, nrOfLayers);
+\endcode
+-# If out-of-band config data (Audio Specific Config (ASC) or Stream Mux Config
+(SMC)) is available, call aacDecoder_ConfigRaw() to pass this data to the
+decoder before beginning the decoding process. If this data is not available in
+advance, the decoder will configure itself while decoding, during the
+aacDecoder_DecodeFrame() function call.
+-# Begin decoding loop.
+\code
+do {
+\endcode
+-# Read data from bitstream file or stream buffer in to the driver program
+working memory (a client-supplied input buffer "inBuffer" in framework). This
+buffer will be used to load AAC bitstream data to the decoder. Only when all
+data in this buffer has been processed will the decoder signal an empty buffer.
+For file-based input, you may invoke mpegFileRead_Read() to acquire new
+bitstream data.
+-# Call aacDecoder_Fill() to fill the decoder's internal bitstream input buffer
+with the client-supplied bitstream input buffer. Note, if the data loaded in to
+the internal buffer is not sufficient to decode a frame,
+aacDecoder_DecodeFrame() will return ::AAC_DEC_NOT_ENOUGH_BITS until a
+sufficient amount of data is loaded in to the internal buffer. For streaming
+formats (ADTS, LOAS), it is acceptable to load more than one frame to the
+decoder. However, for RAW file format (Fraunhofer IIS proprietary format), only
+one frame may be loaded to the decoder per aacDecoder_DecodeFrame() call. For
+least amount of communication delay, fill and decode should be performed on a
+frame by frame basis. \code ErrorStatus = aacDecoder_Fill(aacDecoderInfo,
+inBuffer, bytesRead, bytesValid); \endcode
+-# Call aacDecoder_DecodeFrame(). This function decodes one frame and writes
+decoded PCM audio data to a client-supplied buffer. It is the client's
+responsibility to allocate a buffer which is large enough to hold the decoded
+output data. \code ErrorStatus = aacDecoder_DecodeFrame(aacDecoderInfo,
+TimeData, OUT_BUF_SIZE, flags); \endcode If the bitstream configuration (number
+of channels, sample rate, frame size) is not known a priori, you may call
+aacDecoder_GetStreamInfo() to retrieve a structure that contains this
+information. You may use this data to initialize an audio output device. In the
+example program, if the number of channels or the sample rate has changed since
+program start or the previously decoded frame, the audio output device is then
+re-initialized. If WAVE file output is chosen, a new WAVE file for each new
+stream configuration is be created. \code p_si =
+aacDecoder_GetStreamInfo(aacDecoderInfo); \endcode
+-# Repeat steps 5 to 7 until no data is available to decode any more, or in case
+of error. \code } while (bytesRead[0] > 0 || doFlush || doBsFlush ||
+forceContinue); \endcode
+-# Call aacDecoder_Close() to de-allocate all AAC decoder and transport layer
+structures. \code aacDecoder_Close(aacDecoderInfo); \endcode
+
+\image latex decode.png "Decode calling sequence" width=11cm
+
+\image latex change_source.png "Change data source sequence" width 5cm
+
+\image latex conceal.png "Error concealment sequence" width=14cm
+
+\subsection Error_Concealment_Sequence Error Concealment Sequence
+
+There are different strategies to handle bit stream errors. Depending on the
+system properties the product designer might choose to take different actions in
+case a bit error occurs. In many cases the decoder might be able to do
+reasonable error concealment without the need of any additional actions from the
+system. But in some cases its not even possible to know how many decoded PCM
+output samples are required to fill the gap due to the data error, then the
+software surrounding the decoder must deal with the situation. The most simple
+way would be to just stop audio playback and resume once enough bit stream data
+and/or buffered output samples are available. More sophisticated designs might
+also be able to deal with sender/receiver clock drifts or data drop outs by
+using a closed loop control of FIFO fulness levels. The chosen strategy depends
+on the final product requirements.
+
+The error concealment sequence diagram illustrates the general execution paths
+for error handling.
+
+The macro IS_OUTPUT_VALID(err) can be used to identify if the audio output
+buffer contains valid audio either from error free bit stream data or successful
+error concealment. In case the result is false, the decoder output buffer does
+not contain meaningful audio samples and should not be passed to any output as
+it is. Most likely in case that a continuous audio output PCM stream is
+required, the output buffer must be filled with audio data from the calling
+framework. This might be e.g. an appropriate number of samples all zero.
+
+If error code ::AAC_DEC_TRANSPORT_SYNC_ERROR is returned by the decoder, under
+some particular conditions it is possible to estimate lost frames due to the bit
+stream error. In that case the bit stream is required to have a constant
+bitrate, and compatible transport type. Audio samples for the lost frames can be
+obtained by calling aacDecoder_DecodeFrame() with flag ::AACDEC_CONCEAL set
+n-times where n is the count of lost frames. Please note that the decoder has to
+have encountered valid configuration data at least once to be able to generate
+concealed data, because at the minimum the sampling rate, frame size and amount
+of audio channels needs to be known.
+
+If it is not possible to get an estimation of lost frames then a constant
+fullness of the audio output buffer can be achieved by implementing different
+FIFO control techniques e.g. just stop taking of samples from the buffer to
+avoid underflow or stop filling new data to the buffer to avoid overflow. But
+this techniques are out of scope of this document.
+
+For a detailed description of a specific error code please refer also to
+::AAC_DECODER_ERROR.
+
+\section BufferSystem Buffer System
+
+There are three main buffers in an AAC decoder application. One external input
+buffer to hold bitstream data from file I/O or elsewhere, one decoder-internal
+input buffer, and one to hold the decoded output PCM sample data. In resource
+limited applications, the output buffer may be reused as an external input
+buffer prior to the subsequence aacDecoder_Fill() function call.
+
+The external input buffer is set in the example program and its size is defined
+by ::IN_BUF_SIZE. You may freely choose different buffer sizes. To feed the data
+to the decoder-internal input buffer, use the function aacDecoder_Fill(). This
+function returns important information regarding the number of bytes in the
+external input buffer that have not yet been copied into the internal input
+buffer (variable bytesValid). Once the external buffer has been fully copied, it
+can be completely re-filled again. In case you wish to refill the buffer while
+there are unprocessed bytes (bytesValid is unequal 0), you should preserve the
+unconsumed data. However, we recommend to refill the buffer only when bytesValid
+returns 0.
+
+The bytesValid parameter is an input and output parameter to the FDK decoder. As
+an input, it signals how many valid bytes are available in the external buffer.
+After consumption of the external buffer using aacDecoder_Fill() function, the
+bytesValid parameter indicates if any of the bytes in the external buffer were
+not consumed.
+
+\image latex dec_buffer.png "Life cycle of the external input buffer" width=9cm
+
+\page OutputFormat Decoder audio output
+
+\section OutputFormatObtaining Obtaining channel mapping information
+
+The decoded audio output format is indicated by a set of variables of the
+CStreamInfo structure. While the struct members sampleRate, frameSize and
+numChannels might be self explanatory, pChannelType and pChannelIndices require
+some further explanation.
+
+These two arrays indicate the configuration of channel data within the output
+buffer. Both arrays have CStreamInfo::numChannels number of cells. Each cell of
+pChannelType indicates the channel type, which is described in the enum
+::AUDIO_CHANNEL_TYPE (defined in FDK_audio.h). The cells of pChannelIndices
+indicate the sub index among the channels starting with 0 among channels of the
+same audio channel type.
+
+The indexing scheme is structured as defined in MPEG-2/4 Standards. Indices
+start from the front direction (a center channel if available, will always be
+index 0) and increment, starting with the left side, pairwise (e.g. L, R) and
+from front to back (Front L, Front R, Surround L, Surround R). For detailed
+explanation, please refer to ISO/IEC 13818-7:2005(E), chapter 8.5.3.2.
+
+In case a Program Config is included in the audio configuration, the channel
+mapping described within it will be adopted.
+
+In case of MPEG-D Surround the channel mapping will follow the same criteria
+described in ISO/IEC 13818-7:2005(E), but adding corresponding top channels (if
+available) to the channel types in order to avoid ambiguity. The examples below
+explain these aspects in detail.
+
+\section OutputFormatChange Changing the audio output format
+
+For MPEG-4 audio the channel order can be changed at runtime through the
+parameter
+::AAC_PCM_OUTPUT_CHANNEL_MAPPING. See the description of those
+parameters and the decoder library function aacDecoder_SetParam() for more
+detail.
+
+\section OutputFormatExample Channel mapping examples
+
+The following examples illustrate the location of individual audio samples in
+the audio buffer that is passed to aacDecoder_DecodeFrame() and the expected
+data in the CStreamInfo structure which can be obtained by calling
+aacDecoder_GetStreamInfo().
+
+\subsection ExamplesStereo Stereo
+
+In case of ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1,
+a AAC-LC bit stream which has channelConfiguration = 2 in its audio specific
+config would lead to the following values in CStreamInfo:
+
+CStreamInfo::numChannels = 2
+
+CStreamInfo::pChannelType = { ::ACT_FRONT, ::ACT_FRONT }
+
+CStreamInfo::pChannelIndices = { 0, 1 }
+
+The output buffer will be formatted as follows:
+
+\verbatim
+ <left sample 0> <left sample 1> <left sample 2> ... <left sample N>
+ <right sample 0> <right sample 1> <right sample 2> ... <right sample N>
+\endverbatim
+
+Where N equals to CStreamInfo::frameSize .
+
+\subsection ExamplesSurround Surround 5.1
+
+In case of ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1,
+a AAC-LC bit stream which has channelConfiguration = 6 in its audio specific
+config, would lead to the following values in CStreamInfo:
+
+CStreamInfo::numChannels = 6
+
+CStreamInfo::pChannelType = { ::ACT_FRONT, ::ACT_FRONT, ::ACT_FRONT, ::ACT_LFE,
+::ACT_BACK, ::ACT_BACK }
+
+CStreamInfo::pChannelIndices = { 1, 2, 0, 0, 0, 1 }
+
+Since ::AAC_PCM_OUTPUT_CHANNEL_MAPPING is 1, WAV file channel ordering will be
+used. For a 5.1 channel scheme, thus the channels would be: front left, front
+right, center, LFE, surround left, surround right. Thus the third channel is the
+center channel, receiving the index 0. The other front channels are front left,
+front right being placed as first and second channels with indices 1 and 2
+correspondingly. There is only one LFE, placed as the fourth channel and index
+0. Finally both surround channels get the type definition ACT_BACK, and the
+indices 0 and 1.
+
+The output buffer will be formatted as follows:
+
+\verbatim
+<front left sample 0> <front right sample 0>
+<center sample 0> <LFE sample 0>
+<surround left sample 0> <surround right sample 0>
+
+<front left sample 1> <front right sample 1>
+<center sample 1> <LFE sample 1>
+<surround left sample 1> <surround right sample 1>
+
+...
+
+<front left sample N> <front right sample N>
+<center sample N> <LFE sample N>
+<surround left sample N> <surround right sample N>
+\endverbatim
+
+Where N equals to CStreamInfo::frameSize .
+
+\subsection ExamplesArib ARIB coding mode 2/1
+
+In case of ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1,
+in case of a ARIB bit stream using coding mode 2/1 as described in ARIB STD-B32
+Part 2 Version 2.1-E1, page 61, would lead to the following values in
+CStreamInfo:
+
+CStreamInfo::numChannels = 3
+
+CStreamInfo::pChannelType = { ::ACT_FRONT, ::ACT_FRONT, ::ACT_BACK }
+
+CStreamInfo::pChannelIndices = { 0, 1, 0 }
+
+The audio channels will be placed as follows in the audio output buffer:
+
+\verbatim
+<front left sample 0> <front right sample 0> <mid surround sample 0>
+
+<front left sample 1> <front right sample 1> <mid surround sample 1>
+
+...
+
+<front left sample N> <front right sample N> <mid surround sample N>
+
+Where N equals to CStreamInfo::frameSize .
+
+\endverbatim
+
+*/
+
+#include "machine_type.h"
+#include "FDK_audio.h"
+
+#include "genericStds.h"
+
+#define AACDECODER_LIB_VL0 3
+#define AACDECODER_LIB_VL1 0
+#define AACDECODER_LIB_VL2 0
+
+/**
+ * \brief AAC decoder error codes.
+ */
+typedef enum {
+ AAC_DEC_OK =
+ 0x0000, /*!< No error occurred. Output buffer is valid and error free. */
+ AAC_DEC_OUT_OF_MEMORY =
+ 0x0002, /*!< Heap returned NULL pointer. Output buffer is invalid. */
+ AAC_DEC_UNKNOWN =
+ 0x0005, /*!< Error condition is of unknown reason, or from a another
+ module. Output buffer is invalid. */
+
+ /* Synchronization errors. Output buffer is invalid. */
+ aac_dec_sync_error_start = 0x1000,
+ AAC_DEC_TRANSPORT_SYNC_ERROR = 0x1001, /*!< The transport decoder had
+ synchronization problems. Do not
+ exit decoding. Just feed new
+ bitstream data. */
+ AAC_DEC_NOT_ENOUGH_BITS = 0x1002, /*!< The input buffer ran out of bits. */
+ aac_dec_sync_error_end = 0x1FFF,
+
+ /* Initialization errors. Output buffer is invalid. */
+ aac_dec_init_error_start = 0x2000,
+ AAC_DEC_INVALID_HANDLE =
+ 0x2001, /*!< The handle passed to the function call was invalid (NULL). */
+ AAC_DEC_UNSUPPORTED_AOT =
+ 0x2002, /*!< The AOT found in the configuration is not supported. */
+ AAC_DEC_UNSUPPORTED_FORMAT =
+ 0x2003, /*!< The bitstream format is not supported. */
+ AAC_DEC_UNSUPPORTED_ER_FORMAT =
+ 0x2004, /*!< The error resilience tool format is not supported. */
+ AAC_DEC_UNSUPPORTED_EPCONFIG =
+ 0x2005, /*!< The error protection format is not supported. */
+ AAC_DEC_UNSUPPORTED_MULTILAYER =
+ 0x2006, /*!< More than one layer for AAC scalable is not supported. */
+ AAC_DEC_UNSUPPORTED_CHANNELCONFIG =
+ 0x2007, /*!< The channel configuration (either number or arrangement) is
+ not supported. */
+ AAC_DEC_UNSUPPORTED_SAMPLINGRATE = 0x2008, /*!< The sample rate specified in
+ the configuration is not
+ supported. */
+ AAC_DEC_INVALID_SBR_CONFIG =
+ 0x2009, /*!< The SBR configuration is not supported. */
+ AAC_DEC_SET_PARAM_FAIL = 0x200A, /*!< The parameter could not be set. Either
+ the value was out of range or the
+ parameter does not exist. */
+ AAC_DEC_NEED_TO_RESTART = 0x200B, /*!< The decoder needs to be restarted,
+ since the required configuration change
+ cannot be performed. */
+ AAC_DEC_OUTPUT_BUFFER_TOO_SMALL =
+ 0x200C, /*!< The provided output buffer is too small. */
+ aac_dec_init_error_end = 0x2FFF,
+
+ /* Decode errors. Output buffer is valid but concealed. */
+ aac_dec_decode_error_start = 0x4000,
+ AAC_DEC_TRANSPORT_ERROR =
+ 0x4001, /*!< The transport decoder encountered an unexpected error. */
+ AAC_DEC_PARSE_ERROR = 0x4002, /*!< Error while parsing the bitstream. Most
+ probably it is corrupted, or the system
+ crashed. */
+ AAC_DEC_UNSUPPORTED_EXTENSION_PAYLOAD =
+ 0x4003, /*!< Error while parsing the extension payload of the bitstream.
+ The extension payload type found is not supported. */
+ AAC_DEC_DECODE_FRAME_ERROR = 0x4004, /*!< The parsed bitstream value is out of
+ range. Most probably the bitstream is
+ corrupt, or the system crashed. */
+ AAC_DEC_CRC_ERROR = 0x4005, /*!< The embedded CRC did not match. */
+ AAC_DEC_INVALID_CODE_BOOK = 0x4006, /*!< An invalid codebook was signaled.
+ Most probably the bitstream is corrupt,
+ or the system crashed. */
+ AAC_DEC_UNSUPPORTED_PREDICTION =
+ 0x4007, /*!< Predictor found, but not supported in the AAC Low Complexity
+ profile. Most probably the bitstream is corrupt, or has a wrong
+ format. */
+ AAC_DEC_UNSUPPORTED_CCE = 0x4008, /*!< A CCE element was found which is not
+ supported. Most probably the bitstream is
+ corrupt, or has a wrong format. */
+ AAC_DEC_UNSUPPORTED_LFE = 0x4009, /*!< A LFE element was found which is not
+ supported. Most probably the bitstream is
+ corrupt, or has a wrong format. */
+ AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA =
+ 0x400A, /*!< Gain control data found but not supported. Most probably the
+ bitstream is corrupt, or has a wrong format. */
+ AAC_DEC_UNSUPPORTED_SBA =
+ 0x400B, /*!< SBA found, but currently not supported in the BSAC profile.
+ */
+ AAC_DEC_TNS_READ_ERROR = 0x400C, /*!< Error while reading TNS data. Most
+ probably the bitstream is corrupt or the
+ system crashed. */
+ AAC_DEC_RVLC_ERROR =
+ 0x400D, /*!< Error while decoding error resilient data. */
+ aac_dec_decode_error_end = 0x4FFF,
+ /* Ancillary data errors. Output buffer is valid. */
+ aac_dec_anc_data_error_start = 0x8000,
+ AAC_DEC_ANC_DATA_ERROR =
+ 0x8001, /*!< Non severe error concerning the ancillary data handling. */
+ AAC_DEC_TOO_SMALL_ANC_BUFFER = 0x8002, /*!< The registered ancillary data
+ buffer is too small to receive the
+ parsed data. */
+ AAC_DEC_TOO_MANY_ANC_ELEMENTS = 0x8003, /*!< More than the allowed number of
+ ancillary data elements should be
+ written to buffer. */
+ aac_dec_anc_data_error_end = 0x8FFF
+
+} AAC_DECODER_ERROR;
+
+/** Macro to identify initialization errors. Output buffer is invalid. */
+#define IS_INIT_ERROR(err) \
+ ((((err) >= aac_dec_init_error_start) && ((err) <= aac_dec_init_error_end)) \
+ ? 1 \
+ : 0)
+/** Macro to identify decode errors. Output buffer is valid but concealed. */
+#define IS_DECODE_ERROR(err) \
+ ((((err) >= aac_dec_decode_error_start) && \
+ ((err) <= aac_dec_decode_error_end)) \
+ ? 1 \
+ : 0)
+/**
+ * Macro to identify if the audio output buffer contains valid samples after
+ * calling aacDecoder_DecodeFrame(). Output buffer is valid but can be
+ * concealed.
+ */
+#define IS_OUTPUT_VALID(err) (((err) == AAC_DEC_OK) || IS_DECODE_ERROR(err))
+
+/*! \enum AAC_MD_PROFILE
+ * \brief The available metadata profiles which are mostly related to downmixing. The values define the arguments
+ * for the use with parameter ::AAC_METADATA_PROFILE.
+ */
+typedef enum {
+ AAC_MD_PROFILE_MPEG_STANDARD =
+ 0, /*!< The standard profile creates a mixdown signal based on the
+ advanced downmix metadata (from a DSE). The equations and default
+ values are defined in ISO/IEC 14496:3 Ammendment 4. Any other
+ (legacy) downmix metadata will be ignored. No other parameter will
+ be modified. */
+ AAC_MD_PROFILE_MPEG_LEGACY =
+ 1, /*!< This profile behaves identical to the standard profile if advanced
+ downmix metadata (from a DSE) is available. If not, the
+ matrix_mixdown information embedded in the program configuration
+ element (PCE) will be applied. If neither is the case, the module
+ creates a mixdown using the default coefficients as defined in
+ ISO/IEC 14496:3 AMD 4. The profile can be used to support legacy
+ digital TV (e.g. DVB) streams. */
+ AAC_MD_PROFILE_MPEG_LEGACY_PRIO =
+ 2, /*!< Similar to the ::AAC_MD_PROFILE_MPEG_LEGACY profile but if both
+ the advanced (ISO/IEC 14496:3 AMD 4) and the legacy (PCE) MPEG
+ downmix metadata are available the latter will be applied.
+ */
+ AAC_MD_PROFILE_ARIB_JAPAN =
+ 3 /*!< Downmix creation as described in ABNT NBR 15602-2. But if advanced
+ downmix metadata (ISO/IEC 14496:3 AMD 4) is available it will be
+ preferred because of the higher resolutions. In addition the
+ metadata expiry time will be set to the value defined in the ARIB
+ standard (see ::AAC_METADATA_EXPIRY_TIME).
+ */
+} AAC_MD_PROFILE;
+
+/*! \enum AAC_DRC_DEFAULT_PRESENTATION_MODE_OPTIONS
+ * \brief Options for handling of DRC parameters, if presentation mode is not indicated in bitstream
+ */
+typedef enum {
+ AAC_DRC_PARAMETER_HANDLING_DISABLED = -1, /*!< DRC parameter handling
+ disabled, all parameters are
+ applied as requested. */
+ AAC_DRC_PARAMETER_HANDLING_ENABLED =
+ 0, /*!< Apply changes to requested DRC parameters to prevent clipping. */
+ AAC_DRC_PRESENTATION_MODE_1_DEFAULT =
+ 1, /*!< Use DRC presentation mode 1 as default (e.g. for Nordig) */
+ AAC_DRC_PRESENTATION_MODE_2_DEFAULT =
+ 2 /*!< Use DRC presentation mode 2 as default (e.g. for DTG DBook) */
+} AAC_DRC_DEFAULT_PRESENTATION_MODE_OPTIONS;
+
+/**
+ * \brief AAC decoder setting parameters
+ */
+typedef enum {
+ AAC_PCM_DUAL_CHANNEL_OUTPUT_MODE =
+ 0x0002, /*!< Defines how the decoder processes two channel signals: \n
+ 0: Leave both signals as they are (default). \n
+ 1: Create a dual mono output signal from channel 1. \n
+ 2: Create a dual mono output signal from channel 2. \n
+ 3: Create a dual mono output signal by mixing both channels
+ (L' = R' = 0.5*Ch1 + 0.5*Ch2). */
+ AAC_PCM_OUTPUT_CHANNEL_MAPPING =
+ 0x0003, /*!< Output buffer channel ordering. 0: MPEG PCE style order, 1:
+ WAV file channel order (default). */
+ AAC_PCM_LIMITER_ENABLE =
+ 0x0004, /*!< Enable signal level limiting. \n
+ -1: Auto-config. Enable limiter for all
+ non-lowdelay configurations by default. \n
+ 0: Disable limiter in general. \n
+ 1: Enable limiter always.
+ It is recommended to call the decoder
+ with a AACDEC_CLRHIST flag to reset all
+ states when the limiter switch is changed
+ explicitly. */
+ AAC_PCM_LIMITER_ATTACK_TIME = 0x0005, /*!< Signal level limiting attack time
+ in ms. Default configuration is 15
+ ms. Adjustable range from 1 ms to 15
+ ms. */
+ AAC_PCM_LIMITER_RELEAS_TIME = 0x0006, /*!< Signal level limiting release time
+ in ms. Default configuration is 50
+ ms. Adjustable time must be larger
+ than 0 ms. */
+ AAC_PCM_MIN_OUTPUT_CHANNELS =
+ 0x0011, /*!< Minimum number of PCM output channels. If higher than the
+ number of encoded audio channels, a simple channel extension is
+ applied (see note 4 for exceptions). \n -1, 0: Disable channel
+ extension feature. The decoder output contains the same number
+ of channels as the encoded bitstream. \n 1: This value is
+ currently needed only together with the mix-down feature. See
+ ::AAC_PCM_MAX_OUTPUT_CHANNELS and note 2 below. \n
+ 2: Encoded mono signals will be duplicated to achieve a
+ 2/0/0.0 channel output configuration. \n 6: The decoder
+ tries to reorder encoded signals with less than six channels to
+ achieve a 3/0/2.1 channel output signal. Missing channels will
+ be filled with a zero signal. If reordering is not possible the
+ empty channels will simply be appended. Only available if
+ instance is configured to support multichannel output. \n 8:
+ The decoder tries to reorder encoded signals with less than
+ eight channels to achieve a 3/0/4.1 channel output signal.
+ Missing channels will be filled with a zero signal. If
+ reordering is not possible the empty channels will simply be
+ appended. Only available if instance is configured to
+ support multichannel output.\n NOTE: \n
+ 1. The channel signaling (CStreamInfo::pChannelType and
+ CStreamInfo::pChannelIndices) will not be modified. Added empty
+ channels will be signaled with channel type
+ AUDIO_CHANNEL_TYPE::ACT_NONE. \n
+ 2. If the parameter value is greater than that of
+ ::AAC_PCM_MAX_OUTPUT_CHANNELS both will be set to the same
+ value. \n
+ 3. This parameter does not affect MPEG Surround processing.
+ \n
+ 4. This parameter will be ignored if the number of encoded
+ audio channels is greater than 8. */
+ AAC_PCM_MAX_OUTPUT_CHANNELS =
+ 0x0012, /*!< Maximum number of PCM output channels. If lower than the
+ number of encoded audio channels, downmixing is applied
+ accordingly (see note 5 for exceptions). If dedicated metadata
+ is available in the stream it will be used to achieve better
+ mixing results. \n -1, 0: Disable downmixing feature. The
+ decoder output contains the same number of channels as the
+ encoded bitstream. \n 1: All encoded audio configurations
+ with more than one channel will be mixed down to one mono
+ output signal. \n 2: The decoder performs a stereo mix-down
+ if the number encoded audio channels is greater than two. \n 6:
+ If the number of encoded audio channels is greater than six the
+ decoder performs a mix-down to meet the target output
+ configuration of 3/0/2.1 channels. Only available if instance
+ is configured to support multichannel output. \n 8: This
+ value is currently needed only together with the channel
+ extension feature. See ::AAC_PCM_MIN_OUTPUT_CHANNELS and note 2
+ below. Only available if instance is configured to support
+ multichannel output. \n NOTE: \n
+ 1. Down-mixing of any seven or eight channel configuration
+ not defined in ISO/IEC 14496-3 PDAM 4 is not supported by this
+ software version. \n
+ 2. If the parameter value is greater than zero but smaller
+ than ::AAC_PCM_MIN_OUTPUT_CHANNELS both will be set to same
+ value. \n
+ 3. The operating mode of the MPEG Surround module will be
+ set accordingly. \n
+ 4. Setting this parameter with any value will disable the
+ binaural processing of the MPEG Surround module
+ 5. This parameter will be ignored if the number of encoded
+ audio channels is greater than 8. */
+ AAC_METADATA_PROFILE =
+ 0x0020, /*!< See ::AAC_MD_PROFILE for all available values. */
+ AAC_METADATA_EXPIRY_TIME = 0x0021, /*!< Defines the time in ms after which all
+ the bitstream associated meta-data (DRC,
+ downmix coefficients, ...) will be reset
+ to default if no update has been
+ received. Negative values disable the
+ feature. */
+
+ AAC_CONCEAL_METHOD = 0x0100, /*!< Error concealment: Processing method. \n
+ 0: Spectral muting. \n
+ 1: Noise substitution (see ::CONCEAL_NOISE).
+ \n 2: Energy interpolation (adds additional
+ signal delay of one frame, see
+ ::CONCEAL_INTER. only some AOTs are
+ supported). \n */
+ AAC_DRC_BOOST_FACTOR =
+ 0x0200, /*!< Dynamic Range Control: Scaling factor for boosting gain
+ values. Defines how the boosting DRC factors (conveyed in the
+ bitstream) will be applied to the decoded signal. The valid
+ values range from 0 (don't apply boost factors) to 127 (fully
+ apply boost factors). Default value is 0. */
+ AAC_DRC_ATTENUATION_FACTOR =
+ 0x0201, /*!< Dynamic Range Control: Scaling factor for attenuating gain
+ values. Same as
+ ::AAC_DRC_BOOST_FACTOR but for attenuating DRC factors. */
+ AAC_DRC_REFERENCE_LEVEL =
+ 0x0202, /*!< Dynamic Range Control (DRC): Target reference level. Defines
+ the level below full-scale (quantized in steps of 0.25dB) to
+ which the output audio signal will be normalized to by the DRC
+ module. The parameter controls loudness normalization for both
+ MPEG-4 DRC and MPEG-D DRC. The valid values range from 40 (-10
+ dBFS) to 127 (-31.75 dBFS). Any value smaller than 0 switches
+ off loudness normalization and MPEG-4 DRC. By default, loudness
+ normalization and MPEG-4 DRC is switched off. */
+ AAC_DRC_HEAVY_COMPRESSION =
+ 0x0203, /*!< Dynamic Range Control: En-/Disable DVB specific heavy
+ compression (aka RF mode). If set to 1, the decoder will apply
+ the compression values from the DVB specific ancillary data
+ field. At the same time the MPEG-4 Dynamic Range Control tool
+ will be disabled. By default, heavy compression is disabled. */
+ AAC_DRC_DEFAULT_PRESENTATION_MODE =
+ 0x0204, /*!< Dynamic Range Control: Default presentation mode (DRC
+ parameter handling). \n Defines the handling of the DRC
+ parameters boost factor, attenuation factor and heavy
+ compression, if no presentation mode is indicated in the
+ bitstream.\n For options, see
+ ::AAC_DRC_DEFAULT_PRESENTATION_MODE_OPTIONS.\n Default:
+ ::AAC_DRC_PARAMETER_HANDLING_DISABLED */
+ AAC_DRC_ENC_TARGET_LEVEL =
+ 0x0205, /*!< Dynamic Range Control: Encoder target level for light (i.e.
+ not heavy) compression.\n If known, this declares the target
+ reference level that was assumed at the encoder for calculation
+ of limiting gains. The valid values range from 0 (full-scale)
+ to 127 (31.75 dB below full-scale). This parameter is used only
+ with ::AAC_DRC_PARAMETER_HANDLING_ENABLED and ignored
+ otherwise.\n Default: 127 (worst-case assumption).\n */
+ AAC_QMF_LOWPOWER = 0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing
+ mode. \n -1: Use internal default. Implies MPEG
+ Surround partially complex accordingly. \n 0:
+ Use complex QMF data mode. \n 1: Use real (low
+ power) QMF data mode. \n */
+ AAC_TPDEC_CLEAR_BUFFER =
+ 0x0603, /*!< Clear internal bit stream buffer of transport layers. The
+ decoder will start decoding at new data passed after this event
+ and any previous data is discarded. */
+ AAC_UNIDRC_SET_EFFECT = 0x0903 /*!< MPEG-D DRC: Request a DRC effect type for
+ selection of a DRC set.\n Supported indices
+ are:\n -1: DRC off. Completely disables
+ MPEG-D DRC.\n 0: None (default). Disables
+ MPEG-D DRC, but automatically enables DRC if
+ necessary to prevent clipping.\n 1: Late
+ night\n 2: Noisy environment\n 3: Limited
+ playback range\n 4: Low playback level\n 5:
+ Dialog enhancement\n 6: General compression.
+ Used for generally enabling MPEG-D DRC
+ without particular request.\n */
+
+} AACDEC_PARAM;
+
+/**
+ * \brief This structure gives information about the currently decoded audio
+ * data. All fields are read-only.
+ */
+typedef struct {
+ /* These five members are the only really relevant ones for the user. */
+ INT sampleRate; /*!< The sample rate in Hz of the decoded PCM audio signal. */
+ INT frameSize; /*!< The frame size of the decoded PCM audio signal. \n
+ Typically this is: \n
+ 1024 or 960 for AAC-LC \n
+ 2048 or 1920 for HE-AAC (v2) \n
+ 512 or 480 for AAC-LD and AAC-ELD \n
+ 768, 1024, 2048 or 4096 for USAC */
+ INT numChannels; /*!< The number of output audio channels before the rendering
+ module, i.e. the original channel configuration. */
+ AUDIO_CHANNEL_TYPE
+ *pChannelType; /*!< Audio channel type of each output audio channel. */
+ UCHAR *pChannelIndices; /*!< Audio channel index for each output audio
+ channel. See ISO/IEC 13818-7:2005(E), 8.5.3.2
+ Explicit channel mapping using a
+ program_config_element() */
+ /* Decoder internal members. */
+ INT aacSampleRate; /*!< Sampling rate in Hz without SBR (from configuration
+ info) divided by a (ELD) downscale factor if present. */
+ INT profile; /*!< MPEG-2 profile (from file header) (-1: not applicable (e. g.
+ MPEG-4)). */
+ AUDIO_OBJECT_TYPE
+ aot; /*!< Audio Object Type (from ASC): is set to the appropriate value
+ for MPEG-2 bitstreams (e. g. 2 for AAC-LC). */
+ INT channelConfig; /*!< Channel configuration (0: PCE defined, 1: mono, 2:
+ stereo, ... */
+ INT bitRate; /*!< Instantaneous bit rate. */
+ INT aacSamplesPerFrame; /*!< Samples per frame for the AAC core (from ASC)
+ divided by a (ELD) downscale factor if present. \n
+ Typically this is (with a downscale factor of 1):
+ \n 1024 or 960 for AAC-LC \n 512 or 480 for
+ AAC-LD and AAC-ELD */
+ INT aacNumChannels; /*!< The number of audio channels after AAC core
+ processing (before PS or MPS processing). CAUTION: This
+ are not the final number of output channels! */
+ AUDIO_OBJECT_TYPE extAot; /*!< Extension Audio Object Type (from ASC) */
+ INT extSamplingRate; /*!< Extension sampling rate in Hz (from ASC) divided by
+ a (ELD) downscale factor if present. */
+
+ UINT outputDelay; /*!< The number of samples the output is additionally
+ delayed by.the decoder. */
+ UINT flags; /*!< Copy of internal flags. Only to be written by the decoder,
+ and only to be read externally. */
+
+ SCHAR epConfig; /*!< epConfig level (from ASC): only level 0 supported, -1
+ means no ER (e. g. AOT=2, MPEG-2 AAC, etc.) */
+ /* Statistics */
+ INT numLostAccessUnits; /*!< This integer will reflect the estimated amount of
+ lost access units in case aacDecoder_DecodeFrame()
+ returns AAC_DEC_TRANSPORT_SYNC_ERROR. It will be
+ < 0 if the estimation failed. */
+
+ INT64 numTotalBytes; /*!< This is the number of total bytes that have passed
+ through the decoder. */
+ INT64
+ numBadBytes; /*!< This is the number of total bytes that were considered
+ with errors from numTotalBytes. */
+ INT64
+ numTotalAccessUnits; /*!< This is the number of total access units that
+ have passed through the decoder. */
+ INT64 numBadAccessUnits; /*!< This is the number of total access units that
+ were considered with errors from numTotalBytes. */
+
+ /* Metadata */
+ SCHAR drcProgRefLev; /*!< DRC program reference level. Defines the reference
+ level below full-scale. It is quantized in steps of
+ 0.25dB. The valid values range from 0 (0 dBFS) to 127
+ (-31.75 dBFS). It is used to reflect the average
+ loudness of the audio in LKFS according to ITU-R BS
+ 1770. If no level has been found in the bitstream the
+ value is -1. */
+ SCHAR
+ drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154,
+ this field indicates whether light (MPEG-4 Dynamic Range
+ Control tool) or heavy compression (DVB heavy
+ compression) dynamic range control shall take priority
+ on the outputs. For details, see ETSI TS 101 154, table
+ C.33. Possible values are: \n -1: No corresponding
+ metadata found in the bitstream \n 0: DRC presentation
+ mode not indicated \n 1: DRC presentation mode 1 \n 2:
+ DRC presentation mode 2 \n 3: Reserved */
+
+} CStreamInfo;
+
+typedef struct AAC_DECODER_INSTANCE
+ *HANDLE_AACDECODER; /*!< Pointer to a AAC decoder instance. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Initialize ancillary data buffer.
+ *
+ * \param self AAC decoder handle.
+ * \param buffer Pointer to (external) ancillary data buffer.
+ * \param size Size of the buffer pointed to by buffer.
+ * \return Error code.
+ */
+LINKSPEC_H AAC_DECODER_ERROR aacDecoder_AncDataInit(HANDLE_AACDECODER self,
+ UCHAR *buffer, int size);
+
+/**
+ * \brief Get one ancillary data element.
+ *
+ * \param self AAC decoder handle.
+ * \param index Index of the ancillary data element to get.
+ * \param ptr Pointer to a buffer receiving a pointer to the requested
+ * ancillary data element.
+ * \param size Pointer to a buffer receiving the length of the requested
+ * ancillary data element.
+ * \return Error code.
+ */
+LINKSPEC_H AAC_DECODER_ERROR aacDecoder_AncDataGet(HANDLE_AACDECODER self,
+ int index, UCHAR **ptr,
+ int *size);
+
+/**
+ * \brief Set one single decoder parameter.
+ *
+ * \param self AAC decoder handle.
+ * \param param Parameter to be set.
+ * \param value Parameter value.
+ * \return Error code.
+ */
+LINKSPEC_H AAC_DECODER_ERROR aacDecoder_SetParam(const HANDLE_AACDECODER self,
+ const AACDEC_PARAM param,
+ const INT value);
+
+/**
+ * \brief Get free bytes inside decoder internal buffer.
+ * \param self Handle of AAC decoder instance.
+ * \param pFreeBytes Pointer to variable receiving amount of free bytes inside
+ * decoder internal buffer.
+ * \return Error code.
+ */
+LINKSPEC_H AAC_DECODER_ERROR
+aacDecoder_GetFreeBytes(const HANDLE_AACDECODER self, UINT *pFreeBytes);
+
+/**
+ * \brief Open an AAC decoder instance.
+ * \param transportFmt The transport type to be used.
+ * \param nrOfLayers Number of transport layers.
+ * \return AAC decoder handle.
+ */
+LINKSPEC_H HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt,
+ UINT nrOfLayers);
+
+/**
+ * \brief Explicitly configure the decoder by passing a raw AudioSpecificConfig
+ * (ASC) or a StreamMuxConfig (SMC), contained in a binary buffer. This is
+ * required for MPEG-4 and Raw Packets file format bitstreams as well as for
+ * LATM bitstreams with no in-band SMC. If the transport format is LATM with or
+ * without LOAS, configuration is assumed to be an SMC, for all other file
+ * formats an ASC.
+ *
+ * \param self AAC decoder handle.
+ * \param conf Pointer to an unsigned char buffer containing the binary
+ * configuration buffer (either ASC or SMC).
+ * \param length Length of the configuration buffer in bytes.
+ * \return Error code.
+ */
+LINKSPEC_H AAC_DECODER_ERROR aacDecoder_ConfigRaw(HANDLE_AACDECODER self,
+ UCHAR *conf[],
+ const UINT length[]);
+
+/**
+ * \brief Submit raw ISO base media file format boxes to decoder for parsing
+ * (only some box types are recognized).
+ *
+ * \param self AAC decoder handle.
+ * \param buffer Pointer to an unsigned char buffer containing the binary box
+ * data (including size and type, can be a sequence of multiple boxes).
+ * \param length Length of the data in bytes.
+ * \return Error code.
+ */
+LINKSPEC_H AAC_DECODER_ERROR aacDecoder_RawISOBMFFData(HANDLE_AACDECODER self,
+ UCHAR *buffer,
+ UINT length);
+
+/**
+ * \brief Fill AAC decoder's internal input buffer with bitstream data from the
+ * external input buffer. The function only copies such data as long as the
+ * decoder-internal input buffer is not full. So it grabs whatever it can from
+ * pBuffer and returns information (bytesValid) so that at a subsequent call of
+ * %aacDecoder_Fill(), the right position in pBuffer can be determined to grab
+ * the next data.
+ *
+ * \param self AAC decoder handle.
+ * \param pBuffer Pointer to external input buffer.
+ * \param bufferSize Size of external input buffer. This argument is required
+ * because decoder-internally we need the information to calculate the offset to
+ * pBuffer, where the next available data is, which is then
+ * fed into the decoder-internal buffer (as much as
+ * possible). Our example framework implementation fills the
+ * buffer at pBuffer again, once it contains no available valid bytes anymore
+ * (meaning bytesValid equal 0).
+ * \param bytesValid Number of bitstream bytes in the external bitstream buffer
+ * that have not yet been copied into the decoder's internal bitstream buffer by
+ * calling this function. The value is updated according to
+ * the amount of newly copied bytes.
+ * \return Error code.
+ */
+LINKSPEC_H AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self,
+ UCHAR *pBuffer[],
+ const UINT bufferSize[],
+ UINT *bytesValid);
+
+#define AACDEC_CONCEAL \
+ 1 /*!< Flag for aacDecoder_DecodeFrame(): Trigger the built-in error \
+ concealment module to generate a substitute signal for one lost frame. \
+ New input data will not be considered. */
+#define AACDEC_FLUSH \
+ 2 /*!< Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all \
+ delayed audio without having new input data. Thus new input data will \
+ not be considered.*/
+#define AACDEC_INTR \
+ 4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data \
+ discontinuity. Resync any internals as necessary. */
+#define AACDEC_CLRHIST \
+ 8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and \
+ history buffers. CAUTION: This can cause discontinuities in the output \
+ signal. */
+
+/**
+ * \brief Decode one audio frame
+ *
+ * \param self AAC decoder handle.
+ * \param pTimeData Pointer to external output buffer where the decoded PCM
+ * samples will be stored into.
+ * \param timeDataSize Size of external output buffer.
+ * \param flags Bit field with flags for the decoder: \n
+ * (flags & AACDEC_CONCEAL) == 1: Do concealment. \n
+ * (flags & AACDEC_FLUSH) == 2: Discard input data. Flush
+ * filter banks (output delayed audio). \n (flags & AACDEC_INTR) == 4: Input
+ * data is discontinuous. Resynchronize any internals as
+ * necessary. \n (flags & AACDEC_CLRHIST) == 8: Clear all signal delay lines and
+ * history buffers.
+ * \return Error code.
+ */
+LINKSPEC_H AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
+ INT_PCM *pTimeData,
+ const INT timeDataSize,
+ const UINT flags);
+
+/**
+ * \brief De-allocate all resources of an AAC decoder instance.
+ *
+ * \param self AAC decoder handle.
+ * \return void.
+ */
+LINKSPEC_H void aacDecoder_Close(HANDLE_AACDECODER self);
+
+/**
+ * \brief Get CStreamInfo handle from decoder.
+ *
+ * \param self AAC decoder handle.
+ * \return Reference to requested CStreamInfo.
+ */
+LINKSPEC_H CStreamInfo *aacDecoder_GetStreamInfo(HANDLE_AACDECODER self);
+
+/**
+ * \brief Get decoder library info.
+ *
+ * \param info Pointer to an allocated LIB_INFO structure.
+ * \return 0 on success.
+ */
+LINKSPEC_H INT aacDecoder_GetLibInfo(LIB_INFO *info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AACDECODER_LIB_H */
diff --git a/fdk-aac/libAACdec/src/FDK_delay.cpp b/fdk-aac/libAACdec/src/FDK_delay.cpp
new file mode 100644
index 0000000..0ab1a66
--- /dev/null
+++ b/fdk-aac/libAACdec/src/FDK_delay.cpp
@@ -0,0 +1,173 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description:
+
+*******************************************************************************/
+
+#include "FDK_delay.h"
+
+#include "genericStds.h"
+
+#define MAX_FRAME_LENGTH (1024)
+
+INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
+ const UCHAR num_channels) {
+ FDK_ASSERT(data != NULL);
+ FDK_ASSERT(num_channels > 0);
+
+ if (delay > 0) {
+ data->delay_line =
+ (INT_PCM*)FDKcalloc(num_channels * delay, sizeof(INT_PCM));
+ if (data->delay_line == NULL) {
+ return -1;
+ }
+ } else {
+ data->delay_line = NULL;
+ }
+ data->num_channels = num_channels;
+ data->delay = delay;
+
+ return 0;
+}
+
+void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer,
+ const UINT frame_length, const UCHAR channel) {
+ FDK_ASSERT(data != NULL);
+
+ if (data->delay > 0) {
+ C_ALLOC_SCRATCH_START(tmp, FIXP_PCM, MAX_FRAME_LENGTH)
+ FDK_ASSERT(frame_length <= MAX_FRAME_LENGTH);
+ FDK_ASSERT(channel < data->num_channels);
+ FDK_ASSERT(time_buffer != NULL);
+ if (frame_length >= data->delay) {
+ FDKmemcpy(tmp, &time_buffer[frame_length - data->delay],
+ data->delay * sizeof(FIXP_PCM));
+ FDKmemmove(&time_buffer[data->delay], &time_buffer[0],
+ (frame_length - data->delay) * sizeof(FIXP_PCM));
+ FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay],
+ data->delay * sizeof(FIXP_PCM));
+ FDKmemcpy(&data->delay_line[channel * data->delay], tmp,
+ data->delay * sizeof(FIXP_PCM));
+ } else {
+ FDKmemcpy(tmp, &time_buffer[0], frame_length * sizeof(FIXP_PCM));
+ FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay],
+ frame_length * sizeof(FIXP_PCM));
+ FDKmemcpy(&data->delay_line[channel * data->delay],
+ &data->delay_line[channel * data->delay + frame_length],
+ (data->delay - frame_length) * sizeof(FIXP_PCM));
+ FDKmemcpy(&data->delay_line[channel * data->delay +
+ (data->delay - frame_length)],
+ tmp, frame_length * sizeof(FIXP_PCM));
+ }
+ C_ALLOC_SCRATCH_END(tmp, FIXP_PCM, MAX_FRAME_LENGTH)
+ }
+
+ return;
+}
+
+void FDK_Delay_Destroy(FDK_SignalDelay* data) {
+ if (data->delay_line != NULL) {
+ FDKfree(data->delay_line);
+ }
+ data->delay_line = NULL;
+ data->delay = 0;
+ data->num_channels = 0;
+
+ return;
+}
diff --git a/fdk-aac/libAACdec/src/FDK_delay.h b/fdk-aac/libAACdec/src/FDK_delay.h
new file mode 100644
index 0000000..f89c3a2
--- /dev/null
+++ b/fdk-aac/libAACdec/src/FDK_delay.h
@@ -0,0 +1,152 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef FDK_DELAY_H
+#define FDK_DELAY_H
+
+#include "aac_rom.h"
+
+/**
+ * Structure representing one delay element for multiple channels.
+ */
+typedef struct {
+ INT_PCM* delay_line; /*!< Pointer which stores allocated delay line. */
+ USHORT delay; /*!< Delay required in samples (per channel). */
+ UCHAR num_channels; /*!< Number of channels to delay. */
+} FDK_SignalDelay;
+
+/**
+ * \brief Create delay element for multiple channels with fixed delay value.
+ *
+ * \param data Pointer delay element structure.
+ * \param delay Required delay value in samples per channel.
+ * \param num_channels Required number of channels.
+ *
+ * \return -1 on out of memory, else 0
+ */
+INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
+ const UCHAR num_channels);
+
+/**
+ * \brief Apply delay to one channel (non-interleaved storage assumed).
+ *
+ * \param data Pointer delay element structure.
+ * \param time_buffer Pointer to signal to delay.
+ * \param frame_length Frame length of input/output signal (needs to be >=
+ * delay).
+ * \param channel Index of current channel (0 <= channel < num_channels).
+ *
+ * \return void
+ */
+void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer,
+ const UINT frame_length, const UCHAR channel);
+
+/**
+ * \brief Destroy delay element.
+ *
+ * \param data Pointer delay element structure.
+ *
+ * \return void
+ */
+void FDK_Delay_Destroy(FDK_SignalDelay* data);
+
+#endif /* #ifndef FDK_DELAY_H */
diff --git a/fdk-aac/libAACdec/src/aac_ram.cpp b/fdk-aac/libAACdec/src/aac_ram.cpp
new file mode 100644
index 0000000..e13167d
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aac_ram.cpp
@@ -0,0 +1,185 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#include "aac_ram.h"
+#include "aac_rom.h"
+
+#define WORKBUFFER1_TAG 0
+#define WORKBUFFER2_TAG 1
+
+#define WORKBUFFER3_TAG 4
+#define WORKBUFFER4_TAG 5
+
+#define WORKBUFFER5_TAG 6
+
+#define WORKBUFFER6_TAG 7
+
+/*! The structure AAC_DECODER_INSTANCE is the top level structure holding all
+ decoder configurations, handles and structs.
+ */
+C_ALLOC_MEM(AacDecoder, struct AAC_DECODER_INSTANCE, 1)
+
+/*!
+ \name StaticAacData
+
+ Static memory areas, must not be overwritten in other sections of the decoder
+*/
+/* @{ */
+
+/*! The structure CAacDecoderStaticChannelInfo contains the static sideinfo
+ which is needed for the decoding of one aac channel. <br> Dimension:
+ #AacDecoderChannels */
+C_ALLOC_MEM2(AacDecoderStaticChannelInfo, CAacDecoderStaticChannelInfo, 1, (8))
+
+/*! The structure CAacDecoderChannelInfo contains the dynamic sideinfo which is
+ needed for the decoding of one aac channel. <br> Dimension:
+ #AacDecoderChannels */
+C_AALLOC_MEM2(AacDecoderChannelInfo, CAacDecoderChannelInfo, 1, (8))
+
+/*! Overlap buffer */
+C_AALLOC_MEM2(OverlapBuffer, FIXP_DBL, OverlapBufferSize, (8))
+
+C_ALLOC_MEM(DrcInfo, CDrcInfo, 1)
+
+/*! The structure CpePersistentData holds the persistent data shared by both
+ channels of a CPE. <br> It needs to be allocated for each CPE. <br>
+ Dimension: 1 */
+C_ALLOC_MEM(CpePersistentData, CpePersistentData, 1)
+
+/*! The structure CCplxPredictionData holds data for complex stereo prediction.
+ <br> Dimension: 1
+ */
+C_ALLOC_MEM(CplxPredictionData, CCplxPredictionData, 1)
+
+/*! The buffer holds time samples for the crossfade in case of an USAC DASH IPF
+ config change Dimension: (8)
+ */
+C_ALLOC_MEM2(TimeDataFlush, INT_PCM, TIME_DATA_FLUSH_SIZE, (8))
+
+/* @} */
+
+/*!
+ \name DynamicAacData
+
+ Dynamic memory areas, might be reused in other algorithm sections,
+ e.g. the sbr decoder
+*/
+
+/* Take into consideration to make use of the WorkBufferCore[3/4] for decoder
+ * configurations with more than 2 channels */
+C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((8) * 1024), SECT_DATA_L2,
+ WORKBUFFER2_TAG)
+
+C_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL, WB_SECTION_SIZE, SECT_DATA_L2,
+ WORKBUFFER3_TAG)
+C_AALLOC_MEM(WorkBufferCore4, FIXP_DBL, WB_SECTION_SIZE)
+C_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR,
+ fMax((INT)(sizeof(FIXP_DBL) * WB_SECTION_SIZE),
+ (INT)sizeof(CAacDecoderCommonData)),
+ SECT_DATA_L2, WORKBUFFER6_TAG)
+
+C_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1, 1, SECT_DATA_L1,
+ WORKBUFFER1_TAG)
+
+/* double buffer size needed for de-/interleaving */
+C_ALLOC_MEM_OVERLAY(WorkBufferCore5, PCM_DEC, (8) * (1024 * 4) * 2,
+ SECT_DATA_EXTERN, WORKBUFFER5_TAG)
diff --git a/fdk-aac/libAACdec/src/aac_ram.h b/fdk-aac/libAACdec/src/aac_ram.h
new file mode 100644
index 0000000..a861e25
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aac_ram.h
@@ -0,0 +1,147 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef AAC_RAM_H
+#define AAC_RAM_H
+
+#include "common_fix.h"
+
+#include "aacdecoder.h"
+
+#include "channel.h"
+
+#include "ac_arith_coder.h"
+
+#include "aacdec_hcr_types.h"
+#include "aacdec_hcr.h"
+
+/* End of formal fix.h */
+
+#define MAX_SYNCHS 10
+#define SAMPL_FREQS 12
+
+H_ALLOC_MEM(AacDecoder, AAC_DECODER_INSTANCE)
+
+H_ALLOC_MEM(DrcInfo, CDrcInfo)
+
+H_ALLOC_MEM(AacDecoderStaticChannelInfo, CAacDecoderStaticChannelInfo)
+H_ALLOC_MEM(AacDecoderChannelInfo, CAacDecoderChannelInfo)
+H_ALLOC_MEM(OverlapBuffer, FIXP_DBL)
+
+H_ALLOC_MEM(CpePersistentData, CpePersistentData)
+H_ALLOC_MEM(CplxPredictionData, CCplxPredictionData)
+H_ALLOC_MEM(SpectralCoeffs, FIXP_DBL)
+H_ALLOC_MEM(SpecScale, SHORT)
+
+H_ALLOC_MEM(TimeDataFlush, INT_PCM)
+
+H_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1)
+H_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL)
+
+H_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL)
+H_ALLOC_MEM(WorkBufferCore4, FIXP_DBL)
+
+H_ALLOC_MEM_OVERLAY(WorkBufferCore5, PCM_DEC)
+
+H_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR)
+
+#endif /* #ifndef AAC_RAM_H */
diff --git a/fdk-aac/libAACdec/src/aac_rom.cpp b/fdk-aac/libAACdec/src/aac_rom.cpp
new file mode 100644
index 0000000..cbdffc4
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aac_rom.cpp
@@ -0,0 +1,3428 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl, Tobias Chalupka
+
+ Description: Definition of constant tables
+
+*******************************************************************************/
+
+#include "aac_rom.h"
+
+/* Prescale InverseQuantTable by 4 to save
+ redundant shifts in invers quantization
+ */
+#define SCL_TAB(a) (a >> 4)
+const FIXP_DBL InverseQuantTable[INV_QUANT_TABLESIZE + 1] = {
+ SCL_TAB(0x32CBFD40), SCL_TAB(0x330FC340), SCL_TAB(0x33539FC0),
+ SCL_TAB(0x33979280), SCL_TAB(0x33DB9BC0), SCL_TAB(0x341FBB80),
+ SCL_TAB(0x3463F180), SCL_TAB(0x34A83DC0), SCL_TAB(0x34ECA000),
+ SCL_TAB(0x35311880), SCL_TAB(0x3575A700), SCL_TAB(0x35BA4B80),
+ SCL_TAB(0x35FF0600), SCL_TAB(0x3643D680), SCL_TAB(0x3688BCC0),
+ SCL_TAB(0x36CDB880), SCL_TAB(0x3712CA40), SCL_TAB(0x3757F1C0),
+ SCL_TAB(0x379D2F00), SCL_TAB(0x37E28180), SCL_TAB(0x3827E9C0),
+ SCL_TAB(0x386D6740), SCL_TAB(0x38B2FA40), SCL_TAB(0x38F8A2C0),
+ SCL_TAB(0x393E6080), SCL_TAB(0x39843380), SCL_TAB(0x39CA1BC0),
+ SCL_TAB(0x3A101940), SCL_TAB(0x3A562BC0), SCL_TAB(0x3A9C5340),
+ SCL_TAB(0x3AE28FC0), SCL_TAB(0x3B28E180), SCL_TAB(0x3B6F4800),
+ SCL_TAB(0x3BB5C340), SCL_TAB(0x3BFC5380), SCL_TAB(0x3C42F880),
+ SCL_TAB(0x3C89B200), SCL_TAB(0x3CD08080), SCL_TAB(0x3D176340),
+ SCL_TAB(0x3D5E5B00), SCL_TAB(0x3DA56700), SCL_TAB(0x3DEC87C0),
+ SCL_TAB(0x3E33BCC0), SCL_TAB(0x3E7B0640), SCL_TAB(0x3EC26400),
+ SCL_TAB(0x3F09D640), SCL_TAB(0x3F515C80), SCL_TAB(0x3F98F740),
+ SCL_TAB(0x3FE0A600), SCL_TAB(0x40286900), SCL_TAB(0x40704000),
+ SCL_TAB(0x40B82B00), SCL_TAB(0x41002A00), SCL_TAB(0x41483D00),
+ SCL_TAB(0x41906400), SCL_TAB(0x41D89F00), SCL_TAB(0x4220ED80),
+ SCL_TAB(0x42695000), SCL_TAB(0x42B1C600), SCL_TAB(0x42FA5000),
+ SCL_TAB(0x4342ED80), SCL_TAB(0x438B9E80), SCL_TAB(0x43D46380),
+ SCL_TAB(0x441D3B80), SCL_TAB(0x44662780), SCL_TAB(0x44AF2680),
+ SCL_TAB(0x44F83900), SCL_TAB(0x45415F00), SCL_TAB(0x458A9880),
+ SCL_TAB(0x45D3E500), SCL_TAB(0x461D4500), SCL_TAB(0x4666B800),
+ SCL_TAB(0x46B03E80), SCL_TAB(0x46F9D800), SCL_TAB(0x47438480),
+ SCL_TAB(0x478D4400), SCL_TAB(0x47D71680), SCL_TAB(0x4820FC00),
+ SCL_TAB(0x486AF500), SCL_TAB(0x48B50000), SCL_TAB(0x48FF1E80),
+ SCL_TAB(0x49494F80), SCL_TAB(0x49939380), SCL_TAB(0x49DDEA80),
+ SCL_TAB(0x4A285400), SCL_TAB(0x4A72D000), SCL_TAB(0x4ABD5E80),
+ SCL_TAB(0x4B080000), SCL_TAB(0x4B52B400), SCL_TAB(0x4B9D7A80),
+ SCL_TAB(0x4BE85380), SCL_TAB(0x4C333F00), SCL_TAB(0x4C7E3D00),
+ SCL_TAB(0x4CC94D00), SCL_TAB(0x4D146F80), SCL_TAB(0x4D5FA500),
+ SCL_TAB(0x4DAAEC00), SCL_TAB(0x4DF64580), SCL_TAB(0x4E41B180),
+ SCL_TAB(0x4E8D2F00), SCL_TAB(0x4ED8BF80), SCL_TAB(0x4F246180),
+ SCL_TAB(0x4F701600), SCL_TAB(0x4FBBDC00), SCL_TAB(0x5007B480),
+ SCL_TAB(0x50539F00), SCL_TAB(0x509F9B80), SCL_TAB(0x50EBA980),
+ SCL_TAB(0x5137C980), SCL_TAB(0x5183FB80), SCL_TAB(0x51D03F80),
+ SCL_TAB(0x521C9500), SCL_TAB(0x5268FC80), SCL_TAB(0x52B57580),
+ SCL_TAB(0x53020000), SCL_TAB(0x534E9C80), SCL_TAB(0x539B4A80),
+ SCL_TAB(0x53E80A80), SCL_TAB(0x5434DB80), SCL_TAB(0x5481BE80),
+ SCL_TAB(0x54CEB280), SCL_TAB(0x551BB880), SCL_TAB(0x5568CF80),
+ SCL_TAB(0x55B5F800), SCL_TAB(0x56033200), SCL_TAB(0x56507D80),
+ SCL_TAB(0x569DDA00), SCL_TAB(0x56EB4800), SCL_TAB(0x5738C700),
+ SCL_TAB(0x57865780), SCL_TAB(0x57D3F900), SCL_TAB(0x5821AC00),
+ SCL_TAB(0x586F7000), SCL_TAB(0x58BD4500), SCL_TAB(0x590B2B00),
+ SCL_TAB(0x59592200), SCL_TAB(0x59A72A80), SCL_TAB(0x59F54380),
+ SCL_TAB(0x5A436D80), SCL_TAB(0x5A91A900), SCL_TAB(0x5ADFF500),
+ SCL_TAB(0x5B2E5180), SCL_TAB(0x5B7CBF80), SCL_TAB(0x5BCB3E00),
+ SCL_TAB(0x5C19CD00), SCL_TAB(0x5C686D80), SCL_TAB(0x5CB71E00),
+ SCL_TAB(0x5D05DF80), SCL_TAB(0x5D54B200), SCL_TAB(0x5DA39500),
+ SCL_TAB(0x5DF28880), SCL_TAB(0x5E418C80), SCL_TAB(0x5E90A100),
+ SCL_TAB(0x5EDFC680), SCL_TAB(0x5F2EFC00), SCL_TAB(0x5F7E4280),
+ SCL_TAB(0x5FCD9900), SCL_TAB(0x601D0080), SCL_TAB(0x606C7800),
+ SCL_TAB(0x60BC0000), SCL_TAB(0x610B9800), SCL_TAB(0x615B4100),
+ SCL_TAB(0x61AAF980), SCL_TAB(0x61FAC300), SCL_TAB(0x624A9C80),
+ SCL_TAB(0x629A8600), SCL_TAB(0x62EA8000), SCL_TAB(0x633A8A00),
+ SCL_TAB(0x638AA480), SCL_TAB(0x63DACF00), SCL_TAB(0x642B0980),
+ SCL_TAB(0x647B5400), SCL_TAB(0x64CBAE80), SCL_TAB(0x651C1900),
+ SCL_TAB(0x656C9400), SCL_TAB(0x65BD1E80), SCL_TAB(0x660DB900),
+ SCL_TAB(0x665E6380), SCL_TAB(0x66AF1E00), SCL_TAB(0x66FFE880),
+ SCL_TAB(0x6750C280), SCL_TAB(0x67A1AC80), SCL_TAB(0x67F2A600),
+ SCL_TAB(0x6843B000), SCL_TAB(0x6894C900), SCL_TAB(0x68E5F200),
+ SCL_TAB(0x69372B00), SCL_TAB(0x69887380), SCL_TAB(0x69D9CB80),
+ SCL_TAB(0x6A2B3300), SCL_TAB(0x6A7CAA80), SCL_TAB(0x6ACE3180),
+ SCL_TAB(0x6B1FC800), SCL_TAB(0x6B716E00), SCL_TAB(0x6BC32400),
+ SCL_TAB(0x6C14E900), SCL_TAB(0x6C66BD80), SCL_TAB(0x6CB8A180),
+ SCL_TAB(0x6D0A9500), SCL_TAB(0x6D5C9800), SCL_TAB(0x6DAEAA00),
+ SCL_TAB(0x6E00CB80), SCL_TAB(0x6E52FC80), SCL_TAB(0x6EA53D00),
+ SCL_TAB(0x6EF78C80), SCL_TAB(0x6F49EB80), SCL_TAB(0x6F9C5980),
+ SCL_TAB(0x6FEED700), SCL_TAB(0x70416380), SCL_TAB(0x7093FF00),
+ SCL_TAB(0x70E6AA00), SCL_TAB(0x71396400), SCL_TAB(0x718C2D00),
+ SCL_TAB(0x71DF0580), SCL_TAB(0x7231ED00), SCL_TAB(0x7284E300),
+ SCL_TAB(0x72D7E880), SCL_TAB(0x732AFD00), SCL_TAB(0x737E2080),
+ SCL_TAB(0x73D15300), SCL_TAB(0x74249480), SCL_TAB(0x7477E480),
+ SCL_TAB(0x74CB4400), SCL_TAB(0x751EB200), SCL_TAB(0x75722F00),
+ SCL_TAB(0x75C5BB00), SCL_TAB(0x76195580), SCL_TAB(0x766CFF00),
+ SCL_TAB(0x76C0B700), SCL_TAB(0x77147E00), SCL_TAB(0x77685400),
+ SCL_TAB(0x77BC3880), SCL_TAB(0x78102B80), SCL_TAB(0x78642D80),
+ SCL_TAB(0x78B83E00), SCL_TAB(0x790C5D00), SCL_TAB(0x79608B00),
+ SCL_TAB(0x79B4C780), SCL_TAB(0x7A091280), SCL_TAB(0x7A5D6C00),
+ SCL_TAB(0x7AB1D400), SCL_TAB(0x7B064A80), SCL_TAB(0x7B5ACF80),
+ SCL_TAB(0x7BAF6380), SCL_TAB(0x7C040580), SCL_TAB(0x7C58B600),
+ SCL_TAB(0x7CAD7500), SCL_TAB(0x7D024200), SCL_TAB(0x7D571E00),
+ SCL_TAB(0x7DAC0800), SCL_TAB(0x7E010080), SCL_TAB(0x7E560780),
+ SCL_TAB(0x7EAB1C80), SCL_TAB(0x7F004000), SCL_TAB(0x7F557200),
+ SCL_TAB(0x7FAAB200), SCL_TAB(0x7FFFFFFF)};
+
+/**
+ * \brief Table representing scale factor gains. Given a scale factor sf, and a
+ * value pSpec[i] the gain is given by: MantissaTable[sf % 4][msb] = 2^(sf % 4)
+ * / (1<<ExponentTable[sf % 4][msb] The second dimension "msb" represents the
+ * upper scale factor bit count floor(log2(scalefactor >> 2)) The corresponding
+ * exponents for the values in this tables are stored in ExponentTable[sf %
+ * 4][msb] below.
+ */
+const FIXP_DBL MantissaTable[4][14] = {
+ {0x40000000, 0x50A28C00, 0x6597FA80, 0x40000000, 0x50A28C00, 0x6597FA80,
+ 0x40000000, 0x50A28C00, 0x6597FA80, 0x40000000, 0x50A28C00, 0x6597FA80,
+ 0x40000000, 0x50A28C00},
+ {0x4C1BF800, 0x5FE44380, 0x78D0DF80, 0x4C1BF800, 0x5FE44380, 0x78D0DF80,
+ 0x4C1BF800, 0x5FE44380, 0x78D0DF80, 0x4C1BF800, 0x5FE44380, 0x78D0DF80,
+ 0x4C1BF800, 0x5FE44380},
+ {0x5A827980, 0x7208F800, 0x47D66B00, 0x5A827980, 0x7208F800, 0x47D66B00,
+ 0x5A827980, 0x7208F800, 0x47D66B00, 0x5A827980, 0x7208F800, 0x47D66B00,
+ 0x5A827980, 0x7208F800},
+ {0x6BA27E80, 0x43CE3E80, 0x556E0400, 0x6BA27E80, 0x43CE3E80, 0x556E0400,
+ 0x6BA27E80, 0x43CE3E80, 0x556E0400, 0x6BA27E80, 0x43CE3E80, 0x556E0400,
+ 0x6BA27E80, 0x43CE3E80}};
+
+const SCHAR ExponentTable[4][14] = {
+ {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18},
+ {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18},
+ {1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18},
+ {1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19}};
+
+/* 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 */
+static const SHORT sfb_48_1024[50] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56,
+ 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216,
+ 240, 264, 292, 320, 352, 384, 416, 448, 480, 512, 544, 576, 608,
+ 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 1024};
+/* 14 scfbands */
+static const SHORT sfb_48_128[15] = {0, 4, 8, 12, 16, 20, 28, 36,
+ 44, 56, 68, 80, 96, 112, 128};
+
+/* 51 scfbands */
+static const SHORT sfb_32_1024[52] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56,
+ 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216,
+ 240, 264, 292, 320, 352, 384, 416, 448, 480, 512, 544, 576, 608,
+ 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960, 992, 1024};
+
+/* 47 scfbands */
+static const SHORT sfb_24_1024[48] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
+ 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 136, 148,
+ 160, 172, 188, 204, 220, 240, 260, 284, 308, 336, 364, 396,
+ 432, 468, 508, 552, 600, 652, 704, 768, 832, 896, 960, 1024};
+
+/* 15 scfbands */
+static const SHORT sfb_24_128[16] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 64, 76, 92, 108, 128};
+
+/* 43 scfbands */
+static const SHORT sfb_16_1024[44] = {
+ 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 100, 112, 124,
+ 136, 148, 160, 172, 184, 196, 212, 228, 244, 260, 280, 300, 320, 344, 368,
+ 396, 424, 456, 492, 532, 572, 616, 664, 716, 772, 832, 896, 960, 1024};
+
+/* 15 scfbands */
+static const SHORT sfb_16_128[16] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 32, 40, 48, 60, 72, 88, 108, 128};
+
+/* 40 scfbands */
+static const SHORT sfb_8_1024[41] = {
+ 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156,
+ 172, 188, 204, 220, 236, 252, 268, 288, 308, 328, 348, 372, 396, 420,
+ 448, 476, 508, 544, 580, 620, 664, 712, 764, 820, 880, 944, 1024};
+
+/* 15 scfbands */
+static const SHORT sfb_8_128[16] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 60, 72, 88, 108, 128};
+
+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] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56,
+ 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216,
+ 240, 264, 292, 320, 352, 384, 416, 448, 480, 512, 544, 576, 608,
+ 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960}; /* 49 scfbands */
+static const SHORT sfb_48_120[15] = {
+ 0, 4, 8, 12, 16, 20, 28, 36,
+ 44, 56, 68, 80, 96, 112, 120}; /* 14 scfbands */
+
+static const SHORT sfb_32_960[50] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56,
+ 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216,
+ 240, 264, 292, 320, 352, 384, 416, 448, 480, 512, 544, 576, 608,
+ 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960}; /* 49 scfbands */
+
+static const SHORT sfb_24_960[47] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
+ 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 136, 148,
+ 160, 172, 188, 204, 220, 240, 260, 284, 308, 336, 364, 396,
+ 432, 468, 508, 552, 600, 652, 704, 768, 832, 896, 960}; /* 46 scfbands */
+
+static const SHORT sfb_24_120[16] = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 64, 76, 92, 108, 120}; /* 15 scfbands */
+
+static const SHORT sfb_16_960[43] = {0, 8, 16, 24, 32, 40, 48, 56,
+ 64, 72, 80, 88, 100, 112, 124, 136,
+ 148, 160, 172, 184, 196, 212, 228, 244,
+ 260, 280, 300, 320, 344, 368, 396, 424,
+ 456, 492, 532, 572, 616, 664, 716, 772,
+ 832, 896, 960}; /* 42 scfbands */
+
+static const SHORT sfb_16_120[16] = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ 32, 40, 48, 60, 72, 88, 108, 120}; /* 15 scfbands */
+
+static const SHORT sfb_8_960[41] = {0, 12, 24, 36, 48, 60, 72, 84, 96,
+ 108, 120, 132, 144, 156, 172, 188, 204, 220,
+ 236, 252, 268, 288, 308, 328, 348, 372, 396,
+ 420, 448, 476, 508, 544, 580, 620, 664, 712,
+ 764, 820, 880, 944, 960}; /* 40 scfbands */
+
+static const SHORT sfb_8_120[16] = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 60, 72, 88, 108, 120}; /* 15 scfbands */
+
+static const SHORT
+ sfb_96_768[] = {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}; /* 37 scfbands */
+static const SHORT sfb_96_96[] = {0, 4, 8, 12, 16, 20, 24,
+ 32, 40, 48, 64, 92, 96}; /* 12 scfbands */
+
+static const SHORT sfb_64_768[] =
+ {
+ 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, 768}; /* 41 scfbands */
+
+static const SHORT sfb_64_96[] = {0, 4, 8, 12, 16, 20, 24,
+ 32, 40, 48, 64, 92, 96}; /* 12 scfbands */
+
+static const SHORT
+ sfb_48_768[] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48,
+ 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176,
+ 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, 480, 512,
+ 544, 576, 608, 640, 672, 704, 736, 768}; /* 43 scfbands */
+
+static const SHORT sfb_48_96[] = {0, 4, 8, 12, 16, 20, 28,
+ 36, 44, 56, 68, 80, 96}; /* 12 scfbands */
+
+static const SHORT
+ sfb_32_768[] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48,
+ 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176,
+ 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, 480, 512,
+ 544, 576, 608, 640, 672, 704, 736, 768}; /* 43 scfbands */
+
+static const SHORT
+ sfb_24_768[] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
+ 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 136, 148,
+ 160, 172, 188, 204, 220, 240, 260, 284, 308, 336, 364, 396,
+ 432, 468, 508, 552, 600, 652, 704, 768}; /* 43 scfbands */
+
+static const SHORT sfb_24_96[] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 64, 76, 92, 96}; /* 14 scfbands */
+
+static const SHORT sfb_16_768[] = {0, 8, 16, 24, 32, 40, 48, 56, 64,
+ 72, 80, 88, 100, 112, 124, 136, 148, 160,
+ 172, 184, 196, 212, 228, 244, 260, 280, 300,
+ 320, 344, 368, 396, 424, 456, 492, 532, 572,
+ 616, 664, 716, 768}; /* 39 scfbands */
+
+static const SHORT sfb_16_96[] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 32, 40, 48, 60, 72, 88, 96}; /* 14 scfbands */
+
+static const SHORT
+ sfb_8_768[] = {0, 12, 24, 36, 48, 60, 72, 84, 96, 108,
+ 120, 132, 144, 156, 172, 188, 204, 220, 236, 252,
+ 268, 288, 308, 328, 348, 372, 396, 420, 448, 476,
+ 508, 544, 580, 620, 664, 712, 764, 768}; /* 37 scfbands */
+
+static const SHORT sfb_8_96[] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 60, 72, 88, 96}; /* 14 scfbands */
+
+static const SHORT sfb_48_512[37] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48,
+ 52, 56, 60, 68, 76, 84, 92, 100, 112, 124, 136, 148, 164,
+ 184, 208, 236, 268, 300, 332, 364, 396, 428, 460, 512}; /* 36 scfbands */
+static const SHORT
+ sfb_32_512[38] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 48, 52, 56, 64, 72, 80, 88, 96,
+ 108, 120, 132, 144, 160, 176, 192, 212, 236, 260,
+ 288, 320, 352, 384, 416, 448, 480, 512}; /* 37 scfbands */
+static const SHORT sfb_24_512[32] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40,
+ 44, 52, 60, 68, 80, 92, 104, 120, 140, 164, 192,
+ 224, 256, 288, 320, 352, 384, 416, 448, 480, 512}; /* 31 scfbands */
+
+static const SHORT sfb_48_480[36] = {
+ 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, 272, 304, 336, 368, 400, 432, 480}; /* 35 scfbands */
+static const SHORT
+ sfb_32_480[38] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 48, 52, 56, 60, 64, 72, 80, 88,
+ 96, 104, 112, 124, 136, 148, 164, 180, 200, 224,
+ 256, 288, 320, 352, 384, 416, 448, 480}; /* 37 scfbands */
+static const SHORT sfb_24_480[31] =
+ {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40,
+ 44, 52, 60, 68, 80, 92, 104, 120, 140, 164, 192,
+ 224, 256, 288, 320, 352, 384, 416, 448, 480}; /* 30 scfbands */
+
+const SFB_INFO sfbOffsetTables[5][16] = {{
+ {sfb_96_1024, sfb_96_128, 41, 12},
+ {sfb_96_1024, sfb_96_128, 41, 12},
+ {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_32_1024, sfb_48_128, 51, 14},
+ {sfb_24_1024, sfb_24_128, 47, 15},
+ {sfb_24_1024, sfb_24_128, 47, 15},
+ {sfb_16_1024, sfb_16_128, 43, 15},
+ {sfb_16_1024, sfb_16_128, 43, 15},
+ {sfb_16_1024, sfb_16_128, 43, 15},
+ {sfb_8_1024, sfb_8_128, 40, 15},
+ {sfb_8_1024, sfb_8_128, 40, 15},
+ },
+ {
+ {sfb_96_960, sfb_96_120, 40, 12},
+ {sfb_96_960, sfb_96_120, 40, 12},
+ {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_32_960, sfb_48_120, 49, 14},
+ {sfb_24_960, sfb_24_120, 46, 15},
+ {sfb_24_960, sfb_24_120, 46, 15},
+ {sfb_16_960, sfb_16_120, 42, 15},
+ {sfb_16_960, sfb_16_120, 42, 15},
+ {sfb_16_960, sfb_16_120, 42, 15},
+ {sfb_8_960, sfb_8_120, 40, 15},
+ {sfb_8_960, sfb_8_120, 40, 15},
+ },
+ {
+ {sfb_96_768, sfb_96_96, 37, 12},
+ {sfb_96_768, sfb_96_96, 37, 12},
+ {sfb_64_768, sfb_64_96, 41, 12},
+ {sfb_48_768, sfb_48_96, 43, 12},
+ {sfb_48_768, sfb_48_96, 43, 12},
+ {sfb_32_768, sfb_48_96, 43, 12},
+ {sfb_24_768, sfb_24_96, 43, 14},
+ {sfb_24_768, sfb_24_96, 43, 14},
+ {sfb_16_768, sfb_16_96, 39, 14},
+ {sfb_16_768, sfb_16_96, 39, 14},
+ {sfb_16_768, sfb_16_96, 39, 14},
+ {sfb_8_768, sfb_8_96, 37, 14},
+ {sfb_8_768, sfb_8_96, 37, 14},
+ },
+ {
+ {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_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 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_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ }};
+
+/*# don't use 1 bit hufman tables */
+/*
+ MPEG-2 AAC 2 BITS parallel Hufman Tables
+
+ Bit 0: = 1=ENDNODE, 0=INDEX
+ Bit 1: = CODEWORD LEN MOD 2
+ Bit 2..9: = VALUE/REF Tables 1..10,SCL
+ Bit 2..11: = VALUE/REF Table 11
+*/
+const USHORT HuffmanCodeBook_1[51][4] = {
+ {0x0157, 0x0157, 0x0004, 0x0018}, {0x0008, 0x000c, 0x0010, 0x0014},
+ {0x015b, 0x015b, 0x0153, 0x0153}, {0x0057, 0x0057, 0x0167, 0x0167},
+ {0x0257, 0x0257, 0x0117, 0x0117}, {0x0197, 0x0197, 0x0147, 0x0147},
+ {0x001c, 0x0030, 0x0044, 0x0058}, {0x0020, 0x0024, 0x0028, 0x002c},
+ {0x014b, 0x014b, 0x0163, 0x0163}, {0x0217, 0x0217, 0x0127, 0x0127},
+ {0x0187, 0x0187, 0x0097, 0x0097}, {0x016b, 0x016b, 0x0017, 0x0017},
+ {0x0034, 0x0038, 0x003c, 0x0040}, {0x0143, 0x0143, 0x0107, 0x0107},
+ {0x011b, 0x011b, 0x0067, 0x0067}, {0x0193, 0x0193, 0x0297, 0x0297},
+ {0x019b, 0x019b, 0x0247, 0x0247}, {0x0048, 0x004c, 0x0050, 0x0054},
+ {0x01a7, 0x01a7, 0x0267, 0x0267}, {0x0113, 0x0113, 0x025b, 0x025b},
+ {0x0053, 0x0053, 0x005b, 0x005b}, {0x0253, 0x0253, 0x0047, 0x0047},
+ {0x005c, 0x0070, 0x0084, 0x0098}, {0x0060, 0x0064, 0x0068, 0x006c},
+ {0x012b, 0x012b, 0x0123, 0x0123}, {0x018b, 0x018b, 0x00a7, 0x00a7},
+ {0x0227, 0x0227, 0x0287, 0x0287}, {0x0087, 0x0087, 0x010b, 0x010b},
+ {0x0074, 0x0078, 0x007c, 0x0080}, {0x021b, 0x021b, 0x0027, 0x0027},
+ {0x01a3, 0x01a3, 0x0093, 0x0093}, {0x0183, 0x0183, 0x0207, 0x0207},
+ {0x024b, 0x024b, 0x004b, 0x004b}, {0x0088, 0x008c, 0x0090, 0x0094},
+ {0x0063, 0x0063, 0x0103, 0x0103}, {0x0007, 0x0007, 0x02a7, 0x02a7},
+ {0x009b, 0x009b, 0x026b, 0x026b}, {0x0263, 0x0263, 0x01ab, 0x01ab},
+ {0x009c, 0x00a0, 0x00a4, 0x00b8}, {0x0241, 0x0011, 0x0069, 0x0019},
+ {0x0211, 0x0041, 0x0291, 0x0299}, {0x00a8, 0x00ac, 0x00b0, 0x00b4},
+ {0x008b, 0x008b, 0x0223, 0x0223}, {0x00a3, 0x00a3, 0x020b, 0x020b},
+ {0x02ab, 0x02ab, 0x0283, 0x0283}, {0x002b, 0x002b, 0x0083, 0x0083},
+ {0x00bc, 0x00c0, 0x00c4, 0x00c8}, {0x0003, 0x0003, 0x022b, 0x022b},
+ {0x028b, 0x028b, 0x02a3, 0x02a3}, {0x0023, 0x0023, 0x0203, 0x0203},
+ {0x000b, 0x000b, 0x00ab, 0x00ab}};
+
+const USHORT HuffmanCodeBook_2[39][4] = {
+ {0x0004, 0x000c, 0x0020, 0x0034}, {0x0157, 0x0157, 0x0159, 0x0008},
+ {0x0153, 0x0153, 0x0257, 0x0257}, {0x0010, 0x0014, 0x0018, 0x001c},
+ {0x0117, 0x0117, 0x0057, 0x0057}, {0x0147, 0x0147, 0x0197, 0x0197},
+ {0x0167, 0x0167, 0x0185, 0x0161}, {0x0125, 0x0095, 0x0065, 0x0215},
+ {0x0024, 0x0028, 0x002c, 0x0030}, {0x0051, 0x0149, 0x0119, 0x0141},
+ {0x0015, 0x0199, 0x0259, 0x0245}, {0x0191, 0x0265, 0x0105, 0x0251},
+ {0x0045, 0x0111, 0x0169, 0x01a5}, {0x0038, 0x0044, 0x0058, 0x006c},
+ {0x0295, 0x0059, 0x003c, 0x0040}, {0x0227, 0x0227, 0x021b, 0x021b},
+ {0x0123, 0x0123, 0x0087, 0x0087}, {0x0048, 0x004c, 0x0050, 0x0054},
+ {0x018b, 0x018b, 0x006b, 0x006b}, {0x029b, 0x029b, 0x01a3, 0x01a3},
+ {0x0207, 0x0207, 0x01ab, 0x01ab}, {0x0093, 0x0093, 0x0103, 0x0103},
+ {0x005c, 0x0060, 0x0064, 0x0068}, {0x0213, 0x0213, 0x010b, 0x010b},
+ {0x012b, 0x012b, 0x0249, 0x0061}, {0x0181, 0x0291, 0x0241, 0x0041},
+ {0x0005, 0x0099, 0x0019, 0x0025}, {0x0070, 0x0074, 0x0078, 0x0088},
+ {0x02a5, 0x0261, 0x0011, 0x00a5}, {0x0049, 0x0285, 0x0269, 0x0089},
+ {0x0221, 0x007c, 0x0080, 0x0084}, {0x020b, 0x020b, 0x0003, 0x0003},
+ {0x00a3, 0x00a3, 0x02a3, 0x02a3}, {0x02ab, 0x02ab, 0x0083, 0x0083},
+ {0x008c, 0x0090, 0x0094, 0x0098}, {0x028b, 0x028b, 0x0023, 0x0023},
+ {0x0283, 0x0283, 0x002b, 0x002b}, {0x000b, 0x000b, 0x0203, 0x0203},
+ {0x022b, 0x022b, 0x00ab, 0x00ab}};
+
+const USHORT HuffmanCodeBook_3[39][4] = {
+ {0x0003, 0x0003, 0x0004, 0x0008}, {0x0005, 0x0101, 0x0011, 0x0041},
+ {0x000c, 0x0010, 0x0014, 0x0020}, {0x0017, 0x0017, 0x0143, 0x0143},
+ {0x0051, 0x0111, 0x0045, 0x0151}, {0x0105, 0x0055, 0x0018, 0x001c},
+ {0x0157, 0x0157, 0x0147, 0x0147}, {0x0117, 0x0117, 0x0009, 0x0201},
+ {0x0024, 0x002c, 0x0040, 0x0054}, {0x0241, 0x0019, 0x0065, 0x0028},
+ {0x0183, 0x0183, 0x0193, 0x0193}, {0x0030, 0x0034, 0x0038, 0x003c},
+ {0x0027, 0x0027, 0x0253, 0x0253}, {0x005b, 0x005b, 0x0083, 0x0083},
+ {0x0063, 0x0063, 0x0093, 0x0093}, {0x0023, 0x0023, 0x0213, 0x0213},
+ {0x0044, 0x0048, 0x004c, 0x0050}, {0x004b, 0x004b, 0x0167, 0x0167},
+ {0x0163, 0x0163, 0x0097, 0x0097}, {0x0197, 0x0197, 0x0125, 0x0085},
+ {0x0185, 0x0121, 0x0159, 0x0255}, {0x0058, 0x005c, 0x0060, 0x0070},
+ {0x0119, 0x0245, 0x0281, 0x0291}, {0x0069, 0x00a5, 0x0205, 0x0109},
+ {0x01a1, 0x0064, 0x0068, 0x006c}, {0x002b, 0x002b, 0x01a7, 0x01a7},
+ {0x0217, 0x0217, 0x014b, 0x014b}, {0x0297, 0x0297, 0x016b, 0x016b},
+ {0x0074, 0x0078, 0x007c, 0x0080}, {0x00a3, 0x00a3, 0x0263, 0x0263},
+ {0x0285, 0x0129, 0x0099, 0x00a9}, {0x02a1, 0x01a9, 0x0199, 0x0265},
+ {0x02a5, 0x0084, 0x0088, 0x008c}, {0x0223, 0x0223, 0x008b, 0x008b},
+ {0x0227, 0x0227, 0x0189, 0x0259}, {0x0219, 0x0090, 0x0094, 0x0098},
+ {0x02ab, 0x02ab, 0x026b, 0x026b}, {0x029b, 0x029b, 0x024b, 0x024b},
+ {0x020b, 0x020b, 0x0229, 0x0289}};
+
+const USHORT HuffmanCodeBook_4[38][4] = {
+ {0x0004, 0x0008, 0x000c, 0x0018}, {0x0155, 0x0151, 0x0115, 0x0055},
+ {0x0145, 0x0005, 0x0015, 0x0001}, {0x0141, 0x0045, 0x0010, 0x0014},
+ {0x0107, 0x0107, 0x0053, 0x0053}, {0x0103, 0x0103, 0x0113, 0x0113},
+ {0x001c, 0x0020, 0x0034, 0x0048}, {0x0043, 0x0043, 0x0013, 0x0013},
+ {0x0024, 0x0028, 0x002c, 0x0030}, {0x015b, 0x015b, 0x0197, 0x0197},
+ {0x0167, 0x0167, 0x0257, 0x0257}, {0x005b, 0x005b, 0x011b, 0x011b},
+ {0x0067, 0x0067, 0x014b, 0x014b}, {0x0038, 0x003c, 0x0040, 0x0044},
+ {0x0193, 0x0193, 0x0251, 0x0095}, {0x0161, 0x0245, 0x0125, 0x0215},
+ {0x0185, 0x0019, 0x0049, 0x0025}, {0x0109, 0x0211, 0x0061, 0x0241},
+ {0x004c, 0x0050, 0x0058, 0x006c}, {0x0091, 0x0121, 0x0205, 0x0181},
+ {0x0085, 0x0009, 0x0201, 0x0054}, {0x0023, 0x0023, 0x0083, 0x0083},
+ {0x005c, 0x0060, 0x0064, 0x0068}, {0x01a7, 0x01a7, 0x016b, 0x016b},
+ {0x019b, 0x019b, 0x0297, 0x0297}, {0x0267, 0x0267, 0x025b, 0x025b},
+ {0x00a5, 0x0069, 0x0099, 0x01a1}, {0x0070, 0x0074, 0x0078, 0x0084},
+ {0x0291, 0x0129, 0x0261, 0x0189}, {0x0285, 0x01a9, 0x0225, 0x0249},
+ {0x0219, 0x02a5, 0x007c, 0x0080}, {0x029b, 0x029b, 0x026b, 0x026b},
+ {0x00a3, 0x00a3, 0x002b, 0x002b}, {0x0088, 0x008c, 0x0090, 0x0094},
+ {0x0283, 0x0283, 0x008b, 0x008b}, {0x0223, 0x0223, 0x020b, 0x020b},
+ {0x02ab, 0x02ab, 0x02a3, 0x02a3}, {0x00ab, 0x00ab, 0x0229, 0x0289}};
+
+const USHORT HuffmanCodeBook_5[41][4] = {
+ {0x0113, 0x0113, 0x0004, 0x0008}, {0x010d, 0x0115, 0x0151, 0x00d1},
+ {0x000c, 0x0010, 0x0014, 0x0028}, {0x00d7, 0x00d7, 0x014f, 0x014f},
+ {0x00cf, 0x00cf, 0x0157, 0x0157}, {0x0018, 0x001c, 0x0020, 0x0024},
+ {0x010b, 0x010b, 0x0193, 0x0193}, {0x011b, 0x011b, 0x0093, 0x0093},
+ {0x00c9, 0x0159, 0x008d, 0x0195}, {0x0149, 0x00d9, 0x018d, 0x0095},
+ {0x002c, 0x0030, 0x0044, 0x0058}, {0x0105, 0x011d, 0x0051, 0x01d1},
+ {0x0034, 0x0038, 0x003c, 0x0040}, {0x00c7, 0x00c7, 0x01d7, 0x01d7},
+ {0x015f, 0x015f, 0x004f, 0x004f}, {0x0147, 0x0147, 0x00df, 0x00df},
+ {0x0057, 0x0057, 0x01cf, 0x01cf}, {0x0048, 0x004c, 0x0050, 0x0054},
+ {0x018b, 0x018b, 0x019b, 0x019b}, {0x008b, 0x008b, 0x009b, 0x009b},
+ {0x0085, 0x009d, 0x01c9, 0x0059}, {0x019d, 0x01d9, 0x0185, 0x0049},
+ {0x005c, 0x0060, 0x0074, 0x0088}, {0x0011, 0x0101, 0x0161, 0x0121},
+ {0x0064, 0x0068, 0x006c, 0x0070}, {0x00c3, 0x00c3, 0x0213, 0x0213},
+ {0x00e3, 0x00e3, 0x000f, 0x000f}, {0x0217, 0x0217, 0x020f, 0x020f},
+ {0x0143, 0x0143, 0x0017, 0x0017}, {0x0078, 0x007c, 0x0080, 0x0084},
+ {0x005f, 0x005f, 0x0047, 0x0047}, {0x01c7, 0x01c7, 0x020b, 0x020b},
+ {0x0083, 0x0083, 0x01a3, 0x01a3}, {0x001b, 0x001b, 0x021b, 0x021b},
+ {0x008c, 0x0090, 0x0094, 0x0098}, {0x01df, 0x01df, 0x0183, 0x0183},
+ {0x0009, 0x00a1, 0x001d, 0x0041}, {0x01c1, 0x021d, 0x0205, 0x01e1},
+ {0x0061, 0x0005, 0x009c, 0x00a0}, {0x0023, 0x0023, 0x0203, 0x0203},
+ {0x0223, 0x0223, 0x0003, 0x0003}};
+
+const USHORT HuffmanCodeBook_6[40][4] = {
+ {0x0004, 0x0008, 0x000c, 0x001c}, {0x0111, 0x0115, 0x00d1, 0x0151},
+ {0x010d, 0x0155, 0x014d, 0x00d5}, {0x00cd, 0x0010, 0x0014, 0x0018},
+ {0x00d9, 0x0159, 0x0149, 0x00c9}, {0x0109, 0x018d, 0x0119, 0x0095},
+ {0x0195, 0x0091, 0x008d, 0x0191}, {0x0020, 0x0024, 0x0038, 0x004c},
+ {0x0099, 0x0189, 0x0089, 0x0199}, {0x0028, 0x002c, 0x0030, 0x0034},
+ {0x0147, 0x0147, 0x015f, 0x015f}, {0x00df, 0x00df, 0x01cf, 0x01cf},
+ {0x00c7, 0x00c7, 0x01d7, 0x01d7}, {0x0057, 0x0057, 0x004f, 0x004f},
+ {0x003c, 0x0040, 0x0044, 0x0048}, {0x011f, 0x011f, 0x0107, 0x0107},
+ {0x0053, 0x0053, 0x01d3, 0x01d3}, {0x019f, 0x019f, 0x0085, 0x01c9},
+ {0x01d9, 0x009d, 0x0059, 0x0049}, {0x0050, 0x005c, 0x0070, 0x0084},
+ {0x0185, 0x01dd, 0x0054, 0x0058}, {0x005f, 0x005f, 0x0047, 0x0047},
+ {0x01c7, 0x01c7, 0x0017, 0x0017}, {0x0060, 0x0064, 0x0068, 0x006c},
+ {0x000f, 0x000f, 0x0163, 0x0163}, {0x0143, 0x0143, 0x00c3, 0x00c3},
+ {0x0217, 0x0217, 0x00e3, 0x00e3}, {0x020f, 0x020f, 0x0013, 0x0013},
+ {0x0074, 0x0078, 0x007c, 0x0080}, {0x0183, 0x0183, 0x0083, 0x0083},
+ {0x021b, 0x021b, 0x000b, 0x000b}, {0x0103, 0x0103, 0x01a3, 0x01a3},
+ {0x00a3, 0x00a3, 0x020b, 0x020b}, {0x0088, 0x008c, 0x0090, 0x0094},
+ {0x0123, 0x0123, 0x001b, 0x001b}, {0x0213, 0x0213, 0x0005, 0x0205},
+ {0x001d, 0x0061, 0x021d, 0x01e1}, {0x01c1, 0x0041, 0x0098, 0x009c},
+ {0x0223, 0x0223, 0x0203, 0x0203}, {0x0003, 0x0003, 0x0023, 0x0023}};
+
+const USHORT HuffmanCodeBook_7[31][4] = {
+ {0x0003, 0x0003, 0x0004, 0x0008}, {0x0007, 0x0007, 0x0043, 0x0043},
+ {0x0045, 0x000c, 0x0010, 0x0024}, {0x0049, 0x0085, 0x0009, 0x0081},
+ {0x0014, 0x0018, 0x001c, 0x0020}, {0x004f, 0x004f, 0x00c7, 0x00c7},
+ {0x008b, 0x008b, 0x000f, 0x000f}, {0x00c3, 0x00c3, 0x00c9, 0x008d},
+ {0x0105, 0x0051, 0x0145, 0x0055}, {0x0028, 0x002c, 0x0040, 0x0054},
+ {0x00cd, 0x0109, 0x0101, 0x0011}, {0x0030, 0x0034, 0x0038, 0x003c},
+ {0x0093, 0x0093, 0x014b, 0x014b}, {0x0097, 0x0097, 0x0143, 0x0143},
+ {0x005b, 0x005b, 0x0017, 0x0017}, {0x0187, 0x0187, 0x00d3, 0x00d3},
+ {0x0044, 0x0048, 0x004c, 0x0050}, {0x014f, 0x014f, 0x010f, 0x010f},
+ {0x00d7, 0x00d7, 0x018b, 0x018b}, {0x009b, 0x009b, 0x01c7, 0x01c7},
+ {0x018d, 0x0181, 0x0019, 0x0111}, {0x0058, 0x005c, 0x0060, 0x0068},
+ {0x005d, 0x0151, 0x009d, 0x0115}, {0x00d9, 0x01c9, 0x00dd, 0x0119},
+ {0x0155, 0x0191, 0x01cd, 0x0064}, {0x001f, 0x001f, 0x01c3, 0x01c3},
+ {0x006c, 0x0070, 0x0074, 0x0078}, {0x015b, 0x015b, 0x0197, 0x0197},
+ {0x011f, 0x011f, 0x01d3, 0x01d3}, {0x01d7, 0x01d7, 0x015f, 0x015f},
+ {0x019d, 0x0199, 0x01d9, 0x01dd}};
+
+const USHORT HuffmanCodeBook_8[31][4] = {
+ {0x0004, 0x0008, 0x0010, 0x0024}, {0x0047, 0x0047, 0x0049, 0x0005},
+ {0x0085, 0x0041, 0x0089, 0x000c}, {0x0003, 0x0003, 0x000b, 0x000b},
+ {0x0014, 0x0018, 0x001c, 0x0020}, {0x0083, 0x0083, 0x004f, 0x004f},
+ {0x00c7, 0x00c7, 0x008f, 0x008f}, {0x00cb, 0x00cb, 0x00cd, 0x0051},
+ {0x0105, 0x0091, 0x0109, 0x000d}, {0x0028, 0x002c, 0x0040, 0x0054},
+ {0x00c1, 0x00d1, 0x010d, 0x0095}, {0x0030, 0x0034, 0x0038, 0x003c},
+ {0x0057, 0x0057, 0x014b, 0x014b}, {0x0147, 0x0147, 0x00d7, 0x00d7},
+ {0x014f, 0x014f, 0x0113, 0x0113}, {0x0117, 0x0117, 0x0103, 0x0103},
+ {0x0044, 0x0048, 0x004c, 0x0050}, {0x0153, 0x0153, 0x0013, 0x0013},
+ {0x018b, 0x018b, 0x009b, 0x009b}, {0x005b, 0x005b, 0x0187, 0x0187},
+ {0x018d, 0x00d9, 0x0155, 0x0015}, {0x0058, 0x005c, 0x0060, 0x0068},
+ {0x0119, 0x0141, 0x0191, 0x005d}, {0x009d, 0x01c9, 0x0159, 0x00dd},
+ {0x01c5, 0x0195, 0x01cd, 0x0064}, {0x019b, 0x019b, 0x011f, 0x011f},
+ {0x006c, 0x0070, 0x0074, 0x0078}, {0x001b, 0x001b, 0x01d3, 0x01d3},
+ {0x0183, 0x0183, 0x015f, 0x015f}, {0x019f, 0x019f, 0x01db, 0x01db},
+ {0x01d5, 0x001d, 0x01c1, 0x01dd}};
+
+const USHORT HuffmanCodeBook_9[84][4] = {
+ {0x0003, 0x0003, 0x0004, 0x0008}, {0x0007, 0x0007, 0x0043, 0x0043},
+ {0x0045, 0x000c, 0x0010, 0x002c}, {0x0049, 0x0085, 0x0009, 0x0081},
+ {0x0014, 0x0018, 0x001c, 0x0020}, {0x004f, 0x004f, 0x008b, 0x008b},
+ {0x00c7, 0x00c7, 0x000d, 0x00c1}, {0x00c9, 0x008d, 0x0105, 0x0051},
+ {0x0109, 0x0145, 0x0024, 0x0028}, {0x0093, 0x0093, 0x00cf, 0x00cf},
+ {0x0103, 0x0103, 0x0013, 0x0013}, {0x0030, 0x0044, 0x0058, 0x00a4},
+ {0x0034, 0x0038, 0x003c, 0x0040}, {0x0057, 0x0057, 0x014b, 0x014b},
+ {0x0187, 0x0187, 0x010f, 0x010f}, {0x0097, 0x0097, 0x005b, 0x005b},
+ {0x00d3, 0x00d3, 0x0141, 0x0189}, {0x0048, 0x004c, 0x0050, 0x0054},
+ {0x0015, 0x01c5, 0x014d, 0x0205}, {0x0061, 0x0111, 0x00d5, 0x0099},
+ {0x005d, 0x0181, 0x00a1, 0x0209}, {0x018d, 0x01c9, 0x0151, 0x0065},
+ {0x005c, 0x0068, 0x007c, 0x0090}, {0x0245, 0x009d, 0x0060, 0x0064},
+ {0x001b, 0x001b, 0x0117, 0x0117}, {0x00db, 0x00db, 0x00e3, 0x00e3},
+ {0x006c, 0x0070, 0x0074, 0x0078}, {0x01c3, 0x01c3, 0x00a7, 0x00a7},
+ {0x020f, 0x020f, 0x0193, 0x0193}, {0x01cf, 0x01cf, 0x0203, 0x0203},
+ {0x006b, 0x006b, 0x011b, 0x011b}, {0x0080, 0x0084, 0x0088, 0x008c},
+ {0x024b, 0x024b, 0x0157, 0x0157}, {0x0023, 0x0023, 0x001f, 0x001f},
+ {0x00df, 0x00df, 0x00ab, 0x00ab}, {0x00e7, 0x00e7, 0x0123, 0x0123},
+ {0x0094, 0x0098, 0x009c, 0x00a0}, {0x0287, 0x0287, 0x011f, 0x011f},
+ {0x015b, 0x015b, 0x0197, 0x0197}, {0x0213, 0x0213, 0x01d3, 0x01d3},
+ {0x024f, 0x024f, 0x006f, 0x006f}, {0x00a8, 0x00bc, 0x00d0, 0x00f4},
+ {0x00ac, 0x00b0, 0x00b4, 0x00b8}, {0x0217, 0x0217, 0x0027, 0x0027},
+ {0x0163, 0x0163, 0x00e9, 0x0289}, {0x0241, 0x00ad, 0x0125, 0x0199},
+ {0x0071, 0x0251, 0x01a1, 0x02c5}, {0x00c0, 0x00c4, 0x00c8, 0x00cc},
+ {0x0165, 0x0129, 0x01d5, 0x015d}, {0x02c9, 0x0305, 0x00b1, 0x00ed},
+ {0x028d, 0x0255, 0x01d9, 0x01e1}, {0x012d, 0x0281, 0x019d, 0x00f1},
+ {0x00d4, 0x00d8, 0x00dc, 0x00e0}, {0x0029, 0x0169, 0x0291, 0x0219},
+ {0x0309, 0x01a5, 0x01e5, 0x02d1}, {0x002d, 0x0259, 0x02cd, 0x0295},
+ {0x00e4, 0x00e8, 0x00ec, 0x00f0}, {0x0223, 0x0223, 0x021f, 0x021f},
+ {0x0173, 0x0173, 0x030f, 0x030f}, {0x016f, 0x016f, 0x01df, 0x01df},
+ {0x0133, 0x0133, 0x01af, 0x01af}, {0x00f8, 0x010c, 0x0120, 0x0134},
+ {0x00fc, 0x0100, 0x0104, 0x0108}, {0x01ab, 0x01ab, 0x0313, 0x0313},
+ {0x025f, 0x025f, 0x02d7, 0x02d7}, {0x02c3, 0x02c3, 0x01b3, 0x01b3},
+ {0x029b, 0x029b, 0x0033, 0x0033}, {0x0110, 0x0114, 0x0118, 0x011c},
+ {0x01eb, 0x01eb, 0x0317, 0x0317}, {0x029f, 0x029f, 0x0227, 0x0227},
+ {0x0303, 0x0303, 0x01ef, 0x01ef}, {0x0263, 0x0263, 0x0267, 0x0267},
+ {0x0124, 0x0128, 0x012c, 0x0130}, {0x022b, 0x022b, 0x02df, 0x02df},
+ {0x01f3, 0x01f3, 0x02db, 0x02db}, {0x02e3, 0x02e3, 0x022f, 0x022f},
+ {0x031f, 0x031f, 0x031b, 0x031b}, {0x0138, 0x013c, 0x0140, 0x0144},
+ {0x02a1, 0x0269, 0x0321, 0x02a5}, {0x02e5, 0x0325, 0x02e9, 0x0271},
+ {0x02a9, 0x026d, 0x0231, 0x02ad}, {0x02b1, 0x02f1, 0x0148, 0x014c},
+ {0x032b, 0x032b, 0x02ef, 0x02ef}, {0x032f, 0x032f, 0x0333, 0x0333}};
+
+const USHORT HuffmanCodeBook_10[82][4] = {
+ {0x0004, 0x000c, 0x0020, 0x004c}, {0x0045, 0x0085, 0x0049, 0x0008},
+ {0x008b, 0x008b, 0x0007, 0x0007}, {0x0010, 0x0014, 0x0018, 0x001c},
+ {0x0043, 0x0043, 0x00c7, 0x00c7}, {0x008f, 0x008f, 0x004f, 0x004f},
+ {0x00cb, 0x00cb, 0x00cf, 0x00cf}, {0x0009, 0x0081, 0x0109, 0x0091},
+ {0x0024, 0x0028, 0x002c, 0x0038}, {0x0105, 0x0051, 0x0001, 0x00d1},
+ {0x010d, 0x000d, 0x00c1, 0x0111}, {0x0149, 0x0095, 0x0030, 0x0034},
+ {0x0147, 0x0147, 0x0057, 0x0057}, {0x00d7, 0x00d7, 0x014f, 0x014f},
+ {0x003c, 0x0040, 0x0044, 0x0048}, {0x0117, 0x0117, 0x0153, 0x0153},
+ {0x009b, 0x009b, 0x018b, 0x018b}, {0x00db, 0x00db, 0x0013, 0x0013},
+ {0x005b, 0x005b, 0x0103, 0x0103}, {0x0050, 0x0064, 0x0078, 0x00c0},
+ {0x0054, 0x0058, 0x005c, 0x0060}, {0x0187, 0x0187, 0x018f, 0x018f},
+ {0x0157, 0x0157, 0x011b, 0x011b}, {0x0193, 0x0193, 0x0159, 0x009d},
+ {0x01cd, 0x01c9, 0x0195, 0x00a1}, {0x0068, 0x006c, 0x0070, 0x0074},
+ {0x00dd, 0x0015, 0x005d, 0x0141}, {0x0061, 0x01c5, 0x00e1, 0x011d},
+ {0x01d1, 0x0209, 0x0199, 0x015d}, {0x0205, 0x020d, 0x0121, 0x0211},
+ {0x007c, 0x0084, 0x0098, 0x00ac}, {0x01d5, 0x0161, 0x0215, 0x0080},
+ {0x019f, 0x019f, 0x01db, 0x01db}, {0x0088, 0x008c, 0x0090, 0x0094},
+ {0x00a7, 0x00a7, 0x001b, 0x001b}, {0x021b, 0x021b, 0x00e7, 0x00e7},
+ {0x024f, 0x024f, 0x0067, 0x0067}, {0x024b, 0x024b, 0x0183, 0x0183},
+ {0x009c, 0x00a0, 0x00a4, 0x00a8}, {0x01a3, 0x01a3, 0x0127, 0x0127},
+ {0x0253, 0x0253, 0x00ab, 0x00ab}, {0x0247, 0x0247, 0x01df, 0x01df},
+ {0x01e3, 0x01e3, 0x0167, 0x0167}, {0x00b0, 0x00b4, 0x00b8, 0x00bc},
+ {0x021f, 0x021f, 0x00eb, 0x00eb}, {0x0257, 0x0257, 0x012b, 0x012b},
+ {0x028b, 0x028b, 0x006b, 0x006b}, {0x028f, 0x028f, 0x01a7, 0x01a7},
+ {0x00c4, 0x00d8, 0x00ec, 0x0100}, {0x00c8, 0x00cc, 0x00d0, 0x00d4},
+ {0x025b, 0x025b, 0x0023, 0x0023}, {0x0293, 0x0293, 0x001f, 0x001f},
+ {0x00af, 0x00af, 0x025d, 0x00ed}, {0x01a9, 0x0285, 0x006d, 0x01e5},
+ {0x00dc, 0x00e0, 0x00e4, 0x00e8}, {0x01c1, 0x0221, 0x0169, 0x02cd},
+ {0x0295, 0x0261, 0x016d, 0x0201}, {0x012d, 0x02c9, 0x029d, 0x0299},
+ {0x01e9, 0x02d1, 0x02c5, 0x00b1}, {0x00f0, 0x00f4, 0x00f8, 0x00fc},
+ {0x0225, 0x00f1, 0x01ad, 0x02d5}, {0x0131, 0x01ed, 0x0171, 0x030d},
+ {0x02d9, 0x0025, 0x0229, 0x0029}, {0x0071, 0x0241, 0x0311, 0x0265},
+ {0x0104, 0x010c, 0x0120, 0x0134}, {0x01b1, 0x0309, 0x02a1, 0x0108},
+ {0x02a7, 0x02a7, 0x0307, 0x0307}, {0x0110, 0x0114, 0x0118, 0x011c},
+ {0x022f, 0x022f, 0x01f3, 0x01f3}, {0x02df, 0x02df, 0x0317, 0x0317},
+ {0x031b, 0x031b, 0x026b, 0x026b}, {0x02e3, 0x02e3, 0x0233, 0x0233},
+ {0x0124, 0x0128, 0x012c, 0x0130}, {0x0283, 0x0283, 0x031f, 0x031f},
+ {0x002f, 0x002f, 0x02ab, 0x02ab}, {0x026f, 0x026f, 0x02af, 0x02af},
+ {0x02c3, 0x02c3, 0x02ef, 0x02ef}, {0x0138, 0x013c, 0x0140, 0x0144},
+ {0x02e7, 0x02e7, 0x02eb, 0x02eb}, {0x0033, 0x0033, 0x0323, 0x0323},
+ {0x0271, 0x0329, 0x0325, 0x032d}, {0x02f1, 0x0301, 0x02b1, 0x0331}};
+
+const USHORT HuffmanCodeBook_11[152][4] = {
+ {0x0004, 0x0010, 0x0038, 0x008c}, {0x0001, 0x0085, 0x0008, 0x000c},
+ {0x0843, 0x0843, 0x0007, 0x0007}, {0x0083, 0x0083, 0x008b, 0x008b},
+ {0x0014, 0x0018, 0x001c, 0x0024}, {0x0107, 0x0107, 0x010b, 0x010b},
+ {0x0185, 0x008d, 0x010d, 0x0009}, {0x0189, 0x0101, 0x018d, 0x0020},
+ {0x0093, 0x0093, 0x0207, 0x0207}, {0x0028, 0x002c, 0x0030, 0x0034},
+ {0x0113, 0x0113, 0x020b, 0x020b}, {0x0193, 0x0193, 0x020f, 0x020f},
+ {0x000f, 0x000f, 0x0183, 0x0183}, {0x0097, 0x0097, 0x0117, 0x0117},
+ {0x003c, 0x0050, 0x0064, 0x0078}, {0x0040, 0x0044, 0x0048, 0x004c},
+ {0x028b, 0x028b, 0x0213, 0x0213}, {0x0287, 0x0287, 0x0197, 0x0197},
+ {0x028f, 0x028f, 0x0217, 0x0217}, {0x0291, 0x0119, 0x0309, 0x0099},
+ {0x0054, 0x0058, 0x005c, 0x0060}, {0x0199, 0x030d, 0x0305, 0x0811},
+ {0x080d, 0x02c1, 0x01c1, 0x0241}, {0x0219, 0x0341, 0x0011, 0x0311},
+ {0x0201, 0x0809, 0x0295, 0x0815}, {0x0068, 0x006c, 0x0070, 0x0074},
+ {0x03c1, 0x0141, 0x0441, 0x0389}, {0x011d, 0x038d, 0x0299, 0x0315},
+ {0x0819, 0x0541, 0x019d, 0x009d}, {0x04c1, 0x081d, 0x0805, 0x0385},
+ {0x007c, 0x0080, 0x0084, 0x0088}, {0x0391, 0x05c1, 0x021d, 0x0641},
+ {0x0821, 0x00c1, 0x0319, 0x0825}, {0x0409, 0x0395, 0x0829, 0x06c1},
+ {0x01a1, 0x0121, 0x040d, 0x0015}, {0x0090, 0x00c8, 0x011c, 0x0170},
+ {0x0094, 0x0098, 0x00a0, 0x00b4}, {0x0741, 0x082d, 0x029d, 0x0411},
+ {0x0399, 0x031d, 0x0281, 0x009c}, {0x0223, 0x0223, 0x07c3, 0x07c3},
+ {0x00a4, 0x00a8, 0x00ac, 0x00b0}, {0x0833, 0x0833, 0x0407, 0x0407},
+ {0x00a3, 0x00a3, 0x083b, 0x083b}, {0x0417, 0x0417, 0x0837, 0x0837},
+ {0x048f, 0x048f, 0x02a3, 0x02a3}, {0x00b8, 0x00bc, 0x00c0, 0x00c4},
+ {0x039f, 0x039f, 0x048b, 0x048b}, {0x0323, 0x0323, 0x0127, 0x0127},
+ {0x01a7, 0x01a7, 0x083f, 0x083f}, {0x0493, 0x0493, 0x041b, 0x041b},
+ {0x00cc, 0x00e0, 0x00f4, 0x0108}, {0x00d0, 0x00d4, 0x00d8, 0x00dc},
+ {0x001b, 0x001b, 0x0227, 0x0227}, {0x0497, 0x0497, 0x03a3, 0x03a3},
+ {0x041f, 0x041f, 0x0487, 0x0487}, {0x01ab, 0x01ab, 0x0303, 0x0303},
+ {0x00e4, 0x00e8, 0x00ec, 0x00f0}, {0x012b, 0x012b, 0x00a7, 0x00a7},
+ {0x02a7, 0x02a7, 0x0513, 0x0513}, {0x050b, 0x050b, 0x0327, 0x0327},
+ {0x050f, 0x050f, 0x049b, 0x049b}, {0x00f8, 0x00fc, 0x0100, 0x0104},
+ {0x022b, 0x022b, 0x0423, 0x0423}, {0x02ab, 0x02ab, 0x03a7, 0x03a7},
+ {0x01af, 0x01af, 0x0507, 0x0507}, {0x001f, 0x001f, 0x032b, 0x032b},
+ {0x010c, 0x0110, 0x0114, 0x0118}, {0x049f, 0x049f, 0x058f, 0x058f},
+ {0x0517, 0x0517, 0x00ab, 0x00ab}, {0x0593, 0x0593, 0x012f, 0x012f},
+ {0x0137, 0x0137, 0x051b, 0x051b}, {0x0120, 0x0134, 0x0148, 0x015c},
+ {0x0124, 0x0128, 0x012c, 0x0130}, {0x01b7, 0x01b7, 0x058b, 0x058b},
+ {0x0043, 0x0043, 0x0597, 0x0597}, {0x02af, 0x02af, 0x022d, 0x0425},
+ {0x051d, 0x04a1, 0x0801, 0x0691}, {0x0138, 0x013c, 0x0140, 0x0144},
+ {0x0381, 0x068d, 0x032d, 0x00b5}, {0x0235, 0x01b1, 0x0689, 0x02b5},
+ {0x0521, 0x0599, 0x0429, 0x03a9}, {0x0139, 0x0231, 0x0585, 0x0611},
+ {0x014c, 0x0150, 0x0154, 0x0158}, {0x00ad, 0x060d, 0x0685, 0x0131},
+ {0x059d, 0x070d, 0x0615, 0x0695}, {0x0239, 0x0711, 0x03ad, 0x01b9},
+ {0x02b1, 0x0335, 0x0331, 0x0021}, {0x0160, 0x0164, 0x0168, 0x016c},
+ {0x042d, 0x0609, 0x04a5, 0x02b9}, {0x0699, 0x0529, 0x013d, 0x05a1},
+ {0x0525, 0x0339, 0x04a9, 0x0715}, {0x04ad, 0x00b9, 0x0709, 0x0619},
+ {0x0174, 0x0188, 0x019c, 0x01cc}, {0x0178, 0x017c, 0x0180, 0x0184},
+ {0x0605, 0x0435, 0x0401, 0x03b5}, {0x061d, 0x03b1, 0x069d, 0x01bd},
+ {0x00b1, 0x0719, 0x0789, 0x02bd}, {0x023d, 0x0705, 0x05a5, 0x0791},
+ {0x018c, 0x0190, 0x0194, 0x0198}, {0x03b9, 0x06a1, 0x04b5, 0x0621},
+ {0x0795, 0x078d, 0x05a9, 0x052d}, {0x0431, 0x033d, 0x03bd, 0x0721},
+ {0x00bd, 0x071d, 0x0025, 0x0481}, {0x01a0, 0x01a4, 0x01a8, 0x01b8},
+ {0x06a5, 0x0625, 0x04b1, 0x0439}, {0x06a9, 0x04b9, 0x0531, 0x0799},
+ {0x079d, 0x01ac, 0x01b0, 0x01b4}, {0x0727, 0x0727, 0x043f, 0x043f},
+ {0x05af, 0x05af, 0x072f, 0x072f}, {0x0787, 0x0787, 0x062b, 0x062b},
+ {0x01bc, 0x01c0, 0x01c4, 0x01c8}, {0x072b, 0x072b, 0x05b7, 0x05b7},
+ {0x0537, 0x0537, 0x06af, 0x06af}, {0x062f, 0x062f, 0x07a3, 0x07a3},
+ {0x05bb, 0x05bb, 0x0637, 0x0637}, {0x01d0, 0x01e4, 0x01f8, 0x020c},
+ {0x01d4, 0x01d8, 0x01dc, 0x01e0}, {0x06b3, 0x06b3, 0x04bf, 0x04bf},
+ {0x053b, 0x053b, 0x002b, 0x002b}, {0x05b3, 0x05b3, 0x07a7, 0x07a7},
+ {0x0503, 0x0503, 0x0633, 0x0633}, {0x01e8, 0x01ec, 0x01f0, 0x01f4},
+ {0x002f, 0x002f, 0x0733, 0x0733}, {0x07ab, 0x07ab, 0x06b7, 0x06b7},
+ {0x0683, 0x0683, 0x063b, 0x063b}, {0x053f, 0x053f, 0x05bf, 0x05bf},
+ {0x01fc, 0x0200, 0x0204, 0x0208}, {0x07af, 0x07af, 0x06bb, 0x06bb},
+ {0x0037, 0x0037, 0x0583, 0x0583}, {0x0737, 0x0737, 0x063f, 0x063f},
+ {0x06bf, 0x06bf, 0x07b3, 0x07b3}, {0x0210, 0x0214, 0x0218, 0x021c},
+ {0x003b, 0x003b, 0x073b, 0x073b}, {0x07b7, 0x07b7, 0x0033, 0x0033},
+ {0x07bb, 0x07bb, 0x0701, 0x0601}, {0x073d, 0x003d, 0x0781, 0x07bd},
+ {0x0118, 0x0117, 0x0100, 0x0109}, {0x05a5, 0x05a1, 0x05b7, 0x0513},
+ {0x08f9, 0x08ff, 0x0821, 0x08ff}, {0x084f, 0x08ff, 0x08bc, 0x08ff},
+ {0x0815, 0x08ff, 0x0837, 0x08ff}, {0x080d, 0x08ff, 0x085f, 0x08ff},
+ {0x084a, 0x08ff, 0x087d, 0x08ff}, {0x08ff, 0x08ff, 0x08a8, 0x08ff},
+ {0x0815, 0x08ff, 0x083f, 0x08ff}, {0x0830, 0x08ff, 0x0894, 0x08ff},
+ {0x08d4, 0x08ff, 0x0825, 0x08ff}, {0x08ef, 0x08ff, 0x083f, 0x08ff},
+ {0x0809, 0x08ff, 0x08fc, 0x08ff}, {0x0842, 0x08ff, 0x08b3, 0x08ff},
+ {0x070d, 0x07a9, 0x060e, 0x06e2}, {0x06c7, 0x06d0, 0x04b2, 0x0407}};
+
+const USHORT HuffmanCodeBook_SCL[65][4] = {
+ {0x00f3, 0x00f3, 0x0004, 0x0008}, {0x00ef, 0x00ef, 0x00f5, 0x00e9},
+ {0x00f9, 0x000c, 0x0010, 0x0014}, {0x00e7, 0x00e7, 0x00ff, 0x00ff},
+ {0x00e1, 0x0101, 0x00dd, 0x0105}, {0x0018, 0x001c, 0x0020, 0x0028},
+ {0x010b, 0x010b, 0x00db, 0x00db}, {0x010f, 0x010f, 0x00d5, 0x0111},
+ {0x00d1, 0x0115, 0x00cd, 0x0024}, {0x011b, 0x011b, 0x00cb, 0x00cb},
+ {0x002c, 0x0030, 0x0034, 0x0040}, {0x00c7, 0x00c7, 0x011f, 0x011f},
+ {0x0121, 0x00c1, 0x0125, 0x00bd}, {0x0129, 0x00b9, 0x0038, 0x003c},
+ {0x0133, 0x0133, 0x012f, 0x012f}, {0x0137, 0x0137, 0x013b, 0x013b},
+ {0x0044, 0x0048, 0x004c, 0x0058}, {0x00b7, 0x00b7, 0x00af, 0x00af},
+ {0x00b1, 0x013d, 0x00a9, 0x00a5}, {0x0141, 0x00a1, 0x0050, 0x0054},
+ {0x0147, 0x0147, 0x009f, 0x009f}, {0x014b, 0x014b, 0x009b, 0x009b},
+ {0x005c, 0x0060, 0x0064, 0x0070}, {0x014f, 0x014f, 0x0095, 0x008d},
+ {0x0155, 0x0085, 0x0091, 0x0089}, {0x0151, 0x0081, 0x0068, 0x006c},
+ {0x015f, 0x015f, 0x0167, 0x0167}, {0x007b, 0x007b, 0x007f, 0x007f},
+ {0x0074, 0x0078, 0x0080, 0x00b0}, {0x0159, 0x0075, 0x0069, 0x006d},
+ {0x0071, 0x0061, 0x0161, 0x007c}, {0x0067, 0x0067, 0x005b, 0x005b},
+ {0x0084, 0x0088, 0x008c, 0x009c}, {0x005f, 0x005f, 0x0169, 0x0055},
+ {0x004d, 0x000d, 0x0005, 0x0009}, {0x0001, 0x0090, 0x0094, 0x0098},
+ {0x018b, 0x018b, 0x018f, 0x018f}, {0x0193, 0x0193, 0x0197, 0x0197},
+ {0x019b, 0x019b, 0x01d7, 0x01d7}, {0x00a0, 0x00a4, 0x00a8, 0x00ac},
+ {0x0187, 0x0187, 0x016f, 0x016f}, {0x0173, 0x0173, 0x0177, 0x0177},
+ {0x017b, 0x017b, 0x017f, 0x017f}, {0x0183, 0x0183, 0x01a3, 0x01a3},
+ {0x00b4, 0x00c8, 0x00dc, 0x00f0}, {0x00b8, 0x00bc, 0x00c0, 0x00c4},
+ {0x01bf, 0x01bf, 0x01c3, 0x01c3}, {0x01c7, 0x01c7, 0x01cb, 0x01cb},
+ {0x01cf, 0x01cf, 0x01d3, 0x01d3}, {0x01bb, 0x01bb, 0x01a7, 0x01a7},
+ {0x00cc, 0x00d0, 0x00d4, 0x00d8}, {0x01ab, 0x01ab, 0x01af, 0x01af},
+ {0x01b3, 0x01b3, 0x01b7, 0x01b7}, {0x01db, 0x01db, 0x001b, 0x001b},
+ {0x0023, 0x0023, 0x0027, 0x0027}, {0x00e0, 0x00e4, 0x00e8, 0x00ec},
+ {0x002b, 0x002b, 0x0017, 0x0017}, {0x019f, 0x019f, 0x01e3, 0x01e3},
+ {0x01df, 0x01df, 0x0013, 0x0013}, {0x001f, 0x001f, 0x003f, 0x003f},
+ {0x00f4, 0x00f8, 0x00fc, 0x0100}, {0x0043, 0x0043, 0x004b, 0x004b},
+ {0x0053, 0x0053, 0x0047, 0x0047}, {0x002f, 0x002f, 0x0033, 0x0033},
+ {0x003b, 0x003b, 0x0037, 0x0037}};
+
+/* .CodeBook = HuffmanCodeBook_x, .Dimension = 4, .numBits = 2, .Offset = 0 */
+const CodeBookDescription AACcodeBookDescriptionTable[13] = {
+ {NULL, 0, 0, 0},
+ {HuffmanCodeBook_1, 4, 2, 1},
+ {HuffmanCodeBook_2, 4, 2, 1},
+ {HuffmanCodeBook_3, 4, 2, 0},
+ {HuffmanCodeBook_4, 4, 2, 0},
+ {HuffmanCodeBook_5, 2, 4, 4},
+ {HuffmanCodeBook_6, 2, 4, 4},
+ {HuffmanCodeBook_7, 2, 4, 0},
+ {HuffmanCodeBook_8, 2, 4, 0},
+ {HuffmanCodeBook_9, 2, 4, 0},
+ {HuffmanCodeBook_10, 2, 4, 0},
+ {HuffmanCodeBook_11, 2, 5, 0},
+ {HuffmanCodeBook_SCL, 1, 8, 60}};
+
+const CodeBookDescription AACcodeBookDescriptionSCL = {HuffmanCodeBook_SCL, 1,
+ 8, 60};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree41 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 1). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 4) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 4 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* HuffTree */
+const UINT aHuffTree41[80] = {
+ 0x4a0001, 0x026002, 0x013003, 0x021004, 0x01c005, 0x00b006, 0x010007,
+ 0x019008, 0x00900e, 0x00a03a, 0x400528, 0x00c037, 0x00d03b, 0x454404,
+ 0x00f04c, 0x448408, 0x017011, 0x01202e, 0x42c40c, 0x034014, 0x01502c,
+ 0x016049, 0x410470, 0x01804e, 0x414424, 0x03201a, 0x02001b, 0x520418,
+ 0x02f01d, 0x02a01e, 0x01f04d, 0x41c474, 0x540420, 0x022024, 0x04a023,
+ 0x428510, 0x025029, 0x430508, 0x02703c, 0x028047, 0x50c434, 0x438478,
+ 0x04802b, 0x46443c, 0x02d03e, 0x4404b0, 0x44451c, 0x03003f, 0x03104b,
+ 0x52444c, 0x033039, 0x4f0450, 0x035041, 0x036046, 0x4e8458, 0x04f038,
+ 0x45c53c, 0x4604e0, 0x4f8468, 0x46c4d4, 0x04503d, 0x4ac47c, 0x518480,
+ 0x043040, 0x4844dc, 0x042044, 0x4884a8, 0x4bc48c, 0x530490, 0x4a4494,
+ 0x4984b8, 0x49c4c4, 0x5044b4, 0x5004c0, 0x4d04c8, 0x4f44cc, 0x4d8538,
+ 0x4ec4e4, 0x52c4fc, 0x514534};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree42 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 2). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 4) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 4 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree42[80] = {
+ 0x026001, 0x014002, 0x009003, 0x010004, 0x01d005, 0x00600d, 0x007018,
+ 0x450008, 0x4e0400, 0x02e00a, 0x03900b, 0x03d00c, 0x43c404, 0x01b00e,
+ 0x00f04f, 0x4d8408, 0x023011, 0x01203b, 0x01a013, 0x41440c, 0x015020,
+ 0x016040, 0x025017, 0x500410, 0x038019, 0x540418, 0x41c444, 0x02d01c,
+ 0x420520, 0x01e042, 0x03701f, 0x4244cc, 0x02a021, 0x02204c, 0x478428,
+ 0x024031, 0x42c4dc, 0x4304e8, 0x027033, 0x4a0028, 0x50c029, 0x4344a4,
+ 0x02c02b, 0x470438, 0x4404c8, 0x4f8448, 0x04902f, 0x04b030, 0x44c484,
+ 0x524032, 0x4ec454, 0x03e034, 0x035046, 0x4c4036, 0x488458, 0x4d445c,
+ 0x460468, 0x04e03a, 0x51c464, 0x03c04a, 0x46c514, 0x47453c, 0x04503f,
+ 0x47c4ac, 0x044041, 0x510480, 0x04304d, 0x4e448c, 0x490518, 0x49449c,
+ 0x048047, 0x4c0498, 0x4b84a8, 0x4b0508, 0x4fc4b4, 0x4bc504, 0x5304d0,
+ 0x5344f0, 0x4f452c, 0x528538};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree43 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 3). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 4) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 4 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree43[80] = {
+ 0x400001, 0x002004, 0x00300a, 0x46c404, 0x00b005, 0x00600d, 0x034007,
+ 0x037008, 0x494009, 0x4d8408, 0x42440c, 0x00c01b, 0x490410, 0x00e016,
+ 0x00f011, 0x010014, 0x4144fc, 0x01201d, 0x020013, 0x508418, 0x4c0015,
+ 0x41c440, 0x022017, 0x018026, 0x019035, 0x03801a, 0x420444, 0x01c01f,
+ 0x430428, 0x02101e, 0x44842c, 0x478434, 0x4b4438, 0x45443c, 0x02c023,
+ 0x039024, 0x02503f, 0x48844c, 0x030027, 0x02e028, 0x032029, 0x02a041,
+ 0x4d402b, 0x4504f0, 0x04302d, 0x4584a8, 0x02f03b, 0x46045c, 0x03103d,
+ 0x464046, 0x033044, 0x46853c, 0x47049c, 0x045036, 0x4744dc, 0x4a047c,
+ 0x500480, 0x4ac03a, 0x4b8484, 0x03c04e, 0x48c524, 0x03e040, 0x4984e8,
+ 0x50c4a4, 0x4b0530, 0x042047, 0x4bc04b, 0x4e44c4, 0x5184c8, 0x52c4cc,
+ 0x5204d0, 0x04d048, 0x04a049, 0x4e004c, 0x51c4ec, 0x4f4510, 0x5284f8,
+ 0x50404f, 0x514538, 0x540534};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree44 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 4). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 4) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 4 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree44[80] = {
+ 0x001004, 0x020002, 0x036003, 0x490400, 0x005008, 0x010006, 0x01f007,
+ 0x404428, 0x00e009, 0x01100a, 0x00b018, 0x01600c, 0x03700d, 0x408015,
+ 0x00f03e, 0x40c424, 0x410478, 0x022012, 0x038013, 0x01e014, 0x454414,
+ 0x448418, 0x025017, 0x47441c, 0x030019, 0x02601a, 0x02d01b, 0x01c034,
+ 0x01d029, 0x4204f0, 0x4dc42c, 0x470430, 0x02103c, 0x4a0434, 0x02302a,
+ 0x440024, 0x4384a8, 0x43c44c, 0x02703a, 0x02802c, 0x444524, 0x4504e0,
+ 0x02b03d, 0x458480, 0x45c4f4, 0x04b02e, 0x04f02f, 0x460520, 0x042031,
+ 0x048032, 0x049033, 0x514464, 0x03504c, 0x540468, 0x47c46c, 0x4844d8,
+ 0x039044, 0x4884fc, 0x03b045, 0x48c53c, 0x49449c, 0x4b8498, 0x03f046,
+ 0x041040, 0x4c44a4, 0x50c4ac, 0x04a043, 0x5184b0, 0x4e44b4, 0x4bc4ec,
+ 0x04e047, 0x4c04e8, 0x4c8510, 0x4cc52c, 0x4d0530, 0x5044d4, 0x53804d,
+ 0x5284f8, 0x508500, 0x51c534};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree21 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 5). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree21[80] = {
+ 0x450001, 0x044002, 0x042003, 0x035004, 0x026005, 0x022006, 0x013007,
+ 0x010008, 0x00d009, 0x01c00a, 0x01f00b, 0x01e00c, 0x4a0400, 0x01b00e,
+ 0x03200f, 0x47e402, 0x020011, 0x01204d, 0x40449c, 0x017014, 0x015019,
+ 0x01603f, 0x406458, 0x01804f, 0x448408, 0x04901a, 0x40a45a, 0x48c40c,
+ 0x01d031, 0x40e48e, 0x490410, 0x492412, 0x021030, 0x480414, 0x033023,
+ 0x02402e, 0x02503e, 0x416482, 0x02a027, 0x02802c, 0x029040, 0x418468,
+ 0x02b04a, 0x41a486, 0x02d048, 0x41c484, 0x04e02f, 0x41e426, 0x420434,
+ 0x42249e, 0x424494, 0x03d034, 0x428470, 0x039036, 0x03703b, 0x038041,
+ 0x42a476, 0x03a04b, 0x42c454, 0x03c047, 0x42e472, 0x430478, 0x43246e,
+ 0x496436, 0x488438, 0x43a466, 0x046043, 0x43c464, 0x04504c, 0x43e462,
+ 0x460440, 0x44245e, 0x45c444, 0x46a446, 0x44a456, 0x47444c, 0x45244e,
+ 0x46c47c, 0x48a47a, 0x49a498};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree22 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 6). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree22[80] = {
+ 0x03c001, 0x02f002, 0x020003, 0x01c004, 0x00f005, 0x00c006, 0x016007,
+ 0x04d008, 0x00b009, 0x01500a, 0x400490, 0x40e402, 0x00d013, 0x00e02a,
+ 0x40c404, 0x019010, 0x011041, 0x038012, 0x40a406, 0x014037, 0x40849c,
+ 0x4a0410, 0x04a017, 0x458018, 0x412422, 0x02801a, 0x01b029, 0x480414,
+ 0x02401d, 0x01e02b, 0x48a01f, 0x416432, 0x02d021, 0x026022, 0x023039,
+ 0x418468, 0x025043, 0x48641a, 0x027040, 0x41c488, 0x41e48c, 0x42045a,
+ 0x47c424, 0x04c02c, 0x46e426, 0x03602e, 0x428478, 0x030033, 0x43c031,
+ 0x04b032, 0x42e42a, 0x03403a, 0x035048, 0x42c442, 0x470430, 0x494434,
+ 0x43649a, 0x45c438, 0x04403b, 0x43a454, 0x04503d, 0x03e03f, 0x43e464,
+ 0x440460, 0x484444, 0x049042, 0x446448, 0x44a456, 0x46644c, 0x047046,
+ 0x44e452, 0x450462, 0x47445e, 0x46a496, 0x49846c, 0x472476, 0x47a482,
+ 0x04e04f, 0x47e492, 0x48e49e};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree23 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 7). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree23[63] = {
+ 0x400001, 0x002003, 0x410402, 0x004007, 0x412005, 0x01c006, 0x420404,
+ 0x00800b, 0x01d009, 0x00a01f, 0x406026, 0x00c012, 0x00d00f, 0x02700e,
+ 0x408440, 0x010022, 0x028011, 0x45440a, 0x013017, 0x029014, 0x024015,
+ 0x01602f, 0x43c40c, 0x02b018, 0x019033, 0x03201a, 0x43e01b, 0x47040e,
+ 0x422414, 0x01e025, 0x432416, 0x020021, 0x418442, 0x41a452, 0x036023,
+ 0x41c446, 0x46441e, 0x424430, 0x426434, 0x436428, 0x44442a, 0x02e02a,
+ 0x45642c, 0x03002c, 0x02d03b, 0x46642e, 0x43a438, 0x460448, 0x031037,
+ 0x47244a, 0x45a44c, 0x034039, 0x038035, 0x47844e, 0x462450, 0x474458,
+ 0x46a45c, 0x03a03c, 0x45e47a, 0x476468, 0x03d03e, 0x47c46c, 0x46e47e};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree24 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 8). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree24[63] = {
+ 0x001006, 0x01d002, 0x005003, 0x424004, 0x400420, 0x414402, 0x00700a,
+ 0x008020, 0x00901f, 0x404432, 0x00b011, 0x00c00e, 0x00d032, 0x406446,
+ 0x02300f, 0x033010, 0x458408, 0x025012, 0x013016, 0x01402f, 0x015038,
+ 0x46840a, 0x028017, 0x01801a, 0x039019, 0x40c47a, 0x03e01b, 0x03b01c,
+ 0x40e47e, 0x41201e, 0x422410, 0x416434, 0x02a021, 0x02202b, 0x418444,
+ 0x02c024, 0x41a456, 0x02d026, 0x027034, 0x46241c, 0x029036, 0x41e45c,
+ 0x426031, 0x428430, 0x45242a, 0x03702e, 0x42c464, 0x03003c, 0x47442e,
+ 0x436442, 0x438454, 0x43a448, 0x03503a, 0x43c466, 0x43e03d, 0x44a440,
+ 0x44c472, 0x46044e, 0x45a450, 0x45e470, 0x46a476, 0x46c478, 0x47c46e};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree25 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 9). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree25[168] = {
+ 0x400001, 0x002003, 0x41a402, 0x004007, 0x41c005, 0x035006, 0x434404,
+ 0x008010, 0x00900c, 0x04a00a, 0x42000b, 0x44e406, 0x03600d, 0x03800e,
+ 0x05a00f, 0x408468, 0x01101a, 0x012016, 0x039013, 0x070014, 0x46e015,
+ 0x40a440, 0x03b017, 0x01804d, 0x01904f, 0x4b840c, 0x01b022, 0x01c041,
+ 0x03f01d, 0x01e020, 0x01f05b, 0x40e4ee, 0x02107c, 0x45c410, 0x02302c,
+ 0x024028, 0x053025, 0x026045, 0x02707d, 0x412522, 0x047029, 0x05e02a,
+ 0x02b08a, 0x526414, 0x05602d, 0x02e081, 0x02f032, 0x06e030, 0x031080,
+ 0x416544, 0x079033, 0x034091, 0x41852c, 0x43641e, 0x04b037, 0x42246a,
+ 0x43c424, 0x04c03a, 0x426456, 0x03c066, 0x03d03e, 0x482428, 0x45842a,
+ 0x040072, 0x42c4ba, 0x050042, 0x04305c, 0x044074, 0x42e4be, 0x06a046,
+ 0x4dc430, 0x075048, 0x0490a3, 0x44a432, 0x450438, 0x43a452, 0x48443e,
+ 0x04e068, 0x45a442, 0x4d4444, 0x051088, 0x052087, 0x44648c, 0x077054,
+ 0x4da055, 0x50a448, 0x057060, 0x06b058, 0x05906d, 0x44c4f6, 0x46c454,
+ 0x45e474, 0x06905d, 0x460520, 0x05f07e, 0x462494, 0x061063, 0x07f062,
+ 0x464496, 0x06408b, 0x08d065, 0x542466, 0x067071, 0x4d2470, 0x4724ec,
+ 0x478476, 0x53a47a, 0x09b06c, 0x47c4ac, 0x4f847e, 0x06f078, 0x510480,
+ 0x48649e, 0x4884a0, 0x07307b, 0x49c48a, 0x4a648e, 0x098076, 0x4904c0,
+ 0x4924ea, 0x4c8498, 0x07a08e, 0x51249a, 0x4a24d6, 0x5064a4, 0x4f24a8,
+ 0x4aa4de, 0x51e4ae, 0x4b0538, 0x082092, 0x083085, 0x08f084, 0x5464b2,
+ 0x096086, 0x4ce4b4, 0x4d04b6, 0x089090, 0x4bc508, 0x4c253e, 0x08c0a4,
+ 0x5284c4, 0x4e04c6, 0x4ca4fa, 0x5144cc, 0x4f04d8, 0x4e24fc, 0x09309c,
+ 0x094099, 0x095097, 0x4e4516, 0x4e652e, 0x4e84fe, 0x4f450c, 0x09a09f,
+ 0x500502, 0x50450e, 0x09d0a0, 0x09e0a5, 0x518530, 0x51a54a, 0x0a70a1,
+ 0x0a20a6, 0x51c534, 0x53c524, 0x54052a, 0x548532, 0x536550, 0x54c54e};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree26 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 10). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree26[168] = {
+ 0x006001, 0x002013, 0x00300f, 0x00400d, 0x03b005, 0x40046e, 0x037007,
+ 0x00800a, 0x009067, 0x402420, 0x05600b, 0x00c057, 0x434404, 0x06600e,
+ 0x406470, 0x03c010, 0x059011, 0x06f012, 0x49e408, 0x014019, 0x03f015,
+ 0x016044, 0x017042, 0x079018, 0x4b840a, 0x01a01f, 0x01b047, 0x07c01c,
+ 0x08701d, 0x06901e, 0x44640c, 0x020027, 0x04b021, 0x02204f, 0x023025,
+ 0x02406b, 0x40e4e0, 0x081026, 0x528410, 0x02802c, 0x06c029, 0x08f02a,
+ 0x02b078, 0x53a412, 0x05202d, 0x02e033, 0x02f031, 0x0300a2, 0x4144ce,
+ 0x0a6032, 0x416534, 0x09a034, 0x09f035, 0x0360a7, 0x54e418, 0x03a038,
+ 0x436039, 0x43841a, 0x41c41e, 0x42246a, 0x05803d, 0x03e068, 0x424484,
+ 0x04005b, 0x04107a, 0x42645a, 0x043093, 0x4d2428, 0x05e045, 0x046072,
+ 0x42a45e, 0x048060, 0x073049, 0x04a098, 0x42c4c4, 0x07504c, 0x09504d,
+ 0x04e09c, 0x51042e, 0x063050, 0x077051, 0x43053c, 0x053084, 0x065054,
+ 0x4e4055, 0x4fe432, 0x43a454, 0x43c46c, 0x43e486, 0x07005a, 0x4a0440,
+ 0x07105c, 0x05d07b, 0x45c442, 0x05f08a, 0x476444, 0x07f061, 0x06206a,
+ 0x448506, 0x06408e, 0x52644a, 0x54444c, 0x45644e, 0x452450, 0x488458,
+ 0x4604ec, 0x4624f6, 0x50e464, 0x08206d, 0x0a406e, 0x542466, 0x4a2468,
+ 0x48a472, 0x474089, 0x4d8478, 0x097074, 0x47a508, 0x08d076, 0x47c4b6,
+ 0x51247e, 0x4804fc, 0x4bc482, 0x48c4a4, 0x48e4d4, 0x07d07e, 0x4904da,
+ 0x49208b, 0x094080, 0x49450c, 0x4964e2, 0x09d083, 0x52a498, 0x085091,
+ 0x0a5086, 0x4cc49a, 0x08808c, 0x4ee49c, 0x4a64ba, 0x4a84c0, 0x4c24aa,
+ 0x4ac4f0, 0x4ae4d0, 0x4ca4b0, 0x0900a1, 0x4b24ea, 0x092099, 0x4b4516,
+ 0x4d64be, 0x4c650a, 0x522096, 0x4c8524, 0x4dc4f2, 0x4de4f4, 0x4e6548,
+ 0x09e09b, 0x5384e8, 0x5204f8, 0x4fa53e, 0x50051a, 0x0a30a0, 0x502536,
+ 0x514504, 0x51e518, 0x54a51c, 0x54052c, 0x52e546, 0x530532, 0x54c550};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree27 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 11). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree27[288] = {
+ 0x00100d, 0x002006, 0x003004, 0x400424, 0x047005, 0x402446, 0x048007,
+ 0x00800a, 0x00904c, 0x44a404, 0x07400b, 0x00c0bb, 0x466406, 0x00e014,
+ 0x00f054, 0x04e010, 0x051011, 0x0a9012, 0x0130bc, 0x408464, 0x01501f,
+ 0x01601a, 0x017059, 0x0af018, 0x0ca019, 0x40a0e4, 0x01b05e, 0x01c084,
+ 0x0bf01d, 0x05d01e, 0x55a40c, 0x020026, 0x021066, 0x043022, 0x023062,
+ 0x02408d, 0x025108, 0x40e480, 0x027030, 0x02802c, 0x02906b, 0x02a0da,
+ 0x06502b, 0x4105c8, 0x0a402d, 0x0ec02e, 0x0dd02f, 0x532412, 0x06e031,
+ 0x032036, 0x03303e, 0x0fd034, 0x0fc035, 0x4145b0, 0x03703a, 0x038117,
+ 0x10d039, 0x5ba416, 0x10f03b, 0x03c041, 0x5fa03d, 0x41c418, 0x10403f,
+ 0x04011d, 0x41a5f4, 0x11c042, 0x41e61c, 0x087044, 0x0f5045, 0x0d9046,
+ 0x4204a2, 0x640422, 0x04904a, 0x426448, 0x04b073, 0x428468, 0x46c04d,
+ 0x48a42a, 0x04f077, 0x076050, 0x42c4b0, 0x0520a7, 0x096053, 0x42e4a8,
+ 0x05507d, 0x07a056, 0x0d4057, 0x0df058, 0x442430, 0x05a081, 0x05b09b,
+ 0x05c0e2, 0x5b8432, 0x4fe434, 0x05f09e, 0x0e6060, 0x0610d6, 0x57c436,
+ 0x0cc063, 0x112064, 0x4384a0, 0x43a5ca, 0x067089, 0x0680b7, 0x0690a2,
+ 0x0a106a, 0x43c59c, 0x09206c, 0x06d0ba, 0x60643e, 0x0d106f, 0x0700ee,
+ 0x0de071, 0x10b072, 0x44056c, 0x46a444, 0x075094, 0x48c44c, 0x44e490,
+ 0x095078, 0x0ab079, 0x4504ce, 0x07b097, 0x11e07c, 0x630452, 0x0ac07e,
+ 0x07f099, 0x080106, 0x4544b8, 0x0820b1, 0x0830e5, 0x4fc456, 0x0b3085,
+ 0x08609d, 0x45853e, 0x0880c2, 0x5c045a, 0x08a08f, 0x08b0ce, 0x08c0f7,
+ 0x58645c, 0x11108e, 0x45e5c4, 0x0c4090, 0x10a091, 0x4604e4, 0x0d0093,
+ 0x462608, 0x48e46e, 0x4704b2, 0x4d2472, 0x0980bd, 0x4f2474, 0x0e309a,
+ 0x4764aa, 0x0be09c, 0x47851a, 0x47a4de, 0x09f0b5, 0x0a00c1, 0x50047c,
+ 0x57847e, 0x0a30c3, 0x504482, 0x0e90a5, 0x0a6100, 0x4c8484, 0x0a811f,
+ 0x48662a, 0x0c70aa, 0x488494, 0x4924d0, 0x0ad0c8, 0x0ae0d8, 0x496636,
+ 0x10e0b0, 0x4f8498, 0x0f30b2, 0x49a4dc, 0x0f20b4, 0x53c49c, 0x0b60cb,
+ 0x49e57a, 0x0b80e0, 0x0b9109, 0x5e44a4, 0x5484a6, 0x4ac4ae, 0x4b44ca,
+ 0x4d64b6, 0x4ba5da, 0x0c60c0, 0x4bc51e, 0x4be556, 0x6204c0, 0x4c24c4,
+ 0x0f80c5, 0x5664c6, 0x4cc53a, 0x4d462c, 0x0f10c9, 0x4d8552, 0x4da4fa,
+ 0x5be4e0, 0x0cd0ff, 0x5244e2, 0x0cf0e8, 0x4e6568, 0x59a4e8, 0x0f90d2,
+ 0x1010d3, 0x5ac4ea, 0x0d50d7, 0x4ec634, 0x4ee560, 0x4f44f0, 0x4f6638,
+ 0x502522, 0x0db0dc, 0x5065a6, 0x508604, 0x60050a, 0x50c0fb, 0x63250e,
+ 0x1130e1, 0x5a4510, 0x5125fc, 0x516514, 0x51863e, 0x51c536, 0x0e70f4,
+ 0x55c520, 0x602526, 0x0eb0ea, 0x5cc528, 0x5ea52a, 0x1140ed, 0x60c52c,
+ 0x1020ef, 0x0f0119, 0x58e52e, 0x530622, 0x558534, 0x53861e, 0x55e540,
+ 0x5800f6, 0x57e542, 0x5445e6, 0x5465e8, 0x0fa115, 0x54c54a, 0x54e60e,
+ 0x5ae550, 0x1160fe, 0x5f0554, 0x564562, 0x56a58a, 0x56e5ee, 0x10310c,
+ 0x5705d0, 0x107105, 0x5725d4, 0x57463a, 0x5765b4, 0x5825bc, 0x5845e2,
+ 0x5885de, 0x58c592, 0x5ce590, 0x5945f6, 0x63c596, 0x11b110, 0x5d8598,
+ 0x5c259e, 0x5e05a0, 0x5a25c6, 0x5a860a, 0x5aa5ec, 0x5b2610, 0x11a118,
+ 0x6185b6, 0x5f25d2, 0x5d6616, 0x5dc5f8, 0x61a5fe, 0x612614, 0x62e624,
+ 0x626628};
+
+/* get starting addresses of huffman tables into an array [convert codebook into
+ * starting address] */
+/* cb tree */
+const UINT *aHuffTable[MAX_CB] = {
+ aHuffTree41,
+ /* 0 - */ /* use tree 1 as dummy here */
+ aHuffTree41, /* 1 1 */
+ aHuffTree42, /* 2 2 */
+ aHuffTree43, /* 3 3 */
+ aHuffTree44, /* 4 4 */
+ aHuffTree21, /* 5 5 */
+ aHuffTree22, /* 6 6 */
+ aHuffTree23, /* 7 7 */
+ aHuffTree24, /* 8 8 */
+ aHuffTree25, /* 9 9 */
+ aHuffTree26, /* 10 10 */
+ aHuffTree27, /* 11 11 */
+ aHuffTree41,
+ /* 12 - */ /* use tree 1 as dummy here */
+ aHuffTree41,
+ /* 13 - */ /* use tree 1 as dummy here */
+ aHuffTree41,
+ /* 14 - */ /* use tree 1 as dummy here */
+ aHuffTree41,
+ /* 15 - */ /* use tree 1 as dummy here */
+ aHuffTree27, /* 16 11 */
+ aHuffTree27, /* 17 11 */
+ aHuffTree27, /* 18 11 */
+ aHuffTree27, /* 19 11 */
+ aHuffTree27, /* 20 11 */
+ aHuffTree27, /* 21 11 */
+ aHuffTree27, /* 22 11 */
+ aHuffTree27, /* 23 11 */
+ aHuffTree27, /* 24 11 */
+ aHuffTree27, /* 25 11 */
+ aHuffTree27, /* 26 11 */
+ aHuffTree27, /* 27 11 */
+ aHuffTree27, /* 28 11 */
+ aHuffTree27, /* 29 11 */
+ aHuffTree27, /* 30 11 */
+ aHuffTree27}; /* 31 11 */
+
+/*---------------------------------------------------------------------------------------------
+ data-description:
+ The following tables contain the quantized values. Two or four of the
+ quantized values are indexed by the result of the decoding in the decoding tree
+ (see tables above).
+ --------------------------------------------------------------------------------------------
+ */
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab41 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks
+ * 1-2. */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab41[324] = {
+ -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, -1, 0, -1, -1, -1,
+ 0, 0, -1, -1, 0, 1, -1, -1, 1, -1, -1, -1, 1, 0, -1, -1, 1, 1,
+ -1, 0, -1, -1, -1, 0, -1, 0, -1, 0, -1, 1, -1, 0, 0, -1, -1, 0,
+ 0, 0, -1, 0, 0, 1, -1, 0, 1, -1, -1, 0, 1, 0, -1, 0, 1, 1,
+ -1, 1, -1, -1, -1, 1, -1, 0, -1, 1, -1, 1, -1, 1, 0, -1, -1, 1,
+ 0, 0, -1, 1, 0, 1, -1, 1, 1, -1, -1, 1, 1, 0, -1, 1, 1, 1,
+ 0, -1, -1, -1, 0, -1, -1, 0, 0, -1, -1, 1, 0, -1, 0, -1, 0, -1,
+ 0, 0, 0, -1, 0, 1, 0, -1, 1, -1, 0, -1, 1, 0, 0, -1, 1, 1,
+ 0, 0, -1, -1, 0, 0, -1, 0, 0, 0, -1, 1, 0, 0, 0, -1, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 1, 0, 0, 0, 1, 1,
+ 0, 1, -1, -1, 0, 1, -1, 0, 0, 1, -1, 1, 0, 1, 0, -1, 0, 1,
+ 0, 0, 0, 1, 0, 1, 0, 1, 1, -1, 0, 1, 1, 0, 0, 1, 1, 1,
+ 1, -1, -1, -1, 1, -1, -1, 0, 1, -1, -1, 1, 1, -1, 0, -1, 1, -1,
+ 0, 0, 1, -1, 0, 1, 1, -1, 1, -1, 1, -1, 1, 0, 1, -1, 1, 1,
+ 1, 0, -1, -1, 1, 0, -1, 0, 1, 0, -1, 1, 1, 0, 0, -1, 1, 0,
+ 0, 0, 1, 0, 0, 1, 1, 0, 1, -1, 1, 0, 1, 0, 1, 0, 1, 1,
+ 1, 1, -1, -1, 1, 1, -1, 0, 1, 1, -1, 1, 1, 1, 0, -1, 1, 1,
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, -1, 1, 1, 1, 0, 1, 1, 1, 1};
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab42 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks
+ * 3-4. */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab42[324] = {
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 2, 0,
+ 0, 2, 0, 0, 0, 2, 1, 0, 0, 2, 2, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 2, 0, 1,
+ 1, 0, 0, 1, 1, 1, 0, 1, 1, 2, 0, 1, 2, 0, 0, 1, 2, 1, 0, 1, 2, 2, 0, 2, 0,
+ 0, 0, 2, 0, 1, 0, 2, 0, 2, 0, 2, 1, 0, 0, 2, 1, 1, 0, 2, 1, 2, 0, 2, 2, 0,
+ 0, 2, 2, 1, 0, 2, 2, 2, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 1, 0, 1,
+ 0, 1, 1, 1, 0, 1, 2, 1, 0, 2, 0, 1, 0, 2, 1, 1, 0, 2, 2, 1, 1, 0, 0, 1, 1,
+ 0, 1, 1, 1, 0, 2, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 0, 1, 1, 2,
+ 1, 1, 1, 2, 2, 1, 2, 0, 0, 1, 2, 0, 1, 1, 2, 0, 2, 1, 2, 1, 0, 1, 2, 1, 1,
+ 1, 2, 1, 2, 1, 2, 2, 0, 1, 2, 2, 1, 1, 2, 2, 2, 2, 0, 0, 0, 2, 0, 0, 1, 2,
+ 0, 0, 2, 2, 0, 1, 0, 2, 0, 1, 1, 2, 0, 1, 2, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0,
+ 2, 2, 2, 1, 0, 0, 2, 1, 0, 1, 2, 1, 0, 2, 2, 1, 1, 0, 2, 1, 1, 1, 2, 1, 1,
+ 2, 2, 1, 2, 0, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2, 0, 0, 2, 2, 0, 1, 2, 2, 0, 2,
+ 2, 2, 1, 0, 2, 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2, 2};
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab21 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks
+ * 5-6. */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab21[162] = {
+ -4, -4, -4, -3, -4, -2, -4, -1, -4, 0, -4, 1, -4, 2, -4, 3, -4, 4,
+ -3, -4, -3, -3, -3, -2, -3, -1, -3, 0, -3, 1, -3, 2, -3, 3, -3, 4,
+ -2, -4, -2, -3, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, 3, -2, 4,
+ -1, -4, -1, -3, -1, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4,
+ 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, 0, 1, 0, 2, 0, 3, 0, 4,
+ 1, -4, 1, -3, 1, -2, 1, -1, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4,
+ 2, -4, 2, -3, 2, -2, 2, -1, 2, 0, 2, 1, 2, 2, 2, 3, 2, 4,
+ 3, -4, 3, -3, 3, -2, 3, -1, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4,
+ 4, -4, 4, -3, 4, -2, 4, -1, 4, 0, 4, 1, 4, 2, 4, 3, 4, 4};
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab22 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks
+ * 7-8. */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab22[128] = {
+ 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 1, 0, 1, 1, 1, 2,
+ 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5,
+ 2, 6, 2, 7, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5, 3, 6, 3, 7, 4, 0,
+ 4, 1, 4, 2, 4, 3, 4, 4, 4, 5, 4, 6, 4, 7, 5, 0, 5, 1, 5, 2, 5, 3,
+ 5, 4, 5, 5, 5, 6, 5, 7, 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 6, 5, 6, 6,
+ 6, 7, 7, 0, 7, 1, 7, 2, 7, 3, 7, 4, 7, 5, 7, 6, 7, 7};
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab23 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks
+ * 9-10. */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab23[338] = {
+ 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0,
+ 9, 0, 10, 0, 11, 0, 12, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5,
+ 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11, 1, 12, 2, 0, 2, 1, 2,
+ 2, 2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 2, 8, 2, 9, 2, 10, 2, 11,
+ 2, 12, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5, 3, 6, 3, 7, 3,
+ 8, 3, 9, 3, 10, 3, 11, 3, 12, 4, 0, 4, 1, 4, 2, 4, 3, 4, 4,
+ 4, 5, 4, 6, 4, 7, 4, 8, 4, 9, 4, 10, 4, 11, 4, 12, 5, 0, 5,
+ 1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8, 5, 9, 5, 10,
+ 5, 11, 5, 12, 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 6, 5, 6, 6, 6,
+ 7, 6, 8, 6, 9, 6, 10, 6, 11, 6, 12, 7, 0, 7, 1, 7, 2, 7, 3,
+ 7, 4, 7, 5, 7, 6, 7, 7, 7, 8, 7, 9, 7, 10, 7, 11, 7, 12, 8,
+ 0, 8, 1, 8, 2, 8, 3, 8, 4, 8, 5, 8, 6, 8, 7, 8, 8, 8, 9,
+ 8, 10, 8, 11, 8, 12, 9, 0, 9, 1, 9, 2, 9, 3, 9, 4, 9, 5, 9,
+ 6, 9, 7, 9, 8, 9, 9, 9, 10, 9, 11, 9, 12, 10, 0, 10, 1, 10, 2,
+ 10, 3, 10, 4, 10, 5, 10, 6, 10, 7, 10, 8, 10, 9, 10, 10, 10, 11, 10,
+ 12, 11, 0, 11, 1, 11, 2, 11, 3, 11, 4, 11, 5, 11, 6, 11, 7, 11, 8,
+ 11, 9, 11, 10, 11, 11, 11, 12, 12, 0, 12, 1, 12, 2, 12, 3, 12, 4, 12,
+ 5, 12, 6, 12, 7, 12, 8, 12, 9, 12, 10, 12, 11, 12, 12};
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab24 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks 11.
+ */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab24[578] = {
+ 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0,
+ 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 16, 1, 0, 1, 1,
+ 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1,
+ 11, 1, 12, 1, 13, 1, 14, 1, 15, 1, 16, 2, 0, 2, 1, 2, 2, 2, 3,
+ 2, 4, 2, 5, 2, 6, 2, 7, 2, 8, 2, 9, 2, 10, 2, 11, 2, 12, 2,
+ 13, 2, 14, 2, 15, 2, 16, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5,
+ 3, 6, 3, 7, 3, 8, 3, 9, 3, 10, 3, 11, 3, 12, 3, 13, 3, 14, 3,
+ 15, 3, 16, 4, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4, 5, 4, 6, 4, 7,
+ 4, 8, 4, 9, 4, 10, 4, 11, 4, 12, 4, 13, 4, 14, 4, 15, 4, 16, 5,
+ 0, 5, 1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8, 5, 9,
+ 5, 10, 5, 11, 5, 12, 5, 13, 5, 14, 5, 15, 5, 16, 6, 0, 6, 1, 6,
+ 2, 6, 3, 6, 4, 6, 5, 6, 6, 6, 7, 6, 8, 6, 9, 6, 10, 6, 11,
+ 6, 12, 6, 13, 6, 14, 6, 15, 6, 16, 7, 0, 7, 1, 7, 2, 7, 3, 7,
+ 4, 7, 5, 7, 6, 7, 7, 7, 8, 7, 9, 7, 10, 7, 11, 7, 12, 7, 13,
+ 7, 14, 7, 15, 7, 16, 8, 0, 8, 1, 8, 2, 8, 3, 8, 4, 8, 5, 8,
+ 6, 8, 7, 8, 8, 8, 9, 8, 10, 8, 11, 8, 12, 8, 13, 8, 14, 8, 15,
+ 8, 16, 9, 0, 9, 1, 9, 2, 9, 3, 9, 4, 9, 5, 9, 6, 9, 7, 9,
+ 8, 9, 9, 9, 10, 9, 11, 9, 12, 9, 13, 9, 14, 9, 15, 9, 16, 10, 0,
+ 10, 1, 10, 2, 10, 3, 10, 4, 10, 5, 10, 6, 10, 7, 10, 8, 10, 9, 10,
+ 10, 10, 11, 10, 12, 10, 13, 10, 14, 10, 15, 10, 16, 11, 0, 11, 1, 11, 2,
+ 11, 3, 11, 4, 11, 5, 11, 6, 11, 7, 11, 8, 11, 9, 11, 10, 11, 11, 11,
+ 12, 11, 13, 11, 14, 11, 15, 11, 16, 12, 0, 12, 1, 12, 2, 12, 3, 12, 4,
+ 12, 5, 12, 6, 12, 7, 12, 8, 12, 9, 12, 10, 12, 11, 12, 12, 12, 13, 12,
+ 14, 12, 15, 12, 16, 13, 0, 13, 1, 13, 2, 13, 3, 13, 4, 13, 5, 13, 6,
+ 13, 7, 13, 8, 13, 9, 13, 10, 13, 11, 13, 12, 13, 13, 13, 14, 13, 15, 13,
+ 16, 14, 0, 14, 1, 14, 2, 14, 3, 14, 4, 14, 5, 14, 6, 14, 7, 14, 8,
+ 14, 9, 14, 10, 14, 11, 14, 12, 14, 13, 14, 14, 14, 15, 14, 16, 15, 0, 15,
+ 1, 15, 2, 15, 3, 15, 4, 15, 5, 15, 6, 15, 7, 15, 8, 15, 9, 15, 10,
+ 15, 11, 15, 12, 15, 13, 15, 14, 15, 15, 15, 16, 16, 0, 16, 1, 16, 2, 16,
+ 3, 16, 4, 16, 5, 16, 6, 16, 7, 16, 8, 16, 9, 16, 10, 16, 11, 16, 12,
+ 16, 13, 16, 14, 16, 15, 16, 16};
+
+/* cb quant. val table */
+const SCHAR *aQuantTable[] = {
+ aValTab41,
+ /* 0 - */ /* use quant. val talble 1 as dummy here */
+ aValTab41, /* 1 1 */
+ aValTab41, /* 2 1 */
+ aValTab42, /* 3 2 */
+ aValTab42, /* 4 2 */
+ aValTab21, /* 5 3 */
+ aValTab21, /* 6 3 */
+ aValTab22, /* 7 4 */
+ aValTab22, /* 8 4 */
+ aValTab23, /* 9 5 */
+ aValTab23, /* 10 5 */
+ aValTab24, /* 11 6 */
+ aValTab41,
+ /* 12 - */ /* use quant. val talble 1 as dummy here */
+ aValTab41,
+ /* 13 - */ /* use quant. val talble 1 as dummy here */
+ aValTab41,
+ /* 14 - */ /* use quant. val talble 1 as dummy here */
+ aValTab41,
+ /* 15 - */ /* use quant. val talble 1 as dummy here */
+ aValTab24, /* 16 6 */
+ aValTab24, /* 17 6 */
+ aValTab24, /* 18 6 */
+ aValTab24, /* 19 6 */
+ aValTab24, /* 20 6 */
+ aValTab24, /* 21 6 */
+ aValTab24, /* 22 6 */
+ aValTab24, /* 23 6 */
+ aValTab24, /* 24 6 */
+ aValTab24, /* 25 6 */
+ aValTab24, /* 26 6 */
+ aValTab24, /* 27 6 */
+ aValTab24, /* 28 6 */
+ aValTab24, /* 29 6 */
+ aValTab24, /* 30 6 */
+ aValTab24}; /* 31 6 */
+
+/* arrays for HCR_TABLE_INFO structures */
+/* maximum length of codeword in each codebook */
+/* codebook: 0,1, 2,3, 4, 5, 6, 7, 8, 9,
+ * 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 */
+const UCHAR aMaxCwLen[MAX_CB] = {0, 11, 9, 20, 16, 13, 11, 14, 12, 17, 14,
+ 49, 0, 0, 0, 0, 14, 17, 21, 21, 25, 25,
+ 29, 29, 29, 29, 33, 33, 33, 37, 37, 41};
+
+/* 11 13 15 17 19
+ * 21 23 25 27 39 31 */
+/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20
+ * 22 24 26 28 30 */
+const UCHAR aDimCb[MAX_CB] = {
+ 2, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; /* codebook dimension -
+ zero cb got a
+ dimension of 2 */
+
+/* 11 13 15 17 19
+ * 21 23 25 27 39 31 */
+/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20
+ * 22 24 26 28 30 */
+const UCHAR aDimCbShift[MAX_CB] = {
+ 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; /* codebook dimension */
+
+/* 1 -> decode sign bits */
+/* 0 -> decode no sign bits 11 13 15 17 19 21
+ * 23 25 27 39 31 */
+/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20 22
+ * 24 26 28 30 */
+const UCHAR aSignCb[MAX_CB] = {0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+
+/* arrays for HCR_CB_PAIRS structures */
+const UCHAR aMinOfCbPair[MAX_CB_PAIRS] = {0, 1, 3, 5, 7, 9, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 11};
+const UCHAR aMaxOfCbPair[MAX_CB_PAIRS] = {0, 2, 4, 6, 8, 10, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 11};
+
+/* priorities of codebooks */
+const UCHAR aCbPriority[MAX_CB] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
+ 22, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
+
+const SCHAR aCodebook2StartInt[] = {STOP_THIS_STATE, /* cb 0 */
+ BODY_ONLY, /* cb 1 */
+ BODY_ONLY, /* cb 2 */
+ BODY_SIGN__BODY, /* cb 3 */
+ BODY_SIGN__BODY, /* cb 4 */
+ BODY_ONLY, /* cb 5 */
+ BODY_ONLY, /* cb 6 */
+ BODY_SIGN__BODY, /* cb 7 */
+ BODY_SIGN__BODY, /* cb 8 */
+ BODY_SIGN__BODY, /* cb 9 */
+ BODY_SIGN__BODY, /* cb 10 */
+ BODY_SIGN_ESC__BODY, /* cb 11 */
+ STOP_THIS_STATE, /* cb 12 */
+ STOP_THIS_STATE, /* cb 13 */
+ STOP_THIS_STATE, /* cb 14 */
+ STOP_THIS_STATE, /* cb 15 */
+ BODY_SIGN_ESC__BODY, /* cb 16 */
+ BODY_SIGN_ESC__BODY, /* cb 17 */
+ BODY_SIGN_ESC__BODY, /* cb 18 */
+ BODY_SIGN_ESC__BODY, /* cb 19 */
+ BODY_SIGN_ESC__BODY, /* cb 20 */
+ BODY_SIGN_ESC__BODY, /* cb 21 */
+ BODY_SIGN_ESC__BODY, /* cb 22 */
+ BODY_SIGN_ESC__BODY, /* cb 23 */
+ BODY_SIGN_ESC__BODY, /* cb 24 */
+ BODY_SIGN_ESC__BODY, /* cb 25 */
+ BODY_SIGN_ESC__BODY, /* cb 26 */
+ BODY_SIGN_ESC__BODY, /* cb 27 */
+ BODY_SIGN_ESC__BODY, /* cb 28 */
+ BODY_SIGN_ESC__BODY, /* cb 29 */
+ BODY_SIGN_ESC__BODY, /* cb 30 */
+ BODY_SIGN_ESC__BODY}; /* cb 31 */
+
+const STATEFUNC aStateConstant2State[] = {
+ NULL, /* 0 = STOP_THIS_STATE */
+ Hcr_State_BODY_ONLY, /* 1 = BODY_ONLY */
+ Hcr_State_BODY_SIGN__BODY, /* 2 = BODY_SIGN__BODY */
+ Hcr_State_BODY_SIGN__SIGN, /* 3 = BODY_SIGN__SIGN */
+ Hcr_State_BODY_SIGN_ESC__BODY, /* 4 = BODY_SIGN_ESC__BODY */
+ Hcr_State_BODY_SIGN_ESC__SIGN, /* 5 = BODY_SIGN_ESC__SIGN */
+ Hcr_State_BODY_SIGN_ESC__ESC_PREFIX, /* 6 = BODY_SIGN_ESC__ESC_PREFIX */
+ Hcr_State_BODY_SIGN_ESC__ESC_WORD}; /* 7 = BODY_SIGN_ESC__ESC_WORD */
+
+/* CB: 0 1 2 3 4 5 6 7 8 9 10 12
+ * 14 16 18 20 22 24 26 28 30 */
+const USHORT aLargestAbsoluteValue[MAX_CB] = {
+ 0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12,
+ 8191, 0, 0, 0, 0, 15, 31, 47, 63, 95, 127,
+ 159, 191, 223, 255, 319, 383, 511, 767, 1023, 2047}; /* lav */
+/* CB: 11 13
+ * 15 17 19 21 23 25 27 39 31 */
+
+/* ------------------------------------------------------------------------------------------
+ description: The table 'HuffTreeRvlcEscape' contains the decode tree for
+the rvlc escape sequences. bit 23 and 11 not used bit 22 and 10 determine end
+value --> if set codeword is decoded bit 21-12 and 9-0 (offset to next node)
+or (index value) The escape sequence is the index value.
+
+ input: codeword
+ output: index
+------------------------------------------------------------------------------------------
+*/
+const UINT aHuffTreeRvlcEscape[53] = {
+ 0x002001, 0x400003, 0x401004, 0x402005, 0x403007, 0x404006, 0x00a405,
+ 0x009008, 0x00b406, 0x00c407, 0x00d408, 0x00e409, 0x40b40a, 0x40c00f,
+ 0x40d010, 0x40e011, 0x40f012, 0x410013, 0x411014, 0x412015, 0x016413,
+ 0x414415, 0x017416, 0x417018, 0x419019, 0x01a418, 0x01b41a, 0x01c023,
+ 0x03201d, 0x01e020, 0x43501f, 0x41b41c, 0x021022, 0x41d41e, 0x41f420,
+ 0x02402b, 0x025028, 0x026027, 0x421422, 0x423424, 0x02902a, 0x425426,
+ 0x427428, 0x02c02f, 0x02d02e, 0x42942a, 0x42b42c, 0x030031, 0x42d42e,
+ 0x42f430, 0x033034, 0x431432, 0x433434};
+
+/* ------------------------------------------------------------------------------------------
+ description: The table 'HuffTreeRvlc' contains the huffman decoding tree
+for the RVLC scale factors. The table contains 15 allowed, symmetric codewords
+and 8 forbidden codewords, which are used for error detection.
+
+ usage of bits: bit 23 and 11 not used
+ bit 22 and 10 determine end value --> if set codeword is
+decoded bit 21-12 and 9-0 (offset to next node within the table) or (index+7).
+ The decoded (index+7) is in the range from 0,1,..,22. If the
+(index+7) is in the range 15,16,..,22, then a forbidden codeword is decoded.
+
+ input: A single bit from a RVLC scalefactor codeword
+ output: [if codeword is not completely decoded:] offset to next node
+within table or [if codeword is decoded:] A dpcm value i.e. (index+7) in range
+from 0,1,..,22. The differential scalefactor (DPCM value) named 'index' is
+calculated by subtracting 7 from the decoded value (index+7).
+------------------------------------------------------------------------------------------
+*/
+const UINT aHuffTreeRvlCodewds[22] = {
+ 0x407001, 0x002009, 0x003406, 0x004405, 0x005404, 0x006403,
+ 0x007400, 0x008402, 0x411401, 0x00a408, 0x00c00b, 0x00e409,
+ 0x01000d, 0x40f40a, 0x41400f, 0x01340b, 0x011015, 0x410012,
+ 0x41240c, 0x416014, 0x41540d, 0x41340e};
+
+const FIXP_WTB LowDelaySynthesis256[768] = {
+ WTC(0xdaecb88a), WTC(0xdb7a5230), WTC(0xdc093961), WTC(0xdc9977b5),
+ WTC(0xdd2b11b4), WTC(0xddbe06c1), WTC(0xde525277), WTC(0xdee7f167),
+ WTC(0xdf7ee2f9), WTC(0xe0173207), WTC(0xe0b0e70e), WTC(0xe14beb4d),
+ WTC(0xe1e82002), WTC(0xe285693d), WTC(0xe323ba3c), WTC(0xe3c33cdb),
+ WTC(0xe4640c93), WTC(0xe5060b3f), WTC(0xe5a915ce), WTC(0xe64cffc2),
+ WTC(0xe6f19868), WTC(0xe796b4d7), WTC(0xe83c2ebf), WTC(0xe8e1eea1),
+ WTC(0xe987f784), WTC(0xea2e8014), WTC(0xead5a2b6), WTC(0xeb7d3476),
+ WTC(0xec24ebfb), WTC(0xeccc4e9a), WTC(0xed72f723), WTC(0xee18b585),
+ WTC(0xeebd6902), WTC(0xef610661), WTC(0xf0037f41), WTC(0xf0a4c139),
+ WTC(0xf144c5bc), WTC(0xf1e395c4), WTC(0xf2812c5d), WTC(0xf31d6db4),
+ WTC(0xf3b83ed0), WTC(0xf4517963), WTC(0xf4e8d672), WTC(0xf57de495),
+ WTC(0xf610395e), WTC(0xf69f7e84), WTC(0xf72b9152), WTC(0xf7b495b5),
+ WTC(0xf83af453), WTC(0xf8bf7118), WTC(0xf9429a33), WTC(0xf9c4c183),
+ WTC(0xfa466592), WTC(0xfac80867), WTC(0xfb49d2bd), WTC(0xfbcb7294),
+ WTC(0xfc4d0e35), WTC(0xfccf7e7b), WTC(0xfd53af97), WTC(0xfddab5ca),
+ WTC(0xfe629a56), WTC(0xfee5c7c9), WTC(0xff5b6311), WTC(0xffb6bd45),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbff6c845), WTC(0xbfe461ee), WTC(0xbfd1f586), WTC(0xbfbf85b2),
+ WTC(0xbfad1518), WTC(0xbf9aa640), WTC(0xbf883911), WTC(0xbf75caf0),
+ WTC(0xbf635c4b), WTC(0xbf50f09b), WTC(0xbf3e886d), WTC(0xbf2c2167),
+ WTC(0xbf19bc2c), WTC(0xbf075c64), WTC(0xbef502db), WTC(0xbee2ad83),
+ WTC(0xbed05d67), WTC(0xbebe16a7), WTC(0xbeabda46), WTC(0xbe99a62e),
+ WTC(0xbe877b90), WTC(0xbe755ee8), WTC(0xbe63517d), WTC(0xbe51515b),
+ WTC(0xbe3f5fc9), WTC(0xbe2d8141), WTC(0xbe1bb721), WTC(0xbe09ffa3),
+ WTC(0xbdf85c17), WTC(0xbde6d0e3), WTC(0xbdd55f47), WTC(0xbdc4055d),
+ WTC(0xbdb2c438), WTC(0xbda19fe0), WTC(0xbd909942), WTC(0xbd7fae2f),
+ WTC(0xbd6edf8d), WTC(0xbd5e3153), WTC(0xbd4da45b), WTC(0xbd3d365a),
+ WTC(0xbd2ce7eb), WTC(0xbd1cbc87), WTC(0xbd0cb466), WTC(0xbcfccc80),
+ WTC(0xbced04c5), WTC(0xbcdd6022), WTC(0xbccdde49), WTC(0xbcbe7bb4),
+ WTC(0xbcaf37ec), WTC(0xbca01594), WTC(0xbc91149b), WTC(0xbc823234),
+ WTC(0xbc736d81), WTC(0xbc64c7a4), WTC(0xbc564085), WTC(0xbc47d6a9),
+ WTC(0xbc398617), WTC(0xbc2b4915), WTC(0xbc1d2a92), WTC(0xbc0f4370),
+ WTC(0xbc016785), WTC(0xbbf32f6c), WTC(0xbbe53648), WTC(0xbbd91eb5),
+ WTC(0xbbd02f7c), WTC(0xbbcb58db), WTC(0xbbca5ac2), WTC(0xbbcbdea2),
+ WTC(0xbbcee192), WTC(0xbbd2c7c2), WTC(0xbbd7a648), WTC(0xbbde3c5a),
+ WTC(0xbbe7079f), WTC(0xbbf238bf), WTC(0xbbff8eec), WTC(0xbc0e5d22),
+ WTC(0xbc1e2c8b), WTC(0xbc2ec3a4), WTC(0xbc402f19), WTC(0xbc52c1ac),
+ WTC(0xbc6709aa), WTC(0xbc7dcbce), WTC(0xbc979383), WTC(0xbcb4ae30),
+ WTC(0xbcd52aeb), WTC(0xbcf8db63), WTC(0xbd1f6993), WTC(0xbd485b46),
+ WTC(0xbd735007), WTC(0xbda003fc), WTC(0xbdce556c), WTC(0xbdfe453b),
+ WTC(0xbe2ffd4e), WTC(0xbe63ceb7), WTC(0xbe9a006f), WTC(0xbed2ce2b),
+ WTC(0xbf0e7d8e), WTC(0xbf4d5cfc), WTC(0xbf8f92bd), WTC(0xbfd5160c),
+ WTC(0xc01d3b27), WTC(0xc066b8f5), WTC(0xc0b0a3b8), WTC(0xc0fa7cdd),
+ WTC(0xc144b0e8), WTC(0xc1908d71), WTC(0xc1ded403), WTC(0xc22fae49),
+ WTC(0xc2830092), WTC(0xc2d86ca8), WTC(0xc32f4341), WTC(0xc38687e5),
+ WTC(0xc3dd5c55), WTC(0xc43310e4), WTC(0xc4883eca), WTC(0xc4deba3d),
+ WTC(0xc5372c82), WTC(0xc59102fb), WTC(0xc5eb416a), WTC(0xc644986f),
+ WTC(0xc69cabb2), WTC(0xc6f41290), WTC(0xc74b22bf), WTC(0xc7a1e4b9),
+ WTC(0xc7f83500), WTC(0xc84dc737), WTC(0xc8a24e07), WTC(0xc8f5776f),
+ WTC(0xb4db4a8b), WTC(0xb3c58a32), WTC(0xb2b2acb4), WTC(0xb1a2afc0),
+ WTC(0xb0959107), WTC(0xaf8b4e0a), WTC(0xae83dfef), WTC(0xad7f3ba6),
+ WTC(0xac7d5a57), WTC(0xab7e397d), WTC(0xaa81d5a7), WTC(0xa9882a64),
+ WTC(0xa89135bc), WTC(0xa79cf84e), WTC(0xa6ab74fc), WTC(0xa5bcb0d0),
+ WTC(0xa4d0b1b8), WTC(0xa3e77e6d), WTC(0xa3011e16), WTC(0xa21d986c),
+ WTC(0xa13cf921), WTC(0xa05f4fb9), WTC(0x9f84a850), WTC(0x9ead0baf),
+ WTC(0x9dd8888c), WTC(0x9d073385), WTC(0x9c391db5), WTC(0x9b6e5484),
+ WTC(0x9aa6e656), WTC(0x99e2e2c5), WTC(0x99225ac4), WTC(0x9865608a),
+ WTC(0x97ac0564), WTC(0x96f65984), WTC(0x96446a25), WTC(0x95964196),
+ WTC(0x94ebe9ec), WTC(0x94456d19), WTC(0x93a2d46a), WTC(0x93042864),
+ WTC(0x92696dea), WTC(0x91d2a637), WTC(0x913fd120), WTC(0x90b0ecfe),
+ WTC(0x9025f239), WTC(0x8f9ed33e), WTC(0x8f1b804b), WTC(0x8e9be72b),
+ WTC(0x8e1fe984), WTC(0x8da75ce4), WTC(0x8d321511), WTC(0x8cbfe381),
+ WTC(0x8c508090), WTC(0x8be38b7b), WTC(0x8b78a10a), WTC(0x8b0f5bb4),
+ WTC(0x8aa740f3), WTC(0x8a3fc439), WTC(0x89d8a093), WTC(0x8971e7bf),
+ WTC(0x890d0fa8), WTC(0x88acfc32), WTC(0x8855e07a), WTC(0x880d5010),
+ WTC(0x87cc444c), WTC(0x87b6e84e), WTC(0x879e3713), WTC(0x87850a87),
+ WTC(0x876c76ee), WTC(0x8753c55a), WTC(0x873aa70d), WTC(0x872147e7),
+ WTC(0x8707bb23), WTC(0x86edf64f), WTC(0x86d3f20d), WTC(0x86b9ab68),
+ WTC(0x869f21e7), WTC(0x86845744), WTC(0x8669499e), WTC(0x864df395),
+ WTC(0x863254b2), WTC(0x8616715e), WTC(0x85fa4870), WTC(0x85ddd324),
+ WTC(0x85c1108b), WTC(0x85a40597), WTC(0x8586b1d1), WTC(0x85690f48),
+ WTC(0x854b1dfb), WTC(0x852ce3e7), WTC(0x850e61c8), WTC(0x84ef9303),
+ WTC(0x84d078c2), WTC(0x84b119fa), WTC(0x849177fa), WTC(0x84718e56),
+ WTC(0x84515e65), WTC(0x8430ef53), WTC(0x841042cb), WTC(0x83ef54e8),
+ WTC(0x83ce27ab), WTC(0x83acc30a), WTC(0x838b2934), WTC(0x83695686),
+ WTC(0x83474d47), WTC(0x832515b6), WTC(0x8302b202), WTC(0x82e01e3b),
+ WTC(0x82bd5c8e), WTC(0x829a755a), WTC(0x82776abf), WTC(0x8254388a),
+ WTC(0x8230e07e), WTC(0x820d6a69), WTC(0x81e9d82d), WTC(0x81c625ae),
+ WTC(0x81a25455), WTC(0x817e6b1f), WTC(0x815a6b39), WTC(0x81364fec),
+ WTC(0x81121a34), WTC(0x80edd0c9), WTC(0x80c97479), WTC(0x80a5000a),
+ WTC(0x80807332), WTC(0x805bd2e6), WTC(0x80372460), WTC(0x80126cc4),
+ WTC(0x0a8a8431), WTC(0x0ae3c329), WTC(0x0b3fdab2), WTC(0x0b9e6e44),
+ WTC(0x0bff2161), WTC(0x0c619a72), WTC(0x0cc5c66d), WTC(0x0d2bd6df),
+ WTC(0x0d93cf64), WTC(0x0dfd8545), WTC(0x0e69093a), WTC(0x0ed6a636),
+ WTC(0x0f465aea), WTC(0x0fb7d810), WTC(0x102ade99), WTC(0x109f4245),
+ WTC(0x1114c9e8), WTC(0x118b31bc), WTC(0x120282b8), WTC(0x127b0be1),
+ WTC(0x12f46b9a), WTC(0x136d8dde), WTC(0x13e57912), WTC(0x145b55cb),
+ WTC(0x14ce5b18), WTC(0x153dccd0), WTC(0x15a8e724), WTC(0x160edefe),
+ WTC(0x166f004f), WTC(0x16c8aff4), WTC(0x171b7afc), WTC(0x17673db3),
+ WTC(0x17afb798), WTC(0x17fc62a2), WTC(0x185114c1), WTC(0x18add722),
+ WTC(0x1912798d), WTC(0x197eb9a2), WTC(0x19f25657), WTC(0x1a6d113e),
+ WTC(0x1aeeb824), WTC(0x1b7723ab), WTC(0x1c060b77), WTC(0x1c9b09a1),
+ WTC(0x1d361822), WTC(0x1dd7933f), WTC(0x1e7ff592), WTC(0x1f2fd0b5),
+ WTC(0x1fe762a9), WTC(0x20a68700), WTC(0x216bbf5e), WTC(0x22344798),
+ WTC(0x22feebdb), WTC(0x23cc22a6), WTC(0x249da10b), WTC(0x25762e41),
+ WTC(0x2655ebc8), WTC(0x273a4e66), WTC(0x28212eaa), WTC(0x2908ff30),
+ WTC(0x29f2ca00), WTC(0x2ae221c4), WTC(0x2bd9c6fc), WTC(0x2cdb967e),
+ WTC(0x2de64c86), WTC(0x2ef61340), WTC(0x3006852b), WTC(0x31131a1b),
+ WTC(0x321aec79), WTC(0x3320d4ed), WTC(0x342a2cb3), WTC(0x353e77f7),
+ WTC(0x3660aaba), WTC(0x378ef057), WTC(0x38c42495), WTC(0x39f81cec),
+ WTC(0x3b250148), WTC(0x3c47960e), WTC(0x3d60c625), WTC(0x3e75864a),
+ WTC(0x3f8a9ef7), WTC(0x40a46d36), WTC(0x41c537d7), WTC(0x42ed2889),
+ WTC(0x441b52d1), WTC(0x454dc37f), WTC(0x4681e9fa), WTC(0x47b4a9fe),
+ WTC(0x48e39960), WTC(0x4a0d10fd), WTC(0x4b30824b), WTC(0x4c4e759e),
+ WTC(0x4d680b1c), WTC(0x4e7eecaa), WTC(0x4f947d1e), WTC(0x50a9d1f4),
+ WTC(0x51bfee19), WTC(0x52d7be4d), WTC(0x53f187eb), WTC(0x550cd3c8),
+ WTC(0x56270706), WTC(0x573b7c75), WTC(0x58474819), WTC(0x59496ae2),
+ WTC(0x5a43dfa0), WTC(0x5b3b721f), WTC(0x5c32e266), WTC(0x5d2abea1),
+ WTC(0x5e22b479), WTC(0x5f199f8b), WTC(0x600d9194), WTC(0x60fbe188),
+ WTC(0x61e289de), WTC(0x62c0520c), WTC(0x63974d1e), WTC(0x646cb022),
+ WTC(0x6542745a), WTC(0x66172e2f), WTC(0x66e897d0), WTC(0x67b3cc52),
+ WTC(0x68783ebd), WTC(0x6937b9ed), WTC(0x69f365dd), WTC(0x6aabab1a),
+ WTC(0x6b60849c), WTC(0x6c11876e), WTC(0x6cbe46f0), WTC(0x6d6645bc),
+ WTC(0xae238366), WTC(0xb047d99a), WTC(0xb26207ba), WTC(0xb4733ab5),
+ WTC(0xb67c9f5f), WTC(0xb87f5bce), WTC(0xba7bf18d), WTC(0xbc723dd6),
+ WTC(0xbe621be8), WTC(0xc04b6b3d), WTC(0xc22e00ff), WTC(0xc409a8ad),
+ WTC(0xc5de425b), WTC(0xc7abc2a7), WTC(0xc9721421), WTC(0xcb31173c),
+ WTC(0xcce8c08d), WTC(0xce991894), WTC(0xd04218cd), WTC(0xd1e3aba9),
+ WTC(0xd37dcf0c), WTC(0xd510942f), WTC(0xd69bfa86), WTC(0xd81fefcc),
+ WTC(0xd99c766d), WTC(0xdb11a570), WTC(0xdc7f806e), WTC(0xdde5f79d),
+ WTC(0xdf451092), WTC(0xe09ce645), WTC(0xe1ed7fff), WTC(0xe336d16a),
+ WTC(0xe478e4f4), WTC(0xe5b3dbbb), WTC(0xe6e7c1ac), WTC(0xe8148d53),
+ WTC(0xe93a4835), WTC(0xea590eb0), WTC(0xeb70e4f8), WTC(0xec81b75d),
+ WTC(0xed8b8b6c), WTC(0xee8e8068), WTC(0xef8aa970), WTC(0xf0800dfd),
+ WTC(0xf16edc4d), WTC(0xf2576853), WTC(0xf339e058), WTC(0xf4164a51),
+ WTC(0xf4ec8fb8), WTC(0xf5bc7cef), WTC(0xf685a697), WTC(0xf74771c9),
+ WTC(0xf801f31b), WTC(0xf8b5eeb1), WTC(0xf963fadb), WTC(0xfa0c7427),
+ WTC(0xfaaf3e0f), WTC(0xfb4bcb6d), WTC(0xfbe2276f), WTC(0xfc72f578),
+ WTC(0xfcfe65d9), WTC(0xfd842e5b), WTC(0xfe03e14e), WTC(0xfe7ce07d),
+ WTC(0xfeef932b), WTC(0xff5d0236), WTC(0xffc68fee), WTC(0x002dbccc),
+ WTC(0x00927c78), WTC(0x00f32cbd), WTC(0x014d7209), WTC(0x019e5f51),
+ WTC(0x01e550aa), WTC(0x0223fc07), WTC(0x025d2618), WTC(0x02947b12),
+ WTC(0x02cc33db), WTC(0x0304fa92), WTC(0x033db713), WTC(0x0373a431),
+ WTC(0x03a47d96), WTC(0x03ce9b0f), WTC(0x03f14dc9), WTC(0x040ce0bc),
+ WTC(0x042245a9), WTC(0x043309a5), WTC(0x0440981a), WTC(0x044c30f1),
+ WTC(0x0456bb74), WTC(0x0460c1b4), WTC(0x046a2fdd), WTC(0x0472573f),
+ WTC(0x047877b6), WTC(0x047bc673), WTC(0x047b8615), WTC(0x04770be2),
+ WTC(0x046e23fc), WTC(0x04611460), WTC(0x04507fbd), WTC(0x043d6170),
+ WTC(0x0428ca31), WTC(0x0413d39a), WTC(0x03feb9c3), WTC(0x03e8d946),
+ WTC(0x03d16667), WTC(0x03b77aba), WTC(0x039aa384), WTC(0x037ae75c),
+ WTC(0x0358be80), WTC(0x03350af6), WTC(0x031064fa), WTC(0x02eb13f6),
+ WTC(0x02c51a7b), WTC(0x029e38b0), WTC(0x027619ef), WTC(0x024c5c09),
+ WTC(0x02210ea3), WTC(0x01f4b19e), WTC(0x01c78f79), WTC(0x0199b8ad),
+ WTC(0x016b3aef), WTC(0x013c2366), WTC(0x010c7be8), WTC(0x00dc4bb5),
+ WTC(0x00abab29), WTC(0x007ac3e1), WTC(0x0049c02f), WTC(0x0018ca71),
+ WTC(0xd6208221), WTC(0xd54e9f5b), WTC(0xd47fa35f), WTC(0xd3b35bdb),
+ WTC(0xd2e99693), WTC(0xd2222685), WTC(0xd15d5e4c), WTC(0xd09c06ff),
+ WTC(0xcfde0c24), WTC(0xcf2281d2), WTC(0xce698b2a), WTC(0xcdb455e0),
+ WTC(0xcd02c9b7), WTC(0xcc5381e5), WTC(0xcba580c3), WTC(0xcaf839ea),
+ WTC(0xca4ad0b7), WTC(0xc99c2153), WTC(0xc8ec5a61), WTC(0xc83ce258),
+ WTC(0xc78c42cd), WTC(0xc6d6213b), WTC(0xc616a6e0), WTC(0xc54a9f27),
+ WTC(0xc46ee44d), WTC(0xc38058a2), WTC(0xc27bd88d), WTC(0xc15e3d07),
+ WTC(0xc024a4d9), WTC(0xbecc7ca2), WTC(0xbd53f2b9), WTC(0xbbba98b4),
+ WTC(0xba0ffbc3), WTC(0xb872fb24), WTC(0xb6f36547), WTC(0xb5915345),
+ WTC(0xb44c3975), WTC(0xb3238942), WTC(0xb216b3fb), WTC(0xb1252b0b),
+ WTC(0xb04e5fc8), WTC(0xaf91c370), WTC(0xaeeec760), WTC(0xae64dd0b),
+ WTC(0xadf375ce), WTC(0xad9a02f0), WTC(0xad57f5bc), WTC(0xad2cbf87),
+ WTC(0xad17d19d), WTC(0xad189d42), WTC(0xad2e93d6), WTC(0xad5926d3),
+ WTC(0xad97c78a), WTC(0xade9e726), WTC(0xae4ef6fc), WTC(0xaec6688c),
+ WTC(0xaf4fad2c), WTC(0xafea3605), WTC(0xb0957469), WTC(0xb150d9d2),
+ WTC(0xb21bd793), WTC(0xb2f5de5d), WTC(0xb3de573d), WTC(0xb4d4de47),
+ WTC(0xb5d89c80), WTC(0xb6e937c2), WTC(0xb8061354), WTC(0xb92ea07c),
+ WTC(0xba62508e), WTC(0xbba094e4), WTC(0xbce8dee0), WTC(0xbe3a9fe3),
+ WTC(0xbf954939), WTC(0xc0f84c11), WTC(0xc26319c2), WTC(0xc3d523c5),
+ WTC(0xc54ddb77), WTC(0xc6ccb217), WTC(0xc85118f8), WTC(0xc9da8182),
+ WTC(0xcb685d07), WTC(0xccfa1cc7), WTC(0xce8f3211), WTC(0xd0270e48),
+ WTC(0xd1c122c7), WTC(0xd35ce0de), WTC(0xd4f9b9e1), WTC(0xd6971f23),
+ WTC(0xd83481f8), WTC(0xd9d153bb), WTC(0xdb6d05c0), WTC(0xdd070956),
+ WTC(0xde9ecfd2), WTC(0xe033ca91), WTC(0xe1c56ae7), WTC(0xe3532223),
+ WTC(0xe4dc6199), WTC(0xe6609aa5), WTC(0xe7df3e9a), WTC(0xe957bec9),
+ WTC(0xeac98c84), WTC(0xec341927), WTC(0xed96d607), WTC(0xeef13474),
+ WTC(0xf042a5c5), WTC(0xf18a9b4e), WTC(0xf2c88667), WTC(0xf3fbd863),
+ WTC(0xf5240296), WTC(0xf6407658), WTC(0xf750a4fe), WTC(0xf853ffda),
+ WTC(0xf949f840), WTC(0xfa31ff83), WTC(0xfb0b86fb), WTC(0xfbd5fffe),
+ WTC(0xfc90dbe1), WTC(0xfd3b8bf8), WTC(0xfdd58197), WTC(0xfe5e2e14),
+ WTC(0xfed502c4), WTC(0xff3970fc), WTC(0xff8aea0f), WTC(0xffc8df55),
+ WTC(0xfff2c233), WTC(0x000804e6), WTC(0x0008256a), WTC(0xfff25358),
+};
+
+const FIXP_WTB LowDelaySynthesis240[720] = {
+ WTC(0xdaf16ba1), WTC(0xdb888d4d), WTC(0xdc212bc1), WTC(0xdcbb51d0),
+ WTC(0xdd5703be), WTC(0xddf43f3b), WTC(0xde92fee5), WTC(0xdf333f92),
+ WTC(0xdfd505d1), WTC(0xe078624a), WTC(0xe11d48ff), WTC(0xe1c39358),
+ WTC(0xe26b2066), WTC(0xe313d8a9), WTC(0xe3bde63c), WTC(0xe4696e45),
+ WTC(0xe5164d95), WTC(0xe5c4597d), WTC(0xe673596f), WTC(0xe723153c),
+ WTC(0xe7d35813), WTC(0xe883fa49), WTC(0xe934e7a3), WTC(0xe9e64205),
+ WTC(0xea984aa8), WTC(0xeb4ae6ef), WTC(0xebfdcbf6), WTC(0xecb0744b),
+ WTC(0xed625671), WTC(0xee133361), WTC(0xeec2e1b4), WTC(0xef715334),
+ WTC(0xf01e7588), WTC(0xf0ca33ec), WTC(0xf1748a4e), WTC(0xf21d83ed),
+ WTC(0xf2c50dbe), WTC(0xf36b0639), WTC(0xf40f4892), WTC(0xf4b1944d),
+ WTC(0xf5517289), WTC(0xf5ee573d), WTC(0xf687d70d), WTC(0xf71db368),
+ WTC(0xf7b01057), WTC(0xf83f6570), WTC(0xf8cc9d0a), WTC(0xf9585a73),
+ WTC(0xf9e307f8), WTC(0xfa6d44d2), WTC(0xfaf79d75), WTC(0xfb8208e8),
+ WTC(0xfc0c33c8), WTC(0xfc96d00c), WTC(0xfd22f257), WTC(0xfdb1e623),
+ WTC(0xfe4318a3), WTC(0xfed08c1d), WTC(0xff5091f1), WTC(0xffb4390a),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbff62b62), WTC(0xbfe28a84), WTC(0xbfcee30d), WTC(0xbfbb3832),
+ WTC(0xbfa78d29), WTC(0xbf93e490), WTC(0xbf803cc6), WTC(0xbf6c9376),
+ WTC(0xbf58eb89), WTC(0xbf4547f8), WTC(0xbf31a6aa), WTC(0xbf1e06a3),
+ WTC(0xbf0a6bdf), WTC(0xbef6d863), WTC(0xbee349e5), WTC(0xbecfc145),
+ WTC(0xbebc4362), WTC(0xbea8d111), WTC(0xbe956806), WTC(0xbe820aeb),
+ WTC(0xbe6ebeb9), WTC(0xbe5b8313), WTC(0xbe485678), WTC(0xbe353cfb),
+ WTC(0xbe223ab8), WTC(0xbe0f4e5f), WTC(0xbdfc77b4), WTC(0xbde9bb99),
+ WTC(0xbdd71cbe), WTC(0xbdc4990d), WTC(0xbdb23175), WTC(0xbd9feab6),
+ WTC(0xbd8dc58d), WTC(0xbd7bbf8c), WTC(0xbd69daec), WTC(0xbd581c07),
+ WTC(0xbd46820c), WTC(0xbd350af8), WTC(0xbd23b9cc), WTC(0xbd129158),
+ WTC(0xbd018ece), WTC(0xbcf0b057), WTC(0xbcdff912), WTC(0xbccf69cf),
+ WTC(0xbcbefe81), WTC(0xbcaeb63a), WTC(0xbc9e9406), WTC(0xbc8e977c),
+ WTC(0xbc7ebd58), WTC(0xbc6f0544), WTC(0xbc5f7077), WTC(0xbc4ffe1d),
+ WTC(0xbc40ab99), WTC(0xbc317239), WTC(0xbc2252ad), WTC(0xbc136963),
+ WTC(0xbc04a822), WTC(0xbbf5941e), WTC(0xbbe68dab), WTC(0xbbd97a36),
+ WTC(0xbbcff44f), WTC(0xbbcb1891), WTC(0xbbca7818), WTC(0xbbcc765f),
+ WTC(0xbbcffaa5), WTC(0xbbd46a0f), WTC(0xbbda4060), WTC(0xbbe257f1),
+ WTC(0xbbed131c), WTC(0xbbfa7628), WTC(0xbc09cdd6), WTC(0xbc1a685b),
+ WTC(0xbc2bf2fd), WTC(0xbc3e6557), WTC(0xbc521d37), WTC(0xbc67c093),
+ WTC(0xbc803b98), WTC(0xbc9c3060), WTC(0xbcbbf6da), WTC(0xbcdf8c51),
+ WTC(0xbd06afb5), WTC(0xbd30e36d), WTC(0xbd5d99a0), WTC(0xbd8c71a6),
+ WTC(0xbdbd29c3), WTC(0xbdefb72a), WTC(0xbe243660), WTC(0xbe5b0335),
+ WTC(0xbe9477fd), WTC(0xbed0de00), WTC(0xbf108881), WTC(0xbf53d585),
+ WTC(0xbf9aeeba), WTC(0xbfe5bb38), WTC(0xc033318c), WTC(0xc081cdf2),
+ WTC(0xc0d0a9ee), WTC(0xc11f76d5), WTC(0xc16f66c3), WTC(0xc1c1d5c1),
+ WTC(0xc21726d4), WTC(0xc26f5bba), WTC(0xc2ca1036), WTC(0xc3268b0f),
+ WTC(0xc3839ff3), WTC(0xc3e03d22), WTC(0xc43b93ef), WTC(0xc4968594),
+ WTC(0xc4f3353c), WTC(0xc55202ab), WTC(0xc5b21fcf), WTC(0xc61224e6),
+ WTC(0xc670c168), WTC(0xc6ce3f1e), WTC(0xc72b3fbb), WTC(0xc787e688),
+ WTC(0xc7e41f56), WTC(0xc83f94a9), WTC(0xc899e833), WTC(0xc8f2b832),
+ WTC(0xb4d1fc78), WTC(0xb3a9ec70), WTC(0xb28524ca), WTC(0xb163a2ba),
+ WTC(0xb0456373), WTC(0xaf2a6327), WTC(0xae129708), WTC(0xacfdf2ca),
+ WTC(0xabec7168), WTC(0xaade0f8c), WTC(0xa9d2c80a), WTC(0xa8ca9711),
+ WTC(0xa7c57cdc), WTC(0xa6c37c29), WTC(0xa5c49ae6), WTC(0xa4c8e02c),
+ WTC(0xa3d05422), WTC(0xa2daff83), WTC(0xa1e8ec04), WTC(0xa0fa293f),
+ WTC(0xa00ec98a), WTC(0x9f26d990), WTC(0x9e4265a5), WTC(0x9d618437),
+ WTC(0x9c844ce0), WTC(0x9baad0fa), WTC(0x9ad52154), WTC(0x9a03509b),
+ WTC(0x993572ed), WTC(0x986b9e4d), WTC(0x97a5e7d8), WTC(0x96e46329),
+ WTC(0x96271ff8), WTC(0x956e2ab8), WTC(0x94b98f9c), WTC(0x94095a97),
+ WTC(0x935d969b), WTC(0x92b64cdf), WTC(0x9213809b), WTC(0x9175328a),
+ WTC(0x90db6153), WTC(0x90460712), WTC(0x8fb5146f), WTC(0x8f2876f4),
+ WTC(0x8ea018e5), WTC(0x8e1bd6df), WTC(0x8d9b7d9b), WTC(0x8d1ed745),
+ WTC(0x8ca5a942), WTC(0x8c2f93ce), WTC(0x8bbc204c), WTC(0x8b4ad58d),
+ WTC(0x8adb31e4), WTC(0x8a6c909b), WTC(0x89fe673d), WTC(0x8990a478),
+ WTC(0x89244670), WTC(0x88bc84cb), WTC(0x885e0963), WTC(0x880f73f5),
+ WTC(0x87cba2c0), WTC(0x87b48a6f), WTC(0x8799fb25), WTC(0x877f46f2),
+ WTC(0x876519cd), WTC(0x874a9a11), WTC(0x872fae01), WTC(0x871487d2),
+ WTC(0x86f9287b), WTC(0x86dd83b5), WTC(0x86c1947c), WTC(0x86a558f1),
+ WTC(0x8688d2e3), WTC(0x866c015b), WTC(0x864ede0c), WTC(0x863167cc),
+ WTC(0x8613a3b8), WTC(0x85f58fb2), WTC(0x85d723f0), WTC(0x85b86176),
+ WTC(0x85994d82), WTC(0x8579e443), WTC(0x855a201b), WTC(0x853a05b7),
+ WTC(0x85199a26), WTC(0x84f8d93f), WTC(0x84d7c100), WTC(0x84b65901),
+ WTC(0x8494a4ee), WTC(0x84729fd4), WTC(0x84504a9b), WTC(0x842dadb3),
+ WTC(0x840aca71), WTC(0x83e79c87), WTC(0x83c42892), WTC(0x83a07767),
+ WTC(0x837c883a), WTC(0x83585835), WTC(0x8333eeca), WTC(0x830f5368),
+ WTC(0x82ea82ec), WTC(0x82c57c57), WTC(0x82a048ea), WTC(0x827aed86),
+ WTC(0x82556588), WTC(0x822fb255), WTC(0x8209dd1e), WTC(0x81e3e76f),
+ WTC(0x81bdccac), WTC(0x81979098), WTC(0x81713ad7), WTC(0x814ac95d),
+ WTC(0x812437f2), WTC(0x80fd8c4b), WTC(0x80d6cc0a), WTC(0x80aff283),
+ WTC(0x8088fc64), WTC(0x8061eebe), WTC(0x803acfe9), WTC(0x8013a62d),
+ WTC(0x0a8d710a), WTC(0x0aecd974), WTC(0x0b4f7449), WTC(0x0bb4d13b),
+ WTC(0x0c1c7fee), WTC(0x0c86202a), WTC(0x0cf1c2e7), WTC(0x0d5f98d1),
+ WTC(0x0dcf816a), WTC(0x0e4162ae), WTC(0x0eb588ad), WTC(0x0f2c1e88),
+ WTC(0x0fa4d14f), WTC(0x101f4d80), WTC(0x109b5bfd), WTC(0x1118b908),
+ WTC(0x11971466), WTC(0x12168249), WTC(0x129754ab), WTC(0x1318d5c0),
+ WTC(0x1399b5d7), WTC(0x1418d8ec), WTC(0x14953f24), WTC(0x150dfe8a),
+ WTC(0x15822faa), WTC(0x15f0dd70), WTC(0x16592014), WTC(0x16ba35b2),
+ WTC(0x171384e7), WTC(0x1764cf1f), WTC(0x17b22a28), WTC(0x18047d40),
+ WTC(0x185ffc05), WTC(0x18c4a075), WTC(0x19322980), WTC(0x19a84643),
+ WTC(0x1a26a8f4), WTC(0x1aad099d), WTC(0x1b3b3493), WTC(0x1bd0eb32),
+ WTC(0x1c6db754), WTC(0x1d115a8c), WTC(0x1dbc329b), WTC(0x1e6ecb33),
+ WTC(0x1f29d42a), WTC(0x1feda2e4), WTC(0x20ba056e), WTC(0x218d02a2),
+ WTC(0x22635c75), WTC(0x233c2e7f), WTC(0x24184da1), WTC(0x24fa799d),
+ WTC(0x25e54e95), WTC(0x26d6edd8), WTC(0x27cc57a5), WTC(0x28c36349),
+ WTC(0x29bbdfdf), WTC(0x2ab9b7c2), WTC(0x2bc09790), WTC(0x2cd2d465),
+ WTC(0x2def4cb9), WTC(0x2f115dcc), WTC(0x3033a99c), WTC(0x3150fd8d),
+ WTC(0x32698a94), WTC(0x338152e6), WTC(0x34a02dcd), WTC(0x35cdedd1),
+ WTC(0x370aa9fa), WTC(0x38527a79), WTC(0x399c4a4f), WTC(0x3adf9c27),
+ WTC(0x3c17edc7), WTC(0x3d44f05d), WTC(0x3e6c519e), WTC(0x3f93ea5b),
+ WTC(0x40c0fc6d), WTC(0x41f60bdd), WTC(0x43332d15), WTC(0x4476e6ea),
+ WTC(0x45beb7e1), WTC(0x47072f2b), WTC(0x484cb71a), WTC(0x498ceafd),
+ WTC(0x4ac650c3), WTC(0x4bf93458), WTC(0x4d26a4c7), WTC(0x4e5090eb),
+ WTC(0x4f78c2ac), WTC(0x50a0918a), WTC(0x51c93995), WTC(0x52f3d6c7),
+ WTC(0x5420a9a2), WTC(0x554ef122), WTC(0x567ac4a9), WTC(0x579ebeb9),
+ WTC(0x58b8569c), WTC(0x59c74ea4), WTC(0x5ad03f31), WTC(0x5bd821c8),
+ WTC(0x5ce05502), WTC(0x5de8e582), WTC(0x5ef09b49), WTC(0x5ff56247),
+ WTC(0x60f40d81), WTC(0x61ea1450), WTC(0x62d60a2d), WTC(0x63bad7f1),
+ WTC(0x649e942e), WTC(0x65827556), WTC(0x66648178), WTC(0x67418c31),
+ WTC(0x6816c1ee), WTC(0x68e5411d), WTC(0x69aeffdb), WTC(0x6a74bb0e),
+ WTC(0x6b36a5ae), WTC(0x6bf44fd1), WTC(0x6cad341f), WTC(0x6d60c0ca),
+ WTC(0xae35f79b), WTC(0xb07e1b0d), WTC(0xb2bad26d), WTC(0xb4ed8af7),
+ WTC(0xb717b207), WTC(0xb93a8f5b), WTC(0xbb56631e), WTC(0xbd6afcab),
+ WTC(0xbf7832db), WTC(0xc17dd996), WTC(0xc37bb355), WTC(0xc5718d72),
+ WTC(0xc75f56cc), WTC(0xc944f93d), WTC(0xcb224f17), WTC(0xccf74805),
+ WTC(0xcec3ed8c), WTC(0xd08835d9), WTC(0xd2440837), WTC(0xd3f7692d),
+ WTC(0xd5a26b17), WTC(0xd74502b6), WTC(0xd8df1f82), WTC(0xda70d495),
+ WTC(0xdbfa35a1), WTC(0xdd7b3498), WTC(0xdef3cba3), WTC(0xe064184e),
+ WTC(0xe1cc2ab9), WTC(0xe32bf548), WTC(0xe48381cd), WTC(0xe5d2f779),
+ WTC(0xe71a6218), WTC(0xe859b789), WTC(0xe9910a60), WTC(0xeac07956),
+ WTC(0xebe7fb55), WTC(0xed077f41), WTC(0xee1f1f9d), WTC(0xef2efd99),
+ WTC(0xf0372472), WTC(0xf137b605), WTC(0xf23112b3), WTC(0xf323808a),
+ WTC(0xf40f0a86), WTC(0xf4f39883), WTC(0xf5d0eb3c), WTC(0xf6a679c6),
+ WTC(0xf7739640), WTC(0xf8389849), WTC(0xf8f66b2a), WTC(0xf9ada7d6),
+ WTC(0xfa5e97ed), WTC(0xfb08becd), WTC(0xfbabb380), WTC(0xfc48125f),
+ WTC(0xfcde5b40), WTC(0xfd6e4aac), WTC(0xfdf76560), WTC(0xfe78f3ab),
+ WTC(0xfef34cf0), WTC(0xff67b689), WTC(0xffd7e342), WTC(0x004584ef),
+ WTC(0x00b00074), WTC(0x01152d47), WTC(0x0171ccea), WTC(0x01c2fdbe),
+ WTC(0x0209b563), WTC(0x02489832), WTC(0x0283e2cd), WTC(0x02bf2050),
+ WTC(0x02fb72fb), WTC(0x03381f29), WTC(0x0371ea7c), WTC(0x03a602f3),
+ WTC(0x03d267e0), WTC(0x03f6621b), WTC(0x04125dc8), WTC(0x0427b7a5),
+ WTC(0x04385062), WTC(0x0445caca), WTC(0x04518ee3), WTC(0x045c745e),
+ WTC(0x0466d714), WTC(0x0470125c), WTC(0x047742d7), WTC(0x047b73cf),
+ WTC(0x047bba82), WTC(0x047744aa), WTC(0x046dc536), WTC(0x045f9068),
+ WTC(0x044d7632), WTC(0x0438aa92), WTC(0x04227f39), WTC(0x040c2331),
+ WTC(0x03f561d8), WTC(0x03dd60b4), WTC(0x03c31064), WTC(0x03a58d7d),
+ WTC(0x0384b74f), WTC(0x0360e29a), WTC(0x033b1151), WTC(0x031417f0),
+ WTC(0x02ec54ca), WTC(0x02c3d2ce), WTC(0x029a458d), WTC(0x026f4411),
+ WTC(0x02426093), WTC(0x0213d67f), WTC(0x01e43b01), WTC(0x01b3c7c1),
+ WTC(0x01828dd8), WTC(0x01509d92), WTC(0x011e0556), WTC(0x00eace1d),
+ WTC(0x00b70bb3), WTC(0x0082ed8b), WTC(0x004ea707), WTC(0x001a6b8f),
+ WTC(0xd619769b), WTC(0xd539cbf6), WTC(0xd45d68b9), WTC(0xd3840fce),
+ WTC(0xd2ad840b), WTC(0xd1d9a580), WTC(0xd1092160), WTC(0xd03cacdc),
+ WTC(0xcf7383ba), WTC(0xceacfd46), WTC(0xcdea429a), WTC(0xcd2bf5ec),
+ WTC(0xcc709dc1), WTC(0xcbb6dc91), WTC(0xcafdff71), WTC(0xca4504cd),
+ WTC(0xc98a93f4), WTC(0xc8cf0eb0), WTC(0xc813ee7f), WTC(0xc75665f3),
+ WTC(0xc6912d63), WTC(0xc5bff74a), WTC(0xc4dee9fa), WTC(0xc3ea39ef),
+ WTC(0xc2de1c94), WTC(0xc1b6bd08), WTC(0xc07074da), WTC(0xbf081038),
+ WTC(0xbd7b166b), WTC(0xbbc8afd7), WTC(0xba01d47c), WTC(0xb84b481f),
+ WTC(0xb6b65953), WTC(0xb542e5d2), WTC(0xb3f04291), WTC(0xb2bdc25a),
+ WTC(0xb1aab810), WTC(0xb0b676a0), WTC(0xafe050d5), WTC(0xaf27997d),
+ WTC(0xae8ba390), WTC(0xae0bc202), WTC(0xada7479d), WTC(0xad5d872f),
+ WTC(0xad2dd392), WTC(0xad177f97), WTC(0xad19de04), WTC(0xad3441c5),
+ WTC(0xad65fddc), WTC(0xadae6514), WTC(0xae0cca18), WTC(0xae807fde),
+ WTC(0xaf08d967), WTC(0xafa5296f), WTC(0xb054c2ac), WTC(0xb116f81b),
+ WTC(0xb1eb1cb1), WTC(0xb2d082fe), WTC(0xb3c677e5), WTC(0xb4cc6e9c),
+ WTC(0xb5e17eb4), WTC(0xb7052956), WTC(0xb836b427), WTC(0xb97571f3),
+ WTC(0xbac0b594), WTC(0xbc17d1ee), WTC(0xbd7a19eb), WTC(0xbee6e071),
+ WTC(0xc05d7837), WTC(0xc1dd33fe), WTC(0xc36566c2), WTC(0xc4f56377),
+ WTC(0xc68c7ce5), WTC(0xc82a05db), WTC(0xc9cd5148), WTC(0xcb75b207),
+ WTC(0xcd227ad9), WTC(0xced2fe95), WTC(0xd0869026), WTC(0xd23c8268),
+ WTC(0xd3f42834), WTC(0xd5acd460), WTC(0xd765d9c5), WTC(0xd91e8b42),
+ WTC(0xdad63bb5), WTC(0xdc8c3df2), WTC(0xde3fe4d1), WTC(0xdff08333),
+ WTC(0xe19d6bf6), WTC(0xe345f1ee), WTC(0xe4e967f3), WTC(0xe68720e7),
+ WTC(0xe81e6fa3), WTC(0xe9aea6fb), WTC(0xeb3719cb), WTC(0xecb71af3),
+ WTC(0xee2dfd4b), WTC(0xef9b13ab), WTC(0xf0fdb0ee), WTC(0xf25527f1),
+ WTC(0xf3a0cb8e), WTC(0xf4dfee9f), WTC(0xf611e3ff), WTC(0xf735fe8b),
+ WTC(0xf84b911a), WTC(0xf951ee85), WTC(0xfa4869a5), WTC(0xfb2e5557),
+ WTC(0xfc030477), WTC(0xfcc5c9e0), WTC(0xfd75f86b), WTC(0xfe12e2f2),
+ WTC(0xfe9bdc51), WTC(0xff103761), WTC(0xff6f46fc), WTC(0xffb85dfe),
+ WTC(0xffeacf42), WTC(0x0005ee03), WTC(0x0009162b), WTC(0xfff368d1),
+};
+
+const FIXP_WTB LowDelaySynthesis160[480] = {
+ WTC(0xdb171130), WTC(0xdbfadfbd), WTC(0xdce2192a), WTC(0xddcccbc8),
+ WTC(0xdebaeb0c), WTC(0xdfac6ebd), WTC(0xe0a17875), WTC(0xe199e10c),
+ WTC(0xe29531fd), WTC(0xe3933ef6), WTC(0xe49487be), WTC(0xe598bcf5),
+ WTC(0xe69f38b0), WTC(0xe7a73d45), WTC(0xe8b02e94), WTC(0xe9b9dc97),
+ WTC(0xeac4e62c), WTC(0xebd111fc), WTC(0xecdd0242), WTC(0xede7178d),
+ WTC(0xeeee9c24), WTC(0xeff34dba), WTC(0xf0f4eaf5), WTC(0xf1f36695),
+ WTC(0xf2eeb2b2), WTC(0xf3e663cb), WTC(0xf4d9cbfe), WTC(0xf5c76b3c),
+ WTC(0xf6ada4cb), WTC(0xf78bc92d), WTC(0xf862dc57), WTC(0xf93589ca),
+ WTC(0xfa059b44), WTC(0xfad501fc), WTC(0xfba49819), WTC(0xfc740f58),
+ WTC(0xfd465b6d), WTC(0xfe1ee06f), WTC(0xfef2581b), WTC(0xff9ec7d9),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbff143f6), WTC(0xbfd3cd5c), WTC(0xbfb64d54), WTC(0xbf98ce80),
+ WTC(0xbf7b5291), WTC(0xbf5dd523), WTC(0xbf405f8e), WTC(0xbf22ee55),
+ WTC(0xbf058664), WTC(0xbee82d22), WTC(0xbecae0a1), WTC(0xbeadacb5),
+ WTC(0xbe908f68), WTC(0xbe73901d), WTC(0xbe56b673), WTC(0xbe3a013e),
+ WTC(0xbe1d7dad), WTC(0xbe012b19), WTC(0xbde51134), WTC(0xbdc93781),
+ WTC(0xbdad9c88), WTC(0xbd924bd8), WTC(0xbd774311), WTC(0xbd5c882b),
+ WTC(0xbd4220fa), WTC(0xbd280a49), WTC(0xbd0e4d50), WTC(0xbcf4e46e),
+ WTC(0xbcdbd1a4), WTC(0xbcc31624), WTC(0xbcaaaa02), WTC(0xbc929348),
+ WTC(0xbc7acc12), WTC(0xbc63525e), WTC(0xbc4c26b1), WTC(0xbc353ea9),
+ WTC(0xbc1e91e2), WTC(0xbc085aea), WTC(0xbbf1c04a), WTC(0xbbdc7521),
+ WTC(0xbbce4740), WTC(0xbbca5187), WTC(0xbbcd3a7c), WTC(0xbbd33634),
+ WTC(0xbbdc0a34), WTC(0xbbea218a), WTC(0xbbfe25b7), WTC(0xbc162887),
+ WTC(0xbc3076c5), WTC(0xbc4d09f6), WTC(0xbc6d925c), WTC(0xbc94da6e),
+ WTC(0xbcc48300), WTC(0xbcfc9763), WTC(0xbd3bd94f), WTC(0xbd808d05),
+ WTC(0xbdc9a11b), WTC(0xbe16e339), WTC(0xbe691db9), WTC(0xbec179c1),
+ WTC(0xbf210140), WTC(0xbf88cd62), WTC(0xbff8e8d3), WTC(0xc06e1aaa),
+ WTC(0xc0e45951), WTC(0xc15b3820), WTC(0xc1d6e2ff), WTC(0xc2590e0a),
+ WTC(0xc2e10f83), WTC(0xc36c5c9a), WTC(0xc3f735f3), WTC(0xc47fb2d1),
+ WTC(0xc50abce5), WTC(0xc59a0a25), WTC(0xc629f21c), WTC(0xc6b6ef89),
+ WTC(0xc7427180), WTC(0xc7cd1fc4), WTC(0xc856485f), WTC(0xc8dcae93),
+ WTC(0xb487a986), WTC(0xb2ce0812), WTC(0xb11bc4c2), WTC(0xaf70d5cb),
+ WTC(0xadcd228e), WTC(0xac3086a2), WTC(0xaa9af36b), WTC(0xa90c5935),
+ WTC(0xa784b214), WTC(0xa60407e9), WTC(0xa48a7076), WTC(0xa31806f9),
+ WTC(0xa1aceb03), WTC(0xa0494f63), WTC(0x9eed6840), WTC(0x9d996570),
+ WTC(0x9c4d93b4), WTC(0x9b0a3114), WTC(0x99cf798d), WTC(0x989db16a),
+ WTC(0x97752146), WTC(0x965609f1), WTC(0x95409b05), WTC(0x9434fda9),
+ WTC(0x9333587b), WTC(0x923bc7d6), WTC(0x914e5299), WTC(0x906af345),
+ WTC(0x8f9185e6), WTC(0x8ec1cbe9), WTC(0x8dfb64c9), WTC(0x8d3dab18),
+ WTC(0x8c87de34), WTC(0x8bd8c494), WTC(0x8b2ecacc), WTC(0x8a882a5f),
+ WTC(0x89e2ecd1), WTC(0x893f12b2), WTC(0x88a3c878), WTC(0x882141c7),
+ WTC(0x87c65dcd), WTC(0x87a0c07b), WTC(0x8778b859), WTC(0x87514698),
+ WTC(0x8728e900), WTC(0x87000679), WTC(0x86d68f05), WTC(0x86ac6ee7),
+ WTC(0x8681a5ce), WTC(0x86562ed0), WTC(0x8629fdeb), WTC(0x85fd1ca8),
+ WTC(0x85cf7b32), WTC(0x85a11a2f), WTC(0x8571fbbe), WTC(0x854213f5),
+ WTC(0x8511722b), WTC(0x84e00ee3), WTC(0x84adf346), WTC(0x847b28e5),
+ WTC(0x8447a9d0), WTC(0x84138a20), WTC(0x83dec5b6), WTC(0x83a9694f),
+ WTC(0x83738231), WTC(0x833d0def), WTC(0x8306247b), WTC(0x82cec29b),
+ WTC(0x8296f5f3), WTC(0x825ecbe4), WTC(0x82263fe8), WTC(0x81ed682f),
+ WTC(0x81b4406d), WTC(0x817ad2a1), WTC(0x814127f4), WTC(0x8107392d),
+ WTC(0x80cd184d), WTC(0x8092bc5f), WTC(0x80582866), WTC(0x801d714f),
+ WTC(0x0aa4f846), WTC(0x0b3686fe), WTC(0x0bce899e), WTC(0x0c6b8a7e),
+ WTC(0x0d0d036f), WTC(0x0db358b8), WTC(0x0e5e31dd), WTC(0x0f0e4270),
+ WTC(0x0fc347c1), WTC(0x107c35cc), WTC(0x11383a63), WTC(0x11f68759),
+ WTC(0x12b7b1e3), WTC(0x13799d61), WTC(0x14383db4), WTC(0x14f032c0),
+ WTC(0x159e6920), WTC(0x163fb449), WTC(0x16d14820), WTC(0x17512c3f),
+ WTC(0x17c5f622), WTC(0x18483f2a), WTC(0x18df3074), WTC(0x1989f589),
+ WTC(0x1a4783af), WTC(0x1b16f152), WTC(0x1bf7795a), WTC(0x1ce7c950),
+ WTC(0x1de817ec), WTC(0x1efa3f4a), WTC(0x201ff37a), WTC(0x2157d4e1),
+ WTC(0x22995036), WTC(0x23e0d882), WTC(0x25345db2), WTC(0x269a10c3),
+ WTC(0x280a0798), WTC(0x297d6cf9), WTC(0x2afa7e1b), WTC(0x2c8d210a),
+ WTC(0x2e377db2), WTC(0x2feb60cc), WTC(0x31977111), WTC(0x333b1637),
+ WTC(0x34ea14df), WTC(0x36ba32d4), WTC(0x38a524c8), WTC(0x3a8fa891),
+ WTC(0x3c640cb3), WTC(0x3e22ab11), WTC(0x3fde7cc9), WTC(0x41a80486),
+ WTC(0x438394e4), WTC(0x456c8d8f), WTC(0x4758f4da), WTC(0x493d7a7b),
+ WTC(0x4b139f32), WTC(0x4cdbb199), WTC(0x4e9ab8d1), WTC(0x50569530),
+ WTC(0x5213a89e), WTC(0x53d5462c), WTC(0x559a5aa7), WTC(0x5756acf5),
+ WTC(0x58fcfb38), WTC(0x5a8e3e07), WTC(0x5c1a20e8), WTC(0x5da6c7da),
+ WTC(0x5f3231f3), WTC(0x60b51fb6), WTC(0x62260848), WTC(0x6381f5a9),
+ WTC(0x64d79ac7), WTC(0x662c51c0), WTC(0x67779c07), WTC(0x68b22184),
+ WTC(0x69e0ca28), WTC(0x6b068bcf), WTC(0x6c23008e), WTC(0x6d346856),
+ WTC(0xaec92693), WTC(0xb22ca2bd), WTC(0xb578d421), WTC(0xb8b27edb),
+ WTC(0xbbdc38b5), WTC(0xbef598bb), WTC(0xc1fe0dcd), WTC(0xc4f4d7ff),
+ WTC(0xc7d98479), WTC(0xcaabc289), WTC(0xcd6b38f6), WTC(0xd017edff),
+ WTC(0xd2b1aa37), WTC(0xd538739f), WTC(0xd7ac554d), WTC(0xda0d2f5e),
+ WTC(0xdc5b3f69), WTC(0xde966e30), WTC(0xe0bee2c8), WTC(0xe2d4c9cd),
+ WTC(0xe4d82000), WTC(0xe6c94926), WTC(0xe8a84b14), WTC(0xea755ac3),
+ WTC(0xec309bdc), WTC(0xedd9f2a8), WTC(0xef71c040), WTC(0xf0f842ad),
+ WTC(0xf26e53cb), WTC(0xf3d4cd9f), WTC(0xf52b9ddf), WTC(0xf671db4d),
+ WTC(0xf7a58faa), WTC(0xf8c79907), WTC(0xf9da7c73), WTC(0xfadee240),
+ WTC(0xfbd360e6), WTC(0xfcb95db4), WTC(0xfd913bb1), WTC(0xfe594e2e),
+ WTC(0xff10e67c), WTC(0xffbc2326), WTC(0x00608350), WTC(0x00fc8a2d),
+ WTC(0x01873313), WTC(0x01f8e4fe), WTC(0x02579318), WTC(0x02b03ec3),
+ WTC(0x030ab2da), WTC(0x0363ea2a), WTC(0x03b1e60d), WTC(0x03ee2920),
+ WTC(0x0418405c), WTC(0x04348449), WTC(0x0448d9f7), WTC(0x0459c65f),
+ WTC(0x04694a29), WTC(0x0475b506), WTC(0x047bebeb), WTC(0x0478dcd2),
+ WTC(0x046aa475), WTC(0x045249a9), WTC(0x043332f0), WTC(0x0411bb77),
+ WTC(0x03ef893b), WTC(0x03c9ebb8), WTC(0x039da778), WTC(0x036a1273),
+ WTC(0x03316a60), WTC(0x02f6553a), WTC(0x02b98be9), WTC(0x027a2e2c),
+ WTC(0x0236df64), WTC(0x01f036bf), WTC(0x01a78b41), WTC(0x015d29da),
+ WTC(0x01114624), WTC(0x00c406e9), WTC(0x0075ddb1), WTC(0x00277692),
+ WTC(0xd5e139e9), WTC(0xd494362e), WTC(0xd34e2bff), WTC(0xd20e56f8),
+ WTC(0xd0d5a3dc), WTC(0xcfa5904f), WTC(0xce7be3cb), WTC(0xcd5b3086),
+ WTC(0xcc420f0f), WTC(0xcb2c2bf6), WTC(0xca1695c3), WTC(0xc8fdf020),
+ WTC(0xc7e4fc07), WTC(0xc6c374c6), WTC(0xc5895653), WTC(0xc4297218),
+ WTC(0xc296f958), WTC(0xc0c51a3c), WTC(0xbea84ee5), WTC(0xbc38842f),
+ WTC(0xb9915966), WTC(0xb7186ae5), WTC(0xb4eb3040), WTC(0xb3076897),
+ WTC(0xb16acba3), WTC(0xb013112a), WTC(0xaefdf0a2), WTC(0xae2921f5),
+ WTC(0xad925cd6), WTC(0xad3758be), WTC(0xad15cd3d), WTC(0xad2b71ca),
+ WTC(0xad75fe65), WTC(0xadf32a84), WTC(0xaea0ada9), WTC(0xaf7c3fcd),
+ WTC(0xb0839825), WTC(0xb1b46e9c), WTC(0xb30c7a20), WTC(0xb48970be),
+ WTC(0xb62912e0), WTC(0xb7e90de7), WTC(0xb9c71d12), WTC(0xbbc0f7fd),
+ WTC(0xbdd45674), WTC(0xbffef022), WTC(0xc23e7c49), WTC(0xc490b2d4),
+ WTC(0xc6f34b70), WTC(0xc963fda9), WTC(0xcbe0813e), WTC(0xce668d98),
+ WTC(0xd0f3da69), WTC(0xd3861f64), WTC(0xd61b141f), WTC(0xd8b07038),
+ WTC(0xdb43eb5d), WTC(0xddd33d22), WTC(0xe05c1d2e), WTC(0xe2dc432c),
+ WTC(0xe55166ad), WTC(0xe7b93f62), WTC(0xea1184df), WTC(0xec57eec9),
+ WTC(0xee8a34c6), WTC(0xf0a60e70), WTC(0xf2a9336e), WTC(0xf4915b60),
+ WTC(0xf65c3dea), WTC(0xf80792ae), WTC(0xf9911147), WTC(0xfaf67154),
+ WTC(0xfc356a7e), WTC(0xfd4bb465), WTC(0xfe3706a9), WTC(0xfef518ec),
+ WTC(0xff83a2cf), WTC(0xffe05bed), WTC(0x0008fd26), WTC(0xfffb4037),
+};
+
+const FIXP_WTB LowDelaySynthesis128[384] = {
+ WTC(0xdb335c78), WTC(0xdc512d40), WTC(0xdd746116), WTC(0xde9cf7ae),
+ WTC(0xdfcadda8), WTC(0xe0fe4196), WTC(0xe236a409), WTC(0xe373518f),
+ WTC(0xe4b4e870), WTC(0xe5faf25e), WTC(0xe744190a), WTC(0xe88f06f4),
+ WTC(0xe9db2796), WTC(0xeb29613f), WTC(0xec78b08e), WTC(0xedc5f65d),
+ WTC(0xef0f5af4), WTC(0xf05447dd), WTC(0xf1945392), WTC(0xf2cf795a),
+ WTC(0xf405123d), WTC(0xf533af3d), WTC(0xf65842dd), WTC(0xf77071ae),
+ WTC(0xf87d623f), WTC(0xf983c711), WTC(0xfa8730ce), WTC(0xfb8aad4b),
+ WTC(0xfc8e1dc6), WTC(0xfd96d19a), WTC(0xfea5325a), WTC(0xff8d21da),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbfed9606), WTC(0xbfc8bddf), WTC(0xbfa3dd57), WTC(0xbf7f023c),
+ WTC(0xbf5a25e8), WTC(0xbf3554df), WTC(0xbf108b6b), WTC(0xbeebd7bd),
+ WTC(0xbec738a6), WTC(0xbea2bf45), WTC(0xbe7e6b42), WTC(0xbe5a4fd5),
+ WTC(0xbe366de8), WTC(0xbe12d91e), WTC(0xbdef9338), WTC(0xbdccaf6e),
+ WTC(0xbdaa2e3f), WTC(0xbd88205e), WTC(0xbd668430), WTC(0xbd456994),
+ WTC(0xbd24cdad), WTC(0xbd04bc91), WTC(0xbce52def), WTC(0xbcc62942),
+ WTC(0xbca7a273), WTC(0xbc899fba), WTC(0xbc6c16ab), WTC(0xbc4f0812),
+ WTC(0xbc326537), WTC(0xbc162fb3), WTC(0xbbfa5915), WTC(0xbbded462),
+ WTC(0xbbcd3956), WTC(0xbbcae0f5), WTC(0xbbd0beb7), WTC(0xbbdaaf42),
+ WTC(0xbbec5289), WTC(0xbc06d115), WTC(0xbc266162), WTC(0xbc494d27),
+ WTC(0xbc721013), WTC(0xbca5b2d9), WTC(0xbce6a063), WTC(0xbd339d3d),
+ WTC(0xbd8975b2), WTC(0xbde618b1), WTC(0xbe499de1), WTC(0xbeb60feb),
+ WTC(0xbf2d830e), WTC(0xbfb1ee2e), WTC(0xc041e22f), WTC(0xc0d59618),
+ WTC(0xc16a574d), WTC(0xc206ed94), WTC(0xc2ad7ad1), WTC(0xc35ae733),
+ WTC(0xc4085fbf), WTC(0xc4b33a35), WTC(0xc563f6ce), WTC(0xc6181ab7),
+ WTC(0xc6c86beb), WTC(0xc7768de4), WTC(0xc8231ab3), WTC(0xc8cc145a),
+ WTC(0xb4500dde), WTC(0xb22a524e), WTC(0xb010144c), WTC(0xae013530),
+ WTC(0xabfd7206), WTC(0xaa04a92f), WTC(0xa816c008), WTC(0xa633baab),
+ WTC(0xa45bbe2b), WTC(0xa28eff5e), WTC(0xa0cdc4c6), WTC(0x9f187801),
+ WTC(0x9d6f7708), WTC(0x9bd34eb0), WTC(0x9a44763a), WTC(0x98c36ace),
+ WTC(0x9750b896), WTC(0x95ecdc61), WTC(0x94982f8c), WTC(0x9353005a),
+ WTC(0x921d8bac), WTC(0x90f7e126), WTC(0x8fe1e828), WTC(0x8edb3ddc),
+ WTC(0x8de337c8), WTC(0x8cf89cdb), WTC(0x8c19be6d), WTC(0x8b43d072),
+ WTC(0x8a737663), WTC(0x89a52f4d), WTC(0x88dc38e8), WTC(0x882f6f3f),
+ WTC(0x87c22c55), WTC(0x87918a21), WTC(0x87602c61), WTC(0x872dfd0a),
+ WTC(0x86fae063), WTC(0x86c6d729), WTC(0x8691c4ad), WTC(0x865ba7e8),
+ WTC(0x86246b66), WTC(0x85ec17ab), WTC(0x85b293e2), WTC(0x8577eaac),
+ WTC(0x853c09be), WTC(0x84ff042d), WTC(0x84c0d195), WTC(0x84818c4c),
+ WTC(0x84412e63), WTC(0x83ffd42c), WTC(0x83bd7bdf), WTC(0x837a471b),
+ WTC(0x833636dc), WTC(0x82f16e48), WTC(0x82abed37), WTC(0x8265d6c4),
+ WTC(0x821f28cf), WTC(0x81d80322), WTC(0x8190625c), WTC(0x81486134),
+ WTC(0x80fff7a0), WTC(0x80b73d86), WTC(0x806e2527), WTC(0x8024c969),
+ WTC(0x0ab6c2d2), WTC(0x0b6edac2), WTC(0x0c302988), WTC(0x0cf88fab),
+ WTC(0x0dc87461), WTC(0x0e9f9122), WTC(0x0f7ee53f), WTC(0x1064e7bf),
+ WTC(0x114fe4b7), WTC(0x123e9e4c), WTC(0x13311589), WTC(0x1420b664),
+ WTC(0x15069245), WTC(0x15dc93ad), WTC(0x169caf41), WTC(0x17422e16),
+ WTC(0x17d51de4), WTC(0x187e7622), WTC(0x1947aa0b), WTC(0x1a2ed3b4),
+ WTC(0x1b321858), WTC(0x1c4fcc7f), WTC(0x1d8601a3), WTC(0x1ed6ec5e),
+ WTC(0x20460b07), WTC(0x21cfbf59), WTC(0x23652732), WTC(0x2508e4b1),
+ WTC(0x26c7b0a6), WTC(0x289505da), WTC(0x2a698dd8), WTC(0x2c5954d2),
+ WTC(0x2e6dd135), WTC(0x308d838f), WTC(0x329de377), WTC(0x34b28f13),
+ WTC(0x36f67988), WTC(0x395ec1e5), WTC(0x3bb7b587), WTC(0x3deb63cc),
+ WTC(0x4016b320), WTC(0x42584eb2), WTC(0x44b424ca), WTC(0x471ba5b2),
+ WTC(0x49791954), WTC(0x4bc02004), WTC(0x4df3b8c0), WTC(0x501f1e1e),
+ WTC(0x524b93e2), WTC(0x547f0eef), WTC(0x56b23d03), WTC(0x58c99052),
+ WTC(0x5abfc042), WTC(0x5caebf1a), WTC(0x5e9e618b), WTC(0x608595d7),
+ WTC(0x62528e67), WTC(0x6401eb53), WTC(0x65ad0eb1), WTC(0x674f1cd2),
+ WTC(0x68d8804e), WTC(0x6a4ff10e), WTC(0x6bb987a5), WTC(0x6d12e937),
+ WTC(0xaf370652), WTC(0xb36badcf), WTC(0xb77ec321), WTC(0xbb77e364),
+ WTC(0xbf57979e), WTC(0xc31cb589), WTC(0xc6c5e686), WTC(0xca52811d),
+ WTC(0xcdc1d66b), WTC(0xd113d0f0), WTC(0xd4481c98), WTC(0xd75ee41b),
+ WTC(0xda57f7bf), WTC(0xdd33a926), WTC(0xdff1e272), WTC(0xe2931227),
+ WTC(0xe5174232), WTC(0xe77f0b15), WTC(0xe9ca889d), WTC(0xebfa2f7c),
+ WTC(0xee0de002), WTC(0xf0063326), WTC(0xf1e3e5f1), WTC(0xf3a8d749),
+ WTC(0xf5555599), WTC(0xf6e77eb2), WTC(0xf85cb5d6), WTC(0xf9b8e64d),
+ WTC(0xfafe52ad), WTC(0xfc2b37b8), WTC(0xfd420467), WTC(0xfe41412c),
+ WTC(0xff26ded5), WTC(0xfffa6150), WTC(0x00c374a4), WTC(0x01773884),
+ WTC(0x02058de3), WTC(0x0278d689), WTC(0x02e87372), WTC(0x03593268),
+ WTC(0x03ba79ab), WTC(0x03fff32b), WTC(0x042b2341), WTC(0x044690de),
+ WTC(0x045bc96a), WTC(0x046e77e9), WTC(0x047a85c1), WTC(0x0479d8c4),
+ WTC(0x04681aec), WTC(0x0447318f), WTC(0x041e4d13), WTC(0x03f3edad),
+ WTC(0x03c4cc17), WTC(0x038b1f6f), WTC(0x03470909), WTC(0x02fdcebd),
+ WTC(0x02b1cb18), WTC(0x0261730d), WTC(0x020afad0), WTC(0x01b0b9c8),
+ WTC(0x0153c1a0), WTC(0x00f47426), WTC(0x00933db7), WTC(0x003140e9),
+ WTC(0xd5b730bf), WTC(0xd4192c32), WTC(0xd2859479), WTC(0xd0fc3b9d),
+ WTC(0xcf800352), WTC(0xce0e6ab3), WTC(0xccaaf25f), WTC(0xcb4ed003),
+ WTC(0xc9f3ae44), WTC(0xc8948a56), WTC(0xc73226fd), WTC(0xc5b2676a),
+ WTC(0xc3fa2a82), WTC(0xc1f05f70), WTC(0xbf7c884b), WTC(0xbc8b1e86),
+ WTC(0xb93e1633), WTC(0xb63eb483), WTC(0xb3b45d14), WTC(0xb19a8ee2),
+ WTC(0xafecd4aa), WTC(0xaea6b8e7), WTC(0xadc3c6bf), WTC(0xad3f88ac),
+ WTC(0xad158929), WTC(0xad4152b1), WTC(0xadbe7068), WTC(0xae886c76),
+ WTC(0xaf9ad1fe), WTC(0xb0f12b26), WTC(0xb2870347), WTC(0xb457d633),
+ WTC(0xb65f592c), WTC(0xb898eca0), WTC(0xbb00291b), WTC(0xbd90996b),
+ WTC(0xc045c861), WTC(0xc31b4022), WTC(0xc60c8bd5), WTC(0xc91535f2),
+ WTC(0xcc30c94c), WTC(0xcf5ad039), WTC(0xd28ed58a), WTC(0xd5c863e5),
+ WTC(0xd90305e6), WTC(0xdc3a4644), WTC(0xdf69af93), WTC(0xe28ccc93),
+ WTC(0xe59f27d7), WTC(0xe89c4c15), WTC(0xeb7fc3e3), WTC(0xee4519f7),
+ WTC(0xf0e7d8ed), WTC(0xf3638b73), WTC(0xf5b3bc30), WTC(0xf7d3f5d0),
+ WTC(0xf9bfc2f0), WTC(0xfb72ae35), WTC(0xfce84251), WTC(0xfe1c09e5),
+ WTC(0xff098f9a), WTC(0xffac5e15), WTC(0xffffffb2), WTC(0x0000159b),
+};
+
+const FIXP_WTB LowDelaySynthesis120[360] = {
+ WTC(0xdb3ccdcd), WTC(0xdc6e0d69), WTC(0xdda570a7), WTC(0xdee2ef33),
+ WTC(0xe02680f4), WTC(0xe1704397), WTC(0xe2bf5626), WTC(0xe4137c80),
+ WTC(0xe56d30cd), WTC(0xe6cb22fe), WTC(0xe82b9f14), WTC(0xe98d8220),
+ WTC(0xeaf18a17), WTC(0xec57328f), WTC(0xedbae901), WTC(0xef1a42b9),
+ WTC(0xf07481f7), WTC(0xf1c932d4), WTC(0xf3183e19), WTC(0xf460b35f),
+ WTC(0xf5a04ac7), WTC(0xf6d33845), WTC(0xf7f80ec0), WTC(0xf912a5cd),
+ WTC(0xfa282a2e), WTC(0xfb3cd81c), WTC(0xfc51629b), WTC(0xfd69f81f),
+ WTC(0xfe8abdeb), WTC(0xff86f173), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbfec5bfa), WTC(0xbfc50dd8), WTC(0xbf9db88b), WTC(0xbf76683c),
+ WTC(0xbf4f1944), WTC(0xbf27d649), WTC(0xbf00a158), WTC(0xbed9848c),
+ WTC(0xbeb288f1), WTC(0xbe8bb79f), WTC(0xbe651f00), WTC(0xbe3ec6f8),
+ WTC(0xbe18c1f6), WTC(0xbdf315fe), WTC(0xbdcdd79d), WTC(0xbda909c1),
+ WTC(0xbd84beae), WTC(0xbd60f6ab), WTC(0xbd3dc210), WTC(0xbd1b2093),
+ WTC(0xbcf91ae9), WTC(0xbcd7acab), WTC(0xbcb6d5cc), WTC(0xbc969143),
+ WTC(0xbc76dcf4), WTC(0xbc57b317), WTC(0xbc390c4d), WTC(0xbc1ad514),
+ WTC(0xbbfd2fdb), WTC(0xbbdfa548), WTC(0xbbcce946), WTC(0xbbcb39d9),
+ WTC(0xbbd214cf), WTC(0xbbddfb60), WTC(0xbbf3783e), WTC(0xbc11f8d2),
+ WTC(0xbc3509f8), WTC(0xbc5ca2b0), WTC(0xbc8dc0b0), WTC(0xbccd4b2f),
+ WTC(0xbd1b7107), WTC(0xbd74c6a4), WTC(0xbdd635c0), WTC(0xbe3f4cd7),
+ WTC(0xbeb24836), WTC(0xbf31b5df), WTC(0xbfbfe6e2), WTC(0xc05a6dbf),
+ WTC(0xc0f80700), WTC(0xc198449c), WTC(0xc242ea15), WTC(0xc2f8270d),
+ WTC(0xc3b20bd2), WTC(0xc468f554), WTC(0xc522637e), WTC(0xc5e2403b),
+ WTC(0xc69f9771), WTC(0xc7599dd5), WTC(0xc811f85a), WTC(0xc8c687db),
+ WTC(0xb43d8b3b), WTC(0xb1f3fb3c), WTC(0xafb77be9), WTC(0xad87e063),
+ WTC(0xab64dcd5), WTC(0xa94e4cc2), WTC(0xa74418f8), WTC(0xa5465837),
+ WTC(0xa3554252), WTC(0xa1711f59), WTC(0x9f9a62f5), WTC(0x9dd18104),
+ WTC(0x9c17167e), WTC(0x9a6bbbe9), WTC(0x98d0061c), WTC(0x97449e23),
+ WTC(0x95ca1ad6), WTC(0x9460e7a1), WTC(0x93096222), WTC(0x91c3c9da),
+ WTC(0x90902633), WTC(0x8f6e3c5f), WTC(0x8e5d7788), WTC(0x8d5cb789),
+ WTC(0x8c6a42d5), WTC(0x8b833d6f), WTC(0x8aa3cc10), WTC(0x89c7789a),
+ WTC(0x88ef9802), WTC(0x883452c3), WTC(0x87c0bb9a), WTC(0x878c8326),
+ WTC(0x8757eb4c), WTC(0x87222119), WTC(0x86eb5f31), WTC(0x86b3802c),
+ WTC(0x867a73ee), WTC(0x86402cf8), WTC(0x8604a439), WTC(0x85c7cd22),
+ WTC(0x8589a40b), WTC(0x854a1d2f), WTC(0x850944c1), WTC(0x84c71670),
+ WTC(0x8483acc8), WTC(0x843f04b6), WTC(0x83f93cd9), WTC(0x83b2576c),
+ WTC(0x836a7812), WTC(0x8321a764), WTC(0x82d805e8), WTC(0x828da076),
+ WTC(0x824290c3), WTC(0x81f6e6a8), WTC(0x81aab23c), WTC(0x815e05f8),
+ WTC(0x8110e4d6), WTC(0x80c362df), WTC(0x8075781d), WTC(0x80273c0c),
+ WTC(0x0abcb7ed), WTC(0x0b81d183), WTC(0x0c5113e3), WTC(0x0d2867d5),
+ WTC(0x0e082fa5), WTC(0x0ef089ad), WTC(0x0fe1d9cd), WTC(0x10d9e5f4),
+ WTC(0x11d6a2a0), WTC(0x12d814b1), WTC(0x13d98f52), WTC(0x14d221e1),
+ WTC(0x15ba467a), WTC(0x168a9c18), WTC(0x173d1fef), WTC(0x17da3bff),
+ WTC(0x18912cac), WTC(0x196c2a5e), WTC(0x1a68dd2e), WTC(0x1b85250c),
+ WTC(0x1cbea9a1), WTC(0x1e147be7), WTC(0x1f8aa446), WTC(0x2122e73a),
+ WTC(0x22cf6de3), WTC(0x248867f3), WTC(0x265d7937), WTC(0x2847c91b),
+ WTC(0x2a39d98e), WTC(0x2c482abf), WTC(0x2e7ff439), WTC(0x30c31f46),
+ WTC(0x32f5245d), WTC(0x3535070e), WTC(0x37adae38), WTC(0x3a3f151a),
+ WTC(0x3caf861b), WTC(0x3effc08b), WTC(0x415a803b), WTC(0x43d45ca9),
+ WTC(0x46631c69), WTC(0x48ed9c7e), WTC(0x4b608807), WTC(0x4dbbead3),
+ WTC(0x500ca1df), WTC(0x525e3c5d), WTC(0x54b7c199), WTC(0x570df9a2),
+ WTC(0x5940f661), WTC(0x5b542f13), WTC(0x5d64a202), WTC(0x5f738e39),
+ WTC(0x61704027), WTC(0x6348ef5e), WTC(0x65109c5f), WTC(0x66d3e29d),
+ WTC(0x687eb29a), WTC(0x6a125643), WTC(0x6b960b3a), WTC(0x6d07b283),
+ WTC(0xaf5b8daa), WTC(0xb3d557ba), WTC(0xb829feb2), WTC(0xbc6199e7),
+ WTC(0xc07bfbc1), WTC(0xc477a1b6), WTC(0xc8532f30), WTC(0xcc0dd698),
+ WTC(0xcfa71f06), WTC(0xd31ec578), WTC(0xd674c5b9), WTC(0xd9a90516),
+ WTC(0xdcbbc2b6), WTC(0xdfacf934), WTC(0xe27d19ab), WTC(0xe52c3d89),
+ WTC(0xe7bb0f52), WTC(0xea29bdd0), WTC(0xec78bc4a), WTC(0xeea805e6),
+ WTC(0xf0b85a68), WTC(0xf2ab266e), WTC(0xf48234a7), WTC(0xf63cb733),
+ WTC(0xf7d70b3f), WTC(0xf952d4d3), WTC(0xfab4906d), WTC(0xfbfaa858),
+ WTC(0xfd272437), WTC(0xfe392bea), WTC(0xff2e26f1), WTC(0x000efac0),
+ WTC(0x00e36d26), WTC(0x019bd803), WTC(0x0229e357), WTC(0x02a16b25),
+ WTC(0x0319ee5e), WTC(0x038ccea0), WTC(0x03e56d3d), WTC(0x041dc072),
+ WTC(0x043f58cc), WTC(0x04571273), WTC(0x046ba761), WTC(0x0479caa5),
+ WTC(0x047a2279), WTC(0x04673950), WTC(0x04435263), WTC(0x041750da),
+ WTC(0x03e99926), WTC(0x03b4ba1f), WTC(0x03731e2b), WTC(0x0327b303),
+ WTC(0x02d8301b), WTC(0x0284fb11), WTC(0x022b464a), WTC(0x01cc1b40),
+ WTC(0x0169ab7d), WTC(0x01047d1e), WTC(0x009d04e0), WTC(0x003484b0),
+ WTC(0xd5a9348a), WTC(0xd3f05eca), WTC(0xd24339e7), WTC(0xd0a269b7),
+ WTC(0xcf0fe026), WTC(0xcd8aa14b), WTC(0xcc13963e), WTC(0xcaa19c5a),
+ WTC(0xc92cd701), WTC(0xc7b5cd7b), WTC(0xc62a4fe3), WTC(0xc46742be),
+ WTC(0xc24e128c), WTC(0xbfc0b758), WTC(0xbca661e3), WTC(0xb922924b),
+ WTC(0xb5f87ac2), WTC(0xb35308e7), WTC(0xb12cc90f), WTC(0xaf80522c),
+ WTC(0xae483b10), WTC(0xad7f1af9), WTC(0xad1f8874), WTC(0xad241a09),
+ WTC(0xad8766ea), WTC(0xae4405b1), WTC(0xaf548d72), WTC(0xb0b394ad),
+ WTC(0xb25bb297), WTC(0xb4476fa1), WTC(0xb6718d2c), WTC(0xb8d47781),
+ WTC(0xbb6ad37b), WTC(0xbe2f3831), WTC(0xc11c3c6c), WTC(0xc42c76b1),
+ WTC(0xc75a7e40), WTC(0xcaa0e9d1), WTC(0xcdfa502b), WTC(0xd1614803),
+ WTC(0xd4d06850), WTC(0xd84247d3), WTC(0xdbb17d6d), WTC(0xdf189fe3),
+ WTC(0xe272461e), WTC(0xe5b906e1), WTC(0xe8e7790e), WTC(0xebf83366),
+ WTC(0xeee5cccc), WTC(0xf1aadc0a), WTC(0xf441f7fa), WTC(0xf6a5b772),
+ WTC(0xf8d0b146), WTC(0xfabd7c3e), WTC(0xfc66af35), WTC(0xfdc6e101),
+ WTC(0xfed8a875), WTC(0xff969c63), WTC(0xfffb5390), WTC(0x00017ad8),
+};
+
+const FIXP_WTB LowDelaySynthesis512[1536] = {
+ /* part 0 */
+ WTC(0xdac984c0), WTC(0xdb100080), WTC(0xdb56cd00), WTC(0xdb9dec40),
+ WTC(0xdbe55fc0), WTC(0xdc2d2880), WTC(0xdc754780), WTC(0xdcbdbd80),
+ WTC(0xdd068a80), WTC(0xdd4fae80), WTC(0xdd992940), WTC(0xdde2f9c0),
+ WTC(0xde2d1fc0), WTC(0xde779a80), WTC(0xdec26a00), WTC(0xdf0d8e00),
+ WTC(0xdf590680), WTC(0xdfa4d540), WTC(0xdff0fc80), WTC(0xe03d7e20),
+ WTC(0xe08a5900), WTC(0xe0d78a20), WTC(0xe1250cc0), WTC(0xe172dcc0),
+ WTC(0xe1c0f7a0), WTC(0xe20f59a0), WTC(0xe25dfea0), WTC(0xe2ace400),
+ WTC(0xe2fc0be0), WTC(0xe34b7bc0), WTC(0xe39b3c80), WTC(0xe3eb5260),
+ WTC(0xe43bbac0), WTC(0xe48c7160), WTC(0xe4dd7140), WTC(0xe52eb600),
+ WTC(0xe5803c00), WTC(0xe5d1fda0), WTC(0xe623f360), WTC(0xe6761700),
+ WTC(0xe6c86400), WTC(0xe71ad500), WTC(0xe76d63e0), WTC(0xe7c00ba0),
+ WTC(0xe812c8e0), WTC(0xe86598e0), WTC(0xe8b878e0), WTC(0xe90b68a0),
+ WTC(0xe95e6c40), WTC(0xe9b18ae0), WTC(0xea04ce80), WTC(0xea583ba0),
+ WTC(0xeaabcda0), WTC(0xeaff7ee0), WTC(0xeb5348e0), WTC(0xeba722c0),
+ WTC(0xebfb0060), WTC(0xec4ed240), WTC(0xeca28540), WTC(0xecf60c20),
+ WTC(0xed496120), WTC(0xed9c7e80), WTC(0xedef5e40), WTC(0xee41fc00),
+ WTC(0xee945600), WTC(0xeee66ac0), WTC(0xef3839a0), WTC(0xef89c0e0),
+ WTC(0xefdafda0), WTC(0xf02bed60), WTC(0xf07c8e80), WTC(0xf0cce000),
+ WTC(0xf11ce220), WTC(0xf16c9620), WTC(0xf1bbfe30), WTC(0xf20b19e0),
+ WTC(0xf259e5a0), WTC(0xf2a85dc0), WTC(0xf2f67ed0), WTC(0xf34445b0),
+ WTC(0xf391aed0), WTC(0xf3deb590), WTC(0xf42b53e0), WTC(0xf4778140),
+ WTC(0xf4c33190), WTC(0xf50e5660), WTC(0xf558df30), WTC(0xf5a2be50),
+ WTC(0xf5ebea10), WTC(0xf6345780), WTC(0xf67bfab0), WTC(0xf6c2cee0),
+ WTC(0xf708d7b0), WTC(0xf74e19c0), WTC(0xf7929a70), WTC(0xf7d66630),
+ WTC(0xf8199268), WTC(0xf85c3860), WTC(0xf89e7480), WTC(0xf8e058c0),
+ WTC(0xf921ec08), WTC(0xf9633800), WTC(0xf9a44980), WTC(0xf9e53158),
+ WTC(0xfa260158), WTC(0xfa66ca18), WTC(0xfaa79ac0), WTC(0xfae87920),
+ WTC(0xfb295fa0), WTC(0xfb6a42b8), WTC(0xfbab1240), WTC(0xfbebd1c0),
+ WTC(0xfc2c9c24), WTC(0xfc6d8d90), WTC(0xfcaec240), WTC(0xfcf05684),
+ WTC(0xfd326a98), WTC(0xfd75254c), WTC(0xfdb8afd4), WTC(0xfdfccdfc),
+ WTC(0xfe40d694), WTC(0xfe84161c), WTC(0xfec5cf5a), WTC(0xff04e7fc),
+ WTC(0xff3fdfe3), WTC(0xff751ddf), WTC(0xffa2fb0f), WTC(0xffc87c42),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbffb6081), WTC(0xbff22f81), WTC(0xbfe8fc01), WTC(0xbfdfc781),
+ WTC(0xbfd69101), WTC(0xbfcd5a01), WTC(0xbfc42201), WTC(0xbfbae981),
+ WTC(0xbfb1b101), WTC(0xbfa87901), WTC(0xbf9f4181), WTC(0xbf960b01),
+ WTC(0xbf8cd481), WTC(0xbf839d81), WTC(0xbf7a6681), WTC(0xbf712f01),
+ WTC(0xbf67f801), WTC(0xbf5ec101), WTC(0xbf558b01), WTC(0xbf4c5681),
+ WTC(0xbf432281), WTC(0xbf39ee81), WTC(0xbf30bb01), WTC(0xbf278801),
+ WTC(0xbf1e5501), WTC(0xbf152381), WTC(0xbf0bf381), WTC(0xbf02c581),
+ WTC(0xbef99901), WTC(0xbef06d01), WTC(0xbee74281), WTC(0xbede1901),
+ WTC(0xbed4f081), WTC(0xbecbca81), WTC(0xbec2a781), WTC(0xbeb98681),
+ WTC(0xbeb06881), WTC(0xbea74c81), WTC(0xbe9e3281), WTC(0xbe951a81),
+ WTC(0xbe8c0501), WTC(0xbe82f301), WTC(0xbe79e481), WTC(0xbe70da01),
+ WTC(0xbe67d381), WTC(0xbe5ed081), WTC(0xbe55d001), WTC(0xbe4cd381),
+ WTC(0xbe43da81), WTC(0xbe3ae601), WTC(0xbe31f701), WTC(0xbe290d01),
+ WTC(0xbe202801), WTC(0xbe174781), WTC(0xbe0e6c01), WTC(0xbe059481),
+ WTC(0xbdfcc301), WTC(0xbdf3f701), WTC(0xbdeb3101), WTC(0xbde27201),
+ WTC(0xbdd9b981), WTC(0xbdd10681), WTC(0xbdc85981), WTC(0xbdbfb281),
+ WTC(0xbdb71201), WTC(0xbdae7881), WTC(0xbda5e601), WTC(0xbd9d5b81),
+ WTC(0xbd94d801), WTC(0xbd8c5c01), WTC(0xbd83e681), WTC(0xbd7b7781),
+ WTC(0xbd731081), WTC(0xbd6ab101), WTC(0xbd625981), WTC(0xbd5a0b01),
+ WTC(0xbd51c481), WTC(0xbd498601), WTC(0xbd414f01), WTC(0xbd391f81),
+ WTC(0xbd30f881), WTC(0xbd28d981), WTC(0xbd20c401), WTC(0xbd18b781),
+ WTC(0xbd10b381), WTC(0xbd08b781), WTC(0xbd00c381), WTC(0xbcf8d781),
+ WTC(0xbcf0f381), WTC(0xbce91801), WTC(0xbce14601), WTC(0xbcd97c81),
+ WTC(0xbcd1bb81), WTC(0xbcca0301), WTC(0xbcc25181), WTC(0xbcbaa801),
+ WTC(0xbcb30601), WTC(0xbcab6c01), WTC(0xbca3db01), WTC(0xbc9c5281),
+ WTC(0xbc94d201), WTC(0xbc8d5901), WTC(0xbc85e801), WTC(0xbc7e7e01),
+ WTC(0xbc771c01), WTC(0xbc6fc101), WTC(0xbc686e01), WTC(0xbc612301),
+ WTC(0xbc59df81), WTC(0xbc52a381), WTC(0xbc4b6e81), WTC(0xbc444081),
+ WTC(0xbc3d1801), WTC(0xbc35f501), WTC(0xbc2ed681), WTC(0xbc27bd81),
+ WTC(0xbc20ae01), WTC(0xbc19ab01), WTC(0xbc12b801), WTC(0xbc0bcf81),
+ WTC(0xbc04e381), WTC(0xbbfde481), WTC(0xbbf6c601), WTC(0xbbef9b81),
+ WTC(0xbbe89901), WTC(0xbbe1f401), WTC(0xbbdbe201), WTC(0xbbd68c81),
+ WTC(0xbbd21281), WTC(0xbbce9181), WTC(0xbbcc2681), WTC(0xbbcaca01),
+ WTC(0xbbca5081), WTC(0xbbca8d01), WTC(0xbbcb5301), WTC(0xbbcc8201),
+ WTC(0xbbce0601), WTC(0xbbcfca81), WTC(0xbbd1bd81), WTC(0xbbd3e101),
+ WTC(0xbbd64d01), WTC(0xbbd91b81), WTC(0xbbdc6481), WTC(0xbbe03801),
+ WTC(0xbbe49d01), WTC(0xbbe99981), WTC(0xbbef3301), WTC(0xbbf56181),
+ WTC(0xbbfc0f81), WTC(0xbc032601), WTC(0xbc0a8f01), WTC(0xbc123b81),
+ WTC(0xbc1a2401), WTC(0xbc224181), WTC(0xbc2a8c81), WTC(0xbc330781),
+ WTC(0xbc3bbc01), WTC(0xbc44b481), WTC(0xbc4dfb81), WTC(0xbc57a301),
+ WTC(0xbc61c401), WTC(0xbc6c7781), WTC(0xbc77d601), WTC(0xbc83f201),
+ WTC(0xbc90d481), WTC(0xbc9e8801), WTC(0xbcad1501), WTC(0xbcbc7e01),
+ WTC(0xbcccbd01), WTC(0xbcddcc81), WTC(0xbcefa601), WTC(0xbd023f01),
+ WTC(0xbd158801), WTC(0xbd297181), WTC(0xbd3deb81), WTC(0xbd52eb01),
+ WTC(0xbd686681), WTC(0xbd7e5581), WTC(0xbd94b001), WTC(0xbdab7181),
+ WTC(0xbdc29a81), WTC(0xbdda2a01), WTC(0xbdf22181), WTC(0xbe0a8581),
+ WTC(0xbe236001), WTC(0xbe3cbc01), WTC(0xbe56a381), WTC(0xbe712001),
+ WTC(0xbe8c3781), WTC(0xbea7f301), WTC(0xbec45881), WTC(0xbee17201),
+ WTC(0xbeff4801), WTC(0xbf1de601), WTC(0xbf3d5501), WTC(0xbf5d9a81),
+ WTC(0xbf7eb581), WTC(0xbfa0a581), WTC(0xbfc36a01), WTC(0xbfe6ed01),
+ WTC(0xc00b04c0), WTC(0xc02f86c0), WTC(0xc0544940), WTC(0xc0792ec0),
+ WTC(0xc09e2640), WTC(0xc0c31f00), WTC(0xc0e80a00), WTC(0xc10cf480),
+ WTC(0xc1320940), WTC(0xc15773c0), WTC(0xc17d5f00), WTC(0xc1a3e340),
+ WTC(0xc1cb05c0), WTC(0xc1f2cbc0), WTC(0xc21b3940), WTC(0xc2444b00),
+ WTC(0xc26df5c0), WTC(0xc2982d80), WTC(0xc2c2e640), WTC(0xc2ee0a00),
+ WTC(0xc3197940), WTC(0xc34513c0), WTC(0xc370b9c0), WTC(0xc39c4f00),
+ WTC(0xc3c7bc00), WTC(0xc3f2e940), WTC(0xc41dc140), WTC(0xc44856c0),
+ WTC(0xc472e640), WTC(0xc49dad80), WTC(0xc4c8e880), WTC(0xc4f4acc0),
+ WTC(0xc520e840), WTC(0xc54d8780), WTC(0xc57a76c0), WTC(0xc5a79640),
+ WTC(0xc5d4bac0), WTC(0xc601b880), WTC(0xc62e6580), WTC(0xc65ab600),
+ WTC(0xc686bd40), WTC(0xc6b28fc0), WTC(0xc6de41c0), WTC(0xc709de40),
+ WTC(0xc7356640), WTC(0xc760da80), WTC(0xc78c3c40), WTC(0xc7b78640),
+ WTC(0xc7e2afc0), WTC(0xc80dae80), WTC(0xc83878c0), WTC(0xc86304c0),
+ WTC(0xc88d4900), WTC(0xc8b73b80), WTC(0xc8e0d280), WTC(0xc90a0440),
+ /* part 1 */
+ WTC(0xb5212e81), WTC(0xb4959501), WTC(0xb40ab501), WTC(0xb3808d81),
+ WTC(0xb2f71f01), WTC(0xb26e6881), WTC(0xb1e66a01), WTC(0xb15f2381),
+ WTC(0xb0d89401), WTC(0xb052bc01), WTC(0xafcd9a81), WTC(0xaf492f01),
+ WTC(0xaec57801), WTC(0xae427481), WTC(0xadc02281), WTC(0xad3e8101),
+ WTC(0xacbd9081), WTC(0xac3d5001), WTC(0xabbdc001), WTC(0xab3edf01),
+ WTC(0xaac0ad01), WTC(0xaa432981), WTC(0xa9c65401), WTC(0xa94a2c01),
+ WTC(0xa8ceb201), WTC(0xa853e501), WTC(0xa7d9c681), WTC(0xa7605601),
+ WTC(0xa6e79401), WTC(0xa66f8201), WTC(0xa5f81f81), WTC(0xa5816e81),
+ WTC(0xa50b6e81), WTC(0xa4962181), WTC(0xa4218801), WTC(0xa3ada281),
+ WTC(0xa33a7201), WTC(0xa2c7f801), WTC(0xa2563501), WTC(0xa1e52a81),
+ WTC(0xa174da81), WTC(0xa1054701), WTC(0xa0967201), WTC(0xa0285d81),
+ WTC(0x9fbb0981), WTC(0x9f4e7801), WTC(0x9ee2a901), WTC(0x9e779f81),
+ WTC(0x9e0d5e01), WTC(0x9da3e601), WTC(0x9d3b3b81), WTC(0x9cd35f81),
+ WTC(0x9c6c5481), WTC(0x9c061b81), WTC(0x9ba0b701), WTC(0x9b3c2801),
+ WTC(0x9ad87081), WTC(0x9a759301), WTC(0x9a139101), WTC(0x99b26c81),
+ WTC(0x99522801), WTC(0x98f2c601), WTC(0x98944901), WTC(0x9836b201),
+ WTC(0x97da0481), WTC(0x977e4181), WTC(0x97236b01), WTC(0x96c98381),
+ WTC(0x96708b81), WTC(0x96188501), WTC(0x95c17081), WTC(0x956b4f81),
+ WTC(0x95162381), WTC(0x94c1ee01), WTC(0x946eaf81), WTC(0x941c6901),
+ WTC(0x93cb1c81), WTC(0x937acb01), WTC(0x932b7501), WTC(0x92dd1b01),
+ WTC(0x928fbe01), WTC(0x92435d01), WTC(0x91f7f981), WTC(0x91ad9281),
+ WTC(0x91642781), WTC(0x911bb981), WTC(0x90d44781), WTC(0x908dd101),
+ WTC(0x90485401), WTC(0x9003ce81), WTC(0x8fc03f01), WTC(0x8f7da401),
+ WTC(0x8f3bfb01), WTC(0x8efb4181), WTC(0x8ebb7581), WTC(0x8e7c9301),
+ WTC(0x8e3e9481), WTC(0x8e017581), WTC(0x8dc53001), WTC(0x8d89be81),
+ WTC(0x8d4f1b01), WTC(0x8d154081), WTC(0x8cdc2901), WTC(0x8ca3cb01),
+ WTC(0x8c6c1b01), WTC(0x8c350d01), WTC(0x8bfe9401), WTC(0x8bc8a401),
+ WTC(0x8b933001), WTC(0x8b5e2c81), WTC(0x8b298b81), WTC(0x8af53e81),
+ WTC(0x8ac13381), WTC(0x8a8d5801), WTC(0x8a599a81), WTC(0x8a25f301),
+ WTC(0x89f26101), WTC(0x89bee581), WTC(0x898b8301), WTC(0x89586901),
+ WTC(0x8925f101), WTC(0x88f47901), WTC(0x88c45e81), WTC(0x88962981),
+ WTC(0x886a8a81), WTC(0x88423301), WTC(0x881dd301), WTC(0x87fdd781),
+ WTC(0x87d0ca81), WTC(0x87c76201), WTC(0x87bcab81), WTC(0x87b0ef01),
+ WTC(0x87a48b01), WTC(0x8797dd81), WTC(0x878b4301), WTC(0x877ede01),
+ WTC(0x87729701), WTC(0x87665481), WTC(0x8759fd01), WTC(0x874d8681),
+ WTC(0x8740f681), WTC(0x87345381), WTC(0x8727a381), WTC(0x871ae981),
+ WTC(0x870e2301), WTC(0x87014f81), WTC(0x86f46d81), WTC(0x86e77b81),
+ WTC(0x86da7901), WTC(0x86cd6681), WTC(0x86c04381), WTC(0x86b30f01),
+ WTC(0x86a5ca81), WTC(0x86987581), WTC(0x868b1001), WTC(0x867d9a81),
+ WTC(0x86701381), WTC(0x86627b01), WTC(0x8654d001), WTC(0x86471281),
+ WTC(0x86394301), WTC(0x862b6201), WTC(0x861d7081), WTC(0x860f6e01),
+ WTC(0x86015981), WTC(0x85f33281), WTC(0x85e4f801), WTC(0x85d6a981),
+ WTC(0x85c84801), WTC(0x85b9d481), WTC(0x85ab4f01), WTC(0x859cb781),
+ WTC(0x858e0e01), WTC(0x857f5101), WTC(0x85707f81), WTC(0x85619a01),
+ WTC(0x8552a181), WTC(0x85439601), WTC(0x85347901), WTC(0x85254a81),
+ WTC(0x85160981), WTC(0x8506b581), WTC(0x84f74e01), WTC(0x84e7d381),
+ WTC(0x84d84601), WTC(0x84c8a701), WTC(0x84b8f801), WTC(0x84a93801),
+ WTC(0x84996701), WTC(0x84898481), WTC(0x84798f81), WTC(0x84698881),
+ WTC(0x84597081), WTC(0x84494881), WTC(0x84391081), WTC(0x8428ca01),
+ WTC(0x84187401), WTC(0x84080d81), WTC(0x83f79681), WTC(0x83e70f01),
+ WTC(0x83d67881), WTC(0x83c5d381), WTC(0x83b52101), WTC(0x83a46181),
+ WTC(0x83939501), WTC(0x8382ba01), WTC(0x8371d081), WTC(0x8360d901),
+ WTC(0x834fd481), WTC(0x833ec381), WTC(0x832da781), WTC(0x831c8101),
+ WTC(0x830b4f81), WTC(0x82fa1181), WTC(0x82e8c801), WTC(0x82d77201),
+ WTC(0x82c61101), WTC(0x82b4a601), WTC(0x82a33281), WTC(0x8291b601),
+ WTC(0x82803101), WTC(0x826ea201), WTC(0x825d0901), WTC(0x824b6601),
+ WTC(0x8239b981), WTC(0x82280581), WTC(0x82164a81), WTC(0x82048881),
+ WTC(0x81f2bf81), WTC(0x81e0ee81), WTC(0x81cf1581), WTC(0x81bd3401),
+ WTC(0x81ab4b01), WTC(0x81995c01), WTC(0x81876781), WTC(0x81756d81),
+ WTC(0x81636d81), WTC(0x81516701), WTC(0x813f5981), WTC(0x812d4481),
+ WTC(0x811b2981), WTC(0x81090981), WTC(0x80f6e481), WTC(0x80e4bb81),
+ WTC(0x80d28d81), WTC(0x80c05a01), WTC(0x80ae1f81), WTC(0x809bdf01),
+ WTC(0x80899881), WTC(0x80774c81), WTC(0x8064fc81), WTC(0x8052a881),
+ WTC(0x80405101), WTC(0x802df701), WTC(0x801b9b01), WTC(0x80093e01),
+ WTC(0x0a74b120), WTC(0x0aa08a90), WTC(0x0acd2b80), WTC(0x0afa8860),
+ WTC(0x0b289590), WTC(0x0b574790), WTC(0x0b8692d0), WTC(0x0bb66bb0),
+ WTC(0x0be6c6b0), WTC(0x0c179830), WTC(0x0c48d500), WTC(0x0c7a7ad0),
+ WTC(0x0cac9000), WTC(0x0cdf1b60), WTC(0x0d122390), WTC(0x0d45a8f0),
+ WTC(0x0d79a5e0), WTC(0x0dae1480), WTC(0x0de2ef30), WTC(0x0e183800),
+ WTC(0x0e4df8c0), WTC(0x0e843b90), WTC(0x0ebb0a20), WTC(0x0ef26430),
+ WTC(0x0f2a3fc0), WTC(0x0f629280), WTC(0x0f9b5210), WTC(0x0fd47690),
+ WTC(0x100dfa80), WTC(0x1047d8a0), WTC(0x10820b40), WTC(0x10bc8b80),
+ WTC(0x10f75080), WTC(0x11325100), WTC(0x116d84e0), WTC(0x11a8ece0),
+ WTC(0x11e49420), WTC(0x122085a0), WTC(0x125ccbc0), WTC(0x12995a40),
+ WTC(0x12d60e80), WTC(0x1312c4c0), WTC(0x134f59e0), WTC(0x138bae60),
+ WTC(0x13c7a740), WTC(0x140329e0), WTC(0x143e1b60), WTC(0x147862a0),
+ WTC(0x14b1e840), WTC(0x14ea94c0), WTC(0x152250a0), WTC(0x15590380),
+ WTC(0x158e93e0), WTC(0x15c2e820), WTC(0x15f5e6e0), WTC(0x162779a0),
+ WTC(0x16578ca0), WTC(0x16860ca0), WTC(0x16b2e640), WTC(0x16de0b00),
+ WTC(0x17077140), WTC(0x172f0fa0), WTC(0x1754e200), WTC(0x17796080),
+ WTC(0x179d7f20), WTC(0x17c23760), WTC(0x17e87da0), WTC(0x1810cc80),
+ WTC(0x183b25a0), WTC(0x18678520), WTC(0x1895e700), WTC(0x18c64540),
+ WTC(0x18f89780), WTC(0x192cd560), WTC(0x1962f680), WTC(0x199af2a0),
+ WTC(0x19d4c1e0), WTC(0x1a105ca0), WTC(0x1a4dbae0), WTC(0x1a8cd660),
+ WTC(0x1acdaa60), WTC(0x1b103260), WTC(0x1b546940), WTC(0x1b9a4600),
+ WTC(0x1be1bb80), WTC(0x1c2abc60), WTC(0x1c753b80), WTC(0x1cc13860),
+ WTC(0x1d0ebe20), WTC(0x1d5dd8c0), WTC(0x1dae9480), WTC(0x1e010060),
+ WTC(0x1e552f40), WTC(0x1eab33e0), WTC(0x1f032060), WTC(0x1f5cfce0),
+ WTC(0x1fb8c660), WTC(0x201679c0), WTC(0x207611c0), WTC(0x20d75f00),
+ WTC(0x213a0640), WTC(0x219dab80), WTC(0x2201f480), WTC(0x2266ba80),
+ WTC(0x22cc0ac0), WTC(0x2331f4c0), WTC(0x23988940), WTC(0x23ffff40),
+ WTC(0x2468b340), WTC(0x24d30300), WTC(0x253f4900), WTC(0x25ad8980),
+ WTC(0x261d72c0), WTC(0x268eaec0), WTC(0x2700e880), WTC(0x2773db40),
+ WTC(0x27e751c0), WTC(0x285b1780), WTC(0x28cefbc0), WTC(0x29431f80),
+ WTC(0x29b7f680), WTC(0x2a2df780), WTC(0x2aa59880), WTC(0x2b1f3280),
+ WTC(0x2b9b0140), WTC(0x2c194000), WTC(0x2c9a2540), WTC(0x2d1d8dc0),
+ WTC(0x2da2fc40), WTC(0x2e29ee80), WTC(0x2eb1e340), WTC(0x2f3a4e40),
+ WTC(0x2fc29980), WTC(0x304a2ec0), WTC(0x30d07cc0), WTC(0x315566c0),
+ WTC(0x31d94480), WTC(0x325c72c0), WTC(0x32df51c0), WTC(0x33628c80),
+ WTC(0x33e71a00), WTC(0x346df400), WTC(0x34f80dc0), WTC(0x3585c640),
+ WTC(0x3616e700), WTC(0x36ab3380), WTC(0x37426ac0), WTC(0x37dbe840),
+ WTC(0x3876a340), WTC(0x39118f40), WTC(0x39aba2c0), WTC(0x3a4422c0),
+ WTC(0x3adaa200), WTC(0x3b6eb6c0), WTC(0x3bfffd80), WTC(0x3c8e9380),
+ WTC(0x3d1b1780), WTC(0x3da62e00), WTC(0x3e307b00), WTC(0x3eba97c0),
+ WTC(0x3f451280), WTC(0x3fd07940), WTC(0x405d577f), WTC(0x40ebf57f),
+ WTC(0x417c59ff), WTC(0x420e897f), WTC(0x42a2857f), WTC(0x4338307f),
+ WTC(0x43cf4d7f), WTC(0x44679cff), WTC(0x4500dfff), WTC(0x459ac2ff),
+ WTC(0x4634e2ff), WTC(0x46ced9ff), WTC(0x4768437f), WTC(0x4800d27f),
+ WTC(0x489850ff), WTC(0x492e88ff), WTC(0x49c346ff), WTC(0x4a5678ff),
+ WTC(0x4ae82f7f), WTC(0x4b787c7f), WTC(0x4c07717f), WTC(0x4c95337f),
+ WTC(0x4d21f77f), WTC(0x4dadf3ff), WTC(0x4e395eff), WTC(0x4ec4657f),
+ WTC(0x4f4f297f), WTC(0x4fd9cd7f), WTC(0x5064737f), WTC(0x50ef3cff),
+ WTC(0x517a46ff), WTC(0x5205b0ff), WTC(0x529197ff), WTC(0x531e04ff),
+ WTC(0x53aaeb7f), WTC(0x54383eff), WTC(0x54c5ef7f), WTC(0x5553a8ff),
+ WTC(0x55e0d57f), WTC(0x566cda7f), WTC(0x56f720ff), WTC(0x577f4aff),
+ WTC(0x580534ff), WTC(0x5888bd7f), WTC(0x5909c6ff), WTC(0x598890ff),
+ WTC(0x5a05b7ff), WTC(0x5a81db7f), WTC(0x5afd99ff), WTC(0x5b794a7f),
+ WTC(0x5bf5007f), WTC(0x5c70cbff), WTC(0x5cecbb7f), WTC(0x5d68c47f),
+ WTC(0x5de4c3ff), WTC(0x5e6094ff), WTC(0x5edc127f), WTC(0x5f56fdff),
+ WTC(0x5fd1017f), WTC(0x6049c67f), WTC(0x60c0f67f), WTC(0x613650ff),
+ WTC(0x61a9a9ff), WTC(0x621ad77f), WTC(0x6289b37f), WTC(0x62f67fff),
+ WTC(0x6361e87f), WTC(0x63cc9bff), WTC(0x6437457f), WTC(0x64a2247f),
+ WTC(0x650d0c7f), WTC(0x6577cc7f), WTC(0x65e2327f), WTC(0x664bf57f),
+ WTC(0x66b4b5ff), WTC(0x671c137f), WTC(0x6781afff), WTC(0x67e579ff),
+ WTC(0x6847abff), WTC(0x68a882ff), WTC(0x69083bff), WTC(0x6966fbff),
+ WTC(0x69c4cfff), WTC(0x6a21c57f), WTC(0x6a7de87f), WTC(0x6ad9377f),
+ WTC(0x6b33a5ff), WTC(0x6b8d257f), WTC(0x6be5a8ff), WTC(0x6c3d20ff),
+ WTC(0x6c9380ff), WTC(0x6ce8ba7f), WTC(0x6d3cbfff), WTC(0x6d8f827f),
+ /* part 2 */
+ WTC(0xad98b481), WTC(0xaead9d01), WTC(0xafbfc381), WTC(0xb0cf4d01),
+ WTC(0xb1dc5f81), WTC(0xb2e72081), WTC(0xb3efb501), WTC(0xb4f64381),
+ WTC(0xb5faf101), WTC(0xb6fde401), WTC(0xb7ff4001), WTC(0xb8ff1601),
+ WTC(0xb9fd6181), WTC(0xbafa1d01), WTC(0xbbf54401), WTC(0xbceed101),
+ WTC(0xbde6c081), WTC(0xbedd0e81), WTC(0xbfd1b701), WTC(0xc0c4b440),
+ WTC(0xc1b5ffc0), WTC(0xc2a59340), WTC(0xc3936780), WTC(0xc47f78c0),
+ WTC(0xc569c600), WTC(0xc6524d40), WTC(0xc7390dc0), WTC(0xc81e04c0),
+ WTC(0xc9012e00), WTC(0xc9e28540), WTC(0xcac20700), WTC(0xcb9fb1c0),
+ WTC(0xcc7b8640), WTC(0xcd558600), WTC(0xce2db200), WTC(0xcf0409c0),
+ WTC(0xcfd88a40), WTC(0xd0ab3080), WTC(0xd17bfa00), WTC(0xd24ae640),
+ WTC(0xd317f7c0), WTC(0xd3e33080), WTC(0xd4ac9340), WTC(0xd5741f40),
+ WTC(0xd639d2c0), WTC(0xd6fdab00), WTC(0xd7bfa5c0), WTC(0xd87fc300),
+ WTC(0xd93e0600), WTC(0xd9fa7180), WTC(0xdab50900), WTC(0xdb6dccc0),
+ WTC(0xdc24ba80), WTC(0xdcd9d000), WTC(0xdd8d0b80), WTC(0xde3e6dc0),
+ WTC(0xdeedf9c0), WTC(0xdf9bb340), WTC(0xe0479e20), WTC(0xe0f1bac0),
+ WTC(0xe19a07e0), WTC(0xe2408380), WTC(0xe2e52c00), WTC(0xe38802e0),
+ WTC(0xe4290c00), WTC(0xe4c84c20), WTC(0xe565c760), WTC(0xe6017f20),
+ WTC(0xe69b7240), WTC(0xe7339f60), WTC(0xe7ca0500), WTC(0xe85ea480),
+ WTC(0xe8f18180), WTC(0xe9829fc0), WTC(0xea1202e0), WTC(0xea9fab80),
+ WTC(0xeb2b9700), WTC(0xebb5c2a0), WTC(0xec3e2bc0), WTC(0xecc4d300),
+ WTC(0xed49bc80), WTC(0xedccec60), WTC(0xee4e66a0), WTC(0xeece2d80),
+ WTC(0xef4c41e0), WTC(0xefc8a480), WTC(0xf0435610), WTC(0xf0bc5c60),
+ WTC(0xf133c230), WTC(0xf1a99270), WTC(0xf21dd7b0), WTC(0xf29097e0),
+ WTC(0xf301d3d0), WTC(0xf3718c20), WTC(0xf3dfc180), WTC(0xf44c7100),
+ WTC(0xf4b79480), WTC(0xf52125b0), WTC(0xf5891df0), WTC(0xf5ef6fe0),
+ WTC(0xf6540730), WTC(0xf6b6cf50), WTC(0xf717b490), WTC(0xf776b9a0),
+ WTC(0xf7d3f720), WTC(0xf82f86e8), WTC(0xf8898260), WTC(0xf8e1fc50),
+ WTC(0xf93900f0), WTC(0xf98e9c28), WTC(0xf9e2d940), WTC(0xfa35b4a0),
+ WTC(0xfa871bd8), WTC(0xfad6fbd0), WTC(0xfb254250), WTC(0xfb71f0c0),
+ WTC(0xfbbd1c28), WTC(0xfc06da60), WTC(0xfc4f40a4), WTC(0xfc965500),
+ WTC(0xfcdc0e5c), WTC(0xfd2062f4), WTC(0xfd6348d0), WTC(0xfda4b1b8),
+ WTC(0xfde48b2c), WTC(0xfe22c280), WTC(0xfe5f462a), WTC(0xfe9a1f2e),
+ WTC(0xfed3711c), WTC(0xff0b60ac), WTC(0xff4212dd), WTC(0xff77b344),
+ WTC(0xffac7407), WTC(0xffe08796), WTC(0x00141e37), WTC(0x00473665),
+ WTC(0x00799cd0), WTC(0x00ab1bff), WTC(0x00db7d8b), WTC(0x010a75ea),
+ WTC(0x0137a46e), WTC(0x0162a77a), WTC(0x018b20ac), WTC(0x01b0fb7a),
+ WTC(0x01d46d3c), WTC(0x01f5ae7c), WTC(0x0214f91c), WTC(0x0232a5cc),
+ WTC(0x024f2c04), WTC(0x026b048c), WTC(0x0286a628), WTC(0x02a25808),
+ WTC(0x02be31c0), WTC(0x02da48e0), WTC(0x02f6b09c), WTC(0x031345dc),
+ WTC(0x032faf50), WTC(0x034b9148), WTC(0x036690e8), WTC(0x0380658c),
+ WTC(0x0398d8e4), WTC(0x03afb568), WTC(0x03c4c6e0), WTC(0x03d7f770),
+ WTC(0x03e94f9c), WTC(0x03f8d938), WTC(0x04069ee8), WTC(0x0412bef8),
+ WTC(0x041d6b30), WTC(0x0426d638), WTC(0x042f3288), WTC(0x0436ad98),
+ WTC(0x043d6fd0), WTC(0x0443a170), WTC(0x04496a40), WTC(0x044ee728),
+ WTC(0x04542a40), WTC(0x04594520), WTC(0x045e4890), WTC(0x04633210),
+ WTC(0x0467ebe8), WTC(0x046c5f80), WTC(0x04707630), WTC(0x047417f0),
+ WTC(0x04772b58), WTC(0x047996e8), WTC(0x047b4140), WTC(0x047c12a0),
+ WTC(0x047bf520), WTC(0x047ad2e0), WTC(0x04789690), WTC(0x047539c8),
+ WTC(0x0470c4b8), WTC(0x046b4058), WTC(0x0464b600), WTC(0x045d3a08),
+ WTC(0x0454ebc8), WTC(0x044beb00), WTC(0x04425798), WTC(0x043853b0),
+ WTC(0x042e0398), WTC(0x04238bd8), WTC(0x04190f98), WTC(0x040e9670),
+ WTC(0x04040c18), WTC(0x03f95b30), WTC(0x03ee6e20), WTC(0x03e32b64),
+ WTC(0x03d77598), WTC(0x03cb2f24), WTC(0x03be3b18), WTC(0x03b08b18),
+ WTC(0x03a21f64), WTC(0x0392f8d4), WTC(0x038318e0), WTC(0x03728e94),
+ WTC(0x03617694), WTC(0x034fee18), WTC(0x033e11f4), WTC(0x032bf530),
+ WTC(0x0319a114), WTC(0x03071e80), WTC(0x02f475f4), WTC(0x02e1a7c0),
+ WTC(0x02ceac04), WTC(0x02bb7a84), WTC(0x02a80af0), WTC(0x029452b0),
+ WTC(0x028044e0), WTC(0x026bd488), WTC(0x0256f558), WTC(0x0241a940),
+ WTC(0x022c0084), WTC(0x02160c08), WTC(0x01ffdc5a), WTC(0x01e97ad2),
+ WTC(0x01d2e982), WTC(0x01bc2a2a), WTC(0x01a53e8c), WTC(0x018e2860),
+ WTC(0x0176e94c), WTC(0x015f82fa), WTC(0x0147f70e), WTC(0x013046c2),
+ WTC(0x011872e8), WTC(0x01007c4a), WTC(0x00e863cf), WTC(0x00d02c81),
+ WTC(0x00b7db94), WTC(0x009f7651), WTC(0x00870204), WTC(0x006e83f8),
+ WTC(0x00560176), WTC(0x003d7fcb), WTC(0x0025043f), WTC(0x000c941f),
+ WTC(0xd65574c0), WTC(0xd5ebc100), WTC(0xd582d080), WTC(0xd51a9cc0),
+ WTC(0xd4b31f80), WTC(0xd44c5280), WTC(0xd3e62f80), WTC(0xd380b040),
+ WTC(0xd31bce40), WTC(0xd2b78380), WTC(0xd253ca40), WTC(0xd1f0acc0),
+ WTC(0xd18e4580), WTC(0xd12caf40), WTC(0xd0cc0400), WTC(0xd06c40c0),
+ WTC(0xd00d4740), WTC(0xcfaef6c0), WTC(0xcf513140), WTC(0xcef3fa80),
+ WTC(0xce977a40), WTC(0xce3bd980), WTC(0xcde13f40), WTC(0xcd87a880),
+ WTC(0xcd2ee800), WTC(0xccd6cf00), WTC(0xcc7f2f40), WTC(0xcc27e880),
+ WTC(0xcbd0ea00), WTC(0xcb7a2380), WTC(0xcb238380), WTC(0xcaccee80),
+ WTC(0xca763ec0), WTC(0xca1f4d00), WTC(0xc9c7f480), WTC(0xc9703b40),
+ WTC(0xc9185200), WTC(0xc8c06b00), WTC(0xc868b4c0), WTC(0xc81100c0),
+ WTC(0xc7b8c280), WTC(0xc75f6a40), WTC(0xc7046900), WTC(0xc6a74340),
+ WTC(0xc6479300), WTC(0xc5e4f200), WTC(0xc57efac0), WTC(0xc5154880),
+ WTC(0xc4a77780), WTC(0xc4352440), WTC(0xc3bdeac0), WTC(0xc3416740),
+ WTC(0xc2bf33c0), WTC(0xc236eb40), WTC(0xc1a82900), WTC(0xc11290c0),
+ WTC(0xc075cf00), WTC(0xbfd19081), WTC(0xbf258401), WTC(0xbe716d81),
+ WTC(0xbdb52b81), WTC(0xbcf09a81), WTC(0xbc23af81), WTC(0xbb505c01),
+ WTC(0xba7a9081), WTC(0xb9a65281), WTC(0xb8d79301), WTC(0xb8104c01),
+ WTC(0xb7508181), WTC(0xb6982201), WTC(0xb5e71b01), WTC(0xb53d5b01),
+ WTC(0xb49ad081), WTC(0xb3ff6901), WTC(0xb36b1301), WTC(0xb2ddbd01),
+ WTC(0xb2575481), WTC(0xb1d7c801), WTC(0xb15f0601), WTC(0xb0ecfc01),
+ WTC(0xb0819881), WTC(0xb01cca01), WTC(0xafbe7e01), WTC(0xaf66a301),
+ WTC(0xaf152701), WTC(0xaec9f881), WTC(0xae850601), WTC(0xae463c81),
+ WTC(0xae0d8b01), WTC(0xaddae001), WTC(0xadae2881), WTC(0xad875381),
+ WTC(0xad664f81), WTC(0xad4b0981), WTC(0xad357081), WTC(0xad257301),
+ WTC(0xad1afe01), WTC(0xad160081), WTC(0xad166901), WTC(0xad1c2481),
+ WTC(0xad272201), WTC(0xad374f81), WTC(0xad4c9b01), WTC(0xad66f381),
+ WTC(0xad864601), WTC(0xadaa8101), WTC(0xadd39301), WTC(0xae016a01),
+ WTC(0xae33f481), WTC(0xae6b2001), WTC(0xaea6db01), WTC(0xaee71381),
+ WTC(0xaf2bb801), WTC(0xaf74b681), WTC(0xafc1fd01), WTC(0xb0137a01),
+ WTC(0xb0691b81), WTC(0xb0c2cf81), WTC(0xb1208481), WTC(0xb1822881),
+ WTC(0xb1e7a981), WTC(0xb250f601), WTC(0xb2bdfc01), WTC(0xb32eaa01),
+ WTC(0xb3a2ed01), WTC(0xb41ab481), WTC(0xb495ee01), WTC(0xb5148801),
+ WTC(0xb5967081), WTC(0xb61b9581), WTC(0xb6a3e581), WTC(0xb72f4e01),
+ WTC(0xb7bdbe01), WTC(0xb84f2381), WTC(0xb8e36c81), WTC(0xb97a8701),
+ WTC(0xba146101), WTC(0xbab0e981), WTC(0xbb500d81), WTC(0xbbf1bc81),
+ WTC(0xbc95e381), WTC(0xbd3c7181), WTC(0xbde55481), WTC(0xbe907a01),
+ WTC(0xbf3dd101), WTC(0xbfed4701), WTC(0xc09ecac0), WTC(0xc1524a00),
+ WTC(0xc207b300), WTC(0xc2bef440), WTC(0xc377fb80), WTC(0xc432b700),
+ WTC(0xc4ef1500), WTC(0xc5ad03c0), WTC(0xc66c7140), WTC(0xc72d4bc0),
+ WTC(0xc7ef8180), WTC(0xc8b30080), WTC(0xc977b700), WTC(0xca3d9340),
+ WTC(0xcb048340), WTC(0xcbcc7540), WTC(0xcc955740), WTC(0xcd5f17c0),
+ WTC(0xce29a480), WTC(0xcef4ec00), WTC(0xcfc0dc80), WTC(0xd08d63c0),
+ WTC(0xd15a7040), WTC(0xd227f000), WTC(0xd2f5d140), WTC(0xd3c40240),
+ WTC(0xd4927100), WTC(0xd5610b80), WTC(0xd62fc080), WTC(0xd6fe7dc0),
+ WTC(0xd7cd3140), WTC(0xd89bc980), WTC(0xd96a34c0), WTC(0xda3860c0),
+ WTC(0xdb063c00), WTC(0xdbd3b480), WTC(0xdca0b880), WTC(0xdd6d3640),
+ WTC(0xde391bc0), WTC(0xdf045740), WTC(0xdfced6c0), WTC(0xe09888c0),
+ WTC(0xe1615b20), WTC(0xe2293c20), WTC(0xe2f01a00), WTC(0xe3b5e2c0),
+ WTC(0xe47a84c0), WTC(0xe53dee00), WTC(0xe6000cc0), WTC(0xe6c0cf20),
+ WTC(0xe7802360), WTC(0xe83df7a0), WTC(0xe8fa39e0), WTC(0xe9b4d880),
+ WTC(0xea6dc1a0), WTC(0xeb24e360), WTC(0xebda2be0), WTC(0xec8d8960),
+ WTC(0xed3eea20), WTC(0xedee3c00), WTC(0xee9b6d80), WTC(0xef466ca0),
+ WTC(0xefef2780), WTC(0xf0958c50), WTC(0xf1398950), WTC(0xf1db0ca0),
+ WTC(0xf27a0470), WTC(0xf3165ed0), WTC(0xf3b00a10), WTC(0xf446f440),
+ WTC(0xf4db0b90), WTC(0xf56c3e30), WTC(0xf5fa7a50), WTC(0xf685ae10),
+ WTC(0xf70dc7a0), WTC(0xf792b520), WTC(0xf81464c8), WTC(0xf892c4c0),
+ WTC(0xf90dc330), WTC(0xf9854e40), WTC(0xf9f95418), WTC(0xfa69c2f0),
+ WTC(0xfad688e8), WTC(0xfb3f9428), WTC(0xfba4d2e8), WTC(0xfc063344),
+ WTC(0xfc63a370), WTC(0xfcbd1194), WTC(0xfd126bdc), WTC(0xfd63a06c),
+ WTC(0xfdb09d78), WTC(0xfdf95124), WTC(0xfe3da99e), WTC(0xfe7d950e),
+ WTC(0xfeb901a2), WTC(0xfeefdd80), WTC(0xff2216d7), WTC(0xff4f9bcf),
+ WTC(0xff785a93), WTC(0xff9c414e), WTC(0xffbb3e2b), WTC(0xffd53f54),
+ WTC(0xffea32f4), WTC(0xfffa0735), WTC(0x0004aa43), WTC(0x000a0a47),
+ WTC(0x000a156c), WTC(0x0004b9de), WTC(0xfff9e5c5), WTC(0xffe9874e)};
+
+const FIXP_WTB LowDelaySynthesis480[1440] = {
+ WTC(0xdad2e6c0), WTC(0xdb1da900), WTC(0xdb68ce40), WTC(0xdbb45840),
+ WTC(0xdc004940), WTC(0xdc4ca280), WTC(0xdc996500), WTC(0xdce69140),
+ WTC(0xdd342780), WTC(0xdd822700), WTC(0xddd08a80), WTC(0xde1f4d00),
+ WTC(0xde6e6ec0), WTC(0xdebdec40), WTC(0xdf0dba80), WTC(0xdf5dd540),
+ WTC(0xdfae3cc0), WTC(0xdfff0500), WTC(0xe0505140), WTC(0xe0a22980),
+ WTC(0xe0f488e0), WTC(0xe1476180), WTC(0xe19aa480), WTC(0xe1ee4d80),
+ WTC(0xe2425400), WTC(0xe29689a0), WTC(0xe2eacd60), WTC(0xe33f2420),
+ WTC(0xe393a300), WTC(0xe3e87f20), WTC(0xe43dcee0), WTC(0xe4938a80),
+ WTC(0xe4e9b0a0), WTC(0xe5404300), WTC(0xe5973e60), WTC(0xe5ee9b80),
+ WTC(0xe64649e0), WTC(0xe69e37e0), WTC(0xe6f65ec0), WTC(0xe74eb6c0),
+ WTC(0xe7a73000), WTC(0xe7ffbe40), WTC(0xe8585ee0), WTC(0xe8b10740),
+ WTC(0xe9099c40), WTC(0xe96214e0), WTC(0xe9ba79a0), WTC(0xea12e7c0),
+ WTC(0xea6b89c0), WTC(0xeac46580), WTC(0xeb1d7260), WTC(0xeb76b620),
+ WTC(0xebd036c0), WTC(0xec29e520), WTC(0xec83aa60), WTC(0xecdd5a00),
+ WTC(0xed36d500), WTC(0xed901540), WTC(0xede91160), WTC(0xee41bc20),
+ WTC(0xee9a0ee0), WTC(0xeef20860), WTC(0xef49a7e0), WTC(0xefa0ec00),
+ WTC(0xeff7d1c0), WTC(0xf04e56b0), WTC(0xf0a476e0), WTC(0xf0fa2f60),
+ WTC(0xf14f80e0), WTC(0xf1a46e10), WTC(0xf1f8fe80), WTC(0xf24d34a0),
+ WTC(0xf2a10bb0), WTC(0xf2f48210), WTC(0xf3479cc0), WTC(0xf39a5be0),
+ WTC(0xf3ecb8f0), WTC(0xf43eafa0), WTC(0xf4903b50), WTC(0xf4e14e80),
+ WTC(0xf531d6a0), WTC(0xf581bc10), WTC(0xf5d0e9c0), WTC(0xf61f5250),
+ WTC(0xf66ce6e0), WTC(0xf6b99330), WTC(0xf7054eb0), WTC(0xf7501f20),
+ WTC(0xf79a0750), WTC(0xf7e30700), WTC(0xf82b2fc0), WTC(0xf872a138),
+ WTC(0xf8b97f18), WTC(0xf8ffe668), WTC(0xf945e538), WTC(0xf98b8860),
+ WTC(0xf9d0f380), WTC(0xfa165148), WTC(0xfa5bb8a8), WTC(0xfaa13df8),
+ WTC(0xfae6fb00), WTC(0xfb2cf8c8), WTC(0xfb732a80), WTC(0xfbb97910),
+ WTC(0xfbffcd10), WTC(0xfc463478), WTC(0xfc8cd3fc), WTC(0xfcd3be5c),
+ WTC(0xfd1afa90), WTC(0xfd62aa84), WTC(0xfdab0288), WTC(0xfdf404b4),
+ WTC(0xfe3d3006), WTC(0xfe85b20e), WTC(0xfecca4cc), WTC(0xff10d559),
+ WTC(0xff50579b), WTC(0xff8a40d2), WTC(0xffb7d86e), WTC(0xffef6bbb),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbff67a01), WTC(0xbfecaa81), WTC(0xbfe2d901), WTC(0xbfd90601),
+ WTC(0xbfcf3181), WTC(0xbfc55c81), WTC(0xbfbb8701), WTC(0xbfb1b101),
+ WTC(0xbfa7dc01), WTC(0xbf9e0701), WTC(0xbf943301), WTC(0xbf8a5f81),
+ WTC(0xbf808b81), WTC(0xbf76b701), WTC(0xbf6ce201), WTC(0xbf630d81),
+ WTC(0xbf593a01), WTC(0xbf4f6801), WTC(0xbf459681), WTC(0xbf3bc601),
+ WTC(0xbf31f501), WTC(0xbf282501), WTC(0xbf1e5501), WTC(0xbf148681),
+ WTC(0xbf0aba01), WTC(0xbf00ef81), WTC(0xbef72681), WTC(0xbeed5f01),
+ WTC(0xbee39801), WTC(0xbed9d281), WTC(0xbed00f81), WTC(0xbec64e81),
+ WTC(0xbebc9181), WTC(0xbeb2d681), WTC(0xbea91f01), WTC(0xbe9f6901),
+ WTC(0xbe95b581), WTC(0xbe8c0501), WTC(0xbe825801), WTC(0xbe78b001),
+ WTC(0xbe6f0c01), WTC(0xbe656c01), WTC(0xbe5bd001), WTC(0xbe523781),
+ WTC(0xbe48a301), WTC(0xbe3f1381), WTC(0xbe358901), WTC(0xbe2c0501),
+ WTC(0xbe228681), WTC(0xbe190d81), WTC(0xbe0f9a01), WTC(0xbe062b81),
+ WTC(0xbdfcc301), WTC(0xbdf36101), WTC(0xbdea0681), WTC(0xbde0b301),
+ WTC(0xbdd76701), WTC(0xbdce2181), WTC(0xbdc4e301), WTC(0xbdbbab01),
+ WTC(0xbdb27b01), WTC(0xbda95301), WTC(0xbda03381), WTC(0xbd971c81),
+ WTC(0xbd8e0e01), WTC(0xbd850701), WTC(0xbd7c0781), WTC(0xbd731081),
+ WTC(0xbd6a2201), WTC(0xbd613d81), WTC(0xbd586281), WTC(0xbd4f9101),
+ WTC(0xbd46c801), WTC(0xbd3e0801), WTC(0xbd355081), WTC(0xbd2ca281),
+ WTC(0xbd23ff01), WTC(0xbd1b6501), WTC(0xbd12d581), WTC(0xbd0a4f81),
+ WTC(0xbd01d281), WTC(0xbcf95e81), WTC(0xbcf0f381), WTC(0xbce89281),
+ WTC(0xbce03b81), WTC(0xbcd7ef01), WTC(0xbccfac01), WTC(0xbcc77181),
+ WTC(0xbcbf4001), WTC(0xbcb71701), WTC(0xbcaef701), WTC(0xbca6e101),
+ WTC(0xbc9ed481), WTC(0xbc96d101), WTC(0xbc8ed701), WTC(0xbc86e581),
+ WTC(0xbc7efc81), WTC(0xbc771c01), WTC(0xbc6f4401), WTC(0xbc677501),
+ WTC(0xbc5fae81), WTC(0xbc57f101), WTC(0xbc503b81), WTC(0xbc488e81),
+ WTC(0xbc40e881), WTC(0xbc394901), WTC(0xbc31af01), WTC(0xbc2a1a81),
+ WTC(0xbc228f01), WTC(0xbc1b1081), WTC(0xbc13a481), WTC(0xbc0c4581),
+ WTC(0xbc04e381), WTC(0xbbfd6c01), WTC(0xbbf5d181), WTC(0xbbee2f81),
+ WTC(0xbbe6c801), WTC(0xbbdfdb81), WTC(0xbbd9a781), WTC(0xbbd45881),
+ WTC(0xbbd01301), WTC(0xbbccfc81), WTC(0xbbcb2281), WTC(0xbbca5d01),
+ WTC(0xbbca7481), WTC(0xbbcb3201), WTC(0xbbcc6b01), WTC(0xbbce0601),
+ WTC(0xbbcfea81), WTC(0xbbd20301), WTC(0xbbd45601), WTC(0xbbd70201),
+ WTC(0xbbda2501), WTC(0xbbdddb01), WTC(0xbbe23281), WTC(0xbbe73201),
+ WTC(0xbbece281), WTC(0xbbf34281), WTC(0xbbfa3c01), WTC(0xbc01b381),
+ WTC(0xbc098d81), WTC(0xbc11b681), WTC(0xbc1a2401), WTC(0xbc22cd81),
+ WTC(0xbc2bab01), WTC(0xbc34c081), WTC(0xbc3e1981), WTC(0xbc47c281),
+ WTC(0xbc51cb01), WTC(0xbc5c4c81), WTC(0xbc676501), WTC(0xbc733401),
+ WTC(0xbc7fd301), WTC(0xbc8d5101), WTC(0xbc9bb901), WTC(0xbcab1781),
+ WTC(0xbcbb7001), WTC(0xbcccbd01), WTC(0xbcdef701), WTC(0xbcf21601),
+ WTC(0xbd060c81), WTC(0xbd1ac801), WTC(0xbd303581), WTC(0xbd464281),
+ WTC(0xbd5ce281), WTC(0xbd740b81), WTC(0xbd8bb281), WTC(0xbda3d081),
+ WTC(0xbdbc6381), WTC(0xbdd56b81), WTC(0xbdeee981), WTC(0xbe08e181),
+ WTC(0xbe236001), WTC(0xbe3e7201), WTC(0xbe5a2301), WTC(0xbe767e81),
+ WTC(0xbe938c81), WTC(0xbeb15701), WTC(0xbecfe601), WTC(0xbeef4601),
+ WTC(0xbf0f8301), WTC(0xbf30a901), WTC(0xbf52c101), WTC(0xbf75cc81),
+ WTC(0xbf99cb01), WTC(0xbfbebb81), WTC(0xbfe48981), WTC(0xc00b04c0),
+ WTC(0xc031f880), WTC(0xc0593340), WTC(0xc0809280), WTC(0xc0a802c0),
+ WTC(0xc0cf6ec0), WTC(0xc0f6cc00), WTC(0xc11e3a80), WTC(0xc145f040),
+ WTC(0xc16e22c0), WTC(0xc196fb00), WTC(0xc1c08680), WTC(0xc1eaca00),
+ WTC(0xc215cbc0), WTC(0xc2418940), WTC(0xc26df5c0), WTC(0xc29b02c0),
+ WTC(0xc2c8a140), WTC(0xc2f6b500), WTC(0xc3251740), WTC(0xc353a0c0),
+ WTC(0xc3822c00), WTC(0xc3b09940), WTC(0xc3deccc0), WTC(0xc40ca800),
+ WTC(0xc43a28c0), WTC(0xc4678a00), WTC(0xc4951780), WTC(0xc4c31d00),
+ WTC(0xc4f1bdc0), WTC(0xc520e840), WTC(0xc5508440), WTC(0xc5807900),
+ WTC(0xc5b09e80), WTC(0xc5e0bfc0), WTC(0xc610a740), WTC(0xc64029c0),
+ WTC(0xc66f49c0), WTC(0xc69e2180), WTC(0xc6ccca40), WTC(0xc6fb5700),
+ WTC(0xc729cc80), WTC(0xc7582b40), WTC(0xc7867480), WTC(0xc7b4a480),
+ WTC(0xc7e2afc0), WTC(0xc8108a80), WTC(0xc83e28c0), WTC(0xc86b7f00),
+ WTC(0xc8988100), WTC(0xc8c52340), WTC(0xc8f15980), WTC(0xc91d1840),
+ WTC(0xb4d6a381), WTC(0xb4422b81), WTC(0xb3ae8601), WTC(0xb31bb301),
+ WTC(0xb289b181), WTC(0xb1f88181), WTC(0xb1682281), WTC(0xb0d89401),
+ WTC(0xb049d601), WTC(0xafbbe801), WTC(0xaf2ec901), WTC(0xaea27681),
+ WTC(0xae16f001), WTC(0xad8c3301), WTC(0xad023f01), WTC(0xac791401),
+ WTC(0xabf0b181), WTC(0xab691681), WTC(0xaae24301), WTC(0xaa5c3601),
+ WTC(0xa9d6ef01), WTC(0xa9526d81), WTC(0xa8ceb201), WTC(0xa84bbb81),
+ WTC(0xa7c98b01), WTC(0xa7482101), WTC(0xa6c77e01), WTC(0xa647a301),
+ WTC(0xa5c89001), WTC(0xa54a4701), WTC(0xa4ccc901), WTC(0xa4501601),
+ WTC(0xa3d43001), WTC(0xa3591801), WTC(0xa2dece81), WTC(0xa2655581),
+ WTC(0xa1ecae01), WTC(0xa174da81), WTC(0xa0fddd81), WTC(0xa087b981),
+ WTC(0xa0127081), WTC(0x9f9e0301), WTC(0x9f2a7281), WTC(0x9eb7c101),
+ WTC(0x9e45f081), WTC(0x9dd50481), WTC(0x9d650081), WTC(0x9cf5e701),
+ WTC(0x9c87ba81), WTC(0x9c1a7c81), WTC(0x9bae2f81), WTC(0x9b42d581),
+ WTC(0x9ad87081), WTC(0x9a6f0381), WTC(0x9a069001), WTC(0x999f1981),
+ WTC(0x9938a281), WTC(0x98d32d81), WTC(0x986ebd81), WTC(0x980b5501),
+ WTC(0x97a8f681), WTC(0x9747a481), WTC(0x96e76101), WTC(0x96882e01),
+ WTC(0x962a0c81), WTC(0x95ccff01), WTC(0x95710601), WTC(0x95162381),
+ WTC(0x94bc5981), WTC(0x9463a881), WTC(0x940c1281), WTC(0x93b59901),
+ WTC(0x93603d01), WTC(0x930bff81), WTC(0x92b8e101), WTC(0x9266e281),
+ WTC(0x92160301), WTC(0x91c64301), WTC(0x9177a301), WTC(0x912a2201),
+ WTC(0x90ddc001), WTC(0x90927b81), WTC(0x90485401), WTC(0x8fff4601),
+ WTC(0x8fb74f81), WTC(0x8f706f01), WTC(0x8f2aa101), WTC(0x8ee5e301),
+ WTC(0x8ea23201), WTC(0x8e5f8881), WTC(0x8e1de001), WTC(0x8ddd3201),
+ WTC(0x8d9d7781), WTC(0x8d5eaa01), WTC(0x8d20c301), WTC(0x8ce3ba81),
+ WTC(0x8ca78781), WTC(0x8c6c1b01), WTC(0x8c316681), WTC(0x8bf75b01),
+ WTC(0x8bbde981), WTC(0x8b850281), WTC(0x8b4c9701), WTC(0x8b149701),
+ WTC(0x8adcee01), WTC(0x8aa58681), WTC(0x8a6e4a01), WTC(0x8a372881),
+ WTC(0x8a001f01), WTC(0x89c92f81), WTC(0x89925a81), WTC(0x895bcd01),
+ WTC(0x8925f101), WTC(0x88f13801), WTC(0x88be1681), WTC(0x888d3181),
+ WTC(0x885f8481), WTC(0x88353501), WTC(0x88124281), WTC(0x87e73d81),
+ WTC(0x87d4ac81), WTC(0x87cb5101), WTC(0x87c05e81), WTC(0x87b42481),
+ WTC(0x87a70e81), WTC(0x87998f01), WTC(0x878c1881), WTC(0x877ede01),
+ WTC(0x8771c601), WTC(0x8764b101), WTC(0x87578181), WTC(0x874a2f01),
+ WTC(0x873cc201), WTC(0x872f4201), WTC(0x8721b481), WTC(0x87141b01),
+ WTC(0x87067281), WTC(0x86f8ba81), WTC(0x86eaf081), WTC(0x86dd1481),
+ WTC(0x86cf2601), WTC(0x86c12401), WTC(0x86b30f01), WTC(0x86a4e781),
+ WTC(0x8696ad01), WTC(0x86886001), WTC(0x867a0081), WTC(0x866b8d81),
+ WTC(0x865d0581), WTC(0x864e6901), WTC(0x863fb701), WTC(0x8630f181),
+ WTC(0x86221801), WTC(0x86132c01), WTC(0x86042c01), WTC(0x85f51681),
+ WTC(0x85e5eb81), WTC(0x85d6a981), WTC(0x85c75201), WTC(0x85b7e601),
+ WTC(0x85a86581), WTC(0x8598d081), WTC(0x85892681), WTC(0x85796601),
+ WTC(0x85698e81), WTC(0x8559a081), WTC(0x85499d01), WTC(0x85398481),
+ WTC(0x85295881), WTC(0x85191801), WTC(0x8508c181), WTC(0x84f85581),
+ WTC(0x84e7d381), WTC(0x84d73c01), WTC(0x84c69101), WTC(0x84b5d301),
+ WTC(0x84a50201), WTC(0x84941d81), WTC(0x84832481), WTC(0x84721701),
+ WTC(0x8460f581), WTC(0x844fc081), WTC(0x843e7a81), WTC(0x842d2281),
+ WTC(0x841bb981), WTC(0x840a3e81), WTC(0x83f8b001), WTC(0x83e70f01),
+ WTC(0x83d55d01), WTC(0x83c39a81), WTC(0x83b1c881), WTC(0x839fe801),
+ WTC(0x838df801), WTC(0x837bf801), WTC(0x8369e781), WTC(0x8357c701),
+ WTC(0x83459881), WTC(0x83335c81), WTC(0x83211501), WTC(0x830ec081),
+ WTC(0x82fc5f01), WTC(0x82e9ef01), WTC(0x82d77201), WTC(0x82c4e801),
+ WTC(0x82b25301), WTC(0x829fb401), WTC(0x828d0b01), WTC(0x827a5801),
+ WTC(0x82679901), WTC(0x8254cf01), WTC(0x8241fa01), WTC(0x822f1b01),
+ WTC(0x821c3401), WTC(0x82094581), WTC(0x81f64f01), WTC(0x81e34f81),
+ WTC(0x81d04681), WTC(0x81bd3401), WTC(0x81aa1981), WTC(0x8196f781),
+ WTC(0x8183cf81), WTC(0x8170a181), WTC(0x815d6c01), WTC(0x814a2f81),
+ WTC(0x8136ea01), WTC(0x81239d81), WTC(0x81104a01), WTC(0x80fcf181),
+ WTC(0x80e99401), WTC(0x80d63101), WTC(0x80c2c781), WTC(0x80af5701),
+ WTC(0x809bdf01), WTC(0x80886081), WTC(0x8074dc01), WTC(0x80615281),
+ WTC(0x804dc481), WTC(0x803a3381), WTC(0x80269f81), WTC(0x80130981),
+ WTC(0x0a608220), WTC(0x0a8ee7d0), WTC(0x0abe35c0), WTC(0x0aee5de0),
+ WTC(0x0b1f5230), WTC(0x0b5104a0), WTC(0x0b836720), WTC(0x0bb66bb0),
+ WTC(0x0bea0440), WTC(0x0c1e22c0), WTC(0x0c52ba70), WTC(0x0c87ca90),
+ WTC(0x0cbd5ba0), WTC(0x0cf375e0), WTC(0x0d2a1f50), WTC(0x0d615480),
+ WTC(0x0d990e40), WTC(0x0dd14500), WTC(0x0e09f730), WTC(0x0e432e90),
+ WTC(0x0e7cf790), WTC(0x0eb75e50), WTC(0x0ef26430), WTC(0x0f2dfd70),
+ WTC(0x0f6a1d70), WTC(0x0fa6b7e0), WTC(0x0fe3c3d0), WTC(0x10213ac0),
+ WTC(0x105f1640), WTC(0x109d4f20), WTC(0x10dbdb80), WTC(0x111ab0c0),
+ WTC(0x1159c360), WTC(0x11990fc0), WTC(0x11d8a060), WTC(0x121882c0),
+ WTC(0x1258c480), WTC(0x12995a40), WTC(0x12da1b00), WTC(0x131adb60),
+ WTC(0x135b70c0), WTC(0x139bb680), WTC(0x13db8c00), WTC(0x141ad080),
+ WTC(0x14596460), WTC(0x149729e0), WTC(0x14d404e0), WTC(0x150fd8e0),
+ WTC(0x154a88c0), WTC(0x1583f5e0), WTC(0x15bc0120), WTC(0x15f28ba0),
+ WTC(0x162779a0), WTC(0x165ab300), WTC(0x168c2040), WTC(0x16bbaa80),
+ WTC(0x16e94120), WTC(0x1714d9e0), WTC(0x173e6440), WTC(0x17660680),
+ WTC(0x178ca020), WTC(0x17b36400), WTC(0x17db84e0), WTC(0x1805d920),
+ WTC(0x18328400), WTC(0x18617cc0), WTC(0x1892bfa0), WTC(0x18c64540),
+ WTC(0x18fc0400), WTC(0x1933f140), WTC(0x196e0320), WTC(0x19aa2fc0),
+ WTC(0x19e86d80), WTC(0x1a28b2e0), WTC(0x1a6af700), WTC(0x1aaf3320),
+ WTC(0x1af56180), WTC(0x1b3d7ce0), WTC(0x1b877c40), WTC(0x1bd350c0),
+ WTC(0x1c20ea40), WTC(0x1c703840), WTC(0x1cc13860), WTC(0x1d13f760),
+ WTC(0x1d688420), WTC(0x1dbeed40), WTC(0x1e174660), WTC(0x1e71a640),
+ WTC(0x1ece2400), WTC(0x1f2cd220), WTC(0x1f8db3c0), WTC(0x1ff0c3e0),
+ WTC(0x20560080), WTC(0x20bd46c0), WTC(0x21263400), WTC(0x21905740),
+ WTC(0x21fb4100), WTC(0x2266ba80), WTC(0x22d2d140), WTC(0x233f9780),
+ WTC(0x23ad25c0), WTC(0x241bc800), WTC(0x248bf040), WTC(0x24fe1380),
+ WTC(0x25728180), WTC(0x25e90a00), WTC(0x26614080), WTC(0x26dabdc0),
+ WTC(0x27552540), WTC(0x27d03200), WTC(0x284ba580), WTC(0x28c740c0),
+ WTC(0x29431f80), WTC(0x29bfc9c0), WTC(0x2a3dd080), WTC(0x2abdc000),
+ WTC(0x2b3ffd00), WTC(0x2bc4cd80), WTC(0x2c4c7d40), WTC(0x2cd72ec0),
+ WTC(0x2d647f80), WTC(0x2df3cd80), WTC(0x2e847d80), WTC(0x2f15ea40),
+ WTC(0x2fa760c0), WTC(0x30382b80), WTC(0x30c79440), WTC(0x315566c0),
+ WTC(0x31e20800), WTC(0x326de7c0), WTC(0x32f98200), WTC(0x3385ba00),
+ WTC(0x3413bec0), WTC(0x34a4c480), WTC(0x3539bf00), WTC(0x35d2c4c0),
+ WTC(0x366f8340), WTC(0x370fb800), WTC(0x37b2cf80), WTC(0x3857a480),
+ WTC(0x38fcee80), WTC(0x39a16840), WTC(0x3a4422c0), WTC(0x3ae495c0),
+ WTC(0x3b824000), WTC(0x3c1cb500), WTC(0x3cb438c0), WTC(0x3d4994c0),
+ WTC(0x3ddd8f40), WTC(0x3e70ec00), WTC(0x3f045e40), WTC(0x3f989080),
+ WTC(0x402e32ff), WTC(0x40c5c07f), WTC(0x415f547f), WTC(0x41faf07f),
+ WTC(0x4298997f), WTC(0x4338307f), WTC(0x43d96bff), WTC(0x447bffff),
+ WTC(0x451f9cff), WTC(0x45c3daff), WTC(0x46683eff), WTC(0x470c4cff),
+ WTC(0x47af93ff), WTC(0x4851c3ff), WTC(0x48f29d7f), WTC(0x4991de7f),
+ WTC(0x4a2f5e7f), WTC(0x4acb287f), WTC(0x4b65537f), WTC(0x4bfdf37f),
+ WTC(0x4c95337f), WTC(0x4d2b51ff), WTC(0x4dc091ff), WTC(0x4e5533ff),
+ WTC(0x4ee96b7f), WTC(0x4f7d61ff), WTC(0x501140ff), WTC(0x50a5317f),
+ WTC(0x51395a7f), WTC(0x51cddf7f), WTC(0x5262e6ff), WTC(0x52f885ff),
+ WTC(0x538eb47f), WTC(0x542560ff), WTC(0x54bc7b7f), WTC(0x5553a8ff),
+ WTC(0x55ea35ff), WTC(0x567f66ff), WTC(0x5712897f), WTC(0x57a33a7f),
+ WTC(0x583152ff), WTC(0x58bca5ff), WTC(0x594530ff), WTC(0x59cb79ff),
+ WTC(0x5a5047ff), WTC(0x5ad45eff), WTC(0x5b584e7f), WTC(0x5bdc417f),
+ WTC(0x5c60487f), WTC(0x5ce476ff), WTC(0x5d68c47f), WTC(0x5ded06ff),
+ WTC(0x5e7111ff), WTC(0x5ef4b5ff), WTC(0x5f77a17f), WTC(0x5ff96aff),
+ WTC(0x6079a7ff), WTC(0x60f7f7ff), WTC(0x617417ff), WTC(0x61edd87f),
+ WTC(0x6264ffff), WTC(0x62d9a6ff), WTC(0x634c817f), WTC(0x63be657f),
+ WTC(0x6430277f), WTC(0x64a2247f), WTC(0x65142bff), WTC(0x6586027f),
+ WTC(0x65f7697f), WTC(0x666801ff), WTC(0x66d756ff), WTC(0x6744f0ff),
+ WTC(0x67b0787f), WTC(0x681a077f), WTC(0x6881ebff), WTC(0x68e8707f),
+ WTC(0x694dceff), WTC(0x69b21e7f), WTC(0x6a156cff), WTC(0x6a77ca7f),
+ WTC(0x6ad9377f), WTC(0x6b39a4ff), WTC(0x6b9901ff), WTC(0x6bf73cff),
+ WTC(0x6c54457f), WTC(0x6cb00aff), WTC(0x6d0a7bff), WTC(0x6d6387ff),
+ WTC(0xae2cbe01), WTC(0xaf526d01), WTC(0xb0751201), WTC(0xb194da81),
+ WTC(0xb2b1f401), WTC(0xb3cc8d01), WTC(0xb4e4d201), WTC(0xb5faf101),
+ WTC(0xb70f1881), WTC(0xb8217301), WTC(0xb9321181), WTC(0xba40ee01),
+ WTC(0xbb4e0201), WTC(0xbc594781), WTC(0xbd62b881), WTC(0xbe6a5181),
+ WTC(0xbf700d01), WTC(0xc073e4c0), WTC(0xc175d240), WTC(0xc275cc80),
+ WTC(0xc373cb80), WTC(0xc46fca00), WTC(0xc569c600), WTC(0xc661bdc0),
+ WTC(0xc757af80), WTC(0xc84b9840), WTC(0xc93d7300), WTC(0xca2d3a40),
+ WTC(0xcb1aea40), WTC(0xcc068280), WTC(0xccf00480), WTC(0xcdd77200),
+ WTC(0xcebccb40), WTC(0xcfa00d80), WTC(0xd0813540), WTC(0xd1603f00),
+ WTC(0xd23d2980), WTC(0xd317f7c0), WTC(0xd3f0ac40), WTC(0xd4c74980),
+ WTC(0xd59bcf80), WTC(0xd66e3b00), WTC(0xd73e8900), WTC(0xd80cb740),
+ WTC(0xd8d8c7c0), WTC(0xd9a2be00), WTC(0xda6a9e40), WTC(0xdb306a40),
+ WTC(0xdbf42080), WTC(0xdcb5be80), WTC(0xdd754140), WTC(0xde32a900),
+ WTC(0xdeedf9c0), WTC(0xdfa737c0), WTC(0xe05e6740), WTC(0xe1138900),
+ WTC(0xe1c69ac0), WTC(0xe2779a40), WTC(0xe3268680), WTC(0xe3d36260),
+ WTC(0xe47e33a0), WTC(0xe526ff80), WTC(0xe5cdc960), WTC(0xe6729100),
+ WTC(0xe7155460), WTC(0xe7b611c0), WTC(0xe854ca20), WTC(0xe8f18180),
+ WTC(0xe98c3ca0), WTC(0xea24ffe0), WTC(0xeabbcb20), WTC(0xeb509b60),
+ WTC(0xebe36d00), WTC(0xec743e00), WTC(0xed0310e0), WTC(0xed8feaa0),
+ WTC(0xee1ad060), WTC(0xeea3c640), WTC(0xef2acd60), WTC(0xefafe6a0),
+ WTC(0xf03312f0), WTC(0xf0b45800), WTC(0xf133c230), WTC(0xf1b15ef0),
+ WTC(0xf22d3af0), WTC(0xf2a75c80), WTC(0xf31fc460), WTC(0xf39673b0),
+ WTC(0xf40b6a00), WTC(0xf47ea230), WTC(0xf4f01450), WTC(0xf55fb930),
+ WTC(0xf5cd84c0), WTC(0xf6396090), WTC(0xf6a333e0), WTC(0xf70ae540),
+ WTC(0xf7707260), WTC(0xf7d3f720), WTC(0xf83592f0), WTC(0xf8956450),
+ WTC(0xf8f38120), WTC(0xf94ff7c8), WTC(0xf9aad740), WTC(0xfa042920),
+ WTC(0xfa5be110), WTC(0xfab1e778), WTC(0xfb062478), WTC(0xfb588d78),
+ WTC(0xfba93530), WTC(0xfbf836c8), WTC(0xfc45ace0), WTC(0xfc91a294),
+ WTC(0xfcdc0e5c), WTC(0xfd24e438), WTC(0xfd6c17dc), WTC(0xfdb19758),
+ WTC(0xfdf54c3c), WTC(0xfe371ef8), WTC(0xfe7701aa), WTC(0xfeb50d62),
+ WTC(0xfef1700a), WTC(0xff2c5574), WTC(0xff65ee7b), WTC(0xff9e75de),
+ WTC(0xffd62863), WTC(0x000d4401), WTC(0x0043d345), WTC(0x00799cd0),
+ WTC(0x00ae5f49), WTC(0x00e1d7a4), WTC(0x0113a6f2), WTC(0x0143575c),
+ WTC(0x01707024), WTC(0x019a9346), WTC(0x01c1cf08), WTC(0x01e66c12),
+ WTC(0x0208ac48), WTC(0x0228e868), WTC(0x0247a6c8), WTC(0x02657aa0),
+ WTC(0x0282f710), WTC(0x02a07e50), WTC(0x02be31c0), WTC(0x02dc2b30),
+ WTC(0x02fa7f34), WTC(0x0318fb10), WTC(0x03372fdc), WTC(0x0354ae54),
+ WTC(0x03710d18), WTC(0x038bfdb4), WTC(0x03a54084), WTC(0x03bc92b8),
+ WTC(0x03d1c710), WTC(0x03e4dd20), WTC(0x03f5e25c), WTC(0x0404e218),
+ WTC(0x0411fc30), WTC(0x041d6b30), WTC(0x04276cd0), WTC(0x04303e00),
+ WTC(0x04381528), WTC(0x043f2310), WTC(0x04459908), WTC(0x044ba430),
+ WTC(0x045161f8), WTC(0x0456e6f8), WTC(0x045c49a8), WTC(0x046192f8),
+ WTC(0x0466af40), WTC(0x046b8240), WTC(0x046ff0d8), WTC(0x0473de18),
+ WTC(0x04772b58), WTC(0x0479b9a0), WTC(0x047b6a30), WTC(0x047c2088),
+ WTC(0x047bc230), WTC(0x047a3418), WTC(0x04776098), WTC(0x04734790),
+ WTC(0x046df4c0), WTC(0x04677220), WTC(0x045fd1b0), WTC(0x04573588),
+ WTC(0x044dc4b8), WTC(0x0443a5b8), WTC(0x04390160), WTC(0x042e0398),
+ WTC(0x0422d8c0), WTC(0x0417aa30), WTC(0x040c7ce0), WTC(0x040136e0),
+ WTC(0x03f5beb0), WTC(0x03e9f8ec), WTC(0x03ddc484), WTC(0x03d0fd9c),
+ WTC(0x03c37fa0), WTC(0x03b53014), WTC(0x03a60a18), WTC(0x03960f88),
+ WTC(0x03854110), WTC(0x0373ad9c), WTC(0x03617694), WTC(0x034ebf9c),
+ WTC(0x033bab30), WTC(0x03284ef0), WTC(0x0314b598), WTC(0x0300ea54),
+ WTC(0x02ecf524), WTC(0x02d8d210), WTC(0x02c476ac), WTC(0x02afd940),
+ WTC(0x029aee4c), WTC(0x0285a6f4), WTC(0x026ff398), WTC(0x0259c448),
+ WTC(0x024317cc), WTC(0x022c0084), WTC(0x02149310), WTC(0x01fce334),
+ WTC(0x01e4fb24), WTC(0x01ccdd0a), WTC(0x01b48b20), WTC(0x019c077e),
+ WTC(0x01835432), WTC(0x016a733c), WTC(0x015166a6), WTC(0x0138302e),
+ WTC(0x011ed0f6), WTC(0x010549f8), WTC(0x00eb9c25), WTC(0x00d1caa6),
+ WTC(0x00b7db94), WTC(0x009dd560), WTC(0x0083be75), WTC(0x00699d41),
+ WTC(0x004f782f), WTC(0x003555ab), WTC(0x001b3c21), WTC(0x000131fe),
+ WTC(0xd61cfc40), WTC(0xd5acb340), WTC(0xd53d4400), WTC(0xd4cea6c0),
+ WTC(0xd460d440), WTC(0xd3f3c440), WTC(0xd3876f80), WTC(0xd31bce40),
+ WTC(0xd2b0d900), WTC(0xd2468980), WTC(0xd1dcef00), WTC(0xd17429c0),
+ WTC(0xd10c5b80), WTC(0xd0a59b80), WTC(0xd03fd780), WTC(0xcfdae780),
+ WTC(0xcf76a380), WTC(0xcf12fac0), WTC(0xceb01100), WTC(0xce4e18c0),
+ WTC(0xcded4440), WTC(0xcd8d9a40), WTC(0xcd2ee800), WTC(0xccd0f440),
+ WTC(0xcc738780), WTC(0xcc167d40), WTC(0xcbb9c180), WTC(0xcb5d4040),
+ WTC(0xcb00e240), WTC(0xcaa48000), WTC(0xca47eac0), WTC(0xc9eaf1c0),
+ WTC(0xc98d8100), WTC(0xc92fc580), WTC(0xc8d1fc80), WTC(0xc8746480),
+ WTC(0xc816dc40), WTC(0xc7b8c280), WTC(0xc7596800), WTC(0xc6f81f80),
+ WTC(0xc6945740), WTC(0xc62d93c0), WTC(0xc5c358c0), WTC(0xc5552b80),
+ WTC(0xc4e29240), WTC(0xc46b1440), WTC(0xc3ee3840), WTC(0xc36b8500),
+ WTC(0xc2e28040), WTC(0xc252ae80), WTC(0xc1bb9540), WTC(0xc11cc200),
+ WTC(0xc075cf00), WTC(0xbfc65781), WTC(0xbf0df881), WTC(0xbe4c6f01),
+ WTC(0xbd819401), WTC(0xbcad2d01), WTC(0xbbcfb981), WTC(0xbaeca681),
+ WTC(0xba08e781), WTC(0xb9297081), WTC(0xb851e081), WTC(0xb782ed01),
+ WTC(0xb6bc6a81), WTC(0xb5fe4981), WTC(0xb5487281), WTC(0xb49ad081),
+ WTC(0xb3f54d81), WTC(0xb357d401), WTC(0xb2c24e01), WTC(0xb234a681),
+ WTC(0xb1aec701), WTC(0xb1309b01), WTC(0xb0ba0c01), WTC(0xb04b0481),
+ WTC(0xafe36f01), WTC(0xaf833601), WTC(0xaf2a4381), WTC(0xaed88201),
+ WTC(0xae8ddb81), WTC(0xae4a3b81), WTC(0xae0d8b01), WTC(0xadd7b581),
+ WTC(0xada8a481), WTC(0xad804281), WTC(0xad5e7a81), WTC(0xad433601),
+ WTC(0xad2e6001), WTC(0xad1fe281), WTC(0xad17a801), WTC(0xad159a81),
+ WTC(0xad19a501), WTC(0xad23b101), WTC(0xad33aa01), WTC(0xad497981),
+ WTC(0xad650a01), WTC(0xad864601), WTC(0xadad1781), WTC(0xadd96981),
+ WTC(0xae0b2601), WTC(0xae423781), WTC(0xae7e8801), WTC(0xaec00201),
+ WTC(0xaf069081), WTC(0xaf521c81), WTC(0xafa29201), WTC(0xaff7da01),
+ WTC(0xb051df01), WTC(0xb0b08c81), WTC(0xb113cb81), WTC(0xb17b8701),
+ WTC(0xb1e7a981), WTC(0xb2581d81), WTC(0xb2cccc81), WTC(0xb345a181),
+ WTC(0xb3c28701), WTC(0xb4436681), WTC(0xb4c82b81), WTC(0xb550bf81),
+ WTC(0xb5dd0d01), WTC(0xb66cff01), WTC(0xb7007f01), WTC(0xb7977781),
+ WTC(0xb831d381), WTC(0xb8cf7d01), WTC(0xb9705e01), WTC(0xba146101),
+ WTC(0xbabb7081), WTC(0xbb657781), WTC(0xbc125f01), WTC(0xbcc21281),
+ WTC(0xbd747b81), WTC(0xbe298581), WTC(0xbee11981), WTC(0xbf9b2301),
+ WTC(0xc0578b80), WTC(0xc1163dc0), WTC(0xc1d72400), WTC(0xc29a28c0),
+ WTC(0xc35f3640), WTC(0xc42636c0), WTC(0xc4ef1500), WTC(0xc5b9bb00),
+ WTC(0xc6861340), WTC(0xc7540840), WTC(0xc8238400), WTC(0xc8f47100),
+ WTC(0xc9c6b9c0), WTC(0xca9a4840), WTC(0xcb6f0780), WTC(0xcc44e140),
+ WTC(0xcd1bc000), WTC(0xcdf38e00), WTC(0xcecc3600), WTC(0xcfa5a240),
+ WTC(0xd07fbcc0), WTC(0xd15a7040), WTC(0xd235a6c0), WTC(0xd3114b00),
+ WTC(0xd3ed4740), WTC(0xd4c98580), WTC(0xd5a5f080), WTC(0xd6827280),
+ WTC(0xd75ef600), WTC(0xd83b6500), WTC(0xd917aa00), WTC(0xd9f3af80),
+ WTC(0xdacf5fc0), WTC(0xdbaaa540), WTC(0xdc856a00), WTC(0xdd5f98c0),
+ WTC(0xde391bc0), WTC(0xdf11dd40), WTC(0xdfe9c780), WTC(0xe0c0c540),
+ WTC(0xe196c080), WTC(0xe26ba3c0), WTC(0xe33f5960), WTC(0xe411cba0),
+ WTC(0xe4e2e500), WTC(0xe5b28fc0), WTC(0xe680b640), WTC(0xe74d42e0),
+ WTC(0xe8181fe0), WTC(0xe8e137e0), WTC(0xe9a87500), WTC(0xea6dc1a0),
+ WTC(0xeb310820), WTC(0xebf23300), WTC(0xecb12c60), WTC(0xed6ddee0),
+ WTC(0xee2834a0), WTC(0xeee01800), WTC(0xef957380), WTC(0xf0483160),
+ WTC(0xf0f83c00), WTC(0xf1a57db0), WTC(0xf24fe0f0), WTC(0xf2f74ff0),
+ WTC(0xf39bb530), WTC(0xf43cfaf0), WTC(0xf4db0b90), WTC(0xf575d180),
+ WTC(0xf60d3700), WTC(0xf6a12680), WTC(0xf7318a50), WTC(0xf7be4cc0),
+ WTC(0xf8475850), WTC(0xf8cc9738), WTC(0xf94df3e0), WTC(0xf9cb58a8),
+ WTC(0xfa44afe0), WTC(0xfab9e3e8), WTC(0xfb2adf20), WTC(0xfb978be8),
+ WTC(0xfbffd488), WTC(0xfc63a370), WTC(0xfcc2e2f0), WTC(0xfd1d7d64),
+ WTC(0xfd735d2c), WTC(0xfdc46c9c), WTC(0xfe109618), WTC(0xfe57c3f4),
+ WTC(0xfe99e090), WTC(0xfed6d644), WTC(0xff0e8f6e), WTC(0xff40f667),
+ WTC(0xff6df58c), WTC(0xff957738), WTC(0xffb765c5), WTC(0xffd3ab90),
+ WTC(0xffea32f4), WTC(0xfffae64c), WTC(0x0005aff3), WTC(0x000a7a44),
+ WTC(0x00092f9c), WTC(0x0001ba54), WTC(0xfff404ca), WTC(0xffdff957)};
+
+/*
+ * TNS_MAX_BANDS
+ * entry for each sampling rate
+ * 1 long window
+ * 2 SHORT window
+ */
+const UCHAR tns_max_bands_tbl[13][2] = {
+ {31, 9}, /* 96000 */
+ {31, 9}, /* 88200 */
+ {34, 10}, /* 64000 */
+ {40, 14}, /* 48000 */
+ {42, 14}, /* 44100 */
+ {51, 14}, /* 32000 */
+ {46, 14}, /* 24000 */
+ {46, 14}, /* 22050 */
+ {42, 14}, /* 16000 */
+ {42, 14}, /* 12000 */
+ {42, 14}, /* 11025 */
+ {39, 14}, /* 8000 */
+ {39, 14}, /* 7350 */
+};
+
+/* TNS_MAX_BANDS for low delay. The array index is the sampleRateIndex */
+const UCHAR tns_max_bands_tbl_480[13] = {
+ 31, /* 96000 */
+ 31, /* 88200 */
+ 31, /* 64000 */
+ 31, /* 48000 */
+ 32, /* 44100 */
+ 37, /* 32000 */
+ 30, /* 24000 */
+ 30, /* 22050 */
+ 30, /* 16000 */
+ 30, /* 12000 */
+ 30, /* 11025 */
+ 30, /* 8000 */
+ 30 /* 7350 */
+};
+const UCHAR tns_max_bands_tbl_512[13] = {
+ 31, /* 96000 */
+ 31, /* 88200 */
+ 31, /* 64000 */
+ 31, /* 48000 */
+ 32, /* 44100 */
+ 37, /* 32000 */
+ 31, /* 24000 */
+ 31, /* 22050 */
+ 31, /* 16000 */
+ 31, /* 12000 */
+ 31, /* 11025 */
+ 31, /* 8000 */
+ 31 /* 7350 */
+};
+
+#define TCC(x) (FIXP_DBL(x))
+
+const FIXP_TCC FDKaacDec_tnsCoeff3[8] = {
+ TCC(0x81f1d1d4), TCC(0x9126146c), TCC(0xadb922c4), TCC(0xd438af1f),
+ TCC(0x00000000), TCC(0x3789809b), TCC(0x64130dd4), TCC(0x7cca7016)};
+const FIXP_TCC FDKaacDec_tnsCoeff4[16] = {
+ TCC(0x808bc842), TCC(0x84e2e58c), TCC(0x8d6b49d1), TCC(0x99da920a),
+ TCC(0xa9c45713), TCC(0xbc9ddeb9), TCC(0xd1c2d51b), TCC(0xe87ae53d),
+ TCC(0x00000000), TCC(0x1a9cd9b6), TCC(0x340ff254), TCC(0x4b3c8c29),
+ TCC(0x5f1f5ebb), TCC(0x6ed9ebba), TCC(0x79bc385f), TCC(0x7f4c7e5b)};
+
+const UCHAR FDKaacDec_tnsCoeff3_gain_ld[] = {
+ 3, 1, 1, 1, 0, 1, 1, 3,
+};
+const UCHAR FDKaacDec_tnsCoeff4_gain_ld[] = {
+ 4, 2, 2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 4,
+};
+
+/* Lookup tables for elements in ER bitstream */
+const MP4_ELEMENT_ID
+ elementsTab[AACDEC_MAX_CH_CONF][AACDEC_CH_ELEMENTS_TAB_SIZE] = {
+ /* 1 */ {ID_SCE, ID_EXT, ID_END, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE}, /* 1 channel */
+ /* 2 */
+ {ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE} /* 2 channels */
+#if (AACDEC_MAX_CH_CONF > 2)
+ /* 3 */,
+ {ID_SCE, ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE,
+ ID_NONE}, /* 3 channels */
+ /* 4 */
+ {ID_SCE, ID_CPE, ID_SCE, ID_EXT, ID_END, ID_NONE,
+ ID_NONE}, /* 4 channels */
+ /* 5 */
+ {ID_SCE, ID_CPE, ID_CPE, ID_EXT, ID_END, ID_NONE,
+ ID_NONE}, /* 5 channels */
+ /* 6 */
+ {ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END,
+ ID_NONE} /* 6 channels */
+#endif
+#if (AACDEC_MAX_CH_CONF > 6)
+ /* 7 */,
+ {ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_EXT,
+ ID_END}, /* 8 channels */
+ /* 8 */
+ {ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE}, /* reserved */
+ /* 9 */
+ {ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE}, /* reserved */
+ /* 10 */
+ {ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE}, /* reserved */
+ /* 11 */
+ {ID_SCE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_EXT,
+ ID_END}, /* 7 channels */
+ /* 12 */
+ {ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_EXT,
+ ID_END}, /* 8 channels */
+ /* 13 */
+ {ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE}, /* see elementsChCfg13 */
+ /* 14 */
+ {ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_CPE, ID_EXT,
+ ID_END} /* 8 channels */
+#endif
+};
+
+/*! Random sign bit used for concealment
+ */
+const USHORT AacDec_randomSign[AAC_NF_NO_RANDOM_VAL / 16] = {
+ /*
+ sign bits of FDK_sbrDecoder_sbr_randomPhase[] entries:
+ LSB ........... MSB -> MSB ... LSB
+ */
+ /* 1001 0111 0011 1100 -> */ 0x3ce9,
+ /* 0100 0111 0111 1011 -> */ 0xdee2,
+ /* 0001 1100 1110 1011 -> */ 0xd738,
+ /* 0001 0011 0110 1001 -> */ 0x96c8,
+ /* 0101 0011 1101 0000 -> */ 0x0bca,
+ /* 0001 0001 1111 0100 -> */ 0x2f88,
+ /* 1110 1100 1110 1101 -> */ 0xb737,
+ /* 0010 1010 1011 1001 -> */ 0x9d54,
+ /* 0111 1100 0110 1010 -> */ 0x563e,
+ /* 1101 0111 0010 0101 -> */ 0xa4eb,
+ /* 0001 0101 1011 1100 -> */ 0x3da8,
+ /* 0101 0111 1001 1011 -> */ 0xd9ea,
+ /* 1101 0100 0101 0101 -> */ 0xaa2b,
+ /* 1000 1001 0100 0011 -> */ 0xc291,
+ /* 1100 1111 1010 1100 -> */ 0x35f3,
+ /* 1100 1010 1110 0010 -> */ 0x4753,
+ /* 0110 0001 1010 1000 -> */ 0x1586,
+ /* 0011 0101 1111 1100 -> */ 0x3fac,
+ /* 0001 0110 1010 0001 -> */ 0x8568,
+ /* 0010 1101 0111 0010 -> */ 0x4eb4,
+ /* 1101 1010 0100 1001 -> */ 0x925b,
+ /* 1100 1001 0000 1110 -> */ 0x7093,
+ /* 1000 1100 0110 1010 -> */ 0x5631,
+ /* 0000 1000 0110 1101 -> */ 0xb610,
+ /* 1000 0001 1111 1011 -> */ 0xdf81,
+ /* 1111 0011 0100 0111 -> */ 0xe2cf,
+ /* 1000 0001 0010 1010 -> */ 0x5481,
+ /* 1101 0101 1100 1111 -> */ 0xf3ab,
+ /* 0110 0001 0110 1000 -> */ 0x1686,
+ /* 0011 0011 1100 0110 -> */ 0x63cc,
+ /* 0011 0111 0101 0110 -> */ 0x6aec,
+ /* 1011 0001 1010 0010 -> */ 0x458d};
+
+/* MDST filter coefficients for current window
+ * max: 0.635722 => 20 bits (unsigned) necessary for representation
+ * min: = -max */
+const FIXP_FILT mdst_filt_coef_curr[20][3] = {
+ {FILT(0.000000f), FILT(0.000000f), FILT(0.500000f)},
+ /*, FILT( 0.000000f), FILT(-0.500000f), FILT( 0.000000f), FILT( 0.000000f) }, */ /* only long / eight short l:sine r:sine */
+ {FILT(0.091497f), FILT(0.000000f), FILT(0.581427f)},
+ /*, FILT( 0.000000f), FILT(-0.581427f), FILT( 0.000000f), FILT(-0.091497f) }, */ /* l:kbd r:kbd */
+ {FILT(0.045748f), FILT(0.057238f), FILT(0.540714f)},
+ /*, FILT( 0.000000f), FILT(-0.540714f), FILT(-0.057238f), FILT(-0.045748f) }, */ /* l:sine r:kbd */
+ {FILT(0.045748f), FILT(-0.057238f), FILT(0.540714f)},
+ /*, FILT( 0.000000f), FILT(-0.540714f), FILT( 0.057238f), FILT(-0.045748f) }, */ /* l:kbd r:sine */
+
+ {FILT(0.102658f), FILT(0.103791f), FILT(0.567149f)},
+ /*, FILT( 0.000000f), FILT(-0.567149f), FILT(-0.103791f), FILT(-0.102658f) }, */ /* long start */
+ {FILT(0.150512f), FILT(0.047969f),
+ FILT(0.608574f)}, /*, FILT( 0.000000f), FILT(-0.608574f),
+ FILT(-0.047969f), FILT(-0.150512f) }, */
+ {FILT(0.104763f), FILT(0.105207f),
+ FILT(0.567861f)}, /*, FILT( 0.000000f), FILT(-0.567861f),
+ FILT(-0.105207f), FILT(-0.104763f) }, */
+ {FILT(0.148406f), FILT(0.046553f),
+ FILT(0.607863f)}, /*, FILT( 0.000000f), FILT(-0.607863f),
+ FILT(-0.046553f), FILT(-0.148406f) }, */
+
+ {FILT(0.102658f), FILT(-0.103791f), FILT(0.567149f)},
+ /*, FILT( 0.000000f), FILT(-0.567149f), FILT( 0.103791f), FILT(-0.102658f) }, */ /* long stop */
+ {FILT(0.150512f), FILT(-0.047969f),
+ FILT(0.608574f)}, /*, FILT( 0.000000f), FILT(-0.608574f), FILT(
+ 0.047969f), FILT(-0.150512f) }, */
+ {FILT(0.148406f), FILT(-0.046553f),
+ FILT(0.607863f)}, /*, FILT( 0.000000f), FILT(-0.607863f), FILT(
+ 0.046553f), FILT(-0.148406f) }, */
+ {FILT(0.104763f), FILT(-0.105207f),
+ FILT(0.567861f)}, /*, FILT( 0.000000f), FILT(-0.567861f), FILT(
+ 0.105207f), FILT(-0.104763f) }, */
+
+ {FILT(0.205316f), FILT(0.000000f), FILT(0.634298f)},
+ /*, FILT( 0.000000f), FILT(-0.634298f), FILT( 0.000000f), FILT(-0.205316f) }, */ /* stop start */
+ {FILT(0.209526f), FILT(0.000000f),
+ FILT(0.635722f)}, /*, FILT( 0.000000f), FILT(-0.635722f), FILT(
+ 0.000000f), FILT(-0.209526f) }, */
+ {FILT(0.207421f), FILT(0.001416f),
+ FILT(0.635010f)}, /*, FILT( 0.000000f), FILT(-0.635010f),
+ FILT(-0.001416f), FILT(-0.207421f) }, */
+ {FILT(0.207421f), FILT(-0.001416f),
+ FILT(0.635010f)}, /*, FILT( 0.000000f), FILT(-0.635010f), FILT(
+ 0.001416f), FILT(-0.207421f) } */
+
+ {FILT(0.185618f), FILT(0.000000f), FILT(0.627371f)},
+ /*, FILT( 0.000000f), FILT(-0.634298f), FILT( 0.000000f), FILT(-0.205316f) }, */ /* stop start Transform Splitting */
+ {FILT(0.204932f), FILT(0.000000f),
+ FILT(0.634159f)}, /*, FILT( 0.000000f), FILT(-0.635722f), FILT(
+ 0.000000f), FILT(-0.209526f) }, */
+ {FILT(0.194609f), FILT(0.006202f),
+ FILT(0.630536f)}, /*, FILT( 0.000000f), FILT(-0.635010f),
+ FILT(-0.001416f), FILT(-0.207421f) }, */
+ {FILT(0.194609f), FILT(-0.006202f),
+ FILT(0.630536f)}, /*, FILT( 0.000000f), FILT(-0.635010f), FILT(
+ 0.001416f), FILT(-0.207421f) } */
+};
+
+/* MDST filter coefficients for previous window
+ * max: 0.31831 => 15 bits (unsigned) necessary for representation
+ * min: 0.0 */
+const FIXP_FILT mdst_filt_coef_prev[6][4] = {
+ {FILT(0.000000f), FILT(0.106103f), FILT(0.250000f), FILT(0.318310f)},
+ /*, FILT( 0.250000f), FILT( 0.106103f), FILT( 0.000000f) }, */ /* only long
+ / long
+ start /
+ eight
+ short
+ l:sine */
+ {FILT(0.059509f), FILT(0.123714f), FILT(0.186579f), FILT(0.213077f)},
+ /*, FILT( 0.186579f), FILT( 0.123714f), FILT( 0.059509f) }, */ /* l:kbd
+ */
+
+ {FILT(0.038498f), FILT(0.039212f), FILT(0.039645f), FILT(0.039790f)},
+ /*, FILT( 0.039645f), FILT( 0.039212f), FILT( 0.038498f) }, */ /* long stop
+ / stop
+ start
+ l:sine */
+ {FILT(0.026142f), FILT(0.026413f), FILT(0.026577f), FILT(0.026631f)},
+ /*, FILT( 0.026577f), FILT( 0.026413f), FILT( 0.026142f) } */ /* l:kbd
+ */
+
+ {FILT(0.069608f), FILT(0.075028f), FILT(0.078423f), FILT(0.079580f)},
+ /*, FILT( 0.039645f), FILT( 0.039212f), FILT( 0.038498f) }, */ /* Transform
+ splitting
+ l:sine */
+ {FILT(0.042172f), FILT(0.043458f), FILT(0.044248f), FILT(0.044514f)},
+ /*, FILT( 0.026577f), FILT( 0.026413f), FILT( 0.026142f) } */ /* l:kbd
+ */
+};
diff --git a/fdk-aac/libAACdec/src/aac_rom.h b/fdk-aac/libAACdec/src/aac_rom.h
new file mode 100644
index 0000000..ffaf951
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aac_rom.h
@@ -0,0 +1,237 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: Definition of constant tables
+
+*******************************************************************************/
+
+#ifndef AAC_ROM_H
+#define AAC_ROM_H
+
+#include "common_fix.h"
+#include "FDK_audio.h"
+#include "aacdec_hcr_types.h"
+#include "aacdec_hcrs.h"
+
+#define PCM_DEC FIXP_DBL
+#define MAXVAL_PCM_DEC MAXVAL_DBL
+#define MINVAL_PCM_DEC MINVAL_DBL
+#define FIXP_DBL2PCM_DEC(x) (x)
+#define PCM_DEC2FIXP_DBL(x) (x)
+#define PCM_DEC_BITS DFRACT_BITS
+#define PCM_DEC2FX_PCM(x) FX_DBL2FX_PCM(x)
+#define FX_PCM2PCM_DEC(x) FX_PCM2FX_DBL(x)
+
+#define AACDEC_MAX_CH_CONF 14
+#define AACDEC_CH_ELEMENTS_TAB_SIZE 7 /*!< Size of element tables */
+
+#define AAC_NF_NO_RANDOM_VAL \
+ 512 /*!< Size of random number array for noise floor */
+
+#define INV_QUANT_TABLESIZE 256
+
+extern const FIXP_DBL InverseQuantTable[INV_QUANT_TABLESIZE + 1];
+extern const FIXP_DBL MantissaTable[4][14];
+extern const SCHAR ExponentTable[4][14];
+
+#define NUM_LD_COEF_512 1536
+#define NUM_LD_COEF_480 1440
+/* Window table partition exponents. */
+#define WTS0 (1)
+#define WTS1 (0)
+#define WTS2 (-2)
+extern const FIXP_WTB LowDelaySynthesis512[1536];
+extern const FIXP_WTB LowDelaySynthesis480[1440];
+extern const FIXP_WTB LowDelaySynthesis256[768];
+extern const FIXP_WTB LowDelaySynthesis240[720];
+extern const FIXP_WTB LowDelaySynthesis160[480];
+extern const FIXP_WTB LowDelaySynthesis128[384];
+extern const FIXP_WTB LowDelaySynthesis120[360];
+
+typedef struct {
+ const SHORT *sfbOffsetLong;
+ const SHORT *sfbOffsetShort;
+ UCHAR numberOfSfbLong;
+ UCHAR numberOfSfbShort;
+} SFB_INFO;
+
+extern const SFB_INFO sfbOffsetTables[5][16];
+
+/* Huffman tables */
+enum { HuffmanBits = 2, HuffmanEntries = (1 << HuffmanBits) };
+
+typedef struct {
+ const USHORT (*CodeBook)[HuffmanEntries];
+ UCHAR Dimension;
+ UCHAR numBits;
+ UCHAR Offset;
+} CodeBookDescription;
+
+extern const CodeBookDescription AACcodeBookDescriptionTable[13];
+extern const CodeBookDescription AACcodeBookDescriptionSCL;
+
+extern const STATEFUNC aStateConstant2State[];
+
+extern const SCHAR aCodebook2StartInt[];
+
+extern const UCHAR aMinOfCbPair[];
+extern const UCHAR aMaxOfCbPair[];
+
+extern const UCHAR aMaxCwLen[];
+extern const UCHAR aDimCb[];
+extern const UCHAR aDimCbShift[];
+extern const UCHAR aSignCb[];
+extern const UCHAR aCbPriority[];
+
+extern const UINT *aHuffTable[];
+extern const SCHAR *aQuantTable[];
+
+extern const USHORT aLargestAbsoluteValue[];
+
+extern const UINT aHuffTreeRvlcEscape[];
+extern const UINT aHuffTreeRvlCodewds[];
+
+extern const UCHAR tns_max_bands_tbl[13][2];
+
+extern const UCHAR tns_max_bands_tbl_480[13];
+extern const UCHAR tns_max_bands_tbl_512[13];
+
+#define FIXP_TCC FIXP_DBL
+
+extern const FIXP_TCC FDKaacDec_tnsCoeff3[8];
+extern const FIXP_TCC FDKaacDec_tnsCoeff4[16];
+
+extern const UCHAR FDKaacDec_tnsCoeff3_gain_ld[];
+extern const UCHAR FDKaacDec_tnsCoeff4_gain_ld[];
+
+extern const USHORT AacDec_randomSign[AAC_NF_NO_RANDOM_VAL / 16];
+
+extern const FIXP_DBL pow2_div24minus1[47];
+extern const int offsetTab[2][16];
+
+/* Channel mapping indices for time domain I/O.
+ The first dimension is the channel configuration index. */
+extern const UCHAR channelMappingTablePassthrough[15][8];
+extern const UCHAR channelMappingTableWAV[15][8];
+
+/* Lookup tables for elements in ER bitstream */
+extern const MP4_ELEMENT_ID elementsTab[AACDEC_MAX_CH_CONF]
+ [AACDEC_CH_ELEMENTS_TAB_SIZE];
+
+#define SF_FNA_COEFFS \
+ 1 /* Compile-time prescaler for MDST-filter coefficients. */
+/* SF_FNA_COEFFS > 0 should only be considered for FIXP_DBL-coefficients */
+/* (i.e. if CPLX_PRED_FILTER_16BIT is not defined). */
+/* With FIXP_DBL loss of precision is possible for SF_FNA_COEFFS > 11. */
+
+#ifdef CPLX_PRED_FILTER_16BIT
+#define FIXP_FILT FIXP_SGL
+#define FILT(a) ((FL2FXCONST_SGL(a)) >> SF_FNA_COEFFS)
+#else
+#define FIXP_FILT FIXP_DBL
+#define FILT(a) ((FL2FXCONST_DBL(a)) >> SF_FNA_COEFFS)
+#endif
+
+extern const FIXP_FILT mdst_filt_coef_curr[20][3]; /* MDST-filter coefficient
+ tables used for current
+ window */
+extern const FIXP_FILT mdst_filt_coef_prev[6][4]; /* MDST-filter coefficient
+ tables used for previous
+ window */
+
+#endif /* #ifndef AAC_ROM_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_drc.cpp b/fdk-aac/libAACdec/src/aacdec_drc.cpp
new file mode 100644
index 0000000..922a09e
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_drc.cpp
@@ -0,0 +1,1355 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Christian Griebel
+
+ Description: Dynamic range control (DRC) decoder tool for AAC
+
+*******************************************************************************/
+
+#include "aacdec_drc.h"
+
+#include "channelinfo.h"
+#include "aac_rom.h"
+
+#include "sbrdecoder.h"
+
+/*
+ * Dynamic Range Control
+ */
+
+/* For parameter conversion */
+#define DRC_PARAMETER_BITS (7)
+#define DRC_MAX_QUANT_STEPS (1 << DRC_PARAMETER_BITS)
+#define DRC_MAX_QUANT_FACTOR (DRC_MAX_QUANT_STEPS - 1)
+#define DRC_PARAM_QUANT_STEP \
+ (FL2FXCONST_DBL(1.0f / (float)DRC_MAX_QUANT_FACTOR))
+#define DRC_PARAM_SCALE (1)
+#define DRC_SCALING_MAX \
+ ((FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)127))
+
+#define DRC_BLOCK_LEN (1024)
+#define DRC_BAND_MULT (4)
+#define DRC_BLOCK_LEN_DIV_BAND_MULT (DRC_BLOCK_LEN / DRC_BAND_MULT)
+
+#define MAX_REFERENCE_LEVEL (127)
+
+#define DRC_HEAVY_THRESHOLD_DB (10)
+
+#define DVB_ANC_DATA_SYNC_BYTE (0xBC) /* DVB ancillary data sync byte. */
+
+#define OFF 0
+#define ON 1
+
+static INT convert_drcParam(FIXP_DBL param_dbl) {
+ /* converts an internal DRC boost/cut scaling factor in FIXP_DBL
+ (which is downscaled by DRC_PARAM_SCALE)
+ back to an integer value between 0 and 127. */
+ LONG param_long;
+
+ param_long = (LONG)param_dbl >> 7;
+ param_long = param_long * (INT)DRC_MAX_QUANT_FACTOR;
+ param_long >>= 31 - 7 - DRC_PARAM_SCALE - 1;
+ param_long += 1; /* for rounding */
+ param_long >>= 1;
+
+ return (INT)param_long;
+}
+
+/*!
+ \brief Initialize DRC information
+
+ \self Handle of DRC info
+
+ \return none
+*/
+void aacDecoder_drcInit(HANDLE_AAC_DRC self) {
+ CDrcParams *pParams;
+
+ if (self == NULL) {
+ return;
+ }
+
+ /* init control fields */
+ self->enable = OFF;
+ self->numThreads = 0;
+
+ /* init params */
+ pParams = &self->params;
+ pParams->bsDelayEnable = 0;
+ pParams->cut = FL2FXCONST_DBL(0.0f);
+ pParams->usrCut = FL2FXCONST_DBL(0.0f);
+ pParams->boost = FL2FXCONST_DBL(0.0f);
+ pParams->usrBoost = FL2FXCONST_DBL(0.0f);
+ pParams->targetRefLevel = -1;
+ pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;
+ pParams->applyDigitalNorm = OFF;
+ pParams->applyHeavyCompression = OFF;
+ pParams->usrApplyHeavyCompression = OFF;
+
+ pParams->defaultPresentationMode = DISABLED_PARAMETER_HANDLING;
+ pParams->encoderTargetLevel = MAX_REFERENCE_LEVEL; /* worst case assumption */
+
+ self->update = 1;
+ self->numOutChannels = 0;
+ self->prevAacNumChannels = 0;
+
+ /* initial program ref level = target ref level */
+ self->progRefLevel = pParams->targetRefLevel;
+ self->progRefLevelPresent = 0;
+ self->presMode = -1;
+ self->uniDrcPrecedence = 0;
+}
+
+/*!
+ \brief Initialize DRC control data for one channel
+
+ \self Handle of DRC info
+
+ \return none
+*/
+void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChData) {
+ if (pDrcChData != NULL) {
+ pDrcChData->expiryCount = 0;
+ pDrcChData->numBands = 1;
+ pDrcChData->bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
+ pDrcChData->drcValue[0] = 0;
+ pDrcChData->drcInterpolationScheme = 0;
+ pDrcChData->drcDataType = UNKNOWN_PAYLOAD;
+ }
+}
+
+/*!
+ \brief Set one single DRC parameter
+
+ \self Handle of DRC info.
+ \param Parameter to be set.
+ \value Value to be set.
+
+ \return an error code.
+*/
+AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
+ AACDEC_DRC_PARAM param, INT value) {
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ switch (param) {
+ case DRC_CUT_SCALE:
+ /* set attenuation scale factor */
+ if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.usrCut = (FIXP_DBL)(
+ (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value);
+ self->update = 1;
+ break;
+ case DRC_BOOST_SCALE:
+ /* set boost factor */
+ if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.usrBoost = (FIXP_DBL)(
+ (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value);
+ self->update = 1;
+ break;
+ case TARGET_REF_LEVEL:
+ if (value > MAX_REFERENCE_LEVEL || value < -MAX_REFERENCE_LEVEL) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ if (value < 0) {
+ self->params.applyDigitalNorm = OFF;
+ self->params.targetRefLevel = -1;
+ } else {
+ /* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */
+ self->params.applyDigitalNorm = ON;
+ if (self->params.targetRefLevel != (SCHAR)value) {
+ self->params.targetRefLevel = (SCHAR)value;
+ self->progRefLevel = (SCHAR)value; /* Always set the program reference
+ level equal to the target level
+ according to 4.5.2.7.3 of
+ ISO/IEC 14496-3. */
+ }
+ self->update = 1;
+ }
+ break;
+ case APPLY_NORMALIZATION:
+ if ((value != OFF) && (value != ON)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ /* Store new parameter value */
+ self->params.applyDigitalNorm = (UCHAR)value;
+ break;
+ case APPLY_HEAVY_COMPRESSION:
+ if ((value != OFF) && (value != ON)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ /* Store new parameter value */
+ self->params.usrApplyHeavyCompression = (UCHAR)value;
+ self->update = 1;
+ break;
+ case DEFAULT_PRESENTATION_MODE:
+ if (value < AAC_DRC_PARAMETER_HANDLING_DISABLED ||
+ value > AAC_DRC_PRESENTATION_MODE_2_DEFAULT) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.defaultPresentationMode =
+ (AACDEC_DRC_PARAMETER_HANDLING)value;
+ self->update = 1;
+ break;
+ case ENCODER_TARGET_LEVEL:
+ if (value > MAX_REFERENCE_LEVEL || value < 0) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.encoderTargetLevel = (UCHAR)value;
+ self->update = 1;
+ break;
+ case DRC_BS_DELAY:
+ if (value < 0 || value > 1) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.bsDelayEnable = value;
+ break;
+ case DRC_DATA_EXPIRY_FRAME:
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.expiryFrame = (value > 0) ? (UINT)value : 0;
+ break;
+ case MAX_OUTPUT_CHANNELS:
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->numOutChannels = (INT)value;
+ self->update = 1;
+ break;
+ case UNIDRC_PRECEDENCE:
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->uniDrcPrecedence = (UCHAR)value;
+ break;
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ } /* switch(param) */
+
+ return ErrorStatus;
+}
+
+static int parseExcludedChannels(UINT *excludedChnsMask,
+ HANDLE_FDK_BITSTREAM bs) {
+ UINT excludeMask = 0;
+ UINT i, j;
+ int bitCnt = 9;
+
+ for (i = 0, j = 1; i < 7; i++, j <<= 1) {
+ if (FDKreadBits(bs, 1)) {
+ excludeMask |= j;
+ }
+ }
+
+ /* additional_excluded_chns */
+ while (FDKreadBits(bs, 1)) {
+ for (i = 0; i < 7; i++, j <<= 1) {
+ if (FDKreadBits(bs, 1)) {
+ excludeMask |= j;
+ }
+ }
+ bitCnt += 9;
+ FDK_ASSERT(j < (UINT)-1);
+ }
+
+ *excludedChnsMask = excludeMask;
+
+ return (bitCnt);
+}
+
+/*!
+ \brief Save DRC payload bitstream position
+
+ \self Handle of DRC info
+ \bs Handle of FDK bitstream
+
+ \return The number of DRC payload bits
+*/
+int aacDecoder_drcMarkPayload(HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM bs,
+ AACDEC_DRC_PAYLOAD_TYPE type) {
+ UINT bsStartPos;
+ int i, numBands = 1, bitCnt = 0;
+
+ if (self == NULL) {
+ return 0;
+ }
+
+ bsStartPos = FDKgetValidBits(bs);
+
+ switch (type) {
+ case MPEG_DRC_EXT_DATA: {
+ bitCnt = 4;
+
+ if (FDKreadBits(bs, 1)) { /* pce_tag_present */
+ FDKreadBits(bs, 8); /* pce_instance_tag + drc_tag_reserved_bits */
+ bitCnt += 8;
+ }
+
+ if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
+ FDKreadBits(bs, 7); /* exclude mask [0..7] */
+ bitCnt += 8;
+ while (FDKreadBits(bs, 1)) { /* additional_excluded_chns */
+ FDKreadBits(bs, 7); /* exclude mask [x..y] */
+ bitCnt += 8;
+ }
+ }
+
+ if (FDKreadBits(bs, 1)) { /* drc_bands_present */
+ numBands += FDKreadBits(bs, 4); /* drc_band_incr */
+ FDKreadBits(bs, 4); /* reserved */
+ bitCnt += 8;
+ for (i = 0; i < numBands; i++) {
+ FDKreadBits(bs, 8); /* drc_band_top[i] */
+ bitCnt += 8;
+ }
+ }
+
+ if (FDKreadBits(bs, 1)) { /* prog_ref_level_present */
+ FDKreadBits(bs, 8); /* prog_ref_level + prog_ref_level_reserved_bits */
+ bitCnt += 8;
+ }
+
+ for (i = 0; i < numBands; i++) {
+ FDKreadBits(bs, 8); /* dyn_rng_sgn[i] + dyn_rng_ctl[i] */
+ bitCnt += 8;
+ }
+
+ if ((self->numPayloads < MAX_DRC_THREADS) &&
+ ((INT)FDKgetValidBits(bs) >= 0)) {
+ self->drcPayloadPosition[self->numPayloads++] = bsStartPos;
+ }
+ } break;
+
+ case DVB_DRC_ANC_DATA:
+ bitCnt += 8;
+ /* check sync word */
+ if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE) {
+ int dmxLevelsPresent, compressionPresent;
+ int coarseGrainTcPresent, fineGrainTcPresent;
+
+ /* bs_info field */
+ FDKreadBits(
+ bs,
+ 8); /* mpeg_audio_type, dolby_surround_mode, presentation_mode */
+ bitCnt += 8;
+
+ /* Evaluate ancillary_data_status */
+ FDKreadBits(bs, 3); /* reserved, set to 0 */
+ dmxLevelsPresent =
+ FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
+ FDKreadBits(bs, 1); /* reserved, set to 0 */
+ compressionPresent =
+ FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
+ coarseGrainTcPresent =
+ FDKreadBits(bs, 1); /* coarse_grain_timecode_status */
+ fineGrainTcPresent =
+ FDKreadBits(bs, 1); /* fine_grain_timecode_status */
+ bitCnt += 8;
+
+ /* MPEG4 downmixing levels */
+ if (dmxLevelsPresent) {
+ FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
+ bitCnt += 8;
+ }
+ /* audio coding mode and compression status */
+ if (compressionPresent) {
+ FDKreadBits(bs, 16); /* audio_coding_mode, Compression_value */
+ bitCnt += 16;
+ }
+ /* coarse grain timecode */
+ if (coarseGrainTcPresent) {
+ FDKreadBits(bs, 16); /* coarse_grain_timecode */
+ bitCnt += 16;
+ }
+ /* fine grain timecode */
+ if (fineGrainTcPresent) {
+ FDKreadBits(bs, 16); /* fine_grain_timecode */
+ bitCnt += 16;
+ }
+ if (!self->dvbAncDataAvailable && ((INT)FDKgetValidBits(bs) >= 0)) {
+ self->dvbAncDataPosition = bsStartPos;
+ self->dvbAncDataAvailable = 1;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return (bitCnt);
+}
+
+/*!
+ \brief Parse DRC parameters from bitstream
+
+ \bs Handle of FDK bitstream (in)
+ \pDrcBs Pointer to DRC payload data container (out)
+ \payloadPosition Bitstream position of MPEG DRC data chunk (in)
+
+ \return Flag telling whether new DRC data has been found or not.
+*/
+static int aacDecoder_drcParse(HANDLE_FDK_BITSTREAM bs, CDrcPayload *pDrcBs,
+ UINT payloadPosition) {
+ int i, numBands;
+
+ /* Move to the beginning of the DRC payload field */
+ FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);
+
+ /* pce_tag_present */
+ if (FDKreadBits(bs, 1)) {
+ pDrcBs->pceInstanceTag = FDKreadBits(bs, 4); /* pce_instance_tag */
+ /* only one program supported */
+ FDKreadBits(bs, 4); /* drc_tag_reserved_bits */
+ } else {
+ pDrcBs->pceInstanceTag = -1; /* not present */
+ }
+
+ if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
+ /* get excluded_chn_mask */
+ parseExcludedChannels(&pDrcBs->excludedChnsMask, bs);
+ } else {
+ pDrcBs->excludedChnsMask = 0;
+ }
+
+ numBands = 1;
+ if (FDKreadBits(bs, 1)) /* drc_bands_present */
+ {
+ /* get band_incr */
+ numBands += FDKreadBits(bs, 4); /* drc_band_incr */
+ pDrcBs->channelData.drcInterpolationScheme =
+ FDKreadBits(bs, 4); /* drc_interpolation_scheme */
+ /* band_top */
+ for (i = 0; i < numBands; i++) {
+ pDrcBs->channelData.bandTop[i] = FDKreadBits(bs, 8); /* drc_band_top[i] */
+ }
+ } else {
+ pDrcBs->channelData.bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT -
+ 1; /* ... comprising the whole spectrum. */
+ ;
+ }
+
+ pDrcBs->channelData.numBands = numBands;
+
+ if (FDKreadBits(bs, 1)) /* prog_ref_level_present */
+ {
+ pDrcBs->progRefLevel = FDKreadBits(bs, 7); /* prog_ref_level */
+ FDKreadBits(bs, 1); /* prog_ref_level_reserved_bits */
+ } else {
+ pDrcBs->progRefLevel = -1;
+ }
+
+ for (i = 0; i < numBands; i++) {
+ pDrcBs->channelData.drcValue[i] = FDKreadBits(bs, 1)
+ << 7; /* dyn_rng_sgn[i] */
+ pDrcBs->channelData.drcValue[i] |=
+ FDKreadBits(bs, 7) & 0x7F; /* dyn_rng_ctl[i] */
+ }
+
+ /* Set DRC payload type */
+ pDrcBs->channelData.drcDataType = MPEG_DRC_EXT_DATA;
+
+ return (1);
+}
+
+/*!
+ \brief Parse heavy compression value transported in DSEs of DVB streams with
+ MPEG-4 content.
+
+ \bs Handle of FDK bitstream (in)
+ \pDrcBs Pointer to DRC payload data container (out)
+ \payloadPosition Bitstream position of DVB ancillary data chunk
+
+ \return Flag telling whether new DRC data has been found or not.
+*/
+#define DVB_COMPRESSION_SCALE (8) /* 48,164 dB */
+
+static int aacDecoder_drcReadCompression(HANDLE_FDK_BITSTREAM bs,
+ CDrcPayload *pDrcBs,
+ UINT payloadPosition) {
+ int foundDrcData = 0;
+ int dmxLevelsPresent, compressionPresent;
+
+ /* Move to the beginning of the DRC payload field */
+ FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);
+
+ /* Sanity checks */
+ if (FDKgetValidBits(bs) < 24) {
+ return 0;
+ }
+
+ /* Check sync word */
+ if (FDKreadBits(bs, 8) != DVB_ANC_DATA_SYNC_BYTE) {
+ return 0;
+ }
+
+ /* Evaluate bs_info field */
+ if (FDKreadBits(bs, 2) != 3) { /* mpeg_audio_type */
+ /* No MPEG-4 audio data */
+ return 0;
+ }
+ FDKreadBits(bs, 2); /* dolby_surround_mode */
+ pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */
+ FDKreadBits(bs, 1); /* stereo_downmix_mode */
+ if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */
+ return 0;
+ }
+
+ /* Evaluate ancillary_data_status */
+ if (FDKreadBits(bs, 3) != 0) { /* reserved, set to 0 */
+ return 0;
+ }
+ dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
+ /*extensionPresent =*/FDKreadBits(bs,
+ 1); /* ancillary_data_extension_status; */
+ compressionPresent =
+ FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
+ /*coarseGrainTcPresent =*/FDKreadBits(bs,
+ 1); /* coarse_grain_timecode_status */
+ /*fineGrainTcPresent =*/FDKreadBits(bs, 1); /* fine_grain_timecode_status */
+
+ if (dmxLevelsPresent) {
+ FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
+ }
+
+ /* audio_coding_mode_and_compression_status */
+ if (compressionPresent) {
+ UCHAR compressionOn, compressionValue;
+
+ /* audio_coding_mode */
+ if (FDKreadBits(bs, 7) != 0) { /* The reserved bits shall be set to "0". */
+ return 0;
+ }
+ compressionOn = (UCHAR)FDKreadBits(bs, 1); /* compression_on */
+ compressionValue = (UCHAR)FDKreadBits(bs, 8); /* Compression_value */
+
+ if (compressionOn) {
+ /* A compression value is available so store the data just like MPEG DRC
+ * data */
+ pDrcBs->channelData.numBands = 1; /* One band ... */
+ pDrcBs->channelData.drcValue[0] =
+ compressionValue; /* ... with one value ... */
+ pDrcBs->channelData.bandTop[0] =
+ DRC_BLOCK_LEN_DIV_BAND_MULT -
+ 1; /* ... comprising the whole spectrum. */
+ ;
+ pDrcBs->pceInstanceTag = -1; /* Not present */
+ pDrcBs->progRefLevel = -1; /* Not present */
+ pDrcBs->channelData.drcDataType =
+ DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */
+ foundDrcData = 1;
+ }
+ }
+
+ return (foundDrcData);
+}
+
+/*
+ * Extract DRC payload from bitstream and map it to channels.
+ * Valid return values are:
+ * -1 : An unexpected error occured.
+ * 0 : No error and no valid DRC data available.
+ * 1 : No error and valid DRC data has been mapped.
+ */
+static int aacDecoder_drcExtractAndMap(
+ HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ UCHAR pceInstanceTag,
+ UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
+ canonical channel index */
+ int validChannels) {
+ CDrcPayload threadBs[MAX_DRC_THREADS];
+ CDrcPayload *validThreadBs[MAX_DRC_THREADS];
+ CDrcParams *pParams;
+ UINT backupBsPosition;
+ int result = 0;
+ int i, thread, validThreads = 0;
+
+ FDK_ASSERT(self != NULL);
+ FDK_ASSERT(hBs != NULL);
+ FDK_ASSERT(pAacDecoderStaticChannelInfo != NULL);
+
+ pParams = &self->params;
+
+ self->numThreads = 0;
+ backupBsPosition = FDKgetValidBits(hBs);
+
+ for (i = 0; i < self->numPayloads && self->numThreads < MAX_DRC_THREADS;
+ i++) {
+ /* Init payload data chunk. The memclear is very important because it
+ initializes the most values. Without it the module wouldn't work properly
+ or crash. */
+ FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
+ threadBs[self->numThreads].channelData.bandTop[0] =
+ DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
+
+ /* Extract payload */
+ self->numThreads += aacDecoder_drcParse(hBs, &threadBs[self->numThreads],
+ self->drcPayloadPosition[i]);
+ }
+ self->numPayloads = 0;
+
+ if (self->dvbAncDataAvailable &&
+ self->numThreads < MAX_DRC_THREADS) { /* Append a DVB heavy compression
+ payload thread if available. */
+
+ /* Init payload data chunk. The memclear is very important because it
+ initializes the most values. Without it the module wouldn't work properly
+ or crash. */
+ FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
+ threadBs[self->numThreads].channelData.bandTop[0] =
+ DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
+
+ /* Extract payload */
+ self->numThreads += aacDecoder_drcReadCompression(
+ hBs, &threadBs[self->numThreads], self->dvbAncDataPosition);
+ }
+ self->dvbAncDataAvailable = 0;
+
+ /* Reset the bitbufffer */
+ FDKpushBiDirectional(hBs, (INT)FDKgetValidBits(hBs) - (INT)backupBsPosition);
+
+ /* calculate number of valid bits in excl_chn_mask */
+
+ /* coupling channels not supported */
+
+ /* check for valid threads */
+ for (thread = 0; thread < self->numThreads; thread++) {
+ CDrcPayload *pThreadBs = &threadBs[thread];
+ int numExclChns = 0;
+
+ switch ((AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType) {
+ default:
+ continue;
+ case MPEG_DRC_EXT_DATA:
+ case DVB_DRC_ANC_DATA:
+ break;
+ }
+
+ if (pThreadBs->pceInstanceTag >= 0) { /* if PCE tag present */
+ if (pThreadBs->pceInstanceTag != pceInstanceTag) {
+ continue; /* don't accept */
+ }
+ }
+
+ /* calculate number of excluded channels */
+ if (pThreadBs->excludedChnsMask > 0) {
+ INT exclMask = pThreadBs->excludedChnsMask;
+ int ch;
+ for (ch = 0; ch < validChannels; ch++) {
+ numExclChns += exclMask & 0x1;
+ exclMask >>= 1;
+ }
+ }
+ if (numExclChns < validChannels) {
+ validThreadBs[validThreads] = pThreadBs;
+ validThreads++;
+ }
+ }
+
+ /* map DRC bitstream information onto DRC channel information */
+ for (thread = 0; thread < validThreads; thread++) {
+ CDrcPayload *pThreadBs = validThreadBs[thread];
+ INT exclMask = pThreadBs->excludedChnsMask;
+ AACDEC_DRC_PAYLOAD_TYPE drcPayloadType =
+ (AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType;
+ int ch;
+
+ /* last progRefLevel transmitted is the one that is used
+ * (but it should really only be transmitted once per block!)
+ */
+ if (pThreadBs->progRefLevel >= 0) {
+ self->progRefLevel = pThreadBs->progRefLevel;
+ self->progRefLevelPresent = 1;
+ self->prlExpiryCount = 0; /* Got a new value -> Reset counter */
+ }
+
+ if (drcPayloadType == DVB_DRC_ANC_DATA) {
+ /* Announce the presentation mode of this valid thread. */
+ self->presMode = pThreadBs->presMode;
+ }
+
+ /* SCE, CPE and LFE */
+ for (ch = 0; ch < validChannels; ch++) {
+ AACDEC_DRC_PAYLOAD_TYPE prvPayloadType = UNKNOWN_PAYLOAD;
+ int mapedChannel = channelMapping[ch];
+
+ if ((mapedChannel >= validChannels) ||
+ ((exclMask & (1 << mapedChannel)) != 0))
+ continue;
+
+ if ((pParams->expiryFrame <= 0) ||
+ (pAacDecoderStaticChannelInfo[ch]->drcData.expiryCount <
+ pParams->expiryFrame)) {
+ prvPayloadType =
+ (AACDEC_DRC_PAYLOAD_TYPE)pAacDecoderStaticChannelInfo[ch]
+ ->drcData.drcDataType;
+ }
+ if (((drcPayloadType == MPEG_DRC_EXT_DATA) &&
+ (prvPayloadType != DVB_DRC_ANC_DATA)) ||
+ ((drcPayloadType == DVB_DRC_ANC_DATA) &&
+ (pParams->applyHeavyCompression ==
+ ON))) { /* copy thread to channel */
+ pAacDecoderStaticChannelInfo[ch]->drcData = pThreadBs->channelData;
+ result = 1;
+ }
+ }
+ /* CCEs not supported by now */
+ }
+
+ /* Increment and check expiry counter for the program reference level: */
+ if ((pParams->expiryFrame > 0) &&
+ (self->prlExpiryCount++ >
+ pParams->expiryFrame)) { /* The program reference level is too old, so
+ set it back to the target level. */
+ self->progRefLevelPresent = 0;
+ self->progRefLevel = pParams->targetRefLevel;
+ self->prlExpiryCount = 0;
+ }
+
+ return result;
+}
+
+void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CDrcChannelData *pDrcChData, FIXP_DBL *extGain,
+ int ch, /* needed only for SBR */
+ int aacFrameSize, int bSbrPresent) {
+ int band, bin, numBands;
+ int bottom = 0;
+ int modifyBins = 0;
+
+ FIXP_DBL max_mantissa;
+ INT max_exponent;
+
+ FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.5f);
+ INT norm_exponent = 1;
+
+ FIXP_DBL fact_mantissa[MAX_DRC_BANDS];
+ INT fact_exponent[MAX_DRC_BANDS];
+
+ CDrcParams *pParams = &self->params;
+
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+ SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
+
+ int winSeq = pIcsInfo->WindowSequence;
+
+ /* Increment and check expiry counter */
+ if ((pParams->expiryFrame > 0) &&
+ (++pDrcChData->expiryCount >
+ pParams->expiryFrame)) { /* The DRC data is too old, so delete it. */
+ aacDecoder_drcInitChannelData(pDrcChData);
+ }
+
+ if (self->enable != ON) {
+ sbrDecoder_drcDisable((HANDLE_SBRDECODER)pSbrDec, ch);
+ if (extGain != NULL) {
+ INT gainScale = (INT)*extGain;
+ /* The gain scaling must be passed to the function in the buffer pointed
+ * on by extGain. */
+ if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
+ *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
+ } else {
+ FDK_ASSERT(0);
+ }
+ }
+ return;
+ }
+
+ numBands = pDrcChData->numBands;
+
+ /* If program reference normalization is done in the digital domain,
+ modify factor to perform normalization. prog_ref_level can
+ alternatively be passed to the system for modification of the level in
+ the analog domain. Analog level modification avoids problems with
+ reduced DAC SNR (if signal is attenuated) or clipping (if signal is
+ boosted) */
+
+ if (pParams->targetRefLevel >= 0) {
+ /* 0.5^((targetRefLevel - progRefLevel)/24) */
+ norm_mantissa =
+ fLdPow(FL2FXCONST_DBL(-1.0), /* log2(0.5) */
+ 0,
+ (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0f / 24.0) >> 3) *
+ (INT)(pParams->targetRefLevel - self->progRefLevel)),
+ 3, &norm_exponent);
+ }
+ /* Always export the normalization gain (if possible). */
+ if (extGain != NULL) {
+ INT gainScale = (INT)*extGain;
+ /* The gain scaling must be passed to the function in the buffer pointed on
+ * by extGain. */
+ if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
+ *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
+ } else {
+ FDK_ASSERT(0);
+ }
+ }
+ if (self->params.applyDigitalNorm == OFF) {
+ /* Reset normalization gain since this module must not apply it */
+ norm_mantissa = FL2FXCONST_DBL(0.5f);
+ norm_exponent = 1;
+ }
+
+ /* calc scale factors */
+ for (band = 0; band < numBands; band++) {
+ UCHAR drcVal = pDrcChData->drcValue[band];
+
+ fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
+ fact_exponent[band] = 1;
+
+ if ((pParams->applyHeavyCompression == ON) &&
+ ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
+ DVB_DRC_ANC_DATA)) {
+ INT compressionFactorVal_e;
+ int valX, valY;
+
+ valX = drcVal >> 4;
+ valY = drcVal & 0x0F;
+
+ /* calculate the unscaled heavy compression factor.
+ compressionFactor = 48.164 - 6.0206*valX - 0.4014*valY dB
+ range: -48.166 dB to 48.164 dB */
+ if (drcVal != 0x7F) {
+ fact_mantissa[band] = fPowInt(
+ FL2FXCONST_DBL(0.95483867181), /* -0.4014dB = 0.95483867181 */
+ 0, valY, &compressionFactorVal_e);
+
+ /* -0.0008dB (48.164 - 6.0206*8 = -0.0008) */
+ fact_mantissa[band] =
+ fMult(FL2FXCONST_DBL(0.99990790084), fact_mantissa[band]);
+
+ fact_exponent[band] =
+ DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e;
+ }
+ } else if ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
+ MPEG_DRC_EXT_DATA) {
+ /* apply the scaled dynamic range control words to factor.
+ * if scaling drc_cut (or drc_boost), or control word drc_mantissa is 0
+ * then there is no dynamic range compression
+ *
+ * if pDrcChData->drcSgn[band] is
+ * 1 then gain is < 1 : factor = 2^(-self->cut *
+ * pDrcChData->drcMag[band] / 24) 0 then gain is > 1 : factor = 2^(
+ * self->boost * pDrcChData->drcMag[band] / 24)
+ */
+
+ if ((drcVal & 0x7F) > 0) {
+ FIXP_DBL tParamVal = (drcVal & 0x80) ? -pParams->cut : pParams->boost;
+
+ fact_mantissa[band] = f2Pow(
+ (FIXP_DBL)((INT)fMult(FL2FXCONST_DBL(1.0f / 192.0f), tParamVal) *
+ (drcVal & 0x7F)),
+ 3 + DRC_PARAM_SCALE, &fact_exponent[band]);
+ }
+ }
+
+ fact_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa);
+ fact_exponent[band] += norm_exponent;
+
+ } /* end loop over bands */
+
+ /* normalizations */
+ {
+ int res;
+
+ max_mantissa = FL2FXCONST_DBL(0.0f);
+ max_exponent = 0;
+ for (band = 0; band < numBands; band++) {
+ max_mantissa = fixMax(max_mantissa, fact_mantissa[band]);
+ max_exponent = fixMax(max_exponent, fact_exponent[band]);
+ }
+
+ /* left shift factors to gain accurancy */
+ res = CntLeadingZeros(max_mantissa) - 1;
+
+ /* above topmost DRC band gain factor is 1 */
+ if (((pDrcChData->bandTop[fMax(0, numBands - 1)] + 1) << 2) < aacFrameSize)
+ res = 0;
+
+ if (res > 0) {
+ res = fixMin(res, max_exponent);
+ max_exponent -= res;
+
+ for (band = 0; band < numBands; band++) {
+ fact_mantissa[band] <<= res;
+ fact_exponent[band] -= res;
+ }
+ }
+
+ /* normalize magnitudes to one scale factor */
+ for (band = 0; band < numBands; band++) {
+ if (fact_exponent[band] < max_exponent) {
+ fact_mantissa[band] >>= max_exponent - fact_exponent[band];
+ }
+ if (fact_mantissa[band] != FL2FXCONST_DBL(0.5f)) {
+ modifyBins = 1;
+ }
+ }
+ if (max_exponent != 1) {
+ modifyBins = 1;
+ }
+ }
+
+ /* apply factor to spectral lines
+ * short blocks must take care that bands fall on
+ * block boundaries!
+ */
+ if (!bSbrPresent) {
+ bottom = 0;
+
+ if (!modifyBins) {
+ /* We don't have to modify the spectral bins because the fractional part
+ of all factors is 0.5. In order to keep accurancy we don't apply the
+ factor but decrease the exponent instead. */
+ max_exponent -= 1;
+ } else {
+ for (band = 0; band < numBands; band++) {
+ int top = fixMin((int)((pDrcChData->bandTop[band] + 1) << 2),
+ aacFrameSize); /* ... * DRC_BAND_MULT; */
+
+ for (bin = bottom; bin < top; bin++) {
+ pSpectralCoefficient[bin] =
+ fMult(pSpectralCoefficient[bin], fact_mantissa[band]);
+ }
+
+ bottom = top;
+ }
+ }
+
+ /* above topmost DRC band gain factor is 1 */
+ if (max_exponent > 0) {
+ for (bin = bottom; bin < aacFrameSize; bin += 1) {
+ pSpectralCoefficient[bin] >>= max_exponent;
+ }
+ }
+
+ /* adjust scaling */
+ pSpecScale[0] += max_exponent;
+
+ if (winSeq == BLOCK_SHORT) {
+ int win;
+ for (win = 1; win < 8; win++) {
+ pSpecScale[win] += max_exponent;
+ }
+ }
+ } else {
+ HANDLE_SBRDECODER hSbrDecoder = (HANDLE_SBRDECODER)pSbrDec;
+ numBands = pDrcChData->numBands;
+
+ /* feed factors into SBR decoder for application in QMF domain. */
+ sbrDecoder_drcFeedChannel(hSbrDecoder, ch, numBands, fact_mantissa,
+ max_exponent, pDrcChData->drcInterpolationScheme,
+ winSeq, pDrcChData->bandTop);
+ }
+
+ return;
+}
+
+/*
+ * DRC parameter and presentation mode handling
+ */
+static void aacDecoder_drcParameterHandling(HANDLE_AAC_DRC self,
+ INT aacNumChannels,
+ SCHAR prevDrcProgRefLevel,
+ SCHAR prevDrcPresMode) {
+ int isDownmix, isMonoDownmix, isStereoDownmix;
+ int dDmx, dHr;
+ AACDEC_DRC_PARAMETER_HANDLING drcParameterHandling;
+ CDrcParams *p;
+
+ FDK_ASSERT(self != NULL);
+
+ p = &self->params;
+
+ if (self->progRefLevel != prevDrcProgRefLevel) self->update = 1;
+
+ if (self->presMode != prevDrcPresMode) self->update = 1;
+
+ if (self->prevAacNumChannels != aacNumChannels) self->update = 1;
+
+ /* return if no relevant parameter has changed */
+ if (!self->update) {
+ return;
+ }
+
+ /* derive downmix property. aacNumChannels: number of channels in aac stream,
+ * numOutChannels: number of output channels */
+ isDownmix = (aacNumChannels > self->numOutChannels);
+ isDownmix = (isDownmix && (self->numOutChannels > 0));
+ isMonoDownmix = (isDownmix && (self->numOutChannels == 1));
+ isStereoDownmix = (isDownmix && (self->numOutChannels == 2));
+
+ if ((self->presMode == 1) || (self->presMode == 2)) {
+ drcParameterHandling = (AACDEC_DRC_PARAMETER_HANDLING)self->presMode;
+ } else { /* no presentation mode -> use parameter handling specified by
+ AAC_DRC_DEFAULT_PRESENTATION_MODE */
+ drcParameterHandling = p->defaultPresentationMode;
+ }
+
+ /* by default, do as desired */
+ p->cut = p->usrCut;
+ p->boost = p->usrBoost;
+ p->applyHeavyCompression = p->usrApplyHeavyCompression;
+
+ switch (drcParameterHandling) {
+ case DISABLED_PARAMETER_HANDLING:
+ default:
+ /* use drc parameters as requested */
+ break;
+
+ case ENABLED_PARAMETER_HANDLING:
+ /* dDmx: estimated headroom reduction due to downmix, format: -1/4*dB
+ dDmx = floor(-4*20*log10(aacNumChannels/numOutChannels)) */
+ if (isDownmix) {
+ FIXP_DBL dmxTmp;
+ int e_log, e_mult;
+ dmxTmp = fDivNorm(self->numOutChannels,
+ aacNumChannels); /* inverse division ->
+ negative sign after
+ logarithm */
+ dmxTmp = fLog2(dmxTmp, 0, &e_log);
+ dmxTmp = fMultNorm(
+ dmxTmp, FL2FXCONST_DBL(4.0f * 20.0f * 0.30103f / (float)(1 << 5)),
+ &e_mult); /* e = e_log + e_mult + 5 */
+ dDmx = (int)scaleValue(dmxTmp, e_log + e_mult + 5 - (DFRACT_BITS - 1));
+ } else {
+ dDmx = 0;
+ }
+
+ /* dHr: Full estimated (decoder) headroom reduction due to loudness
+ * normalisation (DTL - PRL) and downmix. Format: -1/4*dB */
+ if (p->targetRefLevel >= 0) { /* if target level is provided */
+ dHr = p->targetRefLevel + dDmx - self->progRefLevel;
+ } else {
+ dHr = dDmx;
+ }
+
+ if (dHr < 0) { /* if headroom is reduced */
+ /* Use compression, but as little as possible. */
+ /* eHr: Headroom provided by encoder, format: -1/4 dB */
+ int eHr = fixMin(p->encoderTargetLevel - self->progRefLevel, 0);
+ if (eHr <
+ dHr) { /* if encoder provides more headroom than decoder needs */
+ /* derive scaling of light DRC */
+ FIXP_DBL calcFactor_norm;
+ INT calcFactor; /* fraction of DRC gains that is minimally needed for
+ clipping prevention */
+ calcFactor_norm =
+ fDivNorm(-dHr, -eHr); /* 0.0 < calcFactor_norm < 1.0 */
+ calcFactor_norm = calcFactor_norm >> DRC_PARAM_SCALE;
+ /* quantize to 128 steps */
+ calcFactor = convert_drcParam(
+ calcFactor_norm); /* convert to integer value between 0 and 127 */
+ calcFactor_norm = (FIXP_DBL)(
+ (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * calcFactor);
+ p->cut = (calcFactor_norm > p->cut)
+ ? calcFactor_norm
+ : p->cut; /* use calcFactor_norm as lower limit */
+ } else {
+ /* encoder provides equal or less headroom than decoder needs */
+ /* the time domain limiter must always be active in this case. It is
+ * assumed that the framework activates it by default */
+ p->cut = DRC_SCALING_MAX;
+ if ((dHr - eHr) <=
+ -4 * DRC_HEAVY_THRESHOLD_DB) { /* use heavy compression if
+ headroom deficit is equal or
+ higher than
+ DRC_HEAVY_THRESHOLD_DB */
+ p->applyHeavyCompression = ON;
+ }
+ }
+ } else { /* dHr >= 0 */
+ /* no restrictions required, as headroom is not reduced. */
+ /* p->cut = p->usrCut; */
+ }
+ break;
+
+ /* presentation mode 1 and 2 according to ETSI TS 101 154:
+ Digital Video Broadcasting (DVB); Specification for the use of Video
+ and Audio Coding in Broadcasting Applications based on the MPEG-2
+ Transport Stream, section C.5.4., "Decoding", and Table C.33. Also
+ according to amendment 4 to ISO/IEC 14496-3, section 4.5.2.14.2.4, and
+ Table AMD4.11. ISO DRC -> applyHeavyCompression = OFF (Use
+ light compression, MPEG-style) Compression_value ->
+ applyHeavyCompression = ON (Use heavy compression, DVB-style) scaling
+ restricted -> p->cut = DRC_SCALING_MAX */
+
+ case DRC_PRESENTATION_MODE_1: /* presentation mode 1, Light:-31/Heavy:-23 */
+ if ((p->targetRefLevel >= 0) &&
+ (p->targetRefLevel <
+ 124)) { /* if target level is provided and > -31 dB */
+ /* playback up to -23 dB */
+ p->applyHeavyCompression = ON;
+ } else { /* target level <= -31 dB or not provided */
+ /* playback -31 dB */
+ if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */
+ p->cut = DRC_SCALING_MAX;
+ }
+ }
+ break;
+
+ case DRC_PRESENTATION_MODE_2: /* presentation mode 2, Light:-23/Heavy:-23 */
+ if ((p->targetRefLevel >= 0) &&
+ (p->targetRefLevel <
+ 124)) { /* if target level is provided and > -31 dB */
+ /* playback up to -23 dB */
+ if (isMonoDownmix) { /* if mono downmix */
+ p->applyHeavyCompression = ON;
+ } else {
+ p->applyHeavyCompression = OFF;
+ p->cut = DRC_SCALING_MAX;
+ }
+ } else { /* target level <= -31 dB or not provided */
+ /* playback -31 dB */
+ p->applyHeavyCompression = OFF;
+ if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */
+ p->cut = DRC_SCALING_MAX;
+ }
+ }
+ break;
+ } /* switch (drcParameterHandling) */
+
+ /* With heavy compression, there is no scaling.
+ Scaling factors are set for notification only. */
+ if (p->applyHeavyCompression == ON) {
+ p->boost = DRC_SCALING_MAX;
+ p->cut = DRC_SCALING_MAX;
+ }
+
+ /* switch on/off processing */
+ self->enable = ((p->boost > (FIXP_DBL)0) || (p->cut > (FIXP_DBL)0) ||
+ (p->applyHeavyCompression == ON) || (p->targetRefLevel >= 0));
+ self->enable = (self->enable && !self->uniDrcPrecedence);
+
+ self->prevAacNumChannels = aacNumChannels;
+ self->update = 0;
+}
+
+/*
+ * Prepare DRC processing
+ * Valid return values are:
+ * -1 : An unexpected error occured.
+ * 0 : No error and no valid DRC data available.
+ * 1 : No error and valid DRC data has been mapped.
+ */
+int aacDecoder_drcProlog(
+ HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ UCHAR pceInstanceTag,
+ UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
+ canonical channel index */
+ int validChannels) {
+ int result = 0;
+
+ if (self == NULL) {
+ return -1;
+ }
+
+ if (!self->params.bsDelayEnable) {
+ /* keep previous progRefLevel and presMode for update flag in
+ * drcParameterHandling */
+ INT prevPRL, prevPM = 0;
+ prevPRL = self->progRefLevel;
+ prevPM = self->presMode;
+
+ result = aacDecoder_drcExtractAndMap(
+ self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
+ validChannels);
+
+ if (result < 0) {
+ return result;
+ }
+
+ /* Drc parameter handling */
+ aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
+ }
+
+ return result;
+}
+
+/*
+ * Finalize DRC processing
+ * Valid return values are:
+ * -1 : An unexpected error occured.
+ * 0 : No error and no valid DRC data available.
+ * 1 : No error and valid DRC data has been mapped.
+ */
+int aacDecoder_drcEpilog(
+ HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ UCHAR pceInstanceTag,
+ UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
+ canonical channel index */
+ int validChannels) {
+ int result = 0;
+
+ if (self == NULL) {
+ return -1;
+ }
+
+ if (self->params.bsDelayEnable) {
+ /* keep previous progRefLevel and presMode for update flag in
+ * drcParameterHandling */
+ INT prevPRL, prevPM = 0;
+ prevPRL = self->progRefLevel;
+ prevPM = self->presMode;
+
+ result = aacDecoder_drcExtractAndMap(
+ self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
+ validChannels);
+
+ if (result < 0) {
+ return result;
+ }
+
+ /* Drc parameter handling */
+ aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
+ }
+
+ return result;
+}
+
+/*
+ * Export relevant metadata info from bitstream payload.
+ */
+void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
+ SCHAR *pProgRefLevel) {
+ if (self != NULL) {
+ if (pPresMode != NULL) {
+ *pPresMode = self->presMode;
+ }
+ if (pProgRefLevel != NULL) {
+ if (self->progRefLevelPresent) {
+ *pProgRefLevel = self->progRefLevel;
+ } else {
+ *pProgRefLevel = -1;
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_drc.h b/fdk-aac/libAACdec/src/aacdec_drc.h
new file mode 100644
index 0000000..924ec6f
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_drc.h
@@ -0,0 +1,192 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Christian Griebel
+
+ Description: Dynamic range control (DRC) decoder tool for AAC
+
+*******************************************************************************/
+
+#ifndef AACDEC_DRC_H
+#define AACDEC_DRC_H
+
+#include "tp_data.h" /* for program config element support */
+
+#include "aacdec_drc_types.h"
+#include "channel.h"
+#include "FDK_bitstream.h"
+
+#define AACDEC_DRC_DFLT_EXPIRY_FRAMES \
+ (0) /* Default DRC data expiry time in AAC frames */
+
+/* #define AACDEC_DRC_IGNORE_FRAMES_WITH_MULTIPLE_CH_THREADS */ /* The name says
+ it all. */
+/* #define AACDEC_DRC_DEBUG */
+
+/**
+ * \brief DRC module setting parameters
+ */
+typedef enum {
+ DRC_CUT_SCALE = 0,
+ DRC_BOOST_SCALE,
+ TARGET_REF_LEVEL,
+ DRC_BS_DELAY,
+ DRC_DATA_EXPIRY_FRAME,
+ APPLY_NORMALIZATION,
+ APPLY_HEAVY_COMPRESSION,
+ DEFAULT_PRESENTATION_MODE,
+ ENCODER_TARGET_LEVEL,
+ MAX_OUTPUT_CHANNELS,
+ UNIDRC_PRECEDENCE
+} AACDEC_DRC_PARAM;
+
+/**
+ * \brief DRC module interface functions
+ */
+void aacDecoder_drcInit(HANDLE_AAC_DRC self);
+
+void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChannel);
+
+AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
+ AACDEC_DRC_PARAM param, INT value);
+
+int aacDecoder_drcMarkPayload(HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ AACDEC_DRC_PAYLOAD_TYPE type);
+
+int aacDecoder_drcProlog(
+ HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ UCHAR pceInstanceTag, UCHAR channelMapping[], int validChannels);
+
+/**
+ * \brief Apply DRC. If SBR is present, DRC data is handed over to the SBR
+ * decoder.
+ * \param self AAC decoder instance
+ * \param pSbrDec pointer to SBR decoder instance
+ * \param pAacDecoderChannelInfo AAC decoder channel instance to be processed
+ * \param pDrcDat DRC channel data
+ * \param extGain Pointer to a FIXP_DBL where a externally applyable gain will
+ * be stored into (independently on whether it will be apply internally or not).
+ * At function call the buffer must hold the scale (0 >= scale <
+ * DFRACT_BITS) to be applied on the gain value.
+ * \param ch channel index
+ * \param aacFrameSize AAC frame size
+ * \param bSbrPresent flag indicating that SBR is present, in which case DRC is
+ * handed over to the SBR instance pSbrDec
+ */
+void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CDrcChannelData *pDrcDat, FIXP_DBL *extGain, int ch,
+ int aacFrameSize, int bSbrPresent);
+
+int aacDecoder_drcEpilog(
+ HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ UCHAR pceInstanceTag, UCHAR channelMapping[], int validChannels);
+
+/**
+ * \brief Get metadata information found in bitstream.
+ * \param self DRC module instance handle.
+ * \param pPresMode Pointer to field where the presentation mode will be written
+ * to.
+ * \param pProgRefLevel Pointer to field where the program reference level will
+ * be written to.
+ * \return Nothing.
+ */
+void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
+ SCHAR *pProgRefLevel);
+
+#endif /* AACDEC_DRC_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_drc_types.h b/fdk-aac/libAACdec/src/aacdec_drc_types.h
new file mode 100644
index 0000000..76c35d0
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_drc_types.h
@@ -0,0 +1,220 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Christian Griebel
+
+ Description: Dynamic range control (DRC) global data types
+
+*******************************************************************************/
+
+#ifndef AACDEC_DRC_TYPES_H
+#define AACDEC_DRC_TYPES_H
+
+#include "common_fix.h"
+
+#define MAX_DRC_THREADS \
+ ((8) + 1) /* Heavy compression value is handled just like MPEG DRC data */
+#define MAX_DRC_BANDS (16) /* 2^LEN_DRC_BAND_INCR (LEN_DRC_BAND_INCR = 4) */
+
+/**
+ * \brief DRC module global data types
+ */
+typedef enum {
+ UNKNOWN_PAYLOAD = 0,
+ MPEG_DRC_EXT_DATA = 1,
+ DVB_DRC_ANC_DATA = 2
+
+} AACDEC_DRC_PAYLOAD_TYPE;
+
+/**
+ * \brief Options for parameter handling / presentation mode
+ */
+typedef enum {
+ DISABLED_PARAMETER_HANDLING = -1, /*!< DRC parameter handling disabled, all
+ parameters are applied as requested. */
+ ENABLED_PARAMETER_HANDLING =
+ 0, /*!< Apply changes to requested DRC parameters to prevent clipping */
+ DRC_PRESENTATION_MODE_1 = 1, /*!< DRC Presentation mode 1*/
+ DRC_PRESENTATION_MODE_2 = 2 /*!< DRC Presentation mode 2*/
+
+} AACDEC_DRC_PARAMETER_HANDLING;
+
+typedef struct {
+ UINT expiryCount;
+ UINT numBands;
+ USHORT bandTop[MAX_DRC_BANDS];
+ SHORT drcInterpolationScheme;
+ UCHAR drcValue[MAX_DRC_BANDS];
+ SCHAR drcDataType;
+
+} CDrcChannelData;
+
+typedef struct {
+ UINT excludedChnsMask;
+ SCHAR progRefLevel;
+ SCHAR presMode; /* Presentation mode: 0 (not indicated), 1, 2, and 3
+ (reserved). */
+ SCHAR pceInstanceTag;
+
+ CDrcChannelData channelData;
+
+} CDrcPayload;
+
+typedef struct {
+ /* DRC parameters: Latest user requests */
+ FIXP_DBL usrCut;
+ FIXP_DBL usrBoost;
+ UCHAR usrApplyHeavyCompression;
+
+ /* DRC parameters: Currently used, possibly changed by
+ * aacDecoder_drcParameterHandling */
+ FIXP_DBL cut; /* attenuation scale factor */
+ FIXP_DBL boost; /* boost scale factor */
+ SCHAR targetRefLevel; /* target reference level for loudness normalization */
+ UCHAR applyHeavyCompression; /* heavy compression (DVB) flag */
+
+ UINT expiryFrame;
+ UCHAR bsDelayEnable;
+ UCHAR applyDigitalNorm;
+
+ AACDEC_DRC_PARAMETER_HANDLING defaultPresentationMode;
+ UCHAR encoderTargetLevel;
+
+} CDrcParams;
+
+typedef struct {
+ CDrcParams
+ params; /* Module parameters that can be set by user (via SetParam API
+ function) */
+
+ UCHAR enable; /* Switch that controls dynamic range processing */
+ UCHAR digitalNorm; /* Switch to en-/disable reference level normalization in
+ digital domain */
+
+ UCHAR update; /* Flag indicating the change of a user or bitstream parameter
+ which affects aacDecoder_drcParameterHandling */
+ INT numOutChannels; /* Number of output channels */
+ INT prevAacNumChannels; /* Previous number of channels of aac bitstream, used
+ for update flag */
+
+ USHORT numPayloads; /* The number of DRC data payload elements found within
+ frame */
+ USHORT
+ numThreads; /* The number of DRC data threads extracted from the found
+ payload elements */
+ SCHAR progRefLevel; /* Program reference level for all channels */
+ UCHAR progRefLevelPresent; /* Program reference level found in bitstream */
+
+ UINT prlExpiryCount; /* Counter that can be used to monitor the life time of
+ the program reference level. */
+
+ SCHAR presMode; /* Presentation mode as defined in ETSI TS 101 154 */
+ UCHAR dvbAncDataAvailable; /* Flag that indicates whether DVB ancillary data
+ is present or not */
+ UINT dvbAncDataPosition; /* Used to store the DVB ancillary data payload
+ position in the bitstream (only one per frame) */
+ UINT drcPayloadPosition[MAX_DRC_THREADS]; /* Used to store the DRC payload
+ positions in the bitstream */
+
+ UCHAR
+ uniDrcPrecedence; /* Flag for signalling that uniDrc is active and takes
+ precedence over legacy DRC */
+
+} CDrcInfo;
+
+typedef CDrcInfo *HANDLE_AAC_DRC;
+
+#endif /* AACDEC_DRC_TYPES_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_hcr.cpp b/fdk-aac/libAACdec/src/aacdec_hcr.cpp
new file mode 100644
index 0000000..6114756
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcr.cpp
@@ -0,0 +1,1498 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: HCR initialization, preprocess HCR sideinfo,
+ decode priority codewords (PCWs)
+
+*******************************************************************************/
+
+#include "aacdec_hcr.h"
+
+#include "aacdec_hcr_types.h"
+#include "aacdec_hcr_bit.h"
+#include "aacdec_hcrs.h"
+#include "aac_ram.h"
+#include "aac_rom.h"
+#include "channel.h"
+#include "block.h"
+
+#include "aacdecoder.h" /* for ID_CPE, ID_SCE ... */
+#include "FDK_bitstream.h"
+
+extern int mlFileChCurr;
+
+static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine,
+ UINT *errorWord);
+
+static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,
+ SHORT lengthOfReorderedSpectralData,
+ UINT *errorWord);
+
+static void HcrCalcNumCodeword(H_HCR_INFO pHcr);
+static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr);
+static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr);
+static void HcrExtendedSectionInfo(H_HCR_INFO pHcr);
+
+static void DeriveNumberOfExtendedSortedSectionsInSets(
+ UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection,
+ int numExtendedSortedCodewordInSectionIdx,
+ USHORT *pNumExtendedSortedSectionsInSets,
+ int numExtendedSortedSectionsInSetsIdx);
+
+static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT quantSpecCoef, INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment,
+ int *pNumDecodedBits);
+
+static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ UINT codebookDim, const SCHAR *pQuantVal,
+ FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx,
+ INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment, int *pNumDecodedBits);
+
+static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ const UINT *pCurrentTree,
+ const SCHAR *pQuantValBase,
+ INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment,
+ int *pNumDecodedBits);
+
+static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr);
+
+static void HcrReorderQuantizedSpectralCoefficients(
+ H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo);
+
+static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment,
+ H_HCR_INFO pHcr, PCW_TYPE kind,
+ FIXP_DBL *qsc_base_of_cw,
+ UCHAR dimension);
+
+static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr);
+
+/*---------------------------------------------------------------------------------------------
+ description: Check if codebook and numSect are within allowed range
+(short only)
+--------------------------------------------------------------------------------------------
+*/
+static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine,
+ UINT *errorWord) {
+ if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) {
+ *errorWord |= CB_OUT_OF_RANGE_SHORT_BLOCK;
+ }
+ if (numLine < 0 || numLine > 1024) {
+ *errorWord |= LINE_IN_SECT_OUT_OF_RANGE_SHORT_BLOCK;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Check both HCR lengths
+--------------------------------------------------------------------------------------------
+*/
+static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,
+ SHORT lengthOfReorderedSpectralData,
+ UINT *errorWord) {
+ if (lengthOfReorderedSpectralData < lengthOfLongestCodeword) {
+ *errorWord |= HCR_SI_LENGTHS_FAILURE;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decode (and adapt if necessary) the two HCR sideinfo
+components: 'reordered_spectral_data_length' and 'longest_codeword_length'
+--------------------------------------------------------------------------------------------
+*/
+
+void CHcr_Read(HANDLE_FDK_BITSTREAM bs,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const MP4_ELEMENT_ID globalHcrType) {
+ SHORT lengOfReorderedSpectralData;
+ SCHAR lengOfLongestCodeword;
+
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfReorderedSpectralData =
+ 0;
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword = 0;
+
+ /* ------- SI-Value No 1 ------- */
+ lengOfReorderedSpectralData = FDKreadBits(bs, 14) + ERROR_LORSD;
+ if (globalHcrType == ID_CPE) {
+ if ((lengOfReorderedSpectralData >= 0) &&
+ (lengOfReorderedSpectralData <= CPE_TOP_LENGTH)) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData =
+ lengOfReorderedSpectralData; /* the decoded value is within range */
+ } else {
+ if (lengOfReorderedSpectralData > CPE_TOP_LENGTH) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData =
+ CPE_TOP_LENGTH; /* use valid maximum */
+ }
+ }
+ } else if (globalHcrType == ID_SCE || globalHcrType == ID_LFE ||
+ globalHcrType == ID_CCE) {
+ if ((lengOfReorderedSpectralData >= 0) &&
+ (lengOfReorderedSpectralData <= SCE_TOP_LENGTH)) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData =
+ lengOfReorderedSpectralData; /* the decoded value is within range */
+ } else {
+ if (lengOfReorderedSpectralData > SCE_TOP_LENGTH) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData =
+ SCE_TOP_LENGTH; /* use valid maximum */
+ }
+ }
+ }
+
+ /* ------- SI-Value No 2 ------- */
+ lengOfLongestCodeword = FDKreadBits(bs, 6) + ERROR_LOLC;
+ if ((lengOfLongestCodeword >= 0) &&
+ (lengOfLongestCodeword <= LEN_OF_LONGEST_CW_TOP_LENGTH)) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword =
+ lengOfLongestCodeword; /* the decoded value is within range */
+ } else {
+ if (lengOfLongestCodeword > LEN_OF_LONGEST_CW_TOP_LENGTH) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword =
+ LEN_OF_LONGEST_CW_TOP_LENGTH; /* use valid maximum */
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Set up HCR - must be called before every call to
+HcrDecoder(). For short block a sorting algorithm is applied to get the SI in
+the order that HCR could assemble the qsc's as if it is a long block.
+-----------------------------------------------------------------------------------------------
+ return: error log
+--------------------------------------------------------------------------------------------
+*/
+
+UINT HcrInit(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+ SHORT *pNumLinesInSec;
+ UCHAR *pCodeBk;
+ SHORT numSection;
+ SCHAR cb;
+ int numLine;
+ int i;
+
+ pHcr->decInOut.lengthOfReorderedSpectralData =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData;
+ pHcr->decInOut.lengthOfLongestCodeword =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword;
+ pHcr->decInOut.pQuantizedSpectralCoefficientsBase =
+ pAacDecoderChannelInfo->pSpectralCoefficient;
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx = 0;
+ pHcr->decInOut.pCodebook =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
+ pHcr->decInOut.pNumLineInSect =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
+ pHcr->decInOut.numSection =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection;
+ pHcr->decInOut.errorLog = 0;
+ pHcr->nonPcwSideinfo.pResultBase =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+
+ FDKsyncCache(bs);
+ pHcr->decInOut.bitstreamAnchor = (INT)FDKgetValidBits(bs);
+
+ if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) /* short block */
+ {
+ SHORT band;
+ SHORT maxBand;
+ SCHAR group;
+ SCHAR winGroupLen;
+ SCHAR window;
+ SCHAR numUnitInBand;
+ SCHAR cntUnitInBand;
+ SCHAR groupWin;
+ SCHAR cb_prev;
+
+ UCHAR *pCodeBook;
+ const SHORT *BandOffsets;
+ SCHAR numOfGroups;
+
+ pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook; /* in */
+ pNumLinesInSec = pHcr->decInOut.pNumLineInSect; /* out */
+ pCodeBk = pHcr->decInOut.pCodebook; /* out */
+ BandOffsets =
+ GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo); /* aux */
+ numOfGroups = GetWindowGroups(pIcsInfo);
+
+ numLine = 0;
+ numSection = 0;
+ cb = pCodeBook[0];
+ cb_prev = pCodeBook[0];
+
+ /* convert HCR-sideinfo into a unitwise manner: When the cb changes, a new
+ * section starts */
+
+ *pCodeBk++ = cb_prev;
+
+ maxBand = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ for (band = 0; band < maxBand;
+ band++) { /* from low to high sfbs i.e. from low to high frequencies */
+ numUnitInBand =
+ ((BandOffsets[band + 1] - BandOffsets[band]) >>
+ FOUR_LOG_DIV_TWO_LOG); /* get the number of units in current sfb */
+ for (cntUnitInBand = numUnitInBand; cntUnitInBand != 0;
+ cntUnitInBand--) { /* for every unit in the band */
+ for (window = 0, group = 0; group < numOfGroups; group++) {
+ winGroupLen = (SCHAR)GetWindowGroupLength(
+ &pAacDecoderChannelInfo->icsInfo, group);
+ for (groupWin = winGroupLen; groupWin != 0; groupWin--, window++) {
+ cb = pCodeBook[group * 16 + band];
+ if (cb != cb_prev) {
+ errDetectorInHcrSideinfoShrt(cb, numLine,
+ &pHcr->decInOut.errorLog);
+ if (pHcr->decInOut.errorLog != 0) {
+ return (pHcr->decInOut.errorLog);
+ }
+ *pCodeBk++ = cb;
+ *pNumLinesInSec++ = numLine;
+ numSection++;
+
+ cb_prev = cb;
+ numLine = LINES_PER_UNIT;
+ } else {
+ numLine += LINES_PER_UNIT;
+ }
+ }
+ }
+ }
+ }
+
+ numSection++;
+
+ errDetectorInHcrSideinfoShrt(cb, numLine, &pHcr->decInOut.errorLog);
+ if (numSection <= 0 || numSection > 1024 / 2) {
+ pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_SHORT_BLOCK;
+ }
+ errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword,
+ pHcr->decInOut.lengthOfReorderedSpectralData,
+ &pHcr->decInOut.errorLog);
+ if (pHcr->decInOut.errorLog != 0) {
+ return (pHcr->decInOut.errorLog);
+ }
+
+ *pCodeBk = cb;
+ *pNumLinesInSec = numLine;
+ pHcr->decInOut.numSection = numSection;
+
+ } else /* end short block prepare SI */
+ { /* long block */
+ errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword,
+ pHcr->decInOut.lengthOfReorderedSpectralData,
+ &pHcr->decInOut.errorLog);
+ numSection = pHcr->decInOut.numSection;
+ pNumLinesInSec = pHcr->decInOut.pNumLineInSect;
+ pCodeBk = pHcr->decInOut.pCodebook;
+ if (numSection <= 0 || numSection > 64) {
+ pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_LONG_BLOCK;
+ numSection = 0;
+ }
+
+ for (i = numSection; i != 0; i--) {
+ cb = *pCodeBk++;
+
+ if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) {
+ pHcr->decInOut.errorLog |= CB_OUT_OF_RANGE_LONG_BLOCK;
+ }
+
+ numLine = *pNumLinesInSec++;
+ /* FDK_ASSERT(numLine > 0); */
+
+ if ((numLine <= 0) || (numLine > 1024)) {
+ pHcr->decInOut.errorLog |= LINE_IN_SECT_OUT_OF_RANGE_LONG_BLOCK;
+ }
+ }
+ if (pHcr->decInOut.errorLog != 0) {
+ return (pHcr->decInOut.errorLog);
+ }
+ }
+
+ pCodeBk = pHcr->decInOut.pCodebook;
+ for (i = 0; i < numSection; i++) {
+ if ((*pCodeBk == NOISE_HCB) || (*pCodeBk == INTENSITY_HCB2) ||
+ (*pCodeBk == INTENSITY_HCB)) {
+ *pCodeBk = 0;
+ }
+ pCodeBk++;
+ }
+
+ /* HCR-sideinfo-input is complete and seems to be valid */
+
+ return (pHcr->decInOut.errorLog);
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function decodes the codewords of the spectral
+coefficients from the bitstream according to the HCR algorithm and stores the
+quantized spectral coefficients in correct order in the output buffer.
+--------------------------------------------------------------------------------------------
+*/
+
+UINT HcrDecoder(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ int pTmp1, pTmp2, pTmp3, pTmp4;
+ int pTmp5;
+
+ INT bitCntOffst;
+ INT saveBitCnt = (INT)FDKgetValidBits(bs); /* save bitstream position */
+
+ HcrCalcNumCodeword(pHcr);
+
+ HcrSortCodebookAndNumCodewordInSection(pHcr);
+
+ HcrPrepareSegmentationGrid(pHcr);
+
+ HcrExtendedSectionInfo(pHcr);
+
+ if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) != 0) {
+ return (pHcr->decInOut.errorLog); /* sideinfo is massively corrupt, return
+ from HCR without having decoded
+ anything */
+ }
+
+ DeriveNumberOfExtendedSortedSectionsInSets(
+ pHcr->segmentInfo.numSegment,
+ pHcr->sectionInfo.pNumExtendedSortedCodewordInSection,
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx,
+ pHcr->sectionInfo.pNumExtendedSortedSectionsInSets,
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx);
+
+ /* store */
+ pTmp1 = pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
+ pTmp2 = pHcr->sectionInfo.extendedSortedCodebookIdx;
+ pTmp3 = pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
+ pTmp4 = pHcr->decInOut.quantizedSpectralCoefficientsIdx;
+ pTmp5 = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx;
+
+ /* ------- decode meaningful PCWs ------ */
+ DecodePCWs(bs, pHcr);
+
+ if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) == 0) {
+ /* ------ decode the non-PCWs -------- */
+ DecodeNonPCWs(bs, pHcr);
+ }
+
+ errDetectWithinSegmentationFinal(pHcr);
+
+ /* restore */
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = pTmp1;
+ pHcr->sectionInfo.extendedSortedCodebookIdx = pTmp2;
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = pTmp3;
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx = pTmp4;
+ pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = pTmp5;
+
+ HcrReorderQuantizedSpectralCoefficients(pHcr, pAacDecoderChannelInfo,
+ pSamplingRateInfo);
+
+ /* restore bitstream position */
+ bitCntOffst = (INT)FDKgetValidBits(bs) - saveBitCnt;
+ if (bitCntOffst) {
+ FDKpushBiDirectional(bs, bitCntOffst);
+ }
+
+ return (pHcr->decInOut.errorLog);
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function reorders the quantized spectral coefficients
+sectionwise for long- and short-blocks and compares to the LAV (Largest Absolute
+Value of the current codebook) -- a counter is incremented if there is an error
+ detected.
+ Additional for short-blocks a unit-based-deinterleaving is
+applied. Moreover (for short blocks) the scaling is derived (compare plain
+huffman decoder).
+--------------------------------------------------------------------------------------------
+*/
+
+static void HcrReorderQuantizedSpectralCoefficients(
+ H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo) {
+ INT qsc;
+ UINT abs_qsc;
+ UINT i, j;
+ USHORT numSpectralValuesInSection;
+ FIXP_DBL *pTeVa;
+ USHORT lavErrorCnt = 0;
+
+ UINT numSection = pHcr->decInOut.numSection;
+ SPECTRAL_PTR pQuantizedSpectralCoefficientsBase =
+ pHcr->decInOut.pQuantizedSpectralCoefficientsBase;
+ FIXP_DBL *pQuantizedSpectralCoefficients =
+ SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase);
+ const UCHAR *pCbDimShift = aDimCbShift;
+ const USHORT *pLargestAbsVal = aLargestAbsoluteValue;
+ UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
+ USHORT *pNumSortedCodewordInSection =
+ pHcr->sectionInfo.pNumSortedCodewordInSection;
+ USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset;
+ FIXP_DBL pTempValues[1024];
+ FIXP_DBL *pBak = pTempValues;
+
+ FDKmemclear(pTempValues, 1024 * sizeof(FIXP_DBL));
+
+ /* long and short: check if decoded huffman-values (quantized spectral
+ * coefficients) are within range */
+ for (i = numSection; i != 0; i--) {
+ numSpectralValuesInSection = *pNumSortedCodewordInSection++
+ << pCbDimShift[*pSortedCodebook];
+ pTeVa = &pTempValues[*pReorderOffset++];
+ for (j = numSpectralValuesInSection; j != 0; j--) {
+ qsc = *pQuantizedSpectralCoefficients++;
+ abs_qsc = fAbs(qsc);
+ if (abs_qsc <= pLargestAbsVal[*pSortedCodebook]) {
+ *pTeVa++ = (FIXP_DBL)qsc; /* the qsc value is within range */
+ } else { /* line is too high .. */
+ if (abs_qsc ==
+ Q_VALUE_INVALID) { /* .. because of previous marking --> dont set
+ LAV flag (would be confusing), just copy out
+ the already marked value */
+ *pTeVa++ = (FIXP_DBL)qsc;
+ } else { /* .. because a too high value was decoded for this cb --> set
+ LAV flag */
+ *pTeVa++ = (FIXP_DBL)Q_VALUE_INVALID;
+ lavErrorCnt += 1;
+ }
+ }
+ }
+ pSortedCodebook++;
+ }
+
+ if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
+ FIXP_DBL *pOut;
+ FIXP_DBL locMax;
+ FIXP_DBL tmp;
+ SCHAR groupoffset;
+ SCHAR group;
+ SCHAR band;
+ SCHAR groupwin;
+ SCHAR window;
+ SCHAR numWinGroup;
+ SHORT interm;
+ SCHAR numSfbTransm;
+ SCHAR winGroupLen;
+ SHORT index;
+ INT msb;
+ INT lsb;
+
+ SHORT *pScaleFacHcr = pAacDecoderChannelInfo->pDynData->aScaleFactor;
+ SHORT *pSfbSclHcr = pAacDecoderChannelInfo->pDynData->aSfbScale;
+ const SHORT *BandOffsets = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+
+ pBak = pTempValues;
+ /* deinterleave unitwise for short blocks */
+ for (window = 0; window < (8); window++) {
+ pOut = SPEC(pQuantizedSpectralCoefficientsBase, window,
+ pAacDecoderChannelInfo->granuleLength);
+ for (i = 0; i < (LINES_PER_UNIT_GROUP); i++) {
+ pTeVa = pBak + (window << FOUR_LOG_DIV_TWO_LOG) +
+ i * 32; /* distance of lines between unit groups has to be
+ constant for every framelength (32)! */
+ for (j = (LINES_PER_UNIT); j != 0; j--) {
+ *pOut++ = *pTeVa++;
+ }
+ }
+ }
+
+ /* short blocks only */
+ /* derive global scaling-value for every sfb and every window (as it is done
+ * in plain-huffman-decoder at short blocks) */
+ groupoffset = 0;
+
+ numWinGroup = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+ numSfbTransm =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+
+ for (group = 0; group < numWinGroup; group++) {
+ winGroupLen =
+ GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
+ for (band = 0; band < numSfbTransm; band++) {
+ interm = group * 16 + band;
+ msb = pScaleFacHcr[interm] >> 2;
+ lsb = pScaleFacHcr[interm] & 3;
+ for (groupwin = 0; groupwin < winGroupLen; groupwin++) {
+ window = groupoffset + groupwin;
+ pBak = SPEC(pQuantizedSpectralCoefficientsBase, window,
+ pAacDecoderChannelInfo->granuleLength);
+ locMax = FL2FXCONST_DBL(0.0f);
+ for (index = BandOffsets[band]; index < BandOffsets[band + 1];
+ index += LINES_PER_UNIT) {
+ pTeVa = &pBak[index];
+ for (i = LINES_PER_UNIT; i != 0; i--) {
+ tmp = (*pTeVa < FL2FXCONST_DBL(0.0f)) ? -*pTeVa++ : *pTeVa++;
+ locMax = fixMax(tmp, locMax);
+ }
+ }
+ if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) {
+ locMax = (FIXP_DBL)MAX_QUANTIZED_VALUE;
+ }
+ pSfbSclHcr[window * 16 + band] =
+ msb - GetScaleFromValue(
+ locMax, lsb); /* save global scale maxima in this sfb */
+ }
+ }
+ groupoffset +=
+ GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
+ }
+ } else {
+ /* copy straight for long-blocks */
+ pQuantizedSpectralCoefficients =
+ SPEC_LONG(pQuantizedSpectralCoefficientsBase);
+ for (i = 1024; i != 0; i--) {
+ *pQuantizedSpectralCoefficients++ = *pBak++;
+ }
+ }
+
+ if (lavErrorCnt != 0) {
+ pHcr->decInOut.errorLog |= LAV_VIOLATION;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function calculates the number of codewords
+ for each section (numCodewordInSection) and the number of
+codewords for all sections (numCodeword). For zero and intensity codebooks a
+entry is also done in the variable numCodewordInSection. It is assumed that the
+codebook is a two tuples codebook. This is needed later for the calculation of
+the base addresses for the reordering of the quantize spectral coefficients at
+the end of the hcr tool. The variable numCodeword contain the number of
+codewords which are really in the bitstream. Zero or intensity codebooks does
+not increase the variable numCodewords.
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void HcrCalcNumCodeword(H_HCR_INFO pHcr) {
+ int hcrSection;
+ UINT numCodeword;
+
+ UINT numSection = pHcr->decInOut.numSection;
+ UCHAR *pCodebook = pHcr->decInOut.pCodebook;
+ SHORT *pNumLineInSection = pHcr->decInOut.pNumLineInSect;
+ const UCHAR *pCbDimShift = aDimCbShift;
+
+ USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection;
+
+ numCodeword = 0;
+ for (hcrSection = numSection; hcrSection != 0; hcrSection--) {
+ *pNumCodewordInSection = *pNumLineInSection++ >> pCbDimShift[*pCodebook];
+ if (*pCodebook != 0) {
+ numCodeword += *pNumCodewordInSection;
+ }
+ pNumCodewordInSection++;
+ pCodebook++;
+ }
+ pHcr->sectionInfo.numCodeword = numCodeword;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function calculates the number
+ of sorted codebooks and sorts the codebooks and the
+numCodewordInSection according to the priority.
+--------------------------------------------------------------------------------------------
+*/
+
+static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr) {
+ UINT i, j, k;
+ UCHAR temp;
+ UINT counter;
+ UINT startOffset;
+ UINT numZeroSection;
+ UCHAR *pDest;
+ UINT numSectionDec;
+
+ UINT numSection = pHcr->decInOut.numSection;
+ UCHAR *pCodebook = pHcr->decInOut.pCodebook;
+ UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
+ USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection;
+ USHORT *pNumSortedCodewordInSection =
+ pHcr->sectionInfo.pNumSortedCodewordInSection;
+ UCHAR *pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch;
+ USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset;
+ const UCHAR *pCbPriority = aCbPriority;
+ const UCHAR *pMinOfCbPair = aMinOfCbPair;
+ const UCHAR *pMaxOfCbPair = aMaxOfCbPair;
+ const UCHAR *pCbDimShift = aDimCbShift;
+
+ UINT searchStart = 0;
+
+ /* calculate *pNumSortedSection and store the priorities in array
+ * pSortedCdebook */
+ pDest = pSortedCodebook;
+ numZeroSection = 0;
+ for (i = numSection; i != 0; i--) {
+ if (pCbPriority[*pCodebook] == 0) {
+ numZeroSection += 1;
+ }
+ *pDest++ = pCbPriority[*pCodebook++];
+ }
+ pHcr->sectionInfo.numSortedSection =
+ numSection - numZeroSection; /* numSortedSection contains no zero or
+ intensity section */
+ pCodebook = pHcr->decInOut.pCodebook;
+
+ /* sort priorities of the codebooks in array pSortedCdebook[] */
+ numSectionDec = numSection - 1;
+ if (numSectionDec > 0) {
+ counter = numSectionDec;
+ for (j = numSectionDec; j != 0; j--) {
+ for (i = 0; i < counter; i++) {
+ /* swap priorities */
+ if (pSortedCodebook[i + 1] > pSortedCodebook[i]) {
+ temp = pSortedCodebook[i];
+ pSortedCodebook[i] = pSortedCodebook[i + 1];
+ pSortedCodebook[i + 1] = temp;
+ }
+ }
+ counter -= 1;
+ }
+ }
+
+ /* clear codebookSwitch array */
+ for (i = numSection; i != 0; i--) {
+ *pCodebookSwitch++ = 0;
+ }
+ pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch;
+
+ /* sort sectionCodebooks and numCodwordsInSection and calculate
+ * pReorderOffst[j] */
+ for (j = 0; j < numSection; j++) {
+ for (i = searchStart; i < numSection; i++) {
+ if (pCodebookSwitch[i] == 0 &&
+ (pMinOfCbPair[pSortedCodebook[j]] == pCodebook[i] ||
+ pMaxOfCbPair[pSortedCodebook[j]] == pCodebook[i])) {
+ pCodebookSwitch[i] = 1;
+ pSortedCodebook[j] = pCodebook[i]; /* sort codebook */
+ pNumSortedCodewordInSection[j] =
+ pNumCodewordInSection[i]; /* sort NumCodewordInSection */
+
+ startOffset = 0;
+ for (k = 0; k < i; k++) { /* make entry in pReorderOffst */
+ startOffset += pNumCodewordInSection[k] << pCbDimShift[pCodebook[k]];
+ }
+ pReorderOffset[j] =
+ startOffset; /* offset for reordering the codewords */
+
+ if (i == searchStart) {
+ k = i;
+ while (pCodebookSwitch[k++] == 1) searchStart++;
+ }
+ break;
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function calculates the segmentation, which includes
+numSegment, leftStartOfSegment, rightStartOfSegment and remainingBitsInSegment.
+ The segmentation could be visualized a as kind of
+'overlay-grid' for the bitstream-block holding the HCR-encoded
+quantized-spectral-coefficients.
+--------------------------------------------------------------------------------------------
+*/
+
+static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr) {
+ USHORT i, j;
+ USHORT numSegment = 0;
+ INT segmentStart = 0;
+ UCHAR segmentWidth;
+ UCHAR lastSegmentWidth;
+ UCHAR sortedCodebook;
+ UCHAR endFlag = 0;
+ INT intermediateResult;
+
+ SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword;
+ SHORT lengthOfReorderedSpectralData =
+ pHcr->decInOut.lengthOfReorderedSpectralData;
+ UINT numSortedSection = pHcr->sectionInfo.numSortedSection;
+ UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
+ USHORT *pNumSortedCodewordInSection =
+ pHcr->sectionInfo.pNumSortedCodewordInSection;
+ INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ INT *pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ const UCHAR *pMaxCwLength = aMaxCwLen;
+
+ for (i = numSortedSection; i != 0; i--) {
+ sortedCodebook = *pSortedCodebook++;
+ segmentWidth =
+ fMin((INT)pMaxCwLength[sortedCodebook], (INT)lengthOfLongestCodeword);
+
+ for (j = *pNumSortedCodewordInSection; j != 0; j--) {
+ /* width allows a new segment */
+ intermediateResult = segmentStart;
+ if ((segmentStart + segmentWidth) <= lengthOfReorderedSpectralData) {
+ /* store segment start, segment length and increment the number of
+ * segments */
+ *pLeftStartOfSegment++ = intermediateResult;
+ *pRightStartOfSegment++ = intermediateResult + segmentWidth - 1;
+ *pRemainingBitsInSegment++ = segmentWidth;
+ segmentStart += segmentWidth;
+ numSegment += 1;
+ }
+ /* width does not allow a new segment */
+ else {
+ /* correct the last segment length */
+ pLeftStartOfSegment--;
+ pRightStartOfSegment--;
+ pRemainingBitsInSegment--;
+ segmentStart = *pLeftStartOfSegment;
+
+ lastSegmentWidth = lengthOfReorderedSpectralData - segmentStart;
+ *pRemainingBitsInSegment = lastSegmentWidth;
+ *pRightStartOfSegment = segmentStart + lastSegmentWidth - 1;
+ endFlag = 1;
+ break;
+ }
+ }
+ pNumSortedCodewordInSection++;
+ if (endFlag != 0) {
+ break;
+ }
+ }
+ pHcr->segmentInfo.numSegment = numSegment;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function adapts the sorted section boundaries to the
+boundaries of segmentation. If the section lengths does not fit completely into
+the current segment, the section is spitted into two so called 'extended
+ sections'. The extended-section-info
+(pNumExtendedSortedCodewordInSectin and pExtendedSortedCodebook) is updated in
+this case.
+
+--------------------------------------------------------------------------------------------
+*/
+
+static void HcrExtendedSectionInfo(H_HCR_INFO pHcr) {
+ UINT srtSecCnt = 0; /* counter for sorted sections */
+ UINT xSrtScCnt = 0; /* counter for extended sorted sections */
+ UINT remainNumCwInSortSec;
+ UINT inSegmentRemainNumCW;
+
+ UINT numSortedSection = pHcr->sectionInfo.numSortedSection;
+ UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
+ USHORT *pNumSortedCodewordInSection =
+ pHcr->sectionInfo.pNumSortedCodewordInSection;
+ UCHAR *pExtendedSortedCoBo = pHcr->sectionInfo.pExtendedSortedCodebook;
+ USHORT *pNumExtSortCwInSect =
+ pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
+ UINT numSegment = pHcr->segmentInfo.numSegment;
+ UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec;
+ SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword;
+ const UCHAR *pMaxCwLength = aMaxCwLen;
+
+ remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
+ inSegmentRemainNumCW = numSegment;
+
+ while (srtSecCnt < numSortedSection) {
+ if (inSegmentRemainNumCW < remainNumCwInSortSec) {
+ pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW;
+ pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
+
+ remainNumCwInSortSec -= inSegmentRemainNumCW;
+ inSegmentRemainNumCW = numSegment;
+ /* data of a sorted section was not integrated in extended sorted section
+ */
+ } else if (inSegmentRemainNumCW == remainNumCwInSortSec) {
+ pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW;
+ pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
+
+ srtSecCnt++;
+ remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
+ inSegmentRemainNumCW = numSegment;
+ /* data of a sorted section was integrated in extended sorted section */
+ } else { /* inSegmentRemainNumCW > remainNumCwInSortSec */
+ pNumExtSortCwInSect[xSrtScCnt] = remainNumCwInSortSec;
+ pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
+
+ inSegmentRemainNumCW -= remainNumCwInSortSec;
+ srtSecCnt++;
+ remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
+ /* data of a sorted section was integrated in extended sorted section */
+ }
+ pMaxLenOfCbInExtSrtSec[xSrtScCnt] =
+ fMin((INT)pMaxCwLength[pExtendedSortedCoBo[xSrtScCnt]],
+ (INT)lengthOfLongestCodeword);
+
+ xSrtScCnt += 1;
+
+ if (xSrtScCnt >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ pHcr->decInOut.errorLog |= EXTENDED_SORTED_COUNTER_OVERFLOW;
+ return;
+ }
+ }
+ pNumExtSortCwInSect[xSrtScCnt] = 0;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function calculates the number of extended sorted
+sections which belong to the sets. Each set from set 0 (one and only set for the
+PCWs) till to the last set gets a entry in the array to which
+ 'pNumExtendedSortedSectinsInSets' points to.
+
+ Calculation: The entrys in
+pNumExtendedSortedCodewordInSectin are added untill the value numSegment is
+reached. Then the sum_variable is cleared and the calculation starts from the
+beginning. As much extended sorted Sections are summed up to reach the value
+numSegment, as much is the current entry in *pNumExtendedSortedCodewordInSectin.
+--------------------------------------------------------------------------------------------
+*/
+static void DeriveNumberOfExtendedSortedSectionsInSets(
+ UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection,
+ int numExtendedSortedCodewordInSectionIdx,
+ USHORT *pNumExtendedSortedSectionsInSets,
+ int numExtendedSortedSectionsInSetsIdx) {
+ USHORT counter = 0;
+ UINT cwSum = 0;
+ USHORT *pNumExSortCwInSec = pNumExtendedSortedCodewordInSection;
+ USHORT *pNumExSortSecInSets = pNumExtendedSortedSectionsInSets;
+
+ while (pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx] != 0) {
+ cwSum += pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx];
+ numExtendedSortedCodewordInSectionIdx++;
+ if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ return;
+ }
+ if (cwSum > numSegment) {
+ return;
+ }
+ counter++;
+ if (counter > 1024 / 4) {
+ return;
+ }
+ if (cwSum == numSegment) {
+ pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] = counter;
+ numExtendedSortedSectionsInSetsIdx++;
+ if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) {
+ return;
+ }
+ counter = 0;
+ cwSum = 0;
+ }
+ }
+ pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] =
+ counter; /* save last entry for the last - probably shorter - set */
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function decodes all priority codewords (PCWs) in a
+spectrum (within set 0). The calculation of the PCWs is managed in two loops.
+The loopcounter of the outer loop is set to the first value pointer
+ pNumExtendedSortedSectionsInSets points to. This value
+represents the number of extended sorted sections within set 0. The loopcounter
+of the inner loop is set to the first value pointer
+ pNumExtendedSortedCodewordInSectin points to. The value
+represents the number of extended sorted codewords in sections (the original
+sections have been splitted to go along with the borders of the sets). Each time
+the number of the extended sorted codewords in sections are de- coded, the
+pointer 'pNumExtendedSortedCodewordInSectin' is incremented by one.
+--------------------------------------------------------------------------------------------
+*/
+static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
+ UINT i;
+ USHORT extSortSec;
+ USHORT curExtSortCwInSec;
+ UCHAR codebook;
+ UCHAR dimension;
+ const UINT *pCurrentTree;
+ const SCHAR *pQuantValBase;
+ const SCHAR *pQuantVal;
+
+ USHORT *pNumExtendedSortedCodewordInSection =
+ pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
+ int numExtendedSortedCodewordInSectionIdx =
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
+ UCHAR *pExtendedSortedCodebook = pHcr->sectionInfo.pExtendedSortedCodebook;
+ int extendedSortedCodebookIdx = pHcr->sectionInfo.extendedSortedCodebookIdx;
+ USHORT *pNumExtendedSortedSectionsInSets =
+ pHcr->sectionInfo.pNumExtendedSortedSectionsInSets;
+ int numExtendedSortedSectionsInSetsIdx =
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
+ FIXP_DBL *pQuantizedSpectralCoefficients =
+ SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase);
+ int quantizedSpectralCoefficientsIdx =
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx;
+ INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec;
+ int maxLenOfCbInExtSrtSecIdx = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx;
+ UCHAR maxAllowedCwLen;
+ int numDecodedBits;
+ const UCHAR *pCbDimension = aDimCb;
+ const UCHAR *pCbSign = aSignCb;
+
+ /* clear result array */
+ FDKmemclear(pQuantizedSpectralCoefficients + quantizedSpectralCoefficientsIdx,
+ 1024 * sizeof(FIXP_DBL));
+
+ /* decode all PCWs in the extended sorted section(s) belonging to set 0 */
+ for (extSortSec =
+ pNumExtendedSortedSectionsInSets[numExtendedSortedSectionsInSetsIdx];
+ extSortSec != 0; extSortSec--) {
+ codebook =
+ pExtendedSortedCodebook[extendedSortedCodebookIdx]; /* get codebook for
+ this extended
+ sorted section
+ and increment ptr
+ to cb of next
+ ext. sort sec */
+ extendedSortedCodebookIdx++;
+ if (extendedSortedCodebookIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ return;
+ }
+ dimension = pCbDimension[codebook]; /* get dimension of codebook of this
+ extended sort. sec. */
+ pCurrentTree =
+ aHuffTable[codebook]; /* convert codebook to pointer to QSCs */
+ pQuantValBase =
+ aQuantTable[codebook]; /* convert codebook to index to table of QSCs */
+ maxAllowedCwLen = pMaxLenOfCbInExtSrtSec[maxLenOfCbInExtSrtSecIdx];
+ maxLenOfCbInExtSrtSecIdx++;
+ if (maxLenOfCbInExtSrtSecIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ return;
+ }
+
+ /* switch for decoding with different codebooks: */
+ if (pCbSign[codebook] ==
+ 0) { /* no sign bits follow after the codeword-body */
+ /* PCW_BodyONLY */
+ /*==============*/
+
+ for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
+ [numExtendedSortedCodewordInSectionIdx];
+ curExtSortCwInSec != 0; curExtSortCwInSec--) {
+ numDecodedBits = 0;
+
+ /* decode PCW_BODY */
+ pQuantVal = DecodePCW_Body(
+ bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
+ pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
+
+ /* result is written out here because NO sign bits follow the body */
+ for (i = dimension; i != 0; i--) {
+ pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
+ (FIXP_DBL)*pQuantVal++; /* write quant. spec. coef. into
+ spectrum; sign is already valid */
+ quantizedSpectralCoefficientsIdx++;
+ if (quantizedSpectralCoefficientsIdx >= 1024) {
+ return;
+ }
+ }
+
+ /* one more PCW should be decoded */
+
+ if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_ONLY_TOO_LONG)) {
+ pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_BITS_DECODED;
+ }
+
+ if (1 == errDetectPcwSegmentation(
+ *pRemainingBitsInSegment - ERROR_PCW_BODY, pHcr, PCW_BODY,
+ pQuantizedSpectralCoefficients +
+ quantizedSpectralCoefficientsIdx - dimension,
+ dimension)) {
+ return;
+ }
+ pLeftStartOfSegment++; /* update pointer for decoding the next PCW */
+ pRemainingBitsInSegment++; /* update pointer for decoding the next PCW
+ */
+ }
+ } else if ((codebook < 11) && (pCbSign[codebook] ==
+ 1)) { /* possibly there follow 1,2,3 or 4
+ sign bits after the codeword-body */
+ /* PCW_Body and PCW_Sign */
+ /*=======================*/
+
+ for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
+ [numExtendedSortedCodewordInSectionIdx];
+ curExtSortCwInSec != 0; curExtSortCwInSec--) {
+ int err;
+ numDecodedBits = 0;
+
+ pQuantVal = DecodePCW_Body(
+ bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
+ pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
+
+ err = DecodePCW_Sign(
+ bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal,
+ pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx,
+ pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
+ if (err != 0) {
+ return;
+ }
+ /* one more PCW should be decoded */
+
+ if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_SIGN_TOO_LONG)) {
+ pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_BITS_DECODED;
+ }
+
+ if (1 == errDetectPcwSegmentation(
+ *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN, pHcr,
+ PCW_BODY_SIGN,
+ pQuantizedSpectralCoefficients +
+ quantizedSpectralCoefficientsIdx - dimension,
+ dimension)) {
+ return;
+ }
+ pLeftStartOfSegment++;
+ pRemainingBitsInSegment++;
+ }
+ } else if ((pCbSign[codebook] == 1) &&
+ (codebook >= 11)) { /* possibly there follow some sign bits and
+ maybe one or two escape sequences after
+ the cw-body */
+ /* PCW_Body, PCW_Sign and maybe PCW_Escape */
+ /*=========================================*/
+
+ for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
+ [numExtendedSortedCodewordInSectionIdx];
+ curExtSortCwInSec != 0; curExtSortCwInSec--) {
+ int err;
+ numDecodedBits = 0;
+
+ /* decode PCW_BODY */
+ pQuantVal = DecodePCW_Body(
+ bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
+ pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
+
+ err = DecodePCW_Sign(
+ bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal,
+ pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx,
+ pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
+ if (err != 0) {
+ return;
+ }
+
+ /* decode PCW_ESCAPE if present */
+ quantizedSpectralCoefficientsIdx -= DIMENSION_OF_ESCAPE_CODEBOOK;
+
+ if (fixp_abs(pQuantizedSpectralCoefficients
+ [quantizedSpectralCoefficientsIdx]) ==
+ (FIXP_DBL)ESCAPE_VALUE) {
+ pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
+ (FIXP_DBL)DecodeEscapeSequence(
+ bs, pHcr->decInOut.bitstreamAnchor,
+ pQuantizedSpectralCoefficients
+ [quantizedSpectralCoefficientsIdx],
+ pLeftStartOfSegment, pRemainingBitsInSegment,
+ &numDecodedBits);
+ }
+ quantizedSpectralCoefficientsIdx++;
+ if (quantizedSpectralCoefficientsIdx >= 1024) {
+ return;
+ }
+
+ if (fixp_abs(pQuantizedSpectralCoefficients
+ [quantizedSpectralCoefficientsIdx]) ==
+ (FIXP_DBL)ESCAPE_VALUE) {
+ pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
+ (FIXP_DBL)DecodeEscapeSequence(
+ bs, pHcr->decInOut.bitstreamAnchor,
+ pQuantizedSpectralCoefficients
+ [quantizedSpectralCoefficientsIdx],
+ pLeftStartOfSegment, pRemainingBitsInSegment,
+ &numDecodedBits);
+ }
+ quantizedSpectralCoefficientsIdx++;
+ if (quantizedSpectralCoefficientsIdx >= 1024) {
+ return;
+ }
+
+ /* one more PCW should be decoded */
+
+ if (maxAllowedCwLen <
+ (numDecodedBits + ERROR_PCW_BODY_SIGN_ESC_TOO_LONG)) {
+ pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED;
+ }
+
+ if (1 == errDetectPcwSegmentation(
+ *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN_ESC, pHcr,
+ PCW_BODY_SIGN_ESC,
+ pQuantizedSpectralCoefficients +
+ quantizedSpectralCoefficientsIdx -
+ DIMENSION_OF_ESCAPE_CODEBOOK,
+ DIMENSION_OF_ESCAPE_CODEBOOK)) {
+ return;
+ }
+ pLeftStartOfSegment++;
+ pRemainingBitsInSegment++;
+ }
+ }
+
+ /* all PCWs belonging to this extended section should be decoded */
+ numExtendedSortedCodewordInSectionIdx++;
+ if (numExtendedSortedCodewordInSectionIdx >= MAX_SFB_HCR + MAX_HCR_SETS) {
+ return;
+ }
+ }
+ /* all PCWs should be decoded */
+
+ numExtendedSortedSectionsInSetsIdx++;
+ if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) {
+ return;
+ }
+
+ /* Write back indexes into structure */
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
+ numExtendedSortedCodewordInSectionIdx;
+ pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx;
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx =
+ numExtendedSortedSectionsInSetsIdx;
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx =
+ quantizedSpectralCoefficientsIdx;
+ pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = maxLenOfCbInExtSrtSecIdx;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function checks immediately after every decoded PCW,
+whether out of the current segment too many bits have been read or not. If an
+error occurrs, probably the sideinfo or the HCR-bitstream block holding the
+huffman encoded quantized spectral coefficients is distorted. In this case the
+two or four quantized spectral coefficients belonging to the current codeword
+ are marked (for being detected by concealment later).
+--------------------------------------------------------------------------------------------
+*/
+static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment,
+ H_HCR_INFO pHcr, PCW_TYPE kind,
+ FIXP_DBL *qsc_base_of_cw,
+ UCHAR dimension) {
+ SCHAR i;
+ if (remainingBitsInSegment < 0) {
+ /* log the error */
+ switch (kind) {
+ case PCW_BODY:
+ pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY;
+ break;
+ case PCW_BODY_SIGN:
+ pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN;
+ break;
+ case PCW_BODY_SIGN_ESC:
+ pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN_ESC;
+ break;
+ }
+ /* mark the erred lines */
+ for (i = dimension; i != 0; i--) {
+ *qsc_base_of_cw++ = (FIXP_DBL)Q_VALUE_INVALID;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function checks if all segments are empty after
+decoding. There are _no lines markded_ as invalid because it could not be traced
+back where from the remaining bits are.
+--------------------------------------------------------------------------------------------
+*/
+static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr) {
+ UCHAR segmentationErrorFlag = 0;
+ USHORT i;
+ SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ UINT numSegment = pHcr->segmentInfo.numSegment;
+
+ for (i = numSegment; i != 0; i--) {
+ if (*pRemainingBitsInSegment++ != 0) {
+ segmentationErrorFlag = 1;
+ }
+ }
+ if (segmentationErrorFlag == 1) {
+ pHcr->decInOut.errorLog |= BIT_IN_SEGMENTATION_ERROR;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function walks one step within the decoding tree. Which
+branch is taken depends on the decoded carryBit input parameter.
+--------------------------------------------------------------------------------------------
+*/
+void CarryBitToBranchValue(UCHAR carryBit, UINT treeNode, UINT *branchValue,
+ UINT *branchNode) {
+ if (carryBit == 0) {
+ *branchNode =
+ (treeNode & MASK_LEFT) >> LEFT_OFFSET; /* MASK_LEFT: 00FFF000 */
+ } else {
+ *branchNode = treeNode & MASK_RIGHT; /* MASK_RIGHT: 00000FFF */
+ }
+
+ *branchValue = *branchNode & CLR_BIT_10; /* clear bit 10 (if set) */
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decodes the body of a priority codeword (PCW)
+-----------------------------------------------------------------------------------------------
+ return: - return value is pointer to first of two or four quantized
+spectral coefficients
+--------------------------------------------------------------------------------------------
+*/
+static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ const UINT *pCurrentTree,
+ const SCHAR *pQuantValBase,
+ INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment,
+ int *pNumDecodedBits) {
+ UCHAR carryBit;
+ UINT branchNode;
+ UINT treeNode;
+ UINT branchValue;
+ const SCHAR *pQuantVal;
+
+ /* decode PCW_BODY */
+ treeNode = *pCurrentTree; /* get first node of current tree belonging to
+ current codebook */
+
+ /* decode whole PCW-codeword-body */
+ while (1) {
+ carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
+ pLeftStartOfSegment, /* dummy */
+ FROM_LEFT_TO_RIGHT);
+ *pRemainingBitsInSegment -= 1;
+ *pNumDecodedBits += 1;
+
+ CarryBitToBranchValue(carryBit, treeNode, &branchValue, &branchNode);
+
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; if set --> codeword-body is complete */
+ break; /* end of branch in tree reached i.e. a whole PCW-Body is decoded
+ */
+ } else {
+ treeNode = *(
+ pCurrentTree +
+ branchValue); /* update treeNode for further step in decoding tree */
+ }
+ }
+
+ pQuantVal =
+ pQuantValBase + branchValue; /* update pointer to valid first of 2 or 4
+ quantized values */
+
+ return pQuantVal;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function decodes one escape sequence. In case of a
+escape codebook and in case of the absolute value of the quantized spectral
+value == 16, a escapeSequence is decoded in two steps:
+ 1. escape prefix
+ 2. escape word
+--------------------------------------------------------------------------------------------
+*/
+
+static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT quantSpecCoef, INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment,
+ int *pNumDecodedBits) {
+ UINT i;
+ INT sign;
+ UINT escapeOnesCounter = 0;
+ UINT carryBit;
+ INT escape_word = 0;
+
+ /* decode escape prefix */
+ while (1) {
+ carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
+ pLeftStartOfSegment, /* dummy */
+ FROM_LEFT_TO_RIGHT);
+ *pRemainingBitsInSegment -= 1;
+ *pNumDecodedBits += 1;
+
+ if (carryBit != 0) {
+ escapeOnesCounter += 1;
+ } else {
+ escapeOnesCounter += 4;
+ break;
+ }
+ }
+
+ /* decode escape word */
+ for (i = escapeOnesCounter; i != 0; i--) {
+ carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
+ pLeftStartOfSegment, /* dummy */
+ FROM_LEFT_TO_RIGHT);
+ *pRemainingBitsInSegment -= 1;
+ *pNumDecodedBits += 1;
+
+ escape_word <<= 1;
+ escape_word = escape_word | carryBit;
+ }
+
+ sign = (quantSpecCoef >= 0) ? 1 : -1;
+
+ quantSpecCoef = sign * (((INT)1 << escapeOnesCounter) + escape_word);
+
+ return quantSpecCoef;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decodes the Signbits of a priority codeword (PCW) and writes
+out the resulting quantized spectral values into unsorted sections
+-----------------------------------------------------------------------------------------------
+ output: - two or four lines at position in corresponding section
+(which are not located at the desired position, i.e. they must be reordered in
+the last of eight function of HCR)
+-----------------------------------------------------------------------------------------------
+ return: - updated pQuantSpecCoef pointer (to next empty storage for a
+line)
+--------------------------------------------------------------------------------------------
+*/
+static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ UINT codebookDim, const SCHAR *pQuantVal,
+ FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx,
+ INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment,
+ int *pNumDecodedBits) {
+ UINT i;
+ UINT carryBit;
+ INT quantSpecCoef;
+
+ for (i = codebookDim; i != 0; i--) {
+ quantSpecCoef = *pQuantVal++;
+ if (quantSpecCoef != 0) {
+ carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
+ pLeftStartOfSegment, /* dummy */
+ FROM_LEFT_TO_RIGHT);
+ *pRemainingBitsInSegment -= 1;
+ *pNumDecodedBits += 1;
+ if (*pRemainingBitsInSegment < 0 || *pNumDecodedBits >= (1024 >> 1)) {
+ return -1;
+ }
+
+ /* adapt sign of values according to the decoded sign bit */
+ if (carryBit != 0) {
+ pQuantSpecCoef[*quantSpecCoefIdx] = -(FIXP_DBL)quantSpecCoef;
+ } else {
+ pQuantSpecCoef[*quantSpecCoefIdx] = (FIXP_DBL)quantSpecCoef;
+ }
+ } else {
+ pQuantSpecCoef[*quantSpecCoefIdx] = FL2FXCONST_DBL(0.0f);
+ }
+ *quantSpecCoefIdx += 1;
+ if (*quantSpecCoefIdx >= 1024) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Mutes spectral lines which have been marked as erroneous
+(Q_VALUE_INVALID)
+--------------------------------------------------------------------------------------------
+*/
+void HcrMuteErroneousLines(H_HCR_INFO hHcr) {
+ int c;
+ FIXP_DBL *RESTRICT pLong =
+ SPEC_LONG(hHcr->decInOut.pQuantizedSpectralCoefficientsBase);
+
+ /* if there is a line with value Q_VALUE_INVALID mute it */
+ for (c = 0; c < 1024; c++) {
+ if (pLong[c] == (FIXP_DBL)Q_VALUE_INVALID) {
+ pLong[c] = FL2FXCONST_DBL(0.0f); /* muting */
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_hcr.h b/fdk-aac/libAACdec/src/aacdec_hcr.h
new file mode 100644
index 0000000..be21144
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcr.h
@@ -0,0 +1,128 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Interface function declaration; common defines
+ and structures; defines for switching error-generator,
+ -detector, and -concealment
+
+*******************************************************************************/
+
+#ifndef AACDEC_HCR_H
+#define AACDEC_HCR_H
+
+#include "channelinfo.h"
+#include "FDK_bitstream.h"
+
+UINT HcrInit(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ HANDLE_FDK_BITSTREAM bs);
+UINT HcrDecoder(H_HCR_INFO hHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ HANDLE_FDK_BITSTREAM bs);
+void CarryBitToBranchValue(UCHAR carryBit, UINT treeNode, UINT *branchValue,
+ UINT *branchNode);
+
+void CHcr_Read(HANDLE_FDK_BITSTREAM bs,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const MP4_ELEMENT_ID globalHcrType);
+void HcrMuteErroneousLines(H_HCR_INFO hHcr);
+
+void setHcrType(H_HCR_INFO hHcr, MP4_ELEMENT_ID type);
+INT getHcrType(H_HCR_INFO hHcr);
+
+#endif /* AACDEC_HCR_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_hcr_bit.cpp b/fdk-aac/libAACdec/src/aacdec_hcr_bit.cpp
new file mode 100644
index 0000000..0198659
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcr_bit.cpp
@@ -0,0 +1,164 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Bitstream reading
+
+*******************************************************************************/
+
+#include "aacdec_hcr_bit.h"
+
+/*---------------------------------------------------------------------------------------------
+ description: This function toggles the read direction.
+-----------------------------------------------------------------------------------------------
+ input: current read direction
+-----------------------------------------------------------------------------------------------
+ return: new read direction
+--------------------------------------------------------------------------------------------
+*/
+UCHAR ToggleReadDirection(UCHAR readDirection) {
+ if (readDirection == FROM_LEFT_TO_RIGHT) {
+ return FROM_RIGHT_TO_LEFT;
+ } else {
+ return FROM_LEFT_TO_RIGHT;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function returns a bit from the bitstream according to
+read direction. It is called very often, therefore it makes sense to inline it
+(runtime).
+-----------------------------------------------------------------------------------------------
+ input: - handle to FDK bitstream
+ - reference value marking start of bitfield
+ - pLeftStartOfSegment
+ - pRightStartOfSegment
+ - readDirection
+-----------------------------------------------------------------------------------------------
+ return: - bit from bitstream
+--------------------------------------------------------------------------------------------
+*/
+UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT *pLeftStartOfSegment,
+ INT *pRightStartOfSegment, UCHAR readDirection) {
+ UINT bit;
+ INT readBitOffset;
+
+ if (readDirection == FROM_LEFT_TO_RIGHT) {
+ readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pLeftStartOfSegment;
+ if (readBitOffset) {
+ FDKpushBiDirectional(bs, readBitOffset);
+ }
+
+ bit = FDKreadBits(bs, 1);
+
+ *pLeftStartOfSegment += 1;
+ } else {
+ readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pRightStartOfSegment;
+ if (readBitOffset) {
+ FDKpushBiDirectional(bs, readBitOffset);
+ }
+
+ /* to be replaced with a brother function of FDKreadBits() */
+ bit = FDKreadBits(bs, 1);
+ FDKpushBack(bs, 2);
+
+ *pRightStartOfSegment -= 1;
+ }
+
+ return (bit);
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_hcr_bit.h b/fdk-aac/libAACdec/src/aacdec_hcr_bit.h
new file mode 100644
index 0000000..77242ac
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcr_bit.h
@@ -0,0 +1,114 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Bitstream reading prototypes
+
+*******************************************************************************/
+
+#ifndef AACDEC_HCR_BIT_H
+#define AACDEC_HCR_BIT_H
+
+#include "aacdec_hcr.h"
+
+UCHAR ToggleReadDirection(UCHAR readDirection);
+
+UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT *pLeftStartOfSegment,
+ INT *pRightStartOfSegment, UCHAR readDirection);
+
+#endif /* AACDEC_HCR_BIT_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_hcr_types.h b/fdk-aac/libAACdec/src/aacdec_hcr_types.h
new file mode 100644
index 0000000..1cc3cb0
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcr_types.h
@@ -0,0 +1,432 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Common defines and structures; defines for
+ switching error-generator, -detector, and -concealment;
+
+*******************************************************************************/
+
+#ifndef AACDEC_HCR_TYPES_H
+#define AACDEC_HCR_TYPES_H
+
+#include "FDK_bitstream.h"
+#include "overlapadd.h"
+
+/* ------------------------------------------------ */
+/* ------------------------------------------------ */
+
+#define LINES_PER_UNIT 4
+
+/* ------------------------------------------------ */
+/* ------------------------------------------------ */
+/* ----------- basic HCR configuration ------------ */
+
+#define MAX_SFB_HCR \
+ (((1024 / 8) / LINES_PER_UNIT) * 8) /* (8 * 16) is not enough because sfbs \
+ are split in units for blocktype \
+ short */
+#define NUMBER_OF_UNIT_GROUPS (LINES_PER_UNIT * 8)
+#define LINES_PER_UNIT_GROUP (1024 / NUMBER_OF_UNIT_GROUPS) /* 15 16 30 32 */
+
+/* ------------------------------------------------ */
+/* ------------------------------------------------ */
+/* ------------------------------------------------ */
+
+#define FROM_LEFT_TO_RIGHT 0
+#define FROM_RIGHT_TO_LEFT 1
+
+#define MAX_CB_PAIRS 23
+#define MAX_HCR_SETS 14
+
+#define ESCAPE_VALUE 16
+#define POSITION_OF_FLAG_A 21
+#define POSITION_OF_FLAG_B 20
+
+#define MAX_CB 32 /* last used CB is cb #31 when VCB11 is used */
+
+#define MAX_CB_CHECK \
+ 32 /* support for VCB11 available -- is more general, could therefore used \
+ in both cases */
+
+#define NUMBER_OF_BIT_IN_WORD 32
+
+/* log */
+#define THIRTYTWO_LOG_DIV_TWO_LOG 5
+#define EIGHT_LOG_DIV_TWO_LOG 3
+#define FOUR_LOG_DIV_TWO_LOG 2
+
+/* borders */
+#define CPE_TOP_LENGTH 12288
+#define SCE_TOP_LENGTH 6144
+#define LEN_OF_LONGEST_CW_TOP_LENGTH 49
+
+/* qsc's of high level */
+#define Q_VALUE_INVALID \
+ 8192 /* mark a invalid line with this value (to be concealed later on) */
+#define HCR_DIRAC 500 /* a line of high level */
+
+/* masks */
+#define MASK_LEFT 0xFFF000
+#define MASK_RIGHT 0xFFF
+#define CLR_BIT_10 0x3FF
+#define TEST_BIT_10 0x400
+
+#define LEFT_OFFSET 12
+
+/* when set HCR is replaced by a dummy-module which just fills the outputbuffer
+ * with a dirac sequence */
+/* use this if HCR is suspected to write in other modules -- if error is stell
+ * there, HCR is innocent */
+
+/* ------------------------------ */
+/* - insert HCR errors - */
+/* ------------------------------ */
+
+/* modify input lengths -- high protected */
+#define ERROR_LORSD 0 /* offset: error if different from zero */
+#define ERROR_LOLC 0 /* offset: error if different from zero */
+
+/* segments are earlier empty as expected when decoding PCWs */
+#define ERROR_PCW_BODY \
+ 0 /* set a positive values to trigger the error (make segments earlyer \
+ appear to be empty) */
+#define ERROR_PCW_BODY_SIGN \
+ 0 /* set a positive values to trigger the error (make segments earlyer \
+ appear to be empty) */
+#define ERROR_PCW_BODY_SIGN_ESC \
+ 0 /* set a positive values to trigger the error (make segments earlyer \
+ appear to be empty) */
+
+/* pretend there are too many bits decoded (enlarge length of codeword) at PCWs
+ * -- use a positive value */
+#define ERROR_PCW_BODY_ONLY_TOO_LONG \
+ 0 /* set a positive values to trigger the error */
+#define ERROR_PCW_BODY_SIGN_TOO_LONG \
+ 0 /* set a positive values to trigger the error */
+#define ERROR_PCW_BODY_SIGN_ESC_TOO_LONG \
+ 0 /* set a positive values to trigger the error */
+
+/* modify HCR bitstream block */
+
+#define MODULO_DIVISOR_HCR 30
+
+/* ------------------------------ */
+/* - detect HCR errors - */
+/* ------------------------------ */
+/* check input data */
+
+/* during decoding */
+
+/* all the segments are checked -- therefore -- if this check passes, its a kind
+ of evidence that the decoded PCWs and non-PCWs are fine */
+
+/* if a codeword is decoded there exists a border for the number of bits, which
+ are allowed to read for this codeword. This border is the minimum of the
+ length of the longest codeword (for the currently used codebook) and the
+ separately transmitted 'lengthOfLongestCodeword' in this frame and channel.
+ The number of decoded bits is counted (for PCWs only -- there it makes really
+ sense in my opinion). If this number exceeds the border (derived as minimum
+ -- see above), a error is detected. */
+
+/* -----------------------------------------------------------------------------------------------------
+ This error check could be set to zero because due to a test within
+ RVLC-Escape-huffman-Decoder a too long codeword could not be detected -- it
+ seems that for RVLC-Escape-Codeword the coderoom is used to 100%. Therefore I
+ assume that the coderoom is used to 100% also for the codebooks 1..11 used at
+ HCR Therefore this test is deactivated pending further notice
+ -----------------------------------------------------------------------------------------------------
+ */
+
+/* test if the number of remaining bits in a segment is _below_ zero. If there
+ are no errors the lowest allowed value for remainingBitsInSegment is zero.
+ This check also could be set to zero (save runtime) */
+
+/* other */
+/* when set to '1', avoid setting the LAV-Flag in errorLog due to a
+ previous-line-marking (at PCW decoder). A little more runtime is needed then
+ when writing values out into output-buffer. */
+
+/* ------------------------------ */
+/* - conceal HCR errors - */
+/* ------------------------------ */
+
+#define HCR_ERROR_CONCEALMENT \
+ 1 /* if set to '1', HCR _mutes_ the erred quantized spectral coefficients */
+
+// ------------------------------------------------------------------------------------------------------------------
+// errorLog: A word of 32 bits used for
+// logging possible errors within HCR
+// in case of distorted
+// bitstreams. Table of all
+// known errors:
+// ------------------------------------------------------------------------------------------------------------------------
+// bit fatal location meaning
+// ----+-----+-----------+--------------------------------------
+#define SEGMENT_OVERRIDE_ERR_PCW_BODY \
+ 0x80000000 // 31 no PCW-Dec During PCW decoding it is checked after
+ // every PCW if there are too many bits decoded (immediate
+ // check).
+#define SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN \
+ 0x40000000 // 30 no PCW-Dec During PCW decoding it is checked after
+ // every PCW if there are too many bits decoded (immediate
+ // check).
+#define SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN_ESC \
+ 0x20000000 // 29 no PCW-Dec During PCW decoding it is checked after
+ // every PCW if there are too many bits decoded (immediate
+ // check).
+#define EXTENDED_SORTED_COUNTER_OVERFLOW \
+ 0x10000000 // 28 yes Init-Dec Error during extending sideinfo
+ // (neither a PCW nor a nonPCW was decoded so far)
+ // 0x08000000 // 27 reserved
+ // 0x04000000 // 26 reserved
+ // 0x02000000 // 25 reserved
+ // 0x01000000 // 24 reserved
+ // 0x00800000 // 23 reserved
+ // 0x00400000 // 22 reserved
+ // 0x00200000 // 21 reserved
+ // 0x00100000 // 20 reserved
+
+/* special errors */
+#define TOO_MANY_PCW_BODY_BITS_DECODED \
+ 0x00080000 // 19 yes PCW-Dec During PCW-body-decoding too many bits
+ // have been read from bitstream -- advice: skip non-PCW decoding
+#define TOO_MANY_PCW_BODY_SIGN_BITS_DECODED \
+ 0x00040000 // 18 yes PCW-Dec During PCW-body-sign-decoding too many
+ // bits have been read from bitstream -- advice: skip non-PCW
+ // decoding
+#define TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED \
+ 0x00020000 // 17 yes PCW-Dec During PCW-body-sign-esc-decoding too
+ // many bits have been read from bitstream -- advice: skip
+ // non-PCW decoding
+
+// 0x00010000 // 16 reserved
+#define STATE_ERROR_BODY_ONLY \
+ 0x00008000 // 15 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN__BODY \
+ 0x00004000 // 14 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN__SIGN \
+ 0x00002000 // 13 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN_ESC__BODY \
+ 0x00001000 // 12 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN_ESC__SIGN \
+ 0x00000800 // 11 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX \
+ 0x00000400 // 10 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN_ESC__ESC_WORD \
+ 0x00000200 // 9 no NonPCW-Dec State machine returned with error
+#define HCR_SI_LENGTHS_FAILURE \
+ 0x00000100 // 8 yes Init-Dec LengthOfLongestCodeword must not be
+ // less than lenghtOfReorderedSpectralData
+#define NUM_SECT_OUT_OF_RANGE_SHORT_BLOCK \
+ 0x00000080 // 7 yes Init-Dec The number of sections is not within
+ // the allowed range (short block)
+#define NUM_SECT_OUT_OF_RANGE_LONG_BLOCK \
+ 0x00000040 // 6 yes Init-Dec The number of sections is not within
+ // the allowed range (long block)
+#define LINE_IN_SECT_OUT_OF_RANGE_SHORT_BLOCK \
+ 0x00000020 // 5 yes Init-Dec The number of lines per section is not
+ // within the allowed range (short block)
+#define CB_OUT_OF_RANGE_SHORT_BLOCK \
+ 0x00000010 // 4 yes Init-Dec The codebook is not within the allowed
+ // range (short block)
+#define LINE_IN_SECT_OUT_OF_RANGE_LONG_BLOCK \
+ 0x00000008 // 3 yes Init-Dec The number of lines per section is not
+ // within the allowed range (long block)
+#define CB_OUT_OF_RANGE_LONG_BLOCK \
+ 0x00000004 // 2 yes Init-Dec The codebook is not within the allowed
+ // range (long block)
+#define LAV_VIOLATION \
+ 0x00000002 // 1 no Final The absolute value of at least one
+ // decoded line was too high for the according codebook.
+#define BIT_IN_SEGMENTATION_ERROR \
+ 0x00000001 // 0 no Final After PCW and non-PWC-decoding at least
+ // one segment is not zero (global check).
+
+/*----------*/
+#define HCR_FATAL_PCW_ERROR_MASK 0x100E01FC
+
+typedef enum { PCW_BODY, PCW_BODY_SIGN, PCW_BODY_SIGN_ESC } PCW_TYPE;
+
+/* interface Decoder <---> HCR */
+typedef struct {
+ UINT errorLog;
+ SPECTRAL_PTR pQuantizedSpectralCoefficientsBase;
+ int quantizedSpectralCoefficientsIdx;
+ SHORT lengthOfReorderedSpectralData;
+ SHORT numSection;
+ SHORT *pNumLineInSect;
+ INT bitstreamAnchor;
+ SCHAR lengthOfLongestCodeword;
+ UCHAR *pCodebook;
+} HCR_INPUT_OUTPUT;
+
+typedef struct {
+ const UCHAR *pMinOfCbPair;
+ const UCHAR *pMaxOfCbPair;
+} HCR_CB_PAIRS;
+
+typedef struct {
+ const USHORT *pLargestAbsVal;
+ const UCHAR *pMaxCwLength;
+ const UCHAR *pCbDimension;
+ const UCHAR *pCbDimShift;
+ const UCHAR *pCbSign;
+ const UCHAR *pCbPriority;
+} HCR_TABLE_INFO;
+
+typedef struct {
+ UINT numSegment;
+ UINT pSegmentBitfield[((1024 >> 1) / NUMBER_OF_BIT_IN_WORD + 1)];
+ UINT pCodewordBitfield[((1024 >> 1) / NUMBER_OF_BIT_IN_WORD + 1)];
+ UINT segmentOffset;
+ INT pLeftStartOfSegment[1024 >> 1];
+ INT pRightStartOfSegment[1024 >> 1];
+ SCHAR pRemainingBitsInSegment[1024 >> 1];
+ UCHAR readDirection;
+ UCHAR numWordForBitfield;
+ USHORT pNumBitValidInLastWord;
+} HCR_SEGMENT_INFO;
+
+typedef struct {
+ UINT numCodeword;
+ UINT numSortedSection;
+ USHORT pNumCodewordInSection[MAX_SFB_HCR];
+ USHORT pNumSortedCodewordInSection[MAX_SFB_HCR];
+ USHORT pNumExtendedSortedCodewordInSection[MAX_SFB_HCR + MAX_HCR_SETS];
+ int numExtendedSortedCodewordInSectionIdx;
+ USHORT pNumExtendedSortedSectionsInSets[MAX_HCR_SETS];
+ int numExtendedSortedSectionsInSetsIdx;
+ USHORT pReorderOffset[MAX_SFB_HCR];
+ UCHAR pSortedCodebook[MAX_SFB_HCR];
+
+ UCHAR pExtendedSortedCodebook[MAX_SFB_HCR + MAX_HCR_SETS];
+ int extendedSortedCodebookIdx;
+ UCHAR pMaxLenOfCbInExtSrtSec[MAX_SFB_HCR + MAX_HCR_SETS];
+ int maxLenOfCbInExtSrtSecIdx;
+ UCHAR pCodebookSwitch[MAX_SFB_HCR];
+} HCR_SECTION_INFO;
+
+typedef UINT (*STATEFUNC)(HANDLE_FDK_BITSTREAM, void *);
+
+typedef struct {
+ /* worst-case and 1024/4 non-PCWs exist in worst-case */
+ FIXP_DBL
+ *pResultBase; /* Base address for spectral data output target buffer */
+ UINT iNode[1024 >> 2]; /* Helper indices for code books */
+ USHORT
+ iResultPointer[1024 >> 2]; /* Helper indices for accessing pResultBase */
+ UINT pEscapeSequenceInfo[1024 >> 2];
+ UINT codewordOffset;
+ STATEFUNC pState;
+ UCHAR pCodebook[1024 >> 2];
+ UCHAR pCntSign[1024 >> 2];
+ /* this array holds the states coded as integer values within the range
+ * [0,1,..,7] */
+ SCHAR pSta[1024 >> 2];
+} HCR_NON_PCW_SIDEINFO;
+
+typedef struct {
+ HCR_INPUT_OUTPUT decInOut;
+ HCR_SEGMENT_INFO segmentInfo;
+ HCR_SECTION_INFO sectionInfo;
+ HCR_NON_PCW_SIDEINFO nonPcwSideinfo;
+} CErHcrInfo;
+
+typedef CErHcrInfo *H_HCR_INFO;
+
+#endif /* AACDEC_HCR_TYPES_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_hcrs.cpp b/fdk-aac/libAACdec/src/aacdec_hcrs.cpp
new file mode 100644
index 0000000..d2bc867
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcrs.cpp
@@ -0,0 +1,1551 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Prepare decoding of non-PCWs, segmentation- and
+ bitfield-handling, HCR-Statemachine
+
+*******************************************************************************/
+
+#include "aacdec_hcrs.h"
+
+#include "aacdec_hcr.h"
+
+#include "aacdec_hcr_bit.h"
+#include "aac_rom.h"
+#include "aac_ram.h"
+
+static UINT InitSegmentBitfield(UINT *pNumSegment,
+ SCHAR *pRemainingBitsInSegment,
+ UINT *pSegmentBitfield,
+ UCHAR *pNumWordForBitfield,
+ USHORT *pNumBitValidInLastWord);
+
+static void InitNonPCWSideInformationForCurrentSet(H_HCR_INFO pHcr);
+
+static INT ModuloValue(INT input, INT bufferlength);
+
+static void ClearBitFromBitfield(STATEFUNC *ptrState, UINT offset,
+ UINT *pBitfield);
+
+/*---------------------------------------------------------------------------------------------
+ description: This function decodes all non-priority codewords (non-PCWs) by
+using a state-machine.
+--------------------------------------------------------------------------------------------
+*/
+void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
+ UINT numValidSegment;
+ INT segmentOffset;
+ INT codewordOffsetBase;
+ INT codewordOffset;
+ UINT trial;
+
+ UINT *pNumSegment;
+ SCHAR *pRemainingBitsInSegment;
+ UINT *pSegmentBitfield;
+ UCHAR *pNumWordForBitfield;
+ USHORT *pNumBitValidInLastWord;
+ UINT *pCodewordBitfield;
+ INT bitfieldWord;
+ INT bitInWord;
+ UINT tempWord;
+ UINT interMediateWord;
+ INT tempBit;
+ INT carry;
+
+ UINT numCodeword;
+ UCHAR numSet;
+ UCHAR currentSet;
+ UINT codewordInSet;
+ UINT remainingCodewordsInSet;
+ SCHAR *pSta;
+ UINT ret;
+
+ pNumSegment = &(pHcr->segmentInfo.numSegment);
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pNumWordForBitfield = &(pHcr->segmentInfo.numWordForBitfield);
+ pNumBitValidInLastWord = &(pHcr->segmentInfo.pNumBitValidInLastWord);
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ numValidSegment = InitSegmentBitfield(pNumSegment, pRemainingBitsInSegment,
+ pSegmentBitfield, pNumWordForBitfield,
+ pNumBitValidInLastWord);
+
+ if (numValidSegment != 0) {
+ numCodeword = pHcr->sectionInfo.numCodeword;
+ numSet = ((numCodeword - 1) / *pNumSegment) + 1;
+
+ pHcr->segmentInfo.readDirection = FROM_RIGHT_TO_LEFT;
+
+ /* Process sets subsequently */
+ for (currentSet = 1; currentSet < numSet; currentSet++) {
+ /* step 1 */
+ numCodeword -=
+ *pNumSegment; /* number of remaining non PCWs [for all sets] */
+ if (numCodeword < *pNumSegment) {
+ codewordInSet = numCodeword; /* for last set */
+ } else {
+ codewordInSet = *pNumSegment; /* for all sets except last set */
+ }
+
+ /* step 2 */
+ /* prepare array 'CodewordBitfield'; as much ones are written from left in
+ * all words, as much decodedCodewordInSetCounter nonPCWs exist in this
+ * set */
+ tempWord = 0xFFFFFFFF;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+
+ for (bitfieldWord = *pNumWordForBitfield; bitfieldWord != 0;
+ bitfieldWord--) { /* loop over all used words */
+ if (codewordInSet > NUMBER_OF_BIT_IN_WORD) { /* more codewords than
+ number of bits => fill
+ ones */
+ /* fill a whole word with ones */
+ *pCodewordBitfield++ = tempWord;
+ codewordInSet -= NUMBER_OF_BIT_IN_WORD; /* subtract number of bits */
+ } else {
+ /* prepare last tempWord */
+ for (remainingCodewordsInSet = codewordInSet;
+ remainingCodewordsInSet < NUMBER_OF_BIT_IN_WORD;
+ remainingCodewordsInSet++) {
+ tempWord =
+ tempWord &
+ ~(1
+ << (NUMBER_OF_BIT_IN_WORD - 1 -
+ remainingCodewordsInSet)); /* set a zero at bit number
+ (NUMBER_OF_BIT_IN_WORD-1-i)
+ in tempWord */
+ }
+ *pCodewordBitfield++ = tempWord;
+ tempWord = 0x00000000;
+ }
+ }
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+
+ /* step 3 */
+ /* build non-PCW sideinfo for each non-PCW of the current set */
+ InitNonPCWSideInformationForCurrentSet(pHcr);
+
+ /* step 4 */
+ /* decode all non-PCWs belonging to this set */
+
+ /* loop over trials */
+ codewordOffsetBase = 0;
+ for (trial = *pNumSegment; trial > 0; trial--) {
+ /* loop over number of words in bitfields */
+ segmentOffset = 0; /* start at zero in every segment */
+ pHcr->segmentInfo.segmentOffset =
+ segmentOffset; /* store in structure for states */
+ codewordOffset = codewordOffsetBase;
+ pHcr->nonPcwSideinfo.codewordOffset =
+ codewordOffset; /* store in structure for states */
+
+ for (bitfieldWord = 0; bitfieldWord < *pNumWordForBitfield;
+ bitfieldWord++) {
+ /* derive tempWord with bitwise and */
+ tempWord =
+ pSegmentBitfield[bitfieldWord] & pCodewordBitfield[bitfieldWord];
+
+ /* if tempWord is not zero, decode something */
+ if (tempWord != 0) {
+ /* loop over all bits in tempWord; start state machine if & is true
+ */
+ for (bitInWord = NUMBER_OF_BIT_IN_WORD; bitInWord > 0;
+ bitInWord--) {
+ interMediateWord = ((UINT)1 << (bitInWord - 1));
+ if ((tempWord & interMediateWord) == interMediateWord) {
+ /* get state and start state machine */
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]];
+
+ while (pHcr->nonPcwSideinfo.pState) {
+ ret = ((STATEFUNC)pHcr->nonPcwSideinfo.pState)(bs, pHcr);
+ if (ret != 0) {
+ return;
+ }
+ }
+ }
+
+ /* update both offsets */
+ segmentOffset += 1; /* add NUMBER_OF_BIT_IN_WORD times one */
+ pHcr->segmentInfo.segmentOffset = segmentOffset;
+ codewordOffset += 1; /* add NUMBER_OF_BIT_IN_WORD times one */
+ codewordOffset =
+ ModuloValue(codewordOffset,
+ *pNumSegment); /* index of the current codeword
+ lies within modulo range */
+ pHcr->nonPcwSideinfo.codewordOffset = codewordOffset;
+ }
+ } else {
+ segmentOffset +=
+ NUMBER_OF_BIT_IN_WORD; /* add NUMBER_OF_BIT_IN_WORD at once */
+ pHcr->segmentInfo.segmentOffset = segmentOffset;
+ codewordOffset +=
+ NUMBER_OF_BIT_IN_WORD; /* add NUMBER_OF_BIT_IN_WORD at once */
+ codewordOffset = ModuloValue(
+ codewordOffset,
+ *pNumSegment); /* index of the current codeword lies within
+ modulo range */
+ pHcr->nonPcwSideinfo.codewordOffset = codewordOffset;
+ }
+ } /* end of bitfield word loop */
+
+ /* decrement codeword - pointer */
+ codewordOffsetBase -= 1;
+ codewordOffsetBase =
+ ModuloValue(codewordOffsetBase, *pNumSegment); /* index of the
+ current codeword
+ base lies within
+ modulo range */
+
+ /* rotate numSegment bits in codewordBitfield */
+ /* rotation of *numSegment bits in bitfield of codewords
+ * (circle-rotation) */
+ /* get last valid bit */
+ tempBit = pCodewordBitfield[*pNumWordForBitfield - 1] &
+ (1 << (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord));
+ tempBit = tempBit >> (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord);
+
+ /* write zero into place where tempBit was fetched from */
+ pCodewordBitfield[*pNumWordForBitfield - 1] =
+ pCodewordBitfield[*pNumWordForBitfield - 1] &
+ ~(1 << (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord));
+
+ /* rotate last valid word */
+ pCodewordBitfield[*pNumWordForBitfield - 1] =
+ pCodewordBitfield[*pNumWordForBitfield - 1] >> 1;
+
+ /* transfare carry bit 0 from current word into bitposition 31 from next
+ * word and rotate current word */
+ for (bitfieldWord = *pNumWordForBitfield - 2; bitfieldWord > -1;
+ bitfieldWord--) {
+ /* get carry (=bit at position 0) from current word */
+ carry = pCodewordBitfield[bitfieldWord] & 1;
+
+ /* put the carry bit at position 31 into word right from current word
+ */
+ pCodewordBitfield[bitfieldWord + 1] =
+ pCodewordBitfield[bitfieldWord + 1] |
+ (carry << (NUMBER_OF_BIT_IN_WORD - 1));
+
+ /* shift current word */
+ pCodewordBitfield[bitfieldWord] =
+ pCodewordBitfield[bitfieldWord] >> 1;
+ }
+
+ /* put tempBit into free bit-position 31 from first word */
+ pCodewordBitfield[0] =
+ pCodewordBitfield[0] | (tempBit << (NUMBER_OF_BIT_IN_WORD - 1));
+
+ } /* end of trial loop */
+
+ /* toggle read direction */
+ pHcr->segmentInfo.readDirection =
+ ToggleReadDirection(pHcr->segmentInfo.readDirection);
+ }
+ /* end of set loop */
+
+ /* all non-PCWs of this spectrum are decoded */
+ }
+
+ /* all PCWs and all non PCWs are decoded. They are unbacksorted in output
+ * buffer. Here is the Interface with comparing QSCs to asm decoding */
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function prepares the bitfield used for the
+ segments. The list is set up once to be used in all
+following sets. If a segment is decoded empty, the according bit from the
+Bitfield is removed.
+-----------------------------------------------------------------------------------------------
+ return: numValidSegment = the number of valid segments
+--------------------------------------------------------------------------------------------
+*/
+static UINT InitSegmentBitfield(UINT *pNumSegment,
+ SCHAR *pRemainingBitsInSegment,
+ UINT *pSegmentBitfield,
+ UCHAR *pNumWordForBitfield,
+ USHORT *pNumBitValidInLastWord) {
+ SHORT i;
+ USHORT r;
+ UCHAR bitfieldWord;
+ UINT tempWord;
+ USHORT numValidSegment;
+
+ *pNumWordForBitfield =
+ (*pNumSegment == 0)
+ ? 0
+ : ((*pNumSegment - 1) >> THIRTYTWO_LOG_DIV_TWO_LOG) + 1;
+
+ /* loop over all words, which are completely used or only partial */
+ /* bit in pSegmentBitfield is zero if segment is empty; bit in
+ * pSegmentBitfield is one if segment is not empty */
+ numValidSegment = 0;
+ *pNumBitValidInLastWord = *pNumSegment;
+
+ /* loop over words */
+ for (bitfieldWord = 0; bitfieldWord < *pNumWordForBitfield - 1;
+ bitfieldWord++) {
+ tempWord = 0xFFFFFFFF; /* set ones */
+ r = bitfieldWord << THIRTYTWO_LOG_DIV_TWO_LOG;
+ for (i = 0; i < NUMBER_OF_BIT_IN_WORD; i++) {
+ if (pRemainingBitsInSegment[r + i] == 0) {
+ tempWord = tempWord & ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 -
+ i)); /* set a zero at bit number
+ (NUMBER_OF_BIT_IN_WORD-1-i) in
+ tempWord */
+ } else {
+ numValidSegment += 1; /* count segments which are not empty */
+ }
+ }
+ pSegmentBitfield[bitfieldWord] = tempWord; /* store result */
+ *pNumBitValidInLastWord -= NUMBER_OF_BIT_IN_WORD; /* calculate number of
+ zeros on LSB side in
+ the last word */
+ }
+
+ /* calculate last word: prepare special tempWord */
+ tempWord = 0xFFFFFFFF;
+ for (i = 0; i < (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord); i++) {
+ tempWord = tempWord & ~(1 << i); /* clear bit i in tempWord */
+ }
+
+ /* calculate last word */
+ r = bitfieldWord << THIRTYTWO_LOG_DIV_TWO_LOG;
+ for (i = 0; i < *pNumBitValidInLastWord; i++) {
+ if (pRemainingBitsInSegment[r + i] == 0) {
+ tempWord = tempWord & ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 -
+ i)); /* set a zero at bit number
+ (NUMBER_OF_BIT_IN_WORD-1-i) in
+ tempWord */
+ } else {
+ numValidSegment += 1; /* count segments which are not empty */
+ }
+ }
+ pSegmentBitfield[bitfieldWord] = tempWord; /* store result */
+
+ return numValidSegment;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function sets up sideinfo for the non-PCW decoder (for the
+current set).
+---------------------------------------------------------------------------------------------*/
+static void InitNonPCWSideInformationForCurrentSet(H_HCR_INFO pHcr) {
+ USHORT i, k;
+ UCHAR codebookDim;
+ UINT startNode;
+
+ UCHAR *pCodebook = pHcr->nonPcwSideinfo.pCodebook;
+ UINT *iNode = pHcr->nonPcwSideinfo.iNode;
+ UCHAR *pCntSign = pHcr->nonPcwSideinfo.pCntSign;
+ USHORT *iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ UINT *pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
+ SCHAR *pSta = pHcr->nonPcwSideinfo.pSta;
+ USHORT *pNumExtendedSortedCodewordInSection =
+ pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
+ int numExtendedSortedCodewordInSectionIdx =
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
+ UCHAR *pExtendedSortedCodebook = pHcr->sectionInfo.pExtendedSortedCodebook;
+ int extendedSortedCodebookIdx = pHcr->sectionInfo.extendedSortedCodebookIdx;
+ USHORT *pNumExtendedSortedSectionsInSets =
+ pHcr->sectionInfo.pNumExtendedSortedSectionsInSets;
+ int numExtendedSortedSectionsInSetsIdx =
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
+ int quantizedSpectralCoefficientsIdx =
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx;
+ const UCHAR *pCbDimension = aDimCb;
+ int iterationCounter = 0;
+
+ /* loop over number of extended sorted sections in the current set so all
+ * codewords sideinfo variables within this set can be prepared for decoding
+ */
+ for (i = pNumExtendedSortedSectionsInSets[numExtendedSortedSectionsInSetsIdx];
+ i != 0; i--) {
+ codebookDim =
+ pCbDimension[pExtendedSortedCodebook[extendedSortedCodebookIdx]];
+ startNode = *aHuffTable[pExtendedSortedCodebook[extendedSortedCodebookIdx]];
+
+ for (k = pNumExtendedSortedCodewordInSection
+ [numExtendedSortedCodewordInSectionIdx];
+ k != 0; k--) {
+ iterationCounter++;
+ if (iterationCounter > (1024 >> 2)) {
+ return;
+ }
+ *pSta++ = aCodebook2StartInt
+ [pExtendedSortedCodebook[extendedSortedCodebookIdx]];
+ *pCodebook++ = pExtendedSortedCodebook[extendedSortedCodebookIdx];
+ *iNode++ = startNode;
+ *pCntSign++ = 0;
+ *iResultPointer++ = quantizedSpectralCoefficientsIdx;
+ *pEscapeSequenceInfo++ = 0;
+ quantizedSpectralCoefficientsIdx +=
+ codebookDim; /* update pointer by codebookDim --> point to next
+ starting value for writing out */
+ if (quantizedSpectralCoefficientsIdx >= 1024) {
+ return;
+ }
+ }
+ numExtendedSortedCodewordInSectionIdx++; /* inc ptr for next ext sort sec in
+ current set */
+ extendedSortedCodebookIdx++; /* inc ptr for next ext sort sec in current set
+ */
+ if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS) ||
+ extendedSortedCodebookIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ return;
+ }
+ }
+ numExtendedSortedSectionsInSetsIdx++; /* inc ptr for next set of non-PCWs */
+ if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ return;
+ }
+
+ /* Write back indexes */
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
+ numExtendedSortedCodewordInSectionIdx;
+ pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx;
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx =
+ numExtendedSortedSectionsInSetsIdx;
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
+ numExtendedSortedCodewordInSectionIdx;
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx =
+ quantizedSpectralCoefficientsIdx;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function returns the input value if the value is in the
+ range of bufferlength. If <input> is smaller, one bufferlength
+is added, if <input> is bigger one bufferlength is subtracted.
+-----------------------------------------------------------------------------------------------
+ return: modulo result
+--------------------------------------------------------------------------------------------
+*/
+static INT ModuloValue(INT input, INT bufferlength) {
+ if (input > (bufferlength - 1)) {
+ return (input - bufferlength);
+ }
+ if (input < 0) {
+ return (input + bufferlength);
+ }
+ return input;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function clears a bit from current bitfield and
+ switches off the statemachine.
+
+ A bit is cleared in two cases:
+ a) a codeword is decoded, then a bit is cleared in codeword
+bitfield b) a segment is decoded empty, then a bit is cleared in segment
+bitfield
+--------------------------------------------------------------------------------------------
+*/
+static void ClearBitFromBitfield(STATEFUNC *ptrState, UINT offset,
+ UINT *pBitfield) {
+ UINT numBitfieldWord;
+ UINT numBitfieldBit;
+
+ /* get both values needed for clearing the bit */
+ numBitfieldWord = offset >> THIRTYTWO_LOG_DIV_TWO_LOG; /* int = wordNr */
+ numBitfieldBit = offset - (numBitfieldWord
+ << THIRTYTWO_LOG_DIV_TWO_LOG); /* fract = bitNr */
+
+ /* clear a bit in bitfield */
+ pBitfield[numBitfieldWord] =
+ pBitfield[numBitfieldWord] &
+ ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 - numBitfieldBit));
+
+ /* switch off state machine because codeword is decoded and/or because segment
+ * is empty */
+ *ptrState = NULL;
+}
+
+/* =========================================================================================
+ the states of the statemachine
+ =========================================================================================
+ */
+
+/*---------------------------------------------------------------------------------------------
+ description: Decodes the body of a codeword. This State is used for
+codebooks 1,2,5 and 6. No sign bits are decoded, because the table of the
+quantized spectral values has got a valid sign at the quantized spectral lines.
+-----------------------------------------------------------------------------------------------
+ output: Two or four quantizes spectral values written at position
+where pResultPointr points to
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_ONLY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+ FIXP_DBL *pResultBase;
+ UINT *iNode;
+ USHORT *iResultPointer;
+ UINT codewordOffset;
+ UINT branchNode;
+ UINT branchValue;
+ UINT iQSC;
+ UINT treeNode;
+ UCHAR carryBit;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ SCHAR *pRemainingBitsInSegment;
+ UCHAR readDirection;
+ UCHAR *pCodebook;
+ UCHAR dimCntr;
+ const UINT *pCurrentTree;
+ const UCHAR *pCbDimension;
+ const SCHAR *pQuantVal;
+ const SCHAR *pQuantValBase;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ pCodebook = pHcr->nonPcwSideinfo.pCodebook;
+ iNode = pHcr->nonPcwSideinfo.iNode;
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+
+ pCbDimension = aDimCb;
+
+ treeNode = iNode[codewordOffset];
+ pCurrentTree = aHuffTable[pCodebook[codewordOffset]];
+
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ CarryBitToBranchValue(carryBit, /* make a step in decoding tree */
+ treeNode, &branchValue, &branchNode);
+
+ /* if end of branch reached write out lines and count bits needed for sign,
+ * otherwise store node in codeword sideinfo */
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; ==> body is complete */
+ pQuantValBase = aQuantTable[pCodebook[codewordOffset]]; /* get base
+ address of
+ quantized
+ values
+ belonging to
+ current
+ codebook */
+ pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
+ line [of 2 or 4 quantized
+ values] */
+
+ iQSC = iResultPointer[codewordOffset]; /* get position of first line for
+ writing out result */
+
+ for (dimCntr = pCbDimension[pCodebook[codewordOffset]]; dimCntr != 0;
+ dimCntr--) {
+ pResultBase[iQSC++] =
+ (FIXP_DBL)*pQuantVal++; /* write out 2 or 4 lines into
+ spectrum; no Sign bits
+ available in this state */
+ }
+
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+ break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
+ decoded */
+ } else { /* body is not decoded completely: */
+ treeNode = *(
+ pCurrentTree +
+ branchValue); /* update treeNode for further step in decoding tree */
+ }
+ }
+ iNode[codewordOffset] = treeNode; /* store updated treeNode because maybe
+ decoding of codeword body not finished
+ yet */
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_ONLY;
+ return BODY_ONLY;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decodes the codeword body, writes out result and counts the
+number of quantized spectral values, which are different form zero. For those
+values sign bits are needed.
+
+ If sign bit counter cntSign is different from zero, switch to
+next state to decode sign Bits there. If sign bit counter cntSign is zero, no
+sign bits are needed and codeword is decoded.
+-----------------------------------------------------------------------------------------------
+ output: Two or four written quantizes spectral values written at
+position where pResultPointr points to. The signs of those lines may be wrong.
+If the signs [on just one signle sign] is wrong, the next state will correct it.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+
+ UCHAR *pCodebook;
+ UINT *iNode;
+ UCHAR *pCntSign;
+ FIXP_DBL *pResultBase;
+ USHORT *iResultPointer;
+ UINT codewordOffset;
+
+ UINT iQSC;
+ UINT cntSign;
+ UCHAR dimCntr;
+ UCHAR carryBit;
+ SCHAR *pSta;
+ UINT treeNode;
+ UINT branchValue;
+ UINT branchNode;
+ const UCHAR *pCbDimension;
+ const UINT *pCurrentTree;
+ const SCHAR *pQuantValBase;
+ const SCHAR *pQuantVal;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ pCodebook = pHcr->nonPcwSideinfo.pCodebook;
+ iNode = pHcr->nonPcwSideinfo.iNode;
+ pCntSign = pHcr->nonPcwSideinfo.pCntSign;
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ pCbDimension = aDimCb;
+
+ treeNode = iNode[codewordOffset];
+ pCurrentTree = aHuffTable[pCodebook[codewordOffset]];
+
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ CarryBitToBranchValue(carryBit, /* make a step in decoding tree */
+ treeNode, &branchValue, &branchNode);
+
+ /* if end of branch reached write out lines and count bits needed for sign,
+ * otherwise store node in codeword sideinfo */
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; if set body complete */
+ /* body completely decoded; branchValue is valid, set pQuantVal to first
+ * (of two or four) quantized spectral coefficients */
+ pQuantValBase = aQuantTable[pCodebook[codewordOffset]]; /* get base
+ address of
+ quantized
+ values
+ belonging to
+ current
+ codebook */
+ pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
+ line [of 2 or 4 quantized
+ values] */
+
+ iQSC = iResultPointer[codewordOffset]; /* get position of first line for
+ writing result */
+
+ /* codeword decoding result is written out here: Write out 2 or 4
+ * quantized spectral values with probably */
+ /* wrong sign and count number of values which are different from zero for
+ * sign bit decoding [which happens in next state] */
+ cntSign = 0;
+ for (dimCntr = pCbDimension[pCodebook[codewordOffset]]; dimCntr != 0;
+ dimCntr--) {
+ pResultBase[iQSC++] =
+ (FIXP_DBL)*pQuantVal; /* write quant. spec. coef. into spectrum */
+ if (*pQuantVal++ != 0) {
+ cntSign += 1;
+ }
+ }
+
+ if (cntSign == 0) {
+ ClearBitFromBitfield(
+ &(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and switch off
+ statemachine */
+ } else {
+ pCntSign[codewordOffset] = cntSign; /* write sign count result into
+ codewordsideinfo of current
+ codeword */
+ pSta[codewordOffset] = BODY_SIGN__SIGN; /* change state */
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]]; /* get state from
+ separate array of
+ cw-sideinfo */
+ }
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+ break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
+ decoded */
+ } else { /* body is not decoded completely: */
+ treeNode = *(
+ pCurrentTree +
+ branchValue); /* update treeNode for further step in decoding tree */
+ }
+ }
+ iNode[codewordOffset] = treeNode; /* store updated treeNode because maybe
+ decoding of codeword body not finished
+ yet */
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__BODY;
+ return BODY_SIGN__BODY;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This state decodes the sign bits belonging to a codeword. The
+state is called as often in different "trials" until pCntSgn[codewordOffset] is
+zero.
+-----------------------------------------------------------------------------------------------
+ output: The two or four quantizes spectral values (written in previous
+state) have now the correct sign.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+
+ UCHAR *pCntSign;
+ FIXP_DBL *pResultBase;
+ USHORT *iResultPointer;
+ UINT codewordOffset;
+
+ UCHAR carryBit;
+ UINT iQSC;
+ UCHAR cntSign;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ /*pCodebook = */
+ pCntSign = pHcr->nonPcwSideinfo.pCntSign;
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+
+ iQSC = iResultPointer[codewordOffset];
+ cntSign = pCntSign[codewordOffset];
+
+ /* loop for sign bit decoding */
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+ cntSign -=
+ 1; /* decrement sign counter because one sign bit has been read */
+
+ /* search for a line (which was decoded in previous state) which is not
+ * zero. [This value will get a sign] */
+ while (pResultBase[iQSC] == (FIXP_DBL)0) {
+ if (++iQSC >= 1024) { /* points to current value different from zero */
+ return BODY_SIGN__SIGN;
+ }
+ }
+
+ /* put sign together with line; if carryBit is zero, the sign is ok already;
+ * no write operation necessary in this case */
+ if (carryBit != 0) {
+ pResultBase[iQSC] = -pResultBase[iQSC]; /* carryBit = 1 --> minus */
+ }
+
+ iQSC++; /* update pointer to next (maybe valid) value */
+
+ if (cntSign == 0) { /* if (cntSign==0) ==> set state CODEWORD_DECODED */
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+ break; /* whole nonPCW-Body and according sign bits are decoded */
+ }
+ }
+ pCntSign[codewordOffset] = cntSign;
+ iResultPointer[codewordOffset] = iQSC; /* store updated pResultPointer */
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__SIGN;
+ return BODY_SIGN__SIGN;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decodes the codeword body in case of codebook is 11. Writes
+out resulting two or four lines [with probably wrong sign] and counts the number
+of lines, which are different form zero. This information is needed in next
+ state where sign bits will be decoded, if necessary.
+ If sign bit counter cntSign is zero, no sign bits are needed
+and codeword is decoded completely.
+-----------------------------------------------------------------------------------------------
+ output: Two lines (quantizes spectral coefficients) which are probably
+wrong. The sign may be wrong and if one or two values is/are 16, the following
+states will decode the escape sequence to correct the values which are wirtten
+here.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN_ESC__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+
+ UINT *iNode;
+ UCHAR *pCntSign;
+ FIXP_DBL *pResultBase;
+ USHORT *iResultPointer;
+ UINT codewordOffset;
+
+ UCHAR carryBit;
+ UINT iQSC;
+ UINT cntSign;
+ UINT dimCntr;
+ UINT treeNode;
+ SCHAR *pSta;
+ UINT branchNode;
+ UINT branchValue;
+ const UINT *pCurrentTree;
+ const SCHAR *pQuantValBase;
+ const SCHAR *pQuantVal;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ iNode = pHcr->nonPcwSideinfo.iNode;
+ pCntSign = pHcr->nonPcwSideinfo.pCntSign;
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ treeNode = iNode[codewordOffset];
+ pCurrentTree = aHuffTable[ESCAPE_CODEBOOK];
+
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ /* make a step in tree */
+ CarryBitToBranchValue(carryBit, treeNode, &branchValue, &branchNode);
+
+ /* if end of branch reached write out lines and count bits needed for sign,
+ * otherwise store node in codeword sideinfo */
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; if set body complete */
+
+ /* body completely decoded; branchValue is valid */
+ /* set pQuantVol to first (of two or four) quantized spectral coefficients
+ */
+ pQuantValBase = aQuantTable[ESCAPE_CODEBOOK]; /* get base address of
+ quantized values
+ belonging to current
+ codebook */
+ pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
+ line [of 2 or 4 quantized
+ values] */
+
+ /* make backup from original resultPointer in node storage for state
+ * BODY_SIGN_ESC__SIGN */
+ iNode[codewordOffset] = iResultPointer[codewordOffset];
+
+ /* get position of first line for writing result */
+ iQSC = iResultPointer[codewordOffset];
+
+ /* codeword decoding result is written out here: Write out 2 or 4
+ * quantized spectral values with probably */
+ /* wrong sign and count number of values which are different from zero for
+ * sign bit decoding [which happens in next state] */
+ cntSign = 0;
+
+ for (dimCntr = DIMENSION_OF_ESCAPE_CODEBOOK; dimCntr != 0; dimCntr--) {
+ pResultBase[iQSC++] =
+ (FIXP_DBL)*pQuantVal; /* write quant. spec. coef. into spectrum */
+ if (*pQuantVal++ != 0) {
+ cntSign += 1;
+ }
+ }
+
+ if (cntSign == 0) {
+ ClearBitFromBitfield(
+ &(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and switch off
+ statemachine */
+ /* codeword decoded */
+ } else {
+ /* write sign count result into codewordsideinfo of current codeword */
+ pCntSign[codewordOffset] = cntSign;
+ pSta[codewordOffset] = BODY_SIGN_ESC__SIGN; /* change state */
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]]; /* get state from
+ separate array of
+ cw-sideinfo */
+ }
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* the last reinitialzation
+ of for loop counter (see
+ above) is done here */
+ break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
+ decoded */
+ } else { /* body is not decoded completely: */
+ /* update treeNode for further step in decoding tree and store updated
+ * treeNode because maybe no more bits left in segment */
+ treeNode = *(pCurrentTree + branchValue);
+ iNode[codewordOffset] = treeNode;
+ }
+ }
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__BODY;
+ return BODY_SIGN_ESC__BODY;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This state decodes the sign bits, if a codeword of codebook 11
+needs some. A flag named 'flagB' in codeword sideinfo is set, if the second line
+of quantized spectral values is 16. The 'flagB' is used in case of decoding of a
+escape sequence is necessary as far as the second line is concerned.
+
+ If only the first line needs an escape sequence, the flagB is
+cleared. If only the second line needs an escape sequence, the flagB is not
+used.
+
+ For storing sideinfo in case of escape sequence decoding one
+single word can be used for both escape sequences because they are decoded not
+at the same time:
+
+
+ bit 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5
+4 3 2 1 0
+ ===== == == =========== ===========
+=================================== ^ ^ ^ ^ ^
+^ | | | | | | res. flagA flagB
+escapePrefixUp escapePrefixDown escapeWord
+
+-----------------------------------------------------------------------------------------------
+ output: Two lines with correct sign. If one or two values is/are 16,
+the lines are not valid, otherwise they are.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN_ESC__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+
+ UINT *iNode;
+ UCHAR *pCntSign;
+ FIXP_DBL *pResultBase;
+ USHORT *iResultPointer;
+ UINT *pEscapeSequenceInfo;
+ UINT codewordOffset;
+
+ UINT iQSC;
+ UCHAR cntSign;
+ UINT flagA;
+ UINT flagB;
+ UINT flags;
+ UCHAR carryBit;
+ SCHAR *pSta;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ iNode = pHcr->nonPcwSideinfo.iNode;
+ pCntSign = pHcr->nonPcwSideinfo.pCntSign;
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ iQSC = iResultPointer[codewordOffset];
+ cntSign = pCntSign[codewordOffset];
+
+ /* loop for sign bit decoding */
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ /* decrement sign counter because one sign bit has been read */
+ cntSign -= 1;
+ pCntSign[codewordOffset] = cntSign;
+
+ /* get a quantized spectral value (which was decoded in previous state)
+ * which is not zero. [This value will get a sign] */
+ while (pResultBase[iQSC] == (FIXP_DBL)0) {
+ if (++iQSC >= 1024) {
+ return BODY_SIGN_ESC__SIGN;
+ }
+ }
+ iResultPointer[codewordOffset] = iQSC;
+
+ /* put negative sign together with quantized spectral value; if carryBit is
+ * zero, the sign is ok already; no write operation necessary in this case
+ */
+ if (carryBit != 0) {
+ pResultBase[iQSC] = -pResultBase[iQSC]; /* carryBit = 1 --> minus */
+ }
+ iQSC++; /* update index to next (maybe valid) value */
+ iResultPointer[codewordOffset] = iQSC;
+
+ if (cntSign == 0) {
+ /* all sign bits are decoded now */
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+
+ /* check decoded values if codeword is decoded: Check if one or two escape
+ * sequences 16 follow */
+
+ /* step 0 */
+ /* restore pointer to first decoded quantized value [ = original
+ * pResultPointr] from index iNode prepared in State_BODY_SIGN_ESC__BODY
+ */
+ iQSC = iNode[codewordOffset];
+
+ /* step 1 */
+ /* test first value if escape sequence follows */
+ flagA = 0; /* for first possible escape sequence */
+ if (fixp_abs(pResultBase[iQSC++]) == (FIXP_DBL)ESCAPE_VALUE) {
+ flagA = 1;
+ }
+
+ /* step 2 */
+ /* test second value if escape sequence follows */
+ flagB = 0; /* for second possible escape sequence */
+ if (fixp_abs(pResultBase[iQSC]) == (FIXP_DBL)ESCAPE_VALUE) {
+ flagB = 1;
+ }
+
+ /* step 3 */
+ /* evaluate flag result and go on if necessary */
+ if (!flagA && !flagB) {
+ ClearBitFromBitfield(
+ &(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and switch off
+ statemachine */
+ } else {
+ /* at least one of two lines is 16 */
+ /* store both flags at correct positions in non PCW codeword sideinfo
+ * pEscapeSequenceInfo[codewordOffset] */
+ flags = flagA << POSITION_OF_FLAG_A;
+ flags |= (flagB << POSITION_OF_FLAG_B);
+ pEscapeSequenceInfo[codewordOffset] = flags;
+
+ /* set next state */
+ pSta[codewordOffset] = BODY_SIGN_ESC__ESC_PREFIX;
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]]; /* get state from
+ separate array of
+ cw-sideinfo */
+
+ /* set result pointer to the first line of the two decoded lines */
+ iResultPointer[codewordOffset] = iNode[codewordOffset];
+
+ if (!flagA && flagB) {
+ /* update pResultPointr ==> state Stat_BODY_SIGN_ESC__ESC_WORD writes
+ * to correct position. Second value is the one and only escape value
+ */
+ iQSC = iResultPointer[codewordOffset];
+ iQSC++;
+ iResultPointer[codewordOffset] = iQSC;
+ }
+
+ } /* at least one of two lines is 16 */
+ break; /* nonPCW-Body at cb 11 and according sign bits are decoded */
+
+ } /* if ( cntSign == 0 ) */
+ } /* loop over remaining Bits in segment */
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__SIGN;
+ return BODY_SIGN_ESC__SIGN;
+ }
+ }
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decode escape prefix of first or second escape sequence. The
+escape prefix consists of ones. The following zero is also decoded here.
+-----------------------------------------------------------------------------------------------
+ output: If the single separator-zero which follows the
+escape-prefix-ones is not yet decoded: The value 'escapePrefixUp' in word
+pEscapeSequenceInfo[codewordOffset] is updated.
+
+ If the single separator-zero which follows the
+escape-prefix-ones is decoded: Two updated values 'escapePrefixUp' and
+'escapePrefixDown' in word pEscapeSequenceInfo[codewordOffset]. This State is
+finished. Switch to next state.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT segmentOffset;
+ UINT *pEscapeSequenceInfo;
+ UINT codewordOffset;
+ UCHAR carryBit;
+ UINT escapePrefixUp;
+ SCHAR *pSta;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+ pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ escapePrefixUp =
+ (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_UP) >>
+ LSB_ESCAPE_PREFIX_UP;
+
+ /* decode escape prefix */
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ /* count ones and store sum in escapePrefixUp */
+ if (carryBit == 1) {
+ escapePrefixUp += 1; /* update conter for ones */
+
+ /* store updated counter in sideinfo of current codeword */
+ pEscapeSequenceInfo[codewordOffset] &=
+ ~MASK_ESCAPE_PREFIX_UP; /* delete old escapePrefixUp */
+ escapePrefixUp <<= LSB_ESCAPE_PREFIX_UP; /* shift to correct position */
+ pEscapeSequenceInfo[codewordOffset] |=
+ escapePrefixUp; /* insert new escapePrefixUp */
+ escapePrefixUp >>= LSB_ESCAPE_PREFIX_UP; /* shift back down */
+ } else { /* separator [zero] reached */
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+ escapePrefixUp +=
+ 4; /* if escape_separator '0' appears, add 4 and ==> break */
+
+ /* store escapePrefixUp in pEscapeSequenceInfo[codewordOffset] at bit
+ * position escapePrefixUp */
+ pEscapeSequenceInfo[codewordOffset] &=
+ ~MASK_ESCAPE_PREFIX_UP; /* delete old escapePrefixUp */
+ escapePrefixUp <<= LSB_ESCAPE_PREFIX_UP; /* shift to correct position */
+ pEscapeSequenceInfo[codewordOffset] |=
+ escapePrefixUp; /* insert new escapePrefixUp */
+ escapePrefixUp >>= LSB_ESCAPE_PREFIX_UP; /* shift back down */
+
+ /* store escapePrefixUp in pEscapeSequenceInfo[codewordOffset] at bit
+ * position escapePrefixDown */
+ pEscapeSequenceInfo[codewordOffset] &=
+ ~MASK_ESCAPE_PREFIX_DOWN; /* delete old escapePrefixDown */
+ escapePrefixUp <<= LSB_ESCAPE_PREFIX_DOWN; /* shift to correct position */
+ pEscapeSequenceInfo[codewordOffset] |=
+ escapePrefixUp; /* insert new escapePrefixDown */
+
+ pSta[codewordOffset] = BODY_SIGN_ESC__ESC_WORD; /* set next state */
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]]; /* get state from separate
+ array of cw-sideinfo */
+ break;
+ }
+ }
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX;
+ return BODY_SIGN_ESC__ESC_PREFIX;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decode escapeWord of escape sequence. If the escape sequence
+is decoded completely, assemble quantized-spectral-escape-coefficient and
+replace the previous decoded 16 by the new value. Test flagB. If flagB is set,
+the second escape sequence must be decoded. If flagB is not set, the codeword is
+decoded and the state machine is switched off.
+-----------------------------------------------------------------------------------------------
+ output: Two lines with valid sign. At least one of both lines has got
+the correct value.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+
+ FIXP_DBL *pResultBase;
+ USHORT *iResultPointer;
+ UINT *pEscapeSequenceInfo;
+ UINT codewordOffset;
+
+ UINT escapeWord;
+ UINT escapePrefixDown;
+ UINT escapePrefixUp;
+ UCHAR carryBit;
+ UINT iQSC;
+ INT sign;
+ UINT flagA;
+ UINT flagB;
+ SCHAR *pSta;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ escapeWord = pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_WORD;
+ escapePrefixDown =
+ (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_DOWN) >>
+ LSB_ESCAPE_PREFIX_DOWN;
+
+ /* decode escape word */
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ /* build escape word */
+ escapeWord <<=
+ 1; /* left shift previous decoded part of escapeWord by on bit */
+ escapeWord = escapeWord | carryBit; /* assemble escape word by bitwise or */
+
+ /* decrement counter for length of escape word because one more bit was
+ * decoded */
+ escapePrefixDown -= 1;
+
+ /* store updated escapePrefixDown */
+ pEscapeSequenceInfo[codewordOffset] &=
+ ~MASK_ESCAPE_PREFIX_DOWN; /* delete old escapePrefixDown */
+ escapePrefixDown <<= LSB_ESCAPE_PREFIX_DOWN; /* shift to correct position */
+ pEscapeSequenceInfo[codewordOffset] |=
+ escapePrefixDown; /* insert new escapePrefixDown */
+ escapePrefixDown >>= LSB_ESCAPE_PREFIX_DOWN; /* shift back */
+
+ /* store updated escapeWord */
+ pEscapeSequenceInfo[codewordOffset] &=
+ ~MASK_ESCAPE_WORD; /* delete old escapeWord */
+ pEscapeSequenceInfo[codewordOffset] |=
+ escapeWord; /* insert new escapeWord */
+
+ if (escapePrefixDown == 0) {
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+
+ /* escape sequence decoded. Assemble escape-line and replace original line
+ */
+
+ /* step 0 */
+ /* derive sign */
+ iQSC = iResultPointer[codewordOffset];
+ sign = (pResultBase[iQSC] >= (FIXP_DBL)0)
+ ? 1
+ : -1; /* get sign of escape value 16 */
+
+ /* step 1 */
+ /* get escapePrefixUp */
+ escapePrefixUp =
+ (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_UP) >>
+ LSB_ESCAPE_PREFIX_UP;
+
+ /* step 2 */
+ /* calculate escape value */
+ pResultBase[iQSC] =
+ (FIXP_DBL)(sign * (((INT)1 << escapePrefixUp) + (INT)escapeWord));
+
+ /* get both flags from sideinfo (flags are not shifted to the
+ * lsb-position) */
+ flagA = pEscapeSequenceInfo[codewordOffset] & MASK_FLAG_A;
+ flagB = pEscapeSequenceInfo[codewordOffset] & MASK_FLAG_B;
+
+ /* step 3 */
+ /* clear the whole escape sideinfo word */
+ pEscapeSequenceInfo[codewordOffset] = 0;
+
+ /* change state in dependence of flag flagB */
+ if (flagA != 0) {
+ /* first escape sequence decoded; previous decoded 16 has been replaced
+ * by valid line */
+
+ /* clear flagA in sideinfo word because this escape sequence has already
+ * beed decoded */
+ pEscapeSequenceInfo[codewordOffset] &= ~MASK_FLAG_A;
+
+ if (flagB == 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield
+ and switch off
+ statemachine */
+ } else {
+ /* updated pointer to next and last 16 */
+ iQSC++;
+ iResultPointer[codewordOffset] = iQSC;
+
+ /* change state */
+ pSta[codewordOffset] = BODY_SIGN_ESC__ESC_PREFIX;
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]]; /* get state from
+ separate array of
+ cw-sideinfo */
+ }
+ } else {
+ ClearBitFromBitfield(
+ &(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and switch off
+ statemachine */
+ }
+ break;
+ }
+ }
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_WORD;
+ return BODY_SIGN_ESC__ESC_WORD;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_hcrs.h b/fdk-aac/libAACdec/src/aacdec_hcrs.h
new file mode 100644
index 0000000..acb2f40
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcrs.h
@@ -0,0 +1,176 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Defines of state-constants, masks and
+ state-prototypes
+
+*******************************************************************************/
+
+#ifndef AACDEC_HCRS_H
+#define AACDEC_HCRS_H
+
+#include "FDK_bitstream.h"
+#include "aacdec_hcr_types.h"
+/* The four different kinds of types of states are: */
+/* different states are defined as constants */ /* start middle=self next
+ stop */
+#define STOP_THIS_STATE \
+ 0 /* */
+#define BODY_ONLY \
+ 1 /* X X X */
+#define BODY_SIGN__BODY \
+ 2 /* X X X X [stop if no sign] */
+#define BODY_SIGN__SIGN \
+ 3 /* X X [stop if sign bits decoded] */
+#define BODY_SIGN_ESC__BODY \
+ 4 /* X X X X [stop if no sign] */
+#define BODY_SIGN_ESC__SIGN \
+ 5 /* X X X [stop if no escape sequence] */
+#define BODY_SIGN_ESC__ESC_PREFIX \
+ 6 /* X X */
+#define BODY_SIGN_ESC__ESC_WORD \
+ 7 /* X X X [stop if abs(second qsc) != 16] */
+
+/* examples: */
+
+/* BODY_ONLY means only the codeword body will be decoded; no
+ * sign bits will follow and no escapesequence will follow */
+
+/* BODY_SIGN__BODY means that the codeword consists of two parts;
+ * body and sign part. The part '__BODY' after the two underscores shows */
+/* that the bits which are currently decoded belong
+ * to the '__BODY' of the codeword and not to the sign part. */
+
+/* BODY_SIGN_ESC__ESC_PB means that the codeword consists of three parts;
+ * body, sign and (here: two) escape sequences; */
+/* P = Prefix = ones */
+/* W = Escape Word */
+/* A = first possible (of two) Escape sequeces */
+/* B = second possible (of two) Escape sequeces */
+/* The part after the two underscores shows that
+ * the current bits which are decoded belong to the '__ESC_PB' - part of the */
+/* codeword. That means the body and the sign bits
+ * are decoded completely and the bits which are decoded now belong to */
+/* the escape sequence [P = prefix; B=second
+ * possible escape sequence] */
+
+#define MSB_31_MASK 0x80000000 /* masks MSB (= Bit 31) in a 32 bit word */
+#define DIMENSION_OF_ESCAPE_CODEBOOK 2 /* for cb >= 11 is dimension 2 */
+#define ESCAPE_CODEBOOK 11
+
+#define MASK_ESCAPE_PREFIX_UP 0x000F0000
+#define LSB_ESCAPE_PREFIX_UP 16
+
+#define MASK_ESCAPE_PREFIX_DOWN 0x0000F000
+#define LSB_ESCAPE_PREFIX_DOWN 12
+
+#define MASK_ESCAPE_WORD 0x00000FFF
+#define MASK_FLAG_A 0x00200000
+#define MASK_FLAG_B 0x00100000
+
+extern void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO hHcr);
+
+UINT Hcr_State_BODY_ONLY(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN__BODY(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN_ESC__BODY(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN_ESC__SIGN(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM, void*);
+
+#endif /* AACDEC_HCRS_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_pns.cpp b/fdk-aac/libAACdec/src/aacdec_pns.cpp
new file mode 100644
index 0000000..432cd4e
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_pns.cpp
@@ -0,0 +1,361 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: perceptual noise substitution tool
+
+*******************************************************************************/
+
+#include "aacdec_pns.h"
+
+#include "aac_ram.h"
+#include "aac_rom.h"
+#include "channelinfo.h"
+#include "block.h"
+#include "FDK_bitstream.h"
+
+#include "genericStds.h"
+
+#define NOISE_OFFSET 90 /* cf. ISO 14496-3 p. 175 */
+
+/*!
+ \brief Reset InterChannel and PNS data
+
+ The function resets the InterChannel and PNS data
+*/
+void CPns_ResetData(CPnsData *pPnsData,
+ CPnsInterChannelData *pPnsInterChannelData) {
+ FDK_ASSERT(pPnsData != NULL);
+ FDK_ASSERT(pPnsInterChannelData != NULL);
+ /* Assign pointer always, since pPnsData is not persistent data */
+ pPnsData->pPnsInterChannelData = pPnsInterChannelData;
+ pPnsData->PnsActive = 0;
+ pPnsData->CurrentEnergy = 0;
+
+ FDKmemclear(pPnsData->pnsUsed, (8 * 16) * sizeof(UCHAR));
+ FDKmemclear(pPnsInterChannelData->correlated, (8 * 16) * sizeof(UCHAR));
+}
+
+/*!
+ \brief Update PNS noise generator state.
+
+ The function sets the seed for PNS noise generation.
+ It can be used to link two or more channels in terms of PNS.
+*/
+void CPns_UpdateNoiseState(CPnsData *pPnsData, INT *currentSeed,
+ INT *randomSeed) {
+ /* use pointer because seed has to be
+ same, left and right channel ! */
+ pPnsData->currentSeed = currentSeed;
+ pPnsData->randomSeed = randomSeed;
+}
+
+/*!
+ \brief Indicates if PNS is used
+
+ The function returns a value indicating whether PNS is used or not
+ acordding to the noise energy
+
+ \return PNS used
+*/
+int CPns_IsPnsUsed(const CPnsData *pPnsData, const int group, const int band) {
+ unsigned pns_band = group * 16 + band;
+
+ return pPnsData->pnsUsed[pns_band] & (UCHAR)1;
+}
+
+/*!
+ \brief Set correlation
+
+ The function activates the noise correlation between the channel pair
+*/
+void CPns_SetCorrelation(CPnsData *pPnsData, const int group, const int band,
+ const int outofphase) {
+ CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
+ unsigned pns_band = group * 16 + band;
+
+ pInterChannelData->correlated[pns_band] = (outofphase) ? 3 : 1;
+}
+
+/*!
+ \brief Indicates if correlation is used
+
+ The function indicates if the noise correlation between the channel pair
+ is activated
+
+ \return PNS is correlated
+*/
+static int CPns_IsCorrelated(const CPnsData *pPnsData, const int group,
+ const int band) {
+ CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
+ unsigned pns_band = group * 16 + band;
+
+ return (pInterChannelData->correlated[pns_band] & 0x01) ? 1 : 0;
+}
+
+/*!
+ \brief Indicates if correlated out of phase mode is used.
+
+ The function indicates if the noise correlation between the channel pair
+ is activated in out-of-phase mode.
+
+ \return PNS is out-of-phase
+*/
+static int CPns_IsOutOfPhase(const CPnsData *pPnsData, const int group,
+ const int band) {
+ CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
+ unsigned pns_band = group * 16 + band;
+
+ return (pInterChannelData->correlated[pns_band] & 0x02) ? 1 : 0;
+}
+
+/*!
+ \brief Read PNS information
+
+ The function reads the PNS information from the bitstream
+*/
+void CPns_Read(CPnsData *pPnsData, HANDLE_FDK_BITSTREAM bs,
+ const CodeBookDescription *hcb, SHORT *pScaleFactor,
+ UCHAR global_gain, int band, int group /* = 0 */) {
+ int delta;
+ UINT pns_band = group * 16 + band;
+
+ if (pPnsData->PnsActive) {
+ /* Next PNS band case */
+ delta = CBlock_DecodeHuffmanWord(bs, hcb) - 60;
+ } else {
+ /* First PNS band case */
+ int noiseStartValue = FDKreadBits(bs, 9);
+
+ delta = noiseStartValue - 256;
+ pPnsData->PnsActive = 1;
+ pPnsData->CurrentEnergy = global_gain - NOISE_OFFSET;
+ }
+
+ pPnsData->CurrentEnergy += delta;
+ pScaleFactor[pns_band] = pPnsData->CurrentEnergy;
+
+ pPnsData->pnsUsed[pns_band] = 1;
+}
+
+/**
+ * \brief Generate a vector of noise of given length. The noise values are
+ * scaled in order to yield a noise energy of 1.0
+ * \param spec pointer to were the noise values will be written to.
+ * \param size amount of noise values to be generated.
+ * \param pRandomState pointer to the state of the random generator being used.
+ * \return exponent of generated noise vector.
+ */
+static int GenerateRandomVector(FIXP_DBL *RESTRICT spec, int size,
+ int *pRandomState) {
+ int i, invNrg_e = 0, nrg_e = 0;
+ FIXP_DBL invNrg_m, nrg_m = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL *RESTRICT ptr = spec;
+ int randomState = *pRandomState;
+
+#define GEN_NOISE_NRG_SCALE 7
+
+ /* Generate noise and calculate energy. */
+ for (i = 0; i < size; i++) {
+ randomState =
+ (((INT64)1664525 * randomState) + (INT64)1013904223) & 0xFFFFFFFF;
+ nrg_m = fPow2AddDiv2(nrg_m, (FIXP_DBL)randomState >> GEN_NOISE_NRG_SCALE);
+ *ptr++ = (FIXP_DBL)randomState;
+ }
+ nrg_e = GEN_NOISE_NRG_SCALE * 2 + 1;
+
+ /* weight noise with = 1 / sqrt_nrg; */
+ invNrg_m = invSqrtNorm2(nrg_m << 1, &invNrg_e);
+ invNrg_e += -((nrg_e - 1) >> 1);
+
+ for (i = size; i--;) {
+ spec[i] = fMult(spec[i], invNrg_m);
+ }
+
+ /* Store random state */
+ *pRandomState = randomState;
+
+ return invNrg_e;
+}
+
+static void ScaleBand(FIXP_DBL *RESTRICT spec, int size, int scaleFactor,
+ int specScale, int noise_e, int out_of_phase) {
+ int i, shift, sfExponent;
+ FIXP_DBL sfMatissa;
+
+ /* Get gain from scale factor value = 2^(scaleFactor * 0.25) */
+ sfMatissa = MantissaTable[scaleFactor & 0x03][0];
+ /* sfExponent = (scaleFactor >> 2) + ExponentTable[scaleFactor & 0x03][0]; */
+ /* Note: ExponentTable[scaleFactor & 0x03][0] is always 1. */
+ sfExponent = (scaleFactor >> 2) + 1;
+
+ if (out_of_phase != 0) {
+ sfMatissa = -sfMatissa;
+ }
+
+ /* +1 because of fMultDiv2 below. */
+ shift = sfExponent - specScale + 1 + noise_e;
+
+ /* Apply gain to noise values */
+ if (shift >= 0) {
+ shift = fixMin(shift, DFRACT_BITS - 1);
+ for (i = size; i-- != 0;) {
+ spec[i] = fMultDiv2(spec[i], sfMatissa) << shift;
+ }
+ } else {
+ shift = fixMin(-shift, DFRACT_BITS - 1);
+ for (i = size; i-- != 0;) {
+ spec[i] = fMultDiv2(spec[i], sfMatissa) >> shift;
+ }
+ }
+}
+
+/*!
+ \brief Apply PNS
+
+ The function applies PNS (i.e. it generates noise) on the bands
+ flagged as noisy bands
+
+*/
+void CPns_Apply(const CPnsData *pPnsData, const CIcsInfo *pIcsInfo,
+ SPECTRAL_PTR pSpectrum, const SHORT *pSpecScale,
+ const SHORT *pScaleFactor,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const INT granuleLength, const int channel) {
+ if (pPnsData->PnsActive) {
+ const short *BandOffsets =
+ GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo);
+
+ int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(pIcsInfo);
+
+ for (int window = 0, group = 0; group < GetWindowGroups(pIcsInfo);
+ group++) {
+ for (int groupwin = 0; groupwin < GetWindowGroupLength(pIcsInfo, group);
+ groupwin++, window++) {
+ FIXP_DBL *spectrum = SPEC(pSpectrum, window, granuleLength);
+
+ for (int band = 0; band < ScaleFactorBandsTransmitted; band++) {
+ if (CPns_IsPnsUsed(pPnsData, group, band)) {
+ UINT pns_band = window * 16 + band;
+
+ int bandWidth = BandOffsets[band + 1] - BandOffsets[band];
+ int noise_e;
+
+ FDK_ASSERT(bandWidth >= 0);
+
+ if (channel > 0 && CPns_IsCorrelated(pPnsData, group, band)) {
+ noise_e =
+ GenerateRandomVector(spectrum + BandOffsets[band], bandWidth,
+ &pPnsData->randomSeed[pns_band]);
+ } else {
+ pPnsData->randomSeed[pns_band] = *pPnsData->currentSeed;
+
+ noise_e = GenerateRandomVector(spectrum + BandOffsets[band],
+ bandWidth, pPnsData->currentSeed);
+ }
+
+ int outOfPhase = CPns_IsOutOfPhase(pPnsData, group, band);
+
+ ScaleBand(spectrum + BandOffsets[band], bandWidth,
+ pScaleFactor[group * 16 + band], pSpecScale[window],
+ noise_e, outOfPhase);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_pns.h b/fdk-aac/libAACdec/src/aacdec_pns.h
new file mode 100644
index 0000000..45cd989
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_pns.h
@@ -0,0 +1,129 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: perceptual noise substitution tool
+
+*******************************************************************************/
+
+#ifndef AACDEC_PNS_H
+#define AACDEC_PNS_H
+
+#include "common_fix.h"
+
+#define NO_OFBANDS ((8 * 16))
+
+typedef struct {
+ UCHAR correlated[NO_OFBANDS];
+} CPnsInterChannelData;
+
+typedef struct {
+ CPnsInterChannelData *pPnsInterChannelData;
+ UCHAR pnsUsed[NO_OFBANDS];
+ int CurrentEnergy;
+ UCHAR PnsActive;
+ INT *currentSeed;
+ INT *randomSeed;
+} CPnsData;
+
+void CPns_UpdateNoiseState(CPnsData *pPnsData, INT *currentSeed,
+ INT *randomSeed);
+
+void CPns_ResetData(CPnsData *pPnsData,
+ CPnsInterChannelData *pPnsInterChannelData);
+
+#endif /* #ifndef AACDEC_PNS_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_tns.cpp b/fdk-aac/libAACdec/src/aacdec_tns.cpp
new file mode 100644
index 0000000..fb3fe33
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_tns.cpp
@@ -0,0 +1,361 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: temporal noise shaping tool
+
+*******************************************************************************/
+
+#include "aacdec_tns.h"
+#include "aac_rom.h"
+#include "FDK_bitstream.h"
+#include "channelinfo.h"
+
+#include "FDK_lpc.h"
+
+#define TNS_MAXIMUM_ORDER_AAC 12
+
+/*!
+ \brief Reset tns data
+
+ The function resets the tns data
+
+ \return none
+*/
+void CTns_Reset(CTnsData *pTnsData) {
+ /* Note: the following FDKmemclear should not be required. */
+ FDKmemclear(pTnsData->Filter,
+ TNS_MAX_WINDOWS * TNS_MAXIMUM_FILTERS * sizeof(CFilter));
+ FDKmemclear(pTnsData->NumberOfFilters, TNS_MAX_WINDOWS * sizeof(UCHAR));
+ pTnsData->DataPresent = 0;
+ pTnsData->Active = 0;
+}
+
+void CTns_ReadDataPresentFlag(
+ HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
+ CTnsData *pTnsData) /*!< pointer to aac decoder channel info */
+{
+ pTnsData->DataPresent = (UCHAR)FDKreadBits(bs, 1);
+}
+
+/*!
+ \brief Read tns data from bitstream
+
+ The function reads the elements for tns from
+ the bitstream.
+
+ \return none
+*/
+AAC_DECODER_ERROR CTns_Read(HANDLE_FDK_BITSTREAM bs, CTnsData *pTnsData,
+ const CIcsInfo *pIcsInfo, const UINT flags) {
+ UCHAR n_filt, order;
+ UCHAR length, coef_res, coef_compress;
+ UCHAR window;
+ UCHAR wins_per_frame;
+ UCHAR isLongFlag;
+ UCHAR start_window;
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ if (!pTnsData->DataPresent) {
+ return ErrorStatus;
+ }
+
+ {
+ start_window = 0;
+ wins_per_frame = GetWindowsPerFrame(pIcsInfo);
+ isLongFlag = IsLongBlock(pIcsInfo);
+ }
+
+ pTnsData->GainLd = 0;
+
+ for (window = start_window; window < wins_per_frame; window++) {
+ pTnsData->NumberOfFilters[window] = n_filt =
+ (UCHAR)FDKreadBits(bs, isLongFlag ? 2 : 1);
+
+ if (n_filt) {
+ int index;
+ UCHAR nextstopband;
+
+ coef_res = (UCHAR)FDKreadBits(bs, 1);
+
+ nextstopband = GetScaleFactorBandsTotal(pIcsInfo);
+
+ for (index = 0; index < n_filt; index++) {
+ CFilter *filter = &pTnsData->Filter[window][index];
+
+ length = (UCHAR)FDKreadBits(bs, isLongFlag ? 6 : 4);
+
+ if (length > nextstopband) {
+ length = nextstopband;
+ }
+
+ filter->StartBand = nextstopband - length;
+ filter->StopBand = nextstopband;
+ nextstopband = filter->StartBand;
+
+ if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
+ /* max(Order) = 15 (long), 7 (short) */
+ filter->Order = order = (UCHAR)FDKreadBits(bs, isLongFlag ? 4 : 3);
+ } else {
+ filter->Order = order = (UCHAR)FDKreadBits(bs, isLongFlag ? 5 : 3);
+
+ if (filter->Order > TNS_MAXIMUM_ORDER) {
+ ErrorStatus = AAC_DEC_TNS_READ_ERROR;
+ return ErrorStatus;
+ }
+ }
+
+ FDK_ASSERT(order <=
+ TNS_MAXIMUM_ORDER); /* avoid illegal memory access */
+ if (order) {
+ UCHAR coef, s_mask;
+ UCHAR i;
+ SCHAR n_mask;
+
+ static const UCHAR sgn_mask[] = {0x2, 0x4, 0x8};
+ static const SCHAR neg_mask[] = {~0x3, ~0x7, ~0xF};
+
+ filter->Direction = FDKreadBits(bs, 1) ? -1 : 1;
+
+ coef_compress = (UCHAR)FDKreadBits(bs, 1);
+
+ filter->Resolution = coef_res + 3;
+
+ s_mask = sgn_mask[coef_res + 1 - coef_compress];
+ n_mask = neg_mask[coef_res + 1 - coef_compress];
+
+ for (i = 0; i < order; i++) {
+ coef = (UCHAR)FDKreadBits(bs, filter->Resolution - coef_compress);
+ filter->Coeff[i] = (coef & s_mask) ? (coef | n_mask) : coef;
+ }
+ pTnsData->GainLd = 4;
+ }
+ }
+ }
+ }
+
+ pTnsData->Active = 1;
+
+ return ErrorStatus;
+}
+
+void CTns_ReadDataPresentUsac(HANDLE_FDK_BITSTREAM hBs, CTnsData *pTnsData0,
+ CTnsData *pTnsData1, UCHAR *ptns_on_lr,
+ const CIcsInfo *pIcsInfo, const UINT flags,
+ const UINT elFlags, const int fCommonWindow) {
+ int common_tns = 0;
+
+ if (fCommonWindow) {
+ common_tns = FDKreadBit(hBs);
+ }
+ { *ptns_on_lr = FDKreadBit(hBs); }
+ if (common_tns) {
+ pTnsData0->DataPresent = 1;
+ CTns_Read(hBs, pTnsData0, pIcsInfo, flags);
+
+ pTnsData0->DataPresent = 0;
+ pTnsData0->Active = 1;
+ *pTnsData1 = *pTnsData0;
+ } else {
+ int tns_present_both;
+
+ tns_present_both = FDKreadBit(hBs);
+ if (tns_present_both) {
+ pTnsData0->DataPresent = 1;
+ pTnsData1->DataPresent = 1;
+ } else {
+ pTnsData1->DataPresent = FDKreadBit(hBs);
+ pTnsData0->DataPresent = !pTnsData1->DataPresent;
+ }
+ }
+}
+
+/*!
+ \brief Apply tns to spectral lines
+
+ The function applies the tns to the spectrum,
+
+ \return none
+*/
+void CTns_Apply(CTnsData *RESTRICT pTnsData, /*!< pointer to aac decoder info */
+ const CIcsInfo *pIcsInfo, SPECTRAL_PTR pSpectralCoefficient,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const INT granuleLength, const UCHAR nbands,
+ const UCHAR igf_active, const UINT flags) {
+ int window, index, start, stop, size, start_window, wins_per_frame;
+
+ if (pTnsData->Active) {
+ C_AALLOC_SCRATCH_START(coeff, FIXP_TCC, TNS_MAXIMUM_ORDER)
+
+ {
+ start_window = 0;
+ wins_per_frame = GetWindowsPerFrame(pIcsInfo);
+ }
+
+ for (window = start_window; window < wins_per_frame; window++) {
+ FIXP_DBL *pSpectrum;
+
+ { pSpectrum = SPEC(pSpectralCoefficient, window, granuleLength); }
+
+ for (index = 0; index < pTnsData->NumberOfFilters[window]; index++) {
+ CFilter *filter = &pTnsData->Filter[window][index];
+
+ if (filter->Order > 0) {
+ FIXP_TCC *pCoeff;
+ UCHAR tns_max_bands;
+
+ pCoeff = coeff;
+ if (filter->Resolution == 3) {
+ int i;
+ for (i = 0; i < filter->Order; i++)
+ *pCoeff++ = FDKaacDec_tnsCoeff3[filter->Coeff[i] + 4];
+ } else {
+ int i;
+ for (i = 0; i < filter->Order; i++)
+ *pCoeff++ = FDKaacDec_tnsCoeff4[filter->Coeff[i] + 8];
+ }
+
+ switch (granuleLength) {
+ case 480:
+ tns_max_bands =
+ tns_max_bands_tbl_480[pSamplingRateInfo->samplingRateIndex];
+ break;
+ case 512:
+ tns_max_bands =
+ tns_max_bands_tbl_512[pSamplingRateInfo->samplingRateIndex];
+ break;
+ default:
+ tns_max_bands = GetMaximumTnsBands(
+ pIcsInfo, pSamplingRateInfo->samplingRateIndex);
+ /* See redefinition of TNS_MAX_BANDS table */
+ if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
+ (pSamplingRateInfo->samplingRateIndex > 5)) {
+ tns_max_bands += 1;
+ }
+ break;
+ }
+
+ start = fixMin(fixMin(filter->StartBand, tns_max_bands), nbands);
+
+ start = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo)[start];
+
+ if (igf_active) {
+ stop = fixMin(filter->StopBand, nbands);
+ } else {
+ stop = fixMin(fixMin(filter->StopBand, tns_max_bands), nbands);
+ }
+
+ stop = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo)[stop];
+
+ size = stop - start;
+
+ if (size) {
+ C_ALLOC_SCRATCH_START(state, FIXP_DBL, TNS_MAXIMUM_ORDER)
+
+ FDKmemclear(state, TNS_MAXIMUM_ORDER * sizeof(FIXP_DBL));
+ CLpc_SynthesisLattice(pSpectrum + start, size, 0, 0,
+ filter->Direction, coeff, filter->Order,
+ state);
+
+ C_ALLOC_SCRATCH_END(state, FIXP_DBL, TNS_MAXIMUM_ORDER)
+ }
+ }
+ }
+ }
+ C_AALLOC_SCRATCH_END(coeff, FIXP_TCC, TNS_MAXIMUM_ORDER)
+ }
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_tns.h b/fdk-aac/libAACdec/src/aacdec_tns.h
new file mode 100644
index 0000000..1a63bed
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_tns.h
@@ -0,0 +1,149 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: temporal noise shaping tool
+
+*******************************************************************************/
+
+#ifndef AACDEC_TNS_H
+#define AACDEC_TNS_H
+
+#include "common_fix.h"
+
+enum {
+ TNS_MAX_WINDOWS = 8, /* 8 */
+ TNS_MAXIMUM_FILTERS = 3
+};
+
+/* TNS_MAXIMUM_ORDER (for memory allocation)
+ 12 for AAC-LC and AAC-SSR. Set to 20 for AAC-Main (AOT 1). Some broken
+ encoders also do order 20 for AAC-LC :( 15 for USAC (AOT 42)
+*/
+#define TNS_MAXIMUM_ORDER (20)
+
+#if (TNS_MAXIMUM_ORDER < 15)
+#error USAC: TNS filter order up 15 can be signaled!
+#endif
+
+typedef struct {
+ SCHAR Coeff[TNS_MAXIMUM_ORDER];
+
+ UCHAR StartBand;
+ UCHAR StopBand;
+
+ SCHAR Direction;
+ SCHAR Resolution;
+
+ UCHAR Order;
+} CFilter;
+
+typedef struct {
+ CFilter Filter[TNS_MAX_WINDOWS][TNS_MAXIMUM_FILTERS];
+ UCHAR NumberOfFilters[TNS_MAX_WINDOWS];
+ UCHAR DataPresent;
+ UCHAR Active;
+
+ /* log2 of the maximum total filter gains. The value is required to
+ keep necessary mantissa headroom so that while applying the TNS predictor
+ the mantissas do not overflow. */
+ UCHAR GainLd;
+} CTnsData;
+
+void CTns_Reset(CTnsData *pTnsData);
+
+#endif /* #ifndef AACDEC_TNS_H */
diff --git a/fdk-aac/libAACdec/src/aacdecoder.cpp b/fdk-aac/libAACdec/src/aacdecoder.cpp
new file mode 100644
index 0000000..8f03328
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdecoder.cpp
@@ -0,0 +1,3464 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \page default General Overview of the AAC Decoder Implementation
+
+ The main entry point to decode a AAC frame is CAacDecoder_DecodeFrame(). It
+ handles the different transport multiplexes and bitstream formats supported by
+ this implementation. It extracts the AAC_raw_data_blocks from these bitstreams
+ to further process then in the actual decoding stages.
+
+ Note: Click on a function of file in the above image to see details about the
+ function. Also note, that this is just an overview of the most important
+ functions and not a complete call graph.
+
+ <h2>1 Bitstream deformatter</h2>
+ The basic bit stream parser function CChannelElement_Read() is called. It uses
+ other subcalls in order to parse and unpack the bitstreams. Note, that this
+ includes huffmann decoding of the coded spectral data. This operation can be
+ computational significant specifically at higher bitrates. Optimization is
+ likely in CBlock_ReadSpectralData().
+
+ The bitstream deformatter also includes many bitfield operations. Profiling on
+ the target will determine required optimizations.
+
+ <h2>2 Actual decoding to retain the time domain output</h2>
+ The basic bitstream deformatter function CChannelElement_Decode() for CPE
+ elements and SCE elements are called. Except for the stereo processing (2.1)
+ which is only used for CPE elements, the function calls for CPE or SCE are
+ similar, except that CPE always processes to independent channels while SCE
+ only processes one channel.
+
+ Often there is the distinction between long blocks and short blocks. However,
+ computational expensive functions that ususally require optimization are being
+ shared by these two groups,
+
+ <h3>2.1 Stereo processing for CPE elements</h3>
+ CChannelPairElement_Decode() first calles the joint stereo tools in
+ stereo.cpp when required.
+
+ <h3>2.2 Scaling of spectral data</h3>
+ CBlock_ScaleSpectralData().
+
+ <h3>2.3 Apply additional coding tools</h3>
+ ApplyTools() calles the PNS tools in case of MPEG-4 bitstreams, and TNS
+ filtering CTns_Apply() for MPEG-2 and MPEG-4 bitstreams. The function
+ TnsFilterIIR() which is called by CTns_Apply() (2.3.1) might require some
+ optimization.
+
+ <h2>3 Frequency-To-Time conversion</h3>
+ The filterbank is called using CBlock_FrequencyToTime() using the MDCT module
+ from the FDK Tools
+
+*/
+
+#include "aacdecoder.h"
+
+#include "aac_rom.h"
+#include "aac_ram.h"
+#include "channel.h"
+#include "FDK_audio.h"
+
+#include "aacdec_pns.h"
+
+#include "sbrdecoder.h"
+
+#include "sac_dec_lib.h"
+
+#include "aacdec_hcr.h"
+#include "rvlc.h"
+
+#include "usacdec_lpd.h"
+
+#include "ac_arith_coder.h"
+
+#include "tpdec_lib.h"
+
+#include "conceal.h"
+
+#include "FDK_crc.h"
+#define PS_IS_EXPLICITLY_DISABLED(aot, flags) \
+ (((aot) == AOT_DRM_AAC) && !(flags & AC_PS_PRESENT))
+
+#define IS_STEREO_SBR(el_id, stereoConfigIndex) \
+ (((el_id) == ID_USAC_CPE && (stereoConfigIndex) == 0) || \
+ ((el_id) == ID_USAC_CPE && (stereoConfigIndex) == 3))
+
+void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self) {
+ FDK_ASSERT(
+ !((self->flags[0] & AC_MPS_PRESENT) && (self->flags[0] & AC_PS_PRESENT)));
+
+ /* Assign user requested mode */
+ self->qmfModeCurr = self->qmfModeUser;
+
+ if (IS_USAC(self->streamInfo.aot)) {
+ self->qmfModeCurr = MODE_HQ;
+ }
+
+ if (self->qmfModeCurr == NOT_DEFINED) {
+ if ((IS_LOWDELAY(self->streamInfo.aot) &&
+ (self->flags[0] & AC_MPS_PRESENT)) ||
+ ((self->streamInfo.aacNumChannels == 1) &&
+ ((CAN_DO_PS(self->streamInfo.aot) &&
+ !(self->flags[0] & AC_MPS_PRESENT)) ||
+ (IS_USAC(self->streamInfo.aot))))) {
+ self->qmfModeCurr = MODE_HQ;
+ } else {
+ self->qmfModeCurr = MODE_LP;
+ }
+ }
+
+ if (self->mpsEnableCurr) {
+ if (IS_LOWDELAY(self->streamInfo.aot) &&
+ (self->qmfModeCurr == MODE_LP)) { /* Overrule user requested QMF mode */
+ self->qmfModeCurr = MODE_HQ;
+ }
+ /* Set and check if MPS decoder allows the current mode */
+ switch (mpegSurroundDecoder_SetParam(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
+ SACDEC_PARTIALLY_COMPLEX, self->qmfModeCurr == MODE_LP)) {
+ case MPS_OK:
+ break;
+ case MPS_INVALID_PARAMETER: { /* Only one mode supported. Find out which
+ one: */
+ LIB_INFO libInfo[FDK_MODULE_LAST];
+ UINT mpsCaps;
+
+ FDKinitLibInfo(libInfo);
+ mpegSurroundDecoder_GetLibInfo(libInfo);
+ mpsCaps = FDKlibInfo_getCapabilities(libInfo, FDK_MPSDEC);
+
+ if (((mpsCaps & CAPF_MPS_LP) && (self->qmfModeCurr == MODE_LP)) ||
+ ((mpsCaps & CAPF_MPS_HQ) &&
+ (self->qmfModeCurr ==
+ MODE_HQ))) { /* MPS decoder does support the requested mode. */
+ break;
+ }
+ }
+ FDK_FALLTHROUGH;
+ default:
+ if (self->qmfModeUser == NOT_DEFINED) {
+ /* Revert in case mpegSurroundDecoder_SetParam() fails. */
+ self->qmfModeCurr =
+ (self->qmfModeCurr == MODE_LP) ? MODE_HQ : MODE_LP;
+ } else {
+ /* in case specific mode was requested we disable MPS and playout the
+ * downmix */
+ self->mpsEnableCurr = 0;
+ }
+ }
+ }
+
+ /* Set SBR to current QMF mode. Error does not matter. */
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_QMF_MODE,
+ (self->qmfModeCurr == MODE_LP));
+ self->psPossible =
+ ((CAN_DO_PS(self->streamInfo.aot) &&
+ !PS_IS_EXPLICITLY_DISABLED(self->streamInfo.aot, self->flags[0]) &&
+ self->streamInfo.aacNumChannels == 1 &&
+ !(self->flags[0] & AC_MPS_PRESENT))) &&
+ self->qmfModeCurr == MODE_HQ;
+ FDK_ASSERT(!((self->flags[0] & AC_MPS_PRESENT) && self->psPossible));
+}
+
+void CAacDecoder_SignalInterruption(HANDLE_AACDECODER self) {
+ if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
+ int i;
+
+ for (i = 0; i < fMin(self->aacChannels, (8)); i++) {
+ if (self->pAacDecoderStaticChannelInfo
+ [i]) { /* number of active channels can be smaller */
+ self->pAacDecoderStaticChannelInfo[i]->hArCo->m_numberLinesPrev = 0;
+ }
+ }
+ }
+}
+
+/*!
+ \brief Calculates the number of element channels
+
+ \type channel type
+ \usacStereoConfigIndex usac stereo config index
+
+ \return element channels
+*/
+static int CAacDecoder_GetELChannels(MP4_ELEMENT_ID type,
+ UCHAR usacStereoConfigIndex) {
+ int el_channels = 0;
+
+ switch (type) {
+ case ID_USAC_CPE:
+ if (usacStereoConfigIndex == 1) {
+ el_channels = 1;
+ } else {
+ el_channels = 2;
+ }
+ break;
+ case ID_CPE:
+ el_channels = 2;
+ break;
+ case ID_USAC_SCE:
+ case ID_USAC_LFE:
+ case ID_SCE:
+ case ID_LFE:
+ el_channels = 1;
+ break;
+ default:
+ el_channels = 0;
+ break;
+ }
+
+ return el_channels;
+}
+
+/*!
+ \brief Reset ancillary data struct. Call before parsing a new frame.
+
+ \ancData Pointer to ancillary data structure
+
+ \return Error code
+*/
+static AAC_DECODER_ERROR CAacDecoder_AncDataReset(CAncData *ancData) {
+ int i;
+ for (i = 0; i < 8; i++) {
+ ancData->offset[i] = 0;
+ }
+ ancData->nrElements = 0;
+
+ return AAC_DEC_OK;
+}
+
+/*!
+ \brief Initialize ancillary buffer
+
+ \ancData Pointer to ancillary data structure
+ \buffer Pointer to (external) anc data buffer
+ \size Size of the buffer pointed on by buffer in bytes
+
+ \return Error code
+*/
+AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData,
+ unsigned char *buffer, int size) {
+ if (size >= 0) {
+ ancData->buffer = buffer;
+ ancData->bufferSize = size;
+
+ CAacDecoder_AncDataReset(ancData);
+
+ return AAC_DEC_OK;
+ }
+
+ return AAC_DEC_ANC_DATA_ERROR;
+}
+
+/*!
+ \brief Get one ancillary data element
+
+ \ancData Pointer to ancillary data structure
+ \index Index of the anc data element to get
+ \ptr Pointer to a buffer receiving a pointer to the requested anc data element
+ \size Pointer to a buffer receiving the length of the requested anc data
+ element in bytes
+
+ \return Error code
+*/
+AAC_DECODER_ERROR CAacDecoder_AncDataGet(CAncData *ancData, int index,
+ unsigned char **ptr, int *size) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+
+ *ptr = NULL;
+ *size = 0;
+
+ if (index >= 0 && index < 8 - 1 && index < ancData->nrElements) {
+ *ptr = &ancData->buffer[ancData->offset[index]];
+ *size = ancData->offset[index + 1] - ancData->offset[index];
+ }
+
+ return error;
+}
+
+/*!
+ \brief Parse ancillary data
+
+ \ancData Pointer to ancillary data structure
+ \hBs Handle to FDK bitstream
+ \ancBytes Length of ancillary data to read from the bitstream
+
+ \return Error code
+*/
+static AAC_DECODER_ERROR CAacDecoder_AncDataParse(CAncData *ancData,
+ HANDLE_FDK_BITSTREAM hBs,
+ const int ancBytes) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ int readBytes = 0;
+
+ if (ancData->buffer != NULL) {
+ if (ancBytes > 0) {
+ /* write ancillary data to external buffer */
+ int offset = ancData->offset[ancData->nrElements];
+
+ if ((offset + ancBytes) > ancData->bufferSize) {
+ error = AAC_DEC_TOO_SMALL_ANC_BUFFER;
+ } else if (ancData->nrElements >= 8 - 1) {
+ error = AAC_DEC_TOO_MANY_ANC_ELEMENTS;
+ } else {
+ int i;
+
+ for (i = 0; i < ancBytes; i++) {
+ ancData->buffer[i + offset] = FDKreadBits(hBs, 8);
+ readBytes++;
+ }
+
+ ancData->nrElements++;
+ ancData->offset[ancData->nrElements] =
+ ancBytes + ancData->offset[ancData->nrElements - 1];
+ }
+ }
+ }
+
+ readBytes = ancBytes - readBytes;
+
+ if (readBytes > 0) {
+ /* skip data */
+ FDKpushFor(hBs, readBytes << 3);
+ }
+
+ return error;
+}
+
+/*!
+ \brief Read Stream Data Element
+
+ \bs Bitstream Handle
+
+ \return Error code
+*/
+static AAC_DECODER_ERROR CDataStreamElement_Read(HANDLE_AACDECODER self,
+ HANDLE_FDK_BITSTREAM bs,
+ UCHAR *elementInstanceTag,
+ UINT alignmentAnchor) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ UINT dseBits;
+ INT dataStart;
+ int dataByteAlignFlag, count;
+
+ FDK_ASSERT(self != NULL);
+
+ int crcReg = transportDec_CrcStartReg(self->hInput, 0);
+
+ /* Element Instance Tag */
+ *elementInstanceTag = FDKreadBits(bs, 4);
+ /* Data Byte Align Flag */
+ dataByteAlignFlag = FDKreadBits(bs, 1);
+
+ count = FDKreadBits(bs, 8);
+
+ if (count == 255) {
+ count += FDKreadBits(bs, 8); /* EscCount */
+ }
+ dseBits = count * 8;
+
+ if (dataByteAlignFlag) {
+ FDKbyteAlign(bs, alignmentAnchor);
+ }
+
+ dataStart = (INT)FDKgetValidBits(bs);
+
+ error = CAacDecoder_AncDataParse(&self->ancData, bs, count);
+ transportDec_CrcEndReg(self->hInput, crcReg);
+
+ {
+ /* Move to the beginning of the data chunk */
+ FDKpushBack(bs, dataStart - (INT)FDKgetValidBits(bs));
+
+ /* Read Anc data if available */
+ aacDecoder_drcMarkPayload(self->hDrcInfo, bs, DVB_DRC_ANC_DATA);
+ }
+
+ {
+ PCMDMX_ERROR dmxErr = PCMDMX_OK;
+
+ /* Move to the beginning of the data chunk */
+ FDKpushBack(bs, dataStart - (INT)FDKgetValidBits(bs));
+
+ /* Read DMX meta-data */
+ dmxErr = pcmDmx_Parse(self->hPcmUtils, bs, dseBits, 0 /* not mpeg2 */);
+ if (error == AAC_DEC_OK && dmxErr != PCMDMX_OK) {
+ error = AAC_DEC_UNKNOWN;
+ }
+ }
+
+ /* Move to the very end of the element. */
+ FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - dataStart + (INT)dseBits);
+
+ return error;
+}
+
+/*!
+ \brief Read Program Config Element
+
+ \bs Bitstream Handle
+ \pTp Transport decoder handle for CRC handling
+ \pce Pointer to PCE buffer
+ \channelConfig Current channel configuration
+ \alignAnchor Anchor for byte alignment
+
+ \return PCE status (-1: fail, 0: no new PCE, 1: PCE updated, 2: PCE updated
+ need re-config).
+*/
+static int CProgramConfigElement_Read(HANDLE_FDK_BITSTREAM bs,
+ HANDLE_TRANSPORTDEC pTp,
+ CProgramConfig *pce,
+ const UINT channelConfig,
+ const UINT alignAnchor) {
+ int pceStatus = 0;
+ int crcReg;
+
+ /* read PCE to temporal buffer first */
+ C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
+
+ CProgramConfig_Init(tmpPce);
+
+ crcReg = transportDec_CrcStartReg(pTp, 0);
+
+ CProgramConfig_Read(tmpPce, bs, alignAnchor);
+
+ transportDec_CrcEndReg(pTp, crcReg);
+
+ if (CProgramConfig_IsValid(tmpPce) && (tmpPce->Profile == 1)) {
+ if (!CProgramConfig_IsValid(pce) && (channelConfig > 0)) {
+ /* Create a standard channel config PCE to compare with */
+ CProgramConfig_GetDefault(pce, channelConfig);
+ }
+
+ if (CProgramConfig_IsValid(pce)) {
+ /* Compare the new and the old PCE (tags ignored) */
+ switch (CProgramConfig_Compare(pce, tmpPce)) {
+ case 1: /* Channel configuration not changed. Just new metadata. */
+ FDKmemcpy(pce, tmpPce,
+ sizeof(CProgramConfig)); /* Store the complete PCE */
+ pceStatus = 1; /* New PCE but no change of config */
+ break;
+ case 2: /* The number of channels are identical but not the config */
+ case -1: /* The channel configuration is completely different */
+ pceStatus = -1; /* Not supported! */
+ break;
+ case 0: /* Nothing to do because PCE matches the old one exactly. */
+ default:
+ /* pceStatus = 0; */
+ break;
+ }
+ }
+ }
+
+ C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
+
+ return pceStatus;
+}
+
+/*!
+ \brief Prepares crossfade for USAC DASH IPF config change
+
+ \pTimeData Pointer to time data
+ \pTimeDataFlush Pointer to flushed time data
+ \numChannels Number of channels
+ \frameSize Size of frame
+ \interleaved Indicates if time data is interleaved
+
+ \return Error code
+*/
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade(
+ const INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels,
+ const INT frameSize, const INT interleaved) {
+ int i, ch, s1, s2;
+ AAC_DECODER_ERROR ErrorStatus;
+
+ ErrorStatus = AAC_DEC_OK;
+
+ if (interleaved) {
+ s1 = 1;
+ s2 = numChannels;
+ } else {
+ s1 = frameSize;
+ s2 = 1;
+ }
+
+ for (ch = 0; ch < numChannels; ch++) {
+ const INT_PCM *pIn = &pTimeData[ch * s1];
+ for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
+ pTimeDataFlush[ch][i] = *pIn;
+ pIn += s2;
+ }
+ }
+
+ return ErrorStatus;
+}
+
+/*!
+ \brief Applies crossfade for USAC DASH IPF config change
+
+ \pTimeData Pointer to time data
+ \pTimeDataFlush Pointer to flushed time data
+ \numChannels Number of channels
+ \frameSize Size of frame
+ \interleaved Indicates if time data is interleaved
+
+ \return Error code
+*/
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade(
+ INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels,
+ const INT frameSize, const INT interleaved) {
+ int i, ch, s1, s2;
+ AAC_DECODER_ERROR ErrorStatus;
+
+ ErrorStatus = AAC_DEC_OK;
+
+ if (interleaved) {
+ s1 = 1;
+ s2 = numChannels;
+ } else {
+ s1 = frameSize;
+ s2 = 1;
+ }
+
+ for (ch = 0; ch < numChannels; ch++) {
+ INT_PCM *pIn = &pTimeData[ch * s1];
+ for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
+ FIXP_SGL alpha = (FIXP_SGL)i
+ << (FRACT_BITS - 1 - TIME_DATA_FLUSH_SIZE_SF);
+ FIXP_DBL time = FX_PCM2FX_DBL(*pIn);
+ FIXP_DBL timeFlush = FX_PCM2FX_DBL(pTimeDataFlush[ch][i]);
+
+ *pIn = (INT_PCM)(FIXP_PCM)FX_DBL2FX_PCM(
+ timeFlush - fMult(timeFlush, alpha) + fMult(time, alpha));
+ pIn += s2;
+ }
+ }
+
+ return ErrorStatus;
+}
+
+/*!
+ \brief Parse PreRoll Extension Payload
+
+ \self Handle of AAC decoder
+ \numPrerollAU Number of preRoll AUs
+ \prerollAUOffset Offset to each preRoll AU
+ \prerollAULength Length of each preRoll AU
+
+ \return Error code
+*/
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PreRollExtensionPayloadParse(
+ HANDLE_AACDECODER self, UINT *numPrerollAU, UINT *prerollAUOffset,
+ UINT *prerollAULength) {
+ FDK_BITSTREAM bs;
+ HANDLE_FDK_BITSTREAM hBs;
+ AAC_DECODER_ERROR ErrorStatus;
+
+ INT auStartAnchor;
+ UINT independencyFlag;
+ UINT extPayloadPresentFlag;
+ UINT useDefaultLengthFlag;
+ UINT configLength = 0;
+ UINT preRollPossible = 1;
+ UINT i;
+ UCHAR configChanged = 0;
+ UCHAR config[TP_USAC_MAX_CONFIG_LEN] = {0};
+ UCHAR
+ implicitExplicitCfgDiff = 0; /* in case implicit and explicit config is
+ equal preroll AU's should be processed
+ after decoder reset */
+
+ ErrorStatus = AAC_DEC_OK;
+
+ hBs = transportDec_GetBitstream(self->hInput, 0);
+ bs = *hBs;
+
+ auStartAnchor = (INT)FDKgetValidBits(hBs);
+ if (auStartAnchor <= 0) {
+ ErrorStatus = AAC_DEC_NOT_ENOUGH_BITS;
+ goto bail;
+ }
+
+ /* Independency flag */
+ FDKreadBit(hBs);
+
+ /* Payload present flag of extension ID_EXT_ELE_AUDIOPREROLL must be one */
+ extPayloadPresentFlag = FDKreadBits(hBs, 1);
+ if (!extPayloadPresentFlag) {
+ preRollPossible = 0;
+ }
+
+ /* Default length flag of extension ID_EXT_ELE_AUDIOPREROLL must be zero */
+ useDefaultLengthFlag = FDKreadBits(hBs, 1);
+ if (useDefaultLengthFlag) {
+ preRollPossible = 0;
+ }
+
+ if (preRollPossible) { /* extPayloadPresentFlag && !useDefaultLengthFlag */
+ /* Read overall ext payload length, useDefaultLengthFlag must be zero. */
+ escapedValue(hBs, 8, 16, 0);
+
+ /* Read RSVD60 Config size */
+ configLength = escapedValue(hBs, 4, 4, 8);
+
+ /* Avoid decoding pre roll frames if there was no config change and no
+ * config is included in the pre roll ext payload. */
+ }
+
+ /* If pre roll not possible then exit. */
+ if (preRollPossible == 0) {
+ /* Sanity check: if flushing is switched on, preRollPossible must be 1 */
+ if (self->flushStatus != AACDEC_FLUSH_OFF) {
+ /* Mismatch of current payload and flushing status */
+ self->flushStatus = AACDEC_FLUSH_OFF;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ goto bail;
+ }
+
+ if (self->flags[0] & AC_USAC) {
+ if (configLength > 0) {
+ /* DASH IPF USAC Config Change: Read new config and compare with current
+ * config. Apply reconfiguration if config's are different. */
+ for (i = 0; i < configLength; i++) {
+ config[i] = FDKreadBits(hBs, 8);
+ }
+ TRANSPORTDEC_ERROR terr;
+ terr = transportDec_InBandConfig(self->hInput, config, configLength,
+ self->buildUpStatus, &configChanged, 0,
+ &implicitExplicitCfgDiff);
+ if (terr != TRANSPORTDEC_OK) {
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+ }
+
+ /* For the first frame buildUpStatus is not set and no flushing is performed
+ * but preroll AU's should processed. */
+ /* For USAC there is no idle state. */
+ if ((self->streamInfo.numChannels == 0) && !implicitExplicitCfgDiff &&
+ (self->flags[0] & AC_USAC)) {
+ self->buildUpStatus = AACDEC_USAC_BUILD_UP_ON;
+ /* sanity check: if buildUp status on -> flushing must be off */
+ if (self->flushStatus != AACDEC_FLUSH_OFF) {
+ self->flushStatus = AACDEC_FLUSH_OFF;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ if (self->flags[0] & AC_USAC) {
+ /* We are interested in preroll AUs if an explicit or an implicit config
+ * change is signalized in other words if the build up status is set. */
+ if (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON) {
+ self->applyCrossfade |= FDKreadBit(hBs);
+ FDKreadBit(hBs); /* reserved */
+ /* Read num preroll AU's */
+ *numPrerollAU = escapedValue(hBs, 2, 4, 0);
+ /* check limits for USAC */
+ if (*numPrerollAU > AACDEC_MAX_NUM_PREROLL_AU_USAC) {
+ *numPrerollAU = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+ }
+
+ for (i = 0; i < *numPrerollAU; i++) {
+ /* For every AU get length and offset in the bitstream */
+ prerollAULength[i] = escapedValue(hBs, 16, 16, 0);
+ if (prerollAULength[i] > 0) {
+ prerollAUOffset[i] = auStartAnchor - (INT)FDKgetValidBits(hBs);
+ independencyFlag = FDKreadBit(hBs);
+ if (i == 0 && !independencyFlag) {
+ *numPrerollAU = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ FDKpushFor(hBs, prerollAULength[i] * 8 - 1);
+ self->prerollAULength[i] = (prerollAULength[i] * 8) + prerollAUOffset[i];
+ } else {
+ *numPrerollAU = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR; /* Something is wrong */
+ goto bail;
+ }
+ }
+
+bail:
+
+ *hBs = bs;
+
+ return ErrorStatus;
+}
+
+/*!
+ \brief Parse Extension Payload
+
+ \self Handle of AAC decoder
+ \count Pointer to bit counter.
+ \previous_element ID of previous element (required by some extension payloads)
+
+ \return Error code
+*/
+static AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse(
+ HANDLE_AACDECODER self, HANDLE_FDK_BITSTREAM hBs, int *count,
+ MP4_ELEMENT_ID previous_element, int elIndex, int fIsFillElement) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ EXT_PAYLOAD_TYPE extension_type;
+ int bytes = (*count) >> 3;
+ int crcFlag = 0;
+
+ if (*count < 4) {
+ return AAC_DEC_PARSE_ERROR;
+ } else if ((INT)FDKgetValidBits(hBs) < *count) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ extension_type =
+ (EXT_PAYLOAD_TYPE)FDKreadBits(hBs, 4); /* bs_extension_type */
+ *count -= 4;
+
+ /* For ELD, the SBR signaling is explicit and parsed in
+ aacDecoder_ParseExplicitMpsAndSbr(), therefore skip SBR if implicit
+ present. */
+ if ((self->flags[0] & AC_ELD) && ((extension_type == EXT_SBR_DATA_CRC) ||
+ (extension_type == EXT_SBR_DATA))) {
+ extension_type = EXT_FIL; /* skip sbr data */
+ }
+
+ switch (extension_type) {
+ case EXT_DYNAMIC_RANGE: {
+ INT readBits =
+ aacDecoder_drcMarkPayload(self->hDrcInfo, hBs, MPEG_DRC_EXT_DATA);
+
+ if (readBits > *count) { /* Read too much. Something went wrong! */
+ error = AAC_DEC_PARSE_ERROR;
+ }
+ *count -= readBits;
+ } break;
+ case EXT_UNI_DRC: {
+ DRC_DEC_ERROR drcErr = DRC_DEC_OK;
+ DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED;
+ INT nBitsRemaining = FDKgetValidBits(hBs);
+ INT readBits;
+
+ switch (self->streamInfo.aot) {
+ case AOT_AAC_LC:
+ case AOT_SBR:
+ case AOT_PS:
+ drcDecCodecMode = DRC_DEC_MPEG_4_AAC;
+ break;
+ default:
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ drcErr = FDK_drcDec_SetCodecMode(self->hUniDrcDecoder, drcDecCodecMode);
+ if (drcErr) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ drcErr = FDK_drcDec_ReadUniDrc(self->hUniDrcDecoder, hBs);
+ if (drcErr) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ readBits = (INT)nBitsRemaining - (INT)FDKgetValidBits(hBs);
+ if (readBits > *count) { /* Read too much. Something went wrong! */
+ error = AAC_DEC_PARSE_ERROR;
+ }
+ *count -= readBits;
+ /* Skip any trailing bits */
+ FDKpushFor(hBs, *count);
+ *count = 0;
+ } break;
+ case EXT_LDSAC_DATA:
+ case EXT_SAC_DATA:
+ /* Read MPEG Surround Extension payload */
+ {
+ int err, mpsSampleRate, mpsFrameSize;
+
+ if (self->flags[0] & AC_PS_PRESENT) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ /* Handle SBR dual rate case */
+ if (self->streamInfo.extSamplingRate != 0) {
+ mpsSampleRate = self->streamInfo.extSamplingRate;
+ mpsFrameSize = self->streamInfo.aacSamplesPerFrame *
+ (self->streamInfo.extSamplingRate /
+ self->streamInfo.aacSampleRate);
+ } else {
+ mpsSampleRate = self->streamInfo.aacSampleRate;
+ mpsFrameSize = self->streamInfo.aacSamplesPerFrame;
+ }
+ /* Setting of internal MPS state; may be reset in
+ CAacDecoder_SyncQmfMode if decoder is unable to decode with user
+ defined qmfMode */
+ if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_ELD))) {
+ self->mpsEnableCurr = self->mpsEnableUser;
+ }
+ if (self->mpsEnableCurr) {
+ if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig) {
+ /* if not done yet, allocate full MPEG Surround decoder instance */
+ if (mpegSurroundDecoder_IsFullMpegSurroundDecoderInstanceAvailable(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) ==
+ SAC_INSTANCE_NOT_FULL_AVAILABLE) {
+ if (mpegSurroundDecoder_Open(
+ (CMpegSurroundDecoder **)&self->pMpegSurroundDecoder, -1,
+ &self->qmfDomain)) {
+ return AAC_DEC_OUT_OF_MEMORY;
+ }
+ }
+ }
+ err = mpegSurroundDecoder_Parse(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, hBs, count,
+ self->streamInfo.aot, mpsSampleRate, mpsFrameSize,
+ self->flags[0] & AC_INDEP);
+ if (err == MPS_OK) {
+ self->flags[0] |= AC_MPS_PRESENT;
+ } else {
+ error = AAC_DEC_PARSE_ERROR;
+ }
+ }
+ /* Skip any trailing bytes */
+ FDKpushFor(hBs, *count);
+ *count = 0;
+ }
+ break;
+
+ case EXT_SBR_DATA_CRC:
+ crcFlag = 1;
+ FDK_FALLTHROUGH;
+ case EXT_SBR_DATA:
+ if (IS_CHANNEL_ELEMENT(previous_element)) {
+ SBR_ERROR sbrError;
+ UCHAR configMode = 0;
+ UCHAR configChanged = 0;
+
+ CAacDecoder_SyncQmfMode(self);
+
+ configMode |= AC_CM_ALLOC_MEM;
+
+ sbrError = sbrDecoder_InitElement(
+ self->hSbrDecoder, self->streamInfo.aacSampleRate,
+ self->streamInfo.extSamplingRate,
+ self->streamInfo.aacSamplesPerFrame, self->streamInfo.aot,
+ previous_element, elIndex,
+ 2, /* Signalize that harmonicSBR shall be ignored in the config
+ change detection */
+ 0, configMode, &configChanged, self->downscaleFactor);
+
+ if (sbrError == SBRDEC_OK) {
+ sbrError = sbrDecoder_Parse(self->hSbrDecoder, hBs,
+ self->pDrmBsBuffer, self->drmBsBufferSize,
+ count, *count, crcFlag, previous_element,
+ elIndex, self->flags[0], self->elFlags);
+ /* Enable SBR for implicit SBR signalling but only if no severe error
+ * happend. */
+ if ((sbrError == SBRDEC_OK) || (sbrError == SBRDEC_PARSE_ERROR)) {
+ self->sbrEnabled = 1;
+ }
+ } else {
+ /* Do not try to apply SBR because initializing the element failed. */
+ self->sbrEnabled = 0;
+ }
+ /* Citation from ISO/IEC 14496-3 chapter 4.5.2.1.5.2
+ Fill elements containing an extension_payload() with an extension_type
+ of EXT_SBR_DATA or EXT_SBR_DATA_CRC shall not contain any other
+ extension_payload of any other extension_type.
+ */
+ if (fIsFillElement) {
+ FDKpushBiDirectional(hBs, *count);
+ *count = 0;
+ } else {
+ /* If this is not a fill element with a known length, we are screwed
+ * and further parsing makes no sense. */
+ if (sbrError != SBRDEC_OK) {
+ self->frameOK = 0;
+ }
+ }
+ } else {
+ error = AAC_DEC_PARSE_ERROR;
+ }
+ break;
+
+ case EXT_FILL_DATA: {
+ int temp;
+
+ temp = FDKreadBits(hBs, 4);
+ bytes--;
+ if (temp != 0) {
+ error = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ while (bytes > 0) {
+ temp = FDKreadBits(hBs, 8);
+ bytes--;
+ if (temp != 0xa5) {
+ error = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ }
+ *count = bytes << 3;
+ } break;
+
+ case EXT_DATA_ELEMENT: {
+ int dataElementVersion;
+
+ dataElementVersion = FDKreadBits(hBs, 4);
+ *count -= 4;
+ if (dataElementVersion == 0) /* ANC_DATA */
+ {
+ int temp, dataElementLength = 0;
+ do {
+ temp = FDKreadBits(hBs, 8);
+ *count -= 8;
+ dataElementLength += temp;
+ } while (temp == 255);
+
+ CAacDecoder_AncDataParse(&self->ancData, hBs, dataElementLength);
+ *count -= (dataElementLength << 3);
+ } else {
+ /* align = 0 */
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ } break;
+
+ case EXT_DATA_LENGTH:
+ if (!fIsFillElement /* Makes no sens to have an additional length in a
+ fill ... */
+ &&
+ (self->flags[0] &
+ AC_ER)) /* ... element because this extension payload type was ... */
+ { /* ... created to circumvent the missing length in ER-Syntax. */
+ int bitCnt, len = FDKreadBits(hBs, 4);
+ *count -= 4;
+
+ if (len == 15) {
+ int add_len = FDKreadBits(hBs, 8);
+ *count -= 8;
+ len += add_len;
+
+ if (add_len == 255) {
+ len += FDKreadBits(hBs, 16);
+ *count -= 16;
+ }
+ }
+ len <<= 3;
+ bitCnt = len;
+
+ if ((EXT_PAYLOAD_TYPE)FDKreadBits(hBs, 4) == EXT_DATA_LENGTH) {
+ /* Check NOTE 2: The extension_payload() included here must
+ not have extension_type == EXT_DATA_LENGTH. */
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ } else {
+ /* rewind and call myself again. */
+ FDKpushBack(hBs, 4);
+
+ error = CAacDecoder_ExtPayloadParse(
+ self, hBs, &bitCnt, previous_element, elIndex,
+ 1); /* Treat same as fill element */
+
+ *count -= len - bitCnt;
+ }
+ /* Note: the fall through in case the if statement above is not taken is
+ * intentional. */
+ break;
+ }
+ FDK_FALLTHROUGH;
+
+ case EXT_FIL:
+
+ default:
+ /* align = 4 */
+ FDKpushFor(hBs, *count);
+ *count = 0;
+ break;
+ }
+
+bail:
+ if ((error != AAC_DEC_OK) &&
+ fIsFillElement) { /* Skip the remaining extension bytes */
+ FDKpushBiDirectional(hBs, *count);
+ *count = 0;
+ /* Patch error code because decoding can go on. */
+ error = AAC_DEC_OK;
+ /* Be sure that parsing errors have been stored. */
+ }
+ return error;
+}
+
+static AAC_DECODER_ERROR aacDecoder_ParseExplicitMpsAndSbr(
+ HANDLE_AACDECODER self, HANDLE_FDK_BITSTREAM bs,
+ const MP4_ELEMENT_ID previous_element, const int previous_element_index,
+ const int element_index, const int el_cnt[]) {
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+ INT bitCnt = 0;
+
+ /* get the remaining bits of this frame */
+ bitCnt = transportDec_GetAuBitsRemaining(self->hInput, 0);
+
+ if ((self->flags[0] & AC_SBR_PRESENT) &&
+ (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_ELD | AC_DRM))) {
+ SBR_ERROR err = SBRDEC_OK;
+ int chElIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE] +
+ el_cnt[ID_LFE] + el_cnt[ID_USAC_SCE] +
+ el_cnt[ID_USAC_CPE] + el_cnt[ID_USAC_LFE];
+ INT bitCntTmp = bitCnt;
+
+ if (self->flags[0] & AC_USAC) {
+ chElIdx = numChElements - 1;
+ } else {
+ chElIdx = 0; /* ELD case */
+ }
+
+ for (; chElIdx < numChElements; chElIdx += 1) {
+ MP4_ELEMENT_ID sbrType;
+ SBR_ERROR errTmp;
+ if (self->flags[0] & (AC_USAC)) {
+ FDK_ASSERT((self->elements[element_index] == ID_USAC_SCE) ||
+ (self->elements[element_index] == ID_USAC_CPE));
+ sbrType = IS_STEREO_SBR(self->elements[element_index],
+ self->usacStereoConfigIndex[element_index])
+ ? ID_CPE
+ : ID_SCE;
+ } else
+ sbrType = self->elements[chElIdx];
+ errTmp = sbrDecoder_Parse(self->hSbrDecoder, bs, self->pDrmBsBuffer,
+ self->drmBsBufferSize, &bitCnt, -1,
+ self->flags[0] & AC_SBRCRC, sbrType, chElIdx,
+ self->flags[0], self->elFlags);
+ if (errTmp != SBRDEC_OK) {
+ err = errTmp;
+ bitCntTmp = bitCnt;
+ bitCnt = 0;
+ }
+ }
+ switch (err) {
+ case SBRDEC_PARSE_ERROR:
+ /* Can not go on parsing because we do not
+ know the length of the SBR extension data. */
+ FDKpushFor(bs, bitCntTmp);
+ bitCnt = 0;
+ break;
+ case SBRDEC_OK:
+ self->sbrEnabled = 1;
+ break;
+ default:
+ self->frameOK = 0;
+ break;
+ }
+ }
+
+ if ((bitCnt > 0) && (self->flags[0] & (AC_USAC | AC_RSVD50))) {
+ if ((self->flags[0] & AC_MPS_PRESENT) ||
+ (self->elFlags[element_index] & AC_EL_USAC_MPS212)) {
+ int err;
+
+ err = mpegSurroundDecoder_ParseNoHeader(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, bs, &bitCnt,
+ self->flags[0] & AC_INDEP);
+ if (err != MPS_OK) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ }
+ }
+
+ if (self->flags[0] & AC_DRM) {
+ if ((bitCnt = (INT)FDKgetValidBits(bs)) != 0) {
+ FDKpushBiDirectional(bs, bitCnt);
+ }
+ }
+
+ if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_DRM))) {
+ while (bitCnt > 7) {
+ ErrorStatus = CAacDecoder_ExtPayloadParse(
+ self, bs, &bitCnt, previous_element, previous_element_index, 0);
+ if (ErrorStatus != AAC_DEC_OK) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ }
+ }
+ return ErrorStatus;
+}
+
+/* Stream Configuration and Information.
+
+ This class holds configuration and information data for a stream to be
+ decoded. It provides the calling application as well as the decoder with
+ substantial information, e.g. profile, sampling rate, number of channels
+ found in the bitstream etc.
+*/
+static void CStreamInfoInit(CStreamInfo *pStreamInfo) {
+ pStreamInfo->aacSampleRate = 0;
+ pStreamInfo->profile = -1;
+ pStreamInfo->aot = AOT_NONE;
+
+ pStreamInfo->channelConfig = -1;
+ pStreamInfo->bitRate = 0;
+ pStreamInfo->aacSamplesPerFrame = 0;
+
+ pStreamInfo->extAot = AOT_NONE;
+ pStreamInfo->extSamplingRate = 0;
+
+ pStreamInfo->flags = 0;
+
+ pStreamInfo->epConfig = -1; /* default: no ER */
+
+ pStreamInfo->numChannels = 0;
+ pStreamInfo->sampleRate = 0;
+ pStreamInfo->frameSize = 0;
+
+ pStreamInfo->outputDelay = 0;
+
+ /* DRC */
+ pStreamInfo->drcProgRefLev =
+ -1; /* set program reference level to not indicated */
+ pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */
+}
+
+/*!
+ \brief Initialization of AacDecoderChannelInfo
+
+ The function initializes the pointers to AacDecoderChannelInfo for each
+ channel, set the start values for window shape and window sequence of
+ overlap&add to zero, set the overlap buffer to zero and initializes the
+ pointers to the window coefficients. \param bsFormat is the format of the AAC
+ bitstream
+
+ \return AACDECODER instance
+*/
+LINKSPEC_CPP HANDLE_AACDECODER CAacDecoder_Open(
+ TRANSPORT_TYPE bsFormat) /*!< bitstream format (adif,adts,loas,...). */
+{
+ HANDLE_AACDECODER self;
+
+ self = GetAacDecoder();
+ if (self == NULL) {
+ goto bail;
+ }
+
+ FDK_QmfDomain_ClearRequested(&self->qmfDomain.globalConf);
+
+ /* Assign channel mapping info arrays (doing so removes dependency of settings
+ * header in API header). */
+ self->streamInfo.pChannelIndices = self->channelIndices;
+ self->streamInfo.pChannelType = self->channelType;
+ self->downscaleFactor = 1;
+ self->downscaleFactorInBS = 1;
+
+ /* initialize anc data */
+ CAacDecoder_AncDataInit(&self->ancData, NULL, 0);
+
+ /* initialize stream info */
+ CStreamInfoInit(&self->streamInfo);
+
+ /* initialize progam config */
+ CProgramConfig_Init(&self->pce);
+
+ /* initialize error concealment common data */
+ CConcealment_InitCommonData(&self->concealCommonData);
+ self->concealMethodUser = ConcealMethodNone; /* undefined -> auto mode */
+
+ self->hDrcInfo = GetDrcInfo();
+ if (self->hDrcInfo == NULL) {
+ goto bail;
+ }
+ /* Init common DRC structure */
+ aacDecoder_drcInit(self->hDrcInfo);
+ /* Set default frame delay */
+ aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY,
+ CConcealment_GetDelay(&self->concealCommonData));
+
+ self->workBufferCore2 = GetWorkBufferCore2();
+ if (self->workBufferCore2 == NULL) goto bail;
+
+ /* When RSVD60 is active use dedicated memory for core decoding */
+ self->pTimeData2 = GetWorkBufferCore5();
+ self->timeData2Size = GetRequiredMemWorkBufferCore5();
+ if (self->pTimeData2 == NULL) {
+ goto bail;
+ }
+
+ return self;
+
+bail:
+ CAacDecoder_Close(self);
+
+ return NULL;
+}
+
+/* Revert CAacDecoder_Init() */
+static void CAacDecoder_DeInit(HANDLE_AACDECODER self,
+ const int subStreamIndex) {
+ int ch;
+ int aacChannelOffset = 0, aacChannels = (8);
+ int numElements = (((8)) + (8)), elementOffset = 0;
+
+ if (self == NULL) return;
+
+ {
+ self->ascChannels[0] = 0;
+ self->elements[0] = ID_END;
+ }
+
+ for (ch = aacChannelOffset; ch < aacChannelOffset + aacChannels; ch++) {
+ if (self->pAacDecoderChannelInfo[ch] != NULL) {
+ if (self->pAacDecoderChannelInfo[ch]->pComStaticData != NULL) {
+ if (self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1 != NULL) {
+ if (ch == aacChannelOffset) {
+ FreeWorkBufferCore1(&self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1);
+ }
+ }
+ if (self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->cplxPredictionData != NULL) {
+ FreeCplxPredictionData(&self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->cplxPredictionData);
+ }
+ /* Avoid double free of linked pComStaticData in case of CPE by settings
+ * pointer to NULL. */
+ if (ch < (8) - 1) {
+ if ((self->pAacDecoderChannelInfo[ch + 1] != NULL) &&
+ (self->pAacDecoderChannelInfo[ch + 1]->pComStaticData ==
+ self->pAacDecoderChannelInfo[ch]->pComStaticData)) {
+ self->pAacDecoderChannelInfo[ch + 1]->pComStaticData = NULL;
+ }
+ }
+ FDKfree(self->pAacDecoderChannelInfo[ch]->pComStaticData);
+ self->pAacDecoderChannelInfo[ch]->pComStaticData = NULL;
+ }
+ if (self->pAacDecoderChannelInfo[ch]->pComData != NULL) {
+ /* Avoid double free of linked pComData in case of CPE by settings
+ * pointer to NULL. */
+ if (ch < (8) - 1) {
+ if ((self->pAacDecoderChannelInfo[ch + 1] != NULL) &&
+ (self->pAacDecoderChannelInfo[ch + 1]->pComData ==
+ self->pAacDecoderChannelInfo[ch]->pComData)) {
+ self->pAacDecoderChannelInfo[ch + 1]->pComData = NULL;
+ }
+ }
+ if (ch == aacChannelOffset) {
+ FreeWorkBufferCore6(
+ (SCHAR **)&self->pAacDecoderChannelInfo[ch]->pComData);
+ } else {
+ FDKafree(self->pAacDecoderChannelInfo[ch]->pComData);
+ }
+ self->pAacDecoderChannelInfo[ch]->pComData = NULL;
+ }
+ }
+ if (self->pAacDecoderStaticChannelInfo[ch] != NULL) {
+ if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer != NULL) {
+ FreeOverlapBuffer(
+ &self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer);
+ }
+ if (self->pAacDecoderStaticChannelInfo[ch]->hArCo != NULL) {
+ CArco_Destroy(self->pAacDecoderStaticChannelInfo[ch]->hArCo);
+ }
+ FreeAacDecoderStaticChannelInfo(&self->pAacDecoderStaticChannelInfo[ch]);
+ }
+ if (self->pAacDecoderChannelInfo[ch] != NULL) {
+ FreeAacDecoderChannelInfo(&self->pAacDecoderChannelInfo[ch]);
+ }
+ }
+
+ {
+ int el;
+ for (el = elementOffset; el < elementOffset + numElements; el++) {
+ if (self->cpeStaticData[el] != NULL) {
+ FreeCpePersistentData(&self->cpeStaticData[el]);
+ }
+ }
+ }
+
+ FDK_Delay_Destroy(&self->usacResidualDelay);
+
+ self->aacChannels = 0;
+ self->streamInfo.aacSampleRate = 0;
+ self->streamInfo.sampleRate = 0;
+ /* This samplerate value is checked for configuration change, not the others
+ * above. */
+ self->samplingRateInfo[subStreamIndex].samplingRate = 0;
+}
+
+/*!
+ * \brief CAacDecoder_CtrlCFGChange Set config change parameters.
+ *
+ * \param self [i] handle to AACDECODER structure
+ * \param flushStatus [i] flush status: on|off
+ * \param flushCnt [i] flush frame counter
+ * \param buildUpStatus [i] build up status: on|off
+ * \param buildUpCnt [i] build up frame counter
+ *
+ * \return error
+ */
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_CtrlCFGChange(HANDLE_AACDECODER self,
+ UCHAR flushStatus,
+ SCHAR flushCnt,
+ UCHAR buildUpStatus,
+ SCHAR buildUpCnt) {
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+
+ self->flushStatus = flushStatus;
+ self->flushCnt = flushCnt;
+ self->buildUpStatus = buildUpStatus;
+ self->buildUpCnt = buildUpCnt;
+
+ return (err);
+}
+
+/*!
+ * \brief CAacDecoder_FreeMem Free config dependent AAC memory.
+ *
+ * \param self [i] handle to AACDECODER structure
+ *
+ * \return error
+ */
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_FreeMem(HANDLE_AACDECODER self,
+ const int subStreamIndex) {
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+
+ CAacDecoder_DeInit(self, subStreamIndex);
+
+ return (err);
+}
+
+/* Destroy aac decoder */
+LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self) {
+ if (self == NULL) return;
+
+ CAacDecoder_DeInit(self, 0);
+
+ {
+ int ch;
+ for (ch = 0; ch < (8); ch++) {
+ if (self->pTimeDataFlush[ch] != NULL) {
+ FreeTimeDataFlush(&self->pTimeDataFlush[ch]);
+ }
+ }
+ }
+
+ if (self->hDrcInfo) {
+ FreeDrcInfo(&self->hDrcInfo);
+ }
+
+ /* Free WorkBufferCore2 */
+ if (self->workBufferCore2 != NULL) {
+ FreeWorkBufferCore2(&self->workBufferCore2);
+ }
+ if (self->pTimeData2 != NULL) {
+ FreeWorkBufferCore5(&self->pTimeData2);
+ }
+
+ FDK_QmfDomain_Close(&self->qmfDomain);
+
+ FreeAacDecoder(&self);
+}
+
+/*!
+ \brief Initialization of decoder instance
+
+ The function initializes the decoder.
+
+ \return error status: 0 for success, <>0 for unsupported configurations
+*/
+LINKSPEC_CPP AAC_DECODER_ERROR
+CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
+ UCHAR configMode, UCHAR *configChanged) {
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+ INT ascChannels, ascChanged = 0;
+ AACDEC_RENDER_MODE initRenderMode = AACDEC_RENDER_INVALID;
+ SCHAR usacStereoConfigIndex = -1;
+ int usacResidualDelayCompSamples = 0;
+ int elementOffset, aacChannelsOffset, aacChannelsOffsetIdx;
+ const int streamIndex = 0;
+ INT flushChannels = 0;
+
+ if (!self) return AAC_DEC_INVALID_HANDLE;
+
+ UCHAR downscaleFactor = self->downscaleFactor;
+ UCHAR downscaleFactorInBS = self->downscaleFactorInBS;
+
+ // set profile and check for supported aot
+ // leave profile on default (=-1) for all other supported MPEG-4 aot's except
+ // aot=2 (=AAC-LC)
+ switch (asc->m_aot) {
+ case AOT_AAC_LC:
+ self->streamInfo.profile = 1;
+ FDK_FALLTHROUGH;
+ 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;
+ }
+ FDK_FALLTHROUGH;
+ case AOT_SBR:
+ case AOT_PS:
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LD:
+ case AOT_DRM_AAC:
+ case AOT_DRM_SURROUND:
+ initRenderMode = AACDEC_RENDER_IMDCT;
+ break;
+ case AOT_ER_AAC_ELD:
+ initRenderMode = AACDEC_RENDER_ELDFB;
+ break;
+ case AOT_USAC:
+ initRenderMode = AACDEC_RENDER_IMDCT;
+ break;
+ default:
+ return AAC_DEC_UNSUPPORTED_AOT;
+ }
+
+ if (CProgramConfig_IsValid(&self->pce) && (asc->m_channelConfiguration > 0)) {
+ /* Compare the stored (old) PCE with a default PCE created from the (new)
+ channel_config (on a temporal buffer) to find out wheter we can keep it
+ (and its metadata) or not. */
+ int pceCmpResult;
+ C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
+
+ CProgramConfig_GetDefault(tmpPce, asc->m_channelConfiguration);
+ pceCmpResult = CProgramConfig_Compare(&self->pce, tmpPce);
+ if ((pceCmpResult < 0) /* Reset if PCEs are completely different ... */
+ ||
+ (pceCmpResult > 1)) { /* ... or have a different layout. */
+ CProgramConfig_Init(&self->pce);
+ } /* Otherwise keep the PCE (and its metadata). */
+ C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
+ } else {
+ CProgramConfig_Init(&self->pce);
+ }
+
+ /* set channels */
+ switch (asc->m_channelConfiguration) {
+ case 0:
+ switch (asc->m_aot) {
+ case AOT_USAC:
+ self->chMapIndex = 0;
+ ascChannels = asc->m_sc.m_usacConfig.m_nUsacChannels;
+ break;
+ default:
+ /* get channels from program config (ASC) */
+ if (CProgramConfig_IsValid(&asc->m_progrConfigElement)) {
+ ascChannels = asc->m_progrConfigElement.NumChannels;
+ if (ascChannels > 0) {
+ int el_tmp;
+ /* valid number of channels -> copy program config element (PCE)
+ * from ASC */
+ FDKmemcpy(&self->pce, &asc->m_progrConfigElement,
+ sizeof(CProgramConfig));
+ /* Built element table */
+ el_tmp = CProgramConfig_GetElementTable(
+ &asc->m_progrConfigElement, self->elements, (((8)) + (8)),
+ &self->chMapIndex);
+ for (; el_tmp < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1);
+ el_tmp++) {
+ self->elements[el_tmp] = ID_NONE;
+ }
+ } else {
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+ } else {
+ self->chMapIndex = 0;
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+ break;
+ }
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ ascChannels = asc->m_channelConfiguration;
+ break;
+ case 11:
+ ascChannels = 7;
+ break;
+ case 7:
+ case 12:
+ case 14:
+ ascChannels = 8;
+ break;
+ default:
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ if (asc->m_aot == AOT_USAC) {
+ flushChannels = fMin(ascChannels, (8));
+ INT numChannel;
+ pcmDmx_GetParam(self->hPcmUtils, MIN_NUMBER_OF_OUTPUT_CHANNELS,
+ &numChannel);
+ flushChannels = fMin(fMax(numChannel, flushChannels), (8));
+ }
+
+ if (IS_USAC(asc->m_aot)) {
+ for (int el = 0; el < (INT)asc->m_sc.m_usacConfig.m_usacNumElements; el++) {
+ /* fix number of core channels aka ascChannels for stereoConfigIndex = 1
+ * cases */
+ if (asc->m_sc.m_usacConfig.element[el].m_stereoConfigIndex == 1) {
+ ascChannels--; /* stereoConfigIndex == 1 stereo cases do actually
+ contain only a mono core channel. */
+ } else if (asc->m_sc.m_usacConfig.element[el].m_stereoConfigIndex == 2) {
+ /* In this case it is necessary to follow up the DMX signal delay caused
+ by HBE also with the residual signal (2nd core channel). The SBR
+ overlap delay is not regarded here, this is handled by the MPS212
+ implementation.
+ */
+ if (asc->m_sc.m_usacConfig.element[el].m_harmonicSBR) {
+ usacResidualDelayCompSamples += asc->m_samplesPerFrame;
+ }
+ if (asc->m_sc.m_usacConfig.m_coreSbrFrameLengthIndex == 4) {
+ usacResidualDelayCompSamples +=
+ 6 * 16; /* difference between 12 SBR
+ overlap slots from SBR and 6
+ slots delayed in MPS212 */
+ }
+ }
+ }
+ }
+
+ aacChannelsOffset = 0;
+ aacChannelsOffsetIdx = 0;
+ elementOffset = 0;
+ if ((ascChannels <= 0) || (ascChannels > (8)) ||
+ (asc->m_channelConfiguration > AACDEC_MAX_CH_CONF)) {
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ /* Set syntax flags */
+ self->flags[streamIndex] = 0;
+ { FDKmemclear(self->elFlags, sizeof(self->elFlags)); }
+
+ if ((asc->m_channelConfiguration > 0) || IS_USAC(asc->m_aot)) {
+ if (IS_USAC(asc->m_aot)) {
+ /* copy pointer to usac config
+ (this is preliminary since there's an ongoing discussion about storing
+ the config-part of the bitstream rather than the complete decoded
+ configuration) */
+ self->pUsacConfig[streamIndex] = &asc->m_sc.m_usacConfig;
+
+ /* copy list of elements */
+ if (self->pUsacConfig[streamIndex]->m_usacNumElements >
+ (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
+ goto bail;
+ }
+
+ if (self->numUsacElements[streamIndex] !=
+ asc->m_sc.m_usacConfig.m_usacNumElements) {
+ ascChanged = 1;
+ }
+
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->numUsacElements[streamIndex] =
+ asc->m_sc.m_usacConfig.m_usacNumElements;
+ }
+
+ self->mpsEnableCurr = 0;
+ for (int _el = 0;
+ _el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements;
+ _el++) {
+ int el = _el + elementOffset;
+ if (self->elements[el] !=
+ self->pUsacConfig[streamIndex]->element[_el].usacElementType) {
+ ascChanged = 1;
+ }
+ if (self->usacStereoConfigIndex[el] !=
+ asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex) {
+ ascChanged = 1;
+ }
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->elements[el] =
+ self->pUsacConfig[streamIndex]->element[_el].usacElementType;
+ /* for Unified Stereo Coding */
+ self->usacStereoConfigIndex[el] =
+ asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex;
+ if (self->elements[el] == ID_USAC_CPE) {
+ self->mpsEnableCurr |= self->usacStereoConfigIndex[el] ? 1 : 0;
+ }
+ }
+
+ self->elFlags[el] |=
+ (asc->m_sc.m_usacConfig.element[_el].m_noiseFilling)
+ ? AC_EL_USAC_NOISE
+ : 0;
+ self->elFlags[el] |=
+ (asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex > 0)
+ ? AC_EL_USAC_MPS212
+ : 0;
+ self->elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_interTes)
+ ? AC_EL_USAC_ITES
+ : 0;
+ self->elFlags[el] |=
+ (asc->m_sc.m_usacConfig.element[_el].m_pvc) ? AC_EL_USAC_PVC : 0;
+ self->elFlags[el] |=
+ (asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE)
+ ? AC_EL_USAC_LFE
+ : 0;
+ self->elFlags[el] |=
+ (asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE)
+ ? AC_EL_LFE
+ : 0;
+ if ((asc->m_sc.m_usacConfig.element[_el].usacElementType ==
+ ID_USAC_CPE) &&
+ ((self->usacStereoConfigIndex[el] == 0))) {
+ self->elFlags[el] |= AC_EL_USAC_CP_POSSIBLE;
+ }
+ }
+
+ self->hasAudioPreRoll = 0;
+ if (self->pUsacConfig[streamIndex]->m_usacNumElements) {
+ self->hasAudioPreRoll = asc->m_sc.m_usacConfig.element[0]
+ .extElement.usacExtElementHasAudioPreRoll;
+ }
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->elements[elementOffset +
+ self->pUsacConfig[streamIndex]->m_usacNumElements] =
+ ID_END;
+ }
+ } else {
+ /* Initialize constant mappings for channel config 1-7 */
+ int i;
+ for (i = 0; i < AACDEC_CH_ELEMENTS_TAB_SIZE; i++) {
+ self->elements[i] = elementsTab[asc->m_channelConfiguration - 1][i];
+ }
+ for (; i < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1); i++) {
+ self->elements[i] = ID_NONE;
+ }
+ }
+
+ {
+ int ch;
+
+ for (ch = 0; ch < ascChannels; ch++) {
+ self->chMapping[ch] = ch;
+ }
+ for (; ch < (8); ch++) {
+ self->chMapping[ch] = 255;
+ }
+ }
+
+ self->chMapIndex = asc->m_channelConfiguration;
+ } else {
+ if (CProgramConfig_IsValid(&asc->m_progrConfigElement)) {
+ /* Set matrix mixdown infos if available from PCE. */
+ pcmDmx_SetMatrixMixdownFromPce(
+ self->hPcmUtils, asc->m_progrConfigElement.MatrixMixdownIndexPresent,
+ asc->m_progrConfigElement.MatrixMixdownIndex,
+ asc->m_progrConfigElement.PseudoSurroundEnable);
+ }
+ }
+
+ self->streamInfo.channelConfig = asc->m_channelConfiguration;
+
+ if (self->streamInfo.aot != asc->m_aot) {
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->streamInfo.aot = asc->m_aot;
+ }
+ ascChanged = 1;
+ }
+
+ if (asc->m_aot == AOT_ER_AAC_ELD &&
+ asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency != 0) {
+ if (self->samplingRateInfo[0].samplingRate !=
+ asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency ||
+ self->samplingRateInfo[0].samplingRate * self->downscaleFactor !=
+ asc->m_samplingFrequency) {
+ /* get downscaledSamplingFrequency from ESC and compute the downscale
+ * factor */
+ downscaleFactorInBS =
+ asc->m_samplingFrequency /
+ asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency;
+ if (downscaleFactorInBS == 1 || downscaleFactorInBS == 2 ||
+ downscaleFactorInBS == 3 || downscaleFactorInBS == 4) {
+ downscaleFactor = downscaleFactorInBS;
+ }
+ }
+ } else {
+ downscaleFactorInBS = 1;
+ downscaleFactor = 1;
+ }
+
+ if (self->downscaleFactorInBS != downscaleFactorInBS) {
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->downscaleFactorInBS = downscaleFactorInBS;
+ self->downscaleFactor = downscaleFactor;
+ }
+ ascChanged = 1;
+ }
+
+ if ((INT)asc->m_samplesPerFrame % downscaleFactor != 0) {
+ return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* frameSize/dsf must be an integer
+ number */
+ }
+
+ self->streamInfo.bitRate = 0;
+
+ if (asc->m_aot == AOT_ER_AAC_ELD) {
+ if (self->useLdQmfTimeAlign !=
+ asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) {
+ ascChanged = 1;
+ }
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->useLdQmfTimeAlign =
+ asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign;
+ }
+ }
+
+ self->streamInfo.extAot = asc->m_extensionAudioObjectType;
+ if (self->streamInfo.extSamplingRate !=
+ (INT)asc->m_extensionSamplingFrequency) {
+ ascChanged = 1;
+ }
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->streamInfo.extSamplingRate = asc->m_extensionSamplingFrequency;
+ }
+ self->flags[streamIndex] |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0;
+ self->flags[streamIndex] |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0;
+ if (asc->m_sbrPresentFlag) {
+ self->sbrEnabled = 1;
+ self->sbrEnabledPrev = 1;
+ } else {
+ self->sbrEnabled = 0;
+ self->sbrEnabledPrev = 0;
+ }
+ if (self->sbrEnabled && asc->m_extensionSamplingFrequency) {
+ if (downscaleFactor != 1 && (downscaleFactor)&1) {
+ return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* SBR needs an even downscale
+ factor */
+ }
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->streamInfo.extSamplingRate =
+ self->streamInfo.extSamplingRate / self->downscaleFactor;
+ }
+ }
+
+ /* --------- vcb11 ------------ */
+ self->flags[streamIndex] |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0;
+
+ /* ---------- rvlc ------------ */
+ self->flags[streamIndex] |= (asc->m_rvlcFlag) ? AC_ER_RVLC : 0;
+
+ /* ----------- hcr ------------ */
+ self->flags[streamIndex] |= (asc->m_hcrFlag) ? AC_ER_HCR : 0;
+
+ if (asc->m_aot == AOT_ER_AAC_ELD) {
+ self->mpsEnableCurr = 0;
+ self->flags[streamIndex] |= AC_ELD;
+ self->flags[streamIndex] |=
+ (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[streamIndex] |=
+ (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0;
+ self->flags[streamIndex] |=
+ (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_MPS_PRESENT
+ : 0;
+ if (self->mpsApplicable) {
+ self->mpsEnableCurr = asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign;
+ }
+ }
+ self->flags[streamIndex] |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0;
+ self->flags[streamIndex] |= (asc->m_epConfig >= 0) ? AC_ER : 0;
+
+ if (asc->m_aot == AOT_USAC) {
+ self->flags[streamIndex] |= AC_USAC;
+ self->flags[streamIndex] |=
+ (asc->m_sc.m_usacConfig.element[0].m_stereoConfigIndex > 0)
+ ? AC_MPS_PRESENT
+ : 0;
+ }
+ if (asc->m_aot == AOT_DRM_AAC) {
+ self->flags[streamIndex] |= AC_DRM | AC_SBRCRC | AC_SCALABLE;
+ }
+ if (asc->m_aot == AOT_DRM_SURROUND) {
+ self->flags[streamIndex] |=
+ AC_DRM | AC_SBRCRC | AC_SCALABLE | AC_MPS_PRESENT;
+ FDK_ASSERT(!asc->m_psPresentFlag);
+ }
+ if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) {
+ self->flags[streamIndex] |= AC_SCALABLE;
+ }
+
+ if ((asc->m_epConfig >= 0) && (asc->m_channelConfiguration <= 0)) {
+ /* we have to know the number of channels otherwise no decoding is possible
+ */
+ return AAC_DEC_UNSUPPORTED_ER_FORMAT;
+ }
+
+ self->streamInfo.epConfig = asc->m_epConfig;
+ /* self->hInput->asc.m_epConfig = asc->m_epConfig; */
+
+ if (asc->m_epConfig > 1) return AAC_DEC_UNSUPPORTED_ER_FORMAT;
+
+ /* Check if samplerate changed. */
+ if ((self->samplingRateInfo[streamIndex].samplingRate !=
+ asc->m_samplingFrequency) ||
+ (self->streamInfo.aacSamplesPerFrame !=
+ (INT)asc->m_samplesPerFrame / downscaleFactor)) {
+ AAC_DECODER_ERROR error;
+
+ ascChanged = 1;
+
+ if (configMode & AC_CM_ALLOC_MEM) {
+ /* Update samplerate info. */
+ error = getSamplingRateInfo(
+ &self->samplingRateInfo[streamIndex], asc->m_samplesPerFrame,
+ asc->m_samplingFrequencyIndex, asc->m_samplingFrequency);
+ if (error != AAC_DEC_OK) {
+ return error;
+ }
+ self->streamInfo.aacSampleRate =
+ self->samplingRateInfo[0].samplingRate / self->downscaleFactor;
+ self->streamInfo.aacSamplesPerFrame =
+ asc->m_samplesPerFrame / self->downscaleFactor;
+ }
+ }
+
+ /* Check if amount of channels has changed. */
+ if (self->ascChannels[streamIndex] != ascChannels) {
+ ascChanged = 1;
+ }
+
+ /* detect config change */
+ if (configMode & AC_CM_DET_CFG_CHANGE) {
+ if (ascChanged != 0) {
+ *configChanged = 1;
+ }
+ return err;
+ }
+
+ /* set AC_USAC_SCFGI3 globally if any usac element uses */
+ switch (asc->m_aot) {
+ case AOT_USAC:
+ if (self->sbrEnabled) {
+ for (int _el = 0;
+ _el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements;
+ _el++) {
+ int el = elementOffset + _el;
+ if (IS_USAC_CHANNEL_ELEMENT(self->elements[el])) {
+ if (usacStereoConfigIndex < 0) {
+ usacStereoConfigIndex = self->usacStereoConfigIndex[el];
+ } else {
+ if ((usacStereoConfigIndex != self->usacStereoConfigIndex[el]) ||
+ (self->usacStereoConfigIndex[el] > 0)) {
+ goto bail;
+ }
+ }
+ }
+ }
+
+ if (usacStereoConfigIndex < 0) {
+ goto bail;
+ }
+
+ if (usacStereoConfigIndex == 3) {
+ self->flags[streamIndex] |= AC_USAC_SCFGI3;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (*configChanged) {
+ /* Set up QMF domain for AOTs with explicit signalling of SBR and or MPS.
+ This is to be able to play out the first frame alway with the correct
+ frame size and sampling rate even in case of concealment.
+ */
+ switch (asc->m_aot) {
+ case AOT_USAC:
+ if (self->sbrEnabled) {
+ const UCHAR map_sbrRatio_2_nAnaBands[] = {16, 24, 32};
+
+ FDK_ASSERT(asc->m_sc.m_usacConfig.m_sbrRatioIndex > 0);
+ FDK_ASSERT(streamIndex == 0);
+
+ self->qmfDomain.globalConf.nInputChannels_requested = ascChannels;
+ self->qmfDomain.globalConf.nOutputChannels_requested =
+ (usacStereoConfigIndex == 1) ? 2 : ascChannels;
+ self->qmfDomain.globalConf.flags_requested = 0;
+ self->qmfDomain.globalConf.nBandsAnalysis_requested =
+ map_sbrRatio_2_nAnaBands[asc->m_sc.m_usacConfig.m_sbrRatioIndex -
+ 1];
+ self->qmfDomain.globalConf.nBandsSynthesis_requested = 64;
+ self->qmfDomain.globalConf.nQmfTimeSlots_requested =
+ (asc->m_sc.m_usacConfig.m_sbrRatioIndex == 1) ? 64 : 32;
+ self->qmfDomain.globalConf.nQmfOvTimeSlots_requested =
+ (asc->m_sc.m_usacConfig.m_sbrRatioIndex == 1) ? 12 : 6;
+ self->qmfDomain.globalConf.nQmfProcBands_requested = 64;
+ self->qmfDomain.globalConf.nQmfProcChannels_requested = 1;
+ self->qmfDomain.globalConf.parkChannel =
+ (usacStereoConfigIndex == 3) ? 1 : 0;
+ self->qmfDomain.globalConf.parkChannel_requested =
+ (usacStereoConfigIndex == 3) ? 1 : 0;
+ self->qmfDomain.globalConf.qmfDomainExplicitConfig = 1;
+ }
+ break;
+ case AOT_ER_AAC_ELD:
+ if (self->mpsEnableCurr &&
+ asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) {
+ SAC_INPUT_CONFIG sac_interface =
+ (self->sbrEnabled && self->hSbrDecoder) ? SAC_INTERFACE_QMF
+ : SAC_INTERFACE_TIME;
+ mpegSurroundDecoder_ConfigureQmfDomain(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface,
+ (UINT)self->streamInfo.aacSampleRate, asc->m_aot);
+ self->qmfDomain.globalConf.qmfDomainExplicitConfig = 1;
+ }
+ break;
+ default:
+ self->qmfDomain.globalConf.qmfDomainExplicitConfig =
+ 0; /* qmfDomain is initialized by SBR and MPS init functions if
+ required */
+ break;
+ }
+
+ /* Allocate all memory structures for each channel */
+ {
+ int ch = aacChannelsOffset;
+ for (int _ch = 0; _ch < ascChannels; _ch++) {
+ if (ch >= (8)) {
+ goto bail;
+ }
+ self->pAacDecoderChannelInfo[ch] = GetAacDecoderChannelInfo(ch);
+ /* This is temporary until the DynamicData is split into two or more
+ regions! The memory could be reused after completed core decoding. */
+ if (self->pAacDecoderChannelInfo[ch] == NULL) {
+ goto bail;
+ }
+ ch++;
+ }
+
+ int chIdx = aacChannelsOffsetIdx;
+ ch = aacChannelsOffset;
+ int _numElements;
+ _numElements = (((8)) + (8));
+ if (self->flags[streamIndex] & (AC_RSV603DA | AC_USAC)) {
+ _numElements = (int)asc->m_sc.m_usacConfig.m_usacNumElements;
+ }
+ for (int _el = 0; _el < _numElements; _el++) {
+ int el_channels = 0;
+ int el = elementOffset + _el;
+
+ if (self->flags[streamIndex] &
+ (AC_ER | AC_LD | AC_ELD | AC_RSV603DA | AC_USAC | AC_RSVD50)) {
+ if (ch >= ascChannels) {
+ break;
+ }
+ }
+
+ switch (self->elements[el]) {
+ case ID_SCE:
+ case ID_CPE:
+ case ID_LFE:
+ case ID_USAC_SCE:
+ case ID_USAC_CPE:
+ case ID_USAC_LFE:
+
+ el_channels = CAacDecoder_GetELChannels(
+ self->elements[el], self->usacStereoConfigIndex[el]);
+
+ {
+ self->pAacDecoderChannelInfo[ch]->pComStaticData =
+ (CAacDecoderCommonStaticData *)FDKcalloc(
+ 1, sizeof(CAacDecoderCommonStaticData));
+ if (self->pAacDecoderChannelInfo[ch]->pComStaticData == NULL) {
+ goto bail;
+ }
+ if (ch == aacChannelsOffset) {
+ self->pAacDecoderChannelInfo[ch]->pComData =
+ (CAacDecoderCommonData *)GetWorkBufferCore6();
+ self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1 = GetWorkBufferCore1();
+ } else {
+ self->pAacDecoderChannelInfo[ch]->pComData =
+ (CAacDecoderCommonData *)FDKaalloc(
+ sizeof(CAacDecoderCommonData), ALIGNMENT_DEFAULT);
+ self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1 =
+ self->pAacDecoderChannelInfo[aacChannelsOffset]
+ ->pComStaticData->pWorkBufferCore1;
+ }
+ if ((self->pAacDecoderChannelInfo[ch]->pComData == NULL) ||
+ (self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1 == NULL)) {
+ goto bail;
+ }
+ self->pAacDecoderChannelInfo[ch]->pDynData =
+ &(self->pAacDecoderChannelInfo[ch]
+ ->pComData->pAacDecoderDynamicData[0]);
+ self->pAacDecoderChannelInfo[ch]->pSpectralCoefficient =
+ (SPECTRAL_PTR)&self->workBufferCore2[ch * 1024];
+
+ if (el_channels == 2) {
+ if (ch >= (8) - 1) {
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+ self->pAacDecoderChannelInfo[ch + 1]->pComData =
+ self->pAacDecoderChannelInfo[ch]->pComData;
+ self->pAacDecoderChannelInfo[ch + 1]->pComStaticData =
+ self->pAacDecoderChannelInfo[ch]->pComStaticData;
+ self->pAacDecoderChannelInfo[ch + 1]
+ ->pComStaticData->pWorkBufferCore1 =
+ self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1;
+ self->pAacDecoderChannelInfo[ch + 1]->pDynData =
+ &(self->pAacDecoderChannelInfo[ch]
+ ->pComData->pAacDecoderDynamicData[1]);
+ self->pAacDecoderChannelInfo[ch + 1]->pSpectralCoefficient =
+ (SPECTRAL_PTR)&self->workBufferCore2[(ch + 1) * 1024];
+ }
+
+ ch += el_channels;
+ }
+ chIdx += el_channels;
+ break;
+
+ default:
+ break;
+ }
+
+ if (self->elements[el] == ID_END) {
+ break;
+ }
+
+ el++;
+ }
+
+ chIdx = aacChannelsOffsetIdx;
+ ch = aacChannelsOffset;
+ for (int _ch = 0; _ch < ascChannels; _ch++) {
+ /* Allocate persistent channel memory */
+ {
+ self->pAacDecoderStaticChannelInfo[ch] =
+ GetAacDecoderStaticChannelInfo(ch);
+ if (self->pAacDecoderStaticChannelInfo[ch] == NULL) {
+ goto bail;
+ }
+ self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer =
+ GetOverlapBuffer(ch); /* This area size depends on the AOT */
+ if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer == NULL) {
+ goto bail;
+ }
+ if (self->flags[streamIndex] &
+ (AC_USAC | AC_RSVD50 | AC_RSV603DA /*|AC_BSAC*/)) {
+ self->pAacDecoderStaticChannelInfo[ch]->hArCo = CArco_Create();
+ if (self->pAacDecoderStaticChannelInfo[ch]->hArCo == NULL) {
+ goto bail;
+ }
+ }
+
+ if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) {
+ CPns_UpdateNoiseState(
+ &self->pAacDecoderChannelInfo[ch]->data.aac.PnsData,
+ &self->pAacDecoderStaticChannelInfo[ch]->pnsCurrentSeed,
+ self->pAacDecoderChannelInfo[ch]->pComData->pnsRandomSeed);
+ }
+ ch++;
+ }
+ chIdx++;
+ }
+
+ if (self->flags[streamIndex] & AC_USAC) {
+ for (int _ch = 0; _ch < flushChannels; _ch++) {
+ ch = aacChannelsOffset + _ch;
+ if (self->pTimeDataFlush[ch] == NULL) {
+ self->pTimeDataFlush[ch] = GetTimeDataFlush(ch);
+ if (self->pTimeDataFlush[ch] == NULL) {
+ goto bail;
+ }
+ }
+ }
+ }
+
+ if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA)) {
+ int complexStereoPredPossible = 0;
+ ch = aacChannelsOffset;
+ chIdx = aacChannelsOffsetIdx;
+ for (int _el2 = 0; _el2 < (int)asc->m_sc.m_usacConfig.m_usacNumElements;
+ _el2++) {
+ int el2 = elementOffset + _el2;
+ int elCh = 0, ch2;
+
+ if ((self->elements[el2] == ID_USAC_CPE) &&
+ !(self->usacStereoConfigIndex[el2] == 1)) {
+ elCh = 2;
+ } else if (IS_CHANNEL_ELEMENT(self->elements[el2])) {
+ elCh = 1;
+ }
+
+ if (self->elFlags[el2] & AC_EL_USAC_CP_POSSIBLE) {
+ complexStereoPredPossible = 1;
+ if (self->cpeStaticData[el2] == NULL) {
+ self->cpeStaticData[el2] = GetCpePersistentData();
+ if (self->cpeStaticData[el2] == NULL) {
+ goto bail;
+ }
+ }
+ }
+
+ for (ch2 = 0; ch2 < elCh; ch2++) {
+ /* Hook element specific cpeStaticData into channel specific
+ * aacDecoderStaticChannelInfo */
+ self->pAacDecoderStaticChannelInfo[ch]->pCpeStaticData =
+ self->cpeStaticData[el2];
+ if (self->pAacDecoderStaticChannelInfo[ch]->pCpeStaticData !=
+ NULL) {
+ self->pAacDecoderStaticChannelInfo[ch]
+ ->pCpeStaticData->jointStereoPersistentData
+ .spectralCoeffs[ch2] =
+ self->pAacDecoderStaticChannelInfo[ch]
+ ->concealmentInfo.spectralCoefficient;
+ self->pAacDecoderStaticChannelInfo[ch]
+ ->pCpeStaticData->jointStereoPersistentData.specScale[ch2] =
+ self->pAacDecoderStaticChannelInfo[ch]
+ ->concealmentInfo.specScale;
+ self->pAacDecoderStaticChannelInfo[ch]
+ ->pCpeStaticData->jointStereoPersistentData.scratchBuffer =
+ (FIXP_DBL *)self->pTimeData2;
+ }
+ chIdx++;
+ ch++;
+ } /* for each channel in current element */
+ if (complexStereoPredPossible && (elCh == 2)) {
+ /* needed once for all channels */
+ if (self->pAacDecoderChannelInfo[ch - 1]
+ ->pComStaticData->cplxPredictionData == NULL) {
+ self->pAacDecoderChannelInfo[ch - 1]
+ ->pComStaticData->cplxPredictionData =
+ GetCplxPredictionData();
+ }
+ if (self->pAacDecoderChannelInfo[ch - 1]
+ ->pComStaticData->cplxPredictionData == NULL) {
+ goto bail;
+ }
+ }
+ if (elCh > 0) {
+ self->pAacDecoderStaticChannelInfo[ch - elCh]->nfRandomSeed =
+ (ULONG)0x3039;
+ if (self->elements[el2] == ID_USAC_CPE) {
+ if (asc->m_sc.m_usacConfig.element[el2].m_stereoConfigIndex !=
+ 1) {
+ self->pAacDecoderStaticChannelInfo[ch - elCh + 1]
+ ->nfRandomSeed = (ULONG)0x10932;
+ }
+ }
+ }
+ } /* for each element */
+ }
+
+ if (ascChannels != self->aacChannels) {
+ /* Make allocated channel count persistent in decoder context. */
+ self->aacChannels = aacChannelsOffset + ch;
+ }
+ }
+
+ if (usacResidualDelayCompSamples) {
+ INT delayErr = FDK_Delay_Create(&self->usacResidualDelay,
+ (USHORT)usacResidualDelayCompSamples, 1);
+ if (delayErr) {
+ goto bail;
+ }
+ }
+
+ /* Make amount of signalled channels persistent in decoder context. */
+ self->ascChannels[streamIndex] = ascChannels;
+ /* Init the previous channel count values. This is required to avoid a
+ mismatch of memory accesses in the error concealment module and the
+ allocated channel structures in this function. */
+ self->aacChannelsPrev = 0;
+ }
+
+ if (self->pAacDecoderChannelInfo[0] != NULL) {
+ self->pDrmBsBuffer = self->pAacDecoderChannelInfo[0]
+ ->pComStaticData->pWorkBufferCore1->DrmBsBuffer;
+ self->drmBsBufferSize = DRM_BS_BUFFER_SIZE;
+ }
+
+ /* Update structures */
+ if (*configChanged) {
+ /* Things to be done for each channel, which do not involve allocating
+ memory. Doing these things only on the channels needed for the current
+ configuration (ascChannels) could lead to memory access violation later
+ (error concealment). */
+ int ch = 0;
+ int chIdx = 0;
+ for (int _ch = 0; _ch < self->ascChannels[streamIndex]; _ch++) {
+ switch (self->streamInfo.aot) {
+ case AOT_ER_AAC_ELD:
+ case AOT_ER_AAC_LD:
+ self->pAacDecoderChannelInfo[ch]->granuleLength =
+ self->streamInfo.aacSamplesPerFrame;
+ break;
+ default:
+ self->pAacDecoderChannelInfo[ch]->granuleLength =
+ self->streamInfo.aacSamplesPerFrame / 8;
+ break;
+ }
+ self->pAacDecoderChannelInfo[ch]->renderMode = initRenderMode;
+
+ mdct_init(&self->pAacDecoderStaticChannelInfo[ch]->IMdct,
+ self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer,
+ OverlapBufferSize);
+
+ self->pAacDecoderStaticChannelInfo[ch]->last_core_mode = FD_LONG;
+ self->pAacDecoderStaticChannelInfo[ch]->last_lpd_mode = 255;
+
+ self->pAacDecoderStaticChannelInfo[ch]->last_tcx_pitch = L_DIV;
+
+ /* Reset DRC control data for this channel */
+ aacDecoder_drcInitChannelData(
+ &self->pAacDecoderStaticChannelInfo[ch]->drcData);
+
+ /* Delete mixdown metadata from the past */
+ pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
+
+ /* Reset concealment only if ASC changed. Otherwise it will be done with
+ any config callback. E.g. every time the LATM SMC is present. */
+ CConcealment_InitChannelData(
+ &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
+ &self->concealCommonData, initRenderMode,
+ self->streamInfo.aacSamplesPerFrame);
+ ch++;
+ chIdx++;
+ }
+ }
+
+ /* Update externally visible copy of flags */
+ self->streamInfo.flags = self->flags[0];
+
+ if (*configChanged) {
+ int drcDecSampleRate, drcDecFrameSize;
+
+ if (self->streamInfo.extSamplingRate != 0) {
+ drcDecSampleRate = self->streamInfo.extSamplingRate;
+ drcDecFrameSize = (self->streamInfo.aacSamplesPerFrame *
+ self->streamInfo.extSamplingRate) /
+ self->streamInfo.aacSampleRate;
+ } else {
+ drcDecSampleRate = self->streamInfo.aacSampleRate;
+ drcDecFrameSize = self->streamInfo.aacSamplesPerFrame;
+ }
+
+ if (FDK_drcDec_Init(self->hUniDrcDecoder, drcDecFrameSize, drcDecSampleRate,
+ self->aacChannels) != 0)
+ goto bail;
+ }
+
+ if (asc->m_aot == AOT_USAC) {
+ pcmLimiter_SetAttack(self->hLimiter, (5));
+ pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f));
+ }
+
+ return err;
+
+bail:
+ CAacDecoder_DeInit(self, 0);
+ return AAC_DEC_OUT_OF_MEMORY;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
+ HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData,
+ const INT timeDataSize, const int timeDataChannelOffset) {
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ CProgramConfig *pce;
+ HANDLE_FDK_BITSTREAM bs = transportDec_GetBitstream(self->hInput, 0);
+
+ MP4_ELEMENT_ID type = ID_NONE; /* Current element type */
+ INT aacChannels = 0; /* Channel counter for channels found in the bitstream */
+ const int streamIndex = 0; /* index of the current substream */
+
+ INT auStartAnchor = (INT)FDKgetValidBits(
+ bs); /* AU start bit buffer position for AU byte alignment */
+
+ INT checkSampleRate = self->streamInfo.aacSampleRate;
+
+ INT CConceal_TDFading_Applied[(8)] = {
+ 0}; /* Initialize status of Time Domain fading */
+
+ if (self->aacChannels <= 0) {
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ /* Any supported base layer valid AU will require more than 16 bits. */
+ if ((transportDec_GetAuBitsRemaining(self->hInput, 0) < 15) &&
+ (flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) == 0) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ /* Reset Program Config structure */
+ pce = &self->pce;
+ CProgramConfig_Reset(pce);
+
+ CAacDecoder_AncDataReset(&self->ancData);
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) &&
+ !(self->flags[0] & (AC_USAC | AC_RSV603DA))) {
+ int ch;
+ if (self->streamInfo.channelConfig == 0) {
+ /* Init Channel/Element mapping table */
+ for (ch = 0; ch < (8); ch++) {
+ self->chMapping[ch] = 255;
+ }
+ if (!CProgramConfig_IsValid(pce)) {
+ int el;
+ for (el = 0; el < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1);
+ el++) {
+ self->elements[el] = ID_NONE;
+ }
+ }
+ }
+ }
+
+ if (self->downscaleFactor > 1 && (self->flags[0] & AC_ELD)) {
+ self->flags[0] |= AC_ELD_DOWNSCALE;
+ } else {
+ self->flags[0] &= ~AC_ELD_DOWNSCALE;
+ }
+ /* unsupported dsf (aacSampleRate has not yet been divided by dsf) -> divide
+ */
+ if (self->downscaleFactorInBS > 1 &&
+ (self->flags[0] & AC_ELD_DOWNSCALE) == 0) {
+ checkSampleRate =
+ self->streamInfo.aacSampleRate / self->downscaleFactorInBS;
+ }
+
+ /* Check sampling frequency */
+ if (self->streamInfo.aacSampleRate <= 0) {
+ /* Instance maybe uninitialized! */
+ return AAC_DEC_UNSUPPORTED_SAMPLINGRATE;
+ }
+ switch (checkSampleRate) {
+ case 96000:
+ case 88200:
+ case 64000:
+ case 16000:
+ case 12000:
+ case 11025:
+ case 8000:
+ case 7350:
+ case 48000:
+ case 44100:
+ case 32000:
+ case 24000:
+ case 22050:
+ break;
+ default:
+ if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ return AAC_DEC_UNSUPPORTED_SAMPLINGRATE;
+ }
+ break;
+ }
+
+ if (flags & AACDEC_CLRHIST) {
+ if (!(self->flags[0] & AC_USAC)) {
+ int ch;
+ /* Clear history */
+ for (ch = 0; ch < self->aacChannels; ch++) {
+ /* Reset concealment */
+ CConcealment_InitChannelData(
+ &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
+ &self->concealCommonData,
+ self->pAacDecoderChannelInfo[0]->renderMode,
+ self->streamInfo.aacSamplesPerFrame);
+ /* Clear overlap-add buffers to avoid clicks. */
+ FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer,
+ OverlapBufferSize * sizeof(FIXP_DBL));
+ }
+ if (self->streamInfo.channelConfig > 0) {
+ /* Declare the possibly adopted old PCE (with outdated metadata)
+ * invalid. */
+ CProgramConfig_Init(pce);
+ }
+ }
+ }
+
+ int pceRead = 0; /* Flag indicating a PCE in the current raw_data_block() */
+
+ INT hdaacDecoded = 0;
+ MP4_ELEMENT_ID previous_element =
+ ID_END; /* Last element ID (required for extension payload mapping */
+ UCHAR previous_element_index = 0; /* Canonical index of last element */
+ int element_count =
+ 0; /* Element counter for elements found in the bitstream */
+ int channel_element_count = 0; /* Channel element counter */
+ MP4_ELEMENT_ID
+ channel_elements[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) +
+ 1)]; /* Channel elements in bit stream order. */
+ int el_cnt[ID_LAST] = {0}; /* element counter ( robustness ) */
+ int element_count_prev_streams =
+ 0; /* Element count of all previous sub streams. */
+
+ while ((type != ID_END) && (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) &&
+ self->frameOK) {
+ int el_channels;
+
+ if (!(self->flags[0] &
+ (AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_ELD | AC_SCALABLE | AC_ER)))
+ type = (MP4_ELEMENT_ID)FDKreadBits(bs, 3);
+ else {
+ if (element_count >= (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ type = self->elements[element_count];
+ }
+
+ if ((self->flags[streamIndex] & (AC_USAC | AC_RSVD50) &&
+ element_count == 0) ||
+ (self->flags[streamIndex] & AC_RSV603DA)) {
+ self->flags[streamIndex] &= ~AC_INDEP;
+
+ if (FDKreadBit(bs)) {
+ self->flags[streamIndex] |= AC_INDEP;
+ }
+
+ int ch = aacChannels;
+ for (int chIdx = aacChannels; chIdx < self->ascChannels[streamIndex];
+ chIdx++) {
+ {
+ /* Robustness check */
+ if (ch >= self->aacChannels) {
+ return AAC_DEC_UNKNOWN;
+ }
+
+ /* if last frame was broken and this frame is no independent frame,
+ * correct decoding is impossible we need to trigger concealment */
+ if ((CConcealment_GetLastFrameOk(
+ &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
+ 1) == 0) &&
+ !(self->flags[streamIndex] & AC_INDEP)) {
+ self->frameOK = 0;
+ }
+ ch++;
+ }
+ }
+ }
+
+ if ((INT)FDKgetValidBits(bs) < 0) {
+ self->frameOK = 0;
+ }
+
+ switch (type) {
+ case ID_SCE:
+ case ID_CPE:
+ case ID_LFE:
+ case ID_USAC_SCE:
+ case ID_USAC_CPE:
+ case ID_USAC_LFE:
+ if (element_count >= (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+
+ el_channels = CAacDecoder_GetELChannels(
+ type, self->usacStereoConfigIndex[element_count]);
+
+ /*
+ Consistency check
+ */
+ {
+ int totalAscChannels = 0;
+
+ for (int i = 0; i < (1 * 1); i++) {
+ totalAscChannels += self->ascChannels[i];
+ }
+ if ((el_cnt[type] >= (totalAscChannels >> (el_channels - 1))) ||
+ (aacChannels > (totalAscChannels - el_channels))) {
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ self->frameOK = 0;
+ break;
+ }
+ }
+
+ if (!(self->flags[streamIndex] & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ int ch;
+ for (ch = 0; ch < el_channels; ch += 1) {
+ CPns_ResetData(&self->pAacDecoderChannelInfo[aacChannels + ch]
+ ->data.aac.PnsData,
+ &self->pAacDecoderChannelInfo[aacChannels + ch]
+ ->pComData->pnsInterChannelData);
+ }
+ }
+
+ if (self->frameOK) {
+ ErrorStatus = CChannelElement_Read(
+ bs, &self->pAacDecoderChannelInfo[aacChannels],
+ &self->pAacDecoderStaticChannelInfo[aacChannels],
+ self->streamInfo.aot, &self->samplingRateInfo[streamIndex],
+ self->flags[streamIndex], self->elFlags[element_count],
+ self->streamInfo.aacSamplesPerFrame, el_channels,
+ self->streamInfo.epConfig, self->hInput);
+ if (ErrorStatus != AAC_DEC_OK) {
+ self->frameOK = 0;
+ }
+ }
+
+ if (self->frameOK) {
+ /* Lookup the element and decode it only if it belongs to the current
+ * program */
+ if (CProgramConfig_LookupElement(
+ pce, self->streamInfo.channelConfig,
+ self->pAacDecoderChannelInfo[aacChannels]->ElementInstanceTag,
+ aacChannels, self->chMapping, self->channelType,
+ self->channelIndices, (8), &previous_element_index,
+ self->elements, type)) {
+ channel_elements[channel_element_count++] = type;
+ aacChannels += el_channels;
+ } else {
+ self->frameOK = 0;
+ }
+ /* Create SBR element for SBR for upsampling for LFE elements,
+ and if SBR was implicitly signaled, because the first frame(s)
+ may not contain SBR payload (broken encoder, bit errors). */
+ if (self->frameOK &&
+ ((self->flags[streamIndex] & AC_SBR_PRESENT) ||
+ (self->sbrEnabled == 1)) &&
+ !(self->flags[streamIndex] &
+ AC_USAC) /* Is done during explicit config set up */
+ ) {
+ SBR_ERROR sbrError;
+ UCHAR configMode = 0;
+ UCHAR configChanged = 0;
+ configMode |= AC_CM_ALLOC_MEM;
+
+ sbrError = sbrDecoder_InitElement(
+ self->hSbrDecoder, self->streamInfo.aacSampleRate,
+ self->streamInfo.extSamplingRate,
+ self->streamInfo.aacSamplesPerFrame, self->streamInfo.aot, type,
+ previous_element_index, 2, /* Signalize that harmonicSBR shall
+ be ignored in the config change
+ detection */
+ 0, configMode, &configChanged, self->downscaleFactor);
+ if (sbrError != SBRDEC_OK) {
+ /* Do not try to apply SBR because initializing the element
+ * failed. */
+ self->sbrEnabled = 0;
+ }
+ }
+ }
+
+ el_cnt[type]++;
+ if (self->frameOK && (self->flags[streamIndex] & AC_USAC) &&
+ (type == ID_USAC_CPE || type == ID_USAC_SCE)) {
+ ErrorStatus = aacDecoder_ParseExplicitMpsAndSbr(
+ self, bs, previous_element, previous_element_index, element_count,
+ el_cnt);
+ if (ErrorStatus != AAC_DEC_OK) {
+ self->frameOK = 0;
+ }
+ }
+ break;
+
+ case ID_CCE:
+ /*
+ Consistency check
+ */
+ if (el_cnt[type] > self->ascChannels[streamIndex]) {
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ self->frameOK = 0;
+ break;
+ }
+
+ if (self->frameOK) {
+ CAacDecoderCommonData commonData;
+ CAacDecoderCommonStaticData commonStaticData;
+ CWorkBufferCore1 workBufferCore1;
+ commonStaticData.pWorkBufferCore1 = &workBufferCore1;
+ /* memory for spectral lines temporal on scratch */
+ C_AALLOC_SCRATCH_START(mdctSpec, FIXP_DBL, 1024);
+
+ /* create dummy channel for CCE parsing on stack */
+ CAacDecoderChannelInfo tmpAacDecoderChannelInfo,
+ *pTmpAacDecoderChannelInfo;
+
+ FDKmemclear(mdctSpec, 1024 * sizeof(FIXP_DBL));
+
+ tmpAacDecoderChannelInfo.pDynData = commonData.pAacDecoderDynamicData;
+ tmpAacDecoderChannelInfo.pComData = &commonData;
+ tmpAacDecoderChannelInfo.pComStaticData = &commonStaticData;
+ tmpAacDecoderChannelInfo.pSpectralCoefficient =
+ (SPECTRAL_PTR)mdctSpec;
+ /* Assume AAC-LC */
+ tmpAacDecoderChannelInfo.granuleLength =
+ self->streamInfo.aacSamplesPerFrame / 8;
+ /* Reset PNS data. */
+ CPns_ResetData(
+ &tmpAacDecoderChannelInfo.data.aac.PnsData,
+ &tmpAacDecoderChannelInfo.pComData->pnsInterChannelData);
+ pTmpAacDecoderChannelInfo = &tmpAacDecoderChannelInfo;
+ /* do CCE parsing */
+ ErrorStatus = CChannelElement_Read(
+ bs, &pTmpAacDecoderChannelInfo, NULL, self->streamInfo.aot,
+ &self->samplingRateInfo[streamIndex], self->flags[streamIndex],
+ AC_EL_GA_CCE, self->streamInfo.aacSamplesPerFrame, 1,
+ self->streamInfo.epConfig, self->hInput);
+
+ C_AALLOC_SCRATCH_END(mdctSpec, FIXP_DBL, 1024);
+
+ if (ErrorStatus) {
+ self->frameOK = 0;
+ }
+
+ if (self->frameOK) {
+ /* Lookup the element and decode it only if it belongs to the
+ * current program */
+ if (CProgramConfig_LookupElement(
+ pce, self->streamInfo.channelConfig,
+ pTmpAacDecoderChannelInfo->ElementInstanceTag, 0,
+ self->chMapping, self->channelType, self->channelIndices,
+ (8), &previous_element_index, self->elements, type)) {
+ /* decoding of CCE not supported */
+ } else {
+ self->frameOK = 0;
+ }
+ }
+ }
+ el_cnt[type]++;
+ break;
+
+ case ID_DSE: {
+ UCHAR element_instance_tag;
+
+ CDataStreamElement_Read(self, bs, &element_instance_tag, auStartAnchor);
+
+ if (!CProgramConfig_LookupElement(
+ pce, self->streamInfo.channelConfig, element_instance_tag, 0,
+ self->chMapping, self->channelType, self->channelIndices, (8),
+ &previous_element_index, self->elements, type)) {
+ /* most likely an error in bitstream occured */
+ // self->frameOK = 0;
+ }
+ } break;
+
+ case ID_PCE: {
+ int result = CProgramConfigElement_Read(bs, self->hInput, pce,
+ self->streamInfo.channelConfig,
+ auStartAnchor);
+ if (result < 0) {
+ /* Something went wrong */
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ self->frameOK = 0;
+ } else if (result > 1) {
+ /* Built element table */
+ int elIdx = CProgramConfig_GetElementTable(
+ pce, self->elements, (((8)) + (8)), &self->chMapIndex);
+ /* Reset the remaining tabs */
+ for (; elIdx < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1);
+ elIdx++) {
+ self->elements[elIdx] = ID_NONE;
+ }
+ /* Make new number of channel persistent */
+ self->ascChannels[streamIndex] = pce->NumChannels;
+ /* If PCE is not first element conceal this frame to avoid
+ * inconsistencies */
+ if (element_count != 0) {
+ self->frameOK = 0;
+ }
+ }
+ pceRead = (result >= 0) ? 1 : 0;
+ } break;
+
+ case ID_FIL: {
+ int bitCnt = FDKreadBits(bs, 4); /* bs_count */
+
+ if (bitCnt == 15) {
+ int esc_count = FDKreadBits(bs, 8); /* bs_esc_count */
+ bitCnt = esc_count + 14;
+ }
+
+ /* Convert to bits */
+ bitCnt <<= 3;
+
+ while (bitCnt > 0) {
+ ErrorStatus = CAacDecoder_ExtPayloadParse(
+ self, bs, &bitCnt, previous_element, previous_element_index, 1);
+ if (ErrorStatus != AAC_DEC_OK) {
+ self->frameOK = 0;
+ break;
+ }
+ }
+ } break;
+
+ case ID_EXT:
+ if (element_count >= (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+
+ ErrorStatus = aacDecoder_ParseExplicitMpsAndSbr(
+ self, bs, previous_element, previous_element_index, element_count,
+ el_cnt);
+ break;
+
+ case ID_USAC_EXT: {
+ if ((element_count - element_count_prev_streams) >=
+ TP_USAC_MAX_ELEMENTS) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ /* parse extension element payload
+ q.v. rsv603daExtElement() ISO/IEC DIS 23008-3 Table 30
+ or UsacExElement() ISO/IEC FDIS 23003-3:2011(E) Table 21
+ */
+ int usacExtElementPayloadLength;
+ /* int usacExtElementStart, usacExtElementStop; */
+
+ if (FDKreadBit(bs)) { /* usacExtElementPresent */
+ if (FDKreadBit(bs)) { /* usacExtElementUseDefaultLength */
+ usacExtElementPayloadLength =
+ self->pUsacConfig[streamIndex]
+ ->element[element_count - element_count_prev_streams]
+ .extElement.usacExtElementDefaultLength;
+ } else {
+ usacExtElementPayloadLength = FDKreadBits(bs, 8);
+ if (usacExtElementPayloadLength == (UINT)(1 << 8) - 1) {
+ UINT valueAdd = FDKreadBits(bs, 16);
+ usacExtElementPayloadLength += (INT)valueAdd - 2;
+ }
+ }
+ if (usacExtElementPayloadLength > 0) {
+ int usacExtBitPos;
+
+ if (self->pUsacConfig[streamIndex]
+ ->element[element_count - element_count_prev_streams]
+ .extElement.usacExtElementPayloadFrag) {
+ /* usacExtElementStart = */ FDKreadBit(bs);
+ /* usacExtElementStop = */ FDKreadBit(bs);
+ } else {
+ /* usacExtElementStart = 1; */
+ /* usacExtElementStop = 1; */
+ }
+
+ usacExtBitPos = (INT)FDKgetValidBits(bs);
+
+ USAC_EXT_ELEMENT_TYPE usacExtElementType =
+ self->pUsacConfig[streamIndex]
+ ->element[element_count - element_count_prev_streams]
+ .extElement.usacExtElementType;
+
+ switch (usacExtElementType) {
+ case ID_EXT_ELE_UNI_DRC: /* uniDrcGain() */
+ if (streamIndex == 0) {
+ int drcErr;
+
+ drcErr = FDK_drcDec_ReadUniDrcGain(self->hUniDrcDecoder, bs);
+ if (drcErr != 0) {
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Skip any remaining bits of extension payload */
+ usacExtBitPos = (usacExtElementPayloadLength * 8) -
+ (usacExtBitPos - (INT)FDKgetValidBits(bs));
+ if (usacExtBitPos < 0) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ FDKpushBiDirectional(bs, usacExtBitPos);
+ }
+ }
+ } break;
+ case ID_END:
+ case ID_USAC_END:
+ break;
+
+ default:
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ self->frameOK = 0;
+ break;
+ }
+
+ previous_element = type;
+ element_count++;
+
+ } /* while ( (type != ID_END) ... ) */
+
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
+ /* float decoder checks if bitsLeft is in range 0-7; only prerollAUs are
+ * byteAligned with respect to the first bit */
+ /* Byte alignment with respect to the first bit of the raw_data_block(). */
+ if (!(self->flags[streamIndex] & (AC_RSVD50 | AC_USAC)) ||
+ (self->prerollAULength[self->accessUnit]) /* indicates preroll */
+ ) {
+ FDKbyteAlign(bs, auStartAnchor);
+ }
+
+ /* Check if all bits of the raw_data_block() have been read. */
+ if (transportDec_GetAuBitsTotal(self->hInput, 0) > 0) {
+ INT unreadBits = transportDec_GetAuBitsRemaining(self->hInput, 0);
+ /* for pre-roll frames pre-roll length has to be used instead of total AU
+ * lenght */
+ /* unreadBits regarding preroll bounds */
+ if (self->prerollAULength[self->accessUnit]) {
+ unreadBits = unreadBits - transportDec_GetAuBitsTotal(self->hInput, 0) +
+ (INT)self->prerollAULength[self->accessUnit];
+ }
+ if (((self->flags[streamIndex] & (AC_RSVD50 | AC_USAC)) &&
+ ((unreadBits < 0) || (unreadBits > 7)) &&
+ !(self->prerollAULength[self->accessUnit])) ||
+ ((!(self->flags[streamIndex] & (AC_RSVD50 | AC_USAC)) ||
+ (self->prerollAULength[self->accessUnit])) &&
+ (unreadBits != 0))) {
+ if ((((unreadBits < 0) || (unreadBits > 7)) && self->frameOK) &&
+ ((transportDec_GetFormat(self->hInput) == TT_DRM) &&
+ (self->flags[streamIndex] & AC_USAC))) {
+ /* Set frame OK because of fill bits. */
+ self->frameOK = 1;
+ } else {
+ self->frameOK = 0;
+ }
+
+ /* Do not overwrite current error */
+ if (ErrorStatus == AAC_DEC_OK && self->frameOK == 0) {
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ /* Always put the bitbuffer at the right position after the current
+ * Access Unit. */
+ FDKpushBiDirectional(bs, unreadBits);
+ }
+ }
+
+ /* Check the last element. The terminator (ID_END) has to be the last one
+ * (even if ER syntax is used). */
+ if (self->frameOK && type != ID_END) {
+ /* Do not overwrite current error */
+ if (ErrorStatus == AAC_DEC_OK) {
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ self->frameOK = 0;
+ }
+ }
+
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) && self->frameOK) {
+ channel_elements[channel_element_count++] = ID_END;
+ }
+ element_count = 0;
+ aacChannels = 0;
+ type = ID_NONE;
+ previous_element_index = 0;
+
+ while (type != ID_END &&
+ element_count < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
+ int el_channels;
+
+ if ((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) || !self->frameOK) {
+ channel_elements[element_count] = self->elements[element_count];
+ if (channel_elements[element_count] == ID_NONE) {
+ channel_elements[element_count] = ID_END;
+ }
+ }
+
+ if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA | AC_BSAC)) {
+ type = self->elements[element_count];
+ } else {
+ type = channel_elements[element_count];
+ }
+
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) && self->frameOK) {
+ switch (type) {
+ case ID_SCE:
+ case ID_CPE:
+ case ID_LFE:
+ case ID_USAC_SCE:
+ case ID_USAC_CPE:
+ case ID_USAC_LFE:
+
+ el_channels = CAacDecoder_GetELChannels(
+ type, self->usacStereoConfigIndex[element_count]);
+
+ if (!hdaacDecoded) {
+ if (self->pAacDecoderStaticChannelInfo[aacChannels]
+ ->pCpeStaticData != NULL) {
+ self->pAacDecoderStaticChannelInfo[aacChannels]
+ ->pCpeStaticData->jointStereoPersistentData.scratchBuffer =
+ (FIXP_DBL *)pTimeData;
+ }
+ CChannelElement_Decode(
+ &self->pAacDecoderChannelInfo[aacChannels],
+ &self->pAacDecoderStaticChannelInfo[aacChannels],
+ &self->samplingRateInfo[streamIndex], self->flags[streamIndex],
+ self->elFlags[element_count], el_channels);
+ }
+ aacChannels += el_channels;
+ break;
+ case ID_NONE:
+ type = ID_END;
+ break;
+ default:
+ break;
+ }
+ }
+ element_count++;
+ }
+
+ /* More AAC channels than specified by the ASC not allowed. */
+ if ((aacChannels == 0 || aacChannels > self->aacChannels) &&
+ !(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
+ /* Do not overwrite current error */
+ if (ErrorStatus == AAC_DEC_OK) {
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ self->frameOK = 0;
+ aacChannels = 0;
+ }
+
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
+ if (TRANSPORTDEC_OK != transportDec_CrcCheck(self->hInput)) {
+ ErrorStatus = AAC_DEC_CRC_ERROR;
+ self->frameOK = 0;
+ }
+ }
+
+ /* Ensure that in case of concealment a proper error status is set. */
+ if ((self->frameOK == 0) && (ErrorStatus == AAC_DEC_OK)) {
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ if (self->frameOK && (flags & AACDEC_FLUSH)) {
+ aacChannels = self->aacChannelsPrev;
+ /* Because the downmix could be active, its necessary to restore the channel
+ * type and indices. */
+ FDKmemcpy(self->channelType, self->channelTypePrev,
+ (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* restore */
+ FDKmemcpy(self->channelIndices, self->channelIndicesPrev,
+ (8) * sizeof(UCHAR)); /* restore */
+ self->sbrEnabled = self->sbrEnabledPrev;
+ } else {
+ /* store or restore the number of channels and the corresponding info */
+ if (self->frameOK && !(flags & AACDEC_CONCEAL)) {
+ self->aacChannelsPrev = aacChannels; /* store */
+ FDKmemcpy(self->channelTypePrev, self->channelType,
+ (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* store */
+ FDKmemcpy(self->channelIndicesPrev, self->channelIndices,
+ (8) * sizeof(UCHAR)); /* store */
+ self->sbrEnabledPrev = self->sbrEnabled;
+ } else {
+ if (self->aacChannels > 0) {
+ if ((self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON) ||
+ (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON_IN_BAND) ||
+ (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
+ aacChannels = self->aacChannels;
+ self->aacChannelsPrev = aacChannels; /* store */
+ } else {
+ aacChannels = self->aacChannelsPrev; /* restore */
+ }
+ FDKmemcpy(self->channelType, self->channelTypePrev,
+ (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* restore */
+ FDKmemcpy(self->channelIndices, self->channelIndicesPrev,
+ (8) * sizeof(UCHAR)); /* restore */
+ self->sbrEnabled = self->sbrEnabledPrev;
+ }
+ }
+ }
+
+ /* Update number of output channels */
+ self->streamInfo.aacNumChannels = aacChannels;
+
+ /* Ensure consistency of IS_OUTPUT_VALID() macro. */
+ if (aacChannels == 0) {
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ }
+
+ if (pceRead == 1 && CProgramConfig_IsValid(pce)) {
+ /* Set matrix mixdown infos if available from PCE. */
+ pcmDmx_SetMatrixMixdownFromPce(
+ self->hPcmUtils, pce->MatrixMixdownIndexPresent,
+ pce->MatrixMixdownIndex, pce->PseudoSurroundEnable);
+ ;
+ }
+
+ /* If there is no valid data to transfrom into time domain, return. */
+ if (!IS_OUTPUT_VALID(ErrorStatus)) {
+ return ErrorStatus;
+ }
+
+ /* Setup the output channel mapping. The table below shows the three
+ * possibilities: # | chCfg | PCE | chMapIndex
+ * ---+-------+-----+------------------
+ * 1 | > 0 | no | chCfg
+ * 2 | 0 | yes | cChCfg
+ * 3 | 0 | no | aacChannels || 0
+ * ---+-------+-----+--------+------------------
+ * Where chCfg is the channel configuration index from ASC and cChCfg is a
+ * corresponding chCfg derived from a given PCE. The variable aacChannels
+ * represents the number of channel found during bitstream decoding. Due to
+ * the structure of the mapping table it can only be used for mapping if its
+ * value is smaller than 7. Otherwise we use the fallback (0) which is a
+ * simple pass-through. The possibility #3 should appear only with MPEG-2
+ * (ADTS) streams. This is mode is called "implicit channel mapping".
+ */
+ if ((self->streamInfo.channelConfig == 0) && !pce->isValid) {
+ self->chMapIndex = (aacChannels < 7) ? aacChannels : 0;
+ }
+
+ /*
+ Inverse transform
+ */
+ {
+ int c, cIdx;
+ int mapped, fCopyChMap = 1;
+ UCHAR drcChMap[(8)];
+
+ if ((self->streamInfo.channelConfig == 0) && CProgramConfig_IsValid(pce)) {
+ /* ISO/IEC 14496-3 says:
+ If a PCE is present, the exclude_mask bits correspond to the audio
+ channels in the SCE, CPE, CCE and LFE syntax elements in the order of
+ their appearance in the PCE. In the case of a CPE, the first
+ transmitted mask bit corresponds to the first channel in the CPE, the
+ second transmitted mask bit to the second channel. In the case of a
+ CCE, a mask bit is transmitted only if the coupling channel is
+ specified to be an independently switched coupling channel. Thus we
+ have to convert the internal channel mapping from "canonical" MPEG to
+ PCE order: */
+ UCHAR tmpChMap[(8)];
+ if (CProgramConfig_GetPceChMap(pce, tmpChMap, (8)) == 0) {
+ for (c = 0; c < aacChannels; c += 1) {
+ drcChMap[c] =
+ (self->chMapping[c] == 255) ? 255 : tmpChMap[self->chMapping[c]];
+ }
+ fCopyChMap = 0;
+ }
+ }
+ if (fCopyChMap != 0) {
+ FDKmemcpy(drcChMap, self->chMapping, (8) * sizeof(UCHAR));
+ }
+
+ /* Turn on/off DRC modules level normalization in digital domain depending
+ * on the limiter status. */
+ aacDecoder_drcSetParam(self->hDrcInfo, APPLY_NORMALIZATION,
+ (self->limiterEnableCurr) ? 0 : 1);
+
+ /* deactivate legacy DRC in case uniDrc is active, i.e. uniDrc payload is
+ * present and one of DRC or Loudness Normalization is switched on */
+ aacDecoder_drcSetParam(
+ self->hDrcInfo, UNIDRC_PRECEDENCE,
+ FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE));
+
+ /* Extract DRC control data and map it to channels (without bitstream delay)
+ */
+ mapped = aacDecoder_drcProlog(
+ self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
+ pce->ElementInstanceTag, drcChMap, aacChannels);
+ if (mapped > 0) {
+ /* If at least one DRC thread has been mapped to a channel threre was DRC
+ * data in the bitstream. */
+ self->flags[streamIndex] |= AC_DRC_PRESENT;
+ }
+
+ /* Create a reverse mapping table */
+ UCHAR Reverse_chMapping[((8) * 2)];
+ for (c = 0; c < aacChannels; c++) {
+ int d;
+ for (d = 0; d < aacChannels - 1; d++) {
+ if (self->chMapping[d] == c) {
+ break;
+ }
+ }
+ Reverse_chMapping[c] = d;
+ }
+
+ int el;
+ int el_channels;
+ c = 0;
+ cIdx = 0;
+ el_channels = 0;
+ for (el = 0; el < element_count; el++) {
+ int frameOk_butConceal =
+ 0; /* Force frame concealment during mute release active state. */
+ int concealApplyReturnCode;
+
+ if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA | AC_BSAC)) {
+ type = self->elements[el];
+ } else {
+ type = channel_elements[el];
+ }
+
+ {
+ int nElementChannels;
+
+ nElementChannels =
+ CAacDecoder_GetELChannels(type, self->usacStereoConfigIndex[el]);
+
+ el_channels += nElementChannels;
+
+ if (nElementChannels == 0) {
+ continue;
+ }
+ }
+
+ int offset;
+ int elCh = 0;
+ /* "c" iterates in canonical MPEG channel order */
+ for (; cIdx < el_channels; c++, cIdx++, elCh++) {
+ /* Robustness check */
+ if (c >= aacChannels) {
+ return AAC_DEC_UNKNOWN;
+ }
+
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo =
+ self->pAacDecoderChannelInfo[c];
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo =
+ self->pAacDecoderStaticChannelInfo[c];
+
+ /* Setup offset for time buffer traversal. */
+ {
+ pAacDecoderStaticChannelInfo =
+ self->pAacDecoderStaticChannelInfo[Reverse_chMapping[c]];
+ offset =
+ FDK_chMapDescr_getMapValue(
+ &self->mapDescr, Reverse_chMapping[cIdx], self->chMapIndex) *
+ timeDataChannelOffset;
+ }
+
+ if (flags & AACDEC_FLUSH) {
+ /* Clear pAacDecoderChannelInfo->pSpectralCoefficient because with
+ * AACDEC_FLUSH set it contains undefined data. */
+ FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient,
+ sizeof(FIXP_DBL) * self->streamInfo.aacSamplesPerFrame);
+ }
+
+ /* if The ics info is not valid and it will be stored and used in the
+ * following concealment method, mark the frame as erroneous */
+ {
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+ CConcealmentInfo *hConcealmentInfo =
+ &pAacDecoderStaticChannelInfo->concealmentInfo;
+ const int mute_release_active =
+ (self->frameOK && !(flags & AACDEC_CONCEAL)) &&
+ ((hConcealmentInfo->concealState >= ConcealState_Mute) &&
+ (hConcealmentInfo->cntValidFrames + 1 <=
+ hConcealmentInfo->pConcealParams->numMuteReleaseFrames));
+ const int icsIsInvalid = (GetScaleFactorBandsTransmitted(pIcsInfo) >
+ GetScaleFactorBandsTotal(pIcsInfo));
+ const int icsInfoUsedinFadeOut =
+ !(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
+ pAacDecoderStaticChannelInfo->last_lpd_mode == 0);
+ if (icsInfoUsedinFadeOut && icsIsInvalid && !mute_release_active) {
+ self->frameOK = 0;
+ }
+ }
+
+ /*
+ Conceal defective spectral data
+ */
+ {
+ CAacDecoderChannelInfo **ppAacDecoderChannelInfo =
+ &pAacDecoderChannelInfo;
+ CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo =
+ &pAacDecoderStaticChannelInfo;
+ {
+ concealApplyReturnCode = CConcealment_Apply(
+ &(*ppAacDecoderStaticChannelInfo)->concealmentInfo,
+ *ppAacDecoderChannelInfo, *ppAacDecoderStaticChannelInfo,
+ &self->samplingRateInfo[streamIndex],
+ self->streamInfo.aacSamplesPerFrame,
+ pAacDecoderStaticChannelInfo->last_lpd_mode,
+ (self->frameOK && !(flags & AACDEC_CONCEAL)),
+ self->flags[streamIndex]);
+ }
+ }
+ if (concealApplyReturnCode == -1) {
+ frameOk_butConceal = 1;
+ }
+
+ if (flags & (AACDEC_INTR)) {
+ /* Reset DRC control data for this channel */
+ aacDecoder_drcInitChannelData(&pAacDecoderStaticChannelInfo->drcData);
+ }
+ if (flags & (AACDEC_CLRHIST)) {
+ if (!(self->flags[0] & AC_USAC)) {
+ /* Reset DRC control data for this channel */
+ aacDecoder_drcInitChannelData(
+ &pAacDecoderStaticChannelInfo->drcData);
+ }
+ }
+ /* The DRC module demands to be called with the gain field holding the
+ * gain scale. */
+ self->extGain[0] = (FIXP_DBL)TDL_GAIN_SCALING;
+ /* DRC processing */
+ aacDecoder_drcApply(
+ self->hDrcInfo, self->hSbrDecoder, pAacDecoderChannelInfo,
+ &pAacDecoderStaticChannelInfo->drcData, self->extGain, c,
+ self->streamInfo.aacSamplesPerFrame, self->sbrEnabled
+
+ );
+
+ if (timeDataSize < timeDataChannelOffset * self->aacChannels) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ break;
+ }
+ if (self->flushStatus && (self->flushCnt > 0) &&
+ !(flags & AACDEC_CONCEAL)) {
+ FDKmemclear(pTimeData + offset,
+ sizeof(FIXP_PCM) * self->streamInfo.aacSamplesPerFrame);
+ } else
+ switch (pAacDecoderChannelInfo->renderMode) {
+ case AACDEC_RENDER_IMDCT:
+
+ CBlock_FrequencyToTime(
+ pAacDecoderStaticChannelInfo, pAacDecoderChannelInfo,
+ pTimeData + offset, self->streamInfo.aacSamplesPerFrame,
+ (self->frameOK && !(flags & AACDEC_CONCEAL) &&
+ !frameOk_butConceal),
+ pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1
+ ->mdctOutTemp,
+ self->elFlags[el], elCh);
+
+ self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
+ break;
+ case AACDEC_RENDER_ELDFB: {
+ CBlock_FrequencyToTimeLowDelay(
+ pAacDecoderStaticChannelInfo, pAacDecoderChannelInfo,
+ pTimeData + offset, self->streamInfo.aacSamplesPerFrame);
+ self->extGainDelay =
+ (self->streamInfo.aacSamplesPerFrame * 2 -
+ self->streamInfo.aacSamplesPerFrame / 2 - 1) /
+ 2;
+ } break;
+ case AACDEC_RENDER_LPD:
+
+ CLpd_RenderTimeSignal(
+ pAacDecoderStaticChannelInfo, pAacDecoderChannelInfo,
+ pTimeData + offset, self->streamInfo.aacSamplesPerFrame,
+ &self->samplingRateInfo[streamIndex],
+ (self->frameOK && !(flags & AACDEC_CONCEAL) &&
+ !frameOk_butConceal),
+ flags, self->flags[streamIndex]);
+
+ self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
+ break;
+ default:
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ break;
+ }
+ /* TimeDomainFading */
+ if (!CConceal_TDFading_Applied[c]) {
+ CConceal_TDFading_Applied[c] = CConcealment_TDFading(
+ self->streamInfo.aacSamplesPerFrame,
+ &self->pAacDecoderStaticChannelInfo[c], pTimeData + offset, 0);
+ if (c + 1 < (8) && c < aacChannels - 1) {
+ /* update next TDNoise Seed to avoid muting in case of Parametric
+ * Stereo */
+ self->pAacDecoderStaticChannelInfo[c + 1]
+ ->concealmentInfo.TDNoiseSeed =
+ self->pAacDecoderStaticChannelInfo[c]
+ ->concealmentInfo.TDNoiseSeed;
+ }
+ }
+ }
+ }
+
+ if (self->flags[streamIndex] & AC_USAC) {
+ int bsPseudoLr = 0;
+ mpegSurroundDecoder_IsPseudoLR(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, &bsPseudoLr);
+ /* ISO/IEC 23003-3, 7.11.2.6 Modification of core decoder output (pseudo
+ * LR) */
+ if ((aacChannels == 2) && bsPseudoLr) {
+ int i, offset2;
+ const FIXP_SGL invSqrt2 = FL2FXCONST_SGL(0.707106781186547f);
+ FIXP_PCM *pTD = pTimeData;
+
+ offset2 = timeDataChannelOffset;
+
+ for (i = 0; i < self->streamInfo.aacSamplesPerFrame; i++) {
+ FIXP_DBL L = FX_PCM2FX_DBL(pTD[0]);
+ FIXP_DBL R = FX_PCM2FX_DBL(pTD[offset2]);
+ L = fMult(L, invSqrt2);
+ R = fMult(R, invSqrt2);
+#if (SAMPLE_BITS == 16)
+ pTD[0] = FX_DBL2FX_PCM(fAddSaturate(L + R, (FIXP_DBL)0x8000));
+ pTD[offset2] = FX_DBL2FX_PCM(fAddSaturate(L - R, (FIXP_DBL)0x8000));
+#else
+ pTD[0] = FX_DBL2FX_PCM(L + R);
+ pTD[offset2] = FX_DBL2FX_PCM(L - R);
+#endif
+ pTD++;
+ }
+ }
+ }
+
+ /* Extract DRC control data and map it to channels (with bitstream delay) */
+ mapped = aacDecoder_drcEpilog(
+ self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
+ pce->ElementInstanceTag, drcChMap, aacChannels);
+ if (mapped > 0) {
+ /* If at least one DRC thread has been mapped to a channel threre was DRC
+ * data in the bitstream. */
+ self->flags[streamIndex] |= AC_DRC_PRESENT;
+ }
+ }
+
+ /* Add additional concealment delay */
+ self->streamInfo.outputDelay +=
+ CConcealment_GetDelay(&self->concealCommonData) *
+ self->streamInfo.aacSamplesPerFrame;
+
+ /* Map DRC data to StreamInfo structure */
+ aacDecoder_drcGetInfo(self->hDrcInfo, &self->streamInfo.drcPresMode,
+ &self->streamInfo.drcProgRefLev);
+
+ /* Reorder channel type information tables. */
+ if (!(self->flags[0] & AC_RSV603DA)) {
+ AUDIO_CHANNEL_TYPE types[(8)];
+ UCHAR idx[(8)];
+ int c;
+ int mapValue;
+
+ FDK_ASSERT(sizeof(self->channelType) == sizeof(types));
+ FDK_ASSERT(sizeof(self->channelIndices) == sizeof(idx));
+
+ FDKmemcpy(types, self->channelType, sizeof(types));
+ FDKmemcpy(idx, self->channelIndices, sizeof(idx));
+
+ for (c = 0; c < aacChannels; c++) {
+ mapValue =
+ FDK_chMapDescr_getMapValue(&self->mapDescr, c, self->chMapIndex);
+ self->channelType[mapValue] = types[c];
+ self->channelIndices[mapValue] = idx[c];
+ }
+ }
+
+ self->blockNumber++;
+
+ return ErrorStatus;
+}
+
+/*!
+ \brief returns the streaminfo pointer
+
+ The function hands back a pointer to the streaminfo structure
+
+ \return pointer to the struct
+*/
+LINKSPEC_CPP CStreamInfo *CAacDecoder_GetStreamInfo(HANDLE_AACDECODER self) {
+ if (!self) {
+ return NULL;
+ }
+ return &self->streamInfo;
+}
diff --git a/fdk-aac/libAACdec/src/aacdecoder.h b/fdk-aac/libAACdec/src/aacdecoder.h
new file mode 100644
index 0000000..20f4c45
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdecoder.h
@@ -0,0 +1,465 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef AACDECODER_H
+#define AACDECODER_H
+
+#include "common_fix.h"
+
+#include "FDK_bitstream.h"
+
+#include "channel.h"
+
+#include "tpdec_lib.h"
+#include "FDK_audio.h"
+
+#include "block.h"
+
+#include "genericStds.h"
+
+#include "FDK_qmf_domain.h"
+
+#include "sbrdecoder.h"
+
+#include "aacdec_drc.h"
+
+#include "pcmdmx_lib.h"
+
+#include "FDK_drcDecLib.h"
+
+#include "limiter.h"
+
+#include "FDK_delay.h"
+
+#define TIME_DATA_FLUSH_SIZE (128)
+#define TIME_DATA_FLUSH_SIZE_SF (7)
+
+#define AACDEC_MAX_NUM_PREROLL_AU_USAC (3)
+#if (AACDEC_MAX_NUM_PREROLL_AU < 3)
+#undef AACDEC_MAX_NUM_PREROLL_AU
+#define AACDEC_MAX_NUM_PREROLL_AU AACDEC_MAX_NUM_PREROLL_AU_USAC
+#endif
+
+typedef struct AAC_DECODER_INSTANCE *HANDLE_AACDECODER;
+
+enum { L = 0, R = 1 };
+
+typedef struct {
+ unsigned char *buffer;
+ int bufferSize;
+ int offset[8];
+ int nrElements;
+} CAncData;
+
+typedef enum { NOT_DEFINED = -1, MODE_HQ = 0, MODE_LP = 1 } QMF_MODE;
+
+typedef struct {
+ int bsDelay;
+} SBR_PARAMS;
+
+enum {
+ AACDEC_FLUSH_OFF = 0,
+ AACDEC_RSV60_CFG_CHANGE_ATSC_FLUSH_ON = 1,
+ AACDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON = 2,
+ AACDEC_USAC_DASH_IPF_FLUSH_ON = 3
+};
+
+enum {
+ AACDEC_BUILD_UP_OFF = 0,
+ AACDEC_RSV60_BUILD_UP_ON = 1,
+ AACDEC_RSV60_BUILD_UP_ON_IN_BAND = 2,
+ AACDEC_USAC_BUILD_UP_ON = 3,
+ AACDEC_RSV60_BUILD_UP_IDLE = 4,
+ AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND = 5
+};
+
+typedef struct {
+ /* Usac Extension Elements */
+ USAC_EXT_ELEMENT_TYPE usacExtElementType[(3)];
+ UINT usacExtElementDefaultLength[(3)];
+ UCHAR usacExtElementPayloadFrag[(3)];
+} CUsacCoreExtensions;
+
+/* AAC decoder (opaque toward userland) struct declaration */
+struct AAC_DECODER_INSTANCE {
+ INT aacChannels; /*!< Amount of AAC decoder channels allocated. */
+ INT ascChannels[(1 *
+ 1)]; /*!< Amount of AAC decoder channels signalled in ASC. */
+ INT blockNumber; /*!< frame counter */
+
+ INT nrOfLayers;
+
+ INT outputInterleaved; /*!< PCM output format (interleaved/none interleaved).
+ */
+
+ HANDLE_TRANSPORTDEC hInput; /*!< Transport layer handle. */
+
+ SamplingRateInfo
+ samplingRateInfo[(1 * 1)]; /*!< Sampling Rate information table */
+
+ UCHAR
+ frameOK; /*!< Will be unset if a consistency check, e.g. CRC etc. fails */
+
+ UINT flags[(1 * 1)]; /*!< Flags for internal decoder use. DO NOT USE
+ self::streaminfo::flags ! */
+ UINT elFlags[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) +
+ 1)]; /*!< Flags for internal decoder use (element specific). DO
+ NOT USE self::streaminfo::flags ! */
+
+ MP4_ELEMENT_ID elements[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) +
+ 1)]; /*!< Table where the element Id's are listed */
+ UCHAR elTags[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) +
+ 1)]; /*!< Table where the elements id Tags are listed */
+ UCHAR chMapping[((8) * 2)]; /*!< Table of MPEG canonical order to bitstream
+ channel order mapping. */
+
+ AUDIO_CHANNEL_TYPE channelType[(8)]; /*!< Audio channel type of each output
+ audio channel (from 0 upto
+ numChannels). */
+ UCHAR channelIndices[(8)]; /*!< Audio channel index for each output audio
+ channel (from 0 upto numChannels). */
+ /* See ISO/IEC 13818-7:2005(E), 8.5.3.2 Explicit channel mapping using a
+ * program_config_element() */
+
+ FDK_channelMapDescr mapDescr; /*!< Describes the output channel mapping. */
+ UCHAR chMapIndex; /*!< Index to access one line of the channelOutputMapping
+ table. This is required because not all 8 channel
+ configurations have the same output mapping. */
+ INT sbrDataLen; /*!< Expected length of the SBR remaining in bitbuffer after
+ the AAC payload has been pared. */
+
+ CProgramConfig pce;
+ CStreamInfo
+ streamInfo; /*!< Pointer to StreamInfo data (read from the bitstream) */
+ CAacDecoderChannelInfo
+ *pAacDecoderChannelInfo[(8)]; /*!< Temporal channel memory */
+ CAacDecoderStaticChannelInfo
+ *pAacDecoderStaticChannelInfo[(8)]; /*!< Persistent channel memory */
+
+ FIXP_DBL *workBufferCore2;
+ PCM_DEC *pTimeData2;
+ INT timeData2Size;
+
+ CpePersistentData *cpeStaticData[(
+ 3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) +
+ 1)]; /*!< Pointer to persistent data shared by both channels of a CPE.
+This structure is allocated once for each CPE. */
+
+ CConcealParams concealCommonData;
+ CConcealmentMethod concealMethodUser;
+
+ CUsacCoreExtensions usacCoreExt; /*!< Data and handles to extend USAC FD/LPD
+ core decoder (SBR, MPS, ...) */
+ UINT numUsacElements[(1 * 1)];
+ UCHAR usacStereoConfigIndex[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)];
+ const CSUsacConfig *pUsacConfig[(1 * 1)];
+ INT nbDiv; /*!< number of frame divisions in LPD-domain */
+
+ UCHAR useLdQmfTimeAlign;
+
+ INT aacChannelsPrev; /*!< The amount of AAC core channels of the last
+ successful decode call. */
+ AUDIO_CHANNEL_TYPE channelTypePrev[(8)]; /*!< Array holding the channelType
+ values of the last successful
+ decode call. */
+ UCHAR
+ channelIndicesPrev[(8)]; /*!< Array holding the channelIndices values of
+ the last successful decode call. */
+
+ UCHAR
+ downscaleFactor; /*!< Variable to store a supported ELD downscale factor
+ of 1, 2, 3 or 4 */
+ UCHAR downscaleFactorInBS; /*!< Variable to store the (not necessarily
+ supported) ELD downscale factor discovered in
+ the bitstream */
+
+ HANDLE_SBRDECODER hSbrDecoder; /*!< SBR decoder handle. */
+ UCHAR sbrEnabled; /*!< flag to store if SBR has been detected */
+ UCHAR sbrEnabledPrev; /*!< flag to store if SBR has been detected from
+ previous frame */
+ UCHAR psPossible; /*!< flag to store if PS is possible */
+ SBR_PARAMS sbrParams; /*!< struct to store all sbr parameters */
+
+ UCHAR *pDrmBsBuffer; /*!< Pointer to dynamic buffer which is used to reverse
+ the bits of the DRM SBR payload */
+ USHORT drmBsBufferSize; /*!< Size of the dynamic buffer which is used to
+ reverse the bits of the DRM SBR payload */
+ FDK_QMF_DOMAIN
+ qmfDomain; /*!< Instance of module for QMF domain data handling */
+
+ QMF_MODE qmfModeCurr; /*!< The current QMF mode */
+ QMF_MODE qmfModeUser; /*!< The QMF mode requested by the library user */
+
+ HANDLE_AAC_DRC hDrcInfo; /*!< handle to DRC data structure */
+ INT metadataExpiry; /*!< Metadata expiry time in milli-seconds. */
+
+ void *pMpegSurroundDecoder; /*!< pointer to mpeg surround decoder structure */
+ UCHAR mpsEnableUser; /*!< MPS enable user flag */
+ UCHAR mpsEnableCurr; /*!< MPS enable decoder state */
+ UCHAR mpsApplicable; /*!< MPS applicable */
+ SCHAR mpsOutputMode; /*!< setting: normal = 0, binaural = 1, stereo = 2, 5.1ch
+ = 3 */
+ INT mpsOutChannelsLast; /*!< The amount of channels returned by the last
+ successful MPS decoder call. */
+ INT mpsFrameSizeLast; /*!< The frame length returned by the last successful
+ MPS decoder call. */
+
+ CAncData ancData; /*!< structure to handle ancillary data */
+
+ HANDLE_PCM_DOWNMIX hPcmUtils; /*!< privat data for the PCM utils. */
+
+ TDLimiterPtr hLimiter; /*!< Handle of time domain limiter. */
+ UCHAR limiterEnableUser; /*!< The limiter configuration requested by the
+ library user */
+ UCHAR limiterEnableCurr; /*!< The current limiter configuration. */
+ FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */
+ UINT extGainDelay; /*!< Delay that must be accounted for extGain. */
+
+ INT_PCM pcmOutputBuffer[(8) * (1024 * 2)];
+
+ HANDLE_DRC_DECODER hUniDrcDecoder;
+ UCHAR multibandDrcPresent;
+ UCHAR numTimeSlots;
+ UINT loudnessInfoSetPosition[3];
+ SCHAR defaultTargetLoudness;
+
+ INT_PCM
+ *pTimeDataFlush[((8) * 2)]; /*!< Pointer to the flushed time data which
+ will be used for the crossfade in case of
+ an USAC DASH IPF config change */
+
+ UCHAR flushStatus; /*!< Indicates flush status: on|off */
+ SCHAR flushCnt; /*!< Flush frame counter */
+ UCHAR buildUpStatus; /*!< Indicates build up status: on|off */
+ SCHAR buildUpCnt; /*!< Build up frame counter */
+ UCHAR hasAudioPreRoll; /*!< Indicates preRoll status: on|off */
+ UINT prerollAULength[AACDEC_MAX_NUM_PREROLL_AU + 1]; /*!< Relative offset of
+ the prerollAU end
+ position to the AU
+ start position in the
+ bitstream */
+ INT accessUnit; /*!< Number of the actual processed preroll accessUnit */
+ UCHAR applyCrossfade; /*!< if set crossfade for seamless stream switching is
+ applied */
+
+ FDK_SignalDelay usacResidualDelay; /*!< Delay residual signal to compensate
+ for eSBR delay of DMX signal in case of
+ stereoConfigIndex==2. */
+};
+
+#define AAC_DEBUG_EXTHLP \
+ "\
+--- AAC-Core ---\n\
+ 0x00010000 Header data\n\
+ 0x00020000 CRC data\n\
+ 0x00040000 Channel info\n\
+ 0x00080000 Section data\n\
+ 0x00100000 Scalefactor data\n\
+ 0x00200000 Pulse data\n\
+ 0x00400000 Tns data\n\
+ 0x00800000 Quantized spectrum\n\
+ 0x01000000 Requantized spectrum\n\
+ 0x02000000 Time output\n\
+ 0x04000000 Fatal errors\n\
+ 0x08000000 Buffer fullness\n\
+ 0x10000000 Average bitrate\n\
+ 0x20000000 Synchronization\n\
+ 0x40000000 Concealment\n\
+ 0x7FFF0000 all AAC-Core-Info\n\
+"
+
+/**
+ * \brief Synchronise QMF mode for all modules using QMF data.
+ * \param self decoder handle
+ */
+void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self);
+
+/**
+ * \brief Signal a bit stream interruption to the decoder
+ * \param self decoder handle
+ */
+void CAacDecoder_SignalInterruption(HANDLE_AACDECODER self);
+
+/*!
+ \brief Initialize ancillary buffer
+
+ \ancData Pointer to ancillary data structure
+ \buffer Pointer to (external) anc data buffer
+ \size Size of the buffer pointed on by buffer
+
+ \return Error code
+*/
+AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData,
+ unsigned char *buffer, int size);
+
+/*!
+ \brief Get one ancillary data element
+
+ \ancData Pointer to ancillary data structure
+ \index Index of the anc data element to get
+ \ptr Pointer to a buffer receiving a pointer to the requested anc data element
+ \size Pointer to a buffer receiving the length of the requested anc data
+ element
+
+ \return Error code
+*/
+AAC_DECODER_ERROR CAacDecoder_AncDataGet(CAncData *ancData, int index,
+ unsigned char **ptr, int *size);
+
+/* initialization of aac decoder */
+LINKSPEC_H HANDLE_AACDECODER CAacDecoder_Open(TRANSPORT_TYPE bsFormat);
+
+/* Initialization of channel elements */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self,
+ const CSAudioSpecificConfig *asc,
+ UCHAR configMode,
+ UCHAR *configChanged);
+/*!
+ \brief Decodes one aac frame
+
+ The function decodes one aac frame. The decoding of coupling channel
+ elements are not supported. The transport layer might signal, that the
+ data of the current frame is invalid, e.g. as a result of a packet
+ loss in streaming mode.
+ The bitstream position of transportDec_GetBitstream(self->hInput) must
+ be exactly the end of the access unit, including all byte alignment bits.
+ For this purpose, the variable auStartAnchor is used.
+
+ \return error status
+*/
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
+ HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData,
+ const INT timeDataSize, const int timeDataChannelOffset);
+
+/* Free config dependent AAC memory */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_FreeMem(HANDLE_AACDECODER self,
+ const int subStreamIndex);
+
+/* Prepare crossfade for USAC DASH IPF config change */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade(
+ const INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels,
+ const INT frameSize, const INT interleaved);
+
+/* Apply crossfade for USAC DASH IPF config change */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade(
+ INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels,
+ const INT frameSize, const INT interleaved);
+
+/* Set flush and build up mode */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_CtrlCFGChange(HANDLE_AACDECODER self,
+ UCHAR flushStatus,
+ SCHAR flushCnt,
+ UCHAR buildUpStatus,
+ SCHAR buildUpCnt);
+
+/* Parse preRoll Extension Payload */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_PreRollExtensionPayloadParse(
+ HANDLE_AACDECODER self, UINT *numPrerollAU, UINT *prerollAUOffset,
+ UINT *prerollAULength);
+
+/* Destroy aac decoder */
+LINKSPEC_H void CAacDecoder_Close(HANDLE_AACDECODER self);
+
+/* get streaminfo handle from decoder */
+LINKSPEC_H CStreamInfo *CAacDecoder_GetStreamInfo(HANDLE_AACDECODER self);
+
+#endif /* #ifndef AACDECODER_H */
diff --git a/fdk-aac/libAACdec/src/aacdecoder_lib.cpp b/fdk-aac/libAACdec/src/aacdecoder_lib.cpp
new file mode 100644
index 0000000..7df17b9
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdecoder_lib.cpp
@@ -0,0 +1,2035 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description:
+
+*******************************************************************************/
+
+#include "aacdecoder_lib.h"
+
+#include "aac_ram.h"
+#include "aacdecoder.h"
+#include "tpdec_lib.h"
+#include "FDK_core.h" /* FDK_tools version info */
+
+#include "sbrdecoder.h"
+
+#include "conceal.h"
+
+#include "aacdec_drc.h"
+
+#include "sac_dec_lib.h"
+
+#include "pcm_utils.h"
+
+/* Decoder library info */
+#define AACDECODER_LIB_VL0 3
+#define AACDECODER_LIB_VL1 0
+#define AACDECODER_LIB_VL2 0
+#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_TIME __TIME__
+#endif
+
+static AAC_DECODER_ERROR setConcealMethod(const HANDLE_AACDECODER self,
+ const INT method);
+
+static void aacDecoder_setMetadataExpiry(const HANDLE_AACDECODER self,
+ const INT value) {
+ /* check decoder handle */
+ if (self != NULL) {
+ INT mdExpFrame = 0; /* default: disable */
+
+ if ((value > 0) &&
+ (self->streamInfo.aacSamplesPerFrame >
+ 0)) { /* Determine the corresponding number of frames: */
+ FIXP_DBL frameTime = fDivNorm(self->streamInfo.aacSampleRate,
+ self->streamInfo.aacSamplesPerFrame * 1000);
+ mdExpFrame = fMultIceil(frameTime, value);
+ }
+
+ /* Configure DRC module */
+ aacDecoder_drcSetParam(self->hDrcInfo, DRC_DATA_EXPIRY_FRAME, mdExpFrame);
+
+ /* Configure PCM downmix module */
+ pcmDmx_SetParam(self->hPcmUtils, DMX_BS_DATA_EXPIRY_FRAME, mdExpFrame);
+ }
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR
+aacDecoder_GetFreeBytes(const HANDLE_AACDECODER self, UINT *pFreeBytes) {
+ /* reset free bytes */
+ *pFreeBytes = 0;
+
+ /* check handle */
+ if (!self) return AAC_DEC_INVALID_HANDLE;
+
+ /* return nr of free bytes */
+ HANDLE_FDK_BITSTREAM hBs = transportDec_GetBitstream(self->hInput, 0);
+ *pFreeBytes = FDKgetFreeBits(hBs) >> 3;
+
+ /* success */
+ return AAC_DEC_OK;
+}
+
+/**
+ * Config Decoder using a CSAudioSpecificConfig struct.
+ */
+static LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Config(
+ HANDLE_AACDECODER self, const CSAudioSpecificConfig *pAscStruct,
+ UCHAR configMode, UCHAR *configChanged) {
+ AAC_DECODER_ERROR err;
+
+ /* Initialize AAC core decoder, and update self->streaminfo */
+ err = CAacDecoder_Init(self, pAscStruct, configMode, configChanged);
+
+ if (!FDK_chMapDescr_isValid(&self->mapDescr)) {
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ return err;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_ConfigRaw(HANDLE_AACDECODER self,
+ UCHAR *conf[],
+ const UINT length[]) {
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+ TRANSPORTDEC_ERROR errTp;
+ UINT layer, nrOfLayers = self->nrOfLayers;
+
+ for (layer = 0; layer < nrOfLayers; layer++) {
+ if (length[layer] > 0) {
+ errTp = transportDec_OutOfBandConfig(self->hInput, conf[layer],
+ length[layer], layer);
+ if (errTp != TRANSPORTDEC_OK) {
+ switch (errTp) {
+ case TRANSPORTDEC_NEED_TO_RESTART:
+ err = AAC_DEC_NEED_TO_RESTART;
+ break;
+ case TRANSPORTDEC_UNSUPPORTED_FORMAT:
+ err = AAC_DEC_UNSUPPORTED_FORMAT;
+ break;
+ default:
+ err = AAC_DEC_UNKNOWN;
+ break;
+ }
+ /* if baselayer is OK we continue decoding */
+ if (layer >= 1) {
+ self->nrOfLayers = layer;
+ err = AAC_DEC_OK;
+ }
+ break;
+ }
+ }
+ }
+
+ return err;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_RawISOBMFFData(HANDLE_AACDECODER self,
+ UCHAR *buffer,
+ UINT length) {
+ FDK_BITSTREAM bs;
+ HANDLE_FDK_BITSTREAM hBs = &bs;
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+
+ if (length < 8) return AAC_DEC_UNKNOWN;
+
+ while (length >= 8) {
+ UINT size =
+ (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
+ DRC_DEC_ERROR uniDrcErr = DRC_DEC_OK;
+
+ if (length < size) return AAC_DEC_UNKNOWN;
+ if (size <= 8) return AAC_DEC_UNKNOWN;
+
+ FDKinitBitStream(hBs, buffer + 8, 0x10000000, (size - 8) * 8);
+
+ if ((buffer[4] == 'l') && (buffer[5] == 'u') && (buffer[6] == 'd') &&
+ (buffer[7] == 't')) {
+ uniDrcErr = FDK_drcDec_ReadLoudnessBox(self->hUniDrcDecoder, hBs);
+ } else if ((buffer[4] == 'd') && (buffer[5] == 'm') && (buffer[6] == 'i') &&
+ (buffer[7] == 'x')) {
+ uniDrcErr =
+ FDK_drcDec_ReadDownmixInstructions_Box(self->hUniDrcDecoder, hBs);
+ } else if ((buffer[4] == 'u') && (buffer[5] == 'd') && (buffer[6] == 'i') &&
+ (buffer[7] == '2')) {
+ uniDrcErr =
+ FDK_drcDec_ReadUniDrcInstructions_Box(self->hUniDrcDecoder, hBs);
+ } else if ((buffer[4] == 'u') && (buffer[5] == 'd') && (buffer[6] == 'c') &&
+ (buffer[7] == '2')) {
+ uniDrcErr =
+ FDK_drcDec_ReadUniDrcCoefficients_Box(self->hUniDrcDecoder, hBs);
+ }
+
+ if (uniDrcErr != DRC_DEC_OK) err = AAC_DEC_UNKNOWN;
+
+ buffer += size;
+ length -= size;
+ }
+
+ return err;
+}
+
+static INT aacDecoder_ConfigCallback(void *handle,
+ const CSAudioSpecificConfig *pAscStruct,
+ UCHAR configMode, UCHAR *configChanged) {
+ HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+ TRANSPORTDEC_ERROR errTp;
+
+ FDK_ASSERT(self != NULL);
+ {
+ { err = aacDecoder_Config(self, pAscStruct, configMode, configChanged); }
+ }
+ if (err == AAC_DEC_OK) {
+ /*
+ revert concealment method if either
+ - Interpolation concealment might not be meaningful
+ - Interpolation concealment is not implemented
+ */
+ if ((self->flags[0] & (AC_LD | AC_ELD) &&
+ (self->concealMethodUser == ConcealMethodNone) &&
+ CConcealment_GetDelay(&self->concealCommonData) >
+ 0) /* might not be meaningful but allow if user has set it
+ expicitly */
+ || (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) &&
+ CConcealment_GetDelay(&self->concealCommonData) >
+ 0) /* not implemented */
+ ) {
+ /* Revert to error concealment method Noise Substitution.
+ Because interpolation is not implemented for USAC or
+ the additional delay is unwanted for low delay codecs. */
+ setConcealMethod(self, 1);
+ }
+ aacDecoder_setMetadataExpiry(self, self->metadataExpiry);
+ errTp = TRANSPORTDEC_OK;
+ } else {
+ if (err == AAC_DEC_NEED_TO_RESTART) {
+ errTp = TRANSPORTDEC_NEED_TO_RESTART;
+ } else if (IS_INIT_ERROR(err)) {
+ errTp = TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ } /* Fatal errors */
+ else {
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+ }
+
+ return errTp;
+}
+
+static INT aacDecoder_FreeMemCallback(void *handle,
+ const CSAudioSpecificConfig *pAscStruct) {
+ TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK;
+ HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
+
+ const int subStreamIndex = 0;
+
+ FDK_ASSERT(self != NULL);
+
+ if (CAacDecoder_FreeMem(self, subStreamIndex) != AAC_DEC_OK) {
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+
+ /* free Ram_SbrDecoder and Ram_SbrDecChannel */
+ if (self->hSbrDecoder != NULL) {
+ if (sbrDecoder_FreeMem(&self->hSbrDecoder) != SBRDEC_OK) {
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+ }
+
+ /* free pSpatialDec and mpsData */
+ if (self->pMpegSurroundDecoder != NULL) {
+ if (mpegSurroundDecoder_FreeMem(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) != MPS_OK) {
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+ }
+
+ /* free persistent qmf domain buffer, QmfWorkBufferCore3, QmfWorkBufferCore4,
+ * QmfWorkBufferCore5 and configuration variables */
+ FDK_QmfDomain_FreeMem(&self->qmfDomain);
+
+ return errTp;
+}
+
+static INT aacDecoder_CtrlCFGChangeCallback(
+ void *handle, const CCtrlCFGChange *pCtrlCFGChangeStruct) {
+ TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK;
+ HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
+
+ if (self != NULL) {
+ CAacDecoder_CtrlCFGChange(
+ self, pCtrlCFGChangeStruct->flushStatus, pCtrlCFGChangeStruct->flushCnt,
+ pCtrlCFGChangeStruct->buildUpStatus, pCtrlCFGChangeStruct->buildUpCnt);
+ } else {
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+
+ return errTp;
+}
+
+static INT aacDecoder_SbrCallback(
+ void *handle, HANDLE_FDK_BITSTREAM hBs, const INT sampleRateIn,
+ const INT sampleRateOut, const INT samplesPerFrame,
+ const AUDIO_OBJECT_TYPE coreCodec, const MP4_ELEMENT_ID elementID,
+ const INT elementIndex, const UCHAR harmonicSBR,
+ const UCHAR stereoConfigIndex, const UCHAR configMode, UCHAR *configChanged,
+ const INT downscaleFactor) {
+ HANDLE_SBRDECODER self = (HANDLE_SBRDECODER)handle;
+
+ INT errTp = sbrDecoder_Header(self, hBs, sampleRateIn, sampleRateOut,
+ samplesPerFrame, coreCodec, elementID,
+ elementIndex, harmonicSBR, stereoConfigIndex,
+ configMode, configChanged, downscaleFactor);
+
+ return errTp;
+}
+
+static INT aacDecoder_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const INT samplingRate, const INT frameSize,
+ const INT stereoConfigIndex,
+ const INT coreSbrFrameLengthIndex,
+ const INT configBytes, const UCHAR configMode,
+ UCHAR *configChanged) {
+ SACDEC_ERROR err;
+ TRANSPORTDEC_ERROR errTp;
+ HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle;
+
+ err = mpegSurroundDecoder_Config(
+ (CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec,
+ samplingRate, frameSize, stereoConfigIndex, coreSbrFrameLengthIndex,
+ configBytes, configMode, configChanged);
+
+ switch (err) {
+ case MPS_UNSUPPORTED_CONFIG:
+ /* MPS found but invalid or not decodable by this instance */
+ /* We switch off MPS and keep going */
+ hAacDecoder->mpsEnableCurr = 0;
+ hAacDecoder->mpsApplicable = 0;
+ errTp = TRANSPORTDEC_OK;
+ break;
+ case MPS_PARSE_ERROR:
+ /* MPS found but invalid or not decodable by this instance */
+ hAacDecoder->mpsEnableCurr = 0;
+ hAacDecoder->mpsApplicable = 0;
+ if ((coreCodec == AOT_USAC) || (coreCodec == AOT_DRM_USAC) ||
+ IS_LOWDELAY(coreCodec)) {
+ errTp = TRANSPORTDEC_PARSE_ERROR;
+ } else {
+ errTp = TRANSPORTDEC_OK;
+ }
+ break;
+ case MPS_OK:
+ hAacDecoder->mpsApplicable = 1;
+ errTp = TRANSPORTDEC_OK;
+ break;
+ default:
+ /* especially Parsing error is critical for transport layer */
+ hAacDecoder->mpsApplicable = 0;
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+
+ return (INT)errTp;
+}
+
+static INT aacDecoder_UniDrcCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
+ const INT fullPayloadLength,
+ const INT payloadType,
+ const INT subStreamIndex,
+ const INT payloadStart,
+ const AUDIO_OBJECT_TYPE aot) {
+ DRC_DEC_ERROR err = DRC_DEC_OK;
+ TRANSPORTDEC_ERROR errTp;
+ HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle;
+ DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED;
+
+ if (subStreamIndex != 0) {
+ return TRANSPORTDEC_OK;
+ }
+
+ else if (aot == AOT_USAC) {
+ drcDecCodecMode = DRC_DEC_MPEG_D_USAC;
+ }
+
+ err = FDK_drcDec_SetCodecMode(hAacDecoder->hUniDrcDecoder, drcDecCodecMode);
+ if (err) return (INT)TRANSPORTDEC_UNKOWN_ERROR;
+
+ if (payloadType == 0) /* uniDrcConfig */
+ {
+ err = FDK_drcDec_ReadUniDrcConfig(hAacDecoder->hUniDrcDecoder, hBs);
+ } else /* loudnessInfoSet */
+ {
+ err = FDK_drcDec_ReadLoudnessInfoSet(hAacDecoder->hUniDrcDecoder, hBs);
+ hAacDecoder->loudnessInfoSetPosition[1] = payloadStart;
+ hAacDecoder->loudnessInfoSetPosition[2] = fullPayloadLength;
+ }
+
+ if (err == DRC_DEC_OK)
+ errTp = TRANSPORTDEC_OK;
+ else
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+
+ return (INT)errTp;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_AncDataInit(HANDLE_AACDECODER self,
+ UCHAR *buffer, int size) {
+ CAncData *ancData = &self->ancData;
+
+ return CAacDecoder_AncDataInit(ancData, buffer, size);
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_AncDataGet(HANDLE_AACDECODER self,
+ int index, UCHAR **ptr,
+ int *size) {
+ CAncData *ancData = &self->ancData;
+
+ return CAacDecoder_AncDataGet(ancData, index, ptr, size);
+}
+
+/* If MPS is present in stream, but not supported by this instance, we'll
+ have to switch off MPS and use QMF synthesis in the SBR module if required */
+static int isSupportedMpsConfig(AUDIO_OBJECT_TYPE aot,
+ unsigned int numInChannels,
+ unsigned int fMpsPresent) {
+ LIB_INFO libInfo[FDK_MODULE_LAST];
+ UINT mpsCaps;
+ int isSupportedCfg = 1;
+
+ FDKinitLibInfo(libInfo);
+
+ mpegSurroundDecoder_GetLibInfo(libInfo);
+
+ mpsCaps = FDKlibInfo_getCapabilities(libInfo, FDK_MPSDEC);
+
+ if (!(mpsCaps & CAPF_MPS_LD) && IS_LOWDELAY(aot)) {
+ /* We got an LD AOT but MPS decoder does not support LD. */
+ isSupportedCfg = 0;
+ }
+ if ((mpsCaps & CAPF_MPS_LD) && IS_LOWDELAY(aot) && !fMpsPresent) {
+ /* We got an LD AOT and the MPS decoder supports it.
+ * But LD-MPS is not explicitly signaled. */
+ isSupportedCfg = 0;
+ }
+ if (!(mpsCaps & CAPF_MPS_USAC) && IS_USAC(aot)) {
+ /* We got an USAC AOT but MPS decoder does not support USAC. */
+ isSupportedCfg = 0;
+ }
+ if (!(mpsCaps & CAPF_MPS_STD) && !IS_LOWDELAY(aot) && !IS_USAC(aot)) {
+ /* We got an GA AOT but MPS decoder does not support it. */
+ isSupportedCfg = 0;
+ }
+ /* Check whether the MPS modul supports the given number of input channels: */
+ switch (numInChannels) {
+ case 1:
+ if (!(mpsCaps & CAPF_MPS_1CH_IN)) {
+ /* We got a one channel input to MPS decoder but it does not support it.
+ */
+ isSupportedCfg = 0;
+ }
+ break;
+ case 2:
+ if (!(mpsCaps & CAPF_MPS_2CH_IN)) {
+ /* We got a two channel input to MPS decoder but it does not support it.
+ */
+ isSupportedCfg = 0;
+ }
+ break;
+ case 5:
+ case 6:
+ if (!(mpsCaps & CAPF_MPS_6CH_IN)) {
+ /* We got a six channel input to MPS decoder but it does not support it.
+ */
+ isSupportedCfg = 0;
+ }
+ break;
+ default:
+ isSupportedCfg = 0;
+ }
+
+ return (isSupportedCfg);
+}
+
+static AAC_DECODER_ERROR setConcealMethod(
+ const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */
+ const INT method) {
+ AAC_DECODER_ERROR errorStatus = AAC_DEC_OK;
+ CConcealParams *pConcealData = NULL;
+ int method_revert = 0;
+ HANDLE_SBRDECODER hSbrDec = NULL;
+ HANDLE_AAC_DRC hDrcInfo = NULL;
+ HANDLE_PCM_DOWNMIX hPcmDmx = NULL;
+ CConcealmentMethod backupMethod = ConcealMethodNone;
+ int backupDelay = 0;
+ int bsDelay = 0;
+
+ /* check decoder handle */
+ if (self != NULL) {
+ pConcealData = &self->concealCommonData;
+ hSbrDec = self->hSbrDecoder;
+ hDrcInfo = self->hDrcInfo;
+ hPcmDmx = self->hPcmUtils;
+ if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) {
+ /* Interpolation concealment is not implemented for USAC/RSVD50 */
+ /* errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ goto bail; */
+ method_revert = 1;
+ }
+ if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) {
+ /* Interpolation concealment is not implemented for USAC/RSVD50 */
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ goto bail;
+ }
+ }
+
+ /* Get current method/delay */
+ backupMethod = CConcealment_GetMethod(pConcealData);
+ backupDelay = CConcealment_GetDelay(pConcealData);
+
+ /* Be sure to set AAC and SBR concealment method simultaneously! */
+ errorStatus = CConcealment_SetParams(
+ pConcealData,
+ (method_revert == 0) ? (int)method : (int)1, // concealMethod
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeOutSlope
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeInSlope
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealMuteRelease
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED // concealComfNoiseLevel
+ );
+ if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
+ goto bail;
+ }
+
+ /* Get new delay */
+ bsDelay = CConcealment_GetDelay(pConcealData);
+
+ {
+ SBR_ERROR sbrErr = SBRDEC_OK;
+
+ /* set SBR bitstream delay */
+ sbrErr = sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, bsDelay);
+
+ switch (sbrErr) {
+ case SBRDEC_OK:
+ case SBRDEC_NOT_INITIALIZED:
+ if (self != NULL) {
+ /* save the param value and set later
+ (when SBR has been initialized) */
+ self->sbrParams.bsDelay = bsDelay;
+ }
+ break;
+ default:
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ goto bail;
+ }
+ }
+
+ errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, bsDelay);
+ if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
+ goto bail;
+ }
+
+ if (errorStatus == AAC_DEC_OK) {
+ PCMDMX_ERROR err = pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, bsDelay);
+ switch (err) {
+ case PCMDMX_INVALID_HANDLE:
+ errorStatus = AAC_DEC_INVALID_HANDLE;
+ break;
+ case PCMDMX_OK:
+ break;
+ default:
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ goto bail;
+ }
+ }
+
+bail:
+ if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
+ /* Revert to the initial state */
+ CConcealment_SetParams(
+ pConcealData, (int)backupMethod, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED);
+ /* Revert SBR bitstream delay */
+ sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, backupDelay);
+ /* Revert DRC bitstream delay */
+ aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, backupDelay);
+ /* Revert PCM mixdown bitstream delay */
+ pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, backupDelay);
+ }
+
+ return errorStatus;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_SetParam(
+ const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */
+ const AACDEC_PARAM param, /*!< Parameter to set */
+ const INT value) /*!< Parameter valued */
+{
+ AAC_DECODER_ERROR errorStatus = AAC_DEC_OK;
+ HANDLE_TRANSPORTDEC hTpDec = NULL;
+ TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK;
+ HANDLE_AAC_DRC hDrcInfo = NULL;
+ HANDLE_PCM_DOWNMIX hPcmDmx = NULL;
+ PCMDMX_ERROR dmxErr = PCMDMX_OK;
+ TDLimiterPtr hPcmTdl = NULL;
+ DRC_DEC_ERROR uniDrcErr = DRC_DEC_OK;
+
+ /* check decoder handle */
+ if (self != NULL) {
+ hTpDec = self->hInput;
+ hDrcInfo = self->hDrcInfo;
+ hPcmDmx = self->hPcmUtils;
+ hPcmTdl = self->hLimiter;
+ } else {
+ errorStatus = AAC_DEC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* configure the subsystems */
+ switch (param) {
+ case AAC_PCM_MIN_OUTPUT_CHANNELS:
+ if (value < -1 || value > (8)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ dmxErr = pcmDmx_SetParam(hPcmDmx, MIN_NUMBER_OF_OUTPUT_CHANNELS, value);
+ break;
+
+ case AAC_PCM_MAX_OUTPUT_CHANNELS:
+ if (value < -1 || value > (8)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ dmxErr = pcmDmx_SetParam(hPcmDmx, MAX_NUMBER_OF_OUTPUT_CHANNELS, value);
+
+ if (dmxErr != PCMDMX_OK) {
+ goto bail;
+ }
+ errorStatus =
+ aacDecoder_drcSetParam(hDrcInfo, MAX_OUTPUT_CHANNELS, value);
+ if (value > 0) {
+ uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder,
+ DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED,
+ (FIXP_DBL)value);
+ }
+ break;
+
+ case AAC_PCM_DUAL_CHANNEL_OUTPUT_MODE:
+ dmxErr = pcmDmx_SetParam(hPcmDmx, DMX_DUAL_CHANNEL_MODE, value);
+ break;
+
+ case AAC_PCM_LIMITER_ENABLE:
+ if (value < -2 || value > 1) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ self->limiterEnableUser = value;
+ break;
+
+ case AAC_PCM_LIMITER_ATTACK_TIME:
+ if (value <= 0) { /* module function converts value to unsigned */
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ switch (pcmLimiter_SetAttack(hPcmTdl, value)) {
+ case TDLIMIT_OK:
+ break;
+ case TDLIMIT_INVALID_HANDLE:
+ return AAC_DEC_INVALID_HANDLE;
+ case TDLIMIT_INVALID_PARAMETER:
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ break;
+
+ case AAC_PCM_LIMITER_RELEAS_TIME:
+ if (value <= 0) { /* module function converts value to unsigned */
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ switch (pcmLimiter_SetRelease(hPcmTdl, value)) {
+ case TDLIMIT_OK:
+ break;
+ case TDLIMIT_INVALID_HANDLE:
+ return AAC_DEC_INVALID_HANDLE;
+ case TDLIMIT_INVALID_PARAMETER:
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ break;
+
+ case AAC_METADATA_PROFILE: {
+ DMX_PROFILE_TYPE dmxProfile;
+ INT mdExpiry = -1; /* in ms (-1: don't change) */
+
+ switch ((AAC_MD_PROFILE)value) {
+ case AAC_MD_PROFILE_MPEG_STANDARD:
+ dmxProfile = DMX_PRFL_STANDARD;
+ break;
+ case AAC_MD_PROFILE_MPEG_LEGACY:
+ dmxProfile = DMX_PRFL_MATRIX_MIX;
+ break;
+ case AAC_MD_PROFILE_MPEG_LEGACY_PRIO:
+ dmxProfile = DMX_PRFL_FORCE_MATRIX_MIX;
+ break;
+ case AAC_MD_PROFILE_ARIB_JAPAN:
+ dmxProfile = DMX_PRFL_ARIB_JAPAN;
+ mdExpiry = 550; /* ms */
+ break;
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ dmxErr = pcmDmx_SetParam(hPcmDmx, DMX_PROFILE_SETTING, (INT)dmxProfile);
+ if (dmxErr != PCMDMX_OK) {
+ goto bail;
+ }
+ if ((self != NULL) && (mdExpiry >= 0)) {
+ self->metadataExpiry = mdExpiry;
+ /* Determine the corresponding number of frames and configure all
+ * related modules. */
+ aacDecoder_setMetadataExpiry(self, mdExpiry);
+ }
+ } break;
+
+ case AAC_METADATA_EXPIRY_TIME:
+ if (value < 0) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self != NULL) {
+ self->metadataExpiry = value;
+ /* Determine the corresponding number of frames and configure all
+ * related modules. */
+ aacDecoder_setMetadataExpiry(self, value);
+ }
+ break;
+
+ case AAC_PCM_OUTPUT_CHANNEL_MAPPING:
+ if (value < 0 || value > 1) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ /* CAUTION: The given value must be inverted to match the logic! */
+ FDK_chMapDescr_setPassThrough(&self->mapDescr, !value);
+ break;
+
+ case AAC_QMF_LOWPOWER:
+ if (value < -1 || value > 1) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+
+ /**
+ * Set QMF mode (might be overriden)
+ * 0:HQ (complex)
+ * 1:LP (partially complex)
+ */
+ self->qmfModeUser = (QMF_MODE)value;
+ break;
+
+ case AAC_DRC_ATTENUATION_FACTOR:
+ /* DRC compression factor (where 0 is no and 127 is max compression) */
+ errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_CUT_SCALE, value);
+ break;
+
+ case AAC_DRC_BOOST_FACTOR:
+ /* DRC boost factor (where 0 is no and 127 is max boost) */
+ errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BOOST_SCALE, value);
+ break;
+
+ case AAC_DRC_REFERENCE_LEVEL:
+ if ((value >= 0) &&
+ ((value < 40) || (value > 127))) /* allowed range: -10 to -31.75 dB */
+ return AAC_DEC_SET_PARAM_FAIL;
+ /* DRC target reference level quantized in 0.25dB steps using values
+ [40..127]. Negative values switch off loudness normalisation. Negative
+ values also switch off MPEG-4 DRC, while MPEG-D DRC can be separately
+ switched on/off with AAC_UNIDRC_SET_EFFECT */
+ errorStatus = aacDecoder_drcSetParam(hDrcInfo, TARGET_REF_LEVEL, value);
+ uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder,
+ DRC_DEC_LOUDNESS_NORMALIZATION_ON,
+ (FIXP_DBL)(value >= 0));
+ /* set target loudness also for MPEG-D DRC */
+ self->defaultTargetLoudness = (SCHAR)value;
+ break;
+
+ case AAC_DRC_HEAVY_COMPRESSION:
+ /* Don't need to overwrite cut/boost values */
+ errorStatus =
+ aacDecoder_drcSetParam(hDrcInfo, APPLY_HEAVY_COMPRESSION, value);
+ break;
+
+ case AAC_DRC_DEFAULT_PRESENTATION_MODE:
+ /* DRC default presentation mode */
+ errorStatus =
+ aacDecoder_drcSetParam(hDrcInfo, DEFAULT_PRESENTATION_MODE, value);
+ break;
+
+ case AAC_DRC_ENC_TARGET_LEVEL:
+ /* Encoder target level for light (i.e. not heavy) compression:
+ Target reference level assumed at encoder for deriving limiting gains
+ */
+ errorStatus =
+ aacDecoder_drcSetParam(hDrcInfo, ENCODER_TARGET_LEVEL, value);
+ break;
+
+ case AAC_UNIDRC_SET_EFFECT:
+ if ((value < -1) || (value > 6)) return AAC_DEC_SET_PARAM_FAIL;
+ uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_EFFECT_TYPE,
+ (FIXP_DBL)value);
+ break;
+ case AAC_TPDEC_CLEAR_BUFFER:
+ errTp = transportDec_SetParam(hTpDec, TPDEC_PARAM_RESET, 1);
+ self->streamInfo.numLostAccessUnits = 0;
+ self->streamInfo.numBadBytes = 0;
+ self->streamInfo.numTotalBytes = 0;
+ /* aacDecoder_SignalInterruption(self); */
+ break;
+ case AAC_CONCEAL_METHOD:
+ /* Changing the concealment method can introduce additional bitstream
+ delay. And that in turn affects sub libraries and modules which makes
+ the whole thing quite complex. So the complete changing routine is
+ packed into a helper function which keeps all modules and libs in a
+ consistent state even in the case an error occures. */
+ errorStatus = setConcealMethod(self, value);
+ if (errorStatus == AAC_DEC_OK) {
+ self->concealMethodUser = (CConcealmentMethod)value;
+ }
+ break;
+
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ } /* switch(param) */
+
+bail:
+
+ if (errorStatus == AAC_DEC_OK) {
+ /* Check error code returned by DMX module library: */
+ switch (dmxErr) {
+ case PCMDMX_OK:
+ break;
+ case PCMDMX_INVALID_HANDLE:
+ errorStatus = AAC_DEC_INVALID_HANDLE;
+ break;
+ default:
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+
+ if (errTp != TRANSPORTDEC_OK && errorStatus == AAC_DEC_OK) {
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ }
+
+ if (errorStatus == AAC_DEC_OK) {
+ /* Check error code returned by MPEG-D DRC decoder library: */
+ switch (uniDrcErr) {
+ case 0:
+ break;
+ case -9998:
+ errorStatus = AAC_DEC_INVALID_HANDLE;
+ break;
+ default:
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ break;
+ }
+ }
+
+ return (errorStatus);
+}
+LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt,
+ UINT nrOfLayers) {
+ AAC_DECODER_INSTANCE *aacDec = NULL;
+ HANDLE_TRANSPORTDEC pIn;
+ int err = 0;
+ int stereoConfigIndex = -1;
+
+ UINT nrOfLayers_min = fMin(nrOfLayers, (UINT)1);
+
+ /* Allocate transport layer struct. */
+ pIn = transportDec_Open(transportFmt, TP_FLAG_MPEG4, nrOfLayers_min);
+ if (pIn == NULL) {
+ return NULL;
+ }
+
+ transportDec_SetParam(pIn, TPDEC_PARAM_IGNORE_BUFFERFULLNESS, 1);
+
+ /* Allocate AAC decoder core struct. */
+ aacDec = CAacDecoder_Open(transportFmt);
+
+ if (aacDec == NULL) {
+ transportDec_Close(&pIn);
+ goto bail;
+ }
+ aacDec->hInput = pIn;
+
+ aacDec->nrOfLayers = nrOfLayers_min;
+
+ /* Setup channel mapping descriptor. */
+ FDK_chMapDescr_init(&aacDec->mapDescr, NULL, 0, 0);
+
+ /* Register Config Update callback. */
+ transportDec_RegisterAscCallback(pIn, aacDecoder_ConfigCallback,
+ (void *)aacDec);
+
+ /* Register Free Memory callback. */
+ transportDec_RegisterFreeMemCallback(pIn, aacDecoder_FreeMemCallback,
+ (void *)aacDec);
+
+ /* Register config switch control callback. */
+ transportDec_RegisterCtrlCFGChangeCallback(
+ pIn, aacDecoder_CtrlCFGChangeCallback, (void *)aacDec);
+
+ FDKmemclear(&aacDec->qmfDomain, sizeof(FDK_QMF_DOMAIN));
+ /* open SBR decoder */
+ if (SBRDEC_OK != sbrDecoder_Open(&aacDec->hSbrDecoder, &aacDec->qmfDomain)) {
+ err = -1;
+ goto bail;
+ }
+ aacDec->qmfModeUser = NOT_DEFINED;
+ transportDec_RegisterSbrCallback(aacDec->hInput, aacDecoder_SbrCallback,
+ (void *)aacDec->hSbrDecoder);
+
+ if (mpegSurroundDecoder_Open(
+ (CMpegSurroundDecoder **)&aacDec->pMpegSurroundDecoder,
+ stereoConfigIndex, &aacDec->qmfDomain)) {
+ err = -1;
+ goto bail;
+ }
+ /* Set MPEG Surround defaults */
+ aacDec->mpsEnableUser = 0;
+ aacDec->mpsEnableCurr = 0;
+ aacDec->mpsApplicable = 0;
+ aacDec->mpsOutputMode = (SCHAR)SACDEC_OUT_MODE_NORMAL;
+ transportDec_RegisterSscCallback(pIn, aacDecoder_SscCallback, (void *)aacDec);
+
+ {
+ if (FDK_drcDec_Open(&(aacDec->hUniDrcDecoder), DRC_DEC_ALL) != 0) {
+ err = -1;
+ goto bail;
+ }
+ }
+
+ transportDec_RegisterUniDrcConfigCallback(pIn, aacDecoder_UniDrcCallback,
+ (void *)aacDec,
+ aacDec->loudnessInfoSetPosition);
+ aacDec->defaultTargetLoudness = (SCHAR)96;
+
+ pcmDmx_Open(&aacDec->hPcmUtils);
+ if (aacDec->hPcmUtils == NULL) {
+ err = -1;
+ goto bail;
+ }
+
+ aacDec->hLimiter =
+ pcmLimiter_Create(TDL_ATTACK_DEFAULT_MS, TDL_RELEASE_DEFAULT_MS,
+ (FIXP_DBL)MAXVAL_DBL, (8), 96000);
+ if (NULL == aacDec->hLimiter) {
+ err = -1;
+ goto bail;
+ }
+ aacDec->limiterEnableUser = (UCHAR)-1;
+ aacDec->limiterEnableCurr = 0;
+
+ /* Assure that all modules have same delay */
+ if (setConcealMethod(aacDec,
+ CConcealment_GetMethod(&aacDec->concealCommonData))) {
+ err = -1;
+ goto bail;
+ }
+
+bail:
+ if (err == -1) {
+ aacDecoder_Close(aacDec);
+ aacDec = NULL;
+ }
+ return aacDec;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self,
+ UCHAR *pBuffer[],
+ const UINT bufferSize[],
+ UINT *pBytesValid) {
+ TRANSPORTDEC_ERROR tpErr;
+ /* loop counter for layers; if not TT_MP4_RAWPACKETS used as index for only
+ available layer */
+ INT layer = 0;
+ INT nrOfLayers = self->nrOfLayers;
+
+ {
+ for (layer = 0; layer < nrOfLayers; layer++) {
+ {
+ tpErr = transportDec_FillData(self->hInput, pBuffer[layer],
+ bufferSize[layer], &pBytesValid[layer],
+ layer);
+ if (tpErr != TRANSPORTDEC_OK) {
+ return AAC_DEC_UNKNOWN; /* Must be an internal error */
+ }
+ }
+ }
+ }
+
+ return AAC_DEC_OK;
+}
+
+static void aacDecoder_SignalInterruption(HANDLE_AACDECODER self) {
+ CAacDecoder_SignalInterruption(self);
+
+ if (self->hSbrDecoder != NULL) {
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_BS_INTERRUPTION, 1);
+ }
+ if (self->mpsEnableUser) {
+ mpegSurroundDecoder_SetParam(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
+ SACDEC_BS_INTERRUPTION, 1);
+ }
+}
+
+static void aacDecoder_UpdateBitStreamCounters(CStreamInfo *pSi,
+ HANDLE_FDK_BITSTREAM hBs,
+ INT nBits,
+ AAC_DECODER_ERROR ErrorStatus) {
+ /* calculate bit difference (amount of bits moved forward) */
+ nBits = nBits - (INT)FDKgetValidBits(hBs);
+
+ /* Note: The amount of bits consumed might become negative when parsing a
+ bit stream with several sub frames, and we find out at the last sub frame
+ that the total frame length does not match the sum of sub frame length.
+ If this happens, the transport decoder might want to rewind to the supposed
+ ending of the transport frame, and this position might be before the last
+ access unit beginning. */
+
+ /* Calc bitrate. */
+ if (pSi->frameSize > 0) {
+ /* bitRate = nBits * sampleRate / frameSize */
+ int ratio_e = 0;
+ FIXP_DBL ratio_m = fDivNorm(pSi->sampleRate, pSi->frameSize, &ratio_e);
+ pSi->bitRate = (INT)fMultNorm(nBits, DFRACT_BITS - 1, ratio_m, ratio_e,
+ DFRACT_BITS - 1);
+ }
+
+ /* bit/byte counters */
+ {
+ INT nBytes;
+
+ nBytes = nBits >> 3;
+ pSi->numTotalBytes += nBytes;
+ if (IS_OUTPUT_VALID(ErrorStatus)) {
+ pSi->numTotalAccessUnits++;
+ }
+ if (IS_DECODE_ERROR(ErrorStatus)) {
+ pSi->numBadBytes += nBytes;
+ pSi->numBadAccessUnits++;
+ }
+ }
+}
+
+static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) {
+ INT n;
+
+ transportDec_GetMissingAccessUnitCount(&n, self->hInput);
+
+ return n;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR
+aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
+ const INT timeDataSize_extern, const UINT flags) {
+ AAC_DECODER_ERROR ErrorStatus;
+ INT layer;
+ INT nBits;
+ HANDLE_FDK_BITSTREAM hBs;
+ int fTpInterruption = 0; /* Transport originated interruption detection. */
+ int fTpConceal = 0; /* Transport originated concealment. */
+ INT_PCM *pTimeData = NULL;
+ INT timeDataSize = 0;
+ UINT accessUnit = 0;
+ UINT numAccessUnits = 1;
+ UINT numPrerollAU = 0;
+ int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */
+ int applyCrossfade = 1; /* flag indicates if flushing was possible */
+ FIXP_PCM *pTimeDataFixpPcm; /* Signal buffer for decoding process before PCM
+ processing */
+ INT timeDataFixpPcmSize;
+ PCM_DEC *pTimeDataPcmPost; /* Signal buffer for PCM post-processing */
+ INT timeDataPcmPostSize;
+
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+
+ pTimeData = self->pcmOutputBuffer;
+ timeDataSize = sizeof(self->pcmOutputBuffer) / sizeof(*self->pcmOutputBuffer);
+
+ if (flags & AACDEC_INTR) {
+ self->streamInfo.numLostAccessUnits = 0;
+ }
+ hBs = transportDec_GetBitstream(self->hInput, 0);
+
+ /* Get current bits position for bitrate calculation. */
+ nBits = FDKgetValidBits(hBs);
+
+ if (flags & AACDEC_CLRHIST) {
+ if (self->flags[0] & AC_USAC) {
+ /* 1) store AudioSpecificConfig always in AudioSpecificConfig_Parse() */
+ /* 2) free memory of dynamic allocated data */
+ CSAudioSpecificConfig asc;
+ transportDec_GetAsc(self->hInput, 0, &asc);
+ aacDecoder_FreeMemCallback(self, &asc);
+ self->streamInfo.numChannels = 0;
+ /* 3) restore AudioSpecificConfig */
+ transportDec_OutOfBandConfig(self->hInput, asc.config,
+ (asc.configBits + 7) >> 3, 0);
+ }
+ }
+
+ if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) ||
+ (self->flushStatus == AACDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
+ (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) ||
+ (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND))) {
+ TRANSPORTDEC_ERROR err;
+
+ for (layer = 0; layer < self->nrOfLayers; layer++) {
+ err = transportDec_ReadAccessUnit(self->hInput, layer);
+ if (err != TRANSPORTDEC_OK) {
+ switch (err) {
+ case TRANSPORTDEC_NOT_ENOUGH_BITS:
+ ErrorStatus = AAC_DEC_NOT_ENOUGH_BITS;
+ goto bail;
+ case TRANSPORTDEC_SYNC_ERROR:
+ self->streamInfo.numLostAccessUnits =
+ aacDecoder_EstimateNumberOfLostFrames(self);
+ fTpInterruption = 1;
+ break;
+ case TRANSPORTDEC_NEED_TO_RESTART:
+ ErrorStatus = AAC_DEC_NEED_TO_RESTART;
+ goto bail;
+ case TRANSPORTDEC_CRC_ERROR:
+ fTpConceal = 1;
+ break;
+ case TRANSPORTDEC_UNSUPPORTED_FORMAT:
+ ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
+ goto bail;
+ default:
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ goto bail;
+ }
+ }
+ }
+ } else {
+ if (self->streamInfo.numLostAccessUnits > 0) {
+ self->streamInfo.numLostAccessUnits--;
+ }
+ }
+
+ self->frameOK = 1;
+
+ UINT prerollAUOffset[AACDEC_MAX_NUM_PREROLL_AU];
+ UINT prerollAULength[AACDEC_MAX_NUM_PREROLL_AU];
+ for (int i = 0; i < AACDEC_MAX_NUM_PREROLL_AU + 1; i++)
+ self->prerollAULength[i] = 0;
+
+ INT auStartAnchor;
+ HANDLE_FDK_BITSTREAM hBsAu;
+
+ /* Process preroll frames and current frame */
+ do {
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) &&
+ (self->flushStatus != AACDEC_RSV60_CFG_CHANGE_ATSC_FLUSH_ON) &&
+ (accessUnit == 0) &&
+ (self->hasAudioPreRoll ||
+ (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) &&
+ !fTpInterruption &&
+ !fTpConceal /* Bit stream pointer needs to be at the beginning of a
+ (valid) AU. */
+ ) {
+ ErrorStatus = CAacDecoder_PreRollExtensionPayloadParse(
+ self, &numPrerollAU, prerollAUOffset, prerollAULength);
+
+ if (ErrorStatus != AAC_DEC_OK) {
+ switch (ErrorStatus) {
+ case AAC_DEC_NOT_ENOUGH_BITS:
+ goto bail;
+ case AAC_DEC_PARSE_ERROR:
+ self->frameOK = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ numAccessUnits += numPrerollAU;
+ }
+
+ hBsAu = transportDec_GetBitstream(self->hInput, 0);
+ auStartAnchor = (INT)FDKgetValidBits(hBsAu);
+
+ self->accessUnit = accessUnit;
+ if (accessUnit < numPrerollAU) {
+ FDKpushFor(hBsAu, prerollAUOffset[accessUnit]);
+ }
+
+ /* Signal bit stream interruption to other modules if required. */
+ if (fTpInterruption || (flags & AACDEC_INTR)) {
+ aacDecoder_SignalInterruption(self);
+ if (!(flags & AACDEC_INTR)) {
+ ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR;
+ goto bail;
+ }
+ }
+
+ /* Clearing core data will be done in CAacDecoder_DecodeFrame() below.
+ Tell other modules to clear states if required. */
+ if (flags & AACDEC_CLRHIST) {
+ if (!(self->flags[0] & AC_USAC)) {
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_CLEAR_HISTORY, 1);
+ mpegSurroundDecoder_SetParam(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
+ SACDEC_CLEAR_HISTORY, 1);
+ if (FDK_QmfDomain_ClearPersistentMemory(&self->qmfDomain) != 0) {
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ goto bail;
+ }
+ }
+ }
+
+ /* Empty bit buffer in case of flush request. */
+ if (flags & AACDEC_FLUSH && !(flags & AACDEC_CONCEAL)) {
+ if (!self->flushStatus) {
+ transportDec_SetParam(self->hInput, TPDEC_PARAM_RESET, 1);
+ self->streamInfo.numLostAccessUnits = 0;
+ self->streamInfo.numBadBytes = 0;
+ self->streamInfo.numTotalBytes = 0;
+ }
+ }
+ /* Reset the output delay field. The modules will add their figures one
+ * after another. */
+ self->streamInfo.outputDelay = 0;
+
+ if (self->limiterEnableUser == (UCHAR)-2) {
+ /* Enable limiter only for RSVD60. */
+ self->limiterEnableCurr = (self->flags[0] & AC_RSV603DA) ? 1 : 0;
+ } else if (self->limiterEnableUser == (UCHAR)-1) {
+ /* Enable limiter for all non-lowdelay AOT's. */
+ self->limiterEnableCurr = (self->flags[0] & (AC_LD | AC_ELD)) ? 0 : 1;
+ } else {
+ /* Use limiter configuration as requested. */
+ self->limiterEnableCurr = self->limiterEnableUser;
+ }
+ /* reset limiter gain on a per frame basis */
+ self->extGain[0] = FL2FXCONST_DBL(1.0f / (float)(1 << TDL_GAIN_SCALING));
+
+ pTimeDataFixpPcm = pTimeData;
+ timeDataFixpPcmSize = timeDataSize;
+
+ ErrorStatus = CAacDecoder_DecodeFrame(
+ self,
+ flags | (fTpConceal ? AACDEC_CONCEAL : 0) |
+ ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
+ : 0),
+ pTimeDataFixpPcm + 0, timeDataFixpPcmSize,
+ self->streamInfo.aacSamplesPerFrame + 0);
+
+ /* if flushing for USAC DASH IPF was not possible go on with decoding
+ * preroll */
+ if ((self->flags[0] & AC_USAC) &&
+ (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) &&
+ !(flags & AACDEC_CONCEAL) && (ErrorStatus != AAC_DEC_OK)) {
+ applyCrossfade = 0;
+ } else /* USAC DASH IPF flushing possible begin */
+ {
+ if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) || fTpConceal ||
+ self->flushStatus) &&
+ (!(IS_OUTPUT_VALID(ErrorStatus)) || !(accessUnit < numPrerollAU))) {
+ TRANSPORTDEC_ERROR tpErr;
+ tpErr = transportDec_EndAccessUnit(self->hInput);
+ if (tpErr != TRANSPORTDEC_OK) {
+ self->frameOK = 0;
+ }
+ } else { /* while preroll processing later possibly an error in the
+ renderer part occurrs */
+ if (IS_OUTPUT_VALID(ErrorStatus)) {
+ fEndAuNotAdjusted = 1;
+ }
+ }
+
+ /* If the current pTimeDataFixpPcm does not contain a valid signal, there
+ * nothing else we can do, so bail. */
+ if (!IS_OUTPUT_VALID(ErrorStatus)) {
+ goto bail;
+ }
+
+ {
+ self->streamInfo.sampleRate = self->streamInfo.aacSampleRate;
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame;
+ }
+
+ self->streamInfo.numChannels = self->streamInfo.aacNumChannels;
+
+ {
+ FDK_Delay_Apply(&self->usacResidualDelay,
+ pTimeDataFixpPcm +
+ 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0,
+ self->streamInfo.frameSize, 0);
+ }
+
+ /* Setting of internal MPS state; may be reset in CAacDecoder_SyncQmfMode
+ if decoder is unable to decode with user defined qmfMode */
+ if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_ELD))) {
+ self->mpsEnableCurr =
+ (self->mpsEnableUser &&
+ isSupportedMpsConfig(self->streamInfo.aot,
+ self->streamInfo.numChannels,
+ (self->flags[0] & AC_MPS_PRESENT) ? 1 : 0));
+ }
+
+ if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig &&
+ self->mpsEnableCurr) {
+ /* if not done yet, allocate full MPEG Surround decoder instance */
+ if (mpegSurroundDecoder_IsFullMpegSurroundDecoderInstanceAvailable(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) ==
+ SAC_INSTANCE_NOT_FULL_AVAILABLE) {
+ if (mpegSurroundDecoder_Open(
+ (CMpegSurroundDecoder **)&self->pMpegSurroundDecoder, -1,
+ &self->qmfDomain)) {
+ return AAC_DEC_OUT_OF_MEMORY;
+ }
+ }
+ }
+
+ CAacDecoder_SyncQmfMode(self);
+
+ if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig &&
+ self->mpsEnableCurr) {
+ SAC_INPUT_CONFIG sac_interface = (self->sbrEnabled && self->hSbrDecoder)
+ ? SAC_INTERFACE_QMF
+ : SAC_INTERFACE_TIME;
+ /* needs to be done before first SBR apply. */
+ mpegSurroundDecoder_ConfigureQmfDomain(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface,
+ (UINT)self->streamInfo.aacSampleRate, self->streamInfo.aot);
+ if (self->qmfDomain.globalConf.nBandsAnalysis_requested > 0) {
+ self->qmfDomain.globalConf.nQmfTimeSlots_requested =
+ self->streamInfo.aacSamplesPerFrame /
+ self->qmfDomain.globalConf.nBandsAnalysis_requested;
+ } else {
+ self->qmfDomain.globalConf.nQmfTimeSlots_requested = 0;
+ }
+ }
+
+ self->qmfDomain.globalConf.TDinput = pTimeData;
+
+ switch (FDK_QmfDomain_Configure(&self->qmfDomain)) {
+ default:
+ case QMF_DOMAIN_INIT_ERROR:
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ goto bail;
+ case QMF_DOMAIN_OUT_OF_MEMORY:
+ ErrorStatus = AAC_DEC_OUT_OF_MEMORY;
+ goto bail;
+ case QMF_DOMAIN_OK:
+ break;
+ }
+
+ /* sbr decoder */
+
+ if ((ErrorStatus != AAC_DEC_OK) || (flags & AACDEC_CONCEAL) ||
+ self->pAacDecoderStaticChannelInfo[0]->concealmentInfo.concealState >
+ ConcealState_FadeIn) {
+ self->frameOK = 0; /* if an error has occured do concealment in the SBR
+ decoder too */
+ }
+
+ if (self->sbrEnabled && (!(self->flags[0] & AC_USAC_SCFGI3))) {
+ SBR_ERROR sbrError = SBRDEC_OK;
+ int chIdx, numCoreChannel = self->streamInfo.numChannels;
+
+ /* set params */
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY,
+ self->sbrParams.bsDelay);
+ sbrDecoder_SetParam(
+ self->hSbrDecoder, SBR_FLUSH_DATA,
+ (flags & AACDEC_FLUSH) |
+ ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
+ : 0));
+
+ if (self->streamInfo.aot == AOT_ER_AAC_ELD) {
+ /* Configure QMF */
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_LD_QMF_TIME_ALIGN,
+ (self->flags[0] & AC_MPS_PRESENT) ? 1 : 0);
+ }
+
+ {
+ PCMDMX_ERROR dmxErr;
+ INT maxOutCh = 0;
+
+ dmxErr = pcmDmx_GetParam(self->hPcmUtils,
+ MAX_NUMBER_OF_OUTPUT_CHANNELS, &maxOutCh);
+ if ((dmxErr == PCMDMX_OK) && (maxOutCh == 1)) {
+ /* Disable PS processing if we have to create a mono output signal.
+ */
+ self->psPossible = 0;
+ }
+ }
+
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF,
+ (self->mpsEnableCurr) ? 2 : 0);
+
+ INT_PCM *input;
+ input = (INT_PCM *)self->workBufferCore2;
+ FDKmemcpy(input, pTimeData,
+ sizeof(INT_PCM) * (self->streamInfo.numChannels) *
+ (self->streamInfo.frameSize));
+
+ /* apply SBR processing */
+ sbrError = sbrDecoder_Apply(self->hSbrDecoder, input, pTimeData,
+ timeDataSize, &self->streamInfo.numChannels,
+ &self->streamInfo.sampleRate,
+ &self->mapDescr, self->chMapIndex,
+ self->frameOK, &self->psPossible);
+
+ if (sbrError == SBRDEC_OK) {
+ /* Update data in streaminfo structure. Assume that the SBR upsampling
+ factor is either 1, 2, 8/3 or 4. Maximum upsampling factor is 4
+ (CELP+SBR or USAC 4:1 SBR) */
+ self->flags[0] |= AC_SBR_PRESENT;
+ if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) {
+ if (self->streamInfo.aacSampleRate >> 2 ==
+ self->streamInfo.sampleRate) {
+ self->streamInfo.frameSize =
+ self->streamInfo.aacSamplesPerFrame >> 2;
+ self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 2;
+ } else if (self->streamInfo.aacSampleRate >> 1 ==
+ self->streamInfo.sampleRate) {
+ self->streamInfo.frameSize =
+ self->streamInfo.aacSamplesPerFrame >> 1;
+ self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 1;
+ } else if (self->streamInfo.aacSampleRate << 1 ==
+ self->streamInfo.sampleRate) {
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
+ << 1;
+ self->streamInfo.outputDelay = self->streamInfo.outputDelay << 1;
+ } else if (self->streamInfo.aacSampleRate << 2 ==
+ self->streamInfo.sampleRate) {
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
+ << 2;
+ self->streamInfo.outputDelay = self->streamInfo.outputDelay << 2;
+ } else if (self->streamInfo.frameSize == 768) {
+ self->streamInfo.frameSize =
+ (self->streamInfo.aacSamplesPerFrame << 3) / 3;
+ self->streamInfo.outputDelay =
+ (self->streamInfo.outputDelay << 3) / 3;
+ } else {
+ ErrorStatus = AAC_DEC_SET_PARAM_FAIL;
+ goto bail;
+ }
+ } else {
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame;
+ }
+ self->streamInfo.outputDelay +=
+ sbrDecoder_GetDelay(self->hSbrDecoder);
+
+ if (self->psPossible) {
+ self->flags[0] |= AC_PS_PRESENT;
+ }
+ for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels;
+ chIdx += 1) {
+ self->channelType[chIdx] = ACT_FRONT;
+ self->channelIndices[chIdx] = chIdx;
+ }
+ }
+ if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ goto bail;
+ }
+ }
+
+ if (self->mpsEnableCurr) {
+ int err, sac_interface, nChannels, frameSize;
+
+ nChannels = self->streamInfo.numChannels;
+ frameSize = self->streamInfo.frameSize;
+ sac_interface = SAC_INTERFACE_TIME;
+
+ if (self->sbrEnabled && self->hSbrDecoder)
+ sac_interface = SAC_INTERFACE_QMF;
+ if (self->streamInfo.aot == AOT_USAC) {
+ if (self->flags[0] & AC_USAC_SCFGI3) {
+ sac_interface = SAC_INTERFACE_TIME;
+ }
+ }
+ err = mpegSurroundDecoder_SetParam(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
+ SACDEC_INTERFACE, sac_interface);
+
+ if (err == 0) {
+ err = mpegSurroundDecoder_Apply(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
+ (INT_PCM *)self->workBufferCore2, pTimeData, timeDataSize,
+ self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize,
+ self->streamInfo.sampleRate, self->streamInfo.aot,
+ self->channelType, self->channelIndices, &self->mapDescr);
+ }
+
+ if (err == MPS_OUTPUT_BUFFER_TOO_SMALL) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ goto bail;
+ }
+ if (err == 0) {
+ /* Update output parameter */
+ self->streamInfo.numChannels = nChannels;
+ self->streamInfo.frameSize = frameSize;
+ self->streamInfo.outputDelay += mpegSurroundDecoder_GetDelay(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder);
+ /* Save current parameter for possible concealment of next frame */
+ self->mpsOutChannelsLast = nChannels;
+ self->mpsFrameSizeLast = frameSize;
+ } else if ((self->mpsOutChannelsLast > 0) &&
+ (self->mpsFrameSizeLast > 0)) {
+ /* Restore parameters of last frame ... */
+ self->streamInfo.numChannels = self->mpsOutChannelsLast;
+ self->streamInfo.frameSize = self->mpsFrameSizeLast;
+ /* ... and clear output buffer so that potentially corrupted data does
+ * not reach the framework. */
+ FDKmemclear(pTimeData, self->mpsOutChannelsLast *
+ self->mpsFrameSizeLast * sizeof(INT_PCM));
+ /* Additionally proclaim that this frame had errors during decoding.
+ */
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ } else {
+ ErrorStatus = AAC_DEC_UNKNOWN; /* no output */
+ }
+ }
+
+ /* SBR decoder for Unified Stereo Config (stereoConfigIndex == 3) */
+
+ if (self->sbrEnabled && (self->flags[0] & AC_USAC_SCFGI3)) {
+ SBR_ERROR sbrError = SBRDEC_OK;
+
+ /* set params */
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY,
+ self->sbrParams.bsDelay);
+
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1);
+
+ /* apply SBR processing */
+ sbrError = sbrDecoder_Apply(self->hSbrDecoder, pTimeData, pTimeData,
+ timeDataSize, &self->streamInfo.numChannels,
+ &self->streamInfo.sampleRate,
+ &self->mapDescr, self->chMapIndex,
+ self->frameOK, &self->psPossible);
+
+ if (sbrError == SBRDEC_OK) {
+ /* Update data in streaminfo structure. Assume that the SBR upsampling
+ * factor is either 1,2 or 4 */
+ self->flags[0] |= AC_SBR_PRESENT;
+ if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) {
+ if (self->streamInfo.frameSize == 768) {
+ self->streamInfo.frameSize =
+ (self->streamInfo.aacSamplesPerFrame * 8) / 3;
+ } else if (self->streamInfo.aacSampleRate << 2 ==
+ self->streamInfo.sampleRate) {
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
+ << 2;
+ } else {
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
+ << 1;
+ }
+ }
+
+ self->flags[0] &= ~AC_PS_PRESENT;
+ }
+ if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ goto bail;
+ }
+ }
+
+ /* Use dedicated memory for PCM postprocessing */
+ pTimeDataPcmPost = self->pTimeData2;
+ timeDataPcmPostSize = self->timeData2Size;
+
+ {
+ const int size =
+ self->streamInfo.frameSize * self->streamInfo.numChannels;
+ FDK_ASSERT(timeDataPcmPostSize >= size);
+ for (int i = 0; i < size; i++) {
+ pTimeDataPcmPost[i] =
+ (PCM_DEC)FX_PCM2PCM_DEC(pTimeData[i]) >> PCM_OUT_HEADROOM;
+ }
+ }
+
+ {
+ if ((FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) &&
+ !(self->flags[0] & AC_RSV603DA)) {
+ /* Apply DRC gains*/
+ int ch, drcDelay = 0;
+ int needsDeinterleaving = 0;
+ FIXP_DBL *drcWorkBuffer = NULL;
+ FIXP_DBL channelGain[(8)];
+ int reverseInChannelMap[(8)];
+ int reverseOutChannelMap[(8)];
+ int numDrcOutChannels = FDK_drcDec_GetParam(
+ self->hUniDrcDecoder, DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED);
+ FDKmemclear(channelGain, sizeof(channelGain));
+ for (ch = 0; ch < (8); ch++) {
+ reverseInChannelMap[ch] = ch;
+ reverseOutChannelMap[ch] = ch;
+ }
+
+ /* If SBR and/or MPS is active, the DRC gains are aligned to the QMF
+ domain signal before the QMF synthesis. Therefore the DRC gains
+ need to be delayed by the QMF synthesis delay. */
+ if (self->sbrEnabled) drcDelay = 257;
+ if (self->mpsEnableCurr) drcDelay = 257;
+ /* Take into account concealment delay */
+ drcDelay += CConcealment_GetDelay(&self->concealCommonData) *
+ self->streamInfo.frameSize;
+
+ for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
+ UCHAR mapValue = FDK_chMapDescr_getMapValue(
+ &self->mapDescr, (UCHAR)ch, self->chMapIndex);
+ if (mapValue < (8)) reverseInChannelMap[mapValue] = ch;
+ }
+ for (ch = 0; ch < (int)numDrcOutChannels; ch++) {
+ UCHAR mapValue = FDK_chMapDescr_getMapValue(
+ &self->mapDescr, (UCHAR)ch, numDrcOutChannels);
+ if (mapValue < (8)) reverseOutChannelMap[mapValue] = ch;
+ }
+
+ /* The output of SBR and MPS is interleaved. Deinterleaving may be
+ * necessary for FDK_drcDec_ProcessTime, which accepts deinterleaved
+ * audio only. */
+ if ((self->streamInfo.numChannels > 1) &&
+ (0 || (self->sbrEnabled) || (self->mpsEnableCurr))) {
+ /* interleaving/deinterleaving is performed on upper part of
+ * pTimeDataPcmPost. Check if this buffer is large enough. */
+ if (timeDataPcmPostSize <
+ (INT)(2 * self->streamInfo.numChannels *
+ self->streamInfo.frameSize * sizeof(PCM_DEC))) {
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ goto bail;
+ }
+ needsDeinterleaving = 1;
+ drcWorkBuffer =
+ (FIXP_DBL *)pTimeDataPcmPost +
+ self->streamInfo.numChannels * self->streamInfo.frameSize;
+ FDK_deinterleave(
+ pTimeDataPcmPost, drcWorkBuffer, self->streamInfo.numChannels,
+ self->streamInfo.frameSize, self->streamInfo.frameSize);
+ } else {
+ drcWorkBuffer = (FIXP_DBL *)pTimeDataPcmPost;
+ }
+
+ /* prepare Loudness Normalisation gain */
+ FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_TARGET_LOUDNESS,
+ (INT)-self->defaultTargetLoudness *
+ FL2FXCONST_DBL(1.0f / (float)(1 << 9)));
+ FDK_drcDec_SetChannelGains(self->hUniDrcDecoder,
+ self->streamInfo.numChannels,
+ self->streamInfo.frameSize, channelGain,
+ drcWorkBuffer, self->streamInfo.frameSize);
+ FDK_drcDec_Preprocess(self->hUniDrcDecoder);
+
+ /* apply DRC1 gain sequence */
+ for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
+ FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay, DRC_DEC_DRC1,
+ ch, reverseInChannelMap[ch] - ch, 1,
+ drcWorkBuffer, self->streamInfo.frameSize);
+ }
+ /* apply downmix */
+ FDK_drcDec_ApplyDownmix(
+ self->hUniDrcDecoder, reverseInChannelMap, reverseOutChannelMap,
+ drcWorkBuffer,
+ &self->streamInfo.numChannels); /* self->streamInfo.numChannels
+ may change here */
+ /* apply DRC2/3 gain sequence */
+ for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
+ FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay,
+ DRC_DEC_DRC2_DRC3, ch,
+ reverseOutChannelMap[ch] - ch, 1,
+ drcWorkBuffer, self->streamInfo.frameSize);
+ }
+
+ if (needsDeinterleaving) {
+ FDK_interleave(
+ drcWorkBuffer, pTimeDataPcmPost, self->streamInfo.numChannels,
+ self->streamInfo.frameSize, self->streamInfo.frameSize);
+ }
+ }
+ }
+
+ if (self->streamInfo.extAot != AOT_AAC_SLS) {
+ INT pcmLimiterScale = 0;
+ PCMDMX_ERROR dmxErr = PCMDMX_OK;
+ if (flags & (AACDEC_INTR)) {
+ /* delete data from the past (e.g. mixdown coeficients) */
+ pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
+ }
+ if (flags & (AACDEC_CLRHIST)) {
+ if (!(self->flags[0] & AC_USAC)) {
+ /* delete data from the past (e.g. mixdown coeficients) */
+ pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
+ }
+ }
+
+ INT interleaved = 0;
+ interleaved |= (self->sbrEnabled) ? 1 : 0;
+ interleaved |= (self->mpsEnableCurr) ? 1 : 0;
+
+ /* do PCM post processing */
+ dmxErr = pcmDmx_ApplyFrame(
+ self->hPcmUtils, pTimeDataPcmPost, timeDataFixpPcmSize,
+ self->streamInfo.frameSize, &self->streamInfo.numChannels,
+ interleaved, self->channelType, self->channelIndices,
+ &self->mapDescr,
+ (self->limiterEnableCurr) ? &pcmLimiterScale : NULL);
+ if (dmxErr == PCMDMX_OUTPUT_BUFFER_TOO_SMALL) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ goto bail;
+ }
+ if ((ErrorStatus == AAC_DEC_OK) && (dmxErr == PCMDMX_INVALID_MODE)) {
+ /* 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. */
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ if (flags & AACDEC_CLRHIST) {
+ if (!(self->flags[0] & AC_USAC)) {
+ /* Delete the delayed signal. */
+ pcmLimiter_Reset(self->hLimiter);
+ }
+ }
+
+ if (self->limiterEnableCurr) {
+ /* use workBufferCore2 buffer for interleaving */
+ PCM_LIM *pInterleaveBuffer;
+ int blockLength = self->streamInfo.frameSize;
+
+ /* Set actual signal parameters */
+ pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels);
+ pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate);
+ pcmLimiterScale += PCM_OUT_HEADROOM;
+
+ if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
+ (self->mpsEnableCurr)) {
+ pInterleaveBuffer = (PCM_LIM *)pTimeDataPcmPost;
+ } else {
+ pInterleaveBuffer = (PCM_LIM *)pTimeData;
+ /* applyLimiter requests for interleaved data */
+ /* Interleave ouput buffer */
+ FDK_interleave(pTimeDataPcmPost, pInterleaveBuffer,
+ self->streamInfo.numChannels, blockLength,
+ self->streamInfo.frameSize);
+ }
+
+ pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData,
+ self->extGain, &pcmLimiterScale, 1,
+ self->extGainDelay, self->streamInfo.frameSize);
+
+ {
+ /* Announce the additional limiter output delay */
+ self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter);
+ }
+ } else {
+ /* If numChannels = 1 we do not need interleaving. The same applies if
+ SBR or MPS are used, since their output is interleaved already
+ (resampled or not) */
+ if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
+ (self->mpsEnableCurr)) {
+ scaleValuesSaturate(
+ pTimeData, pTimeDataPcmPost,
+ self->streamInfo.frameSize * self->streamInfo.numChannels,
+ PCM_OUT_HEADROOM);
+
+ } else {
+ scaleValuesSaturate(
+ (INT_PCM *)self->workBufferCore2, pTimeDataPcmPost,
+ self->streamInfo.frameSize * self->streamInfo.numChannels,
+ PCM_OUT_HEADROOM);
+ /* Interleave ouput buffer */
+ FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData,
+ self->streamInfo.numChannels,
+ self->streamInfo.frameSize,
+ self->streamInfo.frameSize);
+ }
+ }
+ } /* if (self->streamInfo.extAot != AOT_AAC_SLS)*/
+
+ if (self->flags[0] & AC_USAC) {
+ if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
+ !(flags & AACDEC_CONCEAL)) {
+ CAacDecoder_PrepareCrossFade(pTimeData, self->pTimeDataFlush,
+ self->streamInfo.numChannels,
+ self->streamInfo.frameSize, 1);
+ }
+
+ /* prepare crossfade buffer for fade in */
+ if (!applyCrossfade && self->applyCrossfade &&
+ !(flags & AACDEC_CONCEAL)) {
+ for (int ch = 0; ch < self->streamInfo.numChannels; ch++) {
+ for (int i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
+ self->pTimeDataFlush[ch][i] = 0;
+ }
+ }
+ applyCrossfade = 1;
+ }
+
+ if (applyCrossfade && self->applyCrossfade &&
+ !(accessUnit < numPrerollAU) &&
+ (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
+ CAacDecoder_ApplyCrossFade(pTimeData, self->pTimeDataFlush,
+ self->streamInfo.numChannels,
+ self->streamInfo.frameSize, 1);
+ self->applyCrossfade = 0;
+ }
+ }
+
+ /* Signal interruption to take effect in next frame. */
+ if ((flags & AACDEC_FLUSH || self->flushStatus) &&
+ !(flags & AACDEC_CONCEAL)) {
+ aacDecoder_SignalInterruption(self);
+ }
+
+ /* Update externally visible copy of flags */
+ self->streamInfo.flags = self->flags[0];
+
+ } /* USAC DASH IPF flushing possible end */
+ if (accessUnit < numPrerollAU) {
+ FDKpushBack(hBsAu, auStartAnchor - (INT)FDKgetValidBits(hBsAu));
+ } else {
+ if ((self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON) ||
+ (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON_IN_BAND) ||
+ (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
+ self->buildUpCnt--;
+
+ if (self->buildUpCnt < 0) {
+ self->buildUpStatus = 0;
+ }
+ }
+
+ if (self->flags[0] & AC_USAC) {
+ if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
+ !(flags & AACDEC_CONCEAL)) {
+ self->streamInfo.frameSize = 0;
+ }
+ }
+ }
+
+ if (self->flushStatus != AACDEC_USAC_DASH_IPF_FLUSH_ON) {
+ accessUnit++;
+ }
+ } while ((accessUnit < numAccessUnits) ||
+ ((self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) &&
+ !(flags & AACDEC_CONCEAL)));
+
+bail:
+
+ /* error in renderer part occurred, ErrorStatus was set to invalid output */
+ if (fEndAuNotAdjusted && !IS_OUTPUT_VALID(ErrorStatus) &&
+ (accessUnit < numPrerollAU)) {
+ transportDec_EndAccessUnit(self->hInput);
+ }
+
+ /* Update Statistics */
+ aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits,
+ ErrorStatus);
+ if (((self->streamInfo.numChannels <= 0) ||
+ (self->streamInfo.frameSize <= 0) ||
+ (self->streamInfo.sampleRate <= 0)) &&
+ IS_OUTPUT_VALID(ErrorStatus)) {
+ /* Ensure consistency of IS_OUTPUT_VALID() macro. */
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ }
+
+ /* 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;
+}
+
+LINKSPEC_CPP void aacDecoder_Close(HANDLE_AACDECODER self) {
+ if (self == NULL) return;
+
+ if (self->hLimiter != NULL) {
+ pcmLimiter_Destroy(self->hLimiter);
+ }
+
+ if (self->hPcmUtils != NULL) {
+ pcmDmx_Close(&self->hPcmUtils);
+ }
+
+ FDK_drcDec_Close(&self->hUniDrcDecoder);
+
+ if (self->pMpegSurroundDecoder != NULL) {
+ mpegSurroundDecoder_Close(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder);
+ }
+
+ if (self->hSbrDecoder != NULL) {
+ sbrDecoder_Close(&self->hSbrDecoder);
+ }
+
+ if (self->hInput != NULL) {
+ transportDec_Close(&self->hInput);
+ }
+
+ CAacDecoder_Close(self);
+}
+
+LINKSPEC_CPP CStreamInfo *aacDecoder_GetStreamInfo(HANDLE_AACDECODER self) {
+ return CAacDecoder_GetStreamInfo(self);
+}
+
+LINKSPEC_CPP INT aacDecoder_GetLibInfo(LIB_INFO *info) {
+ int i;
+
+ if (info == NULL) {
+ return -1;
+ }
+
+ sbrDecoder_GetLibInfo(info);
+ mpegSurroundDecoder_GetLibInfo(info);
+ transportDec_GetLibInfo(info);
+ FDK_toolsGetLibInfo(info);
+ pcmDmx_GetLibInfo(info);
+ pcmLimiter_GetLibInfo(info);
+ FDK_drcDec_GetLibInfo(info);
+
+ /* search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) {
+ return -1;
+ }
+ info += i;
+
+ info->module_id = FDK_AACDEC;
+ /* build own library info */
+ info->version =
+ LIB_VERSION(AACDECODER_LIB_VL0, AACDECODER_LIB_VL1, AACDECODER_LIB_VL2);
+ LIB_VERSION_STRING(info);
+ info->build_date = AACDECODER_LIB_BUILD_DATE;
+ info->build_time = AACDECODER_LIB_BUILD_TIME;
+ info->title = AACDECODER_LIB_TITLE;
+
+ /* Set flags */
+ info->flags = 0 | CAPF_AAC_LC | CAPF_ER_AAC_LC | CAPF_ER_AAC_SCAL |
+ CAPF_AAC_VCB11 | CAPF_AAC_HCR | CAPF_AAC_RVLC | CAPF_ER_AAC_LD |
+ CAPF_ER_AAC_ELD | CAPF_AAC_CONCEALMENT | CAPF_AAC_DRC |
+ CAPF_AAC_MPEG4 | CAPF_AAC_DRM_BSFORMAT | CAPF_AAC_1024 |
+ CAPF_AAC_960 | CAPF_AAC_512 | CAPF_AAC_480 |
+ CAPF_AAC_ELD_DOWNSCALE
+
+ | CAPF_AAC_USAC | CAPF_ER_AAC_ELDV2 | CAPF_AAC_UNIDRC;
+ /* End of flags */
+
+ return 0;
+}
diff --git a/fdk-aac/libAACdec/src/arm/block_arm.cpp b/fdk-aac/libAACdec/src/arm/block_arm.cpp
new file mode 100644
index 0000000..3c1b4ba
--- /dev/null
+++ b/fdk-aac/libAACdec/src/arm/block_arm.cpp
@@ -0,0 +1,142 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Arthur Tritthart
+
+ Description: (ARM optimised) Scaling of spectral data
+
+*******************************************************************************/
+
+#define FUNCTION_CBlock_ScaleSpectralData_func1
+
+/* Note: This loop is only separated for ARM in order to save cycles
+ by loop unrolling. The ARM core provides by default a 5-cycle
+ loop overhead per sample, that goes down to 1-cycle per sample
+ with an optimal 4x-loop construct (do - 4x - while).
+*/
+static inline void CBlock_ScaleSpectralData_func1(
+ FIXP_DBL *pSpectrum, int maxSfbs, const SHORT *RESTRICT BandOffsets,
+ int SpecScale_window, const SHORT *RESTRICT pSfbScale, int window) {
+ int band_offset = 0;
+ for (int band = 0; band < maxSfbs; band++) {
+ int runs = band_offset;
+ band_offset = BandOffsets[band + 1];
+ runs = band_offset - runs; /* is always a multiple of 4 */
+ FDK_ASSERT((runs & 3) == 0);
+ int scale =
+ fMin(DFRACT_BITS - 1, SpecScale_window - pSfbScale[window * 16 + band]);
+
+ if (scale) {
+ do {
+ FIXP_DBL tmp0, tmp1, tmp2, tmp3;
+ tmp0 = pSpectrum[0];
+ tmp1 = pSpectrum[1];
+ tmp2 = pSpectrum[2];
+ tmp3 = pSpectrum[3];
+ tmp0 >>= scale;
+ tmp1 >>= scale;
+ tmp2 >>= scale;
+ tmp3 >>= scale;
+ *pSpectrum++ = tmp0;
+ *pSpectrum++ = tmp1;
+ *pSpectrum++ = tmp2;
+ *pSpectrum++ = tmp3;
+ } while ((runs = runs - 4) != 0);
+ } else {
+ pSpectrum += runs;
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/block.cpp b/fdk-aac/libAACdec/src/block.cpp
new file mode 100644
index 0000000..b3d09a6
--- /dev/null
+++ b/fdk-aac/libAACdec/src/block.cpp
@@ -0,0 +1,1260 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: long/short-block decoding
+
+*******************************************************************************/
+
+#include "block.h"
+
+#include "aac_rom.h"
+#include "FDK_bitstream.h"
+#include "scale.h"
+#include "FDK_tools_rom.h"
+
+#include "usacdec_fac.h"
+#include "usacdec_lpd.h"
+#include "usacdec_lpc.h"
+#include "FDK_trigFcts.h"
+
+#include "ac_arith_coder.h"
+
+#include "aacdec_hcr.h"
+#include "rvlc.h"
+
+#if defined(__arm__)
+#include "arm/block_arm.cpp"
+#endif
+
+/*!
+ \brief Read escape sequence of codeword
+
+ The function reads the escape sequence from the bitstream,
+ if the absolute value of the quantized coefficient has the
+ value 16.
+ A limitation is implemented to maximal 21 bits according to
+ ISO/IEC 14496-3:2009(E) 4.6.3.3.
+ This limits the escape prefix to a maximum of eight 1's.
+ If more than eight 1's are read, MAX_QUANTIZED_VALUE + 1 is
+ returned, independent of the sign of parameter q.
+
+ \return quantized coefficient
+*/
+LONG CBlock_GetEscape(HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
+ const LONG q) /*!< quantized coefficient */
+{
+ if (fAbs(q) != 16) return (q);
+
+ LONG i, off;
+ for (i = 4; i < 13; i++) {
+ if (FDKreadBit(bs) == 0) break;
+ }
+
+ if (i == 13) return (MAX_QUANTIZED_VALUE + 1);
+
+ off = FDKreadBits(bs, i);
+ i = off + (1 << i);
+
+ if (q < 0) i = -i;
+
+ return i;
+}
+
+AAC_DECODER_ERROR CBlock_ReadScaleFactorData(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, HANDLE_FDK_BITSTREAM bs,
+ UINT flags) {
+ int temp;
+ int band;
+ int group;
+ int position = 0; /* accu for intensity delta coding */
+ int factor = pAacDecoderChannelInfo->pDynData->RawDataInfo
+ .GlobalGain; /* accu for scale factor delta coding */
+ UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ SHORT *pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
+ const CodeBookDescription *hcb = &AACcodeBookDescriptionTable[BOOKSCL];
+
+ const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook;
+
+ int ScaleFactorBandsTransmitted =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ for (group = 0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+ group++) {
+ for (band = 0; band < ScaleFactorBandsTransmitted; band++) {
+ switch (pCodeBook[band]) {
+ case ZERO_HCB: /* zero book */
+ pScaleFactor[band] = 0;
+ break;
+
+ default: /* decode scale factor */
+ if (!((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) && band == 0 &&
+ group == 0)) {
+ temp = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
+ factor += temp - 60; /* MIDFAC 1.5 dB */
+ }
+ pScaleFactor[band] = factor - 100;
+ break;
+
+ case INTENSITY_HCB: /* intensity steering */
+ case INTENSITY_HCB2:
+ temp = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
+ position += temp - 60;
+ pScaleFactor[band] = position - 100;
+ break;
+
+ case NOISE_HCB: /* PNS */
+ if (flags & (AC_MPEGD_RES | AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+ CPns_Read(&pAacDecoderChannelInfo->data.aac.PnsData, bs, hcb,
+ pAacDecoderChannelInfo->pDynData->aScaleFactor,
+ pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain,
+ band, group);
+ break;
+ }
+ }
+ pCodeBook += 16;
+ pScaleFactor += 16;
+ }
+
+ return AAC_DEC_OK;
+}
+
+void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ UCHAR maxSfbs,
+ SamplingRateInfo *pSamplingRateInfo) {
+ int band;
+ int window;
+ const SHORT *RESTRICT pSfbScale = pAacDecoderChannelInfo->pDynData->aSfbScale;
+ SHORT *RESTRICT pSpecScale = pAacDecoderChannelInfo->specScale;
+ int groupwin, group;
+ const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+ SPECTRAL_PTR RESTRICT pSpectralCoefficient =
+ pAacDecoderChannelInfo->pSpectralCoefficient;
+
+ FDKmemclear(pSpecScale, 8 * sizeof(SHORT));
+
+ for (window = 0, group = 0;
+ group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) {
+ for (groupwin = 0; groupwin < GetWindowGroupLength(
+ &pAacDecoderChannelInfo->icsInfo, group);
+ groupwin++, window++) {
+ int SpecScale_window = pSpecScale[window];
+ FIXP_DBL *pSpectrum = SPEC(pSpectralCoefficient, window,
+ pAacDecoderChannelInfo->granuleLength);
+
+ /* find scaling for current window */
+ for (band = 0; band < maxSfbs; band++) {
+ SpecScale_window =
+ fMax(SpecScale_window, (int)pSfbScale[window * 16 + band]);
+ }
+
+ if (pAacDecoderChannelInfo->pDynData->TnsData.Active &&
+ pAacDecoderChannelInfo->pDynData->TnsData.NumberOfFilters[window] >
+ 0) {
+ int filter_index, SpecScale_window_tns;
+ int tns_start, tns_stop;
+
+ /* Find max scale of TNS bands */
+ SpecScale_window_tns = 0;
+ tns_start = GetMaximumTnsBands(&pAacDecoderChannelInfo->icsInfo,
+ pSamplingRateInfo->samplingRateIndex);
+ tns_stop = 0;
+ for (filter_index = 0;
+ filter_index < (int)pAacDecoderChannelInfo->pDynData->TnsData
+ .NumberOfFilters[window];
+ filter_index++) {
+ for (band = pAacDecoderChannelInfo->pDynData->TnsData
+ .Filter[window][filter_index]
+ .StartBand;
+ band < pAacDecoderChannelInfo->pDynData->TnsData
+ .Filter[window][filter_index]
+ .StopBand;
+ band++) {
+ SpecScale_window_tns =
+ fMax(SpecScale_window_tns, (int)pSfbScale[window * 16 + band]);
+ }
+ /* Find TNS line boundaries for all TNS filters */
+ tns_start =
+ fMin(tns_start, (int)pAacDecoderChannelInfo->pDynData->TnsData
+ .Filter[window][filter_index]
+ .StartBand);
+ tns_stop =
+ fMax(tns_stop, (int)pAacDecoderChannelInfo->pDynData->TnsData
+ .Filter[window][filter_index]
+ .StopBand);
+ }
+ SpecScale_window_tns = SpecScale_window_tns +
+ pAacDecoderChannelInfo->pDynData->TnsData.GainLd;
+ FDK_ASSERT(tns_stop >= tns_start);
+ /* Consider existing headroom of all MDCT lines inside the TNS bands. */
+ SpecScale_window_tns -=
+ getScalefactor(pSpectrum + BandOffsets[tns_start],
+ BandOffsets[tns_stop] - BandOffsets[tns_start]);
+ if (SpecScale_window <= 17) {
+ SpecScale_window_tns++;
+ }
+ /* Add enough mantissa head room such that the spectrum is still
+ representable after applying TNS. */
+ SpecScale_window = fMax(SpecScale_window, SpecScale_window_tns);
+ }
+
+ /* store scaling of current window */
+ pSpecScale[window] = SpecScale_window;
+
+#ifdef FUNCTION_CBlock_ScaleSpectralData_func1
+
+ CBlock_ScaleSpectralData_func1(pSpectrum, maxSfbs, BandOffsets,
+ SpecScale_window, pSfbScale, window);
+
+#else /* FUNCTION_CBlock_ScaleSpectralData_func1 */
+ for (band = 0; band < maxSfbs; band++) {
+ int scale = fMin(DFRACT_BITS - 1,
+ SpecScale_window - pSfbScale[window * 16 + band]);
+ if (scale) {
+ FDK_ASSERT(scale > 0);
+
+ /* following relation can be used for optimizations:
+ * (BandOffsets[i]%4) == 0 for all i */
+ int max_index = BandOffsets[band + 1];
+ DWORD_ALIGNED(pSpectrum);
+ for (int index = BandOffsets[band]; index < max_index; index++) {
+ pSpectrum[index] >>= scale;
+ }
+ }
+ }
+#endif /* FUNCTION_CBlock_ScaleSpectralData_func1 */
+ }
+ }
+}
+
+AAC_DECODER_ERROR CBlock_ReadSectionData(
+ HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags) {
+ int top, band;
+ int sect_len, sect_len_incr;
+ int group;
+ UCHAR sect_cb;
+ UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ /* HCR input (long) */
+ SHORT *pNumLinesInSec =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
+ int numLinesInSecIdx = 0;
+ UCHAR *pHcrCodeBook =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
+ const SHORT *BandOffsets = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection = 0;
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ FDKmemclear(pCodeBook, sizeof(UCHAR) * (8 * 16));
+
+ const int nbits =
+ (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) == 1) ? 5 : 3;
+
+ int sect_esc_val = (1 << nbits) - 1;
+
+ UCHAR ScaleFactorBandsTransmitted =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ for (group = 0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+ group++) {
+ for (band = 0; band < ScaleFactorBandsTransmitted;) {
+ sect_len = 0;
+ if (flags & AC_ER_VCB11) {
+ sect_cb = (UCHAR)FDKreadBits(bs, 5);
+ } else
+ sect_cb = (UCHAR)FDKreadBits(bs, 4);
+
+ if (((flags & AC_ER_VCB11) == 0) || (sect_cb < 11) ||
+ ((sect_cb > 11) && (sect_cb < 16))) {
+ sect_len_incr = FDKreadBits(bs, nbits);
+ while (sect_len_incr == sect_esc_val) {
+ sect_len += sect_esc_val;
+ sect_len_incr = FDKreadBits(bs, nbits);
+ }
+ } else {
+ sect_len_incr = 1;
+ }
+
+ sect_len += sect_len_incr;
+
+ top = band + sect_len;
+
+ if (flags & AC_ER_HCR) {
+ /* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */
+ if (numLinesInSecIdx >= MAX_SFB_HCR) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+ if (top > (int)GetNumberOfScaleFactorBands(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo)) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+ pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
+ numLinesInSecIdx++;
+ if (sect_cb == BOOKSCL) {
+ return AAC_DEC_INVALID_CODE_BOOK;
+ } else {
+ *pHcrCodeBook++ = sect_cb;
+ }
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection++;
+ }
+
+ /* Check spectral line limits */
+ if (IsLongBlock(&(pAacDecoderChannelInfo->icsInfo))) {
+ if (top > 64) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ } else { /* short block */
+ if (top + group * 16 > (8 * 16)) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ }
+
+ /* Check if decoded codebook index is feasible */
+ if ((sect_cb == BOOKSCL) ||
+ ((sect_cb == INTENSITY_HCB || sect_cb == INTENSITY_HCB2) &&
+ pAacDecoderChannelInfo->pDynData->RawDataInfo.CommonWindow == 0)) {
+ return AAC_DEC_INVALID_CODE_BOOK;
+ }
+
+ /* Store codebook index */
+ for (; band < top; band++) {
+ pCodeBook[group * 16 + band] = sect_cb;
+ }
+ }
+ }
+
+ return ErrorStatus;
+}
+
+/* mso: provides a faster way to i-quantize a whole band in one go */
+
+/**
+ * \brief inverse quantize one sfb. Each value of the sfb is processed according
+ * to the formula: spectrum[i] = Sign(spectrum[i]) * Matissa(spectrum[i])^(4/3)
+ * * 2^(lsb/4).
+ * \param spectrum pointer to first line of the sfb to be inverse quantized.
+ * \param noLines number of lines belonging to the sfb.
+ * \param lsb last 2 bits of the scale factor of the sfb.
+ * \param scale max allowed shift scale for the sfb.
+ */
+static inline void InverseQuantizeBand(
+ FIXP_DBL *RESTRICT spectrum, const FIXP_DBL *RESTRICT InverseQuantTabler,
+ const FIXP_DBL *RESTRICT MantissaTabler,
+ const SCHAR *RESTRICT ExponentTabler, INT noLines, INT scale) {
+ scale = scale + 1; /* +1 to compensate fMultDiv2 shift-right in loop */
+
+ FIXP_DBL *RESTRICT ptr = spectrum;
+ FIXP_DBL signedValue;
+
+ for (INT i = noLines; i--;) {
+ if ((signedValue = *ptr++) != FL2FXCONST_DBL(0)) {
+ FIXP_DBL value = fAbs(signedValue);
+ UINT freeBits = CntLeadingZeros(value);
+ UINT exponent = 32 - freeBits;
+
+ UINT x = (UINT)(LONG)value << (INT)freeBits;
+ x <<= 1; /* shift out sign bit to avoid masking later on */
+ UINT tableIndex = x >> 24;
+ x = (x >> 20) & 0x0F;
+
+ UINT r0 = (UINT)(LONG)InverseQuantTabler[tableIndex + 0];
+ UINT r1 = (UINT)(LONG)InverseQuantTabler[tableIndex + 1];
+ UINT temp = (r1 - r0) * x + (r0 << 4);
+
+ value = fMultDiv2((FIXP_DBL)temp, MantissaTabler[exponent]);
+
+ /* + 1 compensates fMultDiv2() */
+ scaleValueInPlace(&value, scale + ExponentTabler[exponent]);
+
+ signedValue = (signedValue < (FIXP_DBL)0) ? -value : value;
+ ptr[-1] = signedValue;
+ }
+ }
+}
+
+static inline FIXP_DBL maxabs_D(const FIXP_DBL *pSpectralCoefficient,
+ const int noLines) {
+ /* Find max spectral line value of the current sfb */
+ FIXP_DBL locMax = (FIXP_DBL)0;
+ int i;
+
+ DWORD_ALIGNED(pSpectralCoefficient);
+
+ for (i = noLines; i-- > 0;) {
+ /* Expensive memory access */
+ locMax = fMax(fixp_abs(pSpectralCoefficient[i]), locMax);
+ }
+
+ return locMax;
+}
+
+AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ SamplingRateInfo *pSamplingRateInfo, UCHAR *band_is_noise,
+ UCHAR active_band_search) {
+ int window, group, groupwin, band;
+ int ScaleFactorBandsTransmitted =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ UCHAR *RESTRICT pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ SHORT *RESTRICT pSfbScale = pAacDecoderChannelInfo->pDynData->aSfbScale;
+ SHORT *RESTRICT pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
+ const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+ const SHORT total_bands =
+ GetScaleFactorBandsTotal(&pAacDecoderChannelInfo->icsInfo);
+
+ FDKmemclear(pAacDecoderChannelInfo->pDynData->aSfbScale,
+ (8 * 16) * sizeof(SHORT));
+
+ for (window = 0, group = 0;
+ group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) {
+ for (groupwin = 0; groupwin < GetWindowGroupLength(
+ &pAacDecoderChannelInfo->icsInfo, group);
+ groupwin++, window++) {
+ /* inverse quantization */
+ for (band = 0; band < ScaleFactorBandsTransmitted; band++) {
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, window,
+ pAacDecoderChannelInfo->granuleLength) +
+ BandOffsets[band];
+ FIXP_DBL locMax;
+
+ const int noLines = BandOffsets[band + 1] - BandOffsets[band];
+ const int bnds = group * 16 + band;
+
+ if ((pCodeBook[bnds] == ZERO_HCB) ||
+ (pCodeBook[bnds] == INTENSITY_HCB) ||
+ (pCodeBook[bnds] == INTENSITY_HCB2))
+ continue;
+
+ if (pCodeBook[bnds] == NOISE_HCB) {
+ /* Leave headroom for PNS values. + 1 because ceil(log2(2^(0.25*3))) =
+ 1, worst case of additional headroom required because of the
+ scalefactor. */
+ pSfbScale[window * 16 + band] = (pScaleFactor[bnds] >> 2) + 1;
+ continue;
+ }
+
+ locMax = maxabs_D(pSpectralCoefficient, noLines);
+
+ if (active_band_search) {
+ if (locMax != FIXP_DBL(0)) {
+ band_is_noise[group * 16 + band] = 0;
+ }
+ }
+
+ /* Cheap robustness improvement - Do not remove!!! */
+ if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+
+ /* Added by Youliy Ninov:
+ The inverse quantization operation is given by (ISO/IEC 14496-3:2009(E))
+ by:
+
+ x_invquant=Sign(x_quant). abs(x_quant)^(4/3)
+
+ We apply a gain, derived from the scale factor for the particular sfb,
+ according to the following function:
+
+ gain=2^(0.25*ScaleFactor)
+
+ So, after scaling we have:
+
+ x_rescale=gain*x_invquant=Sign(x_quant)*2^(0.25*ScaleFactor)*abs(s_quant)^(4/3)
+
+ We could represent the ScaleFactor as:
+
+ ScaleFactor= (ScaleFactor >> 2)*4 + ScaleFactor %4
+
+ When we substitute it we get:
+
+ x_rescale=Sign(x_quant)*2^(ScaleFactor>>2)* (
+ 2^(0.25*(ScaleFactor%4))*abs(s_quant)^(4/3))
+
+ When we set: msb=(ScaleFactor>>2) and lsb=(ScaleFactor%4), we obtain:
+
+ x_rescale=Sign(x_quant)*(2^msb)* ( 2^(lsb/4)*abs(s_quant)^(4/3))
+
+ The rescaled output can be represented by:
+ mantissa : Sign(x_quant)*( 2^(lsb/4)*abs(s_quant)^(4/3))
+ exponent :(2^msb)
+
+ */
+
+ int msb = pScaleFactor[bnds] >> 2;
+
+ /* Inverse quantize band only if it is not empty */
+ if (locMax != FIXP_DBL(0)) {
+ int lsb = pScaleFactor[bnds] & 0x03;
+
+ int scale = EvaluatePower43(&locMax, lsb);
+
+ scale = CntLeadingZeros(locMax) - scale - 2;
+
+ pSfbScale[window * 16 + band] = msb - scale;
+ InverseQuantizeBand(pSpectralCoefficient, InverseQuantTable,
+ MantissaTable[lsb], ExponentTable[lsb], noLines,
+ scale);
+ } else {
+ pSfbScale[window * 16 + band] = msb;
+ }
+
+ } /* for (band=0; band < ScaleFactorBandsTransmitted; band++) */
+
+ /* Make sure the array is cleared to the end */
+ SHORT start_clear = BandOffsets[ScaleFactorBandsTransmitted];
+ SHORT end_clear = BandOffsets[total_bands];
+ int diff_clear = (int)(end_clear - start_clear);
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, window,
+ pAacDecoderChannelInfo->granuleLength) +
+ start_clear;
+ FDKmemclear(pSpectralCoefficient, diff_clear * sizeof(FIXP_DBL));
+
+ } /* for (groupwin=0; groupwin <
+ GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group);
+ groupwin++, window++) */
+ } /* for (window=0, group=0; group <
+ GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)*/
+
+ return AAC_DEC_OK;
+}
+
+AAC_DECODER_ERROR CBlock_ReadSpectralData(
+ HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags) {
+ int index, i;
+ const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+
+ SPECTRAL_PTR pSpectralCoefficient =
+ pAacDecoderChannelInfo->pSpectralCoefficient;
+
+ FDK_ASSERT(BandOffsets != NULL);
+
+ FDKmemclear(pSpectralCoefficient, sizeof(SPECTRUM));
+
+ if ((flags & AC_ER_HCR) == 0) {
+ int group;
+ int groupoffset;
+ UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ int ScaleFactorBandsTransmitted =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ int granuleLength = pAacDecoderChannelInfo->granuleLength;
+
+ groupoffset = 0;
+
+ /* plain huffman decoder short */
+ int max_group = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+
+ for (group = 0; group < max_group; group++) {
+ int max_groupwin =
+ GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
+ int band;
+
+ int bnds = group * 16;
+
+ int bandOffset1 = BandOffsets[0];
+ for (band = 0; band < ScaleFactorBandsTransmitted; band++, bnds++) {
+ UCHAR currentCB = pCodeBook[bnds];
+ int bandOffset0 = bandOffset1;
+ bandOffset1 = BandOffsets[band + 1];
+
+ /* patch to run plain-huffman-decoder with vcb11 input codebooks
+ * (LAV-checking might be possible below using the virtual cb and a
+ * LAV-table) */
+ if ((currentCB >= 16) && (currentCB <= 31)) {
+ pCodeBook[bnds] = currentCB = 11;
+ }
+ if (((currentCB != ZERO_HCB) && (currentCB != NOISE_HCB) &&
+ (currentCB != INTENSITY_HCB) && (currentCB != INTENSITY_HCB2))) {
+ const CodeBookDescription *hcb =
+ &AACcodeBookDescriptionTable[currentCB];
+ int step = hcb->Dimension;
+ int offset = hcb->Offset;
+ int bits = hcb->numBits;
+ int mask = (1 << bits) - 1;
+ const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook;
+ int groupwin;
+
+ FIXP_DBL *mdctSpectrum =
+ &pSpectralCoefficient[groupoffset * granuleLength];
+
+ if (offset == 0) {
+ for (groupwin = 0; groupwin < max_groupwin; groupwin++) {
+ for (index = bandOffset0; index < bandOffset1; index += step) {
+ int idx = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
+ for (i = 0; i < step; i++, idx >>= bits) {
+ FIXP_DBL tmp = (FIXP_DBL)((idx & mask) - offset);
+ if (tmp != FIXP_DBL(0)) tmp = (FDKreadBit(bs)) ? -tmp : tmp;
+ mdctSpectrum[index + i] = tmp;
+ }
+
+ if (currentCB == ESCBOOK) {
+ for (int j = 0; j < 2; j++)
+ mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape(
+ bs, (LONG)mdctSpectrum[index + j]);
+ }
+ }
+ mdctSpectrum += granuleLength;
+ }
+ } else {
+ for (groupwin = 0; groupwin < max_groupwin; groupwin++) {
+ for (index = bandOffset0; index < bandOffset1; index += step) {
+ int idx = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
+ for (i = 0; i < step; i++, idx >>= bits) {
+ mdctSpectrum[index + i] = (FIXP_DBL)((idx & mask) - offset);
+ }
+ if (currentCB == ESCBOOK) {
+ for (int j = 0; j < 2; j++)
+ mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape(
+ bs, (LONG)mdctSpectrum[index + j]);
+ }
+ }
+ mdctSpectrum += granuleLength;
+ }
+ }
+ }
+ }
+ groupoffset += max_groupwin;
+ }
+ /* plain huffman decoding (short) finished */
+ }
+
+ /* HCR - Huffman Codeword Reordering short */
+ else /* if ( flags & AC_ER_HCR ) */
+
+ {
+ H_HCR_INFO hHcr = &pAacDecoderChannelInfo->pComData->overlay.aac.erHcrInfo;
+
+ int hcrStatus = 0;
+
+ /* advanced Huffman decoding starts here (HCR decoding :) */
+ if (pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData != 0) {
+ /* HCR initialization short */
+ hcrStatus = HcrInit(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
+
+ if (hcrStatus != 0) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ /* HCR decoding short */
+ hcrStatus =
+ HcrDecoder(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
+
+ if (hcrStatus != 0) {
+#if HCR_ERROR_CONCEALMENT
+ HcrMuteErroneousLines(hHcr);
+#else
+ return AAC_DEC_DECODE_FRAME_ERROR;
+#endif /* HCR_ERROR_CONCEALMENT */
+ }
+
+ FDKpushFor(bs, pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData);
+ }
+ }
+ /* HCR - Huffman Codeword Reordering short finished */
+
+ if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) &&
+ !(flags & (AC_ELD | AC_SCALABLE))) {
+ /* apply pulse data */
+ CPulseData_Apply(
+ &pAacDecoderChannelInfo->pDynData->specificTo.aac.PulseData,
+ GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo,
+ pSamplingRateInfo),
+ SPEC_LONG(pSpectralCoefficient));
+ }
+
+ return AAC_DEC_OK;
+}
+
+static const FIXP_SGL noise_level_tab[8] = {
+ /* FDKpow(2, (float)(noise_level-14)/3.0f) * 2; (*2 to compensate for
+ fMultDiv2) noise_level_tab(noise_level==0) == 0 by definition
+ */
+ FX_DBL2FXCONST_SGL(0x00000000 /*0x0a145173*/),
+ FX_DBL2FXCONST_SGL(0x0cb2ff5e),
+ FX_DBL2FXCONST_SGL(0x10000000),
+ FX_DBL2FXCONST_SGL(0x1428a2e7),
+ FX_DBL2FXCONST_SGL(0x1965febd),
+ FX_DBL2FXCONST_SGL(0x20000000),
+ FX_DBL2FXCONST_SGL(0x28514606),
+ FX_DBL2FXCONST_SGL(0x32cbfd33)};
+
+void CBlock_ApplyNoise(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ SamplingRateInfo *pSamplingRateInfo, ULONG *nfRandomSeed,
+ UCHAR *band_is_noise) {
+ const SHORT *swb_offset = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+ int g, win, gwin, sfb, noiseFillingStartOffset, nfStartOffset_sfb;
+
+ /* Obtain noise level and scale factor offset. */
+ int noise_level = pAacDecoderChannelInfo->pDynData->specificTo.usac
+ .fd_noise_level_and_offset >>
+ 5;
+ const FIXP_SGL noiseVal_pos = noise_level_tab[noise_level];
+
+ /* noise_offset can change even when noise_level=0. Neccesary for IGF stereo
+ * filling */
+ const int noise_offset = (pAacDecoderChannelInfo->pDynData->specificTo.usac
+ .fd_noise_level_and_offset &
+ 0x1f) -
+ 16;
+
+ int max_sfb =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+
+ noiseFillingStartOffset =
+ (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
+ ? 20
+ : 160;
+ if (pAacDecoderChannelInfo->granuleLength == 96) {
+ noiseFillingStartOffset =
+ (3 * noiseFillingStartOffset) /
+ 4; /* scale offset with 3/4 for coreCoderFrameLength == 768 */
+ }
+
+ /* determine sfb from where on noise filling is applied */
+ for (sfb = 0; swb_offset[sfb] < noiseFillingStartOffset; sfb++)
+ ;
+ nfStartOffset_sfb = sfb;
+
+ /* if (noise_level!=0) */
+ {
+ for (g = 0, win = 0; g < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+ g++) {
+ int windowGroupLength =
+ GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, g);
+ for (sfb = nfStartOffset_sfb; sfb < max_sfb; sfb++) {
+ int bin_start = swb_offset[sfb];
+ int bin_stop = swb_offset[sfb + 1];
+
+ int flagN = band_is_noise[g * 16 + sfb];
+
+ /* if all bins of one sfb in one window group are zero modify the scale
+ * factor by noise_offset */
+ if (flagN) {
+ /* Change scaling factors for empty signal bands */
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] +=
+ noise_offset;
+ /* scale factor "sf" implied gain "g" is g = 2^(sf/4) */
+ for (gwin = 0; gwin < windowGroupLength; gwin++) {
+ pAacDecoderChannelInfo->pDynData
+ ->aSfbScale[(win + gwin) * 16 + sfb] += (noise_offset >> 2);
+ }
+ }
+
+ ULONG seed = *nfRandomSeed;
+ /* + 1 because exponent of MantissaTable[lsb][0] is always 1. */
+ int scale =
+ (pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] >>
+ 2) +
+ 1;
+ int lsb =
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] & 3;
+ FIXP_DBL mantissa = MantissaTable[lsb][0];
+
+ for (gwin = 0; gwin < windowGroupLength; gwin++) {
+ FIXP_DBL *pSpec =
+ SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, win + gwin,
+ pAacDecoderChannelInfo->granuleLength);
+
+ int scale1 = scale - pAacDecoderChannelInfo->pDynData
+ ->aSfbScale[(win + gwin) * 16 + sfb];
+ FIXP_DBL scaled_noiseVal_pos =
+ scaleValue(fMultDiv2(noiseVal_pos, mantissa), scale1);
+ FIXP_DBL scaled_noiseVal_neg = -scaled_noiseVal_pos;
+
+ /* If the whole band is zero, just fill without checking */
+ if (flagN) {
+ for (int bin = bin_start; bin < bin_stop; bin++) {
+ seed = (ULONG)(
+ (UINT64)seed * 69069 +
+ 5); /* Inlined: UsacRandomSign - origin in usacdec_lpd.h */
+ pSpec[bin] =
+ (seed & 0x10000) ? scaled_noiseVal_neg : scaled_noiseVal_pos;
+ } /* for (bin...) */
+ }
+ /*If band is sparsely filled, check for 0 and fill */
+ else {
+ for (int bin = bin_start; bin < bin_stop; bin++) {
+ if (pSpec[bin] == (FIXP_DBL)0) {
+ seed = (ULONG)(
+ (UINT64)seed * 69069 +
+ 5); /* Inlined: UsacRandomSign - origin in usacdec_lpd.h */
+ pSpec[bin] = (seed & 0x10000) ? scaled_noiseVal_neg
+ : scaled_noiseVal_pos;
+ }
+ } /* for (bin...) */
+ }
+
+ } /* for (gwin...) */
+ *nfRandomSeed = seed;
+ } /* for (sfb...) */
+ win += windowGroupLength;
+ } /* for (g...) */
+
+ } /* ... */
+}
+
+AAC_DECODER_ERROR CBlock_ReadAcSpectralData(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT frame_length,
+ const UINT flags) {
+ AAC_DECODER_ERROR errorAAC = AAC_DEC_OK;
+ ARITH_CODING_ERROR error = ARITH_CODER_OK;
+ int arith_reset_flag, lg, numWin, win, winLen;
+ const SHORT *RESTRICT BandOffsets;
+
+ /* number of transmitted spectral coefficients */
+ BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo,
+ pSamplingRateInfo);
+ lg = BandOffsets[GetScaleFactorBandsTransmitted(
+ &pAacDecoderChannelInfo->icsInfo)];
+
+ numWin = GetWindowsPerFrame(&pAacDecoderChannelInfo->icsInfo);
+ winLen = (IsLongBlock(&pAacDecoderChannelInfo->icsInfo))
+ ? (int)frame_length
+ : (int)frame_length / numWin;
+
+ if (flags & AC_INDEP) {
+ arith_reset_flag = 1;
+ } else {
+ arith_reset_flag = (USHORT)FDKreadBits(hBs, 1);
+ }
+
+ for (win = 0; win < numWin; win++) {
+ error =
+ CArco_DecodeArithData(pAacDecoderStaticChannelInfo->hArCo, hBs,
+ SPEC(pAacDecoderChannelInfo->pSpectralCoefficient,
+ win, pAacDecoderChannelInfo->granuleLength),
+ lg, winLen, arith_reset_flag && (win == 0));
+ if (error != ARITH_CODER_OK) {
+ goto bail;
+ }
+ }
+
+bail:
+ if (error == ARITH_CODER_ERROR) {
+ errorAAC = AAC_DEC_PARSE_ERROR;
+ }
+
+ return errorAAC;
+}
+
+void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags,
+ const UINT elFlags, const int channel,
+ const int common_window) {
+ if (!(flags & (AC_USAC | AC_RSVD50 | AC_MPEGD_RES | AC_RSV603DA))) {
+ CPns_Apply(&pAacDecoderChannelInfo[channel]->data.aac.PnsData,
+ &pAacDecoderChannelInfo[channel]->icsInfo,
+ pAacDecoderChannelInfo[channel]->pSpectralCoefficient,
+ pAacDecoderChannelInfo[channel]->specScale,
+ pAacDecoderChannelInfo[channel]->pDynData->aScaleFactor,
+ pSamplingRateInfo,
+ pAacDecoderChannelInfo[channel]->granuleLength, channel);
+ }
+
+ UCHAR nbands =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[channel]->icsInfo);
+
+ CTns_Apply(&pAacDecoderChannelInfo[channel]->pDynData->TnsData,
+ &pAacDecoderChannelInfo[channel]->icsInfo,
+ pAacDecoderChannelInfo[channel]->pSpectralCoefficient,
+ pSamplingRateInfo, pAacDecoderChannelInfo[channel]->granuleLength,
+ nbands, (elFlags & AC_EL_ENHANCED_NOISE) ? 1 : 0, flags);
+}
+
+static int getWindow2Nr(int length, int shape) {
+ int nr = 0;
+
+ if (shape == 2) {
+ /* Low Overlap, 3/4 zeroed */
+ nr = (length * 3) >> 2;
+ }
+
+ return nr;
+}
+
+FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n) {
+ FIXP_DBL corr = (FIXP_DBL)0;
+ FIXP_DBL ener = (FIXP_DBL)1;
+
+ int headroom_x = getScalefactor(x, n);
+ int headroom_y = getScalefactor(y, n);
+
+ /*Calculate the normalization necessary due to addition*/
+ /* Check for power of two /special case */
+ INT width_shift = (INT)(fNormz((FIXP_DBL)n));
+ /* Get the number of bits necessary minus one, because we need one sign bit
+ * only */
+ width_shift = 31 - width_shift;
+
+ for (int i = 0; i < n; i++) {
+ corr +=
+ fMultDiv2((x[i] << headroom_x), (y[i] << headroom_y)) >> width_shift;
+ ener += fPow2Div2((y[i] << headroom_y)) >> width_shift;
+ }
+
+ int exp_corr = (17 - headroom_x) + (17 - headroom_y) + width_shift + 1;
+ int exp_ener = ((17 - headroom_y) << 1) + width_shift + 1;
+
+ int temp_exp = 0;
+ FIXP_DBL output = fDivNormSigned(corr, ener, &temp_exp);
+
+ int output_exp = (exp_corr - exp_ener) + temp_exp;
+
+ INT output_shift = 17 - output_exp;
+ output_shift = fMin(output_shift, 31);
+
+ output = scaleValue(output, -output_shift);
+
+ return output;
+}
+
+void CBlock_FrequencyToTime(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
+ const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
+ UINT elFlags, INT elCh) {
+ int fr, fl, tl, nSpec;
+
+#if defined(FDK_ASSERT_ENABLE)
+ LONG nSamples;
+#endif
+
+ /* Determine left slope length (fl), right slope length (fr) and transform
+ length (tl). USAC: The slope length may mismatch with the previous frame in
+ case of LPD / FD transitions. The adjustment is handled by the imdct
+ implementation.
+ */
+ tl = frameLen;
+ nSpec = 1;
+
+ switch (pAacDecoderChannelInfo->icsInfo.WindowSequence) {
+ default:
+ case BLOCK_LONG:
+ fl = frameLen;
+ fr = frameLen -
+ getWindow2Nr(frameLen,
+ GetWindowShape(&pAacDecoderChannelInfo->icsInfo));
+ /* New startup needs differentiation between sine shape and low overlap
+ shape. This is a special case for the LD-AAC transformation windows,
+ because the slope length can be different while using the same window
+ sequence. */
+ if (pAacDecoderStaticChannelInfo->IMdct.prev_tl == 0) {
+ fl = fr;
+ }
+ break;
+ case BLOCK_STOP:
+ fl = frameLen >> 3;
+ fr = frameLen;
+ break;
+ case BLOCK_START: /* or StopStartSequence */
+ fl = frameLen;
+ fr = frameLen >> 3;
+ break;
+ case BLOCK_SHORT:
+ fl = fr = frameLen >> 3;
+ tl >>= 3;
+ nSpec = 8;
+ break;
+ }
+
+ {
+ int last_frame_lost = pAacDecoderStaticChannelInfo->last_lpc_lost;
+
+ if (pAacDecoderStaticChannelInfo->last_core_mode == LPD) {
+ INT fac_FB = 1;
+ if (elFlags & AC_EL_FULLBANDLPD) {
+ fac_FB = 2;
+ }
+
+ FIXP_DBL *synth;
+
+ /* Keep some free space at the beginning of the buffer. To be used for
+ * past data */
+ if (!(elFlags & AC_EL_LPDSTEREOIDX)) {
+ synth = pWorkBuffer1 + ((PIT_MAX_MAX - (1 * L_SUBFR)) * fac_FB);
+ } else {
+ synth = pWorkBuffer1 + PIT_MAX_MAX * fac_FB;
+ }
+
+ int fac_length =
+ (pAacDecoderChannelInfo->icsInfo.WindowSequence == BLOCK_SHORT)
+ ? (frameLen >> 4)
+ : (frameLen >> 3);
+
+ INT pitch[NB_SUBFR_SUPERFR + SYN_SFD];
+ FIXP_DBL pit_gain[NB_SUBFR_SUPERFR + SYN_SFD];
+
+ int nbDiv = (elFlags & AC_EL_FULLBANDLPD) ? 2 : 4;
+ int lFrame = (elFlags & AC_EL_FULLBANDLPD) ? frameLen / 2 : frameLen;
+ int nbSubfr =
+ lFrame / (nbDiv * L_SUBFR); /* number of subframes per division */
+ int LpdSfd = (nbDiv * nbSubfr) >> 1;
+ int SynSfd = LpdSfd - BPF_SFD;
+
+ FDKmemclear(
+ pitch,
+ sizeof(
+ pitch)); // added to prevent ferret errors in bass_pf_1sf_delay
+ FDKmemclear(pit_gain, sizeof(pit_gain));
+
+ /* FAC case */
+ if (pAacDecoderStaticChannelInfo->last_lpd_mode == 0 ||
+ pAacDecoderStaticChannelInfo->last_lpd_mode == 4) {
+ FIXP_DBL fac_buf[LFAC];
+ FIXP_LPC *A = pAacDecoderChannelInfo->data.usac.lp_coeff[0];
+
+ if (!frameOk || last_frame_lost ||
+ (pAacDecoderChannelInfo->data.usac.fac_data[0] == NULL)) {
+ FDKmemclear(fac_buf,
+ pAacDecoderChannelInfo->granuleLength * sizeof(FIXP_DBL));
+ pAacDecoderChannelInfo->data.usac.fac_data[0] = fac_buf;
+ pAacDecoderChannelInfo->data.usac.fac_data_e[0] = 0;
+ }
+
+ INT A_exp; /* linear prediction coefficients exponent */
+ {
+ for (int i = 0; i < M_LP_FILTER_ORDER; i++) {
+ A[i] = FX_DBL2FX_LPC(fixp_cos(
+ fMult(pAacDecoderStaticChannelInfo->lpc4_lsf[i],
+ FL2FXCONST_SGL((1 << LSPARG_SCALE) * M_PI / 6400.0)),
+ LSF_SCALE - LSPARG_SCALE));
+ }
+
+ E_LPC_f_lsp_a_conversion(A, A, &A_exp);
+ }
+
+#if defined(FDK_ASSERT_ENABLE)
+ nSamples =
+#endif
+ CLpd_FAC_Acelp2Mdct(
+ &pAacDecoderStaticChannelInfo->IMdct, synth,
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
+ pAacDecoderChannelInfo->specScale, nSpec,
+ pAacDecoderChannelInfo->data.usac.fac_data[0],
+ pAacDecoderChannelInfo->data.usac.fac_data_e[0], fac_length,
+ frameLen, tl,
+ FDKgetWindowSlope(
+ fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fr, A, A_exp, &pAacDecoderStaticChannelInfo->acelp,
+ (FIXP_DBL)0, /* FAC gain has already been applied. */
+ (last_frame_lost || !frameOk), 1,
+ pAacDecoderStaticChannelInfo->last_lpd_mode, 0,
+ pAacDecoderChannelInfo->currAliasingSymmetry);
+
+ } else {
+#if defined(FDK_ASSERT_ENABLE)
+ nSamples =
+#endif
+ imlt_block(
+ &pAacDecoderStaticChannelInfo->IMdct, synth,
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
+ pAacDecoderChannelInfo->specScale, nSpec, frameLen, tl,
+ FDKgetWindowSlope(
+ fl, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fl,
+ FDKgetWindowSlope(
+ fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fr, (FIXP_DBL)0,
+ pAacDecoderChannelInfo->currAliasingSymmetry
+ ? MLT_FLAG_CURR_ALIAS_SYMMETRY
+ : 0);
+ }
+ FDK_ASSERT(nSamples == frameLen);
+
+ /* The "if" clause is entered both for fullbandLpd mono and
+ * non-fullbandLpd*. The "else"-> just for fullbandLpd stereo*/
+ if (!(elFlags & AC_EL_LPDSTEREOIDX)) {
+ FDKmemcpy(pitch, pAacDecoderStaticChannelInfo->old_T_pf,
+ SynSfd * sizeof(INT));
+ FDKmemcpy(pit_gain, pAacDecoderStaticChannelInfo->old_gain_pf,
+ SynSfd * sizeof(FIXP_DBL));
+
+ for (int i = SynSfd; i < LpdSfd + 3; i++) {
+ pitch[i] = L_SUBFR;
+ pit_gain[i] = (FIXP_DBL)0;
+ }
+
+ if (pAacDecoderStaticChannelInfo->last_lpd_mode == 0) {
+ pitch[SynSfd] = pitch[SynSfd - 1];
+ pit_gain[SynSfd] = pit_gain[SynSfd - 1];
+ if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
+ pitch[SynSfd + 1] = pitch[SynSfd];
+ pit_gain[SynSfd + 1] = pit_gain[SynSfd];
+ }
+ }
+
+ /* Copy old data to the beginning of the buffer */
+ {
+ FDKmemcpy(
+ pWorkBuffer1, pAacDecoderStaticChannelInfo->old_synth,
+ ((PIT_MAX_MAX - (1 * L_SUBFR)) * fac_FB) * sizeof(FIXP_DBL));
+ }
+
+ FIXP_DBL *p2_synth = pWorkBuffer1 + (PIT_MAX_MAX * fac_FB);
+
+ /* recalculate pitch gain to allow postfilering on FAC area */
+ for (int i = 0; i < SynSfd + 2; i++) {
+ int T = pitch[i];
+ FIXP_DBL gain = pit_gain[i];
+
+ if (gain > (FIXP_DBL)0) {
+ gain = get_gain(&p2_synth[i * L_SUBFR * fac_FB],
+ &p2_synth[(i * L_SUBFR * fac_FB) - fac_FB * T],
+ L_SUBFR * fac_FB);
+ pit_gain[i] = gain;
+ }
+ }
+
+ bass_pf_1sf_delay(p2_synth, pitch, pit_gain, frameLen,
+ (LpdSfd + 2) * L_SUBFR + BPF_SFD * L_SUBFR,
+ frameLen - (LpdSfd + 4) * L_SUBFR, outSamples,
+ pAacDecoderStaticChannelInfo->mem_bpf);
+ }
+
+ } else /* last_core_mode was not LPD */
+ {
+ FIXP_DBL *tmp =
+ pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1->mdctOutTemp;
+#if defined(FDK_ASSERT_ENABLE)
+ nSamples =
+#endif
+ imlt_block(&pAacDecoderStaticChannelInfo->IMdct, tmp,
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
+ pAacDecoderChannelInfo->specScale, nSpec, frameLen, tl,
+ FDKgetWindowSlope(
+ fl, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fl,
+ FDKgetWindowSlope(
+ fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fr, (FIXP_DBL)0,
+ pAacDecoderChannelInfo->currAliasingSymmetry
+ ? MLT_FLAG_CURR_ALIAS_SYMMETRY
+ : 0);
+
+ scaleValuesSaturate(outSamples, tmp, frameLen, MDCT_OUT_HEADROOM);
+ }
+ }
+
+ FDK_ASSERT(nSamples == frameLen);
+
+ pAacDecoderStaticChannelInfo->last_core_mode =
+ (pAacDecoderChannelInfo->icsInfo.WindowSequence == BLOCK_SHORT) ? FD_SHORT
+ : FD_LONG;
+ pAacDecoderStaticChannelInfo->last_lpd_mode = 255;
+}
+
+#include "ldfiltbank.h"
+void CBlock_FrequencyToTimeLowDelay(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
+ const short frameLen) {
+ InvMdctTransformLowDelay_fdk(
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
+ pAacDecoderChannelInfo->specScale[0], outSamples,
+ pAacDecoderStaticChannelInfo->pOverlapBuffer, frameLen);
+}
diff --git a/fdk-aac/libAACdec/src/block.h b/fdk-aac/libAACdec/src/block.h
new file mode 100644
index 0000000..f0f56cd
--- /dev/null
+++ b/fdk-aac/libAACdec/src/block.h
@@ -0,0 +1,345 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: long/short-block decoding
+
+*******************************************************************************/
+
+#ifndef BLOCK_H
+#define BLOCK_H
+
+#include "common_fix.h"
+
+#include "channelinfo.h"
+#include "FDK_bitstream.h"
+
+/* PNS (of block) */
+void CPns_Read(CPnsData *pPnsData, HANDLE_FDK_BITSTREAM bs,
+ const CodeBookDescription *hcb, SHORT *pScaleFactor,
+ UCHAR global_gain, int band, int group);
+
+void CPns_Apply(const CPnsData *pPnsData, const CIcsInfo *pIcsInfo,
+ SPECTRAL_PTR pSpectrum, const SHORT *pSpecScale,
+ const SHORT *pScaleFactor,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const INT granuleLength, const int channel);
+
+void CBlock_ApplyNoise(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ SamplingRateInfo *pSamplingRateInfo, ULONG *nfRandomSeed,
+ UCHAR *band_is_noise);
+
+/* TNS (of block) */
+/*!
+ \brief Read tns data-present flag from bitstream
+
+ The function reads the data-present flag for tns from
+ the bitstream.
+
+ \return none
+*/
+void CTns_ReadDataPresentFlag(HANDLE_FDK_BITSTREAM bs, CTnsData *pTnsData);
+
+void CTns_ReadDataPresentUsac(HANDLE_FDK_BITSTREAM hBs, CTnsData *pTnsData0,
+ CTnsData *pTnsData1, UCHAR *ptns_on_lr,
+ const CIcsInfo *pIcsInfo, const UINT flags,
+ const UINT elFlags, const int fCommonWindow);
+
+AAC_DECODER_ERROR CTns_Read(HANDLE_FDK_BITSTREAM bs, CTnsData *pTnsData,
+ const CIcsInfo *pIcsInfo, const UINT flags);
+
+void CTns_Apply(CTnsData *RESTRICT pTnsData, /*!< pointer to aac decoder info */
+ const CIcsInfo *pIcsInfo, SPECTRAL_PTR pSpectralCoefficient,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const INT granuleLength, const UCHAR nbands,
+ const UCHAR igf_active, const UINT flags);
+
+/* Block */
+
+LONG CBlock_GetEscape(HANDLE_FDK_BITSTREAM bs, const LONG q);
+
+/**
+ * \brief Read scale factor data. See chapter 4.6.2.3.2 of ISO/IEC 14496-3.
+ * The SF_OFFSET = 100 value referenced in chapter 4.6.2.3.3 is already
+ * substracted from the scale factor values. Also includes PNS data reading.
+ * \param bs bit stream handle data source
+ * \param pAacDecoderChannelInfo channel context info were decoded data is
+ * stored into.
+ * \param flags the decoder flags.
+ */
+AAC_DECODER_ERROR CBlock_ReadScaleFactorData(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, HANDLE_FDK_BITSTREAM bs,
+ const UINT flags);
+
+/**
+ * \brief Read Huffman encoded spectral data.
+ * \param pAacDecoderChannelInfo channel context info.
+ * \param pSamplingRateInfo sampling rate info (sfb offsets).
+ * \param flags syntax flags.
+ */
+AAC_DECODER_ERROR CBlock_ReadSpectralData(
+ HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags);
+
+/**
+ * \brief Read Arithmetic encoded spectral data.
+ * \param pAacDecoderChannelInfo channel context info.
+ * \param pAacDecoderStaticChannelInfo static channel context info.
+ * \param pSamplingRateInfo sampling rate info (sfb offsets).
+ * \param frame_length spectral window length.
+ * \param flags syntax flags.
+ * \return error code.
+ */
+AAC_DECODER_ERROR CBlock_ReadAcSpectralData(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT frame_length,
+ const UINT flags);
+
+AAC_DECODER_ERROR CBlock_ReadSectionData(
+ HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags);
+
+/**
+ * \brief find a common exponent (shift factor) for all sfb in each Spectral
+ * window, and store them into CAacDecoderChannelInfo::specScale.
+ * \param pAacDecoderChannelInfo channel context info.
+ * \param UCHAR maxSfbs maximum number of SFBs to be processed (might differ
+ * from pAacDecoderChannelInfo->icsInfo.MaxSfBands)
+ * \param pSamplingRateInfo sampling rate info (sfb offsets).
+ */
+void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ UCHAR maxSfbs,
+ SamplingRateInfo *pSamplingRateInfo);
+
+/**
+ * \brief Apply TNS and PNS tools.
+ */
+void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags,
+ const UINT elFlags, const int channel, const int maybe_jstereo);
+
+/**
+ * \brief Transform MDCT spectral data into time domain
+ */
+void CBlock_FrequencyToTime(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
+ const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
+ UINT elFlags, INT elCh);
+
+/**
+ * \brief Transform double lapped MDCT (AAC-ELD) spectral data into time domain.
+ */
+void CBlock_FrequencyToTimeLowDelay(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
+ const short frameLen);
+
+AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ SamplingRateInfo *pSamplingRateInfo, UCHAR *band_is_noise,
+ UCHAR active_band_search);
+
+/**
+ * \brief Calculate 2^(lsb/4) * value^(4/3)
+ * \param pValue pointer to quantized value. The inverse quantized result is
+ * stored back here.
+ * \param lsb 2 LSBs of the scale factor (scaleFactor % 4) applied as power 2
+ * factor to the resulting inverse quantized value.
+ * \return the exponent of the result (mantissa) stored into *pValue.
+ */
+FDK_INLINE
+int EvaluatePower43(FIXP_DBL *pValue, UINT lsb) {
+ FIXP_DBL value;
+ UINT freeBits;
+ UINT exponent;
+
+ value = *pValue;
+ freeBits = fNormz(value);
+ exponent = DFRACT_BITS - freeBits;
+ FDK_ASSERT(exponent < 14);
+
+ UINT x = (((int)value << freeBits) >> 19);
+ UINT tableIndex = (x & 0x0FFF) >> 4;
+ FIXP_DBL invQVal;
+
+ x = x & 0x0F;
+
+ UINT r0 = (LONG)InverseQuantTable[tableIndex + 0];
+ UINT r1 = (LONG)InverseQuantTable[tableIndex + 1];
+ USHORT nx = 16 - x;
+ UINT temp = (r0)*nx + (r1)*x;
+ invQVal = (FIXP_DBL)temp;
+
+ FDK_ASSERT(lsb < 4);
+ *pValue = fMultDiv2(invQVal, MantissaTable[lsb][exponent]);
+
+ /* + 1 compensates fMultDiv2(). */
+ return ExponentTable[lsb][exponent] + 1;
+}
+
+/* Recalculate gain */
+FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n);
+
+/**
+ * \brief determine the required shift scale for the given quantized value and
+ * scale (factor % 4) value.
+ */
+FDK_INLINE int GetScaleFromValue(FIXP_DBL value, unsigned int lsb) {
+ if (value != (FIXP_DBL)0) {
+ int scale = EvaluatePower43(&value, lsb);
+ return CntLeadingZeros(value) - scale - 2;
+ } else
+ return 0; /* Return zero, because its useless to scale a zero value, saves
+ workload and avoids scaling overshifts. */
+}
+
+/*!
+ \brief Read huffman codeword
+
+ The function reads the huffman codeword from the bitstream and
+ returns the index value.
+
+ \return index value
+*/
+inline int CBlock_DecodeHuffmanWord(
+ HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
+ const CodeBookDescription *hcb) /*!< pointer to codebook description */
+{
+ UINT val;
+ UINT index = 0;
+ const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook;
+
+ while (1) {
+ val = CodeBook[index]
+ [FDKreadBits(bs, HuffmanBits)]; /* Expensive memory access */
+
+ if ((val & 1) == 0) {
+ index = val >> 2;
+ continue;
+ } else {
+ if (val & 2) {
+ FDKpushBackCache(bs, 1);
+ }
+
+ val >>= 2;
+ break;
+ }
+ }
+
+ return val;
+}
+inline int CBlock_DecodeHuffmanWordCB(
+ HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
+ const USHORT (
+ *CodeBook)[HuffmanEntries]) /*!< pointer to codebook description */
+{
+ UINT index = 0;
+
+ while (1) {
+ index = CodeBook[index][FDKread2Bits(bs)]; /* Expensive memory access */
+ if (index & 1) break;
+ index >>= 2;
+ }
+ if (index & 2) {
+ FDKpushBackCache(bs, 1);
+ }
+ return index >> 2;
+}
+
+#endif /* #ifndef BLOCK_H */
diff --git a/fdk-aac/libAACdec/src/channel.cpp b/fdk-aac/libAACdec/src/channel.cpp
new file mode 100644
index 0000000..a020034
--- /dev/null
+++ b/fdk-aac/libAACdec/src/channel.cpp
@@ -0,0 +1,924 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#include "channel.h"
+#include "aacdecoder.h"
+#include "block.h"
+#include "aacdec_tns.h"
+#include "FDK_bitstream.h"
+
+#include "conceal.h"
+
+#include "rvlc.h"
+
+#include "aacdec_hcr.h"
+
+#include "usacdec_lpd.h"
+#include "usacdec_fac.h"
+
+static void MapMidSideMaskToPnsCorrelation(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[2]) {
+ int group;
+
+ for (group = 0; group < pAacDecoderChannelInfo[L]->icsInfo.WindowGroups;
+ group++) {
+ UCHAR groupMask = 1 << group;
+
+ for (UCHAR band = 0; band < pAacDecoderChannelInfo[L]->icsInfo.MaxSfBands;
+ band++) {
+ if (pAacDecoderChannelInfo[L]->pComData->jointStereoData.MsUsed[band] &
+ groupMask) { /* channels are correlated */
+ CPns_SetCorrelation(&pAacDecoderChannelInfo[L]->data.aac.PnsData, group,
+ band, 0);
+
+ if (CPns_IsPnsUsed(&pAacDecoderChannelInfo[L]->data.aac.PnsData, group,
+ band) &&
+ CPns_IsPnsUsed(&pAacDecoderChannelInfo[R]->data.aac.PnsData, group,
+ band))
+ pAacDecoderChannelInfo[L]->pComData->jointStereoData.MsUsed[band] ^=
+ groupMask; /* clear the groupMask-bit */
+ }
+ }
+ }
+}
+
+static void Clean_Complex_Prediction_coefficients(
+ CJointStereoPersistentData *pJointStereoPersistentData, int windowGroups,
+ const int low_limit, const int high_limit) {
+ for (int group = 0; group < windowGroups; group++) {
+ for (int sfb = low_limit; sfb < high_limit; sfb++) {
+ pJointStereoPersistentData->alpha_q_re_prev[group][sfb] = 0;
+ pJointStereoPersistentData->alpha_q_im_prev[group][sfb] = 0;
+ }
+ }
+}
+
+/*!
+ \brief Decode channel pair element
+
+ The function decodes a channel pair element.
+
+ \return none
+*/
+void CChannelElement_Decode(
+ CAacDecoderChannelInfo
+ *pAacDecoderChannelInfo[2], /*!< pointer to aac decoder channel info */
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
+ SamplingRateInfo *pSamplingRateInfo, UINT flags, UINT elFlags,
+ int el_channels) {
+ int ch = 0;
+
+ int maxSfBandsL = 0, maxSfBandsR = 0;
+ int maybe_jstereo = (el_channels > 1);
+
+ if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && el_channels == 2) {
+ if (pAacDecoderChannelInfo[L]->data.usac.core_mode ||
+ pAacDecoderChannelInfo[R]->data.usac.core_mode) {
+ maybe_jstereo = 0;
+ }
+ }
+
+ if (maybe_jstereo) {
+ maxSfBandsL =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[L]->icsInfo);
+ maxSfBandsR =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[R]->icsInfo);
+
+ /* apply ms */
+ if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
+ if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ if (pAacDecoderChannelInfo[L]->data.aac.PnsData.PnsActive ||
+ pAacDecoderChannelInfo[R]->data.aac.PnsData.PnsActive) {
+ MapMidSideMaskToPnsCorrelation(pAacDecoderChannelInfo);
+ }
+ }
+ /* if tns_on_lr == 1 run MS */ /* &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_active
+ == 1) */
+ if (((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
+ 1)) ||
+ ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) == 0)) {
+ int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);
+
+ CJointStereo_ApplyMS(
+ pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ pAacDecoderChannelInfo[L]->pSpectralCoefficient,
+ pAacDecoderChannelInfo[R]->pSpectralCoefficient,
+ pAacDecoderChannelInfo[L]->pDynData->aSfbScale,
+ pAacDecoderChannelInfo[R]->pDynData->aSfbScale,
+ pAacDecoderChannelInfo[L]->specScale,
+ pAacDecoderChannelInfo[R]->specScale,
+ GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
+ pSamplingRateInfo),
+ GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
+ GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), max_sfb_ste,
+ maxSfBandsL, maxSfBandsR,
+ pAacDecoderChannelInfo[L]
+ ->pComData->jointStereoData.store_dmx_re_prev,
+ &(pAacDecoderChannelInfo[L]
+ ->pComData->jointStereoData.store_dmx_re_prev_e),
+ 1);
+
+ } /* if ( ((elFlags & AC_EL_USAC_CP_POSSIBLE).... */
+ } /* if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow)*/
+
+ /* apply intensity stereo */ /* modifies pAacDecoderChannelInfo[]->aSpecSfb
+ */
+ if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ if ((pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ==
+ 1) &&
+ (el_channels == 2)) {
+ CJointStereo_ApplyIS(
+ pAacDecoderChannelInfo,
+ GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
+ pSamplingRateInfo),
+ GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
+ GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo),
+ GetScaleFactorBandsTransmitted(
+ &pAacDecoderChannelInfo[L]->icsInfo));
+ }
+ }
+ } /* maybe_stereo */
+
+ for (ch = 0; ch < el_channels; ch++) {
+ if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_LPD) {
+ /* Decode LPD data */
+ CLpdChannelStream_Decode(pAacDecoderChannelInfo[ch],
+ pAacDecoderStaticChannelInfo[ch], flags);
+ } else {
+ UCHAR noSfbs =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[ch]->icsInfo);
+ /* For USAC common window: max_sfb of both channels may differ
+ * (common_max_sfb == 0). */
+ if ((maybe_jstereo == 1) &&
+ (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ==
+ 1)) {
+ noSfbs = fMax(maxSfBandsL, maxSfBandsR);
+ }
+ int CP_active = 0;
+ if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
+ CP_active = pAacDecoderChannelInfo[ch]
+ ->pComData->jointStereoData.cplx_pred_flag;
+ }
+
+ /* Omit writing of pAacDecoderChannelInfo[ch]->specScale for complex
+ stereo prediction since scaling has already been carried out. */
+ int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);
+
+ if ((!CP_active) || (CP_active && (max_sfb_ste < noSfbs)) ||
+ ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
+ 0))) {
+ CBlock_ScaleSpectralData(pAacDecoderChannelInfo[ch], noSfbs,
+ pSamplingRateInfo);
+
+ /*Active for the case of TNS applied before MS/CP*/
+ if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
+ 0)) {
+ if (IsLongBlock(&pAacDecoderChannelInfo[ch]->icsInfo)) {
+ for (int i = 0; i < noSfbs; i++) {
+ pAacDecoderChannelInfo[ch]->pDynData->aSfbScale[i] =
+ pAacDecoderChannelInfo[ch]->specScale[0];
+ }
+ } else {
+ for (int i = 0; i < 8; i++) {
+ for (int j = 0; j < noSfbs; j++) {
+ pAacDecoderChannelInfo[ch]->pDynData->aSfbScale[i * 16 + j] =
+ pAacDecoderChannelInfo[ch]->specScale[i];
+ }
+ }
+ }
+ }
+ }
+ }
+ } /* End "for (ch = 0; ch < el_channels; ch++)" */
+
+ if (maybe_jstereo) {
+ /* apply ms */
+ if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
+ } /* CommonWindow */
+ else {
+ if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
+ FDKmemclear(
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.alpha_q_re_prev,
+ JointStereoMaximumGroups * JointStereoMaximumBands * sizeof(SHORT));
+ FDKmemclear(
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.alpha_q_im_prev,
+ JointStereoMaximumGroups * JointStereoMaximumBands * sizeof(SHORT));
+ }
+ }
+
+ } /* if (maybe_jstereo) */
+
+ for (ch = 0; ch < el_channels; ch++) {
+ if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_LPD) {
+ } else {
+ if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ /* Use same seed for coupled channels (CPE) */
+ int pnsCh = (ch > 0) ? L : ch;
+ CPns_UpdateNoiseState(
+ &pAacDecoderChannelInfo[ch]->data.aac.PnsData,
+ pAacDecoderChannelInfo[pnsCh]->data.aac.PnsData.currentSeed,
+ pAacDecoderChannelInfo[ch]->pComData->pnsRandomSeed);
+ }
+
+ if ((!(flags & (AC_USAC))) ||
+ ((flags & (AC_USAC)) &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_active ==
+ 1)) ||
+ (maybe_jstereo == 0)) {
+ ApplyTools(
+ pAacDecoderChannelInfo, pSamplingRateInfo, flags, elFlags, ch,
+ pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow);
+ }
+ } /* End "} else" */
+ } /* End "for (ch = 0; ch < el_channels; ch++)" */
+
+ if (maybe_jstereo) {
+ /* apply ms */
+ if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
+ /* if tns_on_lr == 0 run MS */
+ if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
+ 0)) {
+ int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);
+
+ CJointStereo_ApplyMS(
+ pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ pAacDecoderChannelInfo[L]->pSpectralCoefficient,
+ pAacDecoderChannelInfo[R]->pSpectralCoefficient,
+ pAacDecoderChannelInfo[L]->pDynData->aSfbScale,
+ pAacDecoderChannelInfo[R]->pDynData->aSfbScale,
+ pAacDecoderChannelInfo[L]->specScale,
+ pAacDecoderChannelInfo[R]->specScale,
+ GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
+ pSamplingRateInfo),
+ GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
+ GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), max_sfb_ste,
+ maxSfBandsL, maxSfBandsR,
+ pAacDecoderChannelInfo[L]
+ ->pComData->jointStereoData.store_dmx_re_prev,
+ &(pAacDecoderChannelInfo[L]
+ ->pComData->jointStereoData.store_dmx_re_prev_e),
+ 1);
+ }
+
+ } /* if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) */
+
+ } /* if (maybe_jstereo) */
+
+ for (ch = 0; ch < el_channels; ch++) {
+ if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.clearSpectralCoeffs = 0;
+ }
+ }
+
+ CRvlc_ElementCheck(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ flags, el_channels);
+}
+
+void CChannel_CodebookTableInit(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ int b, w, maxBands, maxWindows;
+ int maxSfb = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+
+ if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
+ maxBands = 64;
+ maxWindows = 1;
+ } else {
+ maxBands = 16;
+ maxWindows = 8;
+ }
+
+ for (w = 0; w < maxWindows; w++) {
+ for (b = 0; b < maxSfb; b++) {
+ pCodeBook[b] = ESCBOOK;
+ }
+ for (; b < maxBands; b++) {
+ pCodeBook[b] = ZERO_HCB;
+ }
+ pCodeBook += maxBands;
+ }
+}
+
+/*
+ * Arbitrary order bitstream parser
+ */
+AAC_DECODER_ERROR CChannelElement_Read(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ const AUDIO_OBJECT_TYPE aot, SamplingRateInfo *pSamplingRateInfo,
+ const UINT flags, const UINT elFlags, const UINT frame_length,
+ const UCHAR numberOfChannels, const SCHAR epConfig,
+ HANDLE_TRANSPORTDEC pTpDec) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ const element_list_t *list;
+ int i, ch, decision_bit;
+ int crcReg1 = -1, crcReg2 = -1;
+ int cplxPred;
+ int ind_sw_cce_flag = 0, num_gain_element_lists = 0;
+
+ FDK_ASSERT((numberOfChannels == 1) || (numberOfChannels == 2));
+
+ /* Get channel element sequence table */
+ list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, elFlags);
+ if (list == NULL) {
+ error = AAC_DEC_UNSUPPORTED_FORMAT;
+ goto bail;
+ }
+
+ CTns_Reset(&pAacDecoderChannelInfo[0]->pDynData->TnsData);
+ /* Set common window to 0 by default. If signalized in the bit stream it will
+ * be overwritten later explicitely */
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 0;
+ if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
+ pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active = 0;
+ pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr = 0;
+ }
+ if (numberOfChannels == 2) {
+ CTns_Reset(&pAacDecoderChannelInfo[1]->pDynData->TnsData);
+ pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow = 0;
+ }
+
+ cplxPred = 0;
+ if (pAacDecoderStaticChannelInfo != NULL) {
+ if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
+ pAacDecoderChannelInfo[0]->pComData->jointStereoData.cplx_pred_flag = 0;
+ cplxPred = 1;
+ }
+ }
+
+ if (0 || (flags & (AC_ELD | AC_SCALABLE))) {
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 1;
+ if (numberOfChannels == 2) {
+ pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow =
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow;
+ }
+ }
+
+ /* Iterate through sequence table */
+ i = 0;
+ ch = 0;
+ decision_bit = 0;
+ do {
+ switch (list->id[i]) {
+ case element_instance_tag:
+ pAacDecoderChannelInfo[0]->ElementInstanceTag = FDKreadBits(hBs, 4);
+ if (numberOfChannels == 2) {
+ pAacDecoderChannelInfo[1]->ElementInstanceTag =
+ pAacDecoderChannelInfo[0]->ElementInstanceTag;
+ }
+ break;
+ case common_window:
+ decision_bit =
+ pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.CommonWindow =
+ FDKreadBits(hBs, 1);
+ if (numberOfChannels == 2) {
+ pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow =
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow;
+ }
+ break;
+ case ics_info:
+ /* store last window sequence (utilized in complex stereo prediction)
+ * before reading new channel-info */
+ if (cplxPred) {
+ if (pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow) {
+ pAacDecoderStaticChannelInfo[0]
+ ->pCpeStaticData->jointStereoPersistentData.winSeqPrev =
+ pAacDecoderChannelInfo[0]->icsInfo.WindowSequence;
+ pAacDecoderStaticChannelInfo[0]
+ ->pCpeStaticData->jointStereoPersistentData.winShapePrev =
+ pAacDecoderChannelInfo[0]->icsInfo.WindowShape;
+ }
+ }
+ /* Read individual channel info */
+ error = IcsRead(hBs, &pAacDecoderChannelInfo[ch]->icsInfo,
+ pSamplingRateInfo, flags);
+
+ if (elFlags & AC_EL_LFE &&
+ GetWindowSequence(&pAacDecoderChannelInfo[ch]->icsInfo) !=
+ BLOCK_LONG) {
+ error = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+
+ if (numberOfChannels == 2 &&
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow) {
+ pAacDecoderChannelInfo[1]->icsInfo =
+ pAacDecoderChannelInfo[0]->icsInfo;
+ }
+ break;
+
+ case common_max_sfb:
+ if (FDKreadBit(hBs) == 0) {
+ error = IcsReadMaxSfb(hBs, &pAacDecoderChannelInfo[1]->icsInfo,
+ pSamplingRateInfo);
+ }
+ break;
+
+ case ltp_data_present:
+ if (FDKreadBits(hBs, 1) != 0) {
+ error = AAC_DEC_UNSUPPORTED_PREDICTION;
+ }
+ break;
+
+ case ms:
+
+ INT max_sfb_ste;
+ INT max_sfb_ste_clear;
+
+ max_sfb_ste = GetScaleMaxFactorBandsTransmitted(
+ &pAacDecoderChannelInfo[0]->icsInfo,
+ &pAacDecoderChannelInfo[1]->icsInfo);
+
+ max_sfb_ste_clear = 64;
+
+ pAacDecoderChannelInfo[0]->icsInfo.max_sfb_ste = (UCHAR)max_sfb_ste;
+ pAacDecoderChannelInfo[1]->icsInfo.max_sfb_ste = (UCHAR)max_sfb_ste;
+
+ if (flags & (AC_USAC | AC_RSV603DA) &&
+ pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.CommonWindow ==
+ 0) {
+ Clean_Complex_Prediction_coefficients(
+ &pAacDecoderStaticChannelInfo[0]
+ ->pCpeStaticData->jointStereoPersistentData,
+ GetWindowGroups(&pAacDecoderChannelInfo[0]->icsInfo), 0, 64);
+ }
+
+ if (CJointStereo_Read(
+ hBs, &pAacDecoderChannelInfo[0]->pComData->jointStereoData,
+ GetWindowGroups(&pAacDecoderChannelInfo[0]->icsInfo),
+ max_sfb_ste, max_sfb_ste_clear,
+ /* jointStereoPersistentData and cplxPredictionData are only
+ available/allocated if cplxPred is active. */
+ ((cplxPred == 0) || (pAacDecoderStaticChannelInfo == NULL))
+ ? NULL
+ : &pAacDecoderStaticChannelInfo[0]
+ ->pCpeStaticData->jointStereoPersistentData,
+ ((cplxPred == 0) || (pAacDecoderChannelInfo[0] == NULL))
+ ? NULL
+ : pAacDecoderChannelInfo[0]
+ ->pComStaticData->cplxPredictionData,
+ cplxPred,
+ GetScaleFactorBandsTotal(&pAacDecoderChannelInfo[0]->icsInfo),
+ GetWindowSequence(&pAacDecoderChannelInfo[0]->icsInfo),
+ flags)) {
+ error = AAC_DEC_PARSE_ERROR;
+ }
+
+ break;
+
+ case global_gain:
+ pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.GlobalGain =
+ (UCHAR)FDKreadBits(hBs, 8);
+ break;
+
+ case section_data:
+ error = CBlock_ReadSectionData(hBs, pAacDecoderChannelInfo[ch],
+ pSamplingRateInfo, flags);
+ break;
+
+ case scale_factor_data_usac:
+ pAacDecoderChannelInfo[ch]->currAliasingSymmetry = 0;
+ /* Set active sfb codebook indexes to HCB_ESC to make them "active" */
+ CChannel_CodebookTableInit(
+ pAacDecoderChannelInfo[ch]); /* equals ReadSectionData(self,
+ bs) in float soft. block.c
+ line: ~599 */
+ /* Note: The missing "break" is intentional here, since we need to call
+ * CBlock_ReadScaleFactorData(). */
+ FDK_FALLTHROUGH;
+
+ case scale_factor_data:
+ if (flags & AC_ER_RVLC) {
+ /* read RVLC data from bitstream (error sens. cat. 1) */
+ CRvlc_Read(pAacDecoderChannelInfo[ch], hBs);
+ } else {
+ error = CBlock_ReadScaleFactorData(pAacDecoderChannelInfo[ch], hBs,
+ flags);
+ }
+ break;
+
+ case pulse:
+ if (CPulseData_Read(
+ hBs,
+ &pAacDecoderChannelInfo[ch]->pDynData->specificTo.aac.PulseData,
+ pSamplingRateInfo->ScaleFactorBands_Long, /* pulse data is only
+ allowed to be
+ present in long
+ blocks! */
+ (void *)&pAacDecoderChannelInfo[ch]->icsInfo,
+ frame_length) != 0) {
+ error = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ break;
+ case tns_data_present:
+ CTns_ReadDataPresentFlag(
+ hBs, &pAacDecoderChannelInfo[ch]->pDynData->TnsData);
+ if (elFlags & AC_EL_LFE &&
+ pAacDecoderChannelInfo[ch]->pDynData->TnsData.DataPresent) {
+ error = AAC_DEC_PARSE_ERROR;
+ }
+ break;
+ case tns_data:
+ /* tns_data_present is checked inside CTns_Read(). */
+ error = CTns_Read(hBs, &pAacDecoderChannelInfo[ch]->pDynData->TnsData,
+ &pAacDecoderChannelInfo[ch]->icsInfo, flags);
+
+ break;
+
+ case gain_control_data:
+ break;
+
+ case gain_control_data_present:
+ if (FDKreadBits(hBs, 1)) {
+ error = AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA;
+ }
+ break;
+
+ case tw_data:
+ break;
+ case common_tw:
+ break;
+ case tns_data_present_usac:
+ if (pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active) {
+ CTns_ReadDataPresentUsac(
+ hBs, &pAacDecoderChannelInfo[0]->pDynData->TnsData,
+ &pAacDecoderChannelInfo[1]->pDynData->TnsData,
+ &pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr,
+ &pAacDecoderChannelInfo[0]->icsInfo, flags, elFlags,
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow);
+ } else {
+ pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr =
+ (UCHAR)1;
+ }
+ break;
+ case core_mode:
+ decision_bit = FDKreadBits(hBs, 1);
+ pAacDecoderChannelInfo[ch]->data.usac.core_mode = decision_bit;
+ if ((ch == 1) && (pAacDecoderChannelInfo[0]->data.usac.core_mode !=
+ pAacDecoderChannelInfo[1]->data.usac.core_mode)) {
+ /* StereoCoreToolInfo(core_mode[ch] ) */
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 0;
+ pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow = 0;
+ }
+ break;
+ case tns_active:
+ pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active =
+ FDKreadBit(hBs);
+ break;
+ case noise:
+ if (elFlags & AC_EL_USAC_NOISE) {
+ pAacDecoderChannelInfo[ch]
+ ->pDynData->specificTo.usac.fd_noise_level_and_offset =
+ FDKreadBits(hBs, 3 + 5); /* Noise level */
+ }
+ break;
+ case lpd_channel_stream:
+
+ {
+ error = CLpdChannelStream_Read(/* = lpd_channel_stream() */
+ hBs, pAacDecoderChannelInfo[ch],
+ pAacDecoderStaticChannelInfo[ch],
+ pSamplingRateInfo, flags);
+ }
+
+ pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_LPD;
+ break;
+ case fac_data: {
+ int fFacDatPresent = FDKreadBit(hBs);
+
+ /* Wee need a valid fac_data[0] even if no FAC data is present (as
+ * temporal buffer) */
+ pAacDecoderChannelInfo[ch]->data.usac.fac_data[0] =
+ pAacDecoderChannelInfo[ch]->data.usac.fac_data0;
+
+ if (fFacDatPresent) {
+ if (elFlags & AC_EL_LFE) {
+ error = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ /* FAC data present, this frame is FD, so the last mode had to be
+ * ACELP. */
+ if (pAacDecoderStaticChannelInfo[ch]->last_core_mode != LPD ||
+ pAacDecoderStaticChannelInfo[ch]->last_lpd_mode != 0) {
+ pAacDecoderChannelInfo[ch]->data.usac.core_mode_last = LPD;
+ pAacDecoderChannelInfo[ch]->data.usac.lpd_mode_last = 0;
+ /* We can't change the past! So look to the future and go ahead! */
+ }
+ CLpd_FAC_Read(hBs, pAacDecoderChannelInfo[ch]->data.usac.fac_data[0],
+ pAacDecoderChannelInfo[ch]->data.usac.fac_data_e,
+ CLpd_FAC_getLength(
+ IsLongBlock(&pAacDecoderChannelInfo[ch]->icsInfo),
+ pAacDecoderChannelInfo[ch]->granuleLength),
+ 1, 0);
+ } else {
+ if (pAacDecoderStaticChannelInfo[ch]->last_core_mode == LPD &&
+ pAacDecoderStaticChannelInfo[ch]->last_lpd_mode == 0) {
+ /* ACELP to FD transitons without FAC are possible. That is why we
+ zero it out (i.e FAC will not be considered in the subsequent
+ calculations */
+ FDKmemclear(pAacDecoderChannelInfo[ch]->data.usac.fac_data0,
+ LFAC * sizeof(FIXP_DBL));
+ }
+ }
+ } break;
+ case esc2_rvlc:
+ if (flags & AC_ER_RVLC) {
+ CRvlc_Decode(pAacDecoderChannelInfo[ch],
+ pAacDecoderStaticChannelInfo[ch], hBs);
+ }
+ break;
+
+ case esc1_hcr:
+ if (flags & AC_ER_HCR) {
+ CHcr_Read(hBs, pAacDecoderChannelInfo[ch],
+ numberOfChannels == 2 ? ID_CPE : ID_SCE);
+ }
+ break;
+
+ case spectral_data:
+ error = CBlock_ReadSpectralData(hBs, pAacDecoderChannelInfo[ch],
+ pSamplingRateInfo, flags);
+ if (flags & AC_ELD) {
+ pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_ELDFB;
+ } else {
+ if (flags & AC_HDAAC) {
+ pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_INTIMDCT;
+ } else {
+ pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_IMDCT;
+ }
+ }
+ break;
+
+ case ac_spectral_data:
+ error = CBlock_ReadAcSpectralData(
+ hBs, pAacDecoderChannelInfo[ch], pAacDecoderStaticChannelInfo[ch],
+ pSamplingRateInfo, frame_length, flags);
+ pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_IMDCT;
+ break;
+
+ case coupled_elements: {
+ int num_coupled_elements, c;
+
+ ind_sw_cce_flag = FDKreadBit(hBs);
+ num_coupled_elements = FDKreadBits(hBs, 3);
+
+ for (c = 0; c < (num_coupled_elements + 1); c++) {
+ int cc_target_is_cpe;
+
+ num_gain_element_lists++;
+ cc_target_is_cpe = FDKreadBit(hBs); /* cc_target_is_cpe[c] */
+ FDKreadBits(hBs, 4); /* cc_target_tag_select[c] */
+
+ if (cc_target_is_cpe) {
+ int cc_l, cc_r;
+
+ cc_l = FDKreadBit(hBs); /* cc_l[c] */
+ cc_r = FDKreadBit(hBs); /* cc_r[c] */
+
+ if (cc_l && cc_r) {
+ num_gain_element_lists++;
+ }
+ }
+ }
+ FDKreadBit(hBs); /* cc_domain */
+ FDKreadBit(hBs); /* gain_element_sign */
+ FDKreadBits(hBs, 2); /* gain_element_scale */
+ } break;
+
+ case gain_element_lists: {
+ const CodeBookDescription *hcb;
+ UCHAR *pCodeBook;
+ int c;
+
+ hcb = &AACcodeBookDescriptionTable[BOOKSCL];
+ pCodeBook = pAacDecoderChannelInfo[ch]->pDynData->aCodeBook;
+
+ for (c = 1; c < num_gain_element_lists; c++) {
+ int cge;
+ if (ind_sw_cce_flag) {
+ cge = 1;
+ } else {
+ cge = FDKreadBits(hBs, 1); /* common_gain_element_present[c] */
+ }
+ if (cge) {
+ /* Huffman */
+ CBlock_DecodeHuffmanWord(
+ hBs, hcb); /* hcod_sf[common_gain_element[c]] 1..19 */
+ } else {
+ int g, sfb;
+ for (g = 0;
+ g < GetWindowGroups(&pAacDecoderChannelInfo[ch]->icsInfo);
+ g++) {
+ for (sfb = 0; sfb < GetScaleFactorBandsTransmitted(
+ &pAacDecoderChannelInfo[ch]->icsInfo);
+ sfb++) {
+ if (pCodeBook[sfb] != ZERO_HCB) {
+ /* Huffman */
+ CBlock_DecodeHuffmanWord(
+ hBs,
+ hcb); /* hcod_sf[dpcm_gain_element[c][g][sfb]] 1..19 */
+ }
+ }
+ }
+ }
+ }
+ } break;
+
+ /* CRC handling */
+ case adtscrc_start_reg1:
+ if (pTpDec != NULL) {
+ crcReg1 = transportDec_CrcStartReg(pTpDec, 192);
+ }
+ break;
+ case adtscrc_start_reg2:
+ if (pTpDec != NULL) {
+ crcReg2 = transportDec_CrcStartReg(pTpDec, 128);
+ }
+ break;
+ case adtscrc_end_reg1:
+ case drmcrc_end_reg:
+ if (pTpDec != NULL) {
+ transportDec_CrcEndReg(pTpDec, crcReg1);
+ crcReg1 = -1;
+ }
+ break;
+ case adtscrc_end_reg2:
+ if (crcReg1 != -1) {
+ error = AAC_DEC_DECODE_FRAME_ERROR;
+ } else if (pTpDec != NULL) {
+ transportDec_CrcEndReg(pTpDec, crcReg2);
+ crcReg2 = -1;
+ }
+ break;
+ case drmcrc_start_reg:
+ if (pTpDec != NULL) {
+ crcReg1 = transportDec_CrcStartReg(pTpDec, 0);
+ }
+ break;
+
+ /* Non data cases */
+ case next_channel:
+ ch = (ch + 1) % numberOfChannels;
+ break;
+ case link_sequence:
+ list = list->next[decision_bit];
+ i = -1;
+ break;
+
+ default:
+ error = AAC_DEC_UNSUPPORTED_FORMAT;
+ break;
+ }
+
+ if (error != AAC_DEC_OK) {
+ goto bail;
+ }
+
+ i++;
+
+ } while (list->id[i] != end_of_sequence);
+
+ for (ch = 0; ch < numberOfChannels; ch++) {
+ if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_IMDCT ||
+ pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_ELDFB) {
+ /* Shows which bands are empty. */
+ UCHAR *band_is_noise =
+ pAacDecoderChannelInfo[ch]->pDynData->band_is_noise;
+ FDKmemset(band_is_noise, (UCHAR)1, sizeof(UCHAR) * (8 * 16));
+
+ error = CBlock_InverseQuantizeSpectralData(
+ pAacDecoderChannelInfo[ch], pSamplingRateInfo, band_is_noise, 1);
+ if (error != AAC_DEC_OK) {
+ return error;
+ }
+
+ if (elFlags & AC_EL_USAC_NOISE) {
+ CBlock_ApplyNoise(pAacDecoderChannelInfo[ch], pSamplingRateInfo,
+ &pAacDecoderStaticChannelInfo[ch]->nfRandomSeed,
+ band_is_noise);
+
+ } /* if (elFlags & AC_EL_USAC_NOISE) */
+ }
+ }
+
+bail:
+ if (crcReg1 != -1 || crcReg2 != -1) {
+ if (error == AAC_DEC_OK) {
+ error = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ if (crcReg1 != -1) {
+ transportDec_CrcEndReg(pTpDec, crcReg1);
+ }
+ if (crcReg2 != -1) {
+ transportDec_CrcEndReg(pTpDec, crcReg2);
+ }
+ }
+ return error;
+}
diff --git a/fdk-aac/libAACdec/src/channel.h b/fdk-aac/libAACdec/src/channel.h
new file mode 100644
index 0000000..ed46666
--- /dev/null
+++ b/fdk-aac/libAACdec/src/channel.h
@@ -0,0 +1,160 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef CHANNEL_H
+#define CHANNEL_H
+
+#include "common_fix.h"
+
+#include "FDK_tools_rom.h"
+#include "channelinfo.h"
+#include "tpdec_lib.h"
+
+/**
+ * \brief Init codeBook SFB indices (section data) with HCB_ESC. Useful for
+ * bitstreams which do not have any section data, but still SFB's (scale factor
+ * bands). This has the effect that upto the amount of transmitted SFB are
+ * treated as non-zero.
+ * \param pAacDecoderChannelInfo channel info structure containing a valid
+ * icsInfo struct.
+ */
+void CChannel_CodebookTableInit(CAacDecoderChannelInfo *pAacDecoderChannelInfo);
+
+/**
+ * \brief decode a channel element. To be called after CChannelElement_Read()
+ * \param pAacDecoderChannelInfo pointer to channel data struct. Depending on
+ * el_channels either one or two.
+ * \param pSamplingRateInfo pointer to sample rate information structure
+ * \param el_channels amount of channels of the element to be decoded.
+ * \param output pointer to time domain output buffer (ACELP)
+ */
+void CChannelElement_Decode(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
+ SamplingRateInfo *pSamplingRateInfo, UINT flags, UINT elFlags,
+ int el_channels);
+
+/**
+ * \brief Read channel element of given type from bitstream.
+ * \param hBs bitstream handle to access bitstream data.
+ * \param pAacDecoderChannelInfo pointer array to store channel information.
+ * \param aot Audio Object Type
+ * \param pSamplingRateInfo sampling rate info table.
+ * \param flags common parser guidance flags
+ * \param elFlags element specific parser guidance flags
+ * \param numberOfChannels amoun of channels contained in the object to be
+ * parsed.
+ * \param epConfig the current epConfig value obtained from the Audio Specific
+ * Config.
+ * \param pTp transport decoder handle required for ADTS CRC checking.
+ * ...
+ * \return an AAC_DECODER_ERROR error code.
+ */
+AAC_DECODER_ERROR CChannelElement_Read(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ const AUDIO_OBJECT_TYPE aot, SamplingRateInfo *pSamplingRateInfo,
+ const UINT flags, const UINT elFlags, const UINT frame_length,
+ const UCHAR numberOfChannels, const SCHAR epConfig,
+ HANDLE_TRANSPORTDEC pTpDec);
+
+#endif /* #ifndef CHANNEL_H */
diff --git a/fdk-aac/libAACdec/src/channelinfo.cpp b/fdk-aac/libAACdec/src/channelinfo.cpp
new file mode 100644
index 0000000..79add5b
--- /dev/null
+++ b/fdk-aac/libAACdec/src/channelinfo.cpp
@@ -0,0 +1,297 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: individual channel stream info
+
+*******************************************************************************/
+
+#include "channelinfo.h"
+#include "aac_rom.h"
+#include "aac_ram.h"
+#include "FDK_bitstream.h"
+
+AAC_DECODER_ERROR IcsReadMaxSfb(HANDLE_FDK_BITSTREAM bs, CIcsInfo *pIcsInfo,
+ const SamplingRateInfo *pSamplingRateInfo) {
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+ int nbits;
+
+ if (IsLongBlock(pIcsInfo)) {
+ nbits = 6;
+ pIcsInfo->TotalSfBands = pSamplingRateInfo->NumberOfScaleFactorBands_Long;
+ } else {
+ nbits = 4;
+ pIcsInfo->TotalSfBands = pSamplingRateInfo->NumberOfScaleFactorBands_Short;
+ }
+ pIcsInfo->MaxSfBands = (UCHAR)FDKreadBits(bs, nbits);
+
+ if (pIcsInfo->MaxSfBands > pIcsInfo->TotalSfBands) {
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+
+ return ErrorStatus;
+}
+
+AAC_DECODER_ERROR IcsRead(HANDLE_FDK_BITSTREAM bs, CIcsInfo *pIcsInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const UINT flags) {
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ pIcsInfo->Valid = 0;
+
+ if (flags & AC_ELD) {
+ pIcsInfo->WindowSequence = BLOCK_LONG;
+ pIcsInfo->WindowShape = 0;
+ } else {
+ if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ FDKreadBits(bs, 1);
+ }
+ pIcsInfo->WindowSequence = (BLOCK_TYPE)FDKreadBits(bs, 2);
+ pIcsInfo->WindowShape = (UCHAR)FDKreadBits(bs, 1);
+ if (flags & AC_LD) {
+ if (pIcsInfo->WindowShape) {
+ pIcsInfo->WindowShape = 2; /* select low overlap instead of KBD */
+ }
+ }
+ }
+
+ /* Sanity check */
+ if ((flags & (AC_ELD | AC_LD)) && pIcsInfo->WindowSequence != BLOCK_LONG) {
+ pIcsInfo->WindowSequence = BLOCK_LONG;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ ErrorStatus = IcsReadMaxSfb(bs, pIcsInfo, pSamplingRateInfo);
+ if (ErrorStatus != AAC_DEC_OK) {
+ goto bail;
+ }
+
+ if (IsLongBlock(pIcsInfo)) {
+ if (!(flags & (AC_ELD | AC_SCALABLE | AC_BSAC | AC_USAC | AC_RSVD50 |
+ AC_RSV603DA))) /* If not ELD nor Scalable nor BSAC nor USAC
+ syntax then ... */
+ {
+ if ((UCHAR)FDKreadBits(bs, 1) != 0) /* UCHAR PredictorDataPresent */
+ {
+ ErrorStatus = AAC_DEC_UNSUPPORTED_PREDICTION;
+ goto bail;
+ }
+ }
+
+ pIcsInfo->WindowGroups = 1;
+ pIcsInfo->WindowGroupLength[0] = 1;
+ } else {
+ INT i;
+ UINT mask;
+
+ pIcsInfo->ScaleFactorGrouping = (UCHAR)FDKreadBits(bs, 7);
+
+ pIcsInfo->WindowGroups = 0;
+
+ for (i = 0; i < (8 - 1); i++) {
+ mask = 1 << (6 - i);
+ pIcsInfo->WindowGroupLength[i] = 1;
+
+ if (pIcsInfo->ScaleFactorGrouping & mask) {
+ pIcsInfo->WindowGroupLength[pIcsInfo->WindowGroups]++;
+ } else {
+ pIcsInfo->WindowGroups++;
+ }
+ }
+
+ /* loop runs to i < 7 only */
+ pIcsInfo->WindowGroupLength[8 - 1] = 1;
+ pIcsInfo->WindowGroups++;
+ }
+
+bail:
+ if (ErrorStatus == AAC_DEC_OK) pIcsInfo->Valid = 1;
+
+ return ErrorStatus;
+}
+
+/*
+ interleave codebooks the following way
+
+ 9 (84w) | 1 (51w)
+ 10 (82w) | 2 (39w)
+ SCL (65w) | 4 (38w)
+ 3 (39w) | 5 (41w)
+ | 6 (40w)
+ | 7 (31w)
+ | 8 (31w)
+ (270w) (271w)
+*/
+
+/*
+ Table entries are sorted as following:
+ | num_swb_long_window | sfbands_long | num_swb_short_window | sfbands_short |
+*/
+AAC_DECODER_ERROR getSamplingRateInfo(SamplingRateInfo *t, UINT samplesPerFrame,
+ UINT samplingRateIndex,
+ UINT samplingRate) {
+ int index = 0;
+
+ /* Search closest samplerate according to ISO/IEC 13818-7:2005(E) 8.2.4 (Table
+ * 38): */
+ if ((samplingRateIndex >= 15) || (samplesPerFrame == 768)) {
+ const UINT borders[] = {(UINT)-1, 92017, 75132, 55426, 46009, 37566,
+ 27713, 23004, 18783, 13856, 11502, 9391};
+ UINT i, samplingRateSearch = samplingRate;
+
+ if (samplesPerFrame == 768) {
+ samplingRateSearch = (samplingRate * 4) / 3;
+ }
+
+ for (i = 0; i < 11; i++) {
+ if (borders[i] > samplingRateSearch &&
+ samplingRateSearch >= borders[i + 1]) {
+ break;
+ }
+ }
+ samplingRateIndex = i;
+ }
+
+ t->samplingRateIndex = samplingRateIndex;
+ t->samplingRate = samplingRate;
+
+ switch (samplesPerFrame) {
+ case 1024:
+ index = 0;
+ break;
+ case 960:
+ index = 1;
+ break;
+ case 768:
+ index = 2;
+ break;
+ case 512:
+ index = 3;
+ break;
+ case 480:
+ index = 4;
+ break;
+
+ default:
+ return AAC_DEC_UNSUPPORTED_FORMAT;
+ }
+
+ t->ScaleFactorBands_Long =
+ sfbOffsetTables[index][samplingRateIndex].sfbOffsetLong;
+ t->ScaleFactorBands_Short =
+ sfbOffsetTables[index][samplingRateIndex].sfbOffsetShort;
+ t->NumberOfScaleFactorBands_Long =
+ sfbOffsetTables[index][samplingRateIndex].numberOfSfbLong;
+ t->NumberOfScaleFactorBands_Short =
+ sfbOffsetTables[index][samplingRateIndex].numberOfSfbShort;
+
+ if (t->ScaleFactorBands_Long == NULL ||
+ t->NumberOfScaleFactorBands_Long == 0) {
+ t->samplingRate = 0;
+ return AAC_DEC_UNSUPPORTED_FORMAT;
+ }
+
+ FDK_ASSERT((UINT)t->ScaleFactorBands_Long[t->NumberOfScaleFactorBands_Long] ==
+ samplesPerFrame);
+ FDK_ASSERT(
+ t->ScaleFactorBands_Short == NULL ||
+ (UINT)t->ScaleFactorBands_Short[t->NumberOfScaleFactorBands_Short] * 8 ==
+ samplesPerFrame);
+
+ return AAC_DEC_OK;
+}
diff --git a/fdk-aac/libAACdec/src/channelinfo.h b/fdk-aac/libAACdec/src/channelinfo.h
new file mode 100644
index 0000000..4523400
--- /dev/null
+++ b/fdk-aac/libAACdec/src/channelinfo.h
@@ -0,0 +1,564 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: individual channel stream info
+
+*******************************************************************************/
+
+#ifndef CHANNELINFO_H
+#define CHANNELINFO_H
+
+#include "common_fix.h"
+
+#include "aac_rom.h"
+#include "aacdecoder_lib.h"
+#include "FDK_bitstream.h"
+#include "overlapadd.h"
+
+#include "mdct.h"
+#include "stereo.h"
+#include "pulsedata.h"
+#include "aacdec_tns.h"
+
+#include "aacdec_pns.h"
+
+#include "aacdec_hcr_types.h"
+#include "rvlc_info.h"
+
+#include "usacdec_acelp.h"
+#include "usacdec_const.h"
+#include "usacdec_rom.h"
+
+#include "ac_arith_coder.h"
+
+#include "conceal_types.h"
+
+#include "aacdec_drc_types.h"
+
+#define WB_SECTION_SIZE (1024 * 2)
+
+#define DRM_BS_BUFFER_SIZE \
+ (512) /* size of the dynamic buffer which is used to reverse the bits of \
+ the DRM SBR payload */
+
+/* Output rendering mode */
+typedef enum {
+ AACDEC_RENDER_INVALID = 0,
+ AACDEC_RENDER_IMDCT,
+ AACDEC_RENDER_ELDFB,
+ AACDEC_RENDER_LPD,
+ AACDEC_RENDER_INTIMDCT
+} AACDEC_RENDER_MODE;
+
+enum { MAX_QUANTIZED_VALUE = 8191 };
+
+typedef enum { FD_LONG, FD_SHORT, LPD } USAC_COREMODE;
+
+typedef struct {
+ const SHORT *ScaleFactorBands_Long;
+ const SHORT *ScaleFactorBands_Short;
+ UCHAR NumberOfScaleFactorBands_Long;
+ UCHAR NumberOfScaleFactorBands_Short;
+ UINT samplingRateIndex;
+ UINT samplingRate;
+} SamplingRateInfo;
+
+typedef struct {
+ UCHAR CommonWindow;
+ UCHAR GlobalGain;
+
+} CRawDataInfo;
+
+typedef struct {
+ UCHAR WindowGroupLength[8];
+ UCHAR WindowGroups;
+ UCHAR Valid;
+
+ UCHAR WindowShape; /* 0: sine window, 1: KBD, 2: low overlap */
+ BLOCK_TYPE WindowSequence; /* mdct.h; 0: long, 1: start, 2: short, 3: stop */
+ UCHAR MaxSfBands;
+ UCHAR max_sfb_ste;
+ UCHAR ScaleFactorGrouping;
+
+ UCHAR TotalSfBands;
+
+} CIcsInfo;
+
+enum {
+ ZERO_HCB = 0,
+ ESCBOOK = 11,
+ NSPECBOOKS = ESCBOOK + 1,
+ BOOKSCL = NSPECBOOKS,
+ NOISE_HCB = 13,
+ INTENSITY_HCB2 = 14,
+ INTENSITY_HCB = 15,
+ LAST_HCB
+};
+
+/* This struct holds the persistent data shared by both channels of a CPE.
+ It needs to be allocated for each CPE. */
+typedef struct {
+ CJointStereoPersistentData jointStereoPersistentData;
+} CpePersistentData;
+
+/*
+ * This struct must be allocated one for every channel and must be persistent.
+ */
+typedef struct {
+ FIXP_DBL *pOverlapBuffer;
+ mdct_t IMdct;
+
+ CArcoData *hArCo;
+
+ INT pnsCurrentSeed;
+
+ /* LPD memory */
+ FIXP_DBL old_synth[PIT_MAX_MAX - L_SUBFR];
+ INT old_T_pf[SYN_SFD];
+ FIXP_DBL old_gain_pf[SYN_SFD];
+ FIXP_DBL mem_bpf[L_FILT + L_SUBFR];
+ UCHAR
+ old_bpf_control_info; /* (1: enable, 0: disable) bpf for past superframe
+ */
+
+ USAC_COREMODE last_core_mode; /* core mode used by the decoder in previous
+ frame. (not signalled by the bitstream, see
+ CAacDecoderChannelInfo::core_mode_last !! )
+ */
+ UCHAR last_lpd_mode; /* LPD mode used by the decoder in last LPD subframe
+ (not signalled by the bitstream, see
+ CAacDecoderChannelInfo::lpd_mode_last !! ) */
+ UCHAR last_last_lpd_mode; /* LPD mode used in second last LPD subframe
+ (not signalled by the bitstream) */
+ UCHAR last_lpc_lost; /* Flag indicating that the previous LPC is lost */
+
+ FIXP_LPC
+ lpc4_lsf[M_LP_FILTER_ORDER]; /* Last LPC4 coefficients in LSF domain. */
+ FIXP_LPC lsf_adaptive_mean[M_LP_FILTER_ORDER]; /* Adaptive mean of LPC
+ coefficients in LSF domain
+ for concealment. */
+ FIXP_LPC lp_coeff_old[2][M_LP_FILTER_ORDER]; /* Last LPC coefficients in LP
+ domain. lp_coeff_old[0] is lpc4 (coeffs for
+ right folding point of last tcx frame),
+ lp_coeff_old[1] are coeffs for left folding
+ point of last tcx frame */
+ INT lp_coeff_old_exp[2];
+
+ FIXP_SGL
+ oldStability; /* LPC coeff stability value from last frame (required for
+ TCX concealment). */
+ UINT numLostLpdFrames; /* Number of consecutive lost subframes. */
+
+ /* TCX memory */
+ FIXP_DBL last_tcx_gain;
+ INT last_tcx_gain_e;
+ FIXP_DBL last_alfd_gains[32]; /* Scaled by one bit. */
+ SHORT last_tcx_pitch;
+ UCHAR last_tcx_noise_factor;
+
+ /* ACELP memory */
+ CAcelpStaticMem acelp;
+
+ ULONG nfRandomSeed; /* seed value for USAC noise filling random generator */
+
+ CDrcChannelData drcData;
+ CConcealmentInfo concealmentInfo;
+
+ CpePersistentData *pCpeStaticData;
+
+} CAacDecoderStaticChannelInfo;
+
+/*
+ * This union must be allocated for every element (up to 2 channels).
+ */
+typedef struct {
+ /* Common bit stream data */
+ SHORT aScaleFactor[(
+ 8 * 16)]; /* Spectral scale factors for each sfb in each window. */
+ SHORT aSfbScale[(8 * 16)]; /* could be free after ApplyTools() */
+ UCHAR
+ aCodeBook[(8 * 16)]; /* section data: codebook for each window and sfb. */
+ UCHAR band_is_noise[(8 * 16)];
+ CTnsData TnsData;
+ CRawDataInfo RawDataInfo;
+
+ shouldBeUnion {
+ struct {
+ CPulseData PulseData;
+ SHORT aNumLineInSec4Hcr[MAX_SFB_HCR]; /* needed once for all channels
+ except for Drm syntax */
+ UCHAR
+ aCodeBooks4Hcr[MAX_SFB_HCR]; /* needed once for all channels except for
+ Drm syntax. Same as "aCodeBook" ? */
+ SHORT lenOfReorderedSpectralData;
+ SCHAR lenOfLongestCodeword;
+ SCHAR numberSection;
+ SCHAR rvlcCurrentScaleFactorOK;
+ SCHAR rvlcIntensityUsed;
+ } aac;
+ struct {
+ UCHAR fd_noise_level_and_offset;
+ UCHAR tns_active;
+ UCHAR tns_on_lr;
+ UCHAR tcx_noise_factor[4];
+ UCHAR tcx_global_gain[4];
+ } usac;
+ }
+ specificTo;
+
+} CAacDecoderDynamicData;
+
+typedef shouldBeUnion {
+ UCHAR DrmBsBuffer[DRM_BS_BUFFER_SIZE];
+
+ /* Common signal data, can be used once the bit stream data from above is not
+ * used anymore. */
+ FIXP_DBL mdctOutTemp[1024];
+
+ FIXP_DBL synth_buf[(PIT_MAX_MAX + SYN_DELAY + L_FRAME_PLUS)];
+
+ FIXP_DBL workBuffer[WB_SECTION_SIZE];
+}
+CWorkBufferCore1;
+
+/* Common data referenced by all channels */
+typedef struct {
+ CAacDecoderDynamicData pAacDecoderDynamicData[2];
+
+ CPnsInterChannelData pnsInterChannelData;
+ INT pnsRandomSeed[(8 * 16)];
+
+ CJointStereoData jointStereoData; /* One for one element */
+
+ shouldBeUnion {
+ struct {
+ CErHcrInfo erHcrInfo;
+ CErRvlcInfo erRvlcInfo;
+ SHORT aRvlcScfEsc[RVLC_MAX_SFB]; /* needed once for all channels */
+ SHORT aRvlcScfFwd[RVLC_MAX_SFB]; /* needed once for all channels */
+ SHORT aRvlcScfBwd[RVLC_MAX_SFB]; /* needed once for all channels */
+ } aac;
+ }
+ overlay;
+
+} CAacDecoderCommonData;
+
+typedef struct {
+ CWorkBufferCore1 *pWorkBufferCore1;
+ CCplxPredictionData *cplxPredictionData;
+} CAacDecoderCommonStaticData;
+
+/*
+ * This struct must be allocated one for every channel of every element and must
+ * be persistent. Among its members, the following memory areas can be
+ * overwritten under the given conditions:
+ * - pSpectralCoefficient The memory pointed to can be overwritten after time
+ * signal rendering.
+ * - data can be overwritten after time signal rendering.
+ * - pDynData memory pointed to can be overwritten after each
+ * CChannelElement_Decode() call.
+ * - pComData->overlay memory pointed to can be overwritten after each
+ * CChannelElement_Decode() call..
+ */
+typedef struct {
+ shouldBeUnion {
+ struct {
+ FIXP_DBL fac_data0[LFAC];
+ SCHAR fac_data_e[4];
+ FIXP_DBL
+ *fac_data[4]; /* Pointers to unused parts of pSpectralCoefficient */
+
+ UCHAR core_mode; /* current core mode */
+ USAC_COREMODE
+ core_mode_last; /* previous core mode, signalled in the bitstream
+ (not done by the decoder, see
+ CAacDecoderStaticChannelInfo::last_core_mode !!)*/
+ UCHAR lpd_mode_last; /* previous LPD mode, signalled in the bitstream
+ (not done by the decoder, see
+ CAacDecoderStaticChannelInfo::last_core_mode !!)*/
+ UCHAR mod[4];
+ UCHAR bpf_control_info; /* (1: enable, 0: disable) bpf for current
+ superframe */
+
+ FIXP_LPC lsp_coeff[5][M_LP_FILTER_ORDER]; /* linear prediction
+ coefficients in LSP domain */
+ FIXP_LPC
+ lp_coeff[5][M_LP_FILTER_ORDER]; /* linear prediction coefficients in
+ LP domain */
+ INT lp_coeff_exp[5];
+ FIXP_LPC lsf_adaptive_mean_cand
+ [M_LP_FILTER_ORDER]; /* concealment: is copied to
+ CAacDecoderStaticChannelInfo->lsf_adaptive_mean once frame is
+ assumed to be correct*/
+ FIXP_SGL aStability[4]; /* LPC coeff stability values required for ACELP
+ and TCX (concealment) */
+
+ CAcelpChannelData acelp[4];
+
+ FIXP_DBL tcx_gain[4];
+ SCHAR tcx_gain_e[4];
+ } usac;
+
+ struct {
+ CPnsData PnsData; /* Not required for USAC */
+ } aac;
+ }
+ data;
+
+ SPECTRAL_PTR pSpectralCoefficient; /* Spectral coefficients of each window */
+ SHORT specScale[8]; /* Scale shift values of each spectrum window */
+ CIcsInfo icsInfo;
+ INT granuleLength; /* Size of smallest spectrum piece */
+ UCHAR ElementInstanceTag;
+
+ AACDEC_RENDER_MODE renderMode; /* Output signal rendering mode */
+
+ CAacDecoderDynamicData *
+ pDynData; /* Data required for one element and discarded after decoding */
+ CAacDecoderCommonData
+ *pComData; /* Data required for one channel at a time during decode */
+ CAacDecoderCommonStaticData *pComStaticData; /* Persistent data required for
+ one channel at a time during
+ decode */
+
+ int currAliasingSymmetry; /* required for RSVD60 MCT */
+
+} CAacDecoderChannelInfo;
+
+/* channelinfo.cpp */
+
+AAC_DECODER_ERROR getSamplingRateInfo(SamplingRateInfo *t, UINT samplesPerFrame,
+ UINT samplingRateIndex,
+ UINT samplingRate);
+
+/**
+ * \brief Read max SFB from bit stream and assign TotalSfBands according
+ * to the window sequence and sample rate.
+ * \param hBs bit stream handle as data source
+ * \param pIcsInfo IcsInfo structure to read the window sequence and store
+ * MaxSfBands and TotalSfBands
+ * \param pSamplingRateInfo read only
+ */
+AAC_DECODER_ERROR IcsReadMaxSfb(HANDLE_FDK_BITSTREAM hBs, CIcsInfo *pIcsInfo,
+ const SamplingRateInfo *pSamplingRateInfo);
+
+AAC_DECODER_ERROR IcsRead(HANDLE_FDK_BITSTREAM bs, CIcsInfo *pIcsInfo,
+ const SamplingRateInfo *SamplingRateInfoTable,
+ const UINT flags);
+
+/* stereo.cpp, only called from this file */
+
+/*!
+ \brief Applies MS stereo.
+
+ The function applies MS stereo.
+
+ \param pAacDecoderChannelInfo aac channel info.
+ \param pScaleFactorBandOffsets pointer to scalefactor band offsets.
+ \param pWindowGroupLength pointer to window group length array.
+ \param windowGroups number of window groups.
+ \param scaleFactorBandsTransmittedL number of transmitted scalefactor bands in
+ left channel. \param scaleFactorBandsTransmittedR number of transmitted
+ scalefactor bands in right channel. May differ from
+ scaleFactorBandsTransmittedL only for USAC. \return none
+*/
+void CJointStereo_ApplyMS(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
+ FIXP_DBL *spectrumL, FIXP_DBL *spectrumR, SHORT *SFBleftScale,
+ SHORT *SFBrightScale, SHORT *specScaleL, SHORT *specScaleR,
+ const SHORT *pScaleFactorBandOffsets, const UCHAR *pWindowGroupLength,
+ const int windowGroups, const int max_sfb_ste_outside,
+ const int scaleFactorBandsTransmittedL,
+ const int scaleFactorBandsTransmittedR, FIXP_DBL *store_dmx_re_prev,
+ SHORT *store_dmx_re_prev_e, const int mainband_flag);
+
+/*!
+ \brief Applies intensity stereo
+
+ The function applies intensity stereo.
+
+ \param pAacDecoderChannelInfo aac channel info.
+ \param pScaleFactorBandOffsets pointer to scalefactor band offsets.
+ \param pWindowGroupLength pointer to window group length array.
+ \param windowGroups number of window groups.
+ \param scaleFactorBandsTransmitted number of transmitted scalefactor bands.
+ \return none
+*/
+void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
+ const short *pScaleFactorBandOffsets,
+ const UCHAR *pWindowGroupLength,
+ const int windowGroups,
+ const int scaleFactorBandsTransmitted);
+
+/* aacdec_pns.cpp */
+int CPns_IsPnsUsed(const CPnsData *pPnsData, const int group, const int band);
+
+void CPns_SetCorrelation(CPnsData *pPnsData, const int group, const int band,
+ const int outofphase);
+
+/****************** inline functions ******************/
+
+inline UCHAR IsValid(const CIcsInfo *pIcsInfo) { return pIcsInfo->Valid; }
+
+inline UCHAR IsLongBlock(const CIcsInfo *pIcsInfo) {
+ return (pIcsInfo->WindowSequence != BLOCK_SHORT);
+}
+
+inline UCHAR GetWindowShape(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->WindowShape;
+}
+
+inline BLOCK_TYPE GetWindowSequence(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->WindowSequence;
+}
+
+inline const SHORT *GetScaleFactorBandOffsets(
+ const CIcsInfo *pIcsInfo, const SamplingRateInfo *samplingRateInfo) {
+ if (IsLongBlock(pIcsInfo)) {
+ return samplingRateInfo->ScaleFactorBands_Long;
+ } else {
+ return samplingRateInfo->ScaleFactorBands_Short;
+ }
+}
+
+inline UCHAR GetNumberOfScaleFactorBands(
+ const CIcsInfo *pIcsInfo, const SamplingRateInfo *samplingRateInfo) {
+ if (IsLongBlock(pIcsInfo)) {
+ return samplingRateInfo->NumberOfScaleFactorBands_Long;
+ } else {
+ return samplingRateInfo->NumberOfScaleFactorBands_Short;
+ }
+}
+
+inline int GetWindowsPerFrame(const CIcsInfo *pIcsInfo) {
+ return (pIcsInfo->WindowSequence == BLOCK_SHORT) ? 8 : 1;
+}
+
+inline UCHAR GetWindowGroups(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->WindowGroups;
+}
+
+inline UCHAR GetWindowGroupLength(const CIcsInfo *pIcsInfo, const INT index) {
+ return pIcsInfo->WindowGroupLength[index];
+}
+
+inline const UCHAR *GetWindowGroupLengthTable(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->WindowGroupLength;
+}
+
+inline UCHAR GetScaleFactorBandsTransmitted(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->MaxSfBands;
+}
+
+inline UCHAR GetScaleMaxFactorBandsTransmitted(const CIcsInfo *pIcsInfo0,
+ const CIcsInfo *pIcsInfo1) {
+ return fMax(pIcsInfo0->MaxSfBands, pIcsInfo1->MaxSfBands);
+}
+
+inline UCHAR GetScaleFactorBandsTotal(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->TotalSfBands;
+}
+
+/* Note: This function applies to AAC-LC only ! */
+inline UCHAR GetMaximumTnsBands(const CIcsInfo *pIcsInfo,
+ const int samplingRateIndex) {
+ return tns_max_bands_tbl[samplingRateIndex][!IsLongBlock(pIcsInfo)];
+}
+
+#endif /* #ifndef CHANNELINFO_H */
diff --git a/fdk-aac/libAACdec/src/conceal.cpp b/fdk-aac/libAACdec/src/conceal.cpp
new file mode 100644
index 0000000..5895cb8
--- /dev/null
+++ b/fdk-aac/libAACdec/src/conceal.cpp
@@ -0,0 +1,2095 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: independent channel concealment
+
+*******************************************************************************/
+
+/*!
+ \page concealment AAC core concealment
+
+ This AAC core implementation includes a concealment function, which can be
+ enabled using the several defines during compilation.
+
+ There are various tests inside the core, starting with simple CRC tests and
+ ending in a variety of plausibility checks. If such a check indicates an
+ invalid bitstream, then concealment is applied.
+
+ Concealment is also applied when the calling main program indicates a
+ distorted or missing data frame using the frameOK flag. This is used for error
+ detection on the transport layer. (See below)
+
+ There are three concealment-modes:
+
+ 1) Muting: The spectral data is simply set to zero in case of an detected
+ error.
+
+ 2) Noise substitution: In case of an detected error, concealment copies the
+ last frame and adds attenuates the spectral data. For this mode you have to
+ set the #CONCEAL_NOISE define. Noise substitution adds no additional delay.
+
+ 3) Interpolation: The interpolation routine swaps the spectral data from the
+ previous and the current frame just before the final frequency to time
+ conversion. In case a single frame is corrupted, concealmant interpolates
+ between the last good and the first good frame to create the spectral data for
+ the missing frame. If multiple frames are corrupted, concealment implements
+ first a fade out based on slightly modified spectral values from the last good
+ frame. As soon as good frames are available, concealmant fades in the new
+ spectral data. For this mode you have to set the #CONCEAL_INTER define. Note
+ that in this case, you also need to set #SBR_BS_DELAY_ENABLE, which basically
+ adds approriate delay in the SBR decoder. Note that the
+ Interpolating-Concealment increases the delay of your decoder by one frame and
+ that it does require additional resources such as memory and computational
+ complexity.
+
+ <h2>How concealment can be used with errors on the transport layer</h2>
+
+ Many errors can or have to be detected on the transport layer. For example in
+ IP based systems packet loss can occur. The transport protocol used should
+ indicate such packet loss by inserting an empty frame with frameOK=0.
+*/
+
+#include "conceal.h"
+
+#include "aac_rom.h"
+#include "genericStds.h"
+
+/* PNS (of block) */
+#include "aacdec_pns.h"
+#include "block.h"
+
+#define CONCEAL_DFLT_COMF_NOISE_LEVEL (0x100000)
+
+#define CONCEAL_NOT_DEFINED ((UCHAR)-1)
+
+/* default settings */
+#define CONCEAL_DFLT_FADEOUT_FRAMES (6)
+#define CONCEAL_DFLT_FADEIN_FRAMES (5)
+#define CONCEAL_DFLT_MUTE_RELEASE_FRAMES (0)
+
+#define CONCEAL_DFLT_FADE_FACTOR (0.707106781186548f) /* 1/sqrt(2) */
+
+/* some often used constants: */
+#define FIXP_ZERO FL2FXCONST_DBL(0.0f)
+#define FIXP_ONE FL2FXCONST_DBL(1.0f)
+#define FIXP_FL_CORRECTION FL2FXCONST_DBL(0.53333333333333333f)
+
+/* For parameter conversion */
+#define CONCEAL_PARAMETER_BITS (8)
+#define CONCEAL_MAX_QUANT_FACTOR ((1 << CONCEAL_PARAMETER_BITS) - 1)
+/*#define CONCEAL_MIN_ATTENUATION_FACTOR_025 ( FL2FXCONST_DBL(0.971627951577106174) )*/ /* -0.25 dB */
+#define CONCEAL_MIN_ATTENUATION_FACTOR_025_LD \
+ FL2FXCONST_DBL(-0.041524101186092029596853445212299)
+/*#define CONCEAL_MIN_ATTENUATION_FACTOR_050 ( FL2FXCONST_DBL(0.944060876285923380) )*/ /* -0.50 dB */
+#define CONCEAL_MIN_ATTENUATION_FACTOR_050_LD \
+ FL2FXCONST_DBL(-0.083048202372184059253597008145293)
+
+typedef enum {
+ CConcealment_NoExpand,
+ CConcealment_Expand,
+ CConcealment_Compress
+} CConcealmentExpandType;
+
+static const FIXP_SGL facMod4Table[4] = {
+ FL2FXCONST_SGL(0.500000000f), /* FIXP_SGL(0x4000), 2^-(1-0,00) */
+ FL2FXCONST_SGL(0.594603558f), /* FIXP_SGL(0x4c1b), 2^-(1-0,25) */
+ FL2FXCONST_SGL(0.707106781f), /* FIXP_SGL(0x5a82), 2^-(1-0,50) */
+ FL2FXCONST_SGL(0.840896415f) /* FIXP_SGL(0x6ba2) 2^-(1-0,75) */
+};
+
+static void CConcealment_CalcBandEnergy(
+ FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo,
+ const int blockType, CConcealmentExpandType ex, int *sfbEnergy);
+
+static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
+ SHORT *pSpecScalePrev,
+ SHORT *pSpecScaleAct,
+ SHORT *pSpecScaleOut, int *enPrv,
+ int *enAct, int sfbCnt,
+ const SHORT *pSfbOffset);
+
+static int CConcealment_ApplyInter(
+ CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const int improveTonal, const int frameOk, const int mute_release_active);
+
+static int CConcealment_ApplyNoise(
+ CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const UINT flags);
+
+static void CConcealment_UpdateState(
+ CConcealmentInfo *pConcealmentInfo, int frameOk,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo);
+
+static void CConcealment_ApplyRandomSign(int iRandomPhase, FIXP_DBL *spec,
+ int samplesPerFrame);
+
+/* TimeDomainFading */
+static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
+ FIXP_DBL fadeStop, FIXP_PCM *pcmdata);
+static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
+ int *fadingSteps,
+ FIXP_DBL fadeStop,
+ FIXP_DBL fadeStart,
+ TDfadingType fadingType);
+static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps);
+
+/* Streamline the state machine */
+static int CConcealment_ApplyFadeOut(
+ int mode, CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo);
+
+static int CConcealment_TDNoise_Random(ULONG *seed);
+static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
+ const int len, FIXP_PCM *const pcmdata);
+
+static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) {
+ BLOCK_TYPE newWinSeq = BLOCK_LONG;
+
+ /* Try to have only long blocks */
+ if (prevWinSeq == BLOCK_START || prevWinSeq == BLOCK_SHORT) {
+ newWinSeq = BLOCK_STOP;
+ }
+
+ return (newWinSeq);
+}
+
+/*!
+ \brief Init common concealment information data
+
+ \param pConcealCommonData Pointer to the concealment common data structure.
+*/
+void CConcealment_InitCommonData(CConcealParams *pConcealCommonData) {
+ if (pConcealCommonData != NULL) {
+ int i;
+
+ /* Set default error concealment technique */
+ pConcealCommonData->method = ConcealMethodInter;
+
+ pConcealCommonData->numFadeOutFrames = CONCEAL_DFLT_FADEOUT_FRAMES;
+ pConcealCommonData->numFadeInFrames = CONCEAL_DFLT_FADEIN_FRAMES;
+ pConcealCommonData->numMuteReleaseFrames = CONCEAL_DFLT_MUTE_RELEASE_FRAMES;
+
+ pConcealCommonData->comfortNoiseLevel =
+ (FIXP_DBL)CONCEAL_DFLT_COMF_NOISE_LEVEL;
+
+ /* Init fade factors (symetric) */
+ pConcealCommonData->fadeOutFactor[0] =
+ FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR);
+ pConcealCommonData->fadeInFactor[0] = pConcealCommonData->fadeOutFactor[0];
+
+ for (i = 1; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ pConcealCommonData->fadeOutFactor[i] =
+ FX_DBL2FX_SGL(fMult(pConcealCommonData->fadeOutFactor[i - 1],
+ FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR)));
+ pConcealCommonData->fadeInFactor[i] =
+ pConcealCommonData->fadeOutFactor[i];
+ }
+ }
+}
+
+/*!
+ \brief Get current concealment method.
+
+ \param pConcealCommonData Pointer to common concealment data (for all
+ channels)
+*/
+CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData) {
+ CConcealmentMethod method = ConcealMethodNone;
+
+ if (pConcealCommonData != NULL) {
+ method = pConcealCommonData->method;
+ }
+
+ return (method);
+}
+
+/*!
+ \brief Init concealment information for each channel
+
+ \param pConcealChannelInfo Pointer to the channel related concealment info
+ structure to be initialized. \param pConcealCommonData Pointer to common
+ concealment data (for all channels) \param initRenderMode Initial render
+ mode to be set for the current channel. \param samplesPerFrame The number
+ of samples per frame.
+*/
+void CConcealment_InitChannelData(CConcealmentInfo *pConcealChannelInfo,
+ CConcealParams *pConcealCommonData,
+ AACDEC_RENDER_MODE initRenderMode,
+ int samplesPerFrame) {
+ int i;
+ pConcealChannelInfo->TDNoiseSeed = 0;
+ FDKmemclear(pConcealChannelInfo->TDNoiseStates,
+ sizeof(pConcealChannelInfo->TDNoiseStates));
+ pConcealChannelInfo->TDNoiseCoef[0] = FL2FXCONST_SGL(0.05f);
+ pConcealChannelInfo->TDNoiseCoef[1] = FL2FXCONST_SGL(0.5f);
+ pConcealChannelInfo->TDNoiseCoef[2] = FL2FXCONST_SGL(0.45f);
+
+ pConcealChannelInfo->pConcealParams = pConcealCommonData;
+
+ pConcealChannelInfo->lastRenderMode = initRenderMode;
+
+ pConcealChannelInfo->windowShape = CONCEAL_NOT_DEFINED;
+ pConcealChannelInfo->windowSequence = BLOCK_LONG; /* default type */
+ pConcealChannelInfo->lastWinGrpLen = 1;
+
+ pConcealChannelInfo->concealState = ConcealState_Ok;
+
+ FDKmemclear(pConcealChannelInfo->spectralCoefficient,
+ 1024 * sizeof(FIXP_CNCL));
+
+ for (i = 0; i < 8; i++) {
+ pConcealChannelInfo->specScale[i] = 0;
+ }
+
+ pConcealChannelInfo->iRandomPhase = 0;
+
+ pConcealChannelInfo->prevFrameOk[0] = 1;
+ pConcealChannelInfo->prevFrameOk[1] = 1;
+
+ pConcealChannelInfo->cntFadeFrames = 0;
+ pConcealChannelInfo->cntValidFrames = 0;
+ pConcealChannelInfo->fade_old = (FIXP_DBL)MAXVAL_DBL;
+ pConcealChannelInfo->winGrpOffset[0] = 0;
+ pConcealChannelInfo->winGrpOffset[1] = 0;
+ pConcealChannelInfo->attGrpOffset[0] = 0;
+ pConcealChannelInfo->attGrpOffset[1] = 0;
+}
+
+/*!
+ \brief Set error concealment parameters
+
+ \param concealParams
+ \param method
+ \param fadeOutSlope
+ \param fadeInSlope
+ \param muteRelease
+ \param comfNoiseLevel
+*/
+AAC_DECODER_ERROR
+CConcealment_SetParams(CConcealParams *concealParams, int method,
+ int fadeOutSlope, int fadeInSlope, int muteRelease,
+ FIXP_DBL comfNoiseLevel) {
+ /* set concealment technique */
+ if (method != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
+ switch ((CConcealmentMethod)method) {
+ case ConcealMethodMute:
+ case ConcealMethodNoise:
+ case ConcealMethodInter:
+ /* Be sure to enable delay adjustment of SBR decoder! */
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ } else {
+ /* set param */
+ concealParams->method = (CConcealmentMethod)method;
+ }
+ break;
+
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+
+ /* set number of frames for fade-out slope */
+ if (fadeOutSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
+ if ((fadeOutSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeOutSlope >= 0)) {
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ } else {
+ /* set param */
+ concealParams->numFadeOutFrames = fadeOutSlope;
+ }
+ } else {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+
+ /* set number of frames for fade-in slope */
+ if (fadeInSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
+ if ((fadeInSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeInSlope >= 0)) {
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ } else {
+ /* set param */
+ concealParams->numFadeInFrames = fadeInSlope;
+ }
+ } else {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+
+ /* set number of error-free frames after which the muting will be released */
+ if (muteRelease != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
+ if ((muteRelease < (CONCEAL_MAX_NUM_FADE_FACTORS << 1)) &&
+ (muteRelease >= 0)) {
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ } else {
+ /* set param */
+ concealParams->numMuteReleaseFrames = muteRelease;
+ }
+ } else {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+
+ /* set confort noise level which will be inserted while in state 'muting' */
+ if (comfNoiseLevel != (FIXP_DBL)AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
+ if ((comfNoiseLevel < (FIXP_DBL)0) ||
+ (comfNoiseLevel > (FIXP_DBL)MAXVAL_DBL)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ } else {
+ concealParams->comfortNoiseLevel = (FIXP_DBL)comfNoiseLevel;
+ }
+ }
+
+ return (AAC_DEC_OK);
+}
+
+/*!
+ \brief Set fade-out/in attenuation factor vectors
+
+ \param concealParams
+ \param fadeOutAttenuationVector
+ \param fadeInAttenuationVector
+
+ \return 0 if OK all other values indicate errors
+*/
+AAC_DECODER_ERROR
+CConcealment_SetAttenuation(CConcealParams *concealParams,
+ const SHORT *fadeOutAttenuationVector,
+ const SHORT *fadeInAttenuationVector) {
+ if ((fadeOutAttenuationVector == NULL) && (fadeInAttenuationVector == NULL)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+
+ /* Fade-out factors */
+ if (fadeOutAttenuationVector != NULL) {
+ int i;
+
+ /* check quantized factors first */
+ for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ if ((fadeOutAttenuationVector[i] < 0) ||
+ (fadeOutAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+
+ /* now dequantize factors */
+ for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ concealParams->fadeOutFactor[i] =
+ FX_DBL2FX_SGL(fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0,
+ (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0 / 2.0) >>
+ (CONCEAL_PARAMETER_BITS - 1)) *
+ (INT)fadeOutAttenuationVector[i]),
+ CONCEAL_PARAMETER_BITS));
+ }
+ }
+
+ /* Fade-in factors */
+ if (fadeInAttenuationVector != NULL) {
+ int i;
+
+ /* check quantized factors first */
+ for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ if ((fadeInAttenuationVector[i] < 0) ||
+ (fadeInAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+
+ /* now dequantize factors */
+ for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ concealParams->fadeInFactor[i] = FX_DBL2FX_SGL(
+ fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0,
+ (FIXP_DBL)((INT)(FIXP_ONE >> CONCEAL_PARAMETER_BITS) *
+ (INT)fadeInAttenuationVector[i]),
+ CONCEAL_PARAMETER_BITS));
+ }
+ }
+
+ return (AAC_DEC_OK);
+}
+
+/*!
+ \brief Get state of concealment module.
+
+ \param pConcealChannelInfo
+
+ \return Concealment state.
+*/
+CConcealmentState CConcealment_GetState(CConcealmentInfo *pConcealChannelInfo) {
+ CConcealmentState state = ConcealState_Ok;
+
+ if (pConcealChannelInfo != NULL) {
+ state = pConcealChannelInfo->concealState;
+ }
+
+ return (state);
+}
+
+/*!
+ \brief Store data for concealment techniques applied later
+
+ Interface function to store data for different concealment strategies
+ */
+void CConcealment_Store(
+ CConcealmentInfo *hConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
+ UCHAR nbDiv = NB_DIV;
+
+ if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
+ pAacDecoderChannelInfo->data.usac.mod[nbDiv - 1] == 0))
+
+ {
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+
+ SHORT tSpecScale[8];
+ UCHAR tWindowShape;
+ BLOCK_TYPE tWindowSequence;
+
+ /* store old window infos for swapping */
+ tWindowSequence = hConcealmentInfo->windowSequence;
+ tWindowShape = hConcealmentInfo->windowShape;
+
+ /* store old scale factors for swapping */
+ FDKmemcpy(tSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT));
+
+ /* store new window infos */
+ hConcealmentInfo->windowSequence = GetWindowSequence(pIcsInfo);
+ hConcealmentInfo->windowShape = GetWindowShape(pIcsInfo);
+ hConcealmentInfo->lastWinGrpLen =
+ *(GetWindowGroupLengthTable(pIcsInfo) + GetWindowGroups(pIcsInfo) - 1);
+
+ /* store new scale factors */
+ FDKmemcpy(hConcealmentInfo->specScale, pSpecScale, 8 * sizeof(SHORT));
+
+ if (hConcealmentInfo->pConcealParams->method < ConcealMethodInter) {
+ /* store new spectral bins */
+#if (CNCL_FRACT_BITS == DFRACT_BITS)
+ FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpectralCoefficient,
+ 1024 * sizeof(FIXP_CNCL));
+#else
+ FIXP_CNCL *RESTRICT pCncl =
+ &hConcealmentInfo->spectralCoefficient[1024 - 1];
+ FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
+ int i;
+ for (i = 1024; i != 0; i--) {
+ *pCncl-- = FX_DBL2FX_CNCL(*pSpec--);
+ }
+#endif
+ } else {
+ /* swap spectral data */
+#if (FIXP_CNCL == FIXP_DBL)
+ C_ALLOC_SCRATCH_START(pSpecTmp, FIXP_DBL, 1024);
+ FDKmemcpy(pSpecTmp, pSpectralCoefficient, 1024 * sizeof(FIXP_DBL));
+ FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient,
+ 1024 * sizeof(FIXP_DBL));
+ FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpecTmp,
+ 1024 * sizeof(FIXP_DBL));
+ C_ALLOC_SCRATCH_END(pSpecTmp, FIXP_DBL, 1024);
+#else
+ FIXP_CNCL *RESTRICT pCncl =
+ &hConcealmentInfo->spectralCoefficient[1024 - 1];
+ FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
+ FIXP_DBL tSpec;
+
+ for (int i = 1024; i != 0; i--) {
+ tSpec = *pSpec;
+ *pSpec-- = FX_CNCL2FX_DBL(*pCncl);
+ *pCncl-- = FX_DBL2FX_CNCL(tSpec);
+ }
+#endif
+
+ /* complete swapping of window infos */
+ pIcsInfo->WindowSequence = tWindowSequence;
+ pIcsInfo->WindowShape = tWindowShape;
+
+ /* complete swapping of scale factors */
+ FDKmemcpy(pSpecScale, tSpecScale, 8 * sizeof(SHORT));
+ }
+ }
+
+ if (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD) {
+ /* Store LSF4 */
+ FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf,
+ sizeof(hConcealmentInfo->lsf4));
+ /* Store TCX gain */
+ hConcealmentInfo->last_tcx_gain =
+ pAacDecoderStaticChannelInfo->last_tcx_gain;
+ hConcealmentInfo->last_tcx_gain_e =
+ pAacDecoderStaticChannelInfo->last_tcx_gain_e;
+ }
+}
+
+/*!
+ \brief Apply concealment
+
+ Interface function to different concealment strategies
+ */
+int CConcealment_Apply(
+ CConcealmentInfo *hConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const UCHAR lastLpdMode, const int frameOk, const UINT flags) {
+ int appliedProcessing = 0;
+ const int mute_release_active =
+ frameOk && (hConcealmentInfo->concealState >= ConcealState_Mute) &&
+ (hConcealmentInfo->cntValidFrames + 1 <=
+ hConcealmentInfo->pConcealParams->numMuteReleaseFrames);
+
+ if (hConcealmentInfo->windowShape == CONCEAL_NOT_DEFINED) {
+ /* Initialize window_shape with same value as in the current (parsed) frame.
+ Because section 4.6.11.3.2 (Windowing and block switching) of ISO/IEC
+ 14496-3:2009 says: For the first raw_data_block() to be decoded the
+ window_shape of the left and right half of the window are identical. */
+ hConcealmentInfo->windowShape = pAacDecoderChannelInfo->icsInfo.WindowShape;
+ }
+
+ if (frameOk && !mute_release_active) {
+ /* Update render mode if frameOk except for ongoing mute release state. */
+ hConcealmentInfo->lastRenderMode =
+ (SCHAR)pAacDecoderChannelInfo->renderMode;
+
+ /* Rescue current data for concealment in future frames */
+ CConcealment_Store(hConcealmentInfo, pAacDecoderChannelInfo,
+ pAacDecoderStaticChannelInfo);
+ /* Reset index to random sign vector to make sign calculation frame agnostic
+ (only depends on number of subsequently concealed spectral blocks) */
+ hConcealmentInfo->iRandomPhase = 0;
+ } else {
+ if (hConcealmentInfo->lastRenderMode == AACDEC_RENDER_INVALID) {
+ hConcealmentInfo->lastRenderMode = AACDEC_RENDER_IMDCT;
+ }
+ pAacDecoderChannelInfo->renderMode =
+ (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode;
+ }
+
+ /* hand current frame status to the state machine */
+ CConcealment_UpdateState(hConcealmentInfo, frameOk,
+ pAacDecoderStaticChannelInfo, samplesPerFrame,
+ pAacDecoderChannelInfo);
+
+ {
+ if (!frameOk && pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_IMDCT) {
+ /* LPC extrapolation */
+ CLpc_Conceal(pAacDecoderChannelInfo->data.usac.lsp_coeff,
+ pAacDecoderStaticChannelInfo->lpc4_lsf,
+ pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
+ hConcealmentInfo->lastRenderMode == AACDEC_RENDER_IMDCT);
+ FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf,
+ sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf));
+ }
+
+ /* Create data for signal rendering according to the selected concealment
+ * method and decoder operating mode. */
+
+ if ((!frameOk || mute_release_active) &&
+ (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD)) {
+ /* Restore old LSF4 */
+ FDKmemcpy(pAacDecoderStaticChannelInfo->lpc4_lsf, hConcealmentInfo->lsf4,
+ sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf));
+ /* Restore old TCX gain */
+ pAacDecoderStaticChannelInfo->last_tcx_gain =
+ hConcealmentInfo->last_tcx_gain;
+ pAacDecoderStaticChannelInfo->last_tcx_gain_e =
+ hConcealmentInfo->last_tcx_gain_e;
+ }
+
+ if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
+ pAacDecoderStaticChannelInfo->last_lpd_mode == 0)) {
+ switch (hConcealmentInfo->pConcealParams->method) {
+ default:
+ case ConcealMethodMute:
+ if (!frameOk) {
+ /* Mute spectral data in case of errors */
+ FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient,
+ samplesPerFrame * sizeof(FIXP_DBL));
+ /* Set last window shape */
+ pAacDecoderChannelInfo->icsInfo.WindowShape =
+ hConcealmentInfo->windowShape;
+ appliedProcessing = 1;
+ }
+ break;
+
+ case ConcealMethodNoise:
+ /* Noise substitution error concealment technique */
+ appliedProcessing = CConcealment_ApplyNoise(
+ hConcealmentInfo, pAacDecoderChannelInfo,
+ pAacDecoderStaticChannelInfo, pSamplingRateInfo, samplesPerFrame,
+ flags);
+ break;
+
+ case ConcealMethodInter:
+ /* Energy interpolation concealment based on 3GPP */
+ appliedProcessing = CConcealment_ApplyInter(
+ hConcealmentInfo, pAacDecoderChannelInfo, pSamplingRateInfo,
+ samplesPerFrame, 0, /* don't use tonal improvement */
+ frameOk, mute_release_active);
+ break;
+ }
+ } else if (!frameOk || mute_release_active) {
+ /* simply restore the buffer */
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+#if (CNCL_FRACT_BITS != DFRACT_BITS)
+ FIXP_CNCL *RESTRICT pCncl =
+ &hConcealmentInfo->spectralCoefficient[1024 - 1];
+ FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
+ int i;
+#endif
+
+ /* restore window infos (gri) do we need that? */
+ pIcsInfo->WindowSequence = hConcealmentInfo->windowSequence;
+ pIcsInfo->WindowShape = hConcealmentInfo->windowShape;
+
+ if (hConcealmentInfo->concealState != ConcealState_Mute) {
+ /* restore scale factors */
+ FDKmemcpy(pSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT));
+
+ /* restore spectral bins */
+#if (CNCL_FRACT_BITS == DFRACT_BITS)
+ FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient,
+ 1024 * sizeof(FIXP_DBL));
+#else
+ for (i = 1024; i != 0; i--) {
+ *pSpec-- = FX_CNCL2FX_DBL(*pCncl--);
+ }
+#endif
+ } else {
+ /* clear scale factors */
+ FDKmemclear(pSpecScale, 8 * sizeof(SHORT));
+
+ /* clear buffer */
+ FDKmemclear(pSpectralCoefficient, 1024 * sizeof(FIXP_CNCL));
+ }
+ }
+ }
+ /* update history */
+ hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1];
+ hConcealmentInfo->prevFrameOk[1] = frameOk;
+
+ return mute_release_active ? -1 : appliedProcessing;
+}
+
+/*!
+\brief Apply concealment noise substitution
+
+ In case of frame lost this function produces a noisy frame with respect to the
+ energies values of past frame.
+ */
+static int CConcealment_ApplyNoise(
+ CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const UINT flags) {
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+
+ int appliedProcessing = 0;
+
+ FDK_ASSERT(pConcealmentInfo != NULL);
+ FDK_ASSERT((samplesPerFrame >= 120) && (samplesPerFrame <= 1024));
+
+ switch (pConcealmentInfo->concealState) {
+ case ConcealState_Ok:
+ /* Nothing to do here! */
+ break;
+
+ case ConcealState_Single:
+ case ConcealState_FadeOut:
+ appliedProcessing = CConcealment_ApplyFadeOut(
+ /*mode =*/1, pConcealmentInfo, pAacDecoderStaticChannelInfo,
+ samplesPerFrame, pAacDecoderChannelInfo);
+ break;
+
+ case ConcealState_Mute: {
+ /* set dummy window parameters */
+ pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */
+ pIcsInfo->WindowShape =
+ pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape
+ (required for F/T transform) */
+ pIcsInfo->WindowSequence =
+ CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
+ pConcealmentInfo->windowSequence =
+ pIcsInfo->WindowSequence; /* Store for next frame
+ (spectrum in concealment
+ buffer can't be used at
+ all) */
+
+ /* mute spectral data */
+ FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
+ FDKmemclear(pConcealmentInfo->spectralCoefficient,
+ samplesPerFrame * sizeof(FIXP_DBL));
+
+ appliedProcessing = 1;
+ } break;
+
+ case ConcealState_FadeIn: {
+ /* TimeDomainFading: */
+ /* Attenuation of signal is done in CConcealment_TDFading() */
+
+ appliedProcessing = 1;
+ } break;
+
+ default:
+ /* we shouldn't come here anyway */
+ FDK_ASSERT(0);
+ break;
+ }
+
+ return appliedProcessing;
+}
+
+/*!
+ \brief Apply concealment interpolation
+
+ The function swaps the data from the current and the previous frame. If an
+ error has occured, frame interpolation is performed to restore the missing
+ frame. In case of multiple faulty frames, fade-in and fade-out is applied.
+*/
+static int CConcealment_ApplyInter(
+ CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const int improveTonal, const int frameOk, const int mute_release_active) {
+#if defined(FDK_ASSERT_ENABLE)
+ CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
+#endif
+
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+ SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
+
+ int sfbEnergyPrev[64];
+ int sfbEnergyAct[64];
+
+ int i, appliedProcessing = 0;
+
+ /* clear/init */
+ FDKmemclear(sfbEnergyPrev, 64 * sizeof(int));
+ FDKmemclear(sfbEnergyAct, 64 * sizeof(int));
+
+ if (!frameOk || mute_release_active) {
+ /* Restore last frame from concealment buffer */
+ pIcsInfo->WindowShape = pConcealmentInfo->windowShape;
+ pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
+
+ /* Restore spectral data */
+ for (i = 0; i < samplesPerFrame; i++) {
+ pSpectralCoefficient[i] =
+ FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]);
+ }
+
+ /* Restore scale factors */
+ FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8 * sizeof(SHORT));
+ }
+
+ /* if previous frame was not ok */
+ if (!pConcealmentInfo->prevFrameOk[1] || mute_release_active) {
+ /* if current frame (f_n) is ok and the last but one frame (f_(n-2))
+ was ok, too, then interpolate both frames in order to generate
+ the current output frame (f_(n-1)). Otherwise, use the last stored
+ frame (f_(n-2) or f_(n-3) or ...). */
+ if (frameOk && pConcealmentInfo->prevFrameOk[0] && !mute_release_active) {
+ appliedProcessing = 1;
+
+ /* Interpolate both frames in order to generate the current output frame
+ * (f_(n-1)). */
+ if (pIcsInfo->WindowSequence == BLOCK_SHORT) {
+ /* f_(n-2) == BLOCK_SHORT */
+ /* short--??????--short, short--??????--long interpolation */
+ /* short--short---short, short---long---long interpolation */
+
+ int wnd;
+
+ if (pConcealmentInfo->windowSequence ==
+ BLOCK_SHORT) { /* f_n == BLOCK_SHORT */
+ /* short--short---short interpolation */
+
+ int scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Short;
+ const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
+ pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1;
+ pIcsInfo->WindowSequence = BLOCK_SHORT;
+
+ for (wnd = 0; wnd < 8; wnd++) {
+ CConcealment_CalcBandEnergy(
+ &pSpectralCoefficient[wnd *
+ (samplesPerFrame / 8)], /* spec_(n-2) */
+ pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand,
+ sfbEnergyPrev);
+
+ CConcealment_CalcBandEnergy(
+ &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame /
+ 8)], /* spec_n */
+ pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand,
+ sfbEnergyAct);
+
+ CConcealment_InterpolateBuffer(
+ &pSpectralCoefficient[wnd *
+ (samplesPerFrame / 8)], /* spec_(n-1) */
+ &pSpecScale[wnd], &pConcealmentInfo->specScale[wnd],
+ &pSpecScale[wnd], sfbEnergyPrev, sfbEnergyAct,
+ scaleFactorBandsTotal, pSfbOffset);
+ }
+ } else { /* f_n != BLOCK_SHORT */
+ /* short---long---long interpolation */
+
+ int scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Long;
+ const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
+ SHORT specScaleOut;
+
+ CConcealment_CalcBandEnergy(
+ &pSpectralCoefficient[samplesPerFrame -
+ (samplesPerFrame /
+ 8)], /* [wnd] spec_(n-2) */
+ pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand,
+ sfbEnergyAct);
+
+ CConcealment_CalcBandEnergy(
+ pConcealmentInfo->spectralCoefficient, /* spec_n */
+ pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand,
+ sfbEnergyPrev);
+
+ pIcsInfo->WindowShape = 0;
+ pIcsInfo->WindowSequence = BLOCK_STOP;
+
+ for (i = 0; i < samplesPerFrame; i++) {
+ pSpectralCoefficient[i] =
+ pConcealmentInfo->spectralCoefficient[i]; /* spec_n */
+ }
+
+ for (i = 0; i < 8; i++) { /* search for max(specScale) */
+ if (pSpecScale[i] > pSpecScale[0]) {
+ pSpecScale[0] = pSpecScale[i];
+ }
+ }
+
+ CConcealment_InterpolateBuffer(
+ pSpectralCoefficient, /* spec_(n-1) */
+ &pConcealmentInfo->specScale[0], &pSpecScale[0], &specScaleOut,
+ sfbEnergyPrev, sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset);
+
+ pSpecScale[0] = specScaleOut;
+ }
+ } else {
+ /* long--??????--short, long--??????--long interpolation */
+ /* long---long---short, long---long---long interpolation */
+
+ int scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Long;
+ const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
+ SHORT specScaleAct = pConcealmentInfo->specScale[0];
+
+ CConcealment_CalcBandEnergy(pSpectralCoefficient, /* spec_(n-2) */
+ pSamplingRateInfo, BLOCK_LONG,
+ CConcealment_NoExpand, sfbEnergyPrev);
+
+ if (pConcealmentInfo->windowSequence ==
+ BLOCK_SHORT) { /* f_n == BLOCK_SHORT */
+ /* long---long---short interpolation */
+
+ pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1;
+ pIcsInfo->WindowSequence = BLOCK_START;
+
+ for (i = 1; i < 8; i++) { /* search for max(specScale) */
+ if (pConcealmentInfo->specScale[i] > specScaleAct) {
+ specScaleAct = pConcealmentInfo->specScale[i];
+ }
+ }
+
+ /* Expand first short spectrum */
+ CConcealment_CalcBandEnergy(
+ pConcealmentInfo->spectralCoefficient, /* spec_n */
+ pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand, /* !!! */
+ sfbEnergyAct);
+ } else {
+ /* long---long---long interpolation */
+
+ pIcsInfo->WindowShape = 0;
+ pIcsInfo->WindowSequence = BLOCK_LONG;
+
+ CConcealment_CalcBandEnergy(
+ pConcealmentInfo->spectralCoefficient, /* spec_n */
+ pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand,
+ sfbEnergyAct);
+ }
+
+ CConcealment_InterpolateBuffer(
+ pSpectralCoefficient, /* spec_(n-1) */
+ &pSpecScale[0], &specScaleAct, &pSpecScale[0], sfbEnergyPrev,
+ sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset);
+ }
+ }
+
+ /* Noise substitution of sign of the output spectral coefficients */
+ CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase,
+ pSpectralCoefficient, samplesPerFrame);
+ /* Increment random phase index to avoid repetition artifacts. */
+ pConcealmentInfo->iRandomPhase =
+ (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
+ }
+
+ /* scale spectrum according to concealment state */
+ switch (pConcealmentInfo->concealState) {
+ case ConcealState_Single:
+ appliedProcessing = 1;
+ break;
+
+ case ConcealState_FadeOut: {
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
+ CONCEAL_MAX_NUM_FADE_FACTORS);
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
+ pConcealCommonData->numFadeOutFrames);
+
+ /* TimeDomainFading: */
+ /* Attenuation of signal is done in CConcealment_TDFading() */
+
+ appliedProcessing = 1;
+ } break;
+
+ case ConcealState_FadeIn: {
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
+ CONCEAL_MAX_NUM_FADE_FACTORS);
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
+ pConcealCommonData->numFadeInFrames);
+
+ /* TimeDomainFading: */
+ /* Attenuation of signal is done in CConcealment_TDFading() */
+
+ appliedProcessing = 1;
+ } break;
+
+ case ConcealState_Mute: {
+ /* set dummy window parameters */
+ pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */
+ pIcsInfo->WindowShape =
+ pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape
+ (required for F/T transform) */
+ pIcsInfo->WindowSequence =
+ CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
+ pConcealmentInfo->windowSequence =
+ pIcsInfo->WindowSequence; /* Store for next frame
+ (spectrum in concealment
+ buffer can't be used at
+ all) */
+
+ /* mute spectral data */
+ FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
+
+ appliedProcessing = 1;
+ } break;
+
+ default:
+ /* nothing to do here */
+ break;
+ }
+
+ return appliedProcessing;
+}
+
+/*!
+ \brief Calculate the spectral energy
+
+ The function calculates band-wise the spectral energy. This is used for
+ frame interpolation.
+*/
+static void CConcealment_CalcBandEnergy(
+ FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo,
+ const int blockType, CConcealmentExpandType expandType, int *sfbEnergy) {
+ const SHORT *pSfbOffset;
+ int line, sfb, scaleFactorBandsTotal = 0;
+
+ /* In the following calculations, enAccu is initialized with LSB-value in
+ * order to avoid zero energy-level */
+
+ line = 0;
+
+ switch (blockType) {
+ case BLOCK_LONG:
+ case BLOCK_START:
+ case BLOCK_STOP:
+
+ if (expandType == CConcealment_NoExpand) {
+ /* standard long calculation */
+ scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Long;
+ pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
+
+ for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
+ FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
+ int sfbScale =
+ (sizeof(LONG) << 3) -
+ CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
+ /* scaling depends on sfb width. */
+ for (; line < pSfbOffset[sfb + 1]; line++) {
+ enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
+ }
+ *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
+ }
+ } else {
+ /* compress long to short */
+ scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Short;
+ pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
+
+ for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
+ FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
+ int sfbScale =
+ (sizeof(LONG) << 3) -
+ CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
+ /* scaling depends on sfb width. */
+ for (; line < pSfbOffset[sfb + 1] << 3; line++) {
+ enAccu +=
+ (enAccu + (fPow2Div2(*(spectrum + line)) >> sfbScale)) >> 3;
+ }
+ *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
+ }
+ }
+ break;
+
+ case BLOCK_SHORT:
+
+ if (expandType == CConcealment_NoExpand) {
+ /* standard short calculation */
+ scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Short;
+ pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
+
+ for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
+ FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
+ int sfbScale =
+ (sizeof(LONG) << 3) -
+ CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
+ /* scaling depends on sfb width. */
+ for (; line < pSfbOffset[sfb + 1]; line++) {
+ enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
+ }
+ *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
+ }
+ } else {
+ /* expand short to long spectrum */
+ scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Long;
+ pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
+
+ for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
+ FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
+ int sfbScale =
+ (sizeof(LONG) << 3) -
+ CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
+ /* scaling depends on sfb width. */
+ for (; line < pSfbOffset[sfb + 1]; line++) {
+ enAccu += fPow2Div2(*(spectrum + (line >> 3))) >> sfbScale;
+ }
+ *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
+ }
+ }
+ break;
+ }
+}
+
+/*!
+ \brief Interpolate buffer
+
+ The function creates the interpolated spectral data according to the
+ energy of the last good frame and the current (good) frame.
+*/
+static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
+ SHORT *pSpecScalePrv,
+ SHORT *pSpecScaleAct,
+ SHORT *pSpecScaleOut, int *enPrv,
+ int *enAct, int sfbCnt,
+ const SHORT *pSfbOffset) {
+ int sfb, line = 0;
+ int fac_shift;
+ int fac_mod;
+ FIXP_DBL accu;
+
+ for (sfb = 0; sfb < sfbCnt; sfb++) {
+ fac_shift =
+ enPrv[sfb] - enAct[sfb] + ((*pSpecScaleAct - *pSpecScalePrv) << 1);
+ fac_mod = fac_shift & 3;
+ fac_shift = (fac_shift >> 2) + 1;
+ fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct);
+
+ for (; line < pSfbOffset[sfb + 1]; line++) {
+ accu = fMult(*(spectrum + line), facMod4Table[fac_mod]);
+ if (fac_shift < 0) {
+ accu >>= -fac_shift;
+ } else {
+ accu <<= fac_shift;
+ }
+ *(spectrum + line) = accu;
+ }
+ }
+ *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct);
+}
+
+/*!
+ \brief Find next fading frame in case of changing fading direction
+
+ \param pConcealCommonData Pointer to the concealment common data structure.
+ \param actFadeIndex Last index used for fading
+ \param direction Direction of change: 0 : change from FADE-OUT to FADE-IN, 1
+ : change from FADE-IN to FADE-OUT
+
+ This function determines the next fading index to be used for the fading
+ direction to be changed to.
+*/
+
+static INT findEquiFadeFrame(CConcealParams *pConcealCommonData,
+ INT actFadeIndex, int direction) {
+ FIXP_SGL *pFactor;
+ FIXP_SGL referenceVal;
+ FIXP_SGL minDiff = (FIXP_SGL)MAXVAL_SGL;
+
+ INT nextFadeIndex = 0;
+
+ int i;
+
+ /* init depending on direction */
+ if (direction == 0) { /* FADE-OUT => FADE-IN */
+ if (actFadeIndex < 0) {
+ referenceVal = (FIXP_SGL)MAXVAL_SGL;
+ } else {
+ referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1;
+ }
+ pFactor = pConcealCommonData->fadeInFactor;
+ } else { /* FADE-IN => FADE-OUT */
+ if (actFadeIndex < 0) {
+ referenceVal = (FIXP_SGL)MAXVAL_SGL;
+ } else {
+ referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1;
+ }
+ pFactor = pConcealCommonData->fadeOutFactor;
+ }
+
+ /* search for minimum difference */
+ for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ FIXP_SGL diff = fixp_abs((pFactor[i] >> 1) - referenceVal);
+ if (diff < minDiff) {
+ minDiff = diff;
+ nextFadeIndex = i;
+ }
+ }
+
+ /* check and adjust depending on direction */
+ if (direction == 0) { /* FADE-OUT => FADE-IN */
+ if (nextFadeIndex > pConcealCommonData->numFadeInFrames) {
+ nextFadeIndex = fMax(pConcealCommonData->numFadeInFrames - 1, 0);
+ }
+ if (((pFactor[nextFadeIndex] >> 1) <= referenceVal) &&
+ (nextFadeIndex > 0)) {
+ nextFadeIndex -= 1;
+ }
+ } else { /* FADE-IN => FADE-OUT */
+ if (((pFactor[nextFadeIndex] >> 1) >= referenceVal) &&
+ (nextFadeIndex < CONCEAL_MAX_NUM_FADE_FACTORS - 1)) {
+ nextFadeIndex += 1;
+ }
+ }
+
+ return (nextFadeIndex);
+}
+
+/*!
+ \brief Update the concealment state
+
+ The function updates the state of the concealment state-machine. The
+ states are: mute, fade-in, fade-out, interpolate and frame-ok.
+*/
+static void CConcealment_UpdateState(
+ CConcealmentInfo *pConcealmentInfo, int frameOk,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
+
+ switch (pConcealCommonData->method) {
+ case ConcealMethodNoise: {
+ if (pConcealmentInfo->concealState != ConcealState_Ok) {
+ /* count the valid frames during concealment process */
+ if (frameOk) {
+ pConcealmentInfo->cntValidFrames += 1;
+ } else {
+ pConcealmentInfo->cntValidFrames = 0;
+ }
+ }
+
+ /* -- STATE MACHINE for Noise Substitution -- */
+ switch (pConcealmentInfo->concealState) {
+ case ConcealState_Ok:
+ if (!frameOk) {
+ pConcealmentInfo->cntFadeFrames = 0;
+ pConcealmentInfo->cntValidFrames = 0;
+ pConcealmentInfo->attGrpOffset[0] = 0;
+ pConcealmentInfo->attGrpOffset[1] = 0;
+ pConcealmentInfo->winGrpOffset[0] = 0;
+ pConcealmentInfo->winGrpOffset[1] = 0;
+ if (pConcealCommonData->numFadeOutFrames > 0) {
+ /* change to state SINGLE-FRAME-LOSS */
+ pConcealmentInfo->concealState = ConcealState_Single;
+ /* mode 0 just updates the Fading counter */
+ CConcealment_ApplyFadeOut(
+ /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
+ samplesPerFrame, pAacDecoderChannelInfo);
+
+ } else {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ }
+ }
+ break;
+
+ case ConcealState_Single: /* Just a pre-stage before fade-out begins.
+ Stay here only one frame! */
+ if (frameOk) {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ } else {
+ if (pConcealmentInfo->cntFadeFrames >=
+ pConcealCommonData->numFadeOutFrames) {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ } else {
+ /* change to state FADE-OUT */
+ pConcealmentInfo->concealState = ConcealState_FadeOut;
+ /* mode 0 just updates the Fading counter */
+ CConcealment_ApplyFadeOut(
+ /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
+ samplesPerFrame, pAacDecoderChannelInfo);
+ }
+ }
+ break;
+
+ case ConcealState_FadeOut:
+ if (pConcealmentInfo->cntValidFrames >
+ pConcealCommonData->numMuteReleaseFrames) {
+ if (pConcealCommonData->numFadeInFrames > 0) {
+ /* change to state FADE-IN */
+ pConcealmentInfo->concealState = ConcealState_FadeIn;
+ pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
+ pConcealCommonData, pConcealmentInfo->cntFadeFrames,
+ 0 /* FadeOut -> FadeIn */);
+ } else {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ } else {
+ if (frameOk) {
+ /* we have good frame information but stay fully in concealment -
+ * reset winGrpOffset/attGrpOffset */
+ pConcealmentInfo->winGrpOffset[0] = 0;
+ pConcealmentInfo->winGrpOffset[1] = 0;
+ pConcealmentInfo->attGrpOffset[0] = 0;
+ pConcealmentInfo->attGrpOffset[1] = 0;
+ }
+ if (pConcealmentInfo->cntFadeFrames >=
+ pConcealCommonData->numFadeOutFrames) {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ } else /* Stay in FADE-OUT */
+ {
+ /* mode 0 just updates the Fading counter */
+ CConcealment_ApplyFadeOut(
+ /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
+ samplesPerFrame, pAacDecoderChannelInfo);
+ }
+ }
+ break;
+
+ case ConcealState_Mute:
+ if (pConcealmentInfo->cntValidFrames >
+ pConcealCommonData->numMuteReleaseFrames) {
+ if (pConcealCommonData->numFadeInFrames > 0) {
+ /* change to state FADE-IN */
+ pConcealmentInfo->concealState = ConcealState_FadeIn;
+ pConcealmentInfo->cntFadeFrames =
+ pConcealCommonData->numFadeInFrames - 1;
+ } else {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ } else {
+ if (frameOk) {
+ /* we have good frame information but stay fully in concealment -
+ * reset winGrpOffset/attGrpOffset */
+ pConcealmentInfo->winGrpOffset[0] = 0;
+ pConcealmentInfo->winGrpOffset[1] = 0;
+ pConcealmentInfo->attGrpOffset[0] = 0;
+ pConcealmentInfo->attGrpOffset[1] = 0;
+ }
+ }
+ break;
+
+ case ConcealState_FadeIn:
+ pConcealmentInfo->cntFadeFrames -= 1;
+ if (frameOk) {
+ if (pConcealmentInfo->cntFadeFrames < 0) {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ } else {
+ if (pConcealCommonData->numFadeOutFrames > 0) {
+ /* change to state FADE-OUT */
+ pConcealmentInfo->concealState = ConcealState_FadeOut;
+ pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
+ pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1,
+ 1 /* FadeIn -> FadeOut */);
+ pConcealmentInfo->winGrpOffset[0] = 0;
+ pConcealmentInfo->winGrpOffset[1] = 0;
+ pConcealmentInfo->attGrpOffset[0] = 0;
+ pConcealmentInfo->attGrpOffset[1] = 0;
+
+ pConcealmentInfo
+ ->cntFadeFrames--; /* decrease because
+ CConcealment_ApplyFadeOut() will
+ increase, accordingly */
+ /* mode 0 just updates the Fading counter */
+ CConcealment_ApplyFadeOut(
+ /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
+ samplesPerFrame, pAacDecoderChannelInfo);
+ } else {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ }
+ }
+ break;
+
+ default:
+ FDK_ASSERT(0);
+ break;
+ }
+ } break;
+
+ case ConcealMethodInter:
+ case ConcealMethodTonal: {
+ if (pConcealmentInfo->concealState != ConcealState_Ok) {
+ /* count the valid frames during concealment process */
+ if (pConcealmentInfo->prevFrameOk[1] ||
+ (pConcealmentInfo->prevFrameOk[0] &&
+ !pConcealmentInfo->prevFrameOk[1] && frameOk)) {
+ /* The frame is OK even if it can be estimated by the energy
+ * interpolation algorithm */
+ pConcealmentInfo->cntValidFrames += 1;
+ } else {
+ pConcealmentInfo->cntValidFrames = 0;
+ }
+ }
+
+ /* -- STATE MACHINE for energy interpolation -- */
+ switch (pConcealmentInfo->concealState) {
+ case ConcealState_Ok:
+ if (!(pConcealmentInfo->prevFrameOk[1] ||
+ (pConcealmentInfo->prevFrameOk[0] &&
+ !pConcealmentInfo->prevFrameOk[1] && frameOk))) {
+ if (pConcealCommonData->numFadeOutFrames > 0) {
+ /* Fade out only if the energy interpolation algorithm can not be
+ * applied! */
+ pConcealmentInfo->concealState = ConcealState_FadeOut;
+ } else {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ }
+ pConcealmentInfo->cntFadeFrames = 0;
+ pConcealmentInfo->cntValidFrames = 0;
+ }
+ break;
+
+ case ConcealState_Single:
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ break;
+
+ case ConcealState_FadeOut:
+ pConcealmentInfo->cntFadeFrames += 1;
+
+ if (pConcealmentInfo->cntValidFrames >
+ pConcealCommonData->numMuteReleaseFrames) {
+ if (pConcealCommonData->numFadeInFrames > 0) {
+ /* change to state FADE-IN */
+ pConcealmentInfo->concealState = ConcealState_FadeIn;
+ pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
+ pConcealCommonData, pConcealmentInfo->cntFadeFrames - 1,
+ 0 /* FadeOut -> FadeIn */);
+ } else {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ } else {
+ if (pConcealmentInfo->cntFadeFrames >=
+ pConcealCommonData->numFadeOutFrames) {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ }
+ }
+ break;
+
+ case ConcealState_Mute:
+ if (pConcealmentInfo->cntValidFrames >
+ pConcealCommonData->numMuteReleaseFrames) {
+ if (pConcealCommonData->numFadeInFrames > 0) {
+ /* change to state FADE-IN */
+ pConcealmentInfo->concealState = ConcealState_FadeIn;
+ pConcealmentInfo->cntFadeFrames =
+ pConcealCommonData->numFadeInFrames - 1;
+ } else {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ }
+ break;
+
+ case ConcealState_FadeIn:
+ pConcealmentInfo->cntFadeFrames -=
+ 1; /* used to address the fade-in factors */
+
+ if (frameOk || pConcealmentInfo->prevFrameOk[1]) {
+ if (pConcealmentInfo->cntFadeFrames < 0) {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ } else {
+ if (pConcealCommonData->numFadeOutFrames > 0) {
+ /* change to state FADE-OUT */
+ pConcealmentInfo->concealState = ConcealState_FadeOut;
+ pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
+ pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1,
+ 1 /* FadeIn -> FadeOut */);
+ } else {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ }
+ }
+ break;
+ } /* End switch(pConcealmentInfo->concealState) */
+ } break;
+
+ default:
+ /* Don't need a state machine for other concealment methods. */
+ break;
+ }
+}
+
+/*!
+\brief Randomizes the sign of the spectral data
+
+ The function toggles the sign of the spectral data randomly. This is
+ useful to ensure the quality of the concealed frames.
+ */
+static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec,
+ int samplesPerFrame) {
+ int i;
+ USHORT packedSign = 0;
+
+ /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit
+ */
+
+ /* read current packed sign word */
+ packedSign = AacDec_randomSign[randomPhase >> 4];
+ packedSign >>= (randomPhase & 0xf);
+
+ for (i = 0; i < samplesPerFrame; i++) {
+ if ((randomPhase & 0xf) == 0) {
+ packedSign = AacDec_randomSign[randomPhase >> 4];
+ }
+
+ if (packedSign & 0x1) {
+ spec[i] = -spec[i];
+ }
+ packedSign >>= 1;
+
+ randomPhase = (randomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
+ }
+}
+
+/*!
+ \brief Get fadeing factor for current concealment state.
+
+ The function returns the state (ok or not) of the previous frame.
+ If called before the function CConcealment_Apply() set the fBeforeApply
+ flag to get the correct value.
+
+ \return Frame OK flag of previous frame.
+ */
+int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo,
+ const int fBeforeApply) {
+ int prevFrameOk = 1;
+
+ if (hConcealmentInfo != NULL) {
+ prevFrameOk = hConcealmentInfo->prevFrameOk[fBeforeApply & 0x1];
+ }
+
+ return prevFrameOk;
+}
+
+/*!
+ \brief Get the number of delay frames introduced by concealment technique.
+
+ \return Number of delay frames.
+ */
+UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData) {
+ UINT frameDelay = 0;
+
+ if (pConcealCommonData != NULL) {
+ switch (pConcealCommonData->method) {
+ case ConcealMethodTonal:
+ case ConcealMethodInter:
+ frameDelay = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return frameDelay;
+}
+
+static int CConcealment_ApplyFadeOut(
+ int mode, CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ /* mode 1 = apply RandomSign and mute spectral coefficients if necessary, *
+ * mode 0 = Update cntFadeFrames */
+
+ /* restore frequency coefficients from buffer with a specific muting */
+ int srcWin, dstWin, numWindows = 1;
+ int windowLen = samplesPerFrame;
+ int srcGrpStart = 0;
+ int winIdxStride = 1;
+ int numWinGrpPerFac, attIdx, attIdxStride;
+ int i;
+ int appliedProcessing = 0;
+
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
+
+ /* set old window parameters */
+ if (pConcealmentInfo->lastRenderMode == AACDEC_RENDER_LPD) {
+ switch (pAacDecoderStaticChannelInfo->last_lpd_mode) {
+ case 1:
+ numWindows = 4;
+ srcGrpStart = 3;
+ windowLen = samplesPerFrame >> 2;
+ break;
+ case 2:
+ numWindows = 2;
+ srcGrpStart = 1;
+ windowLen = samplesPerFrame >> 1;
+ winIdxStride = 2;
+ break;
+ case 3:
+ numWindows = 1;
+ srcGrpStart = 0;
+ windowLen = samplesPerFrame;
+ winIdxStride = 4;
+ break;
+ }
+ pConcealmentInfo->lastWinGrpLen = 1;
+ } else {
+ pIcsInfo->WindowShape = pConcealmentInfo->windowShape;
+ pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
+
+ if (pConcealmentInfo->windowSequence == BLOCK_SHORT) {
+ /* short block handling */
+ numWindows = 8;
+ windowLen = samplesPerFrame >> 3;
+ srcGrpStart = numWindows - pConcealmentInfo->lastWinGrpLen;
+ }
+ }
+
+ attIdxStride =
+ fMax(1, (int)(numWindows / (pConcealmentInfo->lastWinGrpLen + 1)));
+
+ /* load last state */
+ attIdx = pConcealmentInfo->cntFadeFrames;
+ numWinGrpPerFac = pConcealmentInfo->attGrpOffset[mode];
+ srcWin = srcGrpStart + pConcealmentInfo->winGrpOffset[mode];
+
+ FDK_ASSERT((srcGrpStart * windowLen + windowLen) <= samplesPerFrame);
+ FDK_ASSERT((srcWin * windowLen + windowLen) <= 1024);
+
+ for (dstWin = 0; dstWin < numWindows; dstWin += 1) {
+ FIXP_CNCL *pCncl =
+ pConcealmentInfo->spectralCoefficient + (srcWin * windowLen);
+ FIXP_DBL *pOut = pSpectralCoefficient + (dstWin * windowLen);
+
+ if (mode == 1) {
+ /* mute if attIdx gets large enaugh */
+ if (attIdx > pConcealmentInfo->pConcealParams->numFadeOutFrames) {
+ FDKmemclear(pCncl, sizeof(FIXP_DBL) * windowLen);
+ }
+
+ /* restore frequency coefficients from buffer - attenuation is done later
+ */
+ for (i = 0; i < windowLen; i++) {
+ pOut[i] = pCncl[i];
+ }
+
+ /* apply random change of sign for spectral coefficients */
+ CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase, pOut,
+ windowLen);
+
+ /* Increment random phase index to avoid repetition artifacts. */
+ pConcealmentInfo->iRandomPhase =
+ (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
+
+ /* set old scale factors */
+ pSpecScale[dstWin * winIdxStride] =
+ pConcealmentInfo->specScale[srcWin * winIdxStride];
+ }
+
+ srcWin += 1;
+
+ if (srcWin >= numWindows) {
+ /* end of sequence -> rewind to first window of group */
+ srcWin = srcGrpStart;
+ numWinGrpPerFac += 1;
+ if (numWinGrpPerFac >= attIdxStride) {
+ numWinGrpPerFac = 0;
+ attIdx += 1;
+ }
+ }
+ }
+
+ /* store current state */
+
+ pConcealmentInfo->winGrpOffset[mode] = srcWin - srcGrpStart;
+ FDK_ASSERT((pConcealmentInfo->winGrpOffset[mode] >= 0) &&
+ (pConcealmentInfo->winGrpOffset[mode] < 8));
+ pConcealmentInfo->attGrpOffset[mode] = numWinGrpPerFac;
+ FDK_ASSERT((pConcealmentInfo->attGrpOffset[mode] >= 0) &&
+ (pConcealmentInfo->attGrpOffset[mode] < attIdxStride));
+
+ if (mode == 0) {
+ pConcealmentInfo->cntFadeFrames = attIdx;
+ }
+
+ appliedProcessing = 1;
+
+ return appliedProcessing;
+}
+
+/*!
+ \brief Do Time domain fading (TDFading) in concealment case
+
+ In case of concealment, this function takes care of the fading, after time
+domain signal has been rendered by the respective signal rendering functions.
+ The fading out in case of ACELP decoding is not done by this function but by
+the ACELP decoder for the first concealed frame if CONCEAL_CORE_IGNORANT_FADE is
+not set.
+
+ TimeDomain fading never creates jumps in energy / discontinuities, it always
+does a continuous fading. To achieve this, fading is always done from a starting
+point to a target point, while the starting point is always determined to be the
+last target point. By varying the target point of a fading, the fading slope can
+be controlled.
+
+ This principle is applied to the fading within a frame and the fading from
+frame to frame.
+
+ One frame is divided into 8 subframes to obtain 8 parts of fading slopes
+within a frame, each maybe with its own gradient.
+
+ Workflow:
+ 1.) Determine Fading behavior and end-of-frame target fading level, based on
+concealmentState (determined by CConcealment_UpdateState()) and the core mode.
+ - By _DEFAULT_,
+ The target fading level is determined by fadeOutFactor[cntFadeFrames]
+in case of fadeOut, or fadeInFactor[cntFadeFrames] in case of fadeIn.
+ --> fading type is FADE_TIMEDOMAIN in this case. Target fading level
+is determined by fading index cntFadeFrames.
+
+ - If concealmentState is signalling a _MUTED SIGNAL_,
+ TDFading decays to 0 within 1/8th of a frame if numFadeOutFrames == 0.
+ --> fading type is FADE_TIMEDOMAIN_TOSPECTRALMUTE in this case.
+
+ - If concealmentState is signalling the _END OF MUTING_,
+ TDFading fades to target fading level within 1/8th of a frame if
+numFadeInFrames == 0.
+ --> fading type is FADE_TIMEDOMAIN_FROMSPECTRALMUTE in this case.
+Target fading level is determined by fading index cntFadeFrames.
+
+#ifndef CONCEAL_CORE_IGNORANT_FADE
+ - In case of an _ACELP FADEOUT_,
+ TDFading leaves fading control to ACELP decoder for 1/2 frame.
+ --> fading type is FADE_ACELPDOMAIN in this case.
+#endif
+
+ 2.) Render fading levels within current frame and do the final fading:
+ Map Fading slopes to fading levels and apply to time domain signal.
+
+
+*/
+
+INT CConcealment_TDFading(
+ int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
+ FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1) {
+ /*
+ Do the fading in Time domain based on concealment states and core mode
+ */
+ FIXP_DBL fadeStop, attMute = (FIXP_DBL)0;
+ int idx = 0, ii;
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo =
+ *ppAacDecoderStaticChannelInfo;
+ CConcealmentInfo *pConcealmentInfo =
+ &pAacDecoderStaticChannelInfo->concealmentInfo;
+ CConcealParams *pConcealParams = pConcealmentInfo->pConcealParams;
+ const CConcealmentState concealState = pConcealmentInfo->concealState;
+ TDfadingType fadingType;
+ FIXP_DBL fadingStations[9] = {0};
+ int fadingSteps[8] = {0};
+ const FIXP_DBL fadeStart =
+ pConcealmentInfo
+ ->fade_old; /* start fading at last end-of-frame attenuation */
+ FIXP_SGL *fadeFactor = pConcealParams->fadeOutFactor;
+ const INT cntFadeFrames = pConcealmentInfo->cntFadeFrames;
+ int TDFadeOutStopBeforeMute = 1;
+ int TDFadeInStopBeforeFullLevel = 1;
+
+ /*
+ determine Fading behaviour (end-of-frame attenuation and fading type) (1.)
+ */
+
+ switch (concealState) {
+ case ConcealState_Single:
+ case ConcealState_Mute:
+ case ConcealState_FadeOut:
+ idx = (pConcealParams->method == ConcealMethodNoise) ? cntFadeFrames - 1
+ : cntFadeFrames;
+ fadingType = FADE_TIMEDOMAIN;
+
+ if (concealState == ConcealState_Mute ||
+ (cntFadeFrames + TDFadeOutStopBeforeMute) >
+ pConcealmentInfo->pConcealParams->numFadeOutFrames) {
+ fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE;
+ }
+
+ break;
+ case ConcealState_FadeIn:
+ idx = cntFadeFrames;
+ idx -= TDFadeInStopBeforeFullLevel;
+ FDK_FALLTHROUGH;
+ case ConcealState_Ok:
+ fadeFactor = pConcealParams->fadeInFactor;
+ idx = (concealState == ConcealState_Ok) ? -1 : idx;
+ fadingType = (pConcealmentInfo->concealState_old == ConcealState_Mute)
+ ? FADE_TIMEDOMAIN_FROMSPECTRALMUTE
+ : FADE_TIMEDOMAIN;
+ break;
+ default:
+ FDK_ASSERT(0);
+ fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE;
+ break;
+ }
+
+ /* determine Target end-of-frame fading level and fading slope */
+ switch (fadingType) {
+ case FADE_TIMEDOMAIN_FROMSPECTRALMUTE:
+ fadeStop =
+ (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]);
+ if (pConcealmentInfo->pConcealParams->numFadeInFrames == 0) {
+ /* do step as fast as possible */
+ fadingSteps[0] = 1;
+ break;
+ }
+ CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
+ break;
+ case FADE_TIMEDOMAIN:
+ fadeStop =
+ (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]);
+ CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
+ break;
+ case FADE_TIMEDOMAIN_TOSPECTRALMUTE:
+ fadeStop = attMute;
+ if (pConcealmentInfo->pConcealParams->numFadeOutFrames == 0) {
+ /* do step as fast as possible */
+ fadingSteps[0] = 1;
+ break;
+ }
+ CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
+ break;
+ }
+
+ /*
+ Render fading levels within current frame and do the final fading (2.)
+ */
+
+ len >>= 3;
+ CConcealment_TDFadeFillFadingStations(fadingStations, fadingSteps, fadeStop,
+ fadeStart, fadingType);
+
+ if ((fadingStations[8] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[7] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[6] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[5] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[4] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[3] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[2] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[1] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[0] !=
+ (FIXP_DBL)MAXVAL_DBL)) /* if there's something to fade */
+ {
+ int start = 0;
+ for (ii = 0; ii < 8; ii++) {
+ CConcealment_TDFadePcmAtt(start, len, fadingStations[ii],
+ fadingStations[ii + 1], pcmdata);
+ start += len;
+ }
+ }
+ CConcealment_TDNoise_Apply(pConcealmentInfo, len, pcmdata);
+
+ /* Save end-of-frame attenuation and fading type */
+ pConcealmentInfo->lastFadingType = fadingType;
+ pConcealmentInfo->fade_old = fadeStop;
+ pConcealmentInfo->concealState_old = concealState;
+
+ return 1;
+}
+
+/* attenuate pcmdata in Time Domain Fading process */
+static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
+ FIXP_DBL fadeStop, FIXP_PCM *pcmdata) {
+ int i;
+ FIXP_DBL dStep;
+ FIXP_DBL dGain;
+ FIXP_DBL dGain_apply;
+ int bitshift = (DFRACT_BITS - SAMPLE_BITS);
+
+ /* set start energy */
+ dGain = fadeStart;
+ /* determine energy steps from sample to sample */
+ dStep = (FIXP_DBL)((int)((fadeStart >> 1) - (fadeStop >> 1)) / len) << 1;
+
+ for (i = start; i < (start + len); i++) {
+ dGain -= dStep;
+ /* prevent gain from getting negative due to possible fixpoint inaccuracies
+ */
+ dGain_apply = fMax((FIXP_DBL)0, dGain);
+ /* finally, attenuate samples */
+ pcmdata[i] = (FIXP_PCM)((fMult(pcmdata[i], (dGain_apply))) >> bitshift);
+ }
+}
+
+/*
+\brief Fill FadingStations
+
+The fadingstations are the attenuation factors, being applied to its dedicated
+portions of pcm data. They are calculated using the fadingsteps. One fadingstep
+is the weighted contribution to the fading slope within its dedicated portion of
+pcm data.
+
+*Fadingsteps : 0 0 0 1 0 1 2 0
+
+ |<- 1 Frame pcm data ->|
+ fadeStart-->|__________ |
+ ^ ^ ^ ^ \____ |
+ Attenuation : | | | | ^ ^\__ |
+ | | | | | | ^\ |
+ | | | | | | | \___|<-- fadeStop
+ | | | | | | | ^ ^
+ | | | | | | | | |
+Fadingstations: [0][1][2][3][4][5][6][7][8]
+
+(Fadingstations "[0]" is "[8] from previous frame", therefore its not meaningful
+to be edited)
+
+*/
+static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
+ int *fadingSteps,
+ FIXP_DBL fadeStop,
+ FIXP_DBL fadeStart,
+ TDfadingType fadingType) {
+ int i;
+ INT fadingSteps_sum = 0;
+ INT fadeDiff;
+
+ fadingSteps_sum = fadingSteps[0] + fadingSteps[1] + fadingSteps[2] +
+ fadingSteps[3] + fadingSteps[4] + fadingSteps[5] +
+ fadingSteps[6] + fadingSteps[7];
+ fadeDiff = ((INT)(fadeStop - fadeStart) / fMax(fadingSteps_sum, (INT)1));
+ fadingStations[0] = fadeStart;
+ for (i = 1; i < 8; i++) {
+ fadingStations[i] =
+ fadingStations[i - 1] + (FIXP_DBL)(fadeDiff * fadingSteps[i - 1]);
+ }
+ fadingStations[8] = fadeStop;
+}
+
+static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps) {
+ fadingSteps[0] = fadingSteps[1] = fadingSteps[2] = fadingSteps[3] =
+ fadingSteps[4] = fadingSteps[5] = fadingSteps[6] = fadingSteps[7] = 1;
+}
+
+/* end of TimeDomainFading functions */
+
+/* derived from int UsacRandomSign() */
+static int CConcealment_TDNoise_Random(ULONG *seed) {
+ *seed = (ULONG)(((UINT64)(*seed) * 69069) + 5);
+ return (int)(*seed);
+}
+
+static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
+ const int len, FIXP_PCM *const pcmdata) {
+ FIXP_PCM *states = pConcealmentInfo->TDNoiseStates;
+ FIXP_PCM noiseVal;
+ FIXP_DBL noiseValLong;
+ FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef;
+ FIXP_DBL TDNoiseAtt;
+ ULONG seed = pConcealmentInfo->TDNoiseSeed =
+ (ULONG)CConcealment_TDNoise_Random(&pConcealmentInfo->TDNoiseSeed) + 1;
+
+ TDNoiseAtt = pConcealmentInfo->pConcealParams->comfortNoiseLevel;
+
+ int ii;
+
+ if ((pConcealmentInfo->concealState != ConcealState_Ok ||
+ pConcealmentInfo->concealState_old != ConcealState_Ok) &&
+ TDNoiseAtt != (FIXP_DBL)0) {
+ for (ii = 0; ii < (len << 3); ii++) {
+ /* create filtered noise */
+ states[2] = states[1];
+ states[1] = states[0];
+ states[0] = ((FIXP_PCM)CConcealment_TDNoise_Random(&seed));
+ noiseValLong = fMult(states[0], coef[0]) + fMult(states[1], coef[1]) +
+ fMult(states[2], coef[2]);
+ noiseVal = FX_DBL2FX_PCM(fMult(noiseValLong, TDNoiseAtt));
+
+ /* add filtered noise - check for clipping, before */
+ if (noiseVal > (FIXP_PCM)0 &&
+ pcmdata[ii] > (FIXP_PCM)MAXVAL_FIXP_PCM - noiseVal) {
+ noiseVal = noiseVal * (FIXP_PCM)-1;
+ } else if (noiseVal < (FIXP_PCM)0 &&
+ pcmdata[ii] < (FIXP_PCM)MINVAL_FIXP_PCM - noiseVal) {
+ noiseVal = noiseVal * (FIXP_PCM)-1;
+ }
+
+ pcmdata[ii] += noiseVal;
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/conceal.h b/fdk-aac/libAACdec/src/conceal.h
new file mode 100644
index 0000000..e01a796
--- /dev/null
+++ b/fdk-aac/libAACdec/src/conceal.h
@@ -0,0 +1,152 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: independent channel concealment
+
+*******************************************************************************/
+
+#ifndef CONCEAL_H
+#define CONCEAL_H
+
+#include "channelinfo.h"
+
+#define AACDEC_CONCEAL_PARAM_NOT_SPECIFIED (0xFFFE)
+
+void CConcealment_InitCommonData(CConcealParams *pConcealCommonData);
+
+void CConcealment_InitChannelData(CConcealmentInfo *hConcealmentInfo,
+ CConcealParams *pConcealCommonData,
+ AACDEC_RENDER_MODE initRenderMode,
+ int samplesPerFrame);
+
+CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData);
+
+UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData);
+
+AAC_DECODER_ERROR
+CConcealment_SetParams(CConcealParams *concealParams, int method,
+ int fadeOutSlope, int fadeInSlope, int muteRelease,
+ FIXP_DBL comfNoiseLevel);
+
+CConcealmentState CConcealment_GetState(CConcealmentInfo *hConcealmentInfo);
+
+AAC_DECODER_ERROR
+CConcealment_SetAttenuation(CConcealParams *concealParams,
+ const SHORT *fadeOutAttenuationVector,
+ const SHORT *fadeInAttenuationVector);
+
+void CConcealment_Store(
+ CConcealmentInfo *hConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo);
+
+int CConcealment_Apply(
+ CConcealmentInfo *hConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const UCHAR lastLpdMode, const int FrameOk, const UINT flags);
+
+int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo,
+ const int fBeforeApply);
+
+INT CConcealment_TDFading(
+ int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
+ FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1);
+
+#endif /* #ifndef CONCEAL_H */
diff --git a/fdk-aac/libAACdec/src/conceal_types.h b/fdk-aac/libAACdec/src/conceal_types.h
new file mode 100644
index 0000000..d90374e
--- /dev/null
+++ b/fdk-aac/libAACdec/src/conceal_types.h
@@ -0,0 +1,203 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Christian Griebel
+
+ Description: Error concealment structs and types
+
+*******************************************************************************/
+
+#ifndef CONCEAL_TYPES_H
+#define CONCEAL_TYPES_H
+
+#include "machine_type.h"
+#include "common_fix.h"
+
+#include "rvlc_info.h"
+
+#include "usacdec_lpc.h"
+
+#define CONCEAL_MAX_NUM_FADE_FACTORS (32)
+
+#define FIXP_CNCL FIXP_DBL
+#define FL2FXCONST_CNCL FL2FXCONST_DBL
+#define FX_DBL2FX_CNCL
+#define FX_CNCL2FX_DBL
+#define CNCL_FRACT_BITS DFRACT_BITS
+
+/* Warning: Do not ever change these values. */
+typedef enum {
+ ConcealMethodNone = -1,
+ ConcealMethodMute = 0,
+ ConcealMethodNoise = 1,
+ ConcealMethodInter = 2,
+ ConcealMethodTonal = 3
+
+} CConcealmentMethod;
+
+typedef enum {
+ ConcealState_Ok,
+ ConcealState_Single,
+ ConcealState_FadeIn,
+ ConcealState_Mute,
+ ConcealState_FadeOut
+
+} CConcealmentState;
+
+typedef struct {
+ FIXP_SGL fadeOutFactor[CONCEAL_MAX_NUM_FADE_FACTORS];
+ FIXP_SGL fadeInFactor[CONCEAL_MAX_NUM_FADE_FACTORS];
+
+ CConcealmentMethod method;
+
+ int numFadeOutFrames;
+ int numFadeInFrames;
+ int numMuteReleaseFrames;
+ FIXP_DBL comfortNoiseLevel;
+
+} CConcealParams;
+
+typedef enum {
+ FADE_TIMEDOMAIN_TOSPECTRALMUTE = 1,
+ FADE_TIMEDOMAIN_FROMSPECTRALMUTE,
+ FADE_TIMEDOMAIN
+} TDfadingType;
+
+typedef struct {
+ CConcealParams *pConcealParams;
+
+ FIXP_CNCL spectralCoefficient[1024];
+ SHORT specScale[8];
+
+ INT iRandomPhase;
+ INT prevFrameOk[2];
+ INT cntValidFrames;
+ INT cntFadeFrames; /* State for signal fade-in/out */
+ /* States for signal fade-out of frames with more than one window/subframe -
+ [0] used by Update CntFadeFrames mode of CConcealment_ApplyFadeOut, [1] used
+ by FadeOut mode */
+ int winGrpOffset[2]; /* State for signal fade-out of frames with more than one
+ window/subframe */
+ int attGrpOffset[2]; /* State for faster signal fade-out of frames with
+ transient signal parts */
+
+ SCHAR lastRenderMode;
+
+ UCHAR windowShape;
+ BLOCK_TYPE windowSequence;
+ UCHAR lastWinGrpLen;
+
+ CConcealmentState concealState;
+ CConcealmentState concealState_old;
+ FIXP_DBL fade_old; /* last fading factor */
+ TDfadingType lastFadingType; /* last fading type */
+
+ SHORT aRvlcPreviousScaleFactor[RVLC_MAX_SFB]; /* needed once per channel */
+ UCHAR aRvlcPreviousCodebook[RVLC_MAX_SFB]; /* needed once per channel */
+ SCHAR rvlcPreviousScaleFactorOK;
+ SCHAR rvlcPreviousBlockType;
+
+ FIXP_LPC lsf4[M_LP_FILTER_ORDER];
+ FIXP_DBL last_tcx_gain;
+ INT last_tcx_gain_e;
+ ULONG TDNoiseSeed;
+ FIXP_PCM TDNoiseStates[3];
+ FIXP_SGL TDNoiseCoef[3];
+ FIXP_SGL TDNoiseAtt;
+
+} CConcealmentInfo;
+
+#endif /* #ifndef CONCEAL_TYPES_H */
diff --git a/fdk-aac/libAACdec/src/ldfiltbank.cpp b/fdk-aac/libAACdec/src/ldfiltbank.cpp
new file mode 100644
index 0000000..c7d2928
--- /dev/null
+++ b/fdk-aac/libAACdec/src/ldfiltbank.cpp
@@ -0,0 +1,276 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s):
+
+ Description: low delay filterbank
+
+*******************************************************************************/
+
+#include "ldfiltbank.h"
+
+#include "aac_rom.h"
+#include "dct.h"
+#include "FDK_tools_rom.h"
+#include "mdct.h"
+
+#define LDFB_HEADROOM 2
+
+#if defined(__arm__)
+#endif
+
+static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
+ FIXP_DBL *z, const int N) {
+ int i;
+
+ /* scale for FIXP_DBL -> INT_PCM conversion. */
+ const int scale = (DFRACT_BITS - SAMPLE_BITS) - LDFB_HEADROOM;
+#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
+ FIXP_DBL rnd_val_wts0 = (FIXP_DBL)0;
+ FIXP_DBL rnd_val_wts1 = (FIXP_DBL)0;
+ if (-WTS0 - 1 + scale)
+ rnd_val_wts0 = (FIXP_DBL)(1 << (-WTS0 - 1 + scale - 1));
+ if (-WTS1 - 1 + scale)
+ rnd_val_wts1 = (FIXP_DBL)(1 << (-WTS1 - 1 + scale - 1));
+#endif
+
+ for (i = 0; i < N / 4; i++) {
+ FIXP_DBL z0, z2, tmp;
+
+ z2 = x[N / 2 + i];
+ z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1));
+
+ z[N / 2 + i] = x[N / 2 - 1 - i] +
+ (fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
+
+ tmp = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
+ fMultDiv2(z[i], fb[N + N / 2 + i]));
+
+#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
+ FDK_ASSERT((-WTS1 - 1 + scale) >= 0);
+ FDK_ASSERT(tmp <= ((FIXP_DBL)0x7FFFFFFF -
+ rnd_val_wts1)); /* rounding must not cause overflow */
+ output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
+ tmp + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS);
+#else
+ FDK_ASSERT((WTS1 + 1 - scale) >= 0);
+ output[(N * 3 / 4 - 1 - i)] =
+ (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp, WTS1 + 1 - scale, PCM_OUT_BITS);
+#endif
+
+ z[i] = z0;
+ z[N + i] = z2;
+ }
+
+ for (i = N / 4; i < N / 2; i++) {
+ FIXP_DBL z0, z2, tmp0, tmp1;
+
+ z2 = x[N / 2 + i];
+ z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1));
+
+ z[N / 2 + i] = x[N / 2 - 1 - i] +
+ (fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
+
+ tmp0 = (fMultDiv2(z[N / 2 + i], fb[N / 2 - 1 - i]) +
+ fMultDiv2(z[i], fb[N / 2 + i]));
+ tmp1 = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
+ fMultDiv2(z[i], fb[N + N / 2 + i]));
+
+#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
+ FDK_ASSERT((-WTS0 - 1 + scale) >= 0);
+ FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
+ rnd_val_wts0)); /* rounding must not cause overflow */
+ FDK_ASSERT(tmp1 <= ((FIXP_DBL)0x7FFFFFFF -
+ rnd_val_wts1)); /* rounding must not cause overflow */
+ output[(i - N / 4)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
+ tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS);
+ output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
+ tmp1 + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS);
+#else
+ FDK_ASSERT((WTS0 + 1 - scale) >= 0);
+ output[(i - N / 4)] =
+ (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
+ output[(N * 3 / 4 - 1 - i)] =
+ (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp1, WTS1 + 1 - scale, PCM_OUT_BITS);
+#endif
+ z[i] = z0;
+ z[N + i] = z2;
+ }
+
+ /* Exchange quarter parts of x to bring them in the "right" order */
+ for (i = 0; i < N / 4; i++) {
+ FIXP_DBL tmp0 = fMultDiv2(z[i], fb[N / 2 + i]);
+
+#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
+ FDK_ASSERT((-WTS0 - 1 + scale) >= 0);
+ FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
+ rnd_val_wts0)); /* rounding must not cause overflow */
+ output[(N * 3 / 4 + i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
+ tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS);
+#else
+ FDK_ASSERT((WTS0 + 1 - scale) >= 0);
+ output[(N * 3 / 4 + i)] =
+ (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
+#endif
+ }
+}
+
+int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctData, const int mdctData_e,
+ FIXP_PCM *output, FIXP_DBL *fs_buffer,
+ const int N) {
+ const FIXP_WTB *coef;
+ FIXP_DBL gain = (FIXP_DBL)0;
+ int scale = mdctData_e + MDCT_OUT_HEADROOM -
+ LDFB_HEADROOM; /* The LDFB_HEADROOM is compensated inside
+ multE2_DinvF_fdk() below */
+ int i;
+
+ /* Select LD window slope */
+ switch (N) {
+ case 256:
+ coef = LowDelaySynthesis256;
+ break;
+ case 240:
+ coef = LowDelaySynthesis240;
+ break;
+ case 160:
+ coef = LowDelaySynthesis160;
+ break;
+ case 128:
+ coef = LowDelaySynthesis128;
+ break;
+ case 120:
+ coef = LowDelaySynthesis120;
+ break;
+ case 512:
+ coef = LowDelaySynthesis512;
+ break;
+ case 480:
+ default:
+ coef = LowDelaySynthesis480;
+ break;
+ }
+
+ /*
+ Apply exponent and 1/N factor.
+ Note: "scale" is off by one because for LD_MDCT the window length is twice
+ the window length of a regular MDCT. This is corrected inside
+ multE2_DinvF_fdk(). Refer to ISO/IEC 14496-3:2009 page 277,
+ chapter 4.6.20.2 "Low Delay Window".
+ */
+ imdct_gain(&gain, &scale, N);
+
+ dct_IV(mdctData, N, &scale);
+
+ if (N == 256 || N == 240 || N == 160) {
+ scale -= 1;
+ } else if (N == 128 || N == 120) {
+ scale -= 2;
+ }
+
+ if (gain != (FIXP_DBL)0) {
+ for (i = 0; i < N; i++) {
+ mdctData[i] = fMult(mdctData[i], gain);
+ }
+ }
+ scaleValuesSaturate(mdctData, N, scale);
+
+ /* Since all exponent and factors have been applied, current exponent is zero.
+ */
+ multE2_DinvF_fdk(output, mdctData, coef, fs_buffer, N);
+
+ return (1);
+}
diff --git a/fdk-aac/libAACdec/src/ldfiltbank.h b/fdk-aac/libAACdec/src/ldfiltbank.h
new file mode 100644
index 0000000..b63da6b
--- /dev/null
+++ b/fdk-aac/libAACdec/src/ldfiltbank.h
@@ -0,0 +1,112 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s):
+
+ Description: low delay filterbank interface
+
+*******************************************************************************/
+
+#ifndef LDFILTBANK_H
+#define LDFILTBANK_H
+
+#include "common_fix.h"
+
+int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctdata_m, const int mdctdata_e,
+ FIXP_PCM *mdctOut, FIXP_DBL *fs_buffer,
+ const int frameLength);
+
+#endif
diff --git a/fdk-aac/libAACdec/src/overlapadd.h b/fdk-aac/libAACdec/src/overlapadd.h
new file mode 100644
index 0000000..49eecd8
--- /dev/null
+++ b/fdk-aac/libAACdec/src/overlapadd.h
@@ -0,0 +1,120 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef OVERLAPADD_H
+#define OVERLAPADD_H
+
+#include "common_fix.h"
+
+/* ELD uses different overlap which is twice the frame size: */
+#define OverlapBufferSize (768)
+
+typedef FIXP_DBL SPECTRUM[1024];
+typedef FIXP_DBL* SPECTRAL_PTR;
+
+#define SPEC_LONG(ptr) (ptr)
+#define SPEC(ptr, w, gl) ((ptr) + ((w) * (gl)))
+
+#define SPEC_TCX(ptr, f, gl, fb) \
+ ((ptr) + ((f) * (gl * 2) * (((fb) == 0) ? 1 : 2)))
+
+#endif /* #ifndef OVERLAPADD_H */
diff --git a/fdk-aac/libAACdec/src/pulsedata.cpp b/fdk-aac/libAACdec/src/pulsedata.cpp
new file mode 100644
index 0000000..eb6d5bc
--- /dev/null
+++ b/fdk-aac/libAACdec/src/pulsedata.cpp
@@ -0,0 +1,164 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: pulse data tool
+
+*******************************************************************************/
+
+#include "pulsedata.h"
+
+#include "channelinfo.h"
+
+INT CPulseData_Read(HANDLE_FDK_BITSTREAM bs, CPulseData *const PulseData,
+ const SHORT *sfb_startlines, const void *pIcsInfo,
+ const SHORT frame_length) {
+ int i, k = 0;
+ const UINT MaxSfBands =
+ GetScaleFactorBandsTransmitted((const CIcsInfo *)pIcsInfo);
+
+ /* reset pulse data flag */
+ PulseData->PulseDataPresent = 0;
+
+ if ((PulseData->PulseDataPresent = (UCHAR)FDKreadBit(bs)) != 0) {
+ if (!IsLongBlock((const CIcsInfo *)pIcsInfo)) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ PulseData->NumberPulse = (UCHAR)FDKreadBits(bs, 2);
+ PulseData->PulseStartBand = (UCHAR)FDKreadBits(bs, 6);
+
+ if (PulseData->PulseStartBand >= MaxSfBands) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ k = sfb_startlines[PulseData->PulseStartBand];
+
+ for (i = 0; i <= PulseData->NumberPulse; i++) {
+ PulseData->PulseOffset[i] = (UCHAR)FDKreadBits(bs, 5);
+ PulseData->PulseAmp[i] = (UCHAR)FDKreadBits(bs, 4);
+ k += PulseData->PulseOffset[i];
+ }
+
+ if (k >= frame_length) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ }
+
+ return 0;
+}
+
+void CPulseData_Apply(
+ CPulseData *PulseData, /*!< pointer to pulse data side info */
+ const short
+ *pScaleFactorBandOffsets, /*!< pointer to scalefactor band offsets */
+ FIXP_DBL *coef) /*!< pointer to spectrum */
+{
+ int i, k;
+
+ if (PulseData->PulseDataPresent) {
+ k = pScaleFactorBandOffsets[PulseData->PulseStartBand];
+
+ for (i = 0; i <= PulseData->NumberPulse; i++) {
+ k += PulseData->PulseOffset[i];
+ if (coef[k] > (FIXP_DBL)0)
+ coef[k] += (FIXP_DBL)(int)PulseData->PulseAmp[i];
+ else
+ coef[k] -= (FIXP_DBL)(int)PulseData->PulseAmp[i];
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/pulsedata.h b/fdk-aac/libAACdec/src/pulsedata.h
new file mode 100644
index 0000000..15ae11c
--- /dev/null
+++ b/fdk-aac/libAACdec/src/pulsedata.h
@@ -0,0 +1,150 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: pulse data tool
+
+*******************************************************************************/
+
+#ifndef PULSEDATA_H
+#define PULSEDATA_H
+
+#include "common_fix.h"
+#include "FDK_bitstream.h"
+
+#define N_MAX_LINES 4
+
+typedef struct {
+ UCHAR PulseDataPresent;
+ UCHAR NumberPulse;
+ UCHAR PulseStartBand;
+ UCHAR PulseOffset[N_MAX_LINES];
+ UCHAR PulseAmp[N_MAX_LINES];
+} CPulseData;
+
+/**
+ * \brief Read pulse data from bitstream
+ *
+ * The function reads the elements for pulse data from
+ * the bitstream.
+ *
+ * \param bs bit stream handle data source.
+ * \param PulseData pointer to a CPulseData were the decoded data is stored
+ * into.
+ * \param MaxSfBands max number of scale factor bands.
+ * \return 0 on success, != 0 on parse error.
+ */
+INT CPulseData_Read(const HANDLE_FDK_BITSTREAM bs, CPulseData *const PulseData,
+ const SHORT *sfb_startlines, const void *pIcsInfo,
+ const SHORT frame_length);
+
+/**
+ * \brief Apply pulse data to spectral lines
+ *
+ * The function applies the pulse data to the
+ * specified spectral lines.
+ *
+ * \param PulseData pointer to the previously decoded pulse data.
+ * \param pScaleFactorBandOffsets scale factor band line offset table.
+ * \param coef pointer to the spectral data were pulse data should be applied
+ * to.
+ * \return none
+ */
+void CPulseData_Apply(CPulseData *PulseData,
+ const short *pScaleFactorBandOffsets, FIXP_DBL *coef);
+
+#endif /* #ifndef PULSEDATA_H */
diff --git a/fdk-aac/libAACdec/src/rvlc.cpp b/fdk-aac/libAACdec/src/rvlc.cpp
new file mode 100644
index 0000000..b7a9be1
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlc.cpp
@@ -0,0 +1,1217 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief RVLC Decoder
+ \author Robert Weidner
+*/
+
+#include "rvlc.h"
+
+#include "block.h"
+
+#include "aac_rom.h"
+#include "rvlcbit.h"
+#include "rvlcconceal.h"
+#include "aacdec_hcr.h"
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcInit
+
+ description: init RVLC by data from channelinfo, which was decoded
+previously and set up pointers
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+ - pointer bitstream structure
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcInit(CErRvlcInfo *pRvlc,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ /* RVLC common initialization part 2 of 2 */
+ SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
+ SHORT *pScfFwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd;
+ SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd;
+ SHORT *pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
+ int bnds;
+
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed = 0;
+
+ pRvlc->numDecodedEscapeWordsEsc = 0;
+ pRvlc->numDecodedEscapeWordsFwd = 0;
+ pRvlc->numDecodedEscapeWordsBwd = 0;
+
+ pRvlc->intensity_used = 0;
+ pRvlc->errorLogRvlc = 0;
+
+ pRvlc->conceal_max = CONCEAL_MAX_INIT;
+ pRvlc->conceal_min = CONCEAL_MIN_INIT;
+
+ pRvlc->conceal_max_esc = CONCEAL_MAX_INIT;
+ pRvlc->conceal_min_esc = CONCEAL_MIN_INIT;
+
+ pRvlc->pHuffTreeRvlcEscape = aHuffTreeRvlcEscape;
+ pRvlc->pHuffTreeRvlCodewds = aHuffTreeRvlCodewds;
+
+ /* init scf arrays (for savety (in case of there are only zero codebooks)) */
+ for (bnds = 0; bnds < RVLC_MAX_SFB; bnds++) {
+ pScfFwd[bnds] = 0;
+ pScfBwd[bnds] = 0;
+ pScfEsc[bnds] = 0;
+ pScaleFactor[bnds] = 0;
+ }
+
+ /* set base bitstream ptr to the RVL-coded part (start of RVLC data (ESC 2))
+ */
+ FDKsyncCache(bs);
+ pRvlc->bsAnchor = (INT)FDKgetValidBits(bs);
+
+ pRvlc->bitstreamIndexRvlFwd =
+ 0; /* first bit within RVL coded block as start address for forward
+ decoding */
+ pRvlc->bitstreamIndexRvlBwd =
+ pRvlc->length_of_rvlc_sf - 1; /* last bit within RVL coded block as start
+ address for backward decoding */
+
+ /* skip RVLC-bitstream-part -- pointing now to escapes (if present) or to TNS
+ * data (if present) */
+ FDKpushFor(bs, pRvlc->length_of_rvlc_sf);
+
+ if (pRvlc->sf_escapes_present != 0) {
+ /* locate internal bitstream ptr at escapes (which is the second part) */
+ FDKsyncCache(bs);
+ pRvlc->bitstreamIndexEsc = pRvlc->bsAnchor - (INT)FDKgetValidBits(bs);
+
+ /* skip escapeRVLC-bitstream-part -- pointing to TNS data (if present) to
+ * make decoder continue */
+ /* decoding of RVLC should work despite this second pushFor during
+ * initialization because */
+ /* bitstream initialization is valid for both ESC2 data parts (RVL-coded
+ * values and ESC-coded values) */
+ FDKpushFor(bs, pRvlc->length_of_rvlc_escapes);
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcCheckIntensityCb
+
+ description: Check if a intensity codebook is used in the current channel.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+-----------------------------------------------------------------------------------------------
+ output: - intensity_used: 0 no intensity codebook is used
+ 1 intensity codebook is used
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcCheckIntensityCb(
+ CErRvlcInfo *pRvlc, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ int group, band, bnds;
+
+ pRvlc->intensity_used = 0;
+
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ if ((pAacDecoderChannelInfo->pDynData->aCodeBook[bnds] ==
+ INTENSITY_HCB) ||
+ (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds] ==
+ INTENSITY_HCB2)) {
+ pRvlc->intensity_used = 1;
+ break;
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcDecodeEscapeWord
+
+ description: Decode a huffman coded RVLC Escape-word. This value is part
+of a DPCM coded scalefactor.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+-----------------------------------------------------------------------------------------------
+ return: - a single RVLC-Escape value which had to be applied to a
+DPCM value (which has a absolute value of 7)
+--------------------------------------------------------------------------------------------
+*/
+
+static SCHAR rvlcDecodeEscapeWord(CErRvlcInfo *pRvlc, HANDLE_FDK_BITSTREAM bs) {
+ int i;
+ SCHAR value;
+ UCHAR carryBit;
+ UINT treeNode;
+ UINT branchValue;
+ UINT branchNode;
+
+ INT *pBitstreamIndexEsc;
+ const UINT *pEscTree;
+
+ pEscTree = pRvlc->pHuffTreeRvlcEscape;
+ pBitstreamIndexEsc = &(pRvlc->bitstreamIndexEsc);
+ treeNode = *pEscTree; /* init at starting node */
+
+ for (i = MAX_LEN_RVLC_ESCAPE_WORD - 1; i >= 0; i--) {
+ carryBit =
+ rvlcReadBitFromBitstream(bs, /* get next bit */
+ pRvlc->bsAnchor, pBitstreamIndexEsc, FWD);
+
+ CarryBitToBranchValue(carryBit, /* huffman decoding, do a single step in
+ huffman decoding tree */
+ treeNode, &branchValue, &branchNode);
+
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; if set --> a RVLC-escape-word is
+ completely decoded */
+ value = (SCHAR)branchNode & CLR_BIT_10;
+ pRvlc->length_of_rvlc_escapes -= (MAX_LEN_RVLC_ESCAPE_WORD - i);
+
+ if (pRvlc->length_of_rvlc_escapes < 0) {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
+ value = -1;
+ }
+
+ return value;
+ } else {
+ treeNode = *(
+ pEscTree +
+ branchValue); /* update treeNode for further step in decoding tree */
+ }
+ }
+
+ pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
+
+ return -1; /* should not be reached */
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcDecodeEscapes
+
+ description: Decodes all huffman coded RVLC Escape Words.
+ Here a difference to the pseudo-code-implementation from
+standard can be found. A while loop (and not two nested for loops) is used for
+two reasons:
+
+ 1. The plain huffman encoded escapes are decoded before the
+RVL-coded scalefactors. Therefore the escapes are present in the second step
+ when decoding the RVL-coded-scalefactor values in forward
+and backward direction.
+
+ When the RVL-coded scalefactors are decoded and there a
+escape is needed, then it is just taken out of the array in ascending order.
+
+ 2. It's faster.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - handle to FDK bitstream
+-----------------------------------------------------------------------------------------------
+ return: - 0 ok the decoded escapes seem to be valid
+ - 1 error there was a error detected during decoding escapes
+ --> all escapes are invalid
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcDecodeEscapes(CErRvlcInfo *pRvlc, SHORT *pEsc,
+ HANDLE_FDK_BITSTREAM bs) {
+ SCHAR escWord;
+ SCHAR escCnt = 0;
+ SHORT *pEscBitCntSum;
+
+ pEscBitCntSum = &(pRvlc->length_of_rvlc_escapes);
+
+ /* Decode all RVLC-Escape words with a plain Huffman-Decoder */
+ while (*pEscBitCntSum > 0) {
+ escWord = rvlcDecodeEscapeWord(pRvlc, bs);
+
+ if (escWord >= 0) {
+ pEsc[escCnt] = escWord;
+ escCnt++;
+ } else {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
+ pRvlc->numDecodedEscapeWordsEsc = escCnt;
+
+ return;
+ }
+ } /* all RVLC escapes decoded */
+
+ pRvlc->numDecodedEscapeWordsEsc = escCnt;
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: decodeRVLCodeword
+
+ description: Decodes a RVL-coded dpcm-word (-part).
+-----------------------------------------------------------------------------------------------
+ input: - FDK bitstream handle
+ - pointer rvlc structure
+-----------------------------------------------------------------------------------------------
+ return: - a dpcm value which is within range [0,1,..,14] in case of
+no errors. The offset of 7 must be subtracted to get a valid dpcm scalefactor
+value. In case of errors a forbidden codeword is detected --> returning -1
+--------------------------------------------------------------------------------------------
+*/
+
+SCHAR decodeRVLCodeword(HANDLE_FDK_BITSTREAM bs, CErRvlcInfo *pRvlc) {
+ int i;
+ SCHAR value;
+ UCHAR carryBit;
+ UINT branchValue;
+ UINT branchNode;
+
+ const UINT *pRvlCodeTree = pRvlc->pHuffTreeRvlCodewds;
+ UCHAR direction = pRvlc->direction;
+ INT *pBitstrIndxRvl = pRvlc->pBitstrIndxRvl_RVL;
+ UINT treeNode = *pRvlCodeTree;
+
+ for (i = MAX_LEN_RVLC_CODE_WORD - 1; i >= 0; i--) {
+ carryBit =
+ rvlcReadBitFromBitstream(bs, /* get next bit */
+ pRvlc->bsAnchor, pBitstrIndxRvl, direction);
+
+ CarryBitToBranchValue(carryBit, /* huffman decoding, do a single step in
+ huffman decoding tree */
+ treeNode, &branchValue, &branchNode);
+
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; if set --> a
+ RVLC-codeword is completely decoded
+ */
+ value = (SCHAR)(branchNode & CLR_BIT_10);
+ *pRvlc->pRvlBitCnt_RVL -= (MAX_LEN_RVLC_CODE_WORD - i);
+
+ /* check available bits for decoding */
+ if (*pRvlc->pRvlBitCnt_RVL < 0) {
+ if (direction == FWD) {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_FWD;
+ } else {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_BWD;
+ }
+ value = -1; /* signalize an error in return value, because too many bits
+ was decoded */
+ }
+
+ /* check max value of dpcm value */
+ if (value > MAX_ALLOWED_DPCM_INDEX) {
+ if (direction == FWD) {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD;
+ } else {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD;
+ }
+ value = -1; /* signalize an error in return value, because a forbidden
+ cw was detected*/
+ }
+
+ return value; /* return a dpcm value with offset +7 or an error status */
+ } else {
+ treeNode = *(
+ pRvlCodeTree +
+ branchValue); /* update treeNode for further step in decoding tree */
+ }
+ }
+
+ return -1;
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcDecodeForward
+
+ description: Decode RVL-coded codewords in forward direction.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+ - handle to FDK bitstream
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcDecodeForward(CErRvlcInfo *pRvlc,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ int band = 0;
+ int group = 0;
+ int bnds = 0;
+
+ SHORT dpcm;
+
+ SHORT factor =
+ pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET;
+ SHORT position = -SF_OFFSET;
+ SHORT noisenrg = pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
+ SF_OFFSET - 90 - 256;
+
+ SHORT *pScfFwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd;
+ SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
+ UCHAR *pEscFwdCnt = &(pRvlc->numDecodedEscapeWordsFwd);
+
+ pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_fwd);
+ pRvlc->pBitstrIndxRvl_RVL = &(pRvlc->bitstreamIndexRvlFwd);
+
+ *pEscFwdCnt = 0;
+ pRvlc->direction = FWD;
+ pRvlc->noise_used = 0;
+ pRvlc->sf_used = 0;
+ pRvlc->lastScf = 0;
+ pRvlc->lastNrg = 0;
+ pRvlc->lastIs = 0;
+
+ rvlcCheckIntensityCb(pRvlc, pAacDecoderChannelInfo);
+
+ /* main loop fwd long */
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ pScfFwd[bnds] = 0;
+ break;
+
+ case INTENSITY_HCB2:
+ case INTENSITY_HCB:
+ /* store dpcm_is_position */
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pRvlc->conceal_max = bnds;
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pRvlc->conceal_max = bnds;
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc++;
+ } else {
+ dpcm += *pScfEsc++;
+ }
+ (*pEscFwdCnt)++;
+ if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
+ pRvlc->conceal_max_esc = bnds;
+ }
+ }
+ }
+ position += dpcm;
+ pScfFwd[bnds] = position;
+ pRvlc->lastIs = position;
+ break;
+
+ case NOISE_HCB:
+ if (pRvlc->noise_used == 0) {
+ pRvlc->noise_used = 1;
+ pRvlc->first_noise_band = bnds;
+ noisenrg += pRvlc->dpcm_noise_nrg;
+ pScfFwd[bnds] = 100 + noisenrg;
+ pRvlc->lastNrg = noisenrg;
+ } else {
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pRvlc->conceal_max = bnds;
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pRvlc->conceal_max = bnds;
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc++;
+ } else {
+ dpcm += *pScfEsc++;
+ }
+ (*pEscFwdCnt)++;
+ if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
+ pRvlc->conceal_max_esc = bnds;
+ }
+ }
+ }
+ noisenrg += dpcm;
+ pScfFwd[bnds] = 100 + noisenrg;
+ pRvlc->lastNrg = noisenrg;
+ }
+ pAacDecoderChannelInfo->data.aac.PnsData.pnsUsed[bnds] = 1;
+ break;
+
+ default:
+ pRvlc->sf_used = 1;
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pRvlc->conceal_max = bnds;
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pRvlc->conceal_max = bnds;
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc++;
+ } else {
+ dpcm += *pScfEsc++;
+ }
+ (*pEscFwdCnt)++;
+ if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
+ pRvlc->conceal_max_esc = bnds;
+ }
+ }
+ }
+ factor += dpcm;
+ pScfFwd[bnds] = factor;
+ pRvlc->lastScf = factor;
+ break;
+ }
+ }
+ }
+
+ /* postfetch fwd long */
+ if (pRvlc->intensity_used) {
+ dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */
+ if (dpcm < 0) {
+ pRvlc->conceal_max = bnds;
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pRvlc->conceal_max = bnds;
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc++;
+ } else {
+ dpcm += *pScfEsc++;
+ }
+ (*pEscFwdCnt)++;
+ if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
+ pRvlc->conceal_max_esc = bnds;
+ }
+ }
+ }
+ pRvlc->dpcm_is_last_position = dpcm;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcDecodeBackward
+
+ description: Decode RVL-coded codewords in backward direction.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+ - handle FDK bitstream
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ SHORT band, group, dpcm, offset;
+ SHORT bnds = pRvlc->maxSfbTransmitted - 1;
+
+ SHORT factor = pRvlc->rev_global_gain - SF_OFFSET;
+ SHORT position = pRvlc->dpcm_is_last_position - SF_OFFSET;
+ SHORT noisenrg = pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position -
+ SF_OFFSET - 90 - 256;
+
+ SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd;
+ SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
+ UCHAR *pEscEscCnt = &(pRvlc->numDecodedEscapeWordsEsc);
+ UCHAR *pEscBwdCnt = &(pRvlc->numDecodedEscapeWordsBwd);
+
+ pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_bwd);
+ pRvlc->pBitstrIndxRvl_RVL = &(pRvlc->bitstreamIndexRvlBwd);
+
+ *pEscBwdCnt = 0;
+ pRvlc->direction = BWD;
+ pScfEsc += *pEscEscCnt - 1; /* set pScfEsc to last entry */
+ pRvlc->firstScf = 0;
+ pRvlc->firstNrg = 0;
+ pRvlc->firstIs = 0;
+
+ /* prefetch long BWD */
+ if (pRvlc->intensity_used) {
+ dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */
+ if (dpcm < 0) {
+ pRvlc->dpcm_is_last_position = 0;
+ pRvlc->conceal_min = bnds;
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pRvlc->conceal_min = bnds;
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc--;
+ } else {
+ dpcm += *pScfEsc--;
+ }
+ (*pEscBwdCnt)++;
+ if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
+ pRvlc->conceal_min_esc = bnds;
+ }
+ }
+ }
+ pRvlc->dpcm_is_last_position = dpcm;
+ }
+
+ /* main loop long BWD */
+ for (group = pRvlc->numWindowGroups - 1; group >= 0; group--) {
+ for (band = pRvlc->maxSfbTransmitted - 1; band >= 0; band--) {
+ bnds = 16 * group + band;
+ if ((band == 0) && (pRvlc->numWindowGroups != 1))
+ offset = 16 - pRvlc->maxSfbTransmitted + 1;
+ else
+ offset = 1;
+
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ pScfBwd[bnds] = 0;
+ break;
+
+ case INTENSITY_HCB2:
+ case INTENSITY_HCB:
+ /* store dpcm_is_position */
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pScfBwd[bnds] = position;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pScfBwd[bnds] = position;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc--;
+ } else {
+ dpcm += *pScfEsc--;
+ }
+ (*pEscBwdCnt)++;
+ if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
+ pRvlc->conceal_min_esc = fMax(0, bnds - offset);
+ }
+ }
+ }
+ pScfBwd[bnds] = position;
+ position -= dpcm;
+ pRvlc->firstIs = position;
+ break;
+
+ case NOISE_HCB:
+ if (bnds == pRvlc->first_noise_band) {
+ pScfBwd[bnds] =
+ pRvlc->dpcm_noise_nrg +
+ pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
+ SF_OFFSET - 90 - 256;
+ pRvlc->firstNrg = pScfBwd[bnds];
+ } else {
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pScfBwd[bnds] = noisenrg;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pScfBwd[bnds] = noisenrg;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc--;
+ } else {
+ dpcm += *pScfEsc--;
+ }
+ (*pEscBwdCnt)++;
+ if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
+ pRvlc->conceal_min_esc = fMax(0, bnds - offset);
+ }
+ }
+ }
+ pScfBwd[bnds] = noisenrg;
+ noisenrg -= dpcm;
+ pRvlc->firstNrg = noisenrg;
+ }
+ break;
+
+ default:
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pScfBwd[bnds] = factor;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pScfBwd[bnds] = factor;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc--;
+ } else {
+ dpcm += *pScfEsc--;
+ }
+ (*pEscBwdCnt)++;
+ if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
+ pRvlc->conceal_min_esc = fMax(0, bnds - offset);
+ }
+ }
+ }
+ pScfBwd[bnds] = factor;
+ factor -= dpcm;
+ pRvlc->firstScf = factor;
+ break;
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcFinalErrorDetection
+
+ description: Call RVLC concealment if error was detected in decoding
+process
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcFinalErrorDetection(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ UCHAR ErrorStatusComplete = 0;
+ UCHAR ErrorStatusLengthFwd = 0;
+ UCHAR ErrorStatusLengthBwd = 0;
+ UCHAR ErrorStatusLengthEscapes = 0;
+ UCHAR ErrorStatusFirstScf = 0;
+ UCHAR ErrorStatusLastScf = 0;
+ UCHAR ErrorStatusFirstNrg = 0;
+ UCHAR ErrorStatusLastNrg = 0;
+ UCHAR ErrorStatusFirstIs = 0;
+ UCHAR ErrorStatusLastIs = 0;
+ UCHAR ErrorStatusForbiddenCwFwd = 0;
+ UCHAR ErrorStatusForbiddenCwBwd = 0;
+ UCHAR ErrorStatusNumEscapesFwd = 0;
+ UCHAR ErrorStatusNumEscapesBwd = 0;
+ UCHAR ConcealStatus = 1;
+ UCHAR currentBlockType; /* short: 0, not short: 1*/
+
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 1;
+
+ /* invalid escape words, bit counter unequal zero, forbidden codeword detected
+ */
+ if (pRvlc->errorLogRvlc & RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD)
+ ErrorStatusForbiddenCwFwd = 1;
+
+ if (pRvlc->errorLogRvlc & RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD)
+ ErrorStatusForbiddenCwBwd = 1;
+
+ /* bit counter forward unequal zero */
+ if (pRvlc->length_of_rvlc_sf_fwd) ErrorStatusLengthFwd = 1;
+
+ /* bit counter backward unequal zero */
+ if (pRvlc->length_of_rvlc_sf_bwd) ErrorStatusLengthBwd = 1;
+
+ /* bit counter escape sequences unequal zero */
+ if (pRvlc->sf_escapes_present)
+ if (pRvlc->length_of_rvlc_escapes) ErrorStatusLengthEscapes = 1;
+
+ if (pRvlc->sf_used) {
+ /* first decoded scf does not match to global gain in backward direction */
+ if (pRvlc->firstScf !=
+ (pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET))
+ ErrorStatusFirstScf = 1;
+
+ /* last decoded scf does not match to rev global gain in forward direction
+ */
+ if (pRvlc->lastScf != (pRvlc->rev_global_gain - SF_OFFSET))
+ ErrorStatusLastScf = 1;
+ }
+
+ if (pRvlc->noise_used) {
+ /* first decoded nrg does not match to dpcm_noise_nrg in backward direction
+ */
+ if (pRvlc->firstNrg !=
+ (pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain +
+ pRvlc->dpcm_noise_nrg - SF_OFFSET - 90 - 256))
+ ErrorStatusFirstNrg = 1;
+
+ /* last decoded nrg does not match to dpcm_noise_last_position in forward
+ * direction */
+ if (pRvlc->lastNrg !=
+ (pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position - SF_OFFSET -
+ 90 - 256))
+ ErrorStatusLastNrg = 1;
+ }
+
+ if (pRvlc->intensity_used) {
+ /* first decoded is position does not match in backward direction */
+ if (pRvlc->firstIs != (-SF_OFFSET)) ErrorStatusFirstIs = 1;
+
+ /* last decoded is position does not match in forward direction */
+ if (pRvlc->lastIs != (pRvlc->dpcm_is_last_position - SF_OFFSET))
+ ErrorStatusLastIs = 1;
+ }
+
+ /* decoded escapes and used escapes in forward direction do not fit */
+ if ((pRvlc->numDecodedEscapeWordsFwd != pRvlc->numDecodedEscapeWordsEsc) &&
+ (pRvlc->conceal_max == CONCEAL_MAX_INIT)) {
+ ErrorStatusNumEscapesFwd = 1;
+ }
+
+ /* decoded escapes and used escapes in backward direction do not fit */
+ if ((pRvlc->numDecodedEscapeWordsBwd != pRvlc->numDecodedEscapeWordsEsc) &&
+ (pRvlc->conceal_min == CONCEAL_MIN_INIT)) {
+ ErrorStatusNumEscapesBwd = 1;
+ }
+
+ if (ErrorStatusLengthEscapes ||
+ (((pRvlc->conceal_max == CONCEAL_MAX_INIT) &&
+ (pRvlc->numDecodedEscapeWordsFwd != pRvlc->numDecodedEscapeWordsEsc) &&
+ (ErrorStatusLastScf || ErrorStatusLastNrg || ErrorStatusLastIs))
+
+ &&
+
+ ((pRvlc->conceal_min == CONCEAL_MIN_INIT) &&
+ (pRvlc->numDecodedEscapeWordsBwd != pRvlc->numDecodedEscapeWordsEsc) &&
+ (ErrorStatusFirstScf || ErrorStatusFirstNrg || ErrorStatusFirstIs))) ||
+ ((pRvlc->conceal_max == CONCEAL_MAX_INIT) &&
+ ((pRvlc->rev_global_gain - SF_OFFSET - pRvlc->lastScf) < -15)) ||
+ ((pRvlc->conceal_min == CONCEAL_MIN_INIT) &&
+ ((pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET -
+ pRvlc->firstScf) < -15))) {
+ if ((pRvlc->conceal_max == CONCEAL_MAX_INIT) ||
+ (pRvlc->conceal_min == CONCEAL_MIN_INIT)) {
+ pRvlc->conceal_max = 0;
+ pRvlc->conceal_min = fMax(
+ 0, (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1);
+ } else {
+ pRvlc->conceal_max = fMin(pRvlc->conceal_max, pRvlc->conceal_max_esc);
+ pRvlc->conceal_min = fMax(pRvlc->conceal_min, pRvlc->conceal_min_esc);
+ }
+ }
+
+ ErrorStatusComplete = ErrorStatusLastScf || ErrorStatusFirstScf ||
+ ErrorStatusLastNrg || ErrorStatusFirstNrg ||
+ ErrorStatusLastIs || ErrorStatusFirstIs ||
+ ErrorStatusForbiddenCwFwd ||
+ ErrorStatusForbiddenCwBwd || ErrorStatusLengthFwd ||
+ ErrorStatusLengthBwd || ErrorStatusLengthEscapes ||
+ ErrorStatusNumEscapesFwd || ErrorStatusNumEscapesBwd;
+
+ currentBlockType =
+ (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) ? 0
+ : 1;
+
+ if (!ErrorStatusComplete) {
+ int band;
+ int group;
+ int bnds;
+ int lastSfbIndex;
+
+ lastSfbIndex = (pRvlc->numWindowGroups > 1) ? 16 : 64;
+
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ }
+ }
+
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] =
+ pAacDecoderChannelInfo->pDynData->aCodeBook[bnds];
+ }
+ for (; band < lastSfbIndex; band++) {
+ bnds = 16 * group + band;
+ FDK_ASSERT(bnds >= 0 && bnds < RVLC_MAX_SFB);
+ pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] = ZERO_HCB;
+ }
+ }
+ } else {
+ int band;
+ int group;
+
+ /* A single bit error was detected in decoding of dpcm values. It also could
+ be an error with more bits in decoding of escapes and dpcm values whereby
+ an illegal codeword followed not directly after the corrupted bits but
+ just after decoding some more (wrong) scalefactors. Use the smaller
+ scalefactor from forward decoding, backward decoding and previous frame.
+ */
+ if (((pRvlc->conceal_min != CONCEAL_MIN_INIT) ||
+ (pRvlc->conceal_max != CONCEAL_MAX_INIT)) &&
+ (pRvlc->conceal_min <= pRvlc->conceal_max) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo.rvlcPreviousBlockType ==
+ currentBlockType) &&
+ pAacDecoderStaticChannelInfo->concealmentInfo
+ .rvlcPreviousScaleFactorOK &&
+ pRvlc->sf_concealment && ConcealStatus) {
+ BidirectionalEstimation_UseScfOfPrevFrameAsReference(
+ pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo);
+ ConcealStatus = 0;
+ }
+
+ /* A single bit error was detected in decoding of dpcm values. It also could
+ be an error with more bits in decoding of escapes and dpcm values whereby
+ an illegal codeword followed not directly after the corrupted bits but
+ just after decoding some more (wrong) scalefactors. Use the smaller
+ scalefactor from forward and backward decoding. */
+ if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
+ ((pRvlc->conceal_min != CONCEAL_MIN_INIT) ||
+ (pRvlc->conceal_max != CONCEAL_MAX_INIT)) &&
+ !(pAacDecoderStaticChannelInfo->concealmentInfo
+ .rvlcPreviousScaleFactorOK &&
+ pRvlc->sf_concealment &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .rvlcPreviousBlockType == currentBlockType)) &&
+ ConcealStatus) {
+ BidirectionalEstimation_UseLowerScfOfCurrentFrame(pAacDecoderChannelInfo);
+ ConcealStatus = 0;
+ }
+
+ /* No errors were detected in decoding of escapes and dpcm values however
+ the first and last value of a group (is,nrg,sf) is incorrect */
+ if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
+ ((ErrorStatusLastScf && ErrorStatusFirstScf) ||
+ (ErrorStatusLastNrg && ErrorStatusFirstNrg) ||
+ (ErrorStatusLastIs && ErrorStatusFirstIs)) &&
+ !(ErrorStatusForbiddenCwFwd || ErrorStatusForbiddenCwBwd ||
+ ErrorStatusLengthEscapes) &&
+ ConcealStatus) {
+ StatisticalEstimation(pAacDecoderChannelInfo);
+ ConcealStatus = 0;
+ }
+
+ /* A error with more bits in decoding of escapes and dpcm values was
+ detected. Use the smaller scalefactor from forward decoding, backward
+ decoding and previous frame. */
+ if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
+ pAacDecoderStaticChannelInfo->concealmentInfo
+ .rvlcPreviousScaleFactorOK &&
+ pRvlc->sf_concealment &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo.rvlcPreviousBlockType ==
+ currentBlockType) &&
+ ConcealStatus) {
+ PredictiveInterpolation(pAacDecoderChannelInfo,
+ pAacDecoderStaticChannelInfo);
+ ConcealStatus = 0;
+ }
+
+ /* Call frame concealment, because no better strategy was found. Setting the
+ scalefactors to zero is done for debugging purposes */
+ if (ConcealStatus) {
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[16 * group + band] = 0;
+ }
+ }
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .rvlcCurrentScaleFactorOK = 0;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: CRvlc_Read
+
+ description: Read RVLC ESC1 data (side info) from bitstream.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+ - pointer bitstream structure
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+void CRvlc_Read(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+
+ int group, band;
+
+ /* RVLC long specific initialization Init part 1 of 2 */
+ pRvlc->numWindowGroups = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+ pRvlc->maxSfbTransmitted =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ pRvlc->noise_used = 0; /* noise detection */
+ pRvlc->dpcm_noise_nrg = 0; /* only for debugging */
+ pRvlc->dpcm_noise_last_position = 0; /* only for debugging */
+ pRvlc->length_of_rvlc_escapes =
+ -1; /* default value is used for error detection and concealment */
+
+ /* read only error sensitivity class 1 data (ESC 1 - data) */
+ pRvlc->sf_concealment = FDKreadBits(bs, 1); /* #1 */
+ pRvlc->rev_global_gain = FDKreadBits(bs, 8); /* #2 */
+
+ if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
+ pRvlc->length_of_rvlc_sf = FDKreadBits(bs, 11); /* #3 */
+ } else {
+ pRvlc->length_of_rvlc_sf = FDKreadBits(bs, 9); /* #3 */
+ }
+
+ /* check if noise codebook is used */
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ if (pAacDecoderChannelInfo->pDynData->aCodeBook[16 * group + band] ==
+ NOISE_HCB) {
+ pRvlc->noise_used = 1;
+ break;
+ }
+ }
+ }
+
+ if (pRvlc->noise_used)
+ pRvlc->dpcm_noise_nrg = FDKreadBits(bs, 9); /* #4 PNS */
+
+ pRvlc->sf_escapes_present = FDKreadBits(bs, 1); /* #5 */
+
+ if (pRvlc->sf_escapes_present) {
+ pRvlc->length_of_rvlc_escapes = FDKreadBits(bs, 8); /* #6 */
+ }
+
+ if (pRvlc->noise_used) {
+ pRvlc->dpcm_noise_last_position = FDKreadBits(bs, 9); /* #7 PNS */
+ pRvlc->length_of_rvlc_sf -= 9;
+ }
+
+ pRvlc->length_of_rvlc_sf_fwd = pRvlc->length_of_rvlc_sf;
+ pRvlc->length_of_rvlc_sf_bwd = pRvlc->length_of_rvlc_sf;
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: CRvlc_Decode
+
+ description: Decode rvlc data
+ The function reads both the escape sequences and the
+scalefactors in forward and backward direction. If an error occured during
+decoding process which can not be concealed with the rvlc concealment frame
+concealment will be initiated. Then the element "rvlcCurrentScaleFactorOK" in
+the decoder channel info is set to 0 otherwise it is set to 1.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+ - pointer to persistent channel info structure
+ - pointer bitstream structure
+-----------------------------------------------------------------------------------------------
+ return: ErrorStatus = AAC_DEC_OK
+--------------------------------------------------------------------------------------------
+*/
+
+void CRvlc_Decode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ INT bitCntOffst;
+ INT saveBitCnt;
+
+ rvlcInit(pRvlc, pAacDecoderChannelInfo, bs);
+
+ /* save bitstream position */
+ saveBitCnt = (INT)FDKgetValidBits(bs);
+
+ if (pRvlc->sf_escapes_present)
+ rvlcDecodeEscapes(
+ pRvlc, pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc, bs);
+
+ rvlcDecodeForward(pRvlc, pAacDecoderChannelInfo, bs);
+ rvlcDecodeBackward(pRvlc, pAacDecoderChannelInfo, bs);
+ rvlcFinalErrorDetection(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo);
+
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed =
+ pRvlc->intensity_used;
+ pAacDecoderChannelInfo->data.aac.PnsData.PnsActive = pRvlc->noise_used;
+
+ /* restore bitstream position */
+ bitCntOffst = (INT)FDKgetValidBits(bs) - saveBitCnt;
+ if (bitCntOffst) {
+ FDKpushBiDirectional(bs, bitCntOffst);
+ }
+}
+
+void CRvlc_ElementCheck(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ const UINT flags, const INT elChannels) {
+ int ch;
+
+ /* Required for MPS residuals. */
+ if (pAacDecoderStaticChannelInfo == NULL) {
+ return;
+ }
+
+ /* RVLC specific sanity checks */
+ if ((flags & AC_ER_RVLC) && (elChannels == 2)) { /* to be reviewed */
+ if (((pAacDecoderChannelInfo[0]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0) ||
+ (pAacDecoderChannelInfo[1]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0)) &&
+ pAacDecoderChannelInfo[0]->pComData->jointStereoData.MsMaskPresent) {
+ pAacDecoderChannelInfo[0]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
+ pAacDecoderChannelInfo[1]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
+ }
+
+ if ((pAacDecoderChannelInfo[0]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0) &&
+ (pAacDecoderChannelInfo[1]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 1) &&
+ (pAacDecoderChannelInfo[1]
+ ->pDynData->specificTo.aac.rvlcIntensityUsed == 1)) {
+ pAacDecoderChannelInfo[1]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
+ }
+ }
+
+ for (ch = 0; ch < elChannels; ch++) {
+ pAacDecoderStaticChannelInfo[ch]->concealmentInfo.rvlcPreviousBlockType =
+ (GetWindowSequence(&pAacDecoderChannelInfo[ch]->icsInfo) == BLOCK_SHORT)
+ ? 0
+ : 1;
+ if (flags & AC_ER_RVLC) {
+ pAacDecoderStaticChannelInfo[ch]
+ ->concealmentInfo.rvlcPreviousScaleFactorOK =
+ pAacDecoderChannelInfo[ch]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK;
+ } else {
+ pAacDecoderStaticChannelInfo[ch]
+ ->concealmentInfo.rvlcPreviousScaleFactorOK = 0;
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/rvlc.h b/fdk-aac/libAACdec/src/rvlc.h
new file mode 100644
index 0000000..9c60d51
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlc.h
@@ -0,0 +1,153 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Defines structures and prototypes for RVLC
+ \author Robert Weidner
+*/
+
+#ifndef RVLC_H
+#define RVLC_H
+
+#include "aacdecoder.h"
+#include "channel.h"
+#include "rvlc_info.h"
+
+/* ------------------------------------------------------------------- */
+/* errorLogRvlc: A word of 32 bits used for logging possible errors */
+/* within RVLC in case of distorted bitstreams. */
+/* ------------------------------------------------------------------- */
+#define RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID \
+ 0x80000000 /* ESC-Dec During RVLC-Escape-decoding there have been more \
+ bits decoded as there are available */
+#define RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_FWD \
+ 0x40000000 /* RVL-Dec negative sum-bitcounter during RVL-fwd-decoding \
+ (long+shrt) */
+#define RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_BWD \
+ 0x20000000 /* RVL-Dec negative sum-bitcounter during RVL-fwd-decoding \
+ (long+shrt) */
+#define RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD \
+ 0x08000000 /* RVL-Dec forbidden codeword detected fwd (long+shrt) */
+#define RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD \
+ 0x04000000 /* RVL-Dec forbidden codeword detected bwd (long+shrt) */
+
+void CRvlc_Read(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ HANDLE_FDK_BITSTREAM bs);
+
+void CRvlc_Decode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ HANDLE_FDK_BITSTREAM bs);
+
+/**
+ * \brief performe sanity checks to the channel data corresponding to one
+ * channel element.
+ * \param pAacDecoderChannelInfo
+ * \param pAacDecoderStaticChannelInfo
+ * \param elChannels amount of channels of the channel element.
+ */
+void CRvlc_ElementCheck(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ const UINT flags, const INT elChannels);
+
+#endif /* RVLC_H */
diff --git a/fdk-aac/libAACdec/src/rvlc_info.h b/fdk-aac/libAACdec/src/rvlc_info.h
new file mode 100644
index 0000000..e7b3b99
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlc_info.h
@@ -0,0 +1,204 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Defines structures for RVLC
+ \author Robert Weidner
+*/
+#ifndef RVLC_INFO_H
+#define RVLC_INFO_H
+
+#define FWD 0 /* bitstream decoding direction forward (RVL coded part) */
+#define BWD 1 /* bitstream decoding direction backward (RVL coded part) */
+
+#define MAX_RVL 7 /* positive RVLC escape */
+#define MIN_RVL -7 /* negative RVLC escape */
+#define MAX_ALLOWED_DPCM_INDEX \
+ 14 /* the maximum allowed index of a decoded dpcm value (offset \
+ 'TABLE_OFFSET' incl --> must be subtracted) */
+#define TABLE_OFFSET \
+ 7 /* dpcm offset of valid output values of rvl table decoding, the rvl table \
+ ouly returns positive values, therefore the offset */
+#define MAX_LEN_RVLC_CODE_WORD 9 /* max length of a RVL codeword in bits */
+#define MAX_LEN_RVLC_ESCAPE_WORD \
+ 20 /* max length of huffman coded RVLC escape word in bits */
+
+#define DPCM_NOISE_NRG_BITS 9
+#define SF_OFFSET 100 /* offset for correcting scf value */
+
+#define CONCEAL_MAX_INIT 1311 /* arbitrary value */
+#define CONCEAL_MIN_INIT -1311 /* arbitrary value */
+
+#define RVLC_MAX_SFB ((8) * (16))
+
+/* sideinfo of RVLC */
+typedef struct {
+ /* ------- ESC 1 Data: --------- */ /* order of RVLC-bitstream components in
+ bitstream (RVLC-initialization), every
+ component appears only once in
+ bitstream */
+ INT sf_concealment; /* 1 */
+ INT rev_global_gain; /* 2 */
+ SHORT length_of_rvlc_sf; /* 3 */ /* original value, gets modified
+ (subtract 9) in case of noise
+ (PNS); is kept for later use */
+ INT dpcm_noise_nrg; /* 4 optional */
+ INT sf_escapes_present; /* 5 */
+ SHORT length_of_rvlc_escapes; /* 6 optional */
+ INT dpcm_noise_last_position; /* 7 optional */
+
+ INT dpcm_is_last_position;
+
+ SHORT length_of_rvlc_sf_fwd; /* length_of_rvlc_sf used for forward decoding */
+ SHORT
+ length_of_rvlc_sf_bwd; /* length_of_rvlc_sf used for backward decoding */
+
+ /* for RVL-Codeword decoder to distinguish between fwd and bwd decoding */
+ SHORT *pRvlBitCnt_RVL;
+ INT *pBitstrIndxRvl_RVL;
+
+ UCHAR numWindowGroups;
+ UCHAR maxSfbTransmitted;
+ UCHAR first_noise_group;
+ UCHAR first_noise_band;
+ UCHAR direction;
+
+ /* bitstream indices */
+ INT bsAnchor; /* hcr bit buffer reference index */
+ INT bitstreamIndexRvlFwd; /* base address of RVL-coded-scalefactor data (ESC
+ 2) for forward decoding */
+ INT bitstreamIndexRvlBwd; /* base address of RVL-coded-scalefactor data (ESC
+ 2) for backward decoding */
+ INT bitstreamIndexEsc; /* base address where RVLC-escapes start (ESC 2) */
+
+ /* decoding trees */
+ const UINT *pHuffTreeRvlCodewds;
+ const UINT *pHuffTreeRvlcEscape;
+
+ /* escape counters */
+ UCHAR numDecodedEscapeWordsFwd; /* when decoding RVL-codes forward */
+ UCHAR numDecodedEscapeWordsBwd; /* when decoding RVL-codes backward */
+ UCHAR numDecodedEscapeWordsEsc; /* when decoding the escape-Words */
+
+ SCHAR noise_used;
+ SCHAR intensity_used;
+ SCHAR sf_used;
+
+ SHORT firstScf;
+ SHORT lastScf;
+ SHORT firstNrg;
+ SHORT lastNrg;
+ SHORT firstIs;
+ SHORT lastIs;
+
+ /* ------ RVLC error detection ------ */
+ UINT errorLogRvlc; /* store RVLC errors */
+ SHORT conceal_min; /* is set at backward decoding */
+ SHORT conceal_max; /* is set at forward decoding */
+ SHORT conceal_min_esc; /* is set at backward decoding */
+ SHORT conceal_max_esc; /* is set at forward decoding */
+} CErRvlcInfo;
+
+typedef CErRvlcInfo RVLC_INFO; /* temp */
+
+#endif /* RVLC_INFO_H */
diff --git a/fdk-aac/libAACdec/src/rvlcbit.cpp b/fdk-aac/libAACdec/src/rvlcbit.cpp
new file mode 100644
index 0000000..b0c4596
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlcbit.cpp
@@ -0,0 +1,148 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief RVLC bitstream reading
+ \author Robert Weidner
+*/
+
+#include "rvlcbit.h"
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcReadBitFromBitstream
+
+ description: This function returns a bit from the bitstream according to
+read direction. It is called very often, therefore it makes sense to inline it
+(runtime).
+-----------------------------------------------------------------------------------------------
+ input: - bitstream
+ - pPosition
+ - readDirection
+-----------------------------------------------------------------------------------------------
+ return: - bit from bitstream
+--------------------------------------------------------------------------------------------
+*/
+
+UCHAR rvlcReadBitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT *pPosition, UCHAR readDirection) {
+ UINT bit;
+ INT readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pPosition;
+
+ if (readBitOffset) {
+ FDKpushBiDirectional(bs, readBitOffset);
+ }
+
+ if (readDirection == FWD) {
+ bit = FDKreadBits(bs, 1);
+
+ *pPosition += 1;
+ } else {
+ /* to be replaced with a brother function of FDKreadBits() */
+ bit = FDKreadBits(bs, 1);
+ FDKpushBack(bs, 2);
+
+ *pPosition -= 1;
+ }
+
+ return (bit);
+}
diff --git a/fdk-aac/libAACdec/src/rvlcbit.h b/fdk-aac/libAACdec/src/rvlcbit.h
new file mode 100644
index 0000000..2578453
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlcbit.h
@@ -0,0 +1,111 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: RVLC Decoder: Bitstream reading
+
+*******************************************************************************/
+
+#ifndef RVLCBIT_H
+#define RVLCBIT_H
+
+#include "rvlc.h"
+
+UCHAR rvlcReadBitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT *pPosition, UCHAR readDirection);
+
+#endif /* RVLCBIT_H */
diff --git a/fdk-aac/libAACdec/src/rvlcconceal.cpp b/fdk-aac/libAACdec/src/rvlcconceal.cpp
new file mode 100644
index 0000000..77fda68
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlcconceal.cpp
@@ -0,0 +1,787 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief rvlc concealment
+ \author Josef Hoepfl
+*/
+
+#include "rvlcconceal.h"
+
+#include "block.h"
+#include "rvlc.h"
+
+/*---------------------------------------------------------------------------------------------
+ function: calcRefValFwd
+
+ description: The function determines the scalefactor which is closed to the
+scalefactorband conceal_min. The same is done for intensity data and noise
+energies.
+-----------------------------------------------------------------------------------------------
+ output: - reference value scf
+ - reference value internsity data
+ - reference value noise energy
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void calcRefValFwd(CErRvlcInfo *pRvlc,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ int *refIsFwd, int *refNrgFwd, int *refScfFwd) {
+ int band, bnds, group, startBand;
+ int idIs, idNrg, idScf;
+ int conceal_min, conceal_group_min;
+ int MaximumScaleFactorBands;
+
+ if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
+ MaximumScaleFactorBands = 16;
+ else
+ MaximumScaleFactorBands = 64;
+
+ conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
+ conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
+
+ /* calculate first reference value for approach in forward direction */
+ idIs = idNrg = idScf = 1;
+
+ /* set reference values */
+ *refIsFwd = -SF_OFFSET;
+ *refNrgFwd = pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
+ SF_OFFSET - 90 - 256;
+ *refScfFwd =
+ pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET;
+
+ startBand = conceal_min - 1;
+ for (group = conceal_group_min; group >= 0; group--) {
+ for (band = startBand; band >= 0; band--) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ break;
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if (idIs) {
+ *refIsFwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ idIs = 0; /* reference value has been set */
+ }
+ break;
+ case NOISE_HCB:
+ if (idNrg) {
+ *refNrgFwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ idNrg = 0; /* reference value has been set */
+ }
+ break;
+ default:
+ if (idScf) {
+ *refScfFwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ idScf = 0; /* reference value has been set */
+ }
+ break;
+ }
+ }
+ startBand = pRvlc->maxSfbTransmitted - 1;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: calcRefValBwd
+
+ description: The function determines the scalefactor which is closed to the
+scalefactorband conceal_max. The same is done for intensity data and noise
+energies.
+-----------------------------------------------------------------------------------------------
+ output: - reference value scf
+ - reference value internsity data
+ - reference value noise energy
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void calcRefValBwd(CErRvlcInfo *pRvlc,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ int *refIsBwd, int *refNrgBwd, int *refScfBwd) {
+ int band, bnds, group, startBand;
+ int idIs, idNrg, idScf;
+ int conceal_max, conceal_group_max;
+ int MaximumScaleFactorBands;
+
+ if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
+ MaximumScaleFactorBands = 16;
+ else
+ MaximumScaleFactorBands = 64;
+
+ conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
+ conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
+
+ /* calculate first reference value for approach in backward direction */
+ idIs = idNrg = idScf = 1;
+
+ /* set reference values */
+ *refIsBwd = pRvlc->dpcm_is_last_position - SF_OFFSET;
+ *refNrgBwd = pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position -
+ SF_OFFSET - 90 - 256 + pRvlc->dpcm_noise_nrg;
+ *refScfBwd = pRvlc->rev_global_gain - SF_OFFSET;
+
+ startBand = conceal_max + 1;
+
+ /* if needed, re-set reference values */
+ for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
+ for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ break;
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if (idIs) {
+ *refIsBwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ idIs = 0; /* reference value has been set */
+ }
+ break;
+ case NOISE_HCB:
+ if (idNrg) {
+ *refNrgBwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ idNrg = 0; /* reference value has been set */
+ }
+ break;
+ default:
+ if (idScf) {
+ *refScfBwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ idScf = 0; /* reference value has been set */
+ }
+ break;
+ }
+ }
+ startBand = 0;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: BidirectionalEstimation_UseLowerScfOfCurrentFrame
+
+ description: This approach by means of bidirectional estimation is generally
+performed when a single bit error has been detected, the bit error can be
+isolated between 'conceal_min' and 'conceal_max' and the 'sf_concealment' flag
+is not set. The sets of scalefactors decoded in forward and backward direction
+are compared with each other. The smaller scalefactor will be considered as the
+correct one respectively. The reconstruction of the scalefactors with this
+approach archieve good results in audio quality. The strategy must be applied to
+scalefactors, intensity data and noise energy seperately.
+-----------------------------------------------------------------------------------------------
+ output: Concealed scalefactor, noise energy and intensity data between
+conceal_min and conceal_max
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+void BidirectionalEstimation_UseLowerScfOfCurrentFrame(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ int band, bnds, startBand, endBand, group;
+ int conceal_min, conceal_max;
+ int conceal_group_min, conceal_group_max;
+ int MaximumScaleFactorBands;
+
+ if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
+ MaximumScaleFactorBands = 16;
+ } else {
+ MaximumScaleFactorBands = 64;
+ }
+
+ /* If an error was detected just in forward or backward direction, set the
+ corresponding border for concealment to a appropriate scalefactor band. The
+ border is set to first or last sfb respectively, because the error will
+ possibly not follow directly after the corrupt bit but just after decoding
+ some more (wrong) scalefactors. */
+ if (pRvlc->conceal_min == CONCEAL_MIN_INIT) pRvlc->conceal_min = 0;
+
+ if (pRvlc->conceal_max == CONCEAL_MAX_INIT)
+ pRvlc->conceal_max =
+ (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1;
+
+ conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
+ conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
+ conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
+ conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
+
+ if (pRvlc->conceal_min == pRvlc->conceal_max) {
+ int refIsFwd, refNrgFwd, refScfFwd;
+ int refIsBwd, refNrgBwd, refScfBwd;
+
+ bnds = pRvlc->conceal_min;
+ calcRefValFwd(pRvlc, pAacDecoderChannelInfo, &refIsFwd, &refNrgFwd,
+ &refScfFwd);
+ calcRefValBwd(pRvlc, pAacDecoderChannelInfo, &refIsBwd, &refNrgBwd,
+ &refScfBwd);
+
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ break;
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if (refIsFwd < refIsBwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsFwd;
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsBwd;
+ break;
+ case NOISE_HCB:
+ if (refNrgFwd < refNrgBwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refNrgFwd;
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refNrgBwd;
+ break;
+ default:
+ if (refScfFwd < refScfBwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refScfFwd;
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refScfBwd;
+ break;
+ }
+ } else {
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfFwd[pRvlc->conceal_max] =
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[pRvlc->conceal_max];
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[pRvlc->conceal_min] =
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfFwd[pRvlc->conceal_min];
+
+ /* consider the smaller of the forward and backward decoded value as the
+ * correct one */
+ startBand = conceal_min;
+ if (conceal_group_min == conceal_group_max)
+ endBand = conceal_max;
+ else
+ endBand = pRvlc->maxSfbTransmitted - 1;
+
+ for (group = conceal_group_min; group <= conceal_group_max; group++) {
+ for (band = startBand; band <= endBand; band++) {
+ bnds = 16 * group + band;
+ if (pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds] <
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds])
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ }
+ startBand = 0;
+ if ((group + 1) == conceal_group_max) endBand = conceal_max;
+ }
+ }
+
+ /* now copy all data to the output buffer which needs not to be concealed */
+ if (conceal_group_min == 0)
+ endBand = conceal_min;
+ else
+ endBand = pRvlc->maxSfbTransmitted;
+ for (group = 0; group <= conceal_group_min; group++) {
+ for (band = 0; band < endBand; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ }
+ if ((group + 1) == conceal_group_min) endBand = conceal_min;
+ }
+
+ startBand = conceal_max + 1;
+ for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
+ for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ }
+ startBand = 0;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: BidirectionalEstimation_UseScfOfPrevFrameAsReference
+
+ description: This approach by means of bidirectional estimation is generally
+performed when a single bit error has been detected, the bit error can be
+isolated between 'conceal_min' and 'conceal_max', the 'sf_concealment' flag is
+set and the previous frame has the same block type as the current frame. The
+scalefactor decoded in forward and backward direction and the scalefactor of the
+previous frame are compared with each other. The smaller scalefactor will be
+considered as the correct one. At this the codebook of the previous and current
+frame must be of the same set (scf, nrg, is) in each scalefactorband. Otherwise
+the scalefactor of the previous frame is not considered in the minimum
+calculation. The reconstruction of the scalefactors with this approach archieve
+good results in audio quality. The strategy must be applied to scalefactors,
+intensity data and noise energy seperately.
+-----------------------------------------------------------------------------------------------
+ output: Concealed scalefactor, noise energy and intensity data between
+conceal_min and conceal_max
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+void BidirectionalEstimation_UseScfOfPrevFrameAsReference(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ int band, bnds, startBand, endBand, group;
+ int conceal_min, conceal_max;
+ int conceal_group_min, conceal_group_max;
+ int MaximumScaleFactorBands;
+ SHORT commonMin;
+
+ if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
+ MaximumScaleFactorBands = 16;
+ } else {
+ MaximumScaleFactorBands = 64;
+ }
+
+ /* If an error was detected just in forward or backward direction, set the
+ corresponding border for concealment to a appropriate scalefactor band. The
+ border is set to first or last sfb respectively, because the error will
+ possibly not follow directly after the corrupt bit but just after decoding
+ some more (wrong) scalefactors. */
+ if (pRvlc->conceal_min == CONCEAL_MIN_INIT) pRvlc->conceal_min = 0;
+
+ if (pRvlc->conceal_max == CONCEAL_MAX_INIT)
+ pRvlc->conceal_max =
+ (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1;
+
+ conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
+ conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
+ conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
+ conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
+
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfFwd[pRvlc->conceal_max] =
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[pRvlc->conceal_max];
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[pRvlc->conceal_min] =
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfFwd[pRvlc->conceal_min];
+
+ /* consider the smaller of the forward and backward decoded value as the
+ * correct one */
+ startBand = conceal_min;
+ if (conceal_group_min == conceal_group_max)
+ endBand = conceal_max;
+ else
+ endBand = pRvlc->maxSfbTransmitted - 1;
+
+ for (group = conceal_group_min; group <= conceal_group_max; group++) {
+ for (band = startBand; band <= endBand; band++) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
+ break;
+
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if ((pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB) ||
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB2)) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ }
+ break;
+
+ case NOISE_HCB:
+ if (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == NOISE_HCB) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ }
+ break;
+
+ default:
+ if ((pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != ZERO_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != NOISE_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB2)) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ }
+ break;
+ }
+ }
+ startBand = 0;
+ if ((group + 1) == conceal_group_max) endBand = conceal_max;
+ }
+
+ /* now copy all data to the output buffer which needs not to be concealed */
+ if (conceal_group_min == 0)
+ endBand = conceal_min;
+ else
+ endBand = pRvlc->maxSfbTransmitted;
+ for (group = 0; group <= conceal_group_min; group++) {
+ for (band = 0; band < endBand; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ }
+ if ((group + 1) == conceal_group_min) endBand = conceal_min;
+ }
+
+ startBand = conceal_max + 1;
+ for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
+ for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ }
+ startBand = 0;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: StatisticalEstimation
+
+ description: This approach by means of statistical estimation is generally
+performed when both the start value and the end value are different and no
+further errors have been detected. Considering the forward and backward decoded
+scalefactors, the set with the lower scalefactors in sum will be considered as
+the correct one. The scalefactors are differentially encoded. Normally it would
+reach to compare one pair of the forward and backward decoded scalefactors to
+specify the lower set. But having detected no further errors does not
+necessarily mean the absence of errors. Therefore all scalefactors decoded in
+forward and backward direction are summed up seperately. The set with the lower
+sum will be used. The strategy must be applied to scalefactors, intensity data
+and noise energy seperately.
+-----------------------------------------------------------------------------------------------
+ output: Concealed scalefactor, noise energy and intensity data
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+void StatisticalEstimation(CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ int band, bnds, group;
+ int sumIsFwd, sumIsBwd; /* sum of intensity data forward/backward */
+ int sumNrgFwd, sumNrgBwd; /* sum of noise energy data forward/backward */
+ int sumScfFwd, sumScfBwd; /* sum of scalefactor data forward/backward */
+ int useIsFwd, useNrgFwd, useScfFwd; /* the flags signals the elements which
+ are used for the final result */
+
+ sumIsFwd = sumIsBwd = sumNrgFwd = sumNrgBwd = sumScfFwd = sumScfBwd = 0;
+ useIsFwd = useNrgFwd = useScfFwd = 0;
+
+ /* calculate sum of each group (scf,nrg,is) of forward and backward direction
+ */
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ break;
+
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ sumIsFwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ sumIsBwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+
+ case NOISE_HCB:
+ sumNrgFwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ sumNrgBwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+
+ default:
+ sumScfFwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ sumScfBwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+ }
+ }
+ }
+
+ /* find for each group (scf,nrg,is) the correct direction */
+ if (sumIsFwd < sumIsBwd) useIsFwd = 1;
+
+ if (sumNrgFwd < sumNrgBwd) useNrgFwd = 1;
+
+ if (sumScfFwd < sumScfBwd) useScfFwd = 1;
+
+ /* conceal each group (scf,nrg,is) */
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ break;
+
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if (useIsFwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+
+ case NOISE_HCB:
+ if (useNrgFwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+
+ default:
+ if (useScfFwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Approach by means of predictive interpolation
+ This approach by means of predictive estimation is generally
+performed when the error cannot be isolated between 'conceal_min' and
+'conceal_max', the 'sf_concealment' flag is set and the previous frame has the
+same block type as the current frame. Check for each scalefactorband if the same
+type of data (scalefactor, internsity data, noise energies) is transmitted. If
+so use the scalefactor (intensity data, noise energy) in the current frame.
+Otherwise set the scalefactor (intensity data, noise energy) for this
+scalefactorband to zero.
+-----------------------------------------------------------------------------------------------
+ output: Concealed scalefactor, noise energy and intensity data
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+void PredictiveInterpolation(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ int band, bnds, group;
+ SHORT commonMin;
+
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
+ break;
+
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if ((pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB) ||
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB2)) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = -110;
+ }
+ break;
+
+ case NOISE_HCB:
+ if (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == NOISE_HCB) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = -110;
+ }
+ break;
+
+ default:
+ if ((pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != ZERO_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != NOISE_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB2)) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/rvlcconceal.h b/fdk-aac/libAACdec/src/rvlcconceal.h
new file mode 100644
index 0000000..8e2062e
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlcconceal.h
@@ -0,0 +1,127 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief rvlc concealment
+ \author Josef Hoepfl
+*/
+
+#ifndef RVLCCONCEAL_H
+#define RVLCCONCEAL_H
+
+#include "rvlc.h"
+
+void BidirectionalEstimation_UseLowerScfOfCurrentFrame(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo);
+
+void BidirectionalEstimation_UseScfOfPrevFrameAsReference(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo);
+
+void StatisticalEstimation(CAacDecoderChannelInfo *pAacDecoderChannelInfo);
+
+void PredictiveInterpolation(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo);
+
+#endif /* RVLCCONCEAL_H */
diff --git a/fdk-aac/libAACdec/src/stereo.cpp b/fdk-aac/libAACdec/src/stereo.cpp
new file mode 100644
index 0000000..eed826b
--- /dev/null
+++ b/fdk-aac/libAACdec/src/stereo.cpp
@@ -0,0 +1,1250 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: joint stereo processing
+
+*******************************************************************************/
+
+#include "stereo.h"
+
+#include "aac_rom.h"
+#include "FDK_bitstream.h"
+#include "channelinfo.h"
+#include "FDK_audio.h"
+
+enum { L = 0, R = 1 };
+
+#include "block.h"
+
+int CJointStereo_Read(HANDLE_FDK_BITSTREAM bs,
+ CJointStereoData *pJointStereoData,
+ const int windowGroups,
+ const int scaleFactorBandsTransmitted,
+ const int max_sfb_ste_clear,
+ CJointStereoPersistentData *pJointStereoPersistentData,
+ CCplxPredictionData *cplxPredictionData,
+ int cplxPredictionActiv, int scaleFactorBandsTotal,
+ int windowSequence, const UINT flags) {
+ int group, band;
+
+ pJointStereoData->MsMaskPresent = (UCHAR)FDKreadBits(bs, 2);
+
+ FDKmemclear(pJointStereoData->MsUsed,
+ scaleFactorBandsTransmitted * sizeof(UCHAR));
+
+ pJointStereoData->cplx_pred_flag = 0;
+ if (cplxPredictionActiv) {
+ cplxPredictionData->pred_dir = 0;
+ cplxPredictionData->complex_coef = 0;
+ cplxPredictionData->use_prev_frame = 0;
+ cplxPredictionData->igf_pred_dir = 0;
+ }
+
+ switch (pJointStereoData->MsMaskPresent) {
+ case 0: /* no M/S */
+ /* all flags are already cleared */
+ break;
+
+ case 1: /* read ms_used */
+ for (group = 0; group < windowGroups; group++) {
+ for (band = 0; band < scaleFactorBandsTransmitted; band++) {
+ pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group);
+ }
+ }
+ break;
+
+ case 2: /* full spectrum M/S */
+ for (band = 0; band < scaleFactorBandsTransmitted; band++) {
+ pJointStereoData->MsUsed[band] = 255; /* set all flags to 1 */
+ }
+ break;
+
+ case 3:
+ /* M/S coding is disabled, complex stereo prediction is enabled */
+ if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
+ if (cplxPredictionActiv) { /* 'if (stereoConfigIndex == 0)' */
+
+ pJointStereoData->cplx_pred_flag = 1;
+
+ /* cplx_pred_data() cp. ISO/IEC FDIS 23003-3:2011(E) Table 26 */
+ int cplx_pred_all = 0; /* local use only */
+ cplx_pred_all = FDKreadBits(bs, 1);
+
+ if (cplx_pred_all) {
+ for (group = 0; group < windowGroups; group++) {
+ UCHAR groupmask = ((UCHAR)1 << group);
+ for (band = 0; band < scaleFactorBandsTransmitted; band++) {
+ pJointStereoData->MsUsed[band] |= groupmask;
+ }
+ }
+ } else {
+ for (group = 0; group < windowGroups; group++) {
+ for (band = 0; band < scaleFactorBandsTransmitted;
+ band += SFB_PER_PRED_BAND) {
+ pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group);
+ if ((band + 1) < scaleFactorBandsTotal) {
+ pJointStereoData->MsUsed[band + 1] |=
+ (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group));
+ }
+ }
+ }
+ }
+ } else {
+ return -1;
+ }
+ }
+ break;
+ }
+
+ if (cplxPredictionActiv) {
+ /* If all sfb are MS-ed then no complex prediction */
+ if (pJointStereoData->MsMaskPresent == 3) {
+ if (pJointStereoData->cplx_pred_flag) {
+ int delta_code_time = 0;
+
+ /* set pointer to Huffman codebooks */
+ const CodeBookDescription *hcb = &AACcodeBookDescriptionTable[BOOKSCL];
+ /* set predictors to zero in case of a transition from long to short
+ * window sequences and vice versa */
+ if (((windowSequence == BLOCK_SHORT) &&
+ (pJointStereoPersistentData->winSeqPrev != BLOCK_SHORT)) ||
+ ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) &&
+ (windowSequence != BLOCK_SHORT))) {
+ FDKmemclear(pJointStereoPersistentData->alpha_q_re_prev,
+ JointStereoMaximumGroups * JointStereoMaximumBands *
+ sizeof(SHORT));
+ FDKmemclear(pJointStereoPersistentData->alpha_q_im_prev,
+ JointStereoMaximumGroups * JointStereoMaximumBands *
+ sizeof(SHORT));
+ }
+ {
+ FDKmemclear(cplxPredictionData->alpha_q_re,
+ JointStereoMaximumGroups * JointStereoMaximumBands *
+ sizeof(SHORT));
+ FDKmemclear(cplxPredictionData->alpha_q_im,
+ JointStereoMaximumGroups * JointStereoMaximumBands *
+ sizeof(SHORT));
+ }
+
+ /* 0 = mid->side prediction, 1 = side->mid prediction */
+ cplxPredictionData->pred_dir = FDKreadBits(bs, 1);
+ cplxPredictionData->complex_coef = FDKreadBits(bs, 1);
+
+ if (cplxPredictionData->complex_coef) {
+ if (flags & AC_INDEP) {
+ cplxPredictionData->use_prev_frame = 0;
+ } else {
+ cplxPredictionData->use_prev_frame = FDKreadBits(bs, 1);
+ }
+ }
+
+ if (flags & AC_INDEP) {
+ delta_code_time = 0;
+ } else {
+ delta_code_time = FDKreadBits(bs, 1);
+ }
+
+ {
+ int last_alpha_q_re = 0, last_alpha_q_im = 0;
+
+ for (group = 0; group < windowGroups; group++) {
+ for (band = 0; band < scaleFactorBandsTransmitted;
+ band += SFB_PER_PRED_BAND) {
+ if (delta_code_time == 1) {
+ if (group > 0) {
+ last_alpha_q_re =
+ cplxPredictionData->alpha_q_re[group - 1][band];
+ last_alpha_q_im =
+ cplxPredictionData->alpha_q_im[group - 1][band];
+ } else if ((windowSequence == BLOCK_SHORT) &&
+ (pJointStereoPersistentData->winSeqPrev ==
+ BLOCK_SHORT)) {
+ /* Included for error-robustness */
+ if (pJointStereoPersistentData->winGroupsPrev == 0) return -1;
+
+ last_alpha_q_re =
+ pJointStereoPersistentData->alpha_q_re_prev
+ [pJointStereoPersistentData->winGroupsPrev - 1][band];
+ last_alpha_q_im =
+ pJointStereoPersistentData->alpha_q_im_prev
+ [pJointStereoPersistentData->winGroupsPrev - 1][band];
+ } else {
+ last_alpha_q_re =
+ pJointStereoPersistentData->alpha_q_re_prev[group][band];
+ last_alpha_q_im =
+ pJointStereoPersistentData->alpha_q_im_prev[group][band];
+ }
+
+ } else {
+ if (band > 0) {
+ last_alpha_q_re =
+ cplxPredictionData->alpha_q_re[group][band - 1];
+ last_alpha_q_im =
+ cplxPredictionData->alpha_q_im[group][band - 1];
+ } else {
+ last_alpha_q_re = 0;
+ last_alpha_q_im = 0;
+ }
+
+ } /* if (delta_code_time == 1) */
+
+ if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) {
+ int dpcm_alpha_re, dpcm_alpha_im;
+
+ dpcm_alpha_re = CBlock_DecodeHuffmanWord(bs, hcb);
+ dpcm_alpha_re -= 60;
+ dpcm_alpha_re *= -1;
+
+ cplxPredictionData->alpha_q_re[group][band] =
+ dpcm_alpha_re + last_alpha_q_re;
+
+ if (cplxPredictionData->complex_coef) {
+ dpcm_alpha_im = CBlock_DecodeHuffmanWord(bs, hcb);
+ dpcm_alpha_im -= 60;
+ dpcm_alpha_im *= -1;
+
+ cplxPredictionData->alpha_q_im[group][band] =
+ dpcm_alpha_im + last_alpha_q_im;
+ } else {
+ cplxPredictionData->alpha_q_im[group][band] = 0;
+ }
+
+ } else {
+ cplxPredictionData->alpha_q_re[group][band] = 0;
+ cplxPredictionData->alpha_q_im[group][band] = 0;
+ } /* if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) */
+
+ if ((band + 1) <
+ scaleFactorBandsTransmitted) { /* <= this should be the
+ correct way (cp.
+ ISO_IEC_FDIS_23003-0(E) */
+ /* 7.7.2.3.2 Decoding of prediction coefficients) */
+ cplxPredictionData->alpha_q_re[group][band + 1] =
+ cplxPredictionData->alpha_q_re[group][band];
+ cplxPredictionData->alpha_q_im[group][band + 1] =
+ cplxPredictionData->alpha_q_im[group][band];
+ } /* if ((band+1)<scaleFactorBandsTotal) */
+
+ pJointStereoPersistentData->alpha_q_re_prev[group][band] =
+ cplxPredictionData->alpha_q_re[group][band];
+ pJointStereoPersistentData->alpha_q_im_prev[group][band] =
+ cplxPredictionData->alpha_q_im[group][band];
+ }
+
+ for (band = scaleFactorBandsTransmitted; band < max_sfb_ste_clear;
+ band++) {
+ cplxPredictionData->alpha_q_re[group][band] = 0;
+ cplxPredictionData->alpha_q_im[group][band] = 0;
+ pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0;
+ pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0;
+ }
+ }
+ }
+ }
+ } else {
+ for (group = 0; group < windowGroups; group++) {
+ for (band = 0; band < max_sfb_ste_clear; band++) {
+ pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0;
+ pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0;
+ }
+ }
+ }
+
+ pJointStereoPersistentData->winGroupsPrev = windowGroups;
+ }
+
+ return 0;
+}
+
+static void CJointStereo_filterAndAdd(
+ FIXP_DBL *in, int len, int windowLen, const FIXP_FILT *coeff, FIXP_DBL *out,
+ UCHAR isCurrent /* output values with even index get a
+ positve addon (=1) or a negative addon
+ (=0) */
+) {
+ int i, j;
+
+ int indices_1[] = {2, 1, 0, 1, 2, 3};
+ int indices_2[] = {1, 0, 0, 2, 3, 4};
+ int indices_3[] = {0, 0, 1, 3, 4, 5};
+
+ int subtr_1[] = {6, 5, 4, 2, 1, 1};
+ int subtr_2[] = {5, 4, 3, 1, 1, 2};
+ int subtr_3[] = {4, 3, 2, 1, 2, 3};
+
+ if (isCurrent == 1) {
+ /* exploit the symmetry of the table: coeff[6] = - coeff[0],
+ coeff[5] = - coeff[1],
+ coeff[4] = - coeff[2],
+ coeff[3] = 0
+ */
+
+ for (i = 0; i < 3; i++) {
+ out[0] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[i]]) >> SR_FNA_OUT;
+ out[0] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[1] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[i]]) >> SR_FNA_OUT;
+ out[1] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[2] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[i]]) >> SR_FNA_OUT;
+ out[2] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ for (j = 3; j < (len - 3); j++) {
+ for (i = 0; i < 3; i++) {
+ out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i]) >> SR_FNA_OUT;
+ out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i]) >> SR_FNA_OUT;
+ }
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[len - 3] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[i]]) >> SR_FNA_OUT;
+ out[len - 3] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[len - 2] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[i]]) >> SR_FNA_OUT;
+ out[len - 2] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[len - 1] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[i]]) >> SR_FNA_OUT;
+ out[len - 1] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ } else {
+ /* exploit the symmetry of the table: coeff[6] = coeff[0],
+ coeff[5] = coeff[1],
+ coeff[4] = coeff[2]
+ */
+
+ for (i = 0; i < 3; i++) {
+ out[0] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[i]] >> SR_FNA_OUT);
+ out[0] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[5 - i]] >> SR_FNA_OUT);
+ }
+ out[0] -= (FIXP_DBL)fMultDiv2(coeff[3], in[0] >> SR_FNA_OUT);
+
+ for (i = 0; i < 3; i++) {
+ out[1] += (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[i]] >> SR_FNA_OUT);
+ out[1] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[5 - i]] >> SR_FNA_OUT);
+ }
+ out[1] += (FIXP_DBL)fMultDiv2(coeff[3], in[1] >> SR_FNA_OUT);
+
+ for (i = 0; i < 3; i++) {
+ out[2] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[i]] >> SR_FNA_OUT);
+ out[2] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[5 - i]] >> SR_FNA_OUT);
+ }
+ out[2] -= (FIXP_DBL)fMultDiv2(coeff[3], in[2] >> SR_FNA_OUT);
+
+ for (j = 3; j < (len - 4); j++) {
+ for (i = 0; i < 3; i++) {
+ out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i] >> SR_FNA_OUT);
+ out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i] >> SR_FNA_OUT);
+ }
+ out[j] += (FIXP_DBL)fMultDiv2(coeff[3], in[j] >> SR_FNA_OUT);
+
+ j++;
+
+ for (i = 0; i < 3; i++) {
+ out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i] >> SR_FNA_OUT);
+ out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i] >> SR_FNA_OUT);
+ }
+ out[j] -= (FIXP_DBL)fMultDiv2(coeff[3], in[j] >> SR_FNA_OUT);
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[len - 3] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[i]] >> SR_FNA_OUT);
+ out[len - 3] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[5 - i]] >> SR_FNA_OUT);
+ }
+ out[len - 3] += (FIXP_DBL)fMultDiv2(coeff[3], in[len - 3] >> SR_FNA_OUT);
+
+ for (i = 0; i < 3; i++) {
+ out[len - 2] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[i]] >> SR_FNA_OUT);
+ out[len - 2] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[5 - i]] >> SR_FNA_OUT);
+ }
+ out[len - 2] -= (FIXP_DBL)fMultDiv2(coeff[3], in[len - 2] >> SR_FNA_OUT);
+
+ for (i = 0; i < 3; i++) {
+ out[len - 1] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[i]] >> SR_FNA_OUT);
+ out[len - 1] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[5 - i]] >> SR_FNA_OUT);
+ }
+ out[len - 1] += (FIXP_DBL)fMultDiv2(coeff[3], in[len - 1] >> SR_FNA_OUT);
+ }
+}
+
+static inline void CJointStereo_GenerateMSOutput(FIXP_DBL *pSpecLCurrBand,
+ FIXP_DBL *pSpecRCurrBand,
+ UINT leftScale,
+ UINT rightScale,
+ UINT nSfbBands) {
+ unsigned int i;
+
+ FIXP_DBL leftCoefficient0;
+ FIXP_DBL leftCoefficient1;
+ FIXP_DBL leftCoefficient2;
+ FIXP_DBL leftCoefficient3;
+
+ FIXP_DBL rightCoefficient0;
+ FIXP_DBL rightCoefficient1;
+ FIXP_DBL rightCoefficient2;
+ FIXP_DBL rightCoefficient3;
+
+ for (i = nSfbBands; i > 0; i -= 4) {
+ leftCoefficient0 = pSpecLCurrBand[i - 4];
+ leftCoefficient1 = pSpecLCurrBand[i - 3];
+ leftCoefficient2 = pSpecLCurrBand[i - 2];
+ leftCoefficient3 = pSpecLCurrBand[i - 1];
+
+ rightCoefficient0 = pSpecRCurrBand[i - 4];
+ rightCoefficient1 = pSpecRCurrBand[i - 3];
+ rightCoefficient2 = pSpecRCurrBand[i - 2];
+ rightCoefficient3 = pSpecRCurrBand[i - 1];
+
+ /* MS output generation */
+ leftCoefficient0 >>= leftScale;
+ leftCoefficient1 >>= leftScale;
+ leftCoefficient2 >>= leftScale;
+ leftCoefficient3 >>= leftScale;
+
+ rightCoefficient0 >>= rightScale;
+ rightCoefficient1 >>= rightScale;
+ rightCoefficient2 >>= rightScale;
+ rightCoefficient3 >>= rightScale;
+
+ pSpecLCurrBand[i - 4] = leftCoefficient0 + rightCoefficient0;
+ pSpecLCurrBand[i - 3] = leftCoefficient1 + rightCoefficient1;
+ pSpecLCurrBand[i - 2] = leftCoefficient2 + rightCoefficient2;
+ pSpecLCurrBand[i - 1] = leftCoefficient3 + rightCoefficient3;
+
+ pSpecRCurrBand[i - 4] = leftCoefficient0 - rightCoefficient0;
+ pSpecRCurrBand[i - 3] = leftCoefficient1 - rightCoefficient1;
+ pSpecRCurrBand[i - 2] = leftCoefficient2 - rightCoefficient2;
+ pSpecRCurrBand[i - 1] = leftCoefficient3 - rightCoefficient3;
+ }
+}
+
+void CJointStereo_ApplyMS(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
+ FIXP_DBL *spectrumL, FIXP_DBL *spectrumR, SHORT *SFBleftScale,
+ SHORT *SFBrightScale, SHORT *specScaleL, SHORT *specScaleR,
+ const SHORT *pScaleFactorBandOffsets, const UCHAR *pWindowGroupLength,
+ const int windowGroups, const int max_sfb_ste_outside,
+ const int scaleFactorBandsTransmittedL,
+ const int scaleFactorBandsTransmittedR, FIXP_DBL *store_dmx_re_prev,
+ SHORT *store_dmx_re_prev_e, const int mainband_flag) {
+ int window, group, band;
+ UCHAR groupMask;
+ CJointStereoData *pJointStereoData =
+ &pAacDecoderChannelInfo[L]->pComData->jointStereoData;
+ CCplxPredictionData *cplxPredictionData =
+ pAacDecoderChannelInfo[L]->pComStaticData->cplxPredictionData;
+
+ int max_sfb_ste =
+ fMax(scaleFactorBandsTransmittedL, scaleFactorBandsTransmittedR);
+ int min_sfb_ste =
+ fMin(scaleFactorBandsTransmittedL, scaleFactorBandsTransmittedR);
+ int scaleFactorBandsTransmitted = min_sfb_ste;
+
+ if (pJointStereoData->cplx_pred_flag) {
+ int windowLen, groupwin, frameMaxScale;
+ CJointStereoPersistentData *pJointStereoPersistentData =
+ &pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData;
+ FIXP_DBL *const staticSpectralCoeffsL =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.spectralCoeffs[L];
+ FIXP_DBL *const staticSpectralCoeffsR =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.spectralCoeffs[R];
+ SHORT *const staticSpecScaleL =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.specScale[L];
+ SHORT *const staticSpecScaleR =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.specScale[R];
+
+ FIXP_DBL *dmx_re =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.scratchBuffer;
+ FIXP_DBL *dmx_re_prev =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.scratchBuffer +
+ 1024;
+
+ /* When MS is applied over the main band this value gets computed. Otherwise
+ * (for the tiles) it uses the assigned value */
+ SHORT dmx_re_prev_e = *store_dmx_re_prev_e;
+
+ const FIXP_FILT *pCoeff;
+ const FIXP_FILT *pCoeffPrev;
+ int coeffPointerOffset;
+
+ int previousShape = (int)pJointStereoPersistentData->winShapePrev;
+ int currentShape = (int)pAacDecoderChannelInfo[L]->icsInfo.WindowShape;
+
+ /* complex stereo prediction */
+
+ /* 0. preparations */
+
+ /* 0.0. get scratch buffer for downmix MDST */
+ C_AALLOC_SCRATCH_START(dmx_im, FIXP_DBL, 1024);
+
+ /* 0.1. window lengths */
+
+ /* get length of short window for current configuration */
+ windowLen =
+ pAacDecoderChannelInfo[L]->granuleLength; /* framelength 768 => 96,
+ framelength 1024 => 128 */
+
+ /* if this is no short-block set length for long-block */
+ if (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence != BLOCK_SHORT) {
+ windowLen *= 8;
+ }
+
+ /* 0.2. set pointer to filter-coefficients for MDST excitation including
+ * previous frame portions */
+ /* cp. ISO/IEC FDIS 23003-3:2011(E) table 125 */
+
+ /* set pointer to default-position */
+ pCoeffPrev = mdst_filt_coef_prev[previousShape];
+
+ if (cplxPredictionData->complex_coef == 1) {
+ switch (pAacDecoderChannelInfo[L]
+ ->icsInfo.WindowSequence) { /* current window sequence */
+ case BLOCK_SHORT:
+ case BLOCK_LONG:
+ pCoeffPrev = mdst_filt_coef_prev[previousShape];
+ break;
+
+ case BLOCK_START:
+ if ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) ||
+ (pJointStereoPersistentData->winSeqPrev == BLOCK_START)) {
+ /* a stop-start-sequence can only follow on an eight-short-sequence
+ * or a start-sequence */
+ pCoeffPrev = mdst_filt_coef_prev[2 + previousShape];
+ } else {
+ pCoeffPrev = mdst_filt_coef_prev[previousShape];
+ }
+ break;
+
+ case BLOCK_STOP:
+ pCoeffPrev = mdst_filt_coef_prev[2 + previousShape];
+ break;
+
+ default:
+ pCoeffPrev = mdst_filt_coef_prev[previousShape];
+ break;
+ }
+ }
+
+ /* 0.3. set pointer to filter-coefficients for MDST excitation */
+
+ /* define offset of pointer to filter-coefficients for MDST exitation
+ * employing only the current frame */
+ if ((previousShape == SHAPE_SINE) && (currentShape == SHAPE_SINE)) {
+ coeffPointerOffset = 0;
+ } else if ((previousShape == SHAPE_SINE) && (currentShape == SHAPE_KBD)) {
+ coeffPointerOffset = 2;
+ } else if ((previousShape == SHAPE_KBD) && (currentShape == SHAPE_KBD)) {
+ coeffPointerOffset = 1;
+ } else /* if ( (previousShape == SHAPE_KBD) && (currentShape == SHAPE_SINE)
+ ) */
+ {
+ coeffPointerOffset = 3;
+ }
+
+ /* set pointer to filter-coefficient table cp. ISO/IEC FDIS 23003-3:2011(E)
+ * table 124 */
+ switch (pAacDecoderChannelInfo[L]
+ ->icsInfo.WindowSequence) { /* current window sequence */
+ case BLOCK_SHORT:
+ case BLOCK_LONG:
+ pCoeff = mdst_filt_coef_curr[coeffPointerOffset];
+ break;
+
+ case BLOCK_START:
+ if ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) ||
+ (pJointStereoPersistentData->winSeqPrev == BLOCK_START)) {
+ /* a stop-start-sequence can only follow on an eight-short-sequence or
+ * a start-sequence */
+ pCoeff = mdst_filt_coef_curr[12 + coeffPointerOffset];
+ } else {
+ pCoeff = mdst_filt_coef_curr[4 + coeffPointerOffset];
+ }
+ break;
+
+ case BLOCK_STOP:
+ pCoeff = mdst_filt_coef_curr[8 + coeffPointerOffset];
+ break;
+
+ default:
+ pCoeff = mdst_filt_coef_curr[coeffPointerOffset];
+ }
+
+ /* 0.4. find maximum common (l/r) band-scaling-factor for whole sequence
+ * (all windows) */
+ frameMaxScale = 0;
+ for (window = 0, group = 0; group < windowGroups; group++) {
+ for (groupwin = 0; groupwin < pWindowGroupLength[group];
+ groupwin++, window++) {
+ SHORT *leftScale = &SFBleftScale[window * 16];
+ SHORT *rightScale = &SFBrightScale[window * 16];
+ int windowMaxScale = 0;
+
+ /* find maximum scaling factor of all bands in this window */
+ for (band = 0; band < min_sfb_ste; band++) {
+ int lScale = leftScale[band];
+ int rScale = rightScale[band];
+ int commonScale = ((lScale > rScale) ? lScale : rScale);
+ windowMaxScale =
+ (windowMaxScale < commonScale) ? commonScale : windowMaxScale;
+ }
+ if (scaleFactorBandsTransmittedL >
+ min_sfb_ste) { /* i.e. scaleFactorBandsTransmittedL == max_sfb_ste
+ */
+ for (; band < max_sfb_ste; band++) {
+ int lScale = leftScale[band];
+ windowMaxScale =
+ (windowMaxScale < lScale) ? lScale : windowMaxScale;
+ }
+ } else {
+ if (scaleFactorBandsTransmittedR >
+ min_sfb_ste) { /* i.e. scaleFactorBandsTransmittedR == max_sfb_ste
+ */
+ for (; band < max_sfb_ste; band++) {
+ int rScale = rightScale[band];
+ windowMaxScale =
+ (windowMaxScale < rScale) ? rScale : windowMaxScale;
+ }
+ }
+ }
+
+ /* find maximum common SF of all windows */
+ frameMaxScale =
+ (frameMaxScale < windowMaxScale) ? windowMaxScale : frameMaxScale;
+ }
+ }
+
+ /* add some headroom for overflow protection during filter and add operation
+ */
+ frameMaxScale += 2;
+
+ /* process on window-basis (i.e. iterate over all groups and corresponding
+ * windows) */
+ for (window = 0, group = 0; group < windowGroups; group++) {
+ groupMask = 1 << group;
+
+ for (groupwin = 0; groupwin < pWindowGroupLength[group];
+ groupwin++, window++) {
+ /* initialize the MDST with zeros */
+ FDKmemclear(&dmx_im[windowLen * window], windowLen * sizeof(FIXP_DBL));
+
+ /* 1. calculate the previous downmix MDCT. We do this once just for the
+ * Main band. */
+ if (cplxPredictionData->complex_coef == 1) {
+ if ((cplxPredictionData->use_prev_frame == 1) && (mainband_flag)) {
+ /* if this is a long-block or the first window of a short-block
+ calculate the downmix MDCT of the previous frame.
+ use_prev_frame is assumed not to change during a frame!
+ */
+
+ /* first determine shiftfactors to scale left and right channel */
+ if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence !=
+ BLOCK_SHORT) ||
+ (window == 0)) {
+ int index_offset = 0;
+ int srLeftChan = 0;
+ int srRightChan = 0;
+ if (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
+ BLOCK_SHORT) {
+ /* use the last window of the previous frame for MDCT
+ * calculation if this is a short-block. */
+ index_offset = windowLen * 7;
+ if (staticSpecScaleL[7] > staticSpecScaleR[7]) {
+ srRightChan = staticSpecScaleL[7] - staticSpecScaleR[7];
+ dmx_re_prev_e = staticSpecScaleL[7];
+ } else {
+ srLeftChan = staticSpecScaleR[7] - staticSpecScaleL[7];
+ dmx_re_prev_e = staticSpecScaleR[7];
+ }
+ } else {
+ if (staticSpecScaleL[0] > staticSpecScaleR[0]) {
+ srRightChan = staticSpecScaleL[0] - staticSpecScaleR[0];
+ dmx_re_prev_e = staticSpecScaleL[0];
+ } else {
+ srLeftChan = staticSpecScaleR[0] - staticSpecScaleL[0];
+ dmx_re_prev_e = staticSpecScaleR[0];
+ }
+ }
+
+ /* now scale channels and determine downmix MDCT of previous frame
+ */
+ if (pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData
+ .clearSpectralCoeffs == 1) {
+ FDKmemclear(dmx_re_prev, windowLen * sizeof(FIXP_DBL));
+ dmx_re_prev_e = 0;
+ } else {
+ if (cplxPredictionData->pred_dir == 0) {
+ for (int i = 0; i < windowLen; i++) {
+ dmx_re_prev[i] =
+ ((staticSpectralCoeffsL[index_offset + i] >>
+ srLeftChan) +
+ (staticSpectralCoeffsR[index_offset + i] >>
+ srRightChan)) >>
+ 1;
+ }
+ } else {
+ for (int i = 0; i < windowLen; i++) {
+ dmx_re_prev[i] =
+ ((staticSpectralCoeffsL[index_offset + i] >>
+ srLeftChan) -
+ (staticSpectralCoeffsR[index_offset + i] >>
+ srRightChan)) >>
+ 1;
+ }
+ }
+ }
+
+ /* In case that we use INF we have to preserve the state of the
+ "dmx_re_prev" (original or computed). This is necessary because we
+ have to apply MS over the separate IGF tiles. */
+ FDKmemcpy(store_dmx_re_prev, &dmx_re_prev[0],
+ windowLen * sizeof(FIXP_DBL));
+
+ /* Particular exponent of the computed/original "dmx_re_prev" must
+ * be kept for the tile MS calculations if necessary.*/
+ *store_dmx_re_prev_e = dmx_re_prev_e;
+
+ } /* if ( (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence !=
+ BLOCK_SHORT) || (window == 0) ) */
+
+ } /* if ( pJointStereoData->use_prev_frame == 1 ) */
+
+ } /* if ( pJointStereoData->complex_coef == 1 ) */
+
+ /* 2. calculate downmix MDCT of current frame */
+
+ /* set pointer to scale-factor-bands of current window */
+ SHORT *leftScale = &SFBleftScale[window * 16];
+ SHORT *rightScale = &SFBrightScale[window * 16];
+
+ specScaleL[window] = specScaleR[window] = frameMaxScale;
+
+ /* adapt scaling-factors to previous frame */
+ if (cplxPredictionData->use_prev_frame == 1) {
+ if (window == 0) {
+ if (dmx_re_prev_e < frameMaxScale) {
+ if (mainband_flag == 0) {
+ scaleValues(dmx_re_prev, store_dmx_re_prev, windowLen,
+ -(frameMaxScale - dmx_re_prev_e));
+ } else {
+ for (int i = 0; i < windowLen; i++) {
+ dmx_re_prev[i] >>= (frameMaxScale - dmx_re_prev_e);
+ }
+ }
+ } else {
+ if (mainband_flag == 0) {
+ FDKmemcpy(dmx_re_prev, store_dmx_re_prev,
+ windowLen * sizeof(FIXP_DBL));
+ }
+ specScaleL[0] = dmx_re_prev_e;
+ specScaleR[0] = dmx_re_prev_e;
+ }
+ } else { /* window != 0 */
+ FDK_ASSERT(pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
+ BLOCK_SHORT);
+ if (specScaleL[window - 1] < frameMaxScale) {
+ for (int i = 0; i < windowLen; i++) {
+ dmx_re[windowLen * (window - 1) + i] >>=
+ (frameMaxScale - specScaleL[window - 1]);
+ }
+ } else {
+ specScaleL[window] = specScaleL[window - 1];
+ specScaleR[window] = specScaleR[window - 1];
+ }
+ }
+ } /* if ( pJointStereoData->use_prev_frame == 1 ) */
+
+ /* scaling factors of both channels ought to be equal now */
+ FDK_ASSERT(specScaleL[window] == specScaleR[window]);
+
+ /* rescale signal and calculate downmix MDCT */
+ for (band = 0; band < max_sfb_ste; band++) {
+ /* first adapt scaling of current band to scaling of current window =>
+ * shift signal right */
+ int lScale = leftScale[band];
+ int rScale = rightScale[band];
+
+ lScale = fMin(DFRACT_BITS - 1, specScaleL[window] - lScale);
+ rScale = fMin(DFRACT_BITS - 1,
+ specScaleL[window] - rScale); /* L or R doesn't
+ matter,
+ specScales are
+ equal at this
+ point */
+
+ /* Write back to sfb scale to cover the case when max_sfb_ste <
+ * max_sfb */
+ leftScale[band] = rightScale[band] = specScaleL[window];
+
+ for (int i = pScaleFactorBandOffsets[band];
+ i < pScaleFactorBandOffsets[band + 1]; i++) {
+ spectrumL[windowLen * window + i] >>= lScale;
+ spectrumR[windowLen * window + i] >>= rScale;
+ }
+
+ /* now calculate downmix MDCT */
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ for (int i = pScaleFactorBandOffsets[band];
+ i < pScaleFactorBandOffsets[band + 1]; i++) {
+ dmx_re[windowLen * window + i] =
+ spectrumL[windowLen * window + i];
+ }
+ } else {
+ if (cplxPredictionData->pred_dir == 0) {
+ for (int i = pScaleFactorBandOffsets[band];
+ i < pScaleFactorBandOffsets[band + 1]; i++) {
+ dmx_re[windowLen * window + i] =
+ (spectrumL[windowLen * window + i] +
+ spectrumR[windowLen * window + i]) >>
+ 1;
+ }
+ } else {
+ for (int i = pScaleFactorBandOffsets[band];
+ i < pScaleFactorBandOffsets[band + 1]; i++) {
+ dmx_re[windowLen * window + i] =
+ (spectrumL[windowLen * window + i] -
+ spectrumR[windowLen * window + i]) >>
+ 1;
+ }
+ }
+ }
+
+ } /* for ( band=0; band<max_sfb_ste; band++ ) */
+ /* Clean until the end */
+ for (int i = pScaleFactorBandOffsets[max_sfb_ste_outside];
+ i < windowLen; i++) {
+ dmx_re[windowLen * window + i] = (FIXP_DBL)0;
+ }
+
+ /* 3. calculate MDST-portion corresponding to the current frame. */
+ if (cplxPredictionData->complex_coef == 1) {
+ {
+ /* 3.1 move pointer in filter-coefficient table in case of short
+ * window sequence */
+ /* (other coefficients are utilized for the last 7 short
+ * windows) */
+ if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
+ BLOCK_SHORT) &&
+ (window != 0)) {
+ pCoeff = mdst_filt_coef_curr[currentShape];
+ pCoeffPrev = mdst_filt_coef_prev[currentShape];
+ }
+
+ /* The length of the filter processing must be extended because of
+ * filter boundary problems */
+ int extended_band = fMin(
+ pScaleFactorBandOffsets[max_sfb_ste_outside] + 7, windowLen);
+
+ /* 3.2. estimate downmix MDST from current frame downmix MDCT */
+ if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
+ BLOCK_SHORT) &&
+ (window != 0)) {
+ CJointStereo_filterAndAdd(&dmx_re[windowLen * window],
+ extended_band, windowLen, pCoeff,
+ &dmx_im[windowLen * window], 1);
+
+ CJointStereo_filterAndAdd(&dmx_re[windowLen * (window - 1)],
+ extended_band, windowLen, pCoeffPrev,
+ &dmx_im[windowLen * window], 0);
+ } else {
+ CJointStereo_filterAndAdd(dmx_re, extended_band, windowLen,
+ pCoeff, dmx_im, 1);
+
+ if (cplxPredictionData->use_prev_frame == 1) {
+ CJointStereo_filterAndAdd(dmx_re_prev, extended_band, windowLen,
+ pCoeffPrev,
+ &dmx_im[windowLen * window], 0);
+ }
+ }
+
+ } /* if(pAacDecoderChannelInfo[L]->transform_splitting_active) */
+ } /* if ( pJointStereoData->complex_coef == 1 ) */
+
+ /* 4. upmix process */
+ INT pred_dir = cplxPredictionData->pred_dir ? -1 : 1;
+ /* 0.1 in Q-3.34 */
+ const FIXP_DBL pointOne = 0x66666666; /* 0.8 */
+ /* Shift value for the downmix */
+ const INT shift_dmx = SF_FNA_COEFFS + 1;
+
+ for (band = 0; band < max_sfb_ste_outside; band++) {
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ FIXP_SGL tempRe =
+ (FIXP_SGL)cplxPredictionData->alpha_q_re[group][band];
+ FIXP_SGL tempIm =
+ (FIXP_SGL)cplxPredictionData->alpha_q_im[group][band];
+
+ /* Find the minimum common headroom for alpha_re and alpha_im */
+ int alpha_re_headroom = CountLeadingBits((INT)tempRe) - 16;
+ if (tempRe == (FIXP_SGL)0) alpha_re_headroom = 15;
+ int alpha_im_headroom = CountLeadingBits((INT)tempIm) - 16;
+ if (tempIm == (FIXP_SGL)0) alpha_im_headroom = 15;
+ int val = fMin(alpha_re_headroom, alpha_im_headroom);
+
+ /* Multiply alpha by 0.1 with maximum precision */
+ FDK_ASSERT(val >= 0);
+ FIXP_DBL alpha_re_tmp = fMult((FIXP_SGL)(tempRe << val), pointOne);
+ FIXP_DBL alpha_im_tmp = fMult((FIXP_SGL)(tempIm << val), pointOne);
+
+ /* Calculate alpha exponent */
+ /* (Q-3.34 * Q15.0) shifted left by "val" */
+ int alpha_re_exp = -3 + 15 - val;
+
+ int help3_shift = alpha_re_exp + 1;
+
+ FIXP_DBL *p2CoeffL = &(
+ spectrumL[windowLen * window + pScaleFactorBandOffsets[band]]);
+ FIXP_DBL *p2CoeffR = &(
+ spectrumR[windowLen * window + pScaleFactorBandOffsets[band]]);
+ FIXP_DBL *p2dmxIm =
+ &(dmx_im[windowLen * window + pScaleFactorBandOffsets[band]]);
+ FIXP_DBL *p2dmxRe =
+ &(dmx_re[windowLen * window + pScaleFactorBandOffsets[band]]);
+
+ for (int i = pScaleFactorBandOffsets[band];
+ i < pScaleFactorBandOffsets[band + 1]; i++) {
+ /* Calculating helper term:
+ side = specR[i] - alpha_re[i] * dmx_re[i] - alpha_im[i] *
+ dmx_im[i];
+
+ Here "dmx_re" may be the same as "specL" or alternatively keep
+ the downmix. "dmx_re" and "specL" are two different pointers
+ pointing to separate arrays, which may or may not contain the
+ same data (with different scaling).
+ */
+
+ /* help1: alpha_re[i] * dmx_re[i] */
+ FIXP_DBL help1 = fMultDiv2(alpha_re_tmp, *p2dmxRe++);
+
+ /* tmp: dmx_im[i] */
+ FIXP_DBL tmp = (*p2dmxIm++) << shift_dmx;
+
+ /* help2: alpha_im[i] * dmx_im[i] */
+ FIXP_DBL help2 = fMultDiv2(alpha_im_tmp, tmp);
+
+ /* help3: alpha_re[i] * dmx_re[i] + alpha_im[i] * dmx_im[i] */
+ FIXP_DBL help3 = help1 + help2;
+
+ /* side (= help4) = specR[i] - (dmx_re[i] * specL[i] + alpha_im[i]
+ * * dmx_im[i]) */
+ FIXP_DBL help4 = *p2CoeffR - scaleValue(help3, help3_shift);
+
+ /* We calculate the left and right output by using the helper
+ * function */
+ /* specR[i] = -/+ (specL[i] - side); */
+ *p2CoeffR =
+ (FIXP_DBL)((LONG)(*p2CoeffL - help4) * (LONG)pred_dir);
+ p2CoeffR++;
+
+ /* specL[i] = specL[i] + side; */
+ *p2CoeffL = *p2CoeffL + help4;
+ p2CoeffL++;
+ }
+ }
+
+ } /* for ( band=0; band < max_sfb_ste; band++ ) */
+ } /* for ( groupwin=0; groupwin<pWindowGroupLength[group]; groupwin++,
+ window++ ) */
+
+ } /* for ( window = 0, group = 0; group < windowGroups; group++ ) */
+
+ /* free scratch buffer */
+ C_AALLOC_SCRATCH_END(dmx_im, FIXP_DBL, 1024);
+
+ } else {
+ /* MS stereo */
+
+ for (window = 0, group = 0; group < windowGroups; group++) {
+ groupMask = 1 << group;
+
+ for (int groupwin = 0; groupwin < pWindowGroupLength[group];
+ groupwin++, window++) {
+ FIXP_DBL *leftSpectrum, *rightSpectrum;
+ SHORT *leftScale = &SFBleftScale[window * 16];
+ SHORT *rightScale = &SFBrightScale[window * 16];
+
+ leftSpectrum =
+ SPEC(spectrumL, window, pAacDecoderChannelInfo[L]->granuleLength);
+ rightSpectrum =
+ SPEC(spectrumR, window, pAacDecoderChannelInfo[R]->granuleLength);
+
+ for (band = 0; band < max_sfb_ste_outside; band++) {
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ int lScale = leftScale[band];
+ int rScale = rightScale[band];
+ int commonScale = lScale > rScale ? lScale : rScale;
+ unsigned int offsetCurrBand, offsetNextBand;
+
+ /* ISO/IEC 14496-3 Chapter 4.6.8.1.1 :
+ M/S joint channel coding can only be used if common_window is 1.
+ */
+ FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) ==
+ GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo));
+ FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) ==
+ GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo));
+
+ commonScale++;
+ leftScale[band] = commonScale;
+ rightScale[band] = commonScale;
+
+ lScale = fMin(DFRACT_BITS - 1, commonScale - lScale);
+ rScale = fMin(DFRACT_BITS - 1, commonScale - rScale);
+
+ FDK_ASSERT(lScale >= 0 && rScale >= 0);
+
+ offsetCurrBand = pScaleFactorBandOffsets[band];
+ offsetNextBand = pScaleFactorBandOffsets[band + 1];
+
+ CJointStereo_GenerateMSOutput(&(leftSpectrum[offsetCurrBand]),
+ &(rightSpectrum[offsetCurrBand]),
+ lScale, rScale,
+ offsetNextBand - offsetCurrBand);
+ }
+ }
+ if (scaleFactorBandsTransmittedL > scaleFactorBandsTransmitted) {
+ for (; band < scaleFactorBandsTransmittedL; band++) {
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ rightScale[band] = leftScale[band];
+
+ for (int index = pScaleFactorBandOffsets[band];
+ index < pScaleFactorBandOffsets[band + 1]; index++) {
+ FIXP_DBL leftCoefficient = leftSpectrum[index];
+ /* FIXP_DBL rightCoefficient = (FIXP_DBL)0; */
+ rightSpectrum[index] = leftCoefficient;
+ }
+ }
+ }
+ } else if (scaleFactorBandsTransmittedR > scaleFactorBandsTransmitted) {
+ for (; band < scaleFactorBandsTransmittedR; band++) {
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ leftScale[band] = rightScale[band];
+
+ for (int index = pScaleFactorBandOffsets[band];
+ index < pScaleFactorBandOffsets[band + 1]; index++) {
+ /* FIXP_DBL leftCoefficient = (FIXP_DBL)0; */
+ FIXP_DBL rightCoefficient = rightSpectrum[index];
+
+ leftSpectrum[index] = rightCoefficient;
+ rightSpectrum[index] = -rightCoefficient;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Reset MsUsed flags if no explicit signalling was transmitted. Necessary
+ for intensity coding. PNS correlation signalling was mapped before
+ calling CJointStereo_ApplyMS(). */
+ if (pJointStereoData->MsMaskPresent == 2) {
+ FDKmemclear(pJointStereoData->MsUsed,
+ JointStereoMaximumBands * sizeof(UCHAR));
+ }
+ }
+}
+
+void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
+ const SHORT *pScaleFactorBandOffsets,
+ const UCHAR *pWindowGroupLength,
+ const int windowGroups,
+ const int scaleFactorBandsTransmitted) {
+ CJointStereoData *pJointStereoData =
+ &pAacDecoderChannelInfo[L]->pComData->jointStereoData;
+
+ for (int window = 0, group = 0; group < windowGroups; group++) {
+ UCHAR *CodeBook;
+ SHORT *ScaleFactor;
+ UCHAR groupMask = 1 << group;
+
+ CodeBook = &pAacDecoderChannelInfo[R]->pDynData->aCodeBook[group * 16];
+ ScaleFactor =
+ &pAacDecoderChannelInfo[R]->pDynData->aScaleFactor[group * 16];
+
+ for (int groupwin = 0; groupwin < pWindowGroupLength[group];
+ groupwin++, window++) {
+ FIXP_DBL *leftSpectrum, *rightSpectrum;
+ SHORT *leftScale =
+ &pAacDecoderChannelInfo[L]->pDynData->aSfbScale[window * 16];
+ SHORT *rightScale =
+ &pAacDecoderChannelInfo[R]->pDynData->aSfbScale[window * 16];
+ int band;
+
+ leftSpectrum = SPEC(pAacDecoderChannelInfo[L]->pSpectralCoefficient,
+ window, pAacDecoderChannelInfo[L]->granuleLength);
+ rightSpectrum = SPEC(pAacDecoderChannelInfo[R]->pSpectralCoefficient,
+ window, pAacDecoderChannelInfo[R]->granuleLength);
+
+ for (band = 0; band < scaleFactorBandsTransmitted; band++) {
+ if ((CodeBook[band] == INTENSITY_HCB) ||
+ (CodeBook[band] == INTENSITY_HCB2)) {
+ int bandScale = -(ScaleFactor[band] + 100);
+
+ int msb = bandScale >> 2;
+ int lsb = bandScale & 0x03;
+
+ /* exponent of MantissaTable[lsb][0] is 1, thus msb+1 below. */
+ FIXP_DBL scale = MantissaTable[lsb][0];
+
+ /* ISO/IEC 14496-3 Chapter 4.6.8.2.3 :
+ The use of intensity stereo coding is signaled by the use of the
+ pseudo codebooks INTENSITY_HCB and INTENSITY_HCB2 (15 and 14) only
+ in the right channel of a channel_pair_element() having a common
+ ics_info() (common_window == 1). */
+ FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) ==
+ GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo));
+ FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) ==
+ GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo));
+
+ rightScale[band] = leftScale[band] + msb + 1;
+
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ if (CodeBook[band] == INTENSITY_HCB) /* _NOT_ in-phase */
+ {
+ scale = -scale;
+ }
+ } else {
+ if (CodeBook[band] == INTENSITY_HCB2) /* out-of-phase */
+ {
+ scale = -scale;
+ }
+ }
+
+ for (int index = pScaleFactorBandOffsets[band];
+ index < pScaleFactorBandOffsets[band + 1]; index++) {
+ rightSpectrum[index] = fMult(leftSpectrum[index], scale);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/stereo.h b/fdk-aac/libAACdec/src/stereo.h
new file mode 100644
index 0000000..af7a74f
--- /dev/null
+++ b/fdk-aac/libAACdec/src/stereo.h
@@ -0,0 +1,211 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: joint stereo processing
+
+*******************************************************************************/
+
+#ifndef STEREO_H
+#define STEREO_H
+
+#include "machine_type.h"
+#include "FDK_bitstream.h"
+#include "common_fix.h"
+
+#define SFB_PER_PRED_BAND 2
+
+#define SR_FNA_OUT \
+ 0 /* Additional scaling of the CJointStereo_filterAndAdd()-output to avoid \
+ overflows. */
+ /* The scaling factor can be set to 0 if the coefficients are prescaled
+ * appropriately. */
+/* Prescaling via factor SF_FNA_COEFFS is done at compile-time but should only
+ * be */
+/* utilized if the coefficients are stored as FIXP_DBL. (cp. aac_rom.cpp/.h) */
+
+/* The NO_CPLX_PRED_BUGFIX-switch was introduced to enable decoding of
+ conformance-streams in way that they are comparable to buggy
+ reference-streams. This is established by storing the prediction direction
+ for computation of the "downmix MDCT of previous frame". This is not standard
+ compliant. Once correct reference-streams for complex-stereo-prediction are
+ available this switch becomes obsolete.
+*/
+/*#define NO_CPLX_PRED_BUGFIX*/
+
+enum { JointStereoMaximumGroups = 8, JointStereoMaximumBands = 64 };
+
+typedef struct {
+ UCHAR pred_dir; // 0 = prediction from mid to side channel, 1 = vice versa
+ UCHAR
+ igf_pred_dir; // 0 = prediction from mid to side channel, 1 = vice versa
+ UCHAR complex_coef; // 0 = alpha_q_im[x] is 0 for all prediction bands, 1 =
+ // alpha_q_im[x] is transmitted via bitstream
+ UCHAR use_prev_frame; // 0 = use current frame for MDST estimation, 1 = use
+ // current and previous frame
+
+ SHORT alpha_q_re[JointStereoMaximumGroups][JointStereoMaximumBands];
+ SHORT alpha_q_im[JointStereoMaximumGroups][JointStereoMaximumBands];
+} CCplxPredictionData;
+
+/* joint stereo scratch memory (valid for this frame) */
+typedef struct {
+ UCHAR MsMaskPresent;
+ UCHAR MsUsed[JointStereoMaximumBands]; /*!< every arry element contains flags
+ for up to 8 groups. this array is
+ also utilized for complex stereo
+ prediction. */
+ UCHAR IGF_MsMaskPresent;
+
+ UCHAR cplx_pred_flag; /* stereo complex prediction was signalled for this
+ frame */
+ UCHAR igf_cplx_pred_flag;
+
+ /* The following array and variable are needed for the case when INF is
+ * active */
+ FIXP_DBL store_dmx_re_prev[1024];
+ SHORT store_dmx_re_prev_e;
+
+} CJointStereoData;
+
+/* joint stereo persistent memory */
+typedef struct {
+ UCHAR clearSpectralCoeffs; /* indicates that the spectral coeffs must be
+ cleared because the transform splitting active
+ flag of the left and right channel was different
+ */
+
+ FIXP_DBL *scratchBuffer; /* pointer to scratch buffer */
+
+ FIXP_DBL
+ *spectralCoeffs[2]; /* spectral coefficients of this channel utilized by
+ complex stereo prediction */
+ SHORT *specScale[2];
+
+ SHORT alpha_q_re_prev[JointStereoMaximumGroups][JointStereoMaximumBands];
+ SHORT alpha_q_im_prev[JointStereoMaximumGroups][JointStereoMaximumBands];
+
+ UCHAR winSeqPrev;
+ UCHAR winShapePrev;
+ UCHAR winGroupsPrev;
+
+} CJointStereoPersistentData;
+
+/*!
+ \brief Read joint stereo data from bitstream
+
+ The function reads joint stereo data from bitstream.
+
+ \param bs bit stream handle data source.
+ \param pJointStereoData pointer to stereo data structure to receive decoded
+ data. \param windowGroups number of window groups. \param
+ scaleFactorBandsTransmitted number of transmitted scalefactor bands. \param
+ flags decoder flags
+
+ \return 0 on success, -1 on error.
+*/
+int CJointStereo_Read(HANDLE_FDK_BITSTREAM bs,
+ CJointStereoData *pJointStereoData,
+ const int windowGroups,
+ const int scaleFactorBandsTransmitted,
+ const int max_sfb_ste_clear,
+ CJointStereoPersistentData *pJointStereoPersistentData,
+ CCplxPredictionData *cplxPredictionData,
+ int cplxPredictionActiv, int scaleFactorBandsTotal,
+ int windowSequence, const UINT flags);
+
+#endif /* #ifndef STEREO_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_ace_d4t64.cpp b/fdk-aac/libAACdec/src/usacdec_ace_d4t64.cpp
new file mode 100644
index 0000000..43e06cd
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_ace_d4t64.cpp
@@ -0,0 +1,439 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s):
+
+ Description: ACELP
+
+*******************************************************************************/
+
+#include "usacdec_ace_d4t64.h"
+
+#define L_SUBFR 64 /* Subframe size */
+
+/*
+ * D_ACELP_add_pulse
+ *
+ * Parameters:
+ * pos I: position of pulse
+ * nb_pulse I: number of pulses
+ * track I: track
+ * code O: fixed codebook
+ *
+ * Function:
+ * Add pulses to fixed codebook
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_add_pulse(SHORT pos[], SHORT nb_pulse, SHORT track,
+ FIXP_COD code[]) {
+ SHORT i, k;
+ for (k = 0; k < nb_pulse; k++) {
+ /* i = ((pos[k] & (16-1))*NB_TRACK) + track; */
+ i = ((pos[k] & (16 - 1)) << 2) + track;
+ if ((pos[k] & 16) == 0) {
+ code[i] = code[i] + (FIXP_COD)(512 << (COD_BITS - FRACT_BITS));
+ } else {
+ code[i] = code[i] - (FIXP_COD)(512 << (COD_BITS - FRACT_BITS));
+ }
+ }
+ return;
+}
+/*
+ * D_ACELP_decode_1p_N1
+ *
+ * Parameters:
+ * index I: pulse index
+ * N I: number of bits for position
+ * offset I: offset
+ * pos O: position of the pulse
+ *
+ * Function:
+ * Decode 1 pulse with N+1 bits
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_decode_1p_N1(LONG index, SHORT N, SHORT offset,
+ SHORT pos[]) {
+ SHORT pos1;
+ LONG i, mask;
+
+ mask = ((1 << N) - 1);
+ /*
+ * Decode 1 pulse with N+1 bits
+ */
+ pos1 = (SHORT)((index & mask) + offset);
+ i = ((index >> N) & 1);
+ if (i == 1) {
+ pos1 += 16;
+ }
+ pos[0] = pos1;
+ return;
+}
+/*
+ * D_ACELP_decode_2p_2N1
+ *
+ * Parameters:
+ * index I: pulse index
+ * N I: number of bits for position
+ * offset I: offset
+ * pos O: position of the pulse
+ *
+ * Function:
+ * Decode 2 pulses with 2*N+1 bits
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_decode_2p_2N1(LONG index, SHORT N, SHORT offset,
+ SHORT pos[]) {
+ SHORT pos1, pos2;
+ LONG mask, i;
+ mask = ((1 << N) - 1);
+ /*
+ * Decode 2 pulses with 2*N+1 bits
+ */
+ pos1 = (SHORT)(((index >> N) & mask) + offset);
+ i = (index >> (2 * N)) & 1;
+ pos2 = (SHORT)((index & mask) + offset);
+ if ((pos2 - pos1) < 0) {
+ if (i == 1) {
+ pos1 += 16;
+ } else {
+ pos2 += 16;
+ }
+ } else {
+ if (i == 1) {
+ pos1 += 16;
+ pos2 += 16;
+ }
+ }
+ pos[0] = pos1;
+ pos[1] = pos2;
+ return;
+}
+/*
+ * D_ACELP_decode_3p_3N1
+ *
+ * Parameters:
+ * index I: pulse index
+ * N I: number of bits for position
+ * offset I: offset
+ * pos O: position of the pulse
+ *
+ * Function:
+ * Decode 3 pulses with 3*N+1 bits
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_decode_3p_3N1(LONG index, SHORT N, SHORT offset,
+ SHORT pos[]) {
+ SHORT j;
+ LONG mask, idx;
+
+ /*
+ * Decode 3 pulses with 3*N+1 bits
+ */
+ mask = ((1 << ((2 * N) - 1)) - 1);
+ idx = index & mask;
+ j = offset;
+ if (((index >> ((2 * N) - 1)) & 1) == 1) {
+ j += (1 << (N - 1));
+ }
+ D_ACELP_decode_2p_2N1(idx, N - 1, j, pos);
+ mask = ((1 << (N + 1)) - 1);
+ idx = (index >> (2 * N)) & mask;
+ D_ACELP_decode_1p_N1(idx, N, offset, pos + 2);
+ return;
+}
+/*
+ * D_ACELP_decode_4p_4N1
+ *
+ * Parameters:
+ * index I: pulse index
+ * N I: number of bits for position
+ * offset I: offset
+ * pos O: position of the pulse
+ *
+ * Function:
+ * Decode 4 pulses with 4*N+1 bits
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_decode_4p_4N1(LONG index, SHORT N, SHORT offset,
+ SHORT pos[]) {
+ SHORT j;
+ LONG mask, idx;
+ /*
+ * Decode 4 pulses with 4*N+1 bits
+ */
+ mask = ((1 << ((2 * N) - 1)) - 1);
+ idx = index & mask;
+ j = offset;
+ if (((index >> ((2 * N) - 1)) & 1) == 1) {
+ j += (1 << (N - 1));
+ }
+ D_ACELP_decode_2p_2N1(idx, N - 1, j, pos);
+ mask = ((1 << ((2 * N) + 1)) - 1);
+ idx = (index >> (2 * N)) & mask;
+ D_ACELP_decode_2p_2N1(idx, N, offset, pos + 2);
+ return;
+}
+/*
+ * D_ACELP_decode_4p_4N
+ *
+ * Parameters:
+ * index I: pulse index
+ * N I: number of bits for position
+ * offset I: offset
+ * pos O: position of the pulse
+ *
+ * Function:
+ * Decode 4 pulses with 4*N bits
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_decode_4p_4N(LONG index, SHORT N, SHORT offset,
+ SHORT pos[]) {
+ SHORT j, n_1;
+ /*
+ * Decode 4 pulses with 4*N bits
+ */
+ n_1 = N - 1;
+ j = offset + (1 << n_1);
+ switch ((index >> ((4 * N) - 2)) & 3) {
+ case 0:
+ if (((index >> ((4 * n_1) + 1)) & 1) == 0) {
+ D_ACELP_decode_4p_4N1(index, n_1, offset, pos);
+ } else {
+ D_ACELP_decode_4p_4N1(index, n_1, j, pos);
+ }
+ break;
+ case 1:
+ D_ACELP_decode_1p_N1((index >> ((3 * n_1) + 1)), n_1, offset, pos);
+ D_ACELP_decode_3p_3N1(index, n_1, j, pos + 1);
+ break;
+ case 2:
+ D_ACELP_decode_2p_2N1((index >> ((2 * n_1) + 1)), n_1, offset, pos);
+ D_ACELP_decode_2p_2N1(index, n_1, j, pos + 2);
+ break;
+ case 3:
+ D_ACELP_decode_3p_3N1((index >> (n_1 + 1)), n_1, offset, pos);
+ D_ACELP_decode_1p_N1(index, n_1, j, pos + 3);
+ break;
+ }
+ return;
+}
+
+/*
+ * D_ACELP_decode_4t
+ *
+ * Parameters:
+ * index I: index
+ * mode I: speech mode
+ * code I: (Q9) algebraic (fixed) codebook excitation
+ *
+ * Function:
+ * 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.
+ * 4 tracks x 16 positions per track = 64 samples.
+ *
+ * 20 bits 5+5+5+5 --> 4 pulses in a frame of 64 samples.
+ * 36 bits 9+9+9+9 --> 8 pulses in a frame of 64 samples.
+ * 44 bits 13+9+13+9 --> 10 pulses in a frame of 64 samples.
+ * 52 bits 13+13+13+13 --> 12 pulses in a frame of 64 samples.
+ * 64 bits 2+2+2+2+14+14+14+14 --> 16 pulses in a frame of 64 samples.
+ * 72 bits 10+2+10+2+10+14+10+14 --> 18 pulses in a frame of 64 samples.
+ * 88 bits 11+11+11+11+11+11+11+11 --> 24 pulses in a frame of 64 samples.
+ *
+ * All pulses can have two (2) possible amplitudes: +1 or -1.
+ * Each pulse can sixteen (16) possible positions.
+ *
+ * codevector length 64
+ * number of track 4
+ * number of position 16
+ *
+ * Returns:
+ * void
+ */
+void D_ACELP_decode_4t64(SHORT index[], int nbits, FIXP_COD code[]) {
+ LONG L_index;
+ SHORT k, pos[6];
+
+ FDKmemclear(code, L_SUBFR * sizeof(FIXP_COD));
+
+ /* decode the positions and signs of pulses and build the codeword */
+ switch (nbits) {
+ case 12:
+ for (k = 0; k < 4; k += 2) {
+ L_index = index[2 * (k / 2) + 1];
+ D_ACELP_decode_1p_N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 1, 2 * (index[2 * (k / 2)]) + k / 2, code);
+ }
+ break;
+ case 16: {
+ int i = 0;
+ int offset = index[i++];
+ offset = (offset == 0) ? 1 : 3;
+ for (k = 0; k < 4; k++) {
+ if (k != offset) {
+ L_index = index[i++];
+ D_ACELP_decode_1p_N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 1, k, code);
+ }
+ }
+ } break;
+ case 20:
+ for (k = 0; k < 4; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_1p_N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 1, k, code);
+ }
+ break;
+ case 28:
+ for (k = 0; k < 4 - 2; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_2p_2N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 2, k, code);
+ }
+ for (k = 2; k < 4; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_1p_N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 1, k, code);
+ }
+ break;
+ case 36:
+ for (k = 0; k < 4; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_2p_2N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 2, k, code);
+ }
+ break;
+ case 44:
+ for (k = 0; k < 4 - 2; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_3p_3N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 3, k, code);
+ }
+ for (k = 2; k < 4; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_2p_2N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 2, k, code);
+ }
+ break;
+ case 52:
+ for (k = 0; k < 4; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_3p_3N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 3, k, code);
+ }
+ break;
+ case 64:
+ for (k = 0; k < 4; k++) {
+ L_index = (((LONG)index[k] << 14) + (LONG)index[k + 4]);
+ D_ACELP_decode_4p_4N(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 4, k, code);
+ }
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+ return;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_ace_d4t64.h b/fdk-aac/libAACdec/src/usacdec_ace_d4t64.h
new file mode 100644
index 0000000..76bc3d9
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_ace_d4t64.h
@@ -0,0 +1,117 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s):
+
+ Description: ACELP
+
+*******************************************************************************/
+
+#ifndef USACDEC_ACE_D4T64_H
+#define USACDEC_ACE_D4T64_H
+
+#include "common_fix.h"
+
+/* Data type definition for the fixed codebook vector */
+#define FIXP_COD FIXP_SGL
+#define FX_COD2FX_DBL(x) (FX_SGL2FX_DBL(x))
+#define FX_DBL2FX_COD(x) FX_DBL2FX_SGL((x) + (FIXP_DBL)0x8000)
+#define FX_SGL2FX_COD(x) (x)
+#define COD_BITS FRACT_BITS
+
+void D_ACELP_decode_4t64(SHORT index[], int nbits, FIXP_COD code[]);
+
+#endif /* USACDEC_ACE_D4T64_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_ace_ltp.cpp b/fdk-aac/libAACdec/src/usacdec_ace_ltp.cpp
new file mode 100644
index 0000000..5964b49
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_ace_ltp.cpp
@@ -0,0 +1,229 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: USAC ACELP LTP filter
+
+*******************************************************************************/
+
+#include "usacdec_ace_ltp.h"
+
+#include "genericStds.h"
+#include "common_fix.h"
+
+#define UP_SAMP 4
+#define L_INTERPOL2 16
+#define L_SUBFR 64
+
+#define A2 FL2FX_SGL(2 * 0.18f)
+#define B FL2FX_SGL(0.64f)
+
+static const LONG Pred_lt4_inter4_2[UP_SAMP][L_INTERPOL2] = {
+ {(LONG)0x0000FFFC, (LONG)0x0008FFFC, (LONG)0xFFEB004C, (LONG)0xFF50014A,
+ (LONG)0xFDD90351, (LONG)0xFB2A06CD, (LONG)0xF6920D46, (LONG)0xEBB42B35,
+ (LONG)0x6D9EEF39, (LONG)0x0618FE0F, (LONG)0xFFE00131, (LONG)0xFE5501C5,
+ (LONG)0xFE5E015D, (LONG)0xFEF700B6, (LONG)0xFF920037, (LONG)0xFFEC0003},
+ {(LONG)0x0002FFF2, (LONG)0x0026FFBD, (LONG)0x005DFF98, (LONG)0x0055FFEF,
+ (LONG)0xFF89015F, (LONG)0xFD3A04E5, (LONG)0xF7D90DAA, (LONG)0xE67A50EE,
+ (LONG)0x50EEE67A, (LONG)0x0DAAF7D9, (LONG)0x04E5FD3A, (LONG)0x015FFF89,
+ (LONG)0xFFEF0055, (LONG)0xFF98005D, (LONG)0xFFBD0026, (LONG)0xFFF20002},
+ {(LONG)0x0003FFEC, (LONG)0x0037FF92, (LONG)0x00B6FEF7, (LONG)0x015DFE5E,
+ (LONG)0x01C5FE55, (LONG)0x0131FFE0, (LONG)0xFE0F0618, (LONG)0xEF396D9E,
+ (LONG)0x2B35EBB4, (LONG)0x0D46F692, (LONG)0x06CDFB2A, (LONG)0x0351FDD9,
+ (LONG)0x014AFF50, (LONG)0x004CFFEB, (LONG)0xFFFC0008, (LONG)0xFFFC0000},
+ {(LONG)0x0002FFF2, (LONG)0x002BFF9E, (LONG)0x00B9FECE, (LONG)0x01CFFD75,
+ (LONG)0x035EFBC1, (LONG)0x0521FA0C, (LONG)0x06AAF8C9, (LONG)0x07907852,
+ (LONG)0x0790F8C9, (LONG)0x06AAFA0C, (LONG)0x0521FBC1, (LONG)0x035EFD75,
+ (LONG)0x01CFFECE, (LONG)0x00B9FF9E, (LONG)0x002BFFF2, (LONG)0x00020000}};
+
+void Pred_lt4(FIXP_DBL exc[], /* in/out: excitation buffer */
+ int T0, /* input : integer pitch lag */
+ int frac /* input : fraction of lag in range 0..3 */
+) {
+ int j;
+ FIXP_DBL *x;
+ const LONG *interpol;
+ FIXP_DBL L_sumb, L_sumt;
+
+ x = &exc[-T0 - L_INTERPOL2 + 1];
+
+ /* remap frac and x:
+ 0 -> 3 x (unchanged)
+ 1 -> 0 x--
+ 2 -> 1 x--
+ 3 -> 2 x--
+ */
+
+ if (--frac < 0)
+ frac += UP_SAMP;
+ else
+ x--;
+
+ j = L_SUBFR + 1;
+ do {
+ LONG filt;
+ FIXP_DBL x0, x1;
+ FIXP_DBL *xi = x++;
+ interpol = Pred_lt4_inter4_2[frac];
+ int i = 3;
+
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultDiv2(x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultDiv2(x1, (FIXP_SGL)((SHORT)filt));
+ do {
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultAddDiv2(L_sumt, x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultAddDiv2(L_sumb, x1, (FIXP_SGL)((SHORT)filt));
+
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultAddDiv2(L_sumt, x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultAddDiv2(L_sumb, x1, (FIXP_SGL)((SHORT)filt));
+
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultAddDiv2(L_sumt, x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultAddDiv2(L_sumb, x1, (FIXP_SGL)((SHORT)filt));
+
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultAddDiv2(L_sumt, x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultAddDiv2(L_sumb, x1, (FIXP_SGL)((SHORT)filt));
+
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultAddDiv2(L_sumt, x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultAddDiv2(L_sumb, x1, (FIXP_SGL)((SHORT)filt));
+ } while (--i != 0);
+
+ L_sumb <<= 1;
+ L_sumb = fAddSaturate(L_sumt << 1, L_sumb);
+ *exc++ = L_sumb;
+ } while (--j != 0);
+ return;
+}
+
+void Pred_lt4_postfilter(FIXP_DBL exc[] /* in/out: excitation buffer */
+) {
+ /*
+ exc[i] = A*exc[i-1] + B*exc[i] + A*exc[i+1]
+ exc[i+1] = A*exc[i] + B*exc[i+1] + A*exc[i+2] ; i = 0:2:62
+ */
+ int i;
+ FIXP_DBL sum0, sum1, a_exc0, a_exc1;
+ a_exc0 = fMultDiv2(A2, exc[-1]);
+ a_exc1 = fMultDiv2(A2, exc[0]);
+
+ /* ARM926: 22 cycles/iteration */
+ for (i = 0; i < L_SUBFR; i += 2) {
+ sum0 = a_exc0 + fMult(B, exc[i]);
+ sum1 = a_exc1 + fMult(B, exc[i + 1]);
+ a_exc0 = fMultDiv2(A2, exc[i + 1]);
+ a_exc1 = fMultDiv2(A2, exc[i + 2]);
+ exc[i] = sum0 + a_exc0;
+ exc[i + 1] = sum1 + a_exc1;
+ }
+ return;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_ace_ltp.h b/fdk-aac/libAACdec/src/usacdec_ace_ltp.h
new file mode 100644
index 0000000..5128acd
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_ace_ltp.h
@@ -0,0 +1,128 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: USAC ACELP LTP filter
+
+*******************************************************************************/
+
+#ifndef USACDEC_ACE_LTP_H
+#define USACDEC_ACE_LTP_H
+
+#include "common_fix.h"
+
+/**
+ * \brief Compute the initial adaptive codebook excitation v'(n) by
+ * interpolating the past excitation vector u'(n).
+ * \param exc points to adaptive codebook of current subframe (input/output)
+ * \param T0 integer part of decoded pitch lag (input)
+ * \param frac fractional part of decoded pitch lag (0..3) (input)
+ */
+void Pred_lt4(FIXP_DBL exc[], /* in/out: excitation buffer */
+ int T0, /* input : integer pitch lag */
+ int frac /* input : fraction of lag */
+);
+
+/**
+ * \brief Compute the adaptive codebook excitation v(n) in case of
+ * ltp_filtering_flag == 0.
+ * \param exc points to adaptive codebook of current subframe (input/output)
+ */
+void Pred_lt4_postfilter(FIXP_DBL exc[] /* in/out: excitation buffer */
+);
+
+#endif /* USACDEC_ACE_LTP_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_acelp.cpp b/fdk-aac/libAACdec/src/usacdec_acelp.cpp
new file mode 100644
index 0000000..a606459
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_acelp.cpp
@@ -0,0 +1,1296 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: USAC ACELP frame decoder
+
+*******************************************************************************/
+
+#include "usacdec_acelp.h"
+
+#include "usacdec_ace_d4t64.h"
+#include "usacdec_ace_ltp.h"
+#include "usacdec_rom.h"
+#include "usacdec_lpc.h"
+#include "genericStds.h"
+
+#define PIT_FR2_12k8 128 /* Minimum pitch lag with resolution 1/2 */
+#define PIT_FR1_12k8 160 /* Minimum pitch lag with resolution 1 */
+#define TILT_CODE2 \
+ FL2FXCONST_SGL(0.3f * 2.0f) /* ACELP code pre-emphasis factor ( *2 ) */
+#define PIT_SHARP \
+ FL2FXCONST_SGL(0.85f) /* pitch sharpening factor */
+#define PREEMPH_FAC \
+ FL2FXCONST_SGL(0.68f) /* ACELP synth pre-emphasis factor */
+
+#define ACELP_HEADROOM 1
+#define ACELP_OUTSCALE (MDCT_OUT_HEADROOM - ACELP_HEADROOM)
+
+/**
+ * \brief Calculate pre-emphasis (1 - mu z^-1) on input signal.
+ * \param[in] in pointer to input signal; in[-1] is also needed.
+ * \param[out] out pointer to output signal.
+ * \param[in] L length of filtering.
+ */
+/* static */
+void E_UTIL_preemph(const FIXP_DBL *in, FIXP_DBL *out, INT L) {
+ int i;
+
+ for (i = 0; i < L; i++) {
+ out[i] = in[i] - fMult(PREEMPH_FAC, in[i - 1]);
+ }
+
+ return;
+}
+
+/**
+ * \brief Calculate de-emphasis 1/(1 - TILT_CODE z^-1) on innovative codebook
+ * vector.
+ * \param[in,out] x innovative codebook vector.
+ */
+static void Preemph_code(
+ FIXP_COD x[] /* (i/o) : input signal overwritten by the output */
+) {
+ int i;
+ FIXP_DBL L_tmp;
+
+ /* ARM926: 12 cycles per sample */
+ for (i = L_SUBFR - 1; i > 0; i--) {
+ L_tmp = FX_COD2FX_DBL(x[i]);
+ L_tmp -= fMultDiv2(x[i - 1], TILT_CODE2);
+ x[i] = FX_DBL2FX_COD(L_tmp);
+ }
+}
+
+/**
+ * \brief Apply pitch sharpener to the innovative codebook vector.
+ * \param[in,out] x innovative codebook vector.
+ * \param[in] pit_lag decoded pitch lag.
+ */
+static void Pit_shrp(
+ FIXP_COD x[], /* in/out: impulse response (or algebraic code) */
+ int pit_lag /* input : pitch lag */
+) {
+ int i;
+ FIXP_DBL L_tmp;
+
+ for (i = pit_lag; i < L_SUBFR; i++) {
+ L_tmp = FX_COD2FX_DBL(x[i]);
+ L_tmp += fMult(x[i - pit_lag], PIT_SHARP);
+ x[i] = FX_DBL2FX_COD(L_tmp);
+ }
+
+ return;
+}
+
+ /**
+ * \brief Calculate Quantized codebook gain, Quantized pitch gain and unbiased
+ * Innovative code vector energy.
+ * \param[in] index index of quantizer.
+ * \param[in] code innovative code vector with exponent = SF_CODE.
+ * \param[out] gain_pit Quantized pitch gain g_p with exponent = SF_GAIN_P.
+ * \param[out] gain_code Quantized codebook gain g_c.
+ * \param[in] mean_ener mean_ener defined in open-loop (2 bits), exponent = 7.
+ * \param[out] E_code unbiased innovative code vector energy.
+ * \param[out] E_code_e exponent of unbiased innovative code vector energy.
+ */
+
+#define SF_MEAN_ENER_LG10 9
+
+/* pow(10.0, {18, 30, 42, 54}/20.0) /(float)(1<<SF_MEAN_ENER_LG10) */
+static const FIXP_DBL pow_10_mean_energy[4] = {0x01fc5ebd, 0x07e7db92,
+ 0x1f791f65, 0x7d4bfba3};
+
+static void D_gain2_plus(int index, FIXP_COD code[], FIXP_SGL *gain_pit,
+ FIXP_DBL *gain_code, int mean_ener_bits, int bfi,
+ FIXP_SGL *past_gpit, FIXP_DBL *past_gcode,
+ FIXP_DBL *pEner_code, int *pEner_code_e) {
+ FIXP_DBL Ltmp;
+ FIXP_DBL gcode0, gcode_inov;
+ INT gcode0_e, gcode_inov_e;
+ int i;
+
+ FIXP_DBL ener_code;
+ INT ener_code_e;
+
+ /* ener_code = sum(code[]^2) */
+ ener_code = FIXP_DBL(0);
+ for (i = 0; i < L_SUBFR; i++) {
+ ener_code += fPow2Div2(code[i]);
+ }
+
+ ener_code_e = fMax(fNorm(ener_code) - 1, 0);
+ ener_code <<= ener_code_e;
+ ener_code_e = 2 * SF_CODE + 1 - ener_code_e;
+
+ /* export energy of code for calc_period_factor() */
+ *pEner_code = ener_code;
+ *pEner_code_e = ener_code_e;
+
+ ener_code += scaleValue(FL2FXCONST_DBL(0.01f), -ener_code_e);
+
+ /* ener_code *= 1/L_SUBFR, and make exponent even (because of square root
+ * below). */
+ if (ener_code_e & 1) {
+ ener_code_e -= 5;
+ ener_code >>= 1;
+ } else {
+ ener_code_e -= 6;
+ }
+ gcode_inov = invSqrtNorm2(ener_code, &gcode0_e);
+ gcode_inov_e = gcode0_e - (ener_code_e >> 1);
+
+ if (bfi) {
+ FIXP_DBL tgcode;
+ FIXP_SGL tgpit;
+
+ tgpit = *past_gpit;
+
+ if (tgpit > FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P))) {
+ tgpit = FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P));
+ } else if (tgpit < FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P))) {
+ tgpit = FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P));
+ }
+ *gain_pit = tgpit;
+ tgpit = FX_DBL2FX_SGL(fMult(tgpit, FL2FXCONST_DBL(0.95f)));
+ *past_gpit = tgpit;
+
+ tgpit = FL2FXCONST_SGL(1.4f / (1 << SF_GAIN_P)) - tgpit;
+ tgcode = fMult(*past_gcode, tgpit) << SF_GAIN_P;
+ *gain_code = scaleValue(fMult(tgcode, gcode_inov), gcode_inov_e);
+ *past_gcode = tgcode;
+
+ return;
+ }
+
+ /*-------------- Decode gains ---------------*/
+ /*
+ gcode0 = pow(10.0, (float)mean_ener/20.0);
+ gcode0 = gcode0 / sqrt(ener_code/L_SUBFR);
+ */
+ gcode0 = pow_10_mean_energy[mean_ener_bits];
+ gcode0 = fMultDiv2(gcode0, gcode_inov);
+ gcode0_e = gcode0_e + SF_MEAN_ENER_LG10 - (ener_code_e >> 1) + 1;
+
+ i = index << 1;
+ *gain_pit = fdk_t_qua_gain7b[i]; /* adaptive codebook gain */
+ /* t_qua_gain[ind2p1] : fixed codebook gain correction factor */
+ Ltmp = fMult(fdk_t_qua_gain7b[i + 1], gcode0);
+ *gain_code = scaleValue(Ltmp, gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B);
+
+ /* update bad frame handler */
+ *past_gpit = *gain_pit;
+
+ /*--------------------------------------------------------
+ past_gcode = gain_code/gcode_inov
+ --------------------------------------------------------*/
+ {
+ FIXP_DBL gcode_m;
+ INT gcode_e;
+
+ gcode_m = fDivNormHighPrec(Ltmp, gcode_inov, &gcode_e);
+ gcode_e += (gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B) - (gcode_inov_e);
+ *past_gcode = scaleValue(gcode_m, gcode_e);
+ }
+}
+
+/**
+ * \brief Calculate period/voicing factor r_v
+ * \param[in] exc pitch excitation.
+ * \param[in] gain_pit gain of pitch g_p.
+ * \param[in] gain_code gain of code g_c.
+ * \param[in] gain_code_e exponent of gain of code.
+ * \param[in] ener_code unbiased innovative code vector energy.
+ * \param[in] ener_code_e exponent of unbiased innovative code vector energy.
+ * \return period/voice factor r_v (-1=unvoiced to 1=voiced), exponent SF_PFAC.
+ */
+static FIXP_DBL calc_period_factor(FIXP_DBL exc[], FIXP_SGL gain_pit,
+ FIXP_DBL gain_code, FIXP_DBL ener_code,
+ int ener_code_e) {
+ int ener_exc_e, L_tmp_e, s = 0;
+ FIXP_DBL ener_exc, L_tmp;
+ FIXP_DBL period_fac;
+
+ /* energy of pitch excitation */
+ ener_exc = (FIXP_DBL)0;
+ for (int i = 0; i < L_SUBFR; i++) {
+ ener_exc += fPow2Div2(exc[i]) >> s;
+ if (ener_exc >= FL2FXCONST_DBL(0.5f)) {
+ ener_exc >>= 1;
+ s++;
+ }
+ }
+
+ ener_exc_e = fNorm(ener_exc);
+ ener_exc = fMult(ener_exc << ener_exc_e, fPow2(gain_pit));
+ if (ener_exc != (FIXP_DBL)0) {
+ ener_exc_e = 2 * SF_EXC + 1 + 2 * SF_GAIN_P - ener_exc_e + s;
+ } else {
+ ener_exc_e = 0;
+ }
+
+ /* energy of innovative code excitation */
+ /* L_tmp = ener_code * gain_code*gain_code; */
+ L_tmp_e = fNorm(gain_code);
+ L_tmp = fPow2(gain_code << L_tmp_e);
+ L_tmp = fMult(ener_code, L_tmp);
+ L_tmp_e = 2 * SF_GAIN_C + ener_code_e - 2 * L_tmp_e;
+
+ /* Find common exponent */
+ {
+ FIXP_DBL num, den;
+ int exp_diff;
+
+ exp_diff = ener_exc_e - L_tmp_e;
+ if (exp_diff >= 0) {
+ ener_exc >>= 1;
+ if (exp_diff <= DFRACT_BITS - 2) {
+ L_tmp >>= exp_diff + 1;
+ } else {
+ L_tmp = (FIXP_DBL)0;
+ }
+ den = ener_exc + L_tmp;
+ if (ener_exc_e < DFRACT_BITS - 1) {
+ den += scaleValue(FL2FXCONST_DBL(0.01f), -ener_exc_e - 1);
+ }
+ } else {
+ if (exp_diff >= -(DFRACT_BITS - 2)) {
+ ener_exc >>= 1 - exp_diff;
+ } else {
+ ener_exc = (FIXP_DBL)0;
+ }
+ L_tmp >>= 1;
+ den = ener_exc + L_tmp;
+ if (L_tmp_e < DFRACT_BITS - 1) {
+ den += scaleValue(FL2FXCONST_DBL(0.01f), -L_tmp_e - 1);
+ }
+ }
+ num = (ener_exc - L_tmp);
+ num >>= SF_PFAC;
+
+ if (den > (FIXP_DBL)0) {
+ if (ener_exc > L_tmp) {
+ period_fac = schur_div(num, den, 16);
+ } else {
+ period_fac = -schur_div(-num, den, 16);
+ }
+ } else {
+ period_fac = (FIXP_DBL)MAXVAL_DBL;
+ }
+ }
+
+ /* exponent = SF_PFAC */
+ return period_fac;
+}
+
+/*------------------------------------------------------------*
+ * noise enhancer *
+ * ~~~~~~~~~~~~~~ *
+ * - Enhance excitation on noise. (modify gain of code) *
+ * If signal is noisy and LPC filter is stable, move gain *
+ * of code 1.5 dB toward gain of code threshold. *
+ * This decrease by 3 dB noise energy variation. *
+ *------------------------------------------------------------*/
+/**
+ * \brief Enhance excitation on noise. (modify gain of code)
+ * \param[in] gain_code Quantized codebook gain g_c, exponent = SF_GAIN_C.
+ * \param[in] period_fac periodicity factor, exponent = SF_PFAC.
+ * \param[in] stab_fac stability factor, exponent = SF_STAB.
+ * \param[in,out] p_gc_threshold modified gain of previous subframe.
+ * \return gain_code smoothed gain of code g_sc, exponent = SF_GAIN_C.
+ */
+static FIXP_DBL
+noise_enhancer(/* (o) : smoothed gain g_sc SF_GAIN_C */
+ FIXP_DBL gain_code, /* (i) : Quantized codebook gain SF_GAIN_C */
+ FIXP_DBL period_fac, /* (i) : periodicity factor (-1=unvoiced to
+ 1=voiced), SF_PFAC */
+ FIXP_SGL stab_fac, /* (i) : stability factor (0 <= ... < 1.0)
+ SF_STAB */
+ FIXP_DBL
+ *p_gc_threshold) /* (io): gain of code threshold SF_GAIN_C */
+{
+ FIXP_DBL fac, L_tmp, gc_thres;
+
+ gc_thres = *p_gc_threshold;
+
+ L_tmp = gain_code;
+ if (L_tmp < gc_thres) {
+ L_tmp += fMultDiv2(gain_code,
+ FL2FXCONST_SGL(2.0 * 0.19f)); /* +1.5dB => *(1.0+0.19) */
+ if (L_tmp > gc_thres) {
+ L_tmp = gc_thres;
+ }
+ } else {
+ L_tmp = fMult(gain_code,
+ FL2FXCONST_SGL(1.0f / 1.19f)); /* -1.5dB => *10^(-1.5/20) */
+ if (L_tmp < gc_thres) {
+ L_tmp = gc_thres;
+ }
+ }
+ *p_gc_threshold = L_tmp;
+
+ /* voicing factor lambda = 0.5*(1-period_fac) */
+ /* gain smoothing factor S_m = lambda*stab_fac (=fac)
+ = 0.5(stab_fac - stab_fac * period_fac) */
+ fac = (FX_SGL2FX_DBL(stab_fac) >> (SF_PFAC + 1)) -
+ fMultDiv2(stab_fac, period_fac);
+ /* fac_e = SF_PFAC + SF_STAB */
+ FDK_ASSERT(fac >= (FIXP_DBL)0);
+
+ /* gain_code = (float)((fac*tmp) + ((1.0-fac)*gain_code)); */
+ gain_code = fMult(fac, L_tmp) -
+ fMult(FL2FXCONST_DBL(-1.0f / (1 << (SF_PFAC + SF_STAB))) + fac,
+ gain_code);
+ gain_code <<= (SF_PFAC + SF_STAB);
+
+ return gain_code;
+}
+
+/**
+ * \brief Update adaptive codebook u'(n) (exc)
+ * Enhance pitch of c(n) and build post-processed excitation u(n) (exc2)
+ * \param[in] code innovative codevector c(n), exponent = SF_CODE.
+ * \param[in,out] exc filtered adaptive codebook v(n), exponent = SF_EXC.
+ * \param[in] gain_pit adaptive codebook gain, exponent = SF_GAIN_P.
+ * \param[in] gain_code innovative codebook gain g_c, exponent = SF_GAIN_C.
+ * \param[in] gain_code_smoothed smoothed innov. codebook gain g_sc, exponent =
+ * SF_GAIN_C.
+ * \param[in] period_fac periodicity factor r_v, exponent = SF_PFAC.
+ * \param[out] exc2 post-processed excitation u(n), exponent = SF_EXC.
+ */
+void BuildAdaptiveExcitation(
+ FIXP_COD code[], /* (i) : algebraic codevector c(n) Q9 */
+ FIXP_DBL exc[], /* (io): filtered adaptive codebook v(n) Q15 */
+ FIXP_SGL gain_pit, /* (i) : adaptive codebook gain g_p Q14 */
+ FIXP_DBL gain_code, /* (i) : innovative codebook gain g_c Q16 */
+ FIXP_DBL gain_code_smoothed, /* (i) : smoothed innov. codebook gain g_sc
+ Q16 */
+ FIXP_DBL period_fac, /* (i) : periodicity factor r_v Q15 */
+ FIXP_DBL exc2[] /* (o) : post-processed excitation u(n) Q15 */
+) {
+/* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory!
+ If exc2[i] is written, code[i] will be destroyed!
+*/
+#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC)
+
+ int i;
+ FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth;
+
+ FIXP_COD code_i;
+ FIXP_DBL cpe_code_smooth, cpe_code_smooth_prev;
+
+ /* cpe = (1+r_v)/8 * 2 ; ( SF = -1) */
+ cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f);
+
+ /* u'(n) */
+ tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); /* v(0)*g_p */
+ *exc++ = tmp + (fMultDiv2(code[0], gain_code) << SF);
+
+ /* u(n) */
+ code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed)
+ << SF; /* c(0) * g_sc */
+ code_i = *code++;
+ code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; /* c(1) * g_sc */
+ tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */
+ cpe_code_smooth = fMultDiv2(cpe, code_smooth);
+ *exc2++ = tmp - cpe_code_smooth;
+ cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev);
+
+ i = L_SUBFR - 2;
+ do /* ARM926: 22 cycles per iteration */
+ {
+ /* u'(n) */
+ tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
+ *exc++ = tmp + (fMultDiv2(code_i, gain_code) << SF);
+ /* u(n) */
+ tmp += code_smooth; /* += g_sc * c(i) */
+ tmp -= cpe_code_smooth_prev;
+ cpe_code_smooth_prev = cpe_code_smooth;
+ code_i = *code++;
+ code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;
+ cpe_code_smooth = fMultDiv2(cpe, code_smooth);
+ *exc2++ = tmp - cpe_code_smooth; /* tmp - c_pe * g_sc * c(i+1) */
+ } while (--i != 0);
+
+ /* u'(n) */
+ tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
+ *exc = tmp + (fMultDiv2(code_i, gain_code) << SF);
+ /* u(n) */
+ tmp += code_smooth;
+ tmp -= cpe_code_smooth_prev;
+ *exc2++ = tmp;
+
+ return;
+}
+
+/**
+ * \brief Interpolate LPC vector in LSP domain for current subframe and convert
+ * to LP domain
+ * \param[in] lsp_old LPC vector (LSP domain) corresponding to the beginning of
+ * current ACELP frame.
+ * \param[in] lsp_new LPC vector (LSP domain) corresponding to the end of
+ * current ACELP frame.
+ * \param[in] subfr_nr number of current ACELP subframe 0..3.
+ * \param[in] nb_subfr total number of ACELP subframes in this frame.
+ * \param[out] A LP filter coefficients for current ACELP subframe, exponent =
+ * SF_A_COEFFS.
+ */
+/* static */
+void int_lpc_acelp(
+ const FIXP_LPC lsp_old[], /* input : LSPs from past frame */
+ const FIXP_LPC lsp_new[], /* input : LSPs from present frame */
+ int subfr_nr, int nb_subfr,
+ FIXP_LPC
+ A[], /* output: interpolated LP coefficients for current subframe */
+ INT *A_exp) {
+ int i;
+ FIXP_LPC lsp_interpol[M_LP_FILTER_ORDER];
+ FIXP_SGL fac_old, fac_new;
+
+ FDK_ASSERT((nb_subfr == 3) || (nb_subfr == 4));
+
+ fac_old = lsp_interpol_factor[nb_subfr & 0x1][(nb_subfr - 1) - subfr_nr];
+ fac_new = lsp_interpol_factor[nb_subfr & 0x1][subfr_nr];
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp_interpol[i] = FX_DBL2FX_LPC(
+ (fMultDiv2(lsp_old[i], fac_old) + fMultDiv2(lsp_new[i], fac_new)) << 1);
+ }
+
+ E_LPC_f_lsp_a_conversion(lsp_interpol, A, A_exp);
+
+ return;
+}
+
+/**
+ * \brief Perform LP synthesis by filtering the post-processed excitation u(n)
+ * through the LP synthesis filter 1/A(z)
+ * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS.
+ * \param[in] length length of input/output signal.
+ * \param[in] x post-processed excitation u(n).
+ * \param[in,out] y LP synthesis signal and filter memory
+ * y[-M_LP_FILTER_ORDER..-1].
+ */
+
+/* static */
+void Syn_filt(const FIXP_LPC a[], /* (i) : a[m] prediction coefficients Q12 */
+ const INT a_exp,
+ INT length, /* (i) : length of input/output signal (64|128) */
+ FIXP_DBL x[], /* (i) : input signal Qx */
+ FIXP_DBL y[] /* (i/o) : filter states / output signal Qx-s*/
+) {
+ int i, j;
+ FIXP_DBL L_tmp;
+
+ for (i = 0; i < length; i++) {
+ L_tmp = (FIXP_DBL)0;
+
+ for (j = 0; j < M_LP_FILTER_ORDER; j++) {
+ L_tmp -= fMultDiv2(a[j], y[i - (j + 1)]) >> (LP_FILTER_SCALE - 1);
+ }
+
+ L_tmp = scaleValue(L_tmp, a_exp + LP_FILTER_SCALE);
+ y[i] = fAddSaturate(L_tmp, x[i]);
+ }
+
+ return;
+}
+
+/**
+ * \brief Calculate de-emphasis 1/(1 - mu z^-1) on input signal.
+ * \param[in] x input signal.
+ * \param[out] y output signal.
+ * \param[in] L length of signal.
+ * \param[in,out] mem memory (signal[-1]).
+ */
+/* static */
+void Deemph(FIXP_DBL *x, FIXP_DBL *y, int L, FIXP_DBL *mem) {
+ int i;
+ FIXP_DBL yi = *mem;
+
+ for (i = 0; i < L; i++) {
+ FIXP_DBL xi = x[i] >> 1;
+ xi = fMultAddDiv2(xi, PREEMPH_FAC, yi);
+ yi = SATURATE_LEFT_SHIFT(xi, 1, 32);
+ y[i] = yi;
+ }
+ *mem = yi;
+ return;
+}
+
+/**
+ * \brief Compute the LP residual by filtering the input speech through the
+ * analysis filter A(z).
+ * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS
+ * \param[in] x input signal (note that values x[-m..-1] are needed), exponent =
+ * SF_SYNTH
+ * \param[out] y output signal (residual), exponent = SF_EXC
+ * \param[in] l length of filtering
+ */
+/* static */
+void E_UTIL_residu(const FIXP_LPC *a, const INT a_exp, FIXP_DBL *x, FIXP_DBL *y,
+ INT l) {
+ FIXP_DBL s;
+ INT i, j;
+
+ /* (note that values x[-m..-1] are needed) */
+ for (i = 0; i < l; i++) {
+ s = (FIXP_DBL)0;
+
+ for (j = 0; j < M_LP_FILTER_ORDER; j++) {
+ s += fMultDiv2(a[j], x[i - j - 1]) >> (LP_FILTER_SCALE - 1);
+ }
+
+ s = scaleValue(s, a_exp + LP_FILTER_SCALE);
+ y[i] = fAddSaturate(s, x[i]);
+ }
+
+ return;
+}
+
+/* use to map subfr number to number of bits used for acb_index */
+static const UCHAR num_acb_idx_bits_table[2][NB_SUBFR] = {
+ {9, 6, 9, 6}, /* coreCoderFrameLength == 1024 */
+ {9, 6, 6, 0} /* coreCoderFrameLength == 768 */
+};
+
+static int DecodePitchLag(HANDLE_FDK_BITSTREAM hBs,
+ const UCHAR num_acb_idx_bits,
+ const int PIT_MIN, /* TMIN */
+ const int PIT_FR2, /* TFR2 */
+ const int PIT_FR1, /* TFR1 */
+ const int PIT_MAX, /* TMAX */
+ int *pT0, int *pT0_frac, int *pT0_min, int *pT0_max) {
+ int acb_idx;
+ int error = 0;
+ int T0, T0_frac;
+
+ FDK_ASSERT((num_acb_idx_bits == 9) || (num_acb_idx_bits == 6));
+
+ acb_idx = FDKreadBits(hBs, num_acb_idx_bits);
+
+ if (num_acb_idx_bits == 6) {
+ /* When the pitch value is encoded on 6 bits, a pitch resolution of 1/4 is
+ always used in the range [T1-8, T1+7.75], where T1 is nearest integer to
+ the fractional pitch lag of the previous subframe.
+ */
+ T0 = *pT0_min + acb_idx / 4;
+ T0_frac = acb_idx & 0x3;
+ } else { /* num_acb_idx_bits == 9 */
+ /* When the pitch value is encoded on 9 bits, a fractional pitch delay is
+ used with resolutions 0.25 in the range [TMIN, TFR2-0.25], resolutions
+ 0.5 in the range [TFR2, TFR1-0.5], and integers only in the range [TFR1,
+ TMAX]. NOTE: for small sampling rates TMAX can get smaller than TFR1.
+ */
+ int T0_min, T0_max;
+
+ if (acb_idx < (PIT_FR2 - PIT_MIN) * 4) {
+ /* first interval with 0.25 pitch resolution */
+ T0 = PIT_MIN + (acb_idx / 4);
+ T0_frac = acb_idx & 0x3;
+ } else if (acb_idx < ((PIT_FR2 - PIT_MIN) * 4 + (PIT_FR1 - PIT_FR2) * 2)) {
+ /* second interval with 0.5 pitch resolution */
+ acb_idx -= (PIT_FR2 - PIT_MIN) * 4;
+ T0 = PIT_FR2 + (acb_idx / 2);
+ T0_frac = (acb_idx & 0x1) * 2;
+ } else {
+ /* third interval with 1.0 pitch resolution */
+ T0 = acb_idx + PIT_FR1 - ((PIT_FR2 - PIT_MIN) * 4) -
+ ((PIT_FR1 - PIT_FR2) * 2);
+ T0_frac = 0;
+ }
+ /* find T0_min and T0_max for subframe 1 or 3 */
+ T0_min = T0 - 8;
+ if (T0_min < PIT_MIN) {
+ T0_min = PIT_MIN;
+ }
+ T0_max = T0_min + 15;
+ if (T0_max > PIT_MAX) {
+ T0_max = PIT_MAX;
+ T0_min = T0_max - 15;
+ }
+ *pT0_min = T0_min;
+ *pT0_max = T0_max;
+ }
+ *pT0 = T0;
+ *pT0_frac = T0_frac;
+
+ return error;
+}
+static void ConcealPitchLag(CAcelpStaticMem *acelp_mem, const int PIT_MAX,
+ int *pT0, int *pT0_frac) {
+ USHORT *pold_T0 = &acelp_mem->old_T0;
+ UCHAR *pold_T0_frac = &acelp_mem->old_T0_frac;
+
+ if ((int)*pold_T0 >= PIT_MAX) {
+ *pold_T0 = (UCHAR)(PIT_MAX - 5);
+ }
+ *pT0 = (int)*pold_T0;
+ *pT0_frac = (int)*pold_T0_frac;
+}
+
+static UCHAR tab_coremode2nbits[8] = {20, 28, 36, 44, 52, 64, 12, 16};
+
+static int MapCoreMode2NBits(int core_mode) {
+ return (int)tab_coremode2nbits[core_mode];
+}
+
+void CLpd_AcelpDecode(CAcelpStaticMem *acelp_mem, INT i_offset,
+ const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
+ const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
+ FIXP_SGL stab_fac, CAcelpChannelData *pAcelpData,
+ INT numLostSubframes, int lastLpcLost, int frameCnt,
+ FIXP_DBL synth[], int pT[], FIXP_DBL *pit_gain,
+ INT coreCoderFrameLength) {
+ int i_subfr, subfr_nr, l_div, T;
+ int T0 = -1, T0_frac = -1; /* mark invalid */
+
+ int pit_gain_index = 0;
+
+ const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset); /* maximum pitch lag */
+
+ FIXP_COD *code;
+ FIXP_DBL *exc2;
+ FIXP_DBL *syn;
+ FIXP_DBL *exc;
+ FIXP_LPC A[M_LP_FILTER_ORDER];
+ INT A_exp;
+
+ FIXP_DBL period_fac;
+ FIXP_SGL gain_pit;
+ FIXP_DBL gain_code, gain_code_smooth, Ener_code;
+ int Ener_code_e;
+ int n;
+ int bfi = (numLostSubframes > 0) ? 1 : 0;
+
+ C_ALLOC_SCRATCH_START(
+ exc_buf, FIXP_DBL,
+ PIT_MAX_MAX + L_INTERPOL + L_DIV + 1); /* 411 + 17 + 256 + 1 = 685 */
+ C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
+ M_LP_FILTER_ORDER + L_DIV); /* 16 + 256 = 272 */
+ /* use same memory for code[L_SUBFR] and exc2[L_SUBFR] */
+ C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_SUBFR); /* 64 */
+ /* make sure they don't overlap if they are accessed alternatingly in
+ * BuildAdaptiveExcitation() */
+#if (COD_BITS == FRACT_BITS)
+ code = (FIXP_COD *)(tmp_buf + L_SUBFR / 2);
+#elif (COD_BITS == DFRACT_BITS)
+ code = (FIXP_COD *)tmp_buf;
+#endif
+ exc2 = (FIXP_DBL *)tmp_buf;
+
+ syn = syn_buf + M_LP_FILTER_ORDER;
+ exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;
+
+ FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
+ M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
+ FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
+ (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
+
+ FDKmemclear(exc_buf + (PIT_MAX_MAX + L_INTERPOL),
+ (L_DIV + 1) * sizeof(FIXP_DBL));
+
+ l_div = coreCoderFrameLength / NB_DIV;
+
+ for (i_subfr = 0, subfr_nr = 0; i_subfr < l_div;
+ i_subfr += L_SUBFR, subfr_nr++) {
+ /*-------------------------------------------------*
+ * - Decode pitch lag (T0 and T0_frac) *
+ *-------------------------------------------------*/
+ if (bfi) {
+ ConcealPitchLag(acelp_mem, PIT_MAX, &T0, &T0_frac);
+ } else {
+ T0 = (int)pAcelpData->T0[subfr_nr];
+ T0_frac = (int)pAcelpData->T0_frac[subfr_nr];
+ }
+
+ /*-------------------------------------------------*
+ * - Find the pitch gain, the interpolation filter *
+ * and the adaptive codebook vector. *
+ *-------------------------------------------------*/
+ Pred_lt4(&exc[i_subfr], T0, T0_frac);
+
+ if ((!bfi && pAcelpData->ltp_filtering_flag[subfr_nr] == 0) ||
+ (bfi && numLostSubframes == 1 && stab_fac < FL2FXCONST_SGL(0.25f))) {
+ /* find pitch excitation with lp filter: v'(n) => v(n) */
+ Pred_lt4_postfilter(&exc[i_subfr]);
+ }
+
+ /*-------------------------------------------------------*
+ * - Decode innovative codebook. *
+ * - Add the fixed-gain pitch contribution to code[]. *
+ *-------------------------------------------------------*/
+ if (bfi) {
+ for (n = 0; n < L_SUBFR; n++) {
+ code[n] =
+ FX_SGL2FX_COD((FIXP_SGL)E_UTIL_random(&acelp_mem->seed_ace)) >> 4;
+ }
+ } else {
+ int nbits = MapCoreMode2NBits((int)pAcelpData->acelp_core_mode);
+ D_ACELP_decode_4t64(pAcelpData->icb_index[subfr_nr], nbits, &code[0]);
+ }
+
+ T = T0;
+ if (T0_frac > 2) {
+ T += 1;
+ }
+
+ Preemph_code(code);
+ Pit_shrp(code, T);
+
+ /* Output pitch lag for bass post-filter */
+ if (T > PIT_MAX) {
+ pT[subfr_nr] = PIT_MAX;
+ } else {
+ pT[subfr_nr] = T;
+ }
+ D_gain2_plus(
+ pAcelpData->gains[subfr_nr],
+ code, /* (i) : Innovative code vector, exponent = SF_CODE */
+ &gain_pit, /* (o) : Quantized pitch gain, exponent = SF_GAIN_P */
+ &gain_code, /* (o) : Quantized codebook gain */
+ pAcelpData
+ ->mean_energy, /* (i) : mean_ener defined in open-loop (2 bits) */
+ bfi, &acelp_mem->past_gpit, &acelp_mem->past_gcode,
+ &Ener_code, /* (o) : Innovative code vector energy */
+ &Ener_code_e); /* (o) : Innovative code vector energy exponent */
+
+ pit_gain[pit_gain_index++] = FX_SGL2FX_DBL(gain_pit);
+
+ /* calc periodicity factor r_v */
+ period_fac =
+ calc_period_factor(/* (o) : factor (-1=unvoiced to 1=voiced) */
+ &exc[i_subfr], /* (i) : pitch excitation, exponent =
+ SF_EXC */
+ gain_pit, /* (i) : gain of pitch, exponent =
+ SF_GAIN_P */
+ gain_code, /* (i) : gain of code */
+ Ener_code, /* (i) : Energy of code[] */
+ Ener_code_e); /* (i) : Exponent of energy of code[]
+ */
+
+ if (lastLpcLost && frameCnt == 0) {
+ if (gain_pit > FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P))) {
+ gain_pit = FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P));
+ }
+ }
+
+ gain_code_smooth =
+ noise_enhancer(/* (o) : smoothed gain g_sc exponent = SF_GAIN_C */
+ gain_code, /* (i) : Quantized codebook gain */
+ period_fac, /* (i) : periodicity factor (-1=unvoiced to
+ 1=voiced) */
+ stab_fac, /* (i) : stability factor (0 <= ... < 1),
+ exponent = 1 */
+ &acelp_mem->gc_threshold);
+
+ /* Compute adaptive codebook update u'(n), pitch enhancement c'(n) and
+ * post-processed excitation u(n). */
+ BuildAdaptiveExcitation(code, exc + i_subfr, gain_pit, gain_code,
+ gain_code_smooth, period_fac, exc2);
+
+ /* Interpolate filter coeffs for current subframe in lsp domain and convert
+ * to LP domain */
+ int_lpc_acelp(lsp_old, /* input : LSPs from past frame */
+ lsp_new, /* input : LSPs from present frame */
+ subfr_nr, /* input : ACELP subframe index */
+ coreCoderFrameLength / L_DIV,
+ A, /* output: LP coefficients of this subframe */
+ &A_exp);
+
+ Syn_filt(A, /* (i) : a[m] prediction coefficients */
+ A_exp, L_SUBFR, /* (i) : length */
+ exc2, /* (i) : input signal */
+ &syn[i_subfr] /* (i/o) : filter states / output signal */
+ );
+
+ } /* end of subframe loop */
+
+ /* update pitch value for bfi procedure */
+ acelp_mem->old_T0_frac = T0_frac;
+ acelp_mem->old_T0 = T0;
+
+ /* save old excitation and old synthesis memory for next ACELP frame */
+ FDKmemcpy(acelp_mem->old_exc_mem, exc + l_div - (PIT_MAX_MAX + L_INTERPOL),
+ sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
+ FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + l_div,
+ sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);
+
+ Deemph(syn, synth, l_div,
+ &acelp_mem->de_emph_mem); /* ref soft: mem = synth[-1] */
+
+ scaleValues(synth, l_div, -ACELP_OUTSCALE);
+ acelp_mem->deemph_mem_wsyn = acelp_mem->de_emph_mem;
+
+ C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_SUBFR);
+ C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
+ C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV + 1);
+ return;
+}
+
+void CLpd_AcelpReset(CAcelpStaticMem *acelp) {
+ acelp->gc_threshold = (FIXP_DBL)0;
+
+ acelp->past_gpit = (FIXP_SGL)0;
+ acelp->past_gcode = (FIXP_DBL)0;
+ acelp->old_T0 = 64;
+ acelp->old_T0_frac = 0;
+ acelp->deemph_mem_wsyn = (FIXP_DBL)0;
+ acelp->wsyn_rms = (FIXP_DBL)0;
+ acelp->seed_ace = 0;
+}
+
+/* TCX time domain concealment */
+/* Compare to figure 13a on page 54 in 3GPP TS 26.290 */
+void CLpd_TcxTDConceal(CAcelpStaticMem *acelp_mem, SHORT *pitch,
+ const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
+ const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
+ const FIXP_SGL stab_fac, INT nLostSf, FIXP_DBL synth[],
+ INT coreCoderFrameLength, UCHAR last_tcx_noise_factor) {
+ /* repeat past excitation with pitch from previous decoded TCX frame */
+ C_ALLOC_SCRATCH_START(
+ exc_buf, FIXP_DBL,
+ PIT_MAX_MAX + L_INTERPOL + L_DIV); /* 411 + 17 + 256 + 1 = */
+ C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
+ M_LP_FILTER_ORDER + L_DIV); /* 256 + 16 = */
+ /* += */
+ FIXP_DBL ns_buf[L_DIV + 1];
+ FIXP_DBL *syn = syn_buf + M_LP_FILTER_ORDER;
+ FIXP_DBL *exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;
+ FIXP_DBL *ns = ns_buf + 1;
+ FIXP_DBL tmp, fact_exc;
+ INT T = fMin(*pitch, (SHORT)PIT_MAX_MAX);
+ int i, i_subfr, subfr_nr;
+ int lDiv = coreCoderFrameLength / NB_DIV;
+
+ FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
+ M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
+ FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
+ (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
+
+ /* if we lost all packets (i.e. 1 packet of TCX-20 ms, 2 packets of
+ the TCX-40 ms or 4 packets of the TCX-80ms), we lost the whole
+ coded frame extrapolation strategy: repeat lost excitation and
+ use extrapolated LSFs */
+
+ /* AMR-WB+ like TCX TD concealment */
+
+ /* number of lost frame cmpt */
+ if (nLostSf < 2) {
+ fact_exc = FL2FXCONST_DBL(0.8f);
+ } else {
+ fact_exc = FL2FXCONST_DBL(0.4f);
+ }
+
+ /* repeat past excitation */
+ for (i = 0; i < lDiv; i++) {
+ exc[i] = fMult(fact_exc, exc[i - T]);
+ }
+
+ tmp = fMult(fact_exc, acelp_mem->wsyn_rms);
+ acelp_mem->wsyn_rms = tmp;
+
+ /* init deemph_mem_wsyn */
+ acelp_mem->deemph_mem_wsyn = exc[-1];
+
+ ns[-1] = acelp_mem->deemph_mem_wsyn;
+
+ for (i_subfr = 0, subfr_nr = 0; i_subfr < lDiv;
+ i_subfr += L_SUBFR, subfr_nr++) {
+ FIXP_DBL tRes[L_SUBFR];
+ FIXP_LPC A[M_LP_FILTER_ORDER];
+ INT A_exp;
+
+ /* interpolate LPC coefficients */
+ int_lpc_acelp(lsp_old, lsp_new, subfr_nr, lDiv / L_SUBFR, A, &A_exp);
+
+ Syn_filt(A, /* (i) : a[m] prediction coefficients */
+ A_exp, L_SUBFR, /* (i) : length */
+ &exc[i_subfr], /* (i) : input signal */
+ &syn[i_subfr] /* (i/o) : filter states / output signal */
+ );
+
+ E_LPC_a_weight(
+ A, A,
+ M_LP_FILTER_ORDER); /* overwrite A as it is not needed any longer */
+
+ E_UTIL_residu(A, A_exp, &syn[i_subfr], tRes, L_SUBFR);
+
+ Deemph(tRes, &ns[i_subfr], L_SUBFR, &acelp_mem->deemph_mem_wsyn);
+
+ /* Amplitude limiter (saturate at wsyn_rms) */
+ for (i = i_subfr; i < i_subfr + L_SUBFR; i++) {
+ if (ns[i] > tmp) {
+ ns[i] = tmp;
+ } else {
+ if (ns[i] < -tmp) {
+ ns[i] = -tmp;
+ }
+ }
+ }
+
+ E_UTIL_preemph(&ns[i_subfr], tRes, L_SUBFR);
+
+ Syn_filt(A, /* (i) : a[m] prediction coefficients */
+ A_exp, L_SUBFR, /* (i) : length */
+ tRes, /* (i) : input signal */
+ &syn[i_subfr] /* (i/o) : filter states / output signal */
+ );
+
+ FDKmemmove(&synth[i_subfr], &syn[i_subfr], L_SUBFR * sizeof(FIXP_DBL));
+ }
+
+ /* save old excitation and old synthesis memory for next ACELP frame */
+ FDKmemcpy(acelp_mem->old_exc_mem, exc + lDiv - (PIT_MAX_MAX + L_INTERPOL),
+ sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
+ FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + lDiv,
+ sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);
+ acelp_mem->de_emph_mem = acelp_mem->deemph_mem_wsyn;
+
+ C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
+ C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV);
+}
+
+void Acelp_PreProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
+ INT *old_T_pf, FIXP_DBL *pit_gain,
+ FIXP_DBL *old_gain_pf, INT samplingRate, INT *i_offset,
+ INT coreCoderFrameLength, INT synSfd,
+ INT nbSubfrSuperfr) {
+ int n;
+
+ /* init beginning of synth_buf with old synthesis from previous frame */
+ FDKmemcpy(synth_buf, old_synth, sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));
+
+ /* calculate pitch lag offset for ACELP decoder */
+ *i_offset =
+ (samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
+ PIT_MIN_12k8;
+
+ /* for bass postfilter */
+ for (n = 0; n < synSfd; n++) {
+ pitch[n] = old_T_pf[n];
+ pit_gain[n] = old_gain_pf[n];
+ }
+ for (n = 0; n < nbSubfrSuperfr; n++) {
+ pitch[n + synSfd] = L_SUBFR;
+ pit_gain[n + synSfd] = (FIXP_DBL)0;
+ }
+}
+
+void Acelp_PostProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
+ INT *old_T_pf, INT coreCoderFrameLength, INT synSfd,
+ INT nbSubfrSuperfr) {
+ int n;
+
+ /* store last part of synth_buf (which is not handled by the IMDCT overlap)
+ * for next frame */
+ FDKmemcpy(old_synth, synth_buf + coreCoderFrameLength,
+ sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));
+
+ /* for bass postfilter */
+ for (n = 0; n < synSfd; n++) {
+ old_T_pf[n] = pitch[nbSubfrSuperfr + n];
+ }
+}
+
+#define L_FAC_ZIR (LFAC)
+
+void CLpd_Acelp_Zir(const FIXP_LPC A[], const INT A_exp,
+ CAcelpStaticMem *acelp_mem, const INT length,
+ FIXP_DBL zir[], int doDeemph) {
+ C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
+ FDK_ASSERT(length <= L_FAC_ZIR);
+
+ FDKmemcpy(tmp_buf, acelp_mem->old_syn_mem,
+ M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
+ FDKmemset(tmp_buf + M_LP_FILTER_ORDER, 0, L_FAC_ZIR * sizeof(FIXP_DBL));
+
+ Syn_filt(A, A_exp, length, &tmp_buf[M_LP_FILTER_ORDER],
+ &tmp_buf[M_LP_FILTER_ORDER]);
+ if (!doDeemph) {
+ /* if last lpd mode was TD concealment, then bypass deemph */
+ FDKmemcpy(zir, tmp_buf, length * sizeof(*zir));
+ } else {
+ Deemph(&tmp_buf[M_LP_FILTER_ORDER], &zir[0], length,
+ &acelp_mem->de_emph_mem);
+ scaleValues(zir, length, -ACELP_OUTSCALE);
+ }
+ C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
+}
+
+void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode,
+ UCHAR last_last_lpd_mode,
+ const FIXP_LPC *A_new, const INT A_new_exp,
+ const FIXP_LPC *A_old, const INT A_old_exp,
+ CAcelpStaticMem *acelp_mem,
+ INT coreCoderFrameLength, INT clearOldExc,
+ UCHAR lpd_mode) {
+ int l_div =
+ coreCoderFrameLength / NB_DIV; /* length of one ACELP/TCX20 frame */
+ int l_div_partial;
+ FIXP_DBL *syn, *old_exc_mem;
+
+ C_ALLOC_SCRATCH_START(synth_buf, FIXP_DBL,
+ PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
+ syn = &synth_buf[M_LP_FILTER_ORDER];
+
+ l_div_partial = PIT_MAX_MAX + L_INTERPOL - l_div;
+ old_exc_mem = acelp_mem->old_exc_mem;
+
+ if (lpd_mode == 4) {
+ /* Bypass Domain conversion. TCXTD Concealment does no deemphasis in the
+ * end. */
+ FDKmemcpy(
+ synth_buf, &synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
+ (PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER) * sizeof(FIXP_DBL));
+ /* Set deemphasis memory state for TD concealment */
+ acelp_mem->deemph_mem_wsyn = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);
+ } else {
+ /* convert past [PIT_MAX_MAX+L_INTERPOL+M_LP_FILTER_ORDER] synthesis to
+ * preemph domain */
+ E_UTIL_preemph(&synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
+ synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
+ scaleValuesSaturate(synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER,
+ ACELP_OUTSCALE);
+ }
+
+ /* Set deemphasis memory state */
+ acelp_mem->de_emph_mem = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);
+
+ /* update acelp synth filter memory */
+ FDKmemcpy(acelp_mem->old_syn_mem,
+ &syn[PIT_MAX_MAX + L_INTERPOL - M_LP_FILTER_ORDER],
+ M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
+
+ if (clearOldExc) {
+ FDKmemclear(old_exc_mem, (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
+ C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
+ PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
+ return;
+ }
+
+ /* update past [PIT_MAX_MAX+L_INTERPOL] samples of exc memory */
+ if (last_lpd_mode == 1) { /* last frame was TCX20 */
+ if (last_last_lpd_mode == 0) { /* ACELP -> TCX20 -> ACELP transition */
+ /* Delay valid part of excitation buffer (from previous ACELP frame) by
+ * l_div samples */
+ FDKmemmove(old_exc_mem, old_exc_mem + l_div,
+ sizeof(FIXP_DBL) * l_div_partial);
+ } else if (last_last_lpd_mode > 0) { /* TCX -> TCX20 -> ACELP transition */
+ E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, l_div_partial);
+ }
+ E_UTIL_residu(A_new, A_new_exp, syn + l_div_partial,
+ old_exc_mem + l_div_partial, l_div);
+ } else { /* prev frame was FD, TCX40 or TCX80 */
+ int exc_A_new_length = (coreCoderFrameLength / 2 > PIT_MAX_MAX + L_INTERPOL)
+ ? PIT_MAX_MAX + L_INTERPOL
+ : coreCoderFrameLength / 2;
+ int exc_A_old_length = PIT_MAX_MAX + L_INTERPOL - exc_A_new_length;
+ E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, exc_A_old_length);
+ E_UTIL_residu(A_new, A_new_exp, &syn[exc_A_old_length],
+ &old_exc_mem[exc_A_old_length], exc_A_new_length);
+ }
+ C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
+ PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
+
+ return;
+}
+
+FIXP_DBL *CLpd_ACELP_GetFreeExcMem(CAcelpStaticMem *acelp_mem, INT length) {
+ FDK_ASSERT(length <= PIT_MAX_MAX + L_INTERPOL);
+ return acelp_mem->old_exc_mem;
+}
+
+INT CLpd_AcelpRead(HANDLE_FDK_BITSTREAM hBs, CAcelpChannelData *acelp,
+ INT acelp_core_mode, INT coreCoderFrameLength,
+ INT i_offset) {
+ int nb_subfr = coreCoderFrameLength / L_DIV;
+ const UCHAR *num_acb_index_bits =
+ (nb_subfr == 4) ? num_acb_idx_bits_table[0] : num_acb_idx_bits_table[1];
+ int nbits;
+ int error = 0;
+
+ const int PIT_MIN = PIT_MIN_12k8 + i_offset;
+ const int PIT_FR2 = PIT_FR2_12k8 - i_offset;
+ const int PIT_FR1 = PIT_FR1_12k8;
+ const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset);
+ int T0, T0_frac, T0_min = 0, T0_max;
+
+ if (PIT_MAX > PIT_MAX_MAX) {
+ error = AAC_DEC_DECODE_FRAME_ERROR;
+ goto bail;
+ }
+
+ acelp->acelp_core_mode = acelp_core_mode;
+
+ nbits = MapCoreMode2NBits(acelp_core_mode);
+
+ /* decode mean energy with 2 bits : 18, 30, 42 or 54 dB */
+ acelp->mean_energy = FDKreadBits(hBs, 2);
+
+ for (int sfr = 0; sfr < nb_subfr; sfr++) {
+ /* read ACB index and store T0 and T0_frac for each ACELP subframe. */
+ error = DecodePitchLag(hBs, num_acb_index_bits[sfr], PIT_MIN, PIT_FR2,
+ PIT_FR1, PIT_MAX, &T0, &T0_frac, &T0_min, &T0_max);
+ if (error) {
+ goto bail;
+ }
+ acelp->T0[sfr] = (USHORT)T0;
+ acelp->T0_frac[sfr] = (UCHAR)T0_frac;
+ acelp->ltp_filtering_flag[sfr] = FDKreadBits(hBs, 1);
+ switch (nbits) {
+ case 12: /* 12 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 1);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
+ break;
+ case 16: /* 16 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
+ break;
+ case 20: /* 20 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
+ break;
+ case 28: /* 28 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
+ break;
+ case 36: /* 36 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
+ break;
+ case 44: /* 44 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
+ break;
+ case 52: /* 52 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 13);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 13);
+ break;
+ case 64: /* 64 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 2);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 2);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 2);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 2);
+ acelp->icb_index[sfr][4] = FDKreadBits(hBs, 14);
+ acelp->icb_index[sfr][5] = FDKreadBits(hBs, 14);
+ acelp->icb_index[sfr][6] = FDKreadBits(hBs, 14);
+ acelp->icb_index[sfr][7] = FDKreadBits(hBs, 14);
+ break;
+ default:
+ FDK_ASSERT(0);
+ break;
+ }
+ acelp->gains[sfr] = FDKreadBits(hBs, 7);
+ }
+
+bail:
+ return error;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_acelp.h b/fdk-aac/libAACdec/src/usacdec_acelp.h
new file mode 100644
index 0000000..9de41ff
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_acelp.h
@@ -0,0 +1,281 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: USAC ACELP frame decoder
+
+*******************************************************************************/
+
+#ifndef USACDEC_ACELP_H
+#define USACDEC_ACELP_H
+
+#include "common_fix.h"
+#include "FDK_bitstream.h"
+#include "usacdec_const.h"
+#include "usacdec_rom.h"
+
+//#define ENHANCED_TCX_TD_CONCEAL_ENABLE
+
+/** Structure which holds the ACELP internal persistent memory */
+typedef struct {
+ FIXP_DBL old_exc_mem[PIT_MAX_MAX + L_INTERPOL];
+ FIXP_DBL old_syn_mem[M_LP_FILTER_ORDER]; /* synthesis filter states */
+ FIXP_SGL A[M_LP_FILTER_ORDER];
+ INT A_exp;
+ FIXP_DBL gc_threshold;
+ FIXP_DBL de_emph_mem;
+ FIXP_SGL past_gpit;
+ FIXP_DBL past_gcode;
+ USHORT old_T0;
+ UCHAR old_T0_frac;
+ FIXP_DBL deemph_mem_wsyn;
+ FIXP_DBL wsyn_rms;
+ SHORT seed_ace;
+} CAcelpStaticMem;
+
+/** Structure which holds the parameter data needed to decode one ACELP frame.
+ */
+typedef struct {
+ UCHAR
+ acelp_core_mode; /**< mean excitation energy index for whole ACELP frame
+ */
+ UCHAR mean_energy; /**< acelp core mode for whole ACELP frame */
+ USHORT T0[NB_SUBFR];
+ UCHAR T0_frac[NB_SUBFR];
+ UCHAR ltp_filtering_flag[NB_SUBFR]; /**< controlls whether LTP postfilter is
+ active for each ACELP subframe */
+ SHORT icb_index[NB_SUBFR]
+ [8]; /**< innovative codebook index for each ACELP subframe */
+ UCHAR gains[NB_SUBFR]; /**< gain index for each ACELP subframe */
+} CAcelpChannelData;
+
+/**
+ * \brief Read the acelp_coding() bitstream part.
+ * \param[in] hBs bitstream handle to read data from.
+ * \param[out] acelpData pointer to structure to store the parsed data of one
+ * ACELP frame.
+ * \param[in] acelp_core_mode the ACELP core mode index.
+ * \param[in] coreCoderFrameLength length of core coder frame (1024|768)
+ */
+INT CLpd_AcelpRead(HANDLE_FDK_BITSTREAM hBs, CAcelpChannelData *acelpData,
+ INT acelp_core_mode, INT i_offset, INT coreCoderFrameLength);
+/**
+ * \brief Initialization of memory before one LPD frame is decoded
+ * \param[out] synth_buf synthesis buffer to be initialized, exponent = SF_SYNTH
+ * \param[in] old_synth past synthesis of previous LPD frame, exponent =
+ * SF_SYNTH
+ * \param[out] synth_buf_fb fullband synthesis buffer to be initialized,
+ * exponent = SF_SYNTH
+ * \param[in] old_synth_fb past fullband synthesis of previous LPD frame,
+ * exponent = SF_SYNTH
+ * \param[out] pitch vector where decoded pitch lag values are stored
+ * \param[in] old_T_pf past pitch lag values of previous LPD frame
+ * \param[in] samplingRate sampling rate for pitch lag offset calculation
+ * \param[out] i_offset pitch lag offset for the decoding of the pitch lag
+ * \param[in] coreCoderFrameLength length of core coder frame (1024|768)
+ */
+void Acelp_PreProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
+ INT *old_T_pf, FIXP_DBL *pit_gain,
+ FIXP_DBL *old_gain_pf, INT samplingRate, INT *i_offset,
+ INT coreCoderFrameLength, INT synSfd,
+ INT nbSubfrSuperfr);
+
+/**
+ * \brief Save tail of buffers for the initialization of the next LPD frame
+ * \param[in] synth_buf synthesis of current LPD frame, exponent = SF_SYNTH
+ * \param[out] old_synth memory where tail of fullband synth_buf is stored,
+ * exponent = SF_SYNTH
+ * \param[in] synth_buf_fb fullband synthesis of current LPD frame, exponent =
+ * SF_SYNTH
+ * \param[out] old_synth_fb memory where tail of fullband synth_buf is stored,
+ * exponent = SF_SYNTH
+ * \param[in] pitch decoded pitch lag values of current LPD frame
+ * \param[out] old_T_pf memory where last SYN_SFD pitch lag values are stored
+ */
+void Acelp_PostProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
+ INT *old_T_pf, INT coreCoderFrameLength, INT synSfd,
+ INT nbSubfrSuperfr);
+
+/**
+ * \brief Decode one ACELP frame (three or four ACELP subframes with 64 samples
+ * each)
+ * \param[in,out] acelp_mem pointer to ACELP memory structure
+ * \param[in] i_offset pitch lag offset
+ * \param[in] lsp_old LPC filter in LSP domain corresponding to previous frame
+ * \param[in] lsp_new LPC filter in LSP domain corresponding to current frame
+ * \param[in] stab_fac stability factor constrained by 0<=stab_fac<=1.0,
+ * exponent = SF_STAB
+ * \param[in] acelpData pointer to struct with data which is needed for decoding
+ * one ACELP frame
+ * \param[out] synth ACELP output signal
+ * \param[out] pT four decoded pitch lag values
+ * \param[in] coreCoderFrameLength length of core coder frame (1024|768)
+ */
+void CLpd_AcelpDecode(CAcelpStaticMem *acelp_mem, INT i_offset,
+ const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
+ const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
+ FIXP_SGL stab_fac, CAcelpChannelData *acelpData,
+ INT numLostSubframes, int lastLpcLost, int frameCnt,
+ FIXP_DBL synth[], int pT[], FIXP_DBL *pit_gain,
+ INT coreCoderFrameLength);
+
+/**
+ * \brief Reset ACELP internal memory.
+ * \param[out] acelp_mem pointer to ACELP memory structure
+ */
+void CLpd_AcelpReset(CAcelpStaticMem *acelp_mem);
+
+/**
+ * \brief Initialize ACELP internal memory in case of FAC before ACELP decoder
+ * is called
+ * \param[in] synth points to end+1 of past valid synthesis signal, exponent =
+ * SF_SYNTH
+ * \param[in] last_lpd_mode last lpd mode
+ * \param[in] last_last_lpd_mode lpd mode before last_lpd_mode
+ * \param[in] A_new LP synthesis filter coeffs corresponding to last frame,
+ * exponent = SF_A_COEFFS
+ * \param[in] A_old LP synthesis filter coeffs corresponding to the frame before
+ * last frame, exponent = SF_A_COEFFS
+ * \param[in,out] acelp_mem pointer to ACELP memory structure
+ * \param[in] coreCoderFrameLength length of core coder frame (1024|768)
+ */
+void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode,
+ UCHAR last_last_lpd_mode,
+ const FIXP_LPC *A_new, const INT A_new_exp,
+ const FIXP_LPC *A_old, const INT A_old_exp,
+ CAcelpStaticMem *acelp_mem,
+ INT coreCoderFrameLength, INT clearOldExc,
+ UCHAR lpd_mode);
+
+/**
+ * \brief Calculate zero input response (zir) of the acelp synthesis filter
+ * \param[in] A LP synthesis filter coefficients, exponent = SF_A_COEFFS
+ * \param[in,out] acelp_mem pointer to ACELP memory structure
+ * \param[in] length length of zir
+ * \param[out] zir pointer to zir output buffer, exponent = SF_SYNTH
+ */
+void CLpd_Acelp_Zir(const FIXP_LPC A[], const INT A_exp,
+ CAcelpStaticMem *acelp_mem, const INT length,
+ FIXP_DBL zir[], int doDeemph);
+
+/**
+ * \brief Borrow static excitation memory from ACELP decoder
+ * \param[in] acelp_mem pointer to ACELP memory structure
+ * \param[in] length number of requested FIXP_DBL values
+ * \return pointer to requested memory
+ *
+ * The caller has to take care not to overwrite valid memory areas.
+ * During TCX/FAC calculations and before CLpd_AcelpPrepareInternalMem() is
+ * called, the following memory size is available:
+ * - 256 samples in case of ACELP -> TCX20 -> ACELP transition
+ * - PIT_MAX_MAX+L_INTERPOL samples in all other cases
+ */
+FIXP_DBL *CLpd_ACELP_GetFreeExcMem(CAcelpStaticMem *acelp_mem, INT length);
+
+void CLpd_TcxTDConceal(CAcelpStaticMem *acelp_mem, SHORT *pitch,
+ const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
+ const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
+ const FIXP_SGL stab_fac, INT numLostSubframes,
+ FIXP_DBL synth[], INT coreCoderFrameLength,
+ UCHAR last_tcx_noise_factor);
+
+inline SHORT E_UTIL_random(SHORT *seed) {
+ *seed = (SHORT)((((LONG)*seed * (LONG)31821) >> 1) + (LONG)13849);
+ return (*seed);
+}
+
+#endif /* USACDEC_ACELP_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_const.h b/fdk-aac/libAACdec/src/usacdec_const.h
new file mode 100644
index 0000000..f68e808
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_const.h
@@ -0,0 +1,203 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description: USAC related constants
+
+*******************************************************************************/
+
+#ifndef USACDEC_CONST_H
+#define USACDEC_CONST_H
+
+/* scale factors */
+#define SF_CODE 6 /* exponent of code[], fixed codebook vector */
+#define SF_GAIN_C 16 /* exponent of gain code and smoothed gain code */
+#define SF_EXC 16 /* exponent of exc[] and exc2[], excitation buffer */
+#define SF_GAIN_P 1 /* exponent of gain_pit */
+#define SF_PFAC 0 /* exponent of period/voicing factor */
+#define SF_SYNTH SF_EXC /* exponent of synthesis buffer */
+#define SF_A_COEFFS 3 /* exponent of LP domain synthesis filter coefficient */
+#define SF_STAB 1 /* exponent of stability factor */
+
+/* definitions which are independent of coreCoderFrameLength */
+#define M_LP_FILTER_ORDER 16 /* LP filter order */
+#define LP_FILTER_SCALE 4 /* LP filter scale */
+
+#define PIT_MIN_12k8 34 /* Minimum pitch lag with resolution 1/4 */
+#define PIT_MAX_12k8 231 /* Maximum pitch lag for fs=12.8kHz */
+#define FSCALE_DENOM 12800 /* Frequency scale denominator */
+#define FAC_FSCALE_MIN \
+ 6000 /* Minimum allowed frequency scale for acelp decoder */
+
+#if !defined(LPD_MAX_CORE_SR)
+#define LPD_MAX_CORE_SR 24000 /* Default value from ref soft */
+#endif
+#define FAC_FSCALE_MAX \
+ LPD_MAX_CORE_SR /* Maximum allowed frequency scale for acelp decoder */
+
+/* Maximum pitch lag (= 411 for fs_max = 24000) */
+#define PIT_MAX_TMP \
+ (PIT_MAX_12k8 + \
+ (6 * \
+ ((((FAC_FSCALE_MAX * PIT_MIN_12k8) + (FSCALE_DENOM / 2)) / FSCALE_DENOM) - \
+ PIT_MIN_12k8)))
+#if (PIT_MAX_TMP < \
+ 256) /* cannot be smaller because of tcx time domain concealment */
+#define PIT_MAX_MAX 256
+#else
+#define PIT_MAX_MAX PIT_MAX_TMP
+#endif
+
+#define NB_DIV 4 /* number of division (20ms) per 80ms frame */
+#define L_SUBFR 64 /* subframe size (5ms) */
+#define BPF_SFD 1 /* bass postfilter delay (subframe) */
+#define BPF_DELAY (BPF_SFD * L_SUBFR) /* bass postfilter delay (samples) */
+
+#define L_FILT 12 /* Delay of up-sampling filter (bass post-filter) */
+#define L_EXTRA 96 /* for bass post-filter */
+#define L_INTERPOL \
+ (16 + 1) /* Length of filter for interpolation (acelp decoder) */
+
+/* definitions for coreCoderFrameLength = 1024 */
+#define L_FRAME_PLUS_1024 1024 /* length of one 80ms superframe */
+#define L_DIV_1024 \
+ (L_FRAME_PLUS_1024 / NB_DIV) /* length of one acelp or tcx20 frame */
+#define NB_SUBFR_1024 \
+ (L_DIV_1024 / L_SUBFR) /* number of 5ms subframe per division */
+#define NB_SUBFR_SUPERFR_1024 \
+ (L_FRAME_PLUS_1024 / L_SUBFR) /* number of 5ms subframe per 80ms frame */
+#define AAC_SFD_1024 (NB_SUBFR_SUPERFR_1024 / 2) /* AAC delay (subframe) */
+#define AAC_DELAY_1024 (AAC_SFD_1024 * L_SUBFR) /* AAC delay (samples) */
+#define SYN_SFD_1024 (AAC_SFD_1024 - BPF_SFD) /* synthesis delay (subframe) */
+#define SYN_DELAY_1024 \
+ (SYN_SFD_1024 * L_SUBFR) /* synthesis delay (samples) \
+ */
+#define LFAC_1024 (L_DIV_1024 / 2) /* FAC frame length */
+#define LFAC_SHORT_1024 \
+ (L_DIV_1024 / 4) /* for transitions EIGHT_SHORT FD->LPD and vv. */
+#define FDNS_NPTS_1024 64 /* FD noise shaping resolution (64=100Hz/point) */
+
+/* definitions for coreCoderFrameLength = 768 */
+#define L_FRAME_PLUS_768 768
+#define L_DIV_768 \
+ (L_FRAME_PLUS_768 / NB_DIV) /* length of one acelp or tcx20 frame */
+#define NB_SUBFR_768 \
+ (L_DIV_768 / L_SUBFR) /* number of 5ms subframe per division */
+#define NB_SUBFR_SUPERFR_768 \
+ (L_FRAME_PLUS_768 / L_SUBFR) /* number of 5ms subframe per 80ms frame */
+#define AAC_SFD_768 (NB_SUBFR_SUPERFR_768 / 2) /* AAC delay (subframe) */
+#define AAC_DELAY_768 (AAC_SFD_768 * L_SUBFR) /* AAC delay (samples) */
+#define SYN_SFD_768 (AAC_SFD_768 - BPF_SFD) /* synthesis delay (subframe) */
+#define SYN_DELAY_768 (SYN_SFD_768 * L_SUBFR) /* synthesis delay (samples) */
+#define LFAC_768 (L_DIV_768 / 2) /* FAC frame length */
+#define LFAC_SHORT_768 \
+ (L_DIV_768 / 4) /* for transitions EIGHT_SHORT FD->LPD and vv. */
+
+/* maximum (used for memory allocation) */
+#define L_FRAME_PLUS L_FRAME_PLUS_1024
+#define L_DIV L_DIV_1024
+#define NB_SUBFR NB_SUBFR_1024
+#define NB_SUBFR_SUPERFR NB_SUBFR_SUPERFR_1024
+#define AAC_SFD AAC_SFD_1024
+#define AAC_DELAY AAC_DELAY_1024
+#define SYN_SFD SYN_SFD_1024
+#define SYN_DELAY SYN_DELAY_1024
+#define LFAC LFAC_1024
+#define LFAC_SHORT LFAC_SHORT_1024
+#define FDNS_NPTS FDNS_NPTS_1024
+
+#endif /* USACDEC_CONST_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_fac.cpp b/fdk-aac/libAACdec/src/usacdec_fac.cpp
new file mode 100644
index 0000000..0d3d844
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_fac.cpp
@@ -0,0 +1,745 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description: USAC FAC
+
+*******************************************************************************/
+
+#include "usacdec_fac.h"
+
+#include "usacdec_const.h"
+#include "usacdec_lpc.h"
+#include "usacdec_acelp.h"
+#include "usacdec_rom.h"
+#include "dct.h"
+#include "FDK_tools_rom.h"
+#include "mdct.h"
+
+#define SPEC_FAC(ptr, i, gl) ((ptr) + ((i) * (gl)))
+
+FIXP_DBL *CLpd_FAC_GetMemory(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ UCHAR mod[NB_DIV], int *pState) {
+ FIXP_DBL *ptr;
+ int i;
+ int k = 0;
+ int max_windows = 8;
+
+ FDK_ASSERT(*pState >= 0 && *pState < max_windows);
+
+ /* Look for free space to store FAC data. 2 FAC data blocks fit into each TCX
+ * spectral data block. */
+ for (i = *pState; i < max_windows; i++) {
+ if (mod[i >> 1] == 0) {
+ break;
+ }
+ }
+
+ *pState = i + 1;
+
+ if (i == max_windows) {
+ ptr = pAacDecoderChannelInfo->data.usac.fac_data0;
+ } else {
+ FDK_ASSERT(mod[(i >> 1)] == 0);
+ ptr = SPEC_FAC(pAacDecoderChannelInfo->pSpectralCoefficient, i,
+ pAacDecoderChannelInfo->granuleLength << k);
+ }
+
+ return ptr;
+}
+
+int CLpd_FAC_Read(HANDLE_FDK_BITSTREAM hBs, FIXP_DBL *pFac, SCHAR *pFacScale,
+ int length, int use_gain, int frame) {
+ FIXP_DBL fac_gain;
+ int fac_gain_e = 0;
+
+ if (use_gain) {
+ CLpd_DecodeGain(&fac_gain, &fac_gain_e, FDKreadBits(hBs, 7));
+ }
+
+ if (CLpc_DecodeAVQ(hBs, pFac, 1, 1, length) != 0) {
+ return -1;
+ }
+
+ {
+ int scale;
+
+ scale = getScalefactor(pFac, length);
+ scaleValues(pFac, length, scale);
+ pFacScale[frame] = DFRACT_BITS - 1 - scale;
+ }
+
+ if (use_gain) {
+ int i;
+
+ pFacScale[frame] += fac_gain_e;
+
+ for (i = 0; i < length; i++) {
+ pFac[i] = fMult(pFac[i], fac_gain);
+ }
+ }
+ return 0;
+}
+
+/**
+ * \brief Apply synthesis filter with zero input to x. The overall filter gain
+ * is 1.0.
+ * \param a LPC filter coefficients.
+ * \param length length of the input/output data vector x.
+ * \param x input/output vector, where the synthesis filter is applied in place.
+ */
+static void Syn_filt_zero(const FIXP_LPC a[], const INT a_exp, INT length,
+ FIXP_DBL x[]) {
+ int i, j;
+ FIXP_DBL L_tmp;
+
+ for (i = 0; i < length; i++) {
+ L_tmp = (FIXP_DBL)0;
+
+ for (j = 0; j < fMin(i, M_LP_FILTER_ORDER); j++) {
+ L_tmp -= fMultDiv2(a[j], x[i - (j + 1)]) >> (LP_FILTER_SCALE - 1);
+ }
+
+ L_tmp = scaleValue(L_tmp, a_exp + LP_FILTER_SCALE);
+ x[i] = fAddSaturate(x[i], L_tmp);
+ }
+}
+
+/* Table is also correct for coreCoderFrameLength = 768. Factor 3/4 is canceled
+ out: gainFac = 0.5 * sqrt(fac_length/lFrame)
+*/
+static const FIXP_DBL gainFac[4] = {0x40000000, 0x2d413ccd, 0x20000000,
+ 0x16a09e66};
+
+void CFac_ApplyGains(FIXP_DBL fac_data[LFAC], const INT fac_length,
+ const FIXP_DBL tcx_gain, const FIXP_DBL alfd_gains[],
+ const INT mod) {
+ FIXP_DBL facFactor;
+ int i;
+
+ FDK_ASSERT((fac_length == 128) || (fac_length == 96));
+
+ /* 2) Apply gain factor to FAC data */
+ facFactor = fMult(gainFac[mod], tcx_gain);
+ for (i = 0; i < fac_length; i++) {
+ fac_data[i] = fMult(fac_data[i], facFactor);
+ }
+
+ /* 3) Apply spectrum deshaping using alfd_gains */
+ for (i = 0; i < fac_length / 4; i++) {
+ int k;
+
+ k = i >> (3 - mod);
+ fac_data[i] = fMult(fac_data[i], alfd_gains[k])
+ << 1; /* alfd_gains is scaled by one bit. */
+ }
+}
+
+static void CFac_CalcFacSignal(FIXP_DBL *pOut, FIXP_DBL *pFac,
+ const int fac_scale, const int fac_length,
+ const FIXP_LPC A[M_LP_FILTER_ORDER],
+ const INT A_exp, const int fAddZir,
+ const int isFdFac) {
+ FIXP_LPC wA[M_LP_FILTER_ORDER];
+ FIXP_DBL tf_gain = (FIXP_DBL)0;
+ int wlength;
+ int scale = fac_scale;
+
+ /* obtain tranform gain. */
+ imdct_gain(&tf_gain, &scale, isFdFac ? 0 : fac_length);
+
+ /* 4) Compute inverse DCT-IV of FAC data. Output scale of DCT IV is 16 bits.
+ */
+ dct_IV(pFac, fac_length, &scale);
+ /* dct_IV scale = log2(fac_length). "- 7" is a factor of 2/128 */
+ if (tf_gain != (FIXP_DBL)0) { /* non-radix 2 transform gain */
+ int i;
+
+ for (i = 0; i < fac_length; i++) {
+ pFac[i] = fMult(tf_gain, pFac[i]);
+ }
+ }
+ scaleValuesSaturate(pOut, pFac, fac_length,
+ scale); /* Avoid overflow issues and saturate. */
+
+ E_LPC_a_weight(wA, A, M_LP_FILTER_ORDER);
+
+ /* We need the output of the IIR filter to be longer than "fac_length".
+ For this reason we run it with zero input appended to the end of the input
+ sequence, i.e. we generate its ZIR and extend the output signal.*/
+ FDKmemclear(pOut + fac_length, fac_length * sizeof(FIXP_DBL));
+ wlength = 2 * fac_length;
+
+ /* 5) Apply weighted synthesis filter to FAC data, including optional Zir (5.
+ * item 4). */
+ Syn_filt_zero(wA, A_exp, wlength, pOut);
+}
+
+INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac,
+ const int fac_scale, FIXP_LPC *A, INT A_exp,
+ INT nrOutSamples, const INT fac_length,
+ const INT isFdFac, UCHAR prevWindowShape) {
+ FIXP_DBL *pOvl;
+ FIXP_DBL *pOut0;
+ const FIXP_WTP *pWindow;
+ int i, fl, nrSamples = 0;
+
+ FDK_ASSERT(fac_length <= 1024 / (4 * 2));
+
+ fl = fac_length * 2;
+
+ pWindow = FDKgetWindowSlope(fl, prevWindowShape);
+
+ /* Adapt window slope length in case of frame loss. */
+ if (hMdct->prev_fr != fl) {
+ int nl = 0;
+ imdct_adapt_parameters(hMdct, &fl, &nl, fac_length, pWindow, nrOutSamples);
+ FDK_ASSERT(nl == 0);
+ }
+
+ if (nrSamples < nrOutSamples) {
+ pOut0 = output;
+ nrSamples += hMdct->ov_offset;
+ /* Purge buffered output. */
+ FDKmemcpy(pOut0, hMdct->overlap.time, hMdct->ov_offset * sizeof(pOut0[0]));
+ hMdct->ov_offset = 0;
+ }
+
+ pOvl = hMdct->overlap.freq + hMdct->ov_size - 1;
+
+ if (nrSamples >= nrOutSamples) {
+ pOut0 = hMdct->overlap.time + hMdct->ov_offset;
+ hMdct->ov_offset += hMdct->prev_nr + fl / 2;
+ } else {
+ pOut0 = output + nrSamples;
+ nrSamples += hMdct->prev_nr + fl / 2;
+ }
+ if (hMdct->prevPrevAliasSymmetry == 0) {
+ for (i = 0; i < hMdct->prev_nr; i++) {
+ FIXP_DBL x = -(*pOvl--);
+ *pOut0 = IMDCT_SCALE_DBL(x);
+ pOut0++;
+ }
+ } else {
+ for (i = 0; i < hMdct->prev_nr; i++) {
+ FIXP_DBL x = (*pOvl--);
+ *pOut0 = IMDCT_SCALE_DBL(x);
+ pOut0++;
+ }
+ }
+ hMdct->prev_nr = 0;
+
+ {
+ if (pFac != NULL) {
+ /* Note: The FAC gain might have been applied directly after bit stream
+ * parse in this case. */
+ CFac_CalcFacSignal(pOut0, pFac, fac_scale, fac_length, A, A_exp, 0,
+ isFdFac);
+ } else {
+ /* Clear buffer because of the overlap and ADD! */
+ FDKmemclear(pOut0, fac_length * sizeof(FIXP_DBL));
+ }
+ }
+
+ i = 0;
+
+ if (hMdct->prevPrevAliasSymmetry == 0) {
+ for (; i < fl / 2; i++) {
+ FIXP_DBL x0;
+
+ /* Overlap Add */
+ x0 = -fMult(*pOvl--, pWindow[i].v.re);
+
+ *pOut0 += IMDCT_SCALE_DBL(x0);
+ pOut0++;
+ }
+ } else {
+ for (; i < fl / 2; i++) {
+ FIXP_DBL x0;
+
+ /* Overlap Add */
+ x0 = fMult(*pOvl--, pWindow[i].v.re);
+
+ *pOut0 += IMDCT_SCALE_DBL(x0);
+ pOut0++;
+ }
+ }
+ if (hMdct->pFacZir !=
+ 0) { /* this should only happen for ACELP -> TCX20 -> ACELP transition */
+ FIXP_DBL *pOut = pOut0 - fl / 2; /* fl/2 == fac_length */
+ for (i = 0; i < fl / 2; i++) {
+ pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
+ }
+ hMdct->pFacZir = NULL;
+ }
+
+ hMdct->prev_fr = 0;
+ hMdct->prev_nr = 0;
+ hMdct->prev_tl = 0;
+ hMdct->prevPrevAliasSymmetry = hMdct->prevAliasSymmetry;
+
+ return nrSamples;
+}
+
+INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
+ const SHORT spec_scale[], const int nSpec,
+ FIXP_DBL *pFac, const int fac_scale,
+ const INT fac_length, INT noOutSamples, const INT tl,
+ const FIXP_WTP *wrs, const INT fr, FIXP_LPC A[16],
+ INT A_exp, CAcelpStaticMem *acelp_mem,
+ const FIXP_DBL gain, const int last_frame_lost,
+ const int isFdFac, const UCHAR last_lpd_mode,
+ const int k, int currAliasingSymmetry) {
+ FIXP_DBL *pCurr, *pOvl, *pSpec;
+ const FIXP_WTP *pWindow;
+ const FIXP_WTB *FacWindowZir_conceal;
+ UCHAR doFacZirConceal = 0;
+ int doDeemph = 1;
+ const FIXP_WTB *FacWindowZir, *FacWindowSynth;
+ FIXP_DBL *pOut0 = output, *pOut1;
+ int w, i, fl, nl, nr, f_len, nrSamples = 0, s = 0, scale, total_gain_e;
+ FIXP_DBL *pF, *pFAC_and_FAC_ZIR = NULL;
+ FIXP_DBL total_gain = gain;
+
+ FDK_ASSERT(fac_length <= 1024 / (4 * 2));
+ switch (fac_length) {
+ /* coreCoderFrameLength = 1024 */
+ case 128:
+ pWindow = SineWindow256;
+ FacWindowZir = FacWindowZir128;
+ FacWindowSynth = FacWindowSynth128;
+ break;
+ case 64:
+ pWindow = SineWindow128;
+ FacWindowZir = FacWindowZir64;
+ FacWindowSynth = FacWindowSynth64;
+ break;
+ case 32:
+ pWindow = SineWindow64;
+ FacWindowZir = FacWindowZir32;
+ FacWindowSynth = FacWindowSynth32;
+ break;
+ /* coreCoderFrameLength = 768 */
+ case 96:
+ pWindow = SineWindow192;
+ FacWindowZir = FacWindowZir96;
+ FacWindowSynth = FacWindowSynth96;
+ break;
+ case 48:
+ pWindow = SineWindow96;
+ FacWindowZir = FacWindowZir48;
+ FacWindowSynth = FacWindowSynth48;
+ break;
+ default:
+ FDK_ASSERT(0);
+ return 0;
+ }
+
+ FacWindowZir_conceal = FacWindowSynth;
+ /* Derive NR and NL */
+ fl = fac_length * 2;
+ nl = (tl - fl) >> 1;
+ nr = (tl - fr) >> 1;
+
+ if (noOutSamples > nrSamples) {
+ /* Purge buffered output. */
+ FDKmemcpy(pOut0, hMdct->overlap.time, hMdct->ov_offset * sizeof(pOut0[0]));
+ nrSamples = hMdct->ov_offset;
+ hMdct->ov_offset = 0;
+ }
+
+ if (nrSamples >= noOutSamples) {
+ pOut1 = hMdct->overlap.time + hMdct->ov_offset;
+ if (hMdct->ov_offset < fac_length) {
+ pOut0 = output + nrSamples;
+ } else {
+ pOut0 = pOut1;
+ }
+ hMdct->ov_offset += fac_length + nl;
+ } else {
+ pOut1 = output + nrSamples;
+ pOut0 = output + nrSamples;
+ }
+
+ {
+ pFAC_and_FAC_ZIR = CLpd_ACELP_GetFreeExcMem(acelp_mem, 2 * fac_length);
+ {
+ const FIXP_DBL *pTmp1, *pTmp2;
+
+ doFacZirConceal |= ((last_frame_lost != 0) && (k == 0));
+ doDeemph &= (last_lpd_mode != 4);
+ if (doFacZirConceal) {
+ /* ACELP contribution in concealment case:
+ Use ZIR with a modified ZIR window to preserve some more energy.
+ Dont use FAC, which contains wrong information for concealed frame
+ Dont use last ACELP samples, but double ZIR, instead (afterwards) */
+ FDKmemclear(pFAC_and_FAC_ZIR, 2 * fac_length * sizeof(FIXP_DBL));
+ FacWindowSynth = (FIXP_WTB *)pFAC_and_FAC_ZIR;
+ FacWindowZir = FacWindowZir_conceal;
+ } else {
+ CFac_CalcFacSignal(pFAC_and_FAC_ZIR, pFac, fac_scale + s, fac_length, A,
+ A_exp, 1, isFdFac);
+ }
+ /* 6) Get windowed past ACELP samples and ACELP ZIR signal */
+
+ /*
+ * Get ACELP ZIR (pFac[]) and ACELP past samples (pOut0[]) and add them
+ * to the FAC synth signal contribution on pOut1[].
+ */
+ {
+ {
+ CLpd_Acelp_Zir(A, A_exp, acelp_mem, fac_length, pFac, doDeemph);
+
+ pTmp1 = pOut0;
+ pTmp2 = pFac;
+ }
+
+ for (i = 0, w = 0; i < fac_length; i++) {
+ FIXP_DBL x;
+ /* Div2 is compensated by table scaling */
+ x = fMultDiv2(pTmp2[i], FacWindowZir[w]);
+ x += fMultDiv2(pTmp1[-i - 1], FacWindowSynth[w]);
+ x += pFAC_and_FAC_ZIR[i];
+ pOut1[i] = x;
+
+ w++;
+ }
+ }
+
+ if (doFacZirConceal) {
+ /* ZIR is the only ACELP contribution, so double it */
+ scaleValues(pOut1, fac_length, 1);
+ }
+ }
+ }
+
+ if (nrSamples < noOutSamples) {
+ nrSamples += fac_length + nl;
+ }
+
+ /* Obtain transform gain */
+ total_gain = gain;
+ total_gain_e = 0;
+ imdct_gain(&total_gain, &total_gain_e, tl);
+
+ /* IMDCT overlap add */
+ scale = total_gain_e;
+ pSpec = _pSpec;
+
+ /* Note:when comming from an LPD frame (TCX/ACELP) the previous alisaing
+ * symmetry must always be 0 */
+ if (currAliasingSymmetry == 0) {
+ dct_IV(pSpec, tl, &scale);
+ } else {
+ FIXP_DBL _tmp[1024 + ALIGNMENT_DEFAULT / sizeof(FIXP_DBL)];
+ FIXP_DBL *tmp = (FIXP_DBL *)ALIGN_PTR(_tmp);
+ C_ALLOC_ALIGNED_REGISTER(tmp, sizeof(_tmp));
+ dst_III(pSpec, tmp, tl, &scale);
+ C_ALLOC_ALIGNED_UNREGISTER(tmp);
+ }
+
+ /* Optional scaling of time domain - no yet windowed - of current spectrum */
+ if (total_gain != (FIXP_DBL)0) {
+ for (i = 0; i < tl; i++) {
+ pSpec[i] = fMult(pSpec[i], total_gain);
+ }
+ }
+ int loc_scale = fixmin_I(spec_scale[0] + scale, (INT)DFRACT_BITS - 1);
+ scaleValuesSaturate(pSpec, tl, loc_scale);
+
+ pOut1 += fl / 2 - 1;
+ pCurr = pSpec + tl - fl / 2;
+
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x1;
+
+ /* FAC signal is already on pOut1, because of that the += operator. */
+ x1 = fMult(*pCurr++, pWindow[i].v.re);
+ FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
+ pOut1 < hMdct->overlap.time + hMdct->ov_size) ||
+ (pOut1 >= output && pOut1 < output + 1024));
+ *pOut1 += IMDCT_SCALE_DBL(-x1);
+ pOut1--;
+ }
+
+ /* NL output samples TL/2+FL/2..TL. - current[FL/2..0] */
+ pOut1 += (fl / 2) + 1;
+
+ pFAC_and_FAC_ZIR += fac_length; /* set pointer to beginning of FAC ZIR */
+
+ if (nl == 0) {
+ /* save pointer to write FAC ZIR data later */
+ hMdct->pFacZir = pFAC_and_FAC_ZIR;
+ } else {
+ FDK_ASSERT(nl >= fac_length);
+ /* FAC ZIR will be added now ... */
+ hMdct->pFacZir = NULL;
+ }
+
+ pF = pFAC_and_FAC_ZIR;
+ f_len = fac_length;
+
+ pCurr = pSpec + tl - fl / 2 - 1;
+ for (i = 0; i < nl; i++) {
+ FIXP_DBL x = -(*pCurr--);
+ /* 5) (item 4) Synthesis filter Zir component, FAC ZIR (another one). */
+ if (i < f_len) {
+ x += *pF++;
+ }
+
+ FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
+ pOut1 < hMdct->overlap.time + hMdct->ov_size) ||
+ (pOut1 >= output && pOut1 < output + 1024));
+ *pOut1 = IMDCT_SCALE_DBL(x);
+ pOut1++;
+ }
+
+ hMdct->prev_nr = nr;
+ hMdct->prev_fr = fr;
+ hMdct->prev_wrs = wrs;
+ hMdct->prev_tl = tl;
+ hMdct->prevPrevAliasSymmetry = hMdct->prevAliasSymmetry;
+ hMdct->prevAliasSymmetry = currAliasingSymmetry;
+ fl = fr;
+ nl = nr;
+
+ pOvl = pSpec + tl / 2 - 1;
+ pOut0 = pOut1;
+
+ for (w = 1; w < nSpec; w++) /* for ACELP -> FD short */
+ {
+ const FIXP_WTP *pWindow_prev;
+
+ /* Setup window pointers */
+ pWindow_prev = hMdct->prev_wrs;
+
+ /* Current spectrum */
+ pSpec = _pSpec + w * tl;
+
+ scale = total_gain_e;
+
+ /* For the second, third, etc. short frames the alisaing symmetry is equal,
+ * either (0,0) or (1,1) */
+ if (currAliasingSymmetry == 0) {
+ /* DCT IV of current spectrum */
+ dct_IV(pSpec, tl, &scale);
+ } else {
+ dst_IV(pSpec, tl, &scale);
+ }
+
+ /* Optional scaling of time domain - no yet windowed - of current spectrum
+ */
+ /* and de-scale current spectrum signal (time domain, no yet windowed) */
+ if (total_gain != (FIXP_DBL)0) {
+ for (i = 0; i < tl; i++) {
+ pSpec[i] = fMult(pSpec[i], total_gain);
+ }
+ }
+ loc_scale = fixmin_I(spec_scale[w] + scale, (INT)DFRACT_BITS - 1);
+ scaleValuesSaturate(pSpec, tl, loc_scale);
+
+ if (noOutSamples <= nrSamples) {
+ /* Divert output first half to overlap buffer if we already got enough
+ * output samples. */
+ pOut0 = hMdct->overlap.time + hMdct->ov_offset;
+ hMdct->ov_offset += hMdct->prev_nr + fl / 2;
+ } else {
+ /* Account output samples */
+ nrSamples += hMdct->prev_nr + fl / 2;
+ }
+
+ /* NR output samples 0 .. NR. -overlap[TL/2..TL/2-NR] */
+ for (i = 0; i < hMdct->prev_nr; i++) {
+ FIXP_DBL x = -(*pOvl--);
+ *pOut0 = IMDCT_SCALE_DBL(x);
+ pOut0++;
+ }
+
+ if (noOutSamples <= nrSamples) {
+ /* Divert output second half to overlap buffer if we already got enough
+ * output samples. */
+ pOut1 = hMdct->overlap.time + hMdct->ov_offset + fl / 2 - 1;
+ hMdct->ov_offset += fl / 2 + nl;
+ } else {
+ pOut1 = pOut0 + (fl - 1);
+ nrSamples += fl / 2 + nl;
+ }
+
+ /* output samples before window crossing point NR .. TL/2.
+ * -overlap[TL/2-NR..TL/2-NR-FL/2] + current[NR..TL/2] */
+ /* output samples after window crossing point TL/2 .. TL/2+FL/2.
+ * -overlap[0..FL/2] - current[TL/2..FL/2] */
+ pCurr = pSpec + tl - fl / 2;
+ if (currAliasingSymmetry == 0) {
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x0, x1;
+
+ cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
+ *pOut0 = IMDCT_SCALE_DBL(x0);
+ *pOut1 = IMDCT_SCALE_DBL(-x1);
+ pOut0++;
+ pOut1--;
+ }
+ } else {
+ if (hMdct->prevPrevAliasSymmetry == 0) {
+ /* Jump DST II -> DST IV for the second window */
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x0, x1;
+
+ cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
+ *pOut0 = IMDCT_SCALE_DBL(x0);
+ *pOut1 = IMDCT_SCALE_DBL(x1);
+ pOut0++;
+ pOut1--;
+ }
+ } else {
+ /* Jump DST IV -> DST IV from the second window on */
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x0, x1;
+
+ cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow_prev[i]);
+ *pOut0 = IMDCT_SCALE_DBL(x0);
+ *pOut1 = IMDCT_SCALE_DBL(x1);
+ pOut0++;
+ pOut1--;
+ }
+ }
+ }
+
+ if (hMdct->pFacZir != 0) {
+ /* add FAC ZIR of previous ACELP -> mdct transition */
+ FIXP_DBL *pOut = pOut0 - fl / 2;
+ FDK_ASSERT(fl / 2 <= 128);
+ for (i = 0; i < fl / 2; i++) {
+ pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
+ }
+ hMdct->pFacZir = NULL;
+ }
+ pOut0 += (fl / 2);
+
+ /* NL output samples TL/2+FL/2..TL. - current[FL/2..0] */
+ pOut1 += (fl / 2) + 1;
+ pCurr = pSpec + tl - fl / 2 - 1;
+ for (i = 0; i < nl; i++) {
+ FIXP_DBL x = -(*pCurr--);
+ *pOut1 = IMDCT_SCALE_DBL(x);
+ pOut1++;
+ }
+
+ /* Set overlap source pointer for next window pOvl = pSpec + tl/2 - 1; */
+ pOvl = pSpec + tl / 2 - 1;
+
+ /* Previous window values. */
+ hMdct->prev_nr = nr;
+ hMdct->prev_fr = fr;
+ hMdct->prev_tl = tl;
+ hMdct->prev_wrs = pWindow_prev;
+ hMdct->prevPrevAliasSymmetry = hMdct->prevAliasSymmetry;
+ hMdct->prevAliasSymmetry = currAliasingSymmetry;
+ }
+
+ /* Save overlap */
+
+ pOvl = hMdct->overlap.freq + hMdct->ov_size - tl / 2;
+ FDK_ASSERT(pOvl >= hMdct->overlap.time + hMdct->ov_offset);
+ FDK_ASSERT(tl / 2 <= hMdct->ov_size);
+ for (i = 0; i < tl / 2; i++) {
+ pOvl[i] = _pSpec[i + (w - 1) * tl];
+ }
+
+ return nrSamples;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_fac.h b/fdk-aac/libAACdec/src/usacdec_fac.h
new file mode 100644
index 0000000..100a6fa
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_fac.h
@@ -0,0 +1,191 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description: USAC FAC
+
+*******************************************************************************/
+
+#ifndef USACDEC_FAC_H
+#define USACDEC_FAC_H
+
+#include "channelinfo.h"
+#include "FDK_bitstream.h"
+
+/**
+ * \brief Get the address of a memory area of the spectral data memory were the
+ * FAC data can be stored into.
+ * \param spec SPECTRAL_PTR pointing to the current spectral data.
+ * \param mod the current LPD mod array.
+ * \param pState pointer to a private state variable which must be 0 for the
+ * first call and not changed externally.
+ * \param isFullbandLPD is 1 if fullband LPD mode is on, otherwise it is 0.
+ */
+FIXP_DBL *CLpd_FAC_GetMemory(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ UCHAR mod[NB_SUBFR], int *pState);
+
+/**
+ * \brief read a fac bitstream data block.
+ * \param hBs a bit stream handle, where the fac bitstream data is located.
+ * \param pFac pointer to were the FAC data will be stored into.
+ * \param pFacScale pointer to were the FAC data scale value will be stored
+ * into.
+ * \param tcx_gain value to be used as FAC gain. If zero, read fac_gain from
+ * bitstream.
+ * \param tcx_gain_e exponen value of tcx_gain.
+ * \param frame the subframe to be considered from the current superframe.
+ * Always 0 for FD case.
+ * \return 0 on success, -1 on error.
+ */
+int CLpd_FAC_Read(HANDLE_FDK_BITSTREAM hBs, FIXP_DBL *pFac, SCHAR *pFacScale,
+ int length, int use_gain, int frame);
+
+/**
+ * \brief Apply TCX and ALFD gains to FAC data.
+ * \param fac_data pointer to FAC data.
+ * \param fac_length FAC length (128 or 96).
+ * \param tcx_gain TCX gain
+ * \param alfd_gains pointer to alfd gains.
+ * \param mod mod value (1,2,3) of TCX frame where the FAC signal needs to be
+ * applied.
+ */
+void CFac_ApplyGains(FIXP_DBL fac_data[LFAC], const INT fac_length,
+ const FIXP_DBL tcx_gain, const FIXP_DBL alfd_gains[],
+ const INT mod);
+
+/**
+ * \brief Do FAC transition from frequency domain to ACELP domain.
+ */
+INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac_data,
+ const int fac_data_e, FIXP_LPC *A, INT A_exp,
+ INT nrOutSamples, const INT fac_length,
+ const INT isFdFac, UCHAR prevWindowShape);
+
+/**
+ * \brief Do FAC transition from ACELP domain to frequency domain.
+ * \param hMdct MDCT context.
+ * \param output pointer for time domain output.
+ * \param pSpec pointer to MDCT spectrum input.
+ * \param spec_scale MDCT spectrum exponents.
+ * \param nSpec amount of contiguos MDCT spectra.
+ * \param pFac pointer to FAC MDCT domain data.
+ * \param fac_scale exponent of FAC data.
+ * \param fac_length length of FAC data.
+ * \param nrSamples room in samples in output buffer.
+ * \param tl MDCT transform length of pSpec.
+ * \param wrs right MDCT window slope.
+ * \param fr right MDCT window slope length.
+ * \param A LP domain filter coefficients.
+ * \param deemph_mem deemphasis filter state.
+ * \param gain gain to be applied to FAC data before overlap add.
+ * \param old_syn_mem Synthesis filter state.
+ * \param isFdFac indicates fac processing from or to FD.
+ * \param pFacData fac data stored for fullband LPD.
+ * \param elFlags element specific parser guidance flags.
+ * \param isFacForFullband indicates that fac is processed for fullband LPD.
+ */
+INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pSpec,
+ const SHORT spec_scale[], const int nSpec,
+ FIXP_DBL *pFac_data, const int fac_data_e,
+ const INT fac_length, INT nrSamples, const INT tl,
+ const FIXP_WTP *wrs, const INT fr, FIXP_LPC A[16],
+ INT A_exp, CAcelpStaticMem *acelp_mem,
+ const FIXP_DBL gain, const int last_frame_lost,
+ const int isFdFac, const UCHAR last_lpd, const int k,
+ int currAliasingSymmetry);
+
+#endif /* USACDEC_FAC_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_lpc.cpp b/fdk-aac/libAACdec/src/usacdec_lpc.cpp
new file mode 100644
index 0000000..271463f
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_lpc.cpp
@@ -0,0 +1,1194 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Matthias Hildenbrand, Manuel Jander
+
+ Description: USAC LPC/AVQ decode
+
+*******************************************************************************/
+
+#include "usacdec_lpc.h"
+
+#include "usacdec_rom.h"
+#include "FDK_trigFcts.h"
+
+#define NQ_MAX 36
+
+/*
+ * Helper functions.
+ */
+
+/**
+ * \brief Read unary code.
+ * \param hBs bitstream handle as data source.
+ * \return decoded value.
+ */
+static int get_vlclbf(HANDLE_FDK_BITSTREAM hBs) {
+ int result = 0;
+
+ while (FDKreadBits(hBs, 1) && result <= NQ_MAX) {
+ result++;
+ }
+ return result;
+}
+
+/**
+ * \brief Read bit count limited unary code.
+ * \param hBs bitstream handle as data source
+ * \param n max amount of bits to be read.
+ * \return decoded value.
+ */
+static int get_vlclbf_n(HANDLE_FDK_BITSTREAM hBs, int n) {
+ int result = 0;
+
+ while (FDKreadBits(hBs, 1)) {
+ result++;
+ n--;
+ if (n <= 0) {
+ break;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Algebraic Vector Quantizer
+ */
+
+/* ZF_SCALE must be greater than (number of FIXP_ZF)/2
+ because the loss of precision caused by fPow2Div2 in RE8_PPV() */
+//#define ZF_SCALE ((NQ_MAX-3)>>1)
+#define ZF_SCALE ((DFRACT_BITS / 2))
+#define FIXP_ZF FIXP_DBL
+#define INT2ZF(x, s) (FIXP_ZF)((x) << (ZF_SCALE - (s)))
+#define ZF2INT(x) (INT)((x) >> ZF_SCALE)
+
+/* 1.0 in ZF format format */
+#define ONEZF ((FIXP_ZF)INT2ZF(1, 0))
+
+/* static */
+void nearest_neighbor_2D8(FIXP_ZF x[8], int y[8]) {
+ FIXP_ZF s, em, e[8];
+ int i, j, sum;
+
+ /* round x into 2Z^8 i.e. compute y=(y1,...,y8) such that yi = 2[xi/2]
+ where [.] is the nearest integer operator
+ in the mean time, compute sum = y1+...+y8
+ */
+ sum = 0;
+ for (i = 0; i < 8; i++) {
+ FIXP_ZF tmp;
+ /* round to ..., -2, 0, 2, ... ([-1..1[ --> 0) */
+ if (x[i] < (FIXP_ZF)0) {
+ tmp = ONEZF - x[i];
+ y[i] = -2 * ((ZF2INT(tmp)) >> 1);
+ } else {
+ tmp = ONEZF + x[i];
+ y[i] = 2 * ((ZF2INT(tmp)) >> 1);
+ }
+ sum += y[i];
+ }
+ /* check if y1+...+y8 is a multiple of 4
+ if not, y is not round xj in the wrong way where j is defined by
+ j = arg max_i | xi -yi|
+ (this is called the Wagner rule)
+ */
+ if (sum % 4) {
+ /* find j = arg max_i | xi -yi| */
+ em = (FIXP_SGL)0;
+ j = 0;
+ for (i = 0; i < 8; i++) {
+ /* compute ei = xi-yi */
+ e[i] = x[i] - INT2ZF(y[i], 0);
+ }
+ for (i = 0; i < 8; i++) {
+ /* compute |ei| = | xi-yi | */
+ if (e[i] < (FIXP_ZF)0) {
+ s = -e[i];
+ } else {
+ s = e[i];
+ }
+ /* check if |ei| is maximal, if so, set j=i */
+ if (em < s) {
+ em = s;
+ j = i;
+ }
+ }
+ /* round xj in the "wrong way" */
+ if (e[j] < (FIXP_ZF)0) {
+ y[j] -= 2;
+ } else {
+ y[j] += 2;
+ }
+ }
+}
+
+/*--------------------------------------------------------------
+ RE8_PPV(x,y)
+ NEAREST NEIGHBOR SEARCH IN INFINITE LATTICE RE8
+ the algorithm is based on the definition of RE8 as
+ RE8 = (2D8) U (2D8+[1,1,1,1,1,1,1,1])
+ it applies the coset decoding of Sloane and Conway
+ (i) x: point in R^8 in 32-ZF_SCALE.ZF_SCALE format
+ (o) y: point in RE8 (8-dimensional integer vector)
+ --------------------------------------------------------------
+*/
+/* static */
+void RE8_PPV(FIXP_ZF x[], SHORT y[], int r) {
+ int i, y0[8], y1[8];
+ FIXP_ZF x1[8], tmp;
+ FIXP_DBL e;
+
+ /* find the nearest neighbor y0 of x in 2D8 */
+ nearest_neighbor_2D8(x, y0);
+ /* find the nearest neighbor y1 of x in 2D8+(1,...,1) (by coset decoding) */
+ for (i = 0; i < 8; i++) {
+ x1[i] = x[i] - ONEZF;
+ }
+ nearest_neighbor_2D8(x1, y1);
+ for (i = 0; i < 8; i++) {
+ y1[i] += 1;
+ }
+
+ /* compute e0=||x-y0||^2 and e1=||x-y1||^2 */
+ e = (FIXP_DBL)0;
+ for (i = 0; i < 8; i++) {
+ tmp = x[i] - INT2ZF(y0[i], 0);
+ e += fPow2Div2(
+ tmp << r); /* shift left to ensure that no fract part bits get lost. */
+ tmp = x[i] - INT2ZF(y1[i], 0);
+ e -= fPow2Div2(tmp << r);
+ }
+ /* select best candidate y0 or y1 to minimize distortion */
+ if (e < (FIXP_DBL)0) {
+ for (i = 0; i < 8; i++) {
+ y[i] = y0[i];
+ }
+ } else {
+ for (i = 0; i < 8; i++) {
+ y[i] = y1[i];
+ }
+ }
+}
+
+/* table look-up of unsigned value: find i where index >= table[i]
+ Note: range must be >= 2, index must be >= table[0] */
+static int table_lookup(const USHORT *table, unsigned int index, int range) {
+ int i;
+
+ for (i = 4; i < range; i += 4) {
+ if (index < table[i]) {
+ break;
+ }
+ }
+ if (i > range) {
+ i = range;
+ }
+
+ if (index < table[i - 2]) {
+ i -= 2;
+ }
+ if (index < table[i - 1]) {
+ i--;
+ }
+ i--;
+
+ return (i); /* index >= table[i] */
+}
+
+/*--------------------------------------------------------------------------
+ re8_decode_rank_of_permutation(rank, xs, x)
+ DECODING OF THE RANK OF THE PERMUTATION OF xs
+ (i) rank: index (rank) of a permutation
+ (i) xs: signed leader in RE8 (8-dimensional integer vector)
+ (o) x: point in RE8 (8-dimensional integer vector)
+ --------------------------------------------------------------------------
+ */
+static void re8_decode_rank_of_permutation(int rank, int *xs, SHORT x[8]) {
+ INT a[8], w[8], B, fac, fac_B, target;
+ int i, j;
+
+ /* --- pre-processing based on the signed leader xs ---
+ - compute the alphabet a=[a[0] ... a[q-1]] of x (q elements)
+ such that a[0]!=...!=a[q-1]
+ it is assumed that xs is sorted in the form of a signed leader
+ which can be summarized in 2 requirements:
+ a) |xs[0]| >= |xs[1]| >= |xs[2]| >= ... >= |xs[7]|
+ b) if |xs[i]|=|xs[i-1]|, xs[i]>=xs[i+1]
+ where |.| indicates the absolute value operator
+ - compute q (the number of symbols in the alphabet)
+ - compute w[0..q-1] where w[j] counts the number of occurences of
+ the symbol a[j] in xs
+ - compute B = prod_j=0..q-1 (w[j]!) where .! is the factorial */
+ /* xs[i], xs[i-1] and ptr_w/a*/
+ j = 0;
+ w[j] = 1;
+ a[j] = xs[0];
+ B = 1;
+ for (i = 1; i < 8; i++) {
+ if (xs[i] != xs[i - 1]) {
+ j++;
+ w[j] = 1;
+ a[j] = xs[i];
+ } else {
+ w[j]++;
+ B *= w[j];
+ }
+ }
+
+ /* --- actual rank decoding ---
+ the rank of x (where x is a permutation of xs) is based on
+ Schalkwijk's formula
+ it is given by rank=sum_{k=0..7} (A_k * fac_k/B_k)
+ the decoding of this rank is sequential and reconstructs x[0..7]
+ element by element from x[0] to x[7]
+ [the tricky part is the inference of A_k for each k...]
+ */
+
+ if (w[0] == 8) {
+ for (i = 0; i < 8; i++) {
+ x[i] = a[0]; /* avoid fac of 40320 */
+ }
+ } else {
+ target = rank * B;
+ fac_B = 1;
+ /* decode x element by element */
+ for (i = 0; i < 8; i++) {
+ fac = fac_B * fdk_dec_tab_factorial[i]; /* fac = 1..5040 */
+ j = -1;
+ do {
+ target -= w[++j] * fac;
+ } while (target >= 0); /* max of 30 tests / SV */
+ x[i] = a[j];
+ /* update rank, denominator B (B_k) and counter w[j] */
+ target += w[j] * fac; /* target = fac_B*B*rank */
+ fac_B *= w[j];
+ w[j]--;
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------
+ re8_decode_base_index(n, I, y)
+ DECODING OF AN INDEX IN Qn (n=0,2,3 or 4)
+ (i) n: codebook number (*n is an integer defined in {0,2,3,4})
+ (i) I: index of c (pointer to unsigned 16-bit word)
+ (o) y: point in RE8 (8-dimensional integer vector)
+ note: the index I is defined as a 32-bit word, but only
+ 16 bits are required (long can be replaced by unsigned integer)
+ --------------------------------------------------------------------------
+ */
+static void re8_decode_base_index(int *n, UINT index, SHORT y[8]) {
+ int i, im, t, sign_code, ka, ks, rank, leader[8];
+
+ if (*n < 2) {
+ for (i = 0; i < 8; i++) {
+ y[i] = 0;
+ }
+ } else {
+ // index = (unsigned int)*I;
+ /* search for the identifier ka of the absolute leader (table-lookup)
+ Q2 is a subset of Q3 - the two cases are considered in the same branch
+ */
+ switch (*n) {
+ case 2:
+ case 3:
+ i = table_lookup(fdk_dec_I3, index, NB_LDQ3);
+ ka = fdk_dec_A3[i];
+ break;
+ case 4:
+ i = table_lookup(fdk_dec_I4, index, NB_LDQ4);
+ ka = fdk_dec_A4[i];
+ break;
+ default:
+ FDK_ASSERT(0);
+ return;
+ }
+ /* reconstruct the absolute leader */
+ for (i = 0; i < 8; i++) {
+ leader[i] = fdk_dec_Da[ka][i];
+ }
+ /* search for the identifier ks of the signed leader (table look-up)
+ (this search is focused based on the identifier ka of the absolute
+ leader)*/
+ t = fdk_dec_Ia[ka];
+ im = fdk_dec_Ns[ka];
+ ks = table_lookup(fdk_dec_Is + t, index, im);
+
+ /* reconstruct the signed leader from its sign code */
+ sign_code = 2 * fdk_dec_Ds[t + ks];
+ for (i = 7; i >= 0; i--) {
+ leader[i] *= (1 - (sign_code & 2));
+ sign_code >>= 1;
+ }
+
+ /* compute and decode the rank of the permutation */
+ rank = index - fdk_dec_Is[t + ks]; /* rank = index - cardinality offset */
+
+ re8_decode_rank_of_permutation(rank, leader, y);
+ }
+ return;
+}
+
+/* re8_y2k(y,m,k)
+ VORONOI INDEXING (INDEX DECODING) k -> y
+ (i) k: Voronoi index k[0..7]
+ (i) m: Voronoi modulo (m = 2^r = 1<<r, where r is integer >=2)
+ (i) r: Voronoi order (m = 2^r = 1<<r, where r is integer >=2)
+ (o) y: 8-dimensional point y[0..7] in RE8
+ */
+static void re8_k2y(int *k, int r, SHORT *y) {
+ int i, tmp, sum;
+ SHORT v[8];
+ FIXP_ZF zf[8];
+
+ FDK_ASSERT(r <= ZF_SCALE);
+
+ /* compute y = k M and z=(y-a)/m, where
+ M = [4 ]
+ [2 2 ]
+ [| \ ]
+ [2 2 ]
+ [1 1 _ 1 1]
+ a=(2,0,...,0)
+ m = 1<<r
+ */
+ for (i = 0; i < 8; i++) {
+ y[i] = k[7];
+ }
+ zf[7] = INT2ZF(y[7], r);
+ sum = 0;
+ for (i = 6; i >= 1; i--) {
+ tmp = 2 * k[i];
+ sum += tmp;
+ y[i] += tmp;
+ zf[i] = INT2ZF(y[i], r);
+ }
+ y[0] += (4 * k[0] + sum);
+ zf[0] = INT2ZF(y[0] - 2, r);
+ /* find nearest neighbor v of z in infinite RE8 */
+ RE8_PPV(zf, v, r);
+ /* compute y -= m v */
+ for (i = 0; i < 8; i++) {
+ y[i] -= (SHORT)(v[i] << r);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ RE8_dec(n, I, k, y)
+ MULTI-RATE INDEXING OF A POINT y in THE LATTICE RE8 (INDEX DECODING)
+ (i) n: codebook number (*n is an integer defined in {0,2,3,4,..,n_max}). n_max
+ = 36 (i) I: index of c (pointer to unsigned 16-bit word) (i) k: index of v
+ (8-dimensional vector of binary indices) = Voronoi index (o) y: point in RE8
+ (8-dimensional integer vector) note: the index I is defined as a 32-bit word,
+ but only 16 bits are required (long can be replaced by unsigned integer)
+
+ return 0 on success, -1 on error.
+ --------------------------------------------------------------------------
+ */
+static int RE8_dec(int n, int I, int *k, FIXP_DBL *y) {
+ SHORT v[8];
+ SHORT _y[8];
+ UINT r;
+ int i;
+
+ /* Check bound of codebook qn */
+ if (n > NQ_MAX) {
+ return -1;
+ }
+
+ /* decode the sub-indices I and kv[] according to the codebook number n:
+ if n=0,2,3,4, decode I (no Voronoi extension)
+ if n>4, Voronoi extension is used, decode I and kv[] */
+ if (n <= 4) {
+ re8_decode_base_index(&n, I, _y);
+ for (i = 0; i < 8; i++) {
+ y[i] = (LONG)_y[i];
+ }
+ } else {
+ /* compute the Voronoi modulo m = 2^r where r is extension order */
+ r = ((n - 3) >> 1);
+
+ while (n > 4) {
+ n -= 2;
+ }
+ /* decode base codebook index I into c (c is an element of Q3 or Q4)
+ [here c is stored in y to save memory] */
+ re8_decode_base_index(&n, I, _y);
+ /* decode Voronoi index k[] into v */
+ re8_k2y(k, r, v);
+ /* reconstruct y as y = m c + v (with m=2^r, r integer >=1) */
+ for (i = 0; i < 8; i++) {
+ y[i] = (LONG)((_y[i] << r) + v[i]);
+ }
+ }
+ return 0;
+}
+
+/**************************/
+/* start LPC decode stuff */
+/**************************/
+//#define M 16
+#define FREQ_MAX 6400.0f
+#define FREQ_DIV 400.0f
+#define LSF_GAP 50.0f
+
+/**
+ * \brief calculate inverse weighting factor and add non-weighted residual
+ * LSF vector to first stage LSF approximation
+ * \param lsfq first stage LSF approximation values.
+ * \param xq weighted residual LSF vector
+ * \param nk_mode code book number coding mode.
+ */
+static void lsf_weight_2st(FIXP_LPC *lsfq, FIXP_DBL *xq, int nk_mode) {
+ FIXP_LPC d[M_LP_FILTER_ORDER + 1];
+ FIXP_SGL factor;
+ LONG w; /* inverse weight factor */
+ int i;
+
+ /* compute lsf distance */
+ d[0] = lsfq[0];
+ d[M_LP_FILTER_ORDER] =
+ FL2FXCONST_LPC(FREQ_MAX / (1 << LSF_SCALE)) - lsfq[M_LP_FILTER_ORDER - 1];
+ for (i = 1; i < M_LP_FILTER_ORDER; i++) {
+ d[i] = lsfq[i] - lsfq[i - 1];
+ }
+
+ switch (nk_mode) {
+ case 0:
+ factor = FL2FXCONST_SGL(2.0f * 60.0f / FREQ_DIV);
+ break; /* abs */
+ case 1:
+ factor = FL2FXCONST_SGL(2.0f * 65.0f / FREQ_DIV);
+ break; /* mid */
+ case 2:
+ factor = FL2FXCONST_SGL(2.0f * 64.0f / FREQ_DIV);
+ break; /* rel1 */
+ default:
+ factor = FL2FXCONST_SGL(2.0f * 63.0f / FREQ_DIV);
+ break; /* rel2 */
+ }
+ /* add non-weighted residual LSF vector to LSF1st */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ w = (LONG)fMultDiv2(factor, sqrtFixp(fMult(d[i], d[i + 1])));
+ lsfq[i] = fAddSaturate(lsfq[i], FX_DBL2FX_LPC((FIXP_DBL)(w * (LONG)xq[i])));
+ }
+
+ return;
+}
+
+/**
+ * \brief decode nqn amount of code book numbers. These values determine the
+ * amount of following bits for nqn AVQ RE8 vectors.
+ * \param nk_mode quantization mode.
+ * \param nqn amount code book number to read.
+ * \param qn pointer to output buffer to hold decoded code book numbers qn.
+ */
+static void decode_qn(HANDLE_FDK_BITSTREAM hBs, int nk_mode, int nqn,
+ int qn[]) {
+ int n;
+
+ if (nk_mode == 1) { /* nk mode 1 */
+ /* Unary code for mid LPC1/LPC3 */
+ /* Q0=0, Q2=10, Q3=110, ... */
+ for (n = 0; n < nqn; n++) {
+ qn[n] = get_vlclbf(hBs);
+ if (qn[n] > 0) {
+ qn[n]++;
+ }
+ }
+ } else { /* nk_mode 0, 3 and 2 */
+ /* 2 bits to specify Q2,Q3,Q4,ext */
+ for (n = 0; n < nqn; n++) {
+ qn[n] = 2 + FDKreadBits(hBs, 2);
+ }
+ if (nk_mode == 2) {
+ /* Unary code for rel LPC1/LPC3 */
+ /* Q0 = 0, Q5=10, Q6=110, ... */
+ for (n = 0; n < nqn; n++) {
+ if (qn[n] > 4) {
+ qn[n] = get_vlclbf(hBs);
+ if (qn[n] > 0) qn[n] += 4;
+ }
+ }
+ } else { /* nk_mode == (0 and 3) */
+ /* Unary code for abs and rel LPC0/LPC2 */
+ /* Q5 = 0, Q6=10, Q0=110, Q7=1110, ... */
+ for (n = 0; n < nqn; n++) {
+ if (qn[n] > 4) {
+ qn[n] = get_vlclbf(hBs);
+ switch (qn[n]) {
+ case 0:
+ qn[n] = 5;
+ break;
+ case 1:
+ qn[n] = 6;
+ break;
+ case 2:
+ qn[n] = 0;
+ break;
+ default:
+ qn[n] += 4;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * \brief reorder LSF coefficients to minimum distance.
+ * \param lsf pointer to buffer containing LSF coefficients and where reordered
+ * LSF coefficients will be stored into, scaled by LSF_SCALE.
+ * \param min_dist min distance scaled by LSF_SCALE
+ * \param n number of LSF/LSP coefficients.
+ */
+static void reorder_lsf(FIXP_LPC *lsf, FIXP_LPC min_dist, int n) {
+ FIXP_LPC lsf_min;
+ int i;
+
+ lsf_min = min_dist;
+ for (i = 0; i < n; i++) {
+ if (lsf[i] < lsf_min) {
+ lsf[i] = lsf_min;
+ }
+ lsf_min = fAddSaturate(lsf[i], min_dist);
+ }
+
+ /* reverse */
+ lsf_min = FL2FXCONST_LPC(FREQ_MAX / (1 << LSF_SCALE)) - min_dist;
+ for (i = n - 1; i >= 0; i--) {
+ if (lsf[i] > lsf_min) {
+ lsf[i] = lsf_min;
+ }
+
+ lsf_min = lsf[i] - min_dist;
+ }
+}
+
+/**
+ * \brief First stage approximation
+ * \param hBs bitstream handle as data source
+ * \param lsfq pointer to output buffer to hold LPC coefficients scaled by
+ * LSF_SCALE.
+ */
+static void vlpc_1st_dec(
+ HANDLE_FDK_BITSTREAM hBs, /* input: codebook index */
+ FIXP_LPC *lsfq /* i/o: i:prediction o:quantized lsf */
+) {
+ const FIXP_LPC *p_dico;
+ int i, index;
+
+ index = FDKreadBits(hBs, 8);
+ p_dico = &fdk_dec_dico_lsf_abs_8b[index * M_LP_FILTER_ORDER];
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsfq[i] = p_dico[i];
+ }
+}
+
+/**
+ * \brief Do first stage approximation weighting and multiply with AVQ
+ * refinement.
+ * \param hBs bitstream handle data ssource.
+ * \param lsfq buffer holding 1st stage approx, 2nd stage approx is added to
+ * this values.
+ * \param nk_mode quantization mode.
+ * \return 0 on success, -1 on error.
+ */
+static int vlpc_2st_dec(
+ HANDLE_FDK_BITSTREAM hBs,
+ FIXP_LPC *lsfq, /* i/o: i:1st stage o:1st+2nd stage */
+ int nk_mode /* input: 0=abs, >0=rel */
+) {
+ int err;
+ FIXP_DBL xq[M_LP_FILTER_ORDER]; /* weighted residual LSF vector */
+
+ /* Decode AVQ refinement */
+ { err = CLpc_DecodeAVQ(hBs, xq, nk_mode, 2, 8); }
+ if (err != 0) {
+ return -1;
+ }
+
+ /* add non-weighted residual LSF vector to LSF1st */
+ lsf_weight_2st(lsfq, xq, nk_mode);
+
+ /* reorder */
+ reorder_lsf(lsfq, FL2FXCONST_LPC(LSF_GAP / (1 << LSF_SCALE)),
+ M_LP_FILTER_ORDER);
+
+ return 0;
+}
+
+/*
+ * Externally visible functions
+ */
+
+int CLpc_DecodeAVQ(HANDLE_FDK_BITSTREAM hBs, FIXP_DBL *pOutput, int nk_mode,
+ int no_qn, int length) {
+ int i, l;
+
+ for (i = 0; i < length; i += 8 * no_qn) {
+ int qn[2], nk, n, I;
+ int kv[8] = {0};
+
+ decode_qn(hBs, nk_mode, no_qn, qn);
+
+ for (l = 0; l < no_qn; l++) {
+ if (qn[l] == 0) {
+ FDKmemclear(&pOutput[i + l * 8], 8 * sizeof(FIXP_DBL));
+ }
+
+ /* Voronoi extension order ( nk ) */
+ nk = 0;
+ n = qn[l];
+ if (qn[l] > 4) {
+ nk = (qn[l] - 3) >> 1;
+ n = qn[l] - nk * 2;
+ }
+
+ /* Base codebook index, in reverse bit group order (!) */
+ I = FDKreadBits(hBs, 4 * n);
+
+ if (nk > 0) {
+ int j;
+
+ for (j = 0; j < 8; j++) {
+ kv[j] = FDKreadBits(hBs, nk);
+ }
+ }
+
+ if (RE8_dec(qn[l], I, kv, &pOutput[i + l * 8]) != 0) {
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+int CLpc_Read(HANDLE_FDK_BITSTREAM hBs, FIXP_LPC lsp[][M_LP_FILTER_ORDER],
+ FIXP_LPC lpc4_lsf[M_LP_FILTER_ORDER],
+ FIXP_LPC lsf_adaptive_mean_cand[M_LP_FILTER_ORDER],
+ FIXP_SGL pStability[], UCHAR *mod, int first_lpd_flag,
+ int last_lpc_lost, int last_frame_ok) {
+ int i, k, err;
+ int mode_lpc_bin = 0; /* mode_lpc bitstream representation */
+ int lpc_present[5] = {0, 0, 0, 0, 0};
+ int lpc0_available = 1;
+ int s = 0;
+ int l = 3;
+ const int nbDiv = NB_DIV;
+
+ lpc_present[4 >> s] = 1; /* LPC4 */
+
+ /* Decode LPC filters in the following order: LPC 4,0,2,1,3 */
+
+ /*** Decode LPC4 ***/
+ vlpc_1st_dec(hBs, lsp[4 >> s]);
+ err = vlpc_2st_dec(hBs, lsp[4 >> s], 0); /* nk_mode = 0 */
+ if (err != 0) {
+ return err;
+ }
+
+ /*** Decode LPC0 and LPC2 ***/
+ k = 0;
+ if (!first_lpd_flag) {
+ lpc_present[0] = 1;
+ lpc0_available = !last_lpc_lost;
+ /* old LPC4 is new LPC0 */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[0][i] = lpc4_lsf[i];
+ }
+ /* skip LPC0 and continue with LPC2 */
+ k = 2;
+ }
+
+ for (; k < l; k += 2) {
+ int nk_mode = 0;
+
+ if ((k == 2) && (mod[0] == 3)) {
+ break; /* skip LPC2 */
+ }
+
+ lpc_present[k >> s] = 1;
+
+ mode_lpc_bin = FDKreadBit(hBs);
+
+ if (mode_lpc_bin == 0) {
+ /* LPC0/LPC2: Abs */
+ vlpc_1st_dec(hBs, lsp[k >> s]);
+ } else {
+ /* LPC0/LPC2: RelR */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[k >> s][i] = lsp[4 >> s][i];
+ }
+ nk_mode = 3;
+ }
+
+ err = vlpc_2st_dec(hBs, lsp[k >> s], nk_mode);
+ if (err != 0) {
+ return err;
+ }
+ }
+
+ /*** Decode LPC1 ***/
+ if (mod[0] < 2) { /* else: skip LPC1 */
+ lpc_present[1] = 1;
+ mode_lpc_bin = get_vlclbf_n(hBs, 2);
+
+ switch (mode_lpc_bin) {
+ case 1:
+ /* LPC1: abs */
+ vlpc_1st_dec(hBs, lsp[1]);
+ err = vlpc_2st_dec(hBs, lsp[1], 0);
+ if (err != 0) {
+ return err;
+ }
+ break;
+ case 2:
+ /* LPC1: mid0 (no second stage AVQ quantizer in this case) */
+ if (lpc0_available) { /* LPC0/lsf[0] might be zero some times */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[1][i] = (lsp[0][i] >> 1) + (lsp[2][i] >> 1);
+ }
+ } else {
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[1][i] = lsp[2][i];
+ }
+ }
+ break;
+ case 0:
+ /* LPC1: RelR */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[1][i] = lsp[2][i];
+ }
+ err = vlpc_2st_dec(hBs, lsp[1], 2 << s);
+ if (err != 0) {
+ return err;
+ }
+ break;
+ }
+ }
+
+ /*** Decode LPC3 ***/
+ if ((mod[2] < 2)) { /* else: skip LPC3 */
+ int nk_mode = 0;
+ lpc_present[3] = 1;
+
+ mode_lpc_bin = get_vlclbf_n(hBs, 3);
+
+ switch (mode_lpc_bin) {
+ case 1:
+ /* LPC3: abs */
+ vlpc_1st_dec(hBs, lsp[3]);
+ break;
+ case 0:
+ /* LPC3: mid */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[3][i] = (lsp[2][i] >> 1) + (lsp[4][i] >> 1);
+ }
+ nk_mode = 1;
+ break;
+ case 2:
+ /* LPC3: relL */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[3][i] = lsp[2][i];
+ }
+ nk_mode = 2;
+ break;
+ case 3:
+ /* LPC3: relR */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[3][i] = lsp[4][i];
+ }
+ nk_mode = 2;
+ break;
+ }
+ err = vlpc_2st_dec(hBs, lsp[3], nk_mode);
+ if (err != 0) {
+ return err;
+ }
+ }
+
+ if (!lpc0_available && !last_frame_ok) {
+ /* LPC(0) was lost. Use next available LPC(k) instead */
+ for (k = 1; k < (nbDiv + 1); k++) {
+ if (lpc_present[k]) {
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+#define LSF_INIT_TILT (0.25f)
+ if (mod[0] > 0) {
+ lsp[0][i] = FX_DBL2FX_LPC(
+ fMult(lsp[k][i], FL2FXCONST_SGL(1.0f - LSF_INIT_TILT)) +
+ fMult(fdk_dec_lsf_init[i], FL2FXCONST_SGL(LSF_INIT_TILT)));
+ } else {
+ lsp[0][i] = lsp[k][i];
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lpc4_lsf[i] = lsp[4 >> s][i];
+ }
+
+ {
+ FIXP_DBL divFac;
+ int last, numLpc = 0;
+
+ i = nbDiv;
+ do {
+ numLpc += lpc_present[i--];
+ } while (i >= 0 && numLpc < 3);
+
+ last = i;
+
+ switch (numLpc) {
+ case 3:
+ divFac = FL2FXCONST_DBL(1.0f / 3.0f);
+ break;
+ case 2:
+ divFac = FL2FXCONST_DBL(1.0f / 2.0f);
+ break;
+ default:
+ divFac = FL2FXCONST_DBL(1.0f);
+ break;
+ }
+
+ /* get the adaptive mean for the next (bad) frame */
+ for (k = 0; k < M_LP_FILTER_ORDER; k++) {
+ FIXP_DBL tmp = (FIXP_DBL)0;
+ for (i = nbDiv; i > last; i--) {
+ if (lpc_present[i]) {
+ tmp = fMultAdd(tmp >> 1, lsp[i][k], divFac);
+ }
+ }
+ lsf_adaptive_mean_cand[k] = FX_DBL2FX_LPC(tmp);
+ }
+ }
+
+ /* calculate stability factor Theta. Needed for ACELP decoder and concealment
+ */
+ {
+ FIXP_LPC *lsf_prev, *lsf_curr;
+ k = 0;
+
+ FDK_ASSERT(lpc_present[0] == 1 && lpc_present[4 >> s] == 1);
+ lsf_prev = lsp[0];
+ for (i = 1; i < (nbDiv + 1); i++) {
+ if (lpc_present[i]) {
+ FIXP_DBL tmp = (FIXP_DBL)0;
+ int j;
+ lsf_curr = lsp[i];
+
+ /* sum = tmp * 2^(LSF_SCALE*2 + 4) */
+ for (j = 0; j < M_LP_FILTER_ORDER; j++) {
+ tmp += fPow2Div2((FIXP_SGL)(lsf_curr[j] - lsf_prev[j])) >> 3;
+ }
+
+ /* tmp = (float)(FL2FXCONST_DBL(1.25f) - fMult(tmp,
+ * FL2FXCONST_DBL(1/400000.0f))); */
+ tmp = FL2FXCONST_DBL(1.25f / (1 << LSF_SCALE)) -
+ fMult(tmp, FL2FXCONST_DBL((1 << (LSF_SCALE + 4)) / 400000.0f));
+ if (tmp >= FL2FXCONST_DBL(1.0f / (1 << LSF_SCALE))) {
+ pStability[k] = FL2FXCONST_SGL(1.0f / 2.0f);
+ } else if (tmp < FL2FXCONST_DBL(0.0f)) {
+ pStability[k] = FL2FXCONST_SGL(0.0f);
+ } else {
+ pStability[k] = FX_DBL2FX_SGL(tmp << (LSF_SCALE - 1));
+ }
+
+ lsf_prev = lsf_curr;
+ k = i;
+ } else {
+ /* Mark stability value as undefined. */
+ pStability[i] = (FIXP_SGL)-1;
+ }
+ }
+ }
+
+ /* convert into LSP domain */
+ for (i = 0; i < (nbDiv + 1); i++) {
+ if (lpc_present[i]) {
+ for (k = 0; k < M_LP_FILTER_ORDER; k++) {
+ lsp[i][k] = FX_DBL2FX_LPC(
+ fixp_cos(fMult(lsp[i][k],
+ FL2FXCONST_SGL((1 << LSPARG_SCALE) * M_PI / 6400.0)),
+ LSF_SCALE - LSPARG_SCALE));
+ }
+ }
+ }
+
+ return 0;
+}
+
+void CLpc_Conceal(FIXP_LPC lsp[][M_LP_FILTER_ORDER],
+ FIXP_LPC lpc4_lsf[M_LP_FILTER_ORDER],
+ FIXP_LPC lsf_adaptive_mean[M_LP_FILTER_ORDER],
+ const int first_lpd_flag) {
+ int i, j;
+
+#define BETA (FL2FXCONST_SGL(0.25f))
+#define ONE_BETA (FL2FXCONST_SGL(0.75f))
+#define BFI_FAC (FL2FXCONST_SGL(0.90f))
+#define ONE_BFI_FAC (FL2FXCONST_SGL(0.10f))
+
+ /* Frame loss concealment (could be improved) */
+
+ if (first_lpd_flag) {
+ /* Reset past LSF values */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[0][i] = lpc4_lsf[i] = fdk_dec_lsf_init[i];
+ }
+ } else {
+ /* old LPC4 is new LPC0 */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[0][i] = lpc4_lsf[i];
+ }
+ }
+
+ /* LPC1 */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ FIXP_LPC lsf_mean = FX_DBL2FX_LPC(fMult(BETA, fdk_dec_lsf_init[i]) +
+ fMult(ONE_BETA, lsf_adaptive_mean[i]));
+
+ lsp[1][i] = FX_DBL2FX_LPC(fMult(BFI_FAC, lpc4_lsf[i]) +
+ fMult(ONE_BFI_FAC, lsf_mean));
+ }
+
+ /* LPC2 - LPC4 */
+ for (j = 2; j <= 4; j++) {
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ /* lsf_mean[i] = FX_DBL2FX_LPC(fMult((FIXP_LPC)(BETA + j *
+ FL2FXCONST_LPC(0.1f)), fdk_dec_lsf_init[i])
+ + fMult((FIXP_LPC)(ONE_BETA - j *
+ FL2FXCONST_LPC(0.1f)), lsf_adaptive_mean[i])); */
+
+ FIXP_LPC lsf_mean = FX_DBL2FX_LPC(
+ fMult((FIXP_SGL)(BETA + (FIXP_SGL)(j * (INT)FL2FXCONST_SGL(0.1f))),
+ (FIXP_SGL)fdk_dec_lsf_init[i]) +
+ fMult(
+ (FIXP_SGL)(ONE_BETA - (FIXP_SGL)(j * (INT)FL2FXCONST_SGL(0.1f))),
+ lsf_adaptive_mean[i]));
+
+ lsp[j][i] = FX_DBL2FX_LPC(fMult(BFI_FAC, lsp[j - 1][i]) +
+ fMult(ONE_BFI_FAC, lsf_mean));
+ }
+ }
+
+ /* Update past values for the future */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lpc4_lsf[i] = lsp[4][i];
+ }
+
+ /* convert into LSP domain */
+ for (j = 0; j < 5; j++) {
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[j][i] = FX_DBL2FX_LPC(fixp_cos(
+ fMult(lsp[j][i], FL2FXCONST_SGL((1 << LSPARG_SCALE) * M_PI / 6400.0)),
+ LSF_SCALE - LSPARG_SCALE));
+ }
+ }
+}
+
+void E_LPC_a_weight(FIXP_LPC *wA, const FIXP_LPC *A, int m) {
+ FIXP_DBL f;
+ int i;
+
+ f = FL2FXCONST_DBL(0.92f);
+ for (i = 0; i < m; i++) {
+ wA[i] = FX_DBL2FX_LPC(fMult(A[i], f));
+ f = fMult(f, FL2FXCONST_DBL(0.92f));
+ }
+}
+
+void CLpd_DecodeGain(FIXP_DBL *gain, INT *gain_e, int gain_code) {
+ /* gain * 2^(gain_e) = 10^(gain_code/28) */
+ *gain = fLdPow(
+ FL2FXCONST_DBL(3.3219280948873623478703194294894 / 4.0), /* log2(10)*/
+ 2,
+ fMultDiv2((FIXP_DBL)gain_code << (DFRACT_BITS - 1 - 7),
+ FL2FXCONST_DBL(2.0f / 28.0f)),
+ 7, gain_e);
+}
+
+ /**
+ * \brief * Find the polynomial F1(z) or F2(z) from the LSPs.
+ * This is performed by expanding the product polynomials:
+ *
+ * F1(z) = product ( 1 - 2 LSP_i z^-1 + z^-2 )
+ * i=0,2,4,6,8
+ * F2(z) = product ( 1 - 2 LSP_i z^-1 + z^-2 )
+ * i=1,3,5,7,9
+ *
+ * where LSP_i are the LSPs in the cosine domain.
+ * R.A.Salami October 1990
+ * \param lsp input, line spectral freq. (cosine domain)
+ * \param f output, the coefficients of F1 or F2, scaled by 8 bits
+ * \param n no of coefficients (m/2)
+ * \param flag 1 : F1(z) ; 2 : F2(z)
+ */
+
+#define SF_F 8
+
+static void get_lsppol(FIXP_LPC lsp[], FIXP_DBL f[], int n, int flag) {
+ FIXP_DBL b;
+ FIXP_LPC *plsp;
+ int i, j;
+
+ plsp = lsp + flag - 1;
+ f[0] = FL2FXCONST_DBL(1.0f / (1 << SF_F));
+ b = -FX_LPC2FX_DBL(*plsp);
+ f[1] = b >> (SF_F - 1);
+ for (i = 2; i <= n; i++) {
+ plsp += 2;
+ b = -FX_LPC2FX_DBL(*plsp);
+ f[i] = ((fMultDiv2(b, f[i - 1]) << 1) + (f[i - 2])) << 1;
+ for (j = i - 1; j > 1; j--) {
+ f[j] = f[j] + (fMultDiv2(b, f[j - 1]) << 2) + f[j - 2];
+ }
+ f[1] = f[1] + (b >> (SF_F - 1));
+ }
+ return;
+}
+
+#define NC M_LP_FILTER_ORDER / 2
+
+/**
+ * \brief lsp input LSP vector
+ * \brief a output LP filter coefficient vector scaled by SF_A_COEFFS.
+ */
+void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp) {
+ FIXP_DBL f1[NC + 1], f2[NC + 1];
+ int i, k;
+
+ /*-----------------------------------------------------*
+ * Find the polynomials F1(z) and F2(z) *
+ *-----------------------------------------------------*/
+
+ get_lsppol(lsp, f1, NC, 1);
+ get_lsppol(lsp, f2, NC, 2);
+
+ /*-----------------------------------------------------*
+ * Multiply F1(z) by (1+z^-1) and F2(z) by (1-z^-1) *
+ *-----------------------------------------------------*/
+ for (i = NC; i > 0; i--) {
+ f1[i] += f1[i - 1];
+ f2[i] -= f2[i - 1];
+ }
+
+ FIXP_DBL aDBL[M_LP_FILTER_ORDER];
+
+ for (i = 1, k = M_LP_FILTER_ORDER - 1; i <= NC; i++, k--) {
+ FIXP_DBL tmp1, tmp2;
+
+ tmp1 = f1[i] >> 1;
+ tmp2 = f2[i] >> 1;
+
+ aDBL[i - 1] = (tmp1 + tmp2);
+ aDBL[k] = (tmp1 - tmp2);
+ }
+
+ int headroom_a = getScalefactor(aDBL, M_LP_FILTER_ORDER);
+
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ a[i] = FX_DBL2FX_LPC(aDBL[i] << headroom_a);
+ }
+
+ *a_exp = 8 - headroom_a;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_lpc.h b/fdk-aac/libAACdec/src/usacdec_lpc.h
new file mode 100644
index 0000000..a6713c1
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_lpc.h
@@ -0,0 +1,190 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Matthias Hildenbrand, Manuel Jander
+
+ Description: USAC LPC/AVQ decode
+
+*******************************************************************************/
+
+#ifndef USACDEC_LPC_H
+#define USACDEC_LPC_H
+
+#include "channelinfo.h"
+#include "common_fix.h"
+#include "FDK_bitstream.h"
+#include "usacdec_rom.h"
+
+#define LSPARG_SCALE 10
+
+/**
+ * \brief AVQ (refinement) decode
+ * \param hBs bitstream handle
+ * \param lsfq buffer for AVQ decode output.
+ * \param nk_mode quantization mode.
+ * \param nqn amount of split/interleaved RE8 vectors.
+ * \param total amount of individual data values to decode.
+ * \return 0 on success, -1 on error.
+ */
+int CLpc_DecodeAVQ(HANDLE_FDK_BITSTREAM hBs, FIXP_DBL *lsfq, int nk_mode,
+ int nqn, int length);
+
+/**
+ * \brief Read and decode LPC coeficient sets. First stage approximation + AVQ
+ * decode.
+ * \param[in] hBs bitstream handle to read data from.
+ * \param[out] lsp buffer into which the decoded LSP coefficients will be stored
+ * into.
+ * \param[in,out] lpc4_lsf buffer into which the decoded LCP4 LSF coefficients
+ * will be stored into (persistent).
+ * \param[out] lsf_adaptive_mean_cand lsf adaptive mean vector needed for
+ * concealment.
+ * \param[out] pStability array with stability values for the ACELP decoder (and
+ * concealment).
+ * \param[in] mod array which defines modes (ACELP, TCX20|40|80) are used in
+ * the current superframe.
+ * \param[in] first_lpd_flag indicates the presence of LPC0
+ * \param[in] last_lpc_lost indicate that LPC4 of previous frame was lost.
+ * \param[in] last_frame_ok indicate that the last frame was ok.
+ * \return 0 on success, -1 on error.
+ */
+int CLpc_Read(HANDLE_FDK_BITSTREAM hBs, FIXP_LPC lsp[][M_LP_FILTER_ORDER],
+ FIXP_LPC lpc4_lsf[M_LP_FILTER_ORDER],
+ FIXP_LPC lsf_adaptive_mean_cand[M_LP_FILTER_ORDER],
+ FIXP_SGL pStability[], UCHAR *mod, int first_lpd_flag,
+ int last_lpc_lost, int last_frame_ok);
+
+/**
+ * \brief Generate LPC coefficient sets in case frame loss.
+ * \param lsp buffer into which the decoded LSP coefficients will be stored
+ * into.
+ * \param lpc4_lsf buffer into which the decoded LCP4 LSF coefficients will be
+ * stored into (persistent).
+ * \param isf_adaptive_mean
+ * \param first_lpd_flag indicates the previous LSF4 coefficients lpc4_lsf[] are
+ * not valid.
+ */
+void CLpc_Conceal(FIXP_LPC lsp[][M_LP_FILTER_ORDER],
+ FIXP_LPC lpc4_lsf[M_LP_FILTER_ORDER],
+ FIXP_LPC isf_adaptive_mean[M_LP_FILTER_ORDER],
+ const int first_lpd_flag);
+
+/**
+ * \brief apply absolute weighting
+ * \param A weighted LPC coefficient vector output. The first coeffcient is
+ * implicitly 1.0
+ * \param A LPC coefficient vector. The first coeffcient is implicitly 1.0
+ * \param m length of vector A
+ */
+/* static */
+void E_LPC_a_weight(FIXP_LPC *wA, const FIXP_LPC *A, const int m);
+
+/**
+ * \brief decode TCX/FAC gain. In case of TCX the lg/sqrt(rms) part
+ * must still be applied to obtain the gain value.
+ * \param gain (o) pointer were the gain mantissa is stored into.
+ * \param gain_e (o) pointer were the gain exponent is stored into.
+ * \param gain_code (i) the 7 bit binary word from the bitstream
+ * representing the gain.
+ */
+void CLpd_DecodeGain(FIXP_DBL *gain, INT *gain_e, int gain_code);
+
+/**
+ * \brief convert LSP coefficients into LP domain.
+ */
+void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp);
+
+#endif /* USACDEC_LPC_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_lpd.cpp b/fdk-aac/libAACdec/src/usacdec_lpd.cpp
new file mode 100644
index 0000000..2110172
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_lpd.cpp
@@ -0,0 +1,2029 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description: USAC Linear Prediction Domain coding
+
+*******************************************************************************/
+
+#include "usacdec_lpd.h"
+
+#include "usacdec_rom.h"
+#include "usacdec_fac.h"
+#include "usacdec_lpc.h"
+#include "FDK_tools_rom.h"
+#include "fft.h"
+#include "mdct.h"
+#include "usacdec_acelp.h"
+#include "overlapadd.h"
+
+#include "conceal.h"
+
+#include "block.h"
+
+#define SF_PITCH_TRACK 6
+#define SF_GAIN 3
+#define MIN_VAL FL2FXCONST_DBL(0.0f)
+#define MAX_VAL (FIXP_DBL) MAXVAL_DBL
+
+#include "ac_arith_coder.h"
+
+void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
+ const FIXP_SGL *filt, INT stop, int len) {
+ INT i, j;
+ FIXP_DBL tmp;
+
+ for (i = 0; i < stop; i++) {
+ tmp = fMultDiv2(noise[i], filt[0]); // Filt in Q-1.16
+ for (j = 1; j <= len; j++) {
+ tmp += fMultDiv2((noise[i - j] + noise[i + j]), filt[j]);
+ }
+ syn_out[i] = (FIXP_PCM)(IMDCT_SCALE(syn[i] - tmp));
+ }
+}
+
+void bass_pf_1sf_delay(
+ FIXP_DBL *syn, /* (i) : 12.8kHz synthesis to postfilter */
+ const INT *T_sf, /* (i) : Pitch period for all subframes (T_sf[16]) */
+ FIXP_DBL *pit_gain,
+ const int frame_length, /* (i) : frame length (should be 768|1024) */
+ const INT l_frame,
+ const INT l_next, /* (i) : look ahead for symmetric filtering */
+ FIXP_PCM *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */
+ FIXP_DBL mem_bpf[]) /* i/o : memory state [L_FILT+L_SUBFR] */
+{
+ INT i, sf, i_subfr, T, T2, lg;
+
+ FIXP_DBL tmp, ener, corr, gain;
+ FIXP_DBL *noise, *noise_in;
+ FIXP_DBL
+ noise_buf[L_FILT + (2 * L_SUBFR)]; // L_FILT = 12, L_SUBFR = 64 => 140
+ const FIXP_DBL *x, *y;
+
+ {
+ noise = noise_buf + L_FILT; // L_FILT = 12 delay of upsampling filter
+ noise_in = noise_buf + L_FILT + L_SUBFR;
+ /* Input scaling of the BPF memory */
+ scaleValues(mem_bpf, (L_FILT + L_SUBFR), 1);
+ }
+
+ int gain_exp = 17;
+
+ sf = 0;
+ for (i_subfr = 0; i_subfr < l_frame; i_subfr += L_SUBFR, sf++) {
+ T = T_sf[sf];
+ gain = pit_gain[sf];
+
+ /* Gain is in Q17.14 */
+ /* If gain > 1 set to 1 */
+ if (gain > (FIXP_DBL)(1 << 14)) gain = (FIXP_DBL)(1 << 14);
+
+ /* If gain < 0 set to 0 */
+ if (gain < (FIXP_DBL)0) gain = (FIXP_DBL)0;
+
+ if (gain > (FIXP_DBL)0) {
+ /* pitch tracker: test pitch/2 to avoid continuous pitch doubling */
+ /* Note: pitch is limited to PIT_MIN (34 = 376Hz) at the encoder */
+ T2 = T >> 1;
+ x = &syn[i_subfr - L_EXTRA];
+ y = &syn[i_subfr - T2 - L_EXTRA];
+
+ ener = (FIXP_DBL)0;
+ corr = (FIXP_DBL)0;
+ tmp = (FIXP_DBL)0;
+
+ int headroom_x = getScalefactor(x, L_SUBFR + L_EXTRA);
+ int headroom_y = getScalefactor(y, L_SUBFR + L_EXTRA);
+
+ int width_shift = 7;
+
+ for (i = 0; i < (L_SUBFR + L_EXTRA); i++) {
+ ener += fPow2Div2((x[i] << headroom_x)) >> width_shift;
+ corr += fMultDiv2((x[i] << headroom_x), (y[i] << headroom_y)) >>
+ width_shift;
+ tmp += fPow2Div2((y[i] << headroom_y)) >> width_shift;
+ }
+
+ int exp_ener = ((17 - headroom_x) << 1) + width_shift + 1;
+ int exp_corr = (17 - headroom_x) + (17 - headroom_y) + width_shift + 1;
+ int exp_tmp = ((17 - headroom_y) << 1) + width_shift + 1;
+
+ /* Add 0.01 to "ener". Adjust exponents */
+ FIXP_DBL point_zero_one = (FIXP_DBL)0x51eb851f; /* In Q-6.37 */
+ int diff;
+ ener = fAddNorm(ener, exp_ener, point_zero_one, -6, &exp_ener);
+ corr = fAddNorm(corr, exp_corr, point_zero_one, -6, &exp_corr);
+ tmp = fAddNorm(tmp, exp_tmp, point_zero_one, -6, &exp_tmp);
+
+ /* use T2 if normalized correlation > 0.95 */
+ INT s1, s2;
+ s1 = CntLeadingZeros(ener) - 1;
+ s2 = CntLeadingZeros(tmp) - 1;
+
+ FIXP_DBL ener_by_tmp = fMultDiv2(ener << s1, tmp << s2);
+ int ener_by_tmp_exp = (exp_ener - s1) + (exp_tmp - s2) + 1;
+
+ if (ener_by_tmp_exp & 1) {
+ ener_by_tmp <<= 1;
+ ener_by_tmp_exp -= 1;
+ }
+
+ int temp_exp = 0;
+
+ FIXP_DBL temp1 = invSqrtNorm2(ener_by_tmp, &temp_exp);
+
+ int temp1_exp = temp_exp - (ener_by_tmp_exp >> 1);
+
+ FIXP_DBL tmp_result = fMult(corr, temp1);
+
+ int tmp_result_exp = exp_corr + temp1_exp;
+
+ diff = tmp_result_exp - 0;
+ FIXP_DBL point95 = FL2FXCONST_DBL(0.95f);
+ if (diff >= 0) {
+ diff = fMin(diff, 31);
+ point95 = FL2FXCONST_DBL(0.95f) >> diff;
+ } else {
+ diff = fMax(diff, -31);
+ tmp_result >>= (-diff);
+ }
+
+ if (tmp_result > point95) T = T2;
+
+ /* prevent that noise calculation below reaches into not defined signal
+ parts at the end of the synth_buf or in other words restrict the below
+ used index (i+i_subfr+T) < l_frame + l_next
+ */
+ lg = l_frame + l_next - T - i_subfr;
+
+ if (lg > L_SUBFR)
+ lg = L_SUBFR;
+ else if (lg < 0)
+ lg = 0;
+
+ /* limit gain to avoid problem on burst */
+ if (lg > 0) {
+ FIXP_DBL tmp1;
+
+ /* max(lg) = 64 => scale with 6 bits minus 1 (fPow2Div2) */
+
+ s1 = getScalefactor(&syn[i_subfr], lg);
+ s2 = getScalefactor(&syn[i_subfr + T], lg);
+ INT s = fixMin(s1, s2);
+
+ tmp = (FIXP_DBL)0;
+ ener = (FIXP_DBL)0;
+ for (i = 0; i < lg; i++) {
+ tmp += fPow2Div2(syn[i + i_subfr] << s1) >> (SF_PITCH_TRACK);
+ ener += fPow2Div2(syn[i + i_subfr + T] << s2) >> (SF_PITCH_TRACK);
+ }
+ tmp = tmp >> fMin(DFRACT_BITS - 1, (2 * (s1 - s)));
+ ener = ener >> fMin(DFRACT_BITS - 1, (2 * (s2 - s)));
+
+ /* error robustness: for the specific case syn[...] == -1.0f for all 64
+ samples ener or tmp might overflow and become negative. For all sane
+ cases we have enough headroom.
+ */
+ if (ener <= (FIXP_DBL)0) {
+ ener = (FIXP_DBL)1;
+ }
+ if (tmp <= (FIXP_DBL)0) {
+ tmp = (FIXP_DBL)1;
+ }
+ FDK_ASSERT(ener > (FIXP_DBL)0);
+
+ /* tmp = sqrt(tmp/ener) */
+ int result_e = 0;
+ tmp1 = fDivNorm(tmp, ener, &result_e);
+ if (result_e & 1) {
+ tmp1 >>= 1;
+ result_e += 1;
+ }
+ tmp = sqrtFixp(tmp1);
+ result_e >>= 1;
+
+ gain_exp = 17;
+
+ diff = result_e - gain_exp;
+
+ FIXP_DBL gain1 = gain;
+
+ if (diff >= 0) {
+ diff = fMin(diff, 31);
+ gain1 >>= diff;
+ } else {
+ result_e += (-diff);
+ diff = fMax(diff, -31);
+ tmp >>= (-diff);
+ }
+
+ if (tmp < gain1) {
+ gain = tmp;
+ gain_exp = result_e;
+ }
+ }
+
+ /* calculate noise based on voiced pitch */
+ /* fMultDiv2() replaces weighting of gain with 0.5 */
+ diff = gain_exp - 17;
+ if (diff >= 0) {
+ gain <<= diff;
+ } else {
+ gain >>= (-diff);
+ }
+
+ s1 = CntLeadingZeros(gain) - 1;
+ s1 -= 16; /* Leading bits for SGL */
+
+ FIXP_SGL gainSGL = FX_DBL2FX_SGL(gain << 16);
+
+ gainSGL = gainSGL << s1;
+
+ {
+ for (i = 0; i < lg; i++) {
+ /* scaled with SF_SYNTH + gain_sf + 1 */
+ noise_in[i] =
+ (fMult(gainSGL, syn[i + i_subfr] - (syn[i + i_subfr - T] >> 1) -
+ (syn[i + i_subfr + T] >> 1))) >>
+ s1;
+ }
+
+ for (i = lg; i < L_SUBFR; i++) {
+ /* scaled with SF_SYNTH + gain_sf + 1 */
+ noise_in[i] =
+ (fMult(gainSGL, syn[i + i_subfr] - syn[i + i_subfr - T])) >> s1;
+ }
+ }
+ } else {
+ FDKmemset(noise_in, (FIXP_DBL)0, L_SUBFR * sizeof(FIXP_DBL));
+ }
+
+ {
+ FDKmemcpy(noise_buf, mem_bpf, (L_FILT + L_SUBFR) * sizeof(FIXP_DBL));
+
+ FDKmemcpy(mem_bpf, noise_buf + L_SUBFR,
+ (L_FILT + L_SUBFR) * sizeof(FIXP_DBL));
+ }
+
+ /* substract from voiced speech low-pass filtered noise */
+ /* filter coefficients are scaled with factor SF_FILT_LP (1) */
+
+ {
+ filtLP(&syn[i_subfr - L_SUBFR], &synth_out[i_subfr], noise,
+ fdk_dec_filt_lp, L_SUBFR, L_FILT);
+ }
+ }
+
+ {
+
+ }
+
+ // To be determined (info from Ben)
+ {
+ /* Output scaling of the BPF memory */
+ scaleValues(mem_bpf, (L_FILT + L_SUBFR), -1);
+ /* Copy the rest of the signal (after the fac) */
+ scaleValuesSaturate((FIXP_PCM *)&synth_out[l_frame],
+ (FIXP_DBL *)&syn[l_frame - L_SUBFR],
+ (frame_length - l_frame), MDCT_OUT_HEADROOM);
+ }
+
+ return;
+}
+
+/*
+ * Frequency Domain Noise Shaping
+ */
+
+/**
+ * \brief Adaptive Low Frequencies Deemphasis of spectral coefficients.
+ *
+ * Ensure quantization of low frequencies in case where the
+ * signal dynamic is higher than the LPC noise shaping.
+ * This is the inverse operation of adap_low_freq_emph().
+ * Output gain of all blocks.
+ *
+ * \param x pointer to the spectral coefficients, requires 1 bit headroom.
+ * \param lg length of x.
+ * \param bUseNewAlfe if set, apply ALFD for fullband lpd.
+ * \param gainLpc1 pointer to gain based on old input LPC coefficients.
+ * \param gainLpc2 pointer to gain based on new input LPC coefficients.
+ * \param alfd_gains pointer to output gains.
+ * \param s current scale shift factor of x.
+ */
+#define ALFDPOW2_SCALE 3
+/*static*/
+void CLpd_AdaptLowFreqDeemph(FIXP_DBL x[], int lg, FIXP_DBL alfd_gains[],
+ INT s) {
+ {
+ int i, j, k, i_max;
+ FIXP_DBL max, fac;
+ /* Note: This stack array saves temporary accumulation results to be used in
+ * a second run */
+ /* The size should be limited to (1024/4)/8=32 */
+ FIXP_DBL tmp_pow2[32];
+
+ s = s * 2 + ALFDPOW2_SCALE;
+ s = fMin(31, s);
+
+ k = 8;
+ i_max = lg / 4; /* ALFD range = 1600Hz (lg = 6400Hz) */
+
+ /* find spectral peak */
+ max = FL2FX_DBL(0.01f) >> s;
+ for (i = 0; i < i_max; i += k) {
+ FIXP_DBL tmp;
+
+ tmp = FIXP_DBL(0);
+ FIXP_DBL *pX = &x[i];
+
+ j = 8;
+ do {
+ FIXP_DBL x0 = *pX++;
+ FIXP_DBL x1 = *pX++;
+ x0 = fPow2Div2(x0);
+ x1 = fPow2Div2(x1);
+ tmp = tmp + (x0 >> (ALFDPOW2_SCALE - 1));
+ tmp = tmp + (x1 >> (ALFDPOW2_SCALE - 1));
+ } while ((j = j - 2) != 0);
+ tmp = fMax(tmp, (FL2FX_DBL(0.01f) >> s));
+ tmp_pow2[i >> 3] = tmp;
+ if (tmp > max) {
+ max = tmp;
+ }
+ }
+
+ /* deemphasis of all blocks below the peak */
+ fac = FL2FX_DBL(0.1f) >> 1;
+ for (i = 0; i < i_max; i += k) {
+ FIXP_DBL tmp;
+ INT shifti;
+
+ tmp = tmp_pow2[i >> 3];
+
+ /* tmp = (float)sqrt(tmp/max); */
+
+ /* value of tmp is between 8/2*max^2 and max^2 / 2. */
+ /* required shift factor of division can grow up to 27
+ (grows exponentially for values toward zero)
+ thus using normalized division to assure valid result. */
+ {
+ INT sd;
+
+ if (tmp != (FIXP_DBL)0) {
+ tmp = fDivNorm(max, tmp, &sd);
+ if (sd & 1) {
+ sd++;
+ tmp >>= 1;
+ }
+ } else {
+ tmp = (FIXP_DBL)MAXVAL_DBL;
+ sd = 0;
+ }
+ tmp = invSqrtNorm2(tmp, &shifti);
+ tmp = scaleValue(tmp, shifti - 1 - (sd / 2));
+ }
+ if (tmp > fac) {
+ fac = tmp;
+ }
+ FIXP_DBL *pX = &x[i];
+
+ j = 8;
+ do {
+ FIXP_DBL x0 = pX[0];
+ FIXP_DBL x1 = pX[1];
+ x0 = fMultDiv2(x0, fac);
+ x1 = fMultDiv2(x1, fac);
+ x0 = x0 << 2;
+ x1 = x1 << 2;
+ *pX++ = x0;
+ *pX++ = x1;
+
+ } while ((j = j - 2) != 0);
+ /* Store gains for FAC */
+ *alfd_gains++ = fac;
+ }
+ }
+}
+
+/**
+ * \brief Interpolated Noise Shaping for mdct coefficients.
+ * This algorithm shapes temporally the spectral noise between
+ * the two spectral noise represention (FDNS_NPTS of resolution).
+ * The noise is shaped monotonically between the two points
+ * using a curved shape to favor the lower gain in mid-frame.
+ * ODFT and amplitud calculation are applied to the 2 LPC coefficients first.
+ *
+ * \param r pointer to spectrum data.
+ * \param rms RMS of output spectrum.
+ * \param lg length of r.
+ * \param A1 pointer to old input LPC coefficients of length M_LP_FILTER_ORDER
+ * scaled by SF_A_COEFFS.
+ * \param A2 pointer to new input LPC coefficients of length M_LP_FILTER_ORDER
+ * scaled by SF_A_COEFFS.
+ * \param bLpc2Mdct flags control lpc2mdct conversion and noise shaping.
+ * \param gainLpc1 pointer to gain based on old input LPC coefficients.
+ * \param gainLpc2 pointer to gain based on new input LPC coefficients.
+ * \param gLpc_e pointer to exponent of gainLpc1 and gainLpc2.
+ */
+/* static */
+#define NSHAPE_SCALE (4)
+
+#define LPC2MDCT_CALC (1)
+#define LPC2MDCT_GAIN_LOAD (2)
+#define LPC2MDCT_GAIN_SAVE (4)
+#define LPC2MDCT_APPLY_NSHAPE (8)
+
+void lpc2mdctAndNoiseShaping(FIXP_DBL *r, SHORT *pScale, const INT lg,
+ const INT fdns_npts, const FIXP_LPC *A1,
+ const INT A1_exp, const FIXP_LPC *A2,
+ const INT A2_exp) {
+ FIXP_DBL *tmp2 = NULL;
+ FIXP_DBL rr_minus_one;
+ int i, k, s, step;
+
+ C_AALLOC_SCRATCH_START(tmp1, FIXP_DBL, FDNS_NPTS * 8)
+
+ {
+ tmp2 = tmp1 + fdns_npts * 4;
+
+ /* lpc2mdct() */
+
+ /* ODFT. E_LPC_a_weight() for A1 and A2 vectors is included into the loop
+ * below. */
+ FIXP_DBL f = FL2FXCONST_DBL(0.92f);
+
+ const FIXP_STP *SinTab;
+ int k_step;
+ /* needed values: sin(phi), cos(phi); phi = i*PI/(2*fdns_npts), i = 0 ...
+ * M_LP_FILTER_ORDER */
+ switch (fdns_npts) {
+ case 64:
+ SinTab = SineTable512;
+ k_step = (512 / 64);
+ FDK_ASSERT(512 >= 64);
+ break;
+ case 48:
+ SinTab = SineTable384;
+ k_step = 384 / 48;
+ FDK_ASSERT(384 >= 48);
+ break;
+ default:
+ FDK_ASSERT(0);
+ return;
+ }
+
+ for (i = 0, k = k_step; i < M_LP_FILTER_ORDER; i++, k += k_step) {
+ FIXP_STP cs = SinTab[k];
+ FIXP_DBL wA1, wA2;
+
+ wA1 = fMult(A1[i], f);
+ wA2 = fMult(A2[i], f);
+
+ /* r[i] = A[i]*cos() */
+ tmp1[2 + i * 2] = fMult(wA1, cs.v.re);
+ tmp2[2 + i * 2] = fMult(wA2, cs.v.re);
+ /* i[i] = A[i]*sin() */
+ tmp1[3 + i * 2] = -fMult(wA1, cs.v.im);
+ tmp2[3 + i * 2] = -fMult(wA2, cs.v.im);
+
+ f = fMult(f, FL2FXCONST_DBL(0.92f));
+ }
+
+ /* Guarantee at least 2 bits of headroom for the FFT */
+ /* "3" stands for 1.0 with 2 bits of headroom; (A1_exp + 2) guarantess 2
+ * bits of headroom if A1_exp > 1 */
+ int A1_exp_fix = fMax(3, A1_exp + 2);
+ int A2_exp_fix = fMax(3, A2_exp + 2);
+
+ /* Set 1.0 in the proper format */
+ tmp1[0] = (FIXP_DBL)(INT)((ULONG)0x80000000 >> A1_exp_fix);
+ tmp2[0] = (FIXP_DBL)(INT)((ULONG)0x80000000 >> A2_exp_fix);
+
+ tmp1[1] = tmp2[1] = (FIXP_DBL)0;
+
+ /* Clear the resto of the array */
+ FDKmemclear(
+ tmp1 + 2 * (M_LP_FILTER_ORDER + 1),
+ 2 * (fdns_npts * 2 - (M_LP_FILTER_ORDER + 1)) * sizeof(FIXP_DBL));
+ FDKmemclear(
+ tmp2 + 2 * (M_LP_FILTER_ORDER + 1),
+ 2 * (fdns_npts * 2 - (M_LP_FILTER_ORDER + 1)) * sizeof(FIXP_DBL));
+
+ /* Guarantee 2 bits of headroom for FFT */
+ scaleValues(&tmp1[2], (2 * M_LP_FILTER_ORDER), (A1_exp - A1_exp_fix));
+ scaleValues(&tmp2[2], (2 * M_LP_FILTER_ORDER), (A2_exp - A2_exp_fix));
+
+ INT s2;
+ s = A1_exp_fix;
+ s2 = A2_exp_fix;
+
+ fft(2 * fdns_npts, tmp1, &s);
+ fft(2 * fdns_npts, tmp2, &s2);
+
+ /* Adjust the exponents of both fft outputs if necessary*/
+ if (s > s2) {
+ scaleValues(tmp2, 2 * fdns_npts, s2 - s);
+ s2 = s;
+ } else if (s < s2) {
+ scaleValues(tmp1, 2 * fdns_npts, s - s2);
+ s = s2;
+ }
+
+ FDK_ASSERT(s == s2);
+ }
+
+ /* Get amplitude and apply gains */
+ step = lg / fdns_npts;
+ rr_minus_one = (FIXP_DBL)0;
+
+ for (k = 0; k < fdns_npts; k++) {
+ FIXP_DBL g1, g2, inv_g1_g2, a, b;
+ INT inv_g1_g2_e;
+ int g_e, shift;
+
+ {
+ FIXP_DBL real, imag;
+ int si1, si2, sInput;
+
+ real = tmp1[k * 2];
+ imag = tmp1[k * 2 + 1];
+ sInput = fMax(fMin(fNorm(real), fNorm(imag)) - 1, 0);
+ real <<= sInput;
+ imag <<= sInput;
+ /* g1_e = si1 - 2*s/2 */
+ g1 = invSqrtNorm2(fPow2(real) + fPow2(imag), &si1);
+ si1 += sInput;
+
+ real = tmp2[k * 2];
+ imag = tmp2[k * 2 + 1];
+ sInput = fMax(fMin(fNorm(real), fNorm(imag)) - 1, 0);
+ real <<= sInput;
+ imag <<= sInput;
+ /* g2_e = si2 - 2*s/2 */
+ g2 = invSqrtNorm2(fPow2(real) + fPow2(imag), &si2);
+ si2 += sInput;
+
+ /* Pick a common scale factor for g1 and g2 */
+ if (si1 > si2) {
+ g2 >>= si1 - si2;
+ g_e = si1 - s;
+ } else {
+ g1 >>= si2 - si1;
+ g_e = si2 - s;
+ }
+ }
+
+ /* end of lpc2mdct() */
+
+ FDK_ASSERT(g1 >= (FIXP_DBL)0);
+ FDK_ASSERT(g2 >= (FIXP_DBL)0);
+
+ /* mdct_IntNoiseShaping() */
+ {
+ /* inv_g1_g2 * 2^inv_g1_g2_e = 1/(g1+g2) */
+ inv_g1_g2 = (g1 >> 1) + (g2 >> 1);
+ if (inv_g1_g2 != (FIXP_DBL)0) {
+ inv_g1_g2 = fDivNorm(FL2FXCONST_DBL(0.5f), inv_g1_g2, &inv_g1_g2_e);
+ inv_g1_g2_e = inv_g1_g2_e - g_e;
+ } else {
+ inv_g1_g2 = (FIXP_DBL)MAXVAL_DBL;
+ inv_g1_g2_e = 0;
+ }
+
+ if (g_e < 0) {
+ /* a_e = g_e + inv_g1_g2_e + 1 */
+ a = scaleValue(fMult(fMult(g1, g2), inv_g1_g2), g_e);
+ /* b_e = g_e + inv_g1_g2_e */
+ b = fMult(g2 - g1, inv_g1_g2);
+ shift = g_e + inv_g1_g2_e + 1 - NSHAPE_SCALE;
+ } else {
+ /* a_e = (g_e+g_e) + inv_g1_g2_e + 1 */
+ a = fMult(fMult(g1, g2), inv_g1_g2);
+ /* b_e = (g_e+g_e) + inv_g1_g2_e */
+ b = scaleValue(fMult(g2 - g1, inv_g1_g2), -g_e);
+ shift = (g_e + g_e) + inv_g1_g2_e + 1 - NSHAPE_SCALE;
+ }
+
+ for (i = k * step; i < (k + 1) * step; i++) {
+ FIXP_DBL tmp;
+
+ /* rr[i] = 2*a*r[i] + b*rr[i-1] */
+ tmp = fMult(a, r[i]);
+ tmp += scaleValue(fMultDiv2(b, rr_minus_one), NSHAPE_SCALE);
+ tmp = scaleValueSaturate(tmp, shift);
+ rr_minus_one = tmp;
+ r[i] = tmp;
+ }
+ }
+ }
+
+ /* end of mdct_IntNoiseShaping() */
+ { *pScale += NSHAPE_SCALE; }
+
+ C_AALLOC_SCRATCH_END(tmp1, FIXP_DBL, FDNS_NPTS * 8)
+}
+
+/**
+ * \brief Calculates the energy.
+ * \param r pointer to spectrum.
+ * \param rs scale factor of spectrum r.
+ * \param lg frame length in audio samples.
+ * \param rms_e pointer to exponent of energy value.
+ * \return mantissa of energy value.
+ */
+static FIXP_DBL calcEnergy(const FIXP_DBL *r, const SHORT rs, const INT lg,
+ INT *rms_e) {
+ int headroom = getScalefactor(r, lg);
+
+ FIXP_DBL rms_m = 0;
+
+ /* Calculate number of growth bits due to addition */
+ INT shift = (INT)(fNormz((FIXP_DBL)lg));
+ shift = 31 - shift;
+
+ /* Generate 1e-2 in Q-6.37 */
+ const FIXP_DBL value0_01 = 0x51eb851e;
+ const INT value0_01_exp = -6;
+
+ /* Find the exponent of the resulting energy value */
+ *rms_e = ((rs - headroom) << 1) + shift + 1;
+
+ INT delta = *rms_e - value0_01_exp;
+ if (delta > 0) {
+ /* Limit shift_to 31*/
+ delta = fMin(31, delta);
+ rms_m = value0_01 >> delta;
+ } else {
+ rms_m = value0_01;
+ *rms_e = value0_01_exp;
+ shift = shift - delta;
+ /* Limit shift_to 31*/
+ shift = fMin(31, shift);
+ }
+
+ for (int i = 0; i < lg; i++) {
+ rms_m += fPow2Div2(r[i] << headroom) >> shift;
+ }
+
+ return rms_m;
+}
+
+/**
+ * \brief TCX gain calculation.
+ * \param pAacDecoderChannelInfo channel context data.
+ * \param r output spectrum.
+ * \param rms_e pointer to mantissa of energy value.
+ * \param rms_e pointer to exponent of energy value.
+ * \param frame the frame index of the LPD super frame.
+ * \param lg the frame length in audio samples.
+ * \param gain_m pointer to mantissa of TCX gain.
+ * \param gain_e pointer to exponent of TCX gain.
+ * \param elFlags element specific parser guidance flags.
+ * \param lg_fb the fullband frame length in audio samples.
+ * \param IGF_bgn the IGF start index.
+ */
+static void calcTCXGain(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ FIXP_DBL *r, FIXP_DBL rms_m, INT rms_e, const INT frame,
+ const INT lg) {
+ if ((rms_m != (FIXP_DBL)0)) {
+ FIXP_DBL tcx_gain_m;
+ INT tcx_gain_e;
+
+ CLpd_DecodeGain(&tcx_gain_m, &tcx_gain_e,
+ pAacDecoderChannelInfo->pDynData->specificTo.usac
+ .tcx_global_gain[frame]);
+
+ /* rms * 2^rms_e = lg/sqrt(sum(spec^2)) */
+ if (rms_e & 1) {
+ rms_m >>= 1;
+ rms_e++;
+ }
+
+ {
+ FIXP_DBL fx_lg;
+ INT fx_lg_e, s;
+ INT inv_e;
+
+ /* lg = fx_lg * 2^fx_lg_e */
+ s = fNorm((FIXP_DBL)lg);
+ fx_lg = (FIXP_DBL)lg << s;
+ fx_lg_e = DFRACT_BITS - 1 - s;
+ /* 1/sqrt(rms) */
+ rms_m = invSqrtNorm2(rms_m, &inv_e);
+ rms_m = fMult(rms_m, fx_lg);
+ rms_e = inv_e - (rms_e >> 1) + fx_lg_e;
+ }
+
+ {
+ int s = fNorm(tcx_gain_m);
+ tcx_gain_m = tcx_gain_m << s;
+ tcx_gain_e -= s;
+ }
+
+ tcx_gain_m = fMultDiv2(tcx_gain_m, rms_m);
+ tcx_gain_e = tcx_gain_e + rms_e;
+
+ /* global_gain * 2^(global_gain_e+rms_e) = (10^(global_gain/28)) * rms *
+ * 2^rms_e */
+ {
+ { tcx_gain_e += 1; }
+ }
+
+ pAacDecoderChannelInfo->data.usac.tcx_gain[frame] = tcx_gain_m;
+ pAacDecoderChannelInfo->data.usac.tcx_gain_e[frame] = tcx_gain_e;
+
+ pAacDecoderChannelInfo->specScale[frame] += tcx_gain_e;
+ }
+}
+
+/**
+ * \brief FDNS decoding.
+ * \param pAacDecoderChannelInfo channel context data.
+ * \param pAacDecoderStaticChannelInfo channel context static data.
+ * \param r output spectrum.
+ * \param lg the frame length in audio samples.
+ * \param frame the frame index of the LPD super frame.
+ * \param pScale pointer to current scale shift factor of r[].
+ * \param A1 old input LPC coefficients of length M_LP_FILTER_ORDER.
+ * \param A2 new input LPC coefficients of length M_LP_FILTER_ORDER.
+ * \param pAlfdGains pointer for ALFD gains output scaled by 1.
+ * \param fdns_npts number of lines (FDNS_NPTS).
+ * \param inf_mask pointer to noise mask.
+ * \param IGF_win_mode IGF window mode (LONG, SHORT, TCX10, TCX20).
+ * \param frameType (IGF_FRAME_DIVISION_AAC_OR_TCX_LONG or
+ * IGF_FRAME_DIVISION_TCX_SHORT_1).
+ * \param elFlags element specific parser guidance flags.
+ * \param lg_fb the fullband frame length in audio samples.
+ * \param IGF_bgn the IGF start index.
+ * \param rms_m mantisse of energy.
+ * \param rms_e exponent of energy.
+ */
+/* static */
+void CLpd_FdnsDecode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ FIXP_DBL r[], const INT lg, const INT frame, SHORT *pScale,
+ const FIXP_LPC A1[M_LP_FILTER_ORDER], const INT A1_exp,
+ const FIXP_LPC A2[M_LP_FILTER_ORDER], const INT A2_exp,
+ FIXP_DBL pAlfdGains[LFAC / 4], const INT fdns_npts) {
+ /* Weight LPC coefficients using Rm values */
+ CLpd_AdaptLowFreqDeemph(r, lg, pAlfdGains, *pScale);
+
+ FIXP_DBL rms_m = (FIXP_DBL)0;
+ INT rms_e = 0;
+ {
+ /* Calculate Energy */
+ rms_m = calcEnergy(r, *pScale, lg, &rms_e);
+ }
+
+ calcTCXGain(pAacDecoderChannelInfo, r, rms_m, rms_e, frame, lg);
+
+ /* Apply ODFT and Noise Shaping. LP coefficient (A1, A2) weighting is done
+ * inside on the fly. */
+
+ lpc2mdctAndNoiseShaping(r, pScale, lg, fdns_npts, A1, A1_exp, A2, A2_exp);
+}
+
+/**
+ * find pitch for TCX20 (time domain) concealment.
+ */
+static int find_mpitch(FIXP_DBL xri[], int lg) {
+ FIXP_DBL max, pitch;
+ INT pitch_e;
+ int i, n;
+
+ max = (FIXP_DBL)0;
+ n = 2;
+
+ /* find maximum below 400Hz */
+ for (i = 2; i < (lg >> 4); i += 2) {
+ FIXP_DBL tmp = fPow2Div2(xri[i]) + fPow2Div2(xri[i + 1]);
+ if (tmp > max) {
+ max = tmp;
+ n = i;
+ }
+ }
+
+ // pitch = ((float)lg<<1)/(float)n;
+ pitch = fDivNorm((FIXP_DBL)lg << 1, (FIXP_DBL)n, &pitch_e);
+ pitch >>= fixMax(0, DFRACT_BITS - 1 - pitch_e - 16);
+
+ /* find pitch multiple under 20ms */
+ if (pitch >= (FIXP_DBL)((256 << 16) - 1)) { /*231.0f*/
+ n = 256;
+ } else {
+ FIXP_DBL mpitch = pitch;
+ while (mpitch < (FIXP_DBL)(255 << 16)) {
+ mpitch += pitch;
+ }
+ n = (int)(mpitch - pitch) >> 16;
+ }
+
+ return (n);
+}
+
+/**
+ * number of spectral coefficients / time domain samples using frame mode as
+ * index.
+ */
+static const int lg_table_ccfl[2][4] = {
+ {256, 256, 512, 1024}, /* coreCoderFrameLength = 1024 */
+ {192, 192, 384, 768} /* coreCoderFrameLength = 768 */
+};
+
+/**
+ * \brief Decode and render one MDCT-TCX frame.
+ * \param pAacDecoderChannelInfo channel context data.
+ * \param lg the frame length in audio samples.
+ * \param frame the frame index of the LPD super frame.
+ */
+static void CLpd_TcxDecode(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, UINT flags,
+ int mod, int last_mod, int frame, int frameOk) {
+ FIXP_DBL *pAlfd_gains = pAacDecoderStaticChannelInfo->last_alfd_gains;
+ ULONG *pSeed = &pAacDecoderStaticChannelInfo->nfRandomSeed;
+ int lg = (pAacDecoderChannelInfo->granuleLength == 128)
+ ? lg_table_ccfl[0][mod + 0]
+ : lg_table_ccfl[1][mod + 0];
+ int next_frame = frame + (1 << (mod - 1));
+ int isFullBandLpd = 0;
+
+ /* Obtain r[] vector by combining the quant[] and noise[] vectors */
+ {
+ FIXP_DBL noise_level;
+ FIXP_DBL *coeffs =
+ SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
+ pAacDecoderChannelInfo->granuleLength, isFullBandLpd);
+ int scale = pAacDecoderChannelInfo->specScale[frame];
+ int i, nfBgn, nfEnd;
+ UCHAR tcx_noise_factor = pAacDecoderChannelInfo->pDynData->specificTo.usac
+ .tcx_noise_factor[frame];
+
+ /* find pitch for bfi case */
+ pAacDecoderStaticChannelInfo->last_tcx_pitch = find_mpitch(coeffs, lg);
+
+ if (frameOk) {
+ /* store for concealment */
+ pAacDecoderStaticChannelInfo->last_tcx_noise_factor = tcx_noise_factor;
+ } else {
+ /* restore last frames value */
+ tcx_noise_factor = pAacDecoderStaticChannelInfo->last_tcx_noise_factor;
+ }
+
+ noise_level =
+ (FIXP_DBL)((LONG)FL2FXCONST_DBL(0.0625f) * (8 - tcx_noise_factor));
+ noise_level = scaleValue(noise_level, -scale);
+
+ const FIXP_DBL neg_noise_level = -noise_level;
+
+ {
+ nfBgn = lg / 6;
+ nfEnd = lg;
+ }
+
+ for (i = nfBgn; i < nfEnd - 7; i += 8) {
+ LONG tmp;
+
+ /* Fill all 8 consecutive zero coeffs with noise */
+ tmp = coeffs[i + 0] | coeffs[i + 1] | coeffs[i + 2] | coeffs[i + 3] |
+ coeffs[i + 4] | coeffs[i + 5] | coeffs[i + 6] | coeffs[i + 7];
+
+ if (tmp == 0) {
+ for (int k = i; k < i + 8; k++) {
+ UsacRandomSign(pSeed) ? (coeffs[k] = neg_noise_level)
+ : (coeffs[k] = noise_level);
+ }
+ }
+ }
+ if ((nfEnd - i) >
+ 0) { /* noise filling for last "band" with less than 8 bins */
+ LONG tmp = (LONG)coeffs[i];
+ int k;
+
+ FDK_ASSERT((nfEnd - i) < 8);
+ for (k = 1; k < (nfEnd - i); k++) {
+ tmp |= (LONG)coeffs[i + k];
+ }
+ if (tmp == 0) {
+ for (k = i; k < nfEnd; k++) {
+ UsacRandomSign(pSeed) ? (coeffs[k] = neg_noise_level)
+ : (coeffs[k] = noise_level);
+ }
+ }
+ }
+ }
+
+ {
+ /* Convert LPC to LP domain */
+ if (last_mod == 0) {
+ /* Note: The case where last_mod == 255 is handled by other means
+ * in CLpdChannelStream_Read() */
+ E_LPC_f_lsp_a_conversion(
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[frame],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[frame],
+ &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[frame]);
+ }
+
+ E_LPC_f_lsp_a_conversion(
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[next_frame],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[next_frame],
+ &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[next_frame]);
+
+ /* FDNS decoding */
+ CLpd_FdnsDecode(
+ pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
+ pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
+ lg, frame, pAacDecoderChannelInfo->specScale + frame,
+ pAacDecoderChannelInfo->data.usac.lp_coeff[frame],
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[frame],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[next_frame],
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[next_frame], pAlfd_gains,
+ pAacDecoderChannelInfo->granuleLength / 2 /* == FDNS_NPTS(ccfl) */
+ );
+ }
+}
+
+/**
+ * \brief Read the tcx_coding bitstream part
+ * \param hBs bitstream handle to read from.
+ * \param pAacDecoderChannelInfo channel context info to store data into.
+ * \param lg the frame length in audio samples.
+ * \param first_tcx_flag flag indicating that this is the first TCX frame.
+ * \param frame the frame index of the LPD super frame.
+ */
+static AAC_DECODER_ERROR CLpd_TCX_Read(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, int lg,
+ int first_tcx_flag, int frame, UINT flags) {
+ AAC_DECODER_ERROR errorAAC = AAC_DEC_OK;
+ ARITH_CODING_ERROR error = ARITH_CODER_OK;
+ FIXP_DBL *pSpec;
+ int arith_reset_flag = 0;
+ int isFullBandLpd = 0;
+
+ pSpec = SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
+ pAacDecoderChannelInfo->granuleLength, isFullBandLpd);
+
+ /* TCX noise level */
+ {
+ pAacDecoderChannelInfo->pDynData->specificTo.usac.tcx_noise_factor[frame] =
+ FDKreadBits(hBs, 3);
+ }
+ /* TCX global gain */
+ pAacDecoderChannelInfo->pDynData->specificTo.usac.tcx_global_gain[frame] =
+ FDKreadBits(hBs, 7);
+
+ /* Arithmetic coded residual/spectrum */
+ if (first_tcx_flag) {
+ if (flags & AC_INDEP) {
+ arith_reset_flag = 1;
+ } else {
+ arith_reset_flag = FDKreadBits(hBs, 1);
+ }
+ }
+
+ /* CArco_DecodeArithData() output scale of "pSpec" is DFRACT_BITS-1 */
+ error = CArco_DecodeArithData(pAacDecoderStaticChannelInfo->hArCo, hBs, pSpec,
+ lg, lg, arith_reset_flag);
+
+ /* Rescale residual/spectrum */
+ {
+ int scale = getScalefactor(pSpec, lg) - 2; /* Leave 2 bits headroom */
+
+ /* Exponent of CArco_DecodeArithData() output is DFRACT_BITS; integer
+ * values. */
+ scaleValues(pSpec, lg, scale);
+ scale = DFRACT_BITS - 1 - scale;
+
+ pAacDecoderChannelInfo->specScale[frame] = scale;
+ }
+
+ if (error == ARITH_CODER_ERROR) errorAAC = AAC_DEC_UNKNOWN;
+
+ return errorAAC;
+}
+
+/**
+ * \brief translate lpd_mode into the mod[] array which describes the mode of
+ * each each LPD frame
+ * \param mod[] the array that will be filled with the mode indexes of the
+ * inidividual frames.
+ * \param lpd_mode the lpd_mode field read from the lpd_channel_stream
+ */
+static AAC_DECODER_ERROR CLpd_ReadAndMapLpdModeToModArray(
+ UCHAR mod[4], HANDLE_FDK_BITSTREAM hBs, UINT elFlags) {
+ int lpd_mode;
+
+ {
+ lpd_mode = FDKreadBits(hBs, 5);
+
+ if (lpd_mode > 25 || lpd_mode < 0) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+
+ switch (lpd_mode) {
+ case 25:
+ /* 1 80MS frame */
+ mod[0] = mod[1] = mod[2] = mod[3] = 3;
+ break;
+ case 24:
+ /* 2 40MS frames */
+ mod[0] = mod[1] = mod[2] = mod[3] = 2;
+ break;
+ default:
+ switch (lpd_mode >> 2) {
+ case 4:
+ /* lpd_mode 19 - 16 => 1 40MS and 2 20MS frames */
+ mod[0] = mod[1] = 2;
+ mod[2] = (lpd_mode & 1) ? 1 : 0;
+ mod[3] = (lpd_mode & 2) ? 1 : 0;
+ break;
+ case 5:
+ /* lpd_mode 23 - 20 => 2 20MS and 1 40MS frames */
+ mod[2] = mod[3] = 2;
+ mod[0] = (lpd_mode & 1) ? 1 : 0;
+ mod[1] = (lpd_mode & 2) ? 1 : 0;
+ break;
+ default:
+ /* lpd_mode < 16 => 4 20MS frames */
+ mod[0] = (lpd_mode & 1) ? 1 : 0;
+ mod[1] = (lpd_mode & 2) ? 1 : 0;
+ mod[2] = (lpd_mode & 4) ? 1 : 0;
+ mod[3] = (lpd_mode & 8) ? 1 : 0;
+ break;
+ }
+ break;
+ }
+ }
+ return AAC_DEC_OK;
+}
+
+static void CLpd_Reset(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ int keep_past_signal) {
+ int i;
+
+ /* Reset TCX / ACELP common memory */
+ if (!keep_past_signal) {
+ FDKmemclear(pAacDecoderStaticChannelInfo->old_synth,
+ sizeof(pAacDecoderStaticChannelInfo->old_synth));
+ }
+
+ /* Initialize the LSFs */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ pAacDecoderStaticChannelInfo->lpc4_lsf[i] = fdk_dec_lsf_init[i];
+ }
+
+ /* Reset memory needed by bass post-filter */
+ FDKmemclear(pAacDecoderStaticChannelInfo->mem_bpf,
+ sizeof(pAacDecoderStaticChannelInfo->mem_bpf));
+
+ pAacDecoderStaticChannelInfo->old_bpf_control_info = 0;
+ for (i = 0; i < SYN_SFD; i++) {
+ pAacDecoderStaticChannelInfo->old_T_pf[i] = 64;
+ pAacDecoderStaticChannelInfo->old_gain_pf[i] = (FIXP_DBL)0;
+ }
+
+ /* Reset ACELP memory */
+ CLpd_AcelpReset(&pAacDecoderStaticChannelInfo->acelp);
+
+ pAacDecoderStaticChannelInfo->last_lpc_lost = 0; /* prev_lpc_lost */
+ pAacDecoderStaticChannelInfo->last_tcx_pitch = L_DIV; /* pitch_tcx */
+ pAacDecoderStaticChannelInfo->numLostLpdFrames = 0; /* nbLostCmpt */
+}
+
+/*
+ * Externally visible functions
+ */
+
+AAC_DECODER_ERROR CLpdChannelStream_Read(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, UINT flags) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ int first_tcx_flag;
+ int k, nbDiv, fFacDataPresent, first_lpd_flag, acelp_core_mode,
+ facGetMemState = 0;
+ UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
+ int lpd_mode_last, prev_frame_was_lpd;
+ USAC_COREMODE core_mode_last;
+ const int lg_table_offset = 0;
+ const int *lg_table = (pAacDecoderChannelInfo->granuleLength == 128)
+ ? &lg_table_ccfl[0][lg_table_offset]
+ : &lg_table_ccfl[1][lg_table_offset];
+ int last_lpc_lost = pAacDecoderStaticChannelInfo->last_lpc_lost;
+
+ int last_frame_ok = CConcealment_GetLastFrameOk(
+ &pAacDecoderStaticChannelInfo->concealmentInfo, 1);
+
+ INT i_offset;
+ UINT samplingRate;
+
+ samplingRate = pSamplingRateInfo->samplingRate;
+
+ i_offset =
+ (INT)(samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
+ (INT)PIT_MIN_12k8;
+
+ if ((samplingRate < FAC_FSCALE_MIN) || (samplingRate > FAC_FSCALE_MAX)) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ acelp_core_mode = FDKreadBits(hBs, 3);
+
+ /* lpd_mode */
+ error = CLpd_ReadAndMapLpdModeToModArray(mod, hBs, 0);
+ if (error != AAC_DEC_OK) {
+ goto bail;
+ }
+
+ /* bpf_control_info */
+ pAacDecoderChannelInfo->data.usac.bpf_control_info = FDKreadBit(hBs);
+
+ /* last_core_mode */
+ prev_frame_was_lpd = FDKreadBit(hBs);
+ /* fac_data_present */
+ fFacDataPresent = FDKreadBit(hBs);
+
+ /* Set valid values from
+ * pAacDecoderStaticChannelInfo->{last_core_mode,last_lpd_mode} */
+ pAacDecoderChannelInfo->data.usac.core_mode_last =
+ pAacDecoderStaticChannelInfo->last_core_mode;
+ lpd_mode_last = pAacDecoderChannelInfo->data.usac.lpd_mode_last =
+ pAacDecoderStaticChannelInfo->last_lpd_mode;
+
+ if (prev_frame_was_lpd == 0) {
+ /* Last frame was FD */
+ pAacDecoderChannelInfo->data.usac.core_mode_last = FD_LONG;
+ pAacDecoderChannelInfo->data.usac.lpd_mode_last = 255;
+ } else {
+ /* Last frame was LPD */
+ pAacDecoderChannelInfo->data.usac.core_mode_last = LPD;
+ if (((mod[0] == 0) && fFacDataPresent) ||
+ ((mod[0] != 0) && !fFacDataPresent)) {
+ /* Currend mod is ACELP, fac data present -> TCX, current mod TCX, no fac
+ * data -> TCX */
+ if (lpd_mode_last == 0) {
+ /* Bit stream interruption detected. Assume last TCX mode as TCX20. */
+ pAacDecoderChannelInfo->data.usac.lpd_mode_last = 1;
+ }
+ /* Else assume that remembered TCX mode is correct. */
+ } else {
+ pAacDecoderChannelInfo->data.usac.lpd_mode_last = 0;
+ }
+ }
+
+ first_lpd_flag = (pAacDecoderChannelInfo->data.usac.core_mode_last !=
+ LPD); /* Depends on bitstream configuration */
+ first_tcx_flag = 1;
+
+ if (pAacDecoderStaticChannelInfo->last_core_mode !=
+ LPD) { /* ATTENTION: Reset depends on what we rendered before! */
+ CLpd_Reset(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo, 0);
+
+ if (!last_frame_ok) {
+ /* If last rendered frame was not LPD and first lpd flag is not set, this
+ * must be an error - set last_lpc_lost flag */
+ last_lpc_lost |= (first_lpd_flag) ? 0 : 1;
+ }
+ }
+
+ core_mode_last = pAacDecoderChannelInfo->data.usac.core_mode_last;
+ lpd_mode_last = pAacDecoderChannelInfo->data.usac.lpd_mode_last;
+
+ nbDiv = NB_DIV;
+
+ /* k is the frame index. If a frame is of size 40MS or 80MS,
+ this frame index is incremented 2 or 4 instead of 1 respectively. */
+
+ k = 0;
+ while (k < nbDiv) {
+ /* Reset FAC data pointers in order to avoid applying old random FAC data.
+ */
+ pAacDecoderChannelInfo->data.usac.fac_data[k] = NULL;
+
+ if ((k == 0 && core_mode_last == LPD && fFacDataPresent) ||
+ (lpd_mode_last == 0 && mod[k] > 0) ||
+ ((lpd_mode_last != 255) && lpd_mode_last > 0 && mod[k] == 0)) {
+ int err;
+
+ /* Assign FAC memory */
+ pAacDecoderChannelInfo->data.usac.fac_data[k] =
+ CLpd_FAC_GetMemory(pAacDecoderChannelInfo, mod, &facGetMemState);
+
+ /* FAC for (ACELP -> TCX) or (TCX -> ACELP) */
+ err = CLpd_FAC_Read(
+ hBs, pAacDecoderChannelInfo->data.usac.fac_data[k],
+ pAacDecoderChannelInfo->data.usac.fac_data_e,
+ pAacDecoderChannelInfo->granuleLength, /* == fac_length */
+ 0, k);
+ if (err != 0) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ if (mod[k] == 0) /* acelp-mode */
+ {
+ int err;
+ err = CLpd_AcelpRead(
+ hBs, &pAacDecoderChannelInfo->data.usac.acelp[k], acelp_core_mode,
+ pAacDecoderChannelInfo->granuleLength * 8 /* coreCoderFrameLength */,
+ i_offset);
+ if (err != 0) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ lpd_mode_last = 0;
+ k++;
+ } else /* mode != 0 => TCX */
+ {
+ error = CLpd_TCX_Read(hBs, pAacDecoderChannelInfo,
+ pAacDecoderStaticChannelInfo, lg_table[mod[k]],
+ first_tcx_flag, k, flags);
+
+ lpd_mode_last = mod[k];
+ first_tcx_flag = 0;
+ k += 1 << (mod[k] - 1);
+ }
+ if (error != AAC_DEC_OK) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ {
+ int err;
+
+ /* Read LPC coefficients */
+ err = CLpc_Read(
+ hBs, pAacDecoderChannelInfo->data.usac.lsp_coeff,
+ pAacDecoderStaticChannelInfo->lpc4_lsf,
+ pAacDecoderChannelInfo->data.usac.lsf_adaptive_mean_cand,
+ pAacDecoderChannelInfo->data.usac.aStability, mod, first_lpd_flag,
+ /* if last lpc4 is available from concealment do not extrapolate lpc0
+ from lpc2 */
+ (mod[0] & 0x3) ? 0
+ : (last_lpc_lost &&
+ pAacDecoderStaticChannelInfo->last_core_mode != LPD),
+ last_frame_ok);
+ if (err != 0) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ /* adjust old lsp[] following to a bad frame (to avoid overshoot) (ref:
+ * dec_LPD.c) */
+ if (last_lpc_lost && !last_frame_ok) {
+ int k_next;
+ k = 0;
+ while (k < nbDiv) {
+ int i;
+ k_next = k + (((mod[k] & 0x3) == 0) ? 1 : (1 << (mod[k] - 1)));
+ FIXP_LPC *lsp_old = pAacDecoderChannelInfo->data.usac.lsp_coeff[k];
+ FIXP_LPC *lsp_new = pAacDecoderChannelInfo->data.usac.lsp_coeff[k_next];
+
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ if (lsp_new[i] < lsp_old[i]) {
+ lsp_old[i] = lsp_new[i];
+ }
+ }
+ k = k_next;
+ }
+ }
+
+ if (!CConcealment_GetLastFrameOk(
+ &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) {
+ E_LPC_f_lsp_a_conversion(
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[0],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[0],
+ &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0]);
+ } else if (pAacDecoderStaticChannelInfo->last_lpd_mode != 0) {
+ if (pAacDecoderStaticChannelInfo->last_lpd_mode == 255) {
+ /* We need it for TCX decoding or ACELP excitation update */
+ E_LPC_f_lsp_a_conversion(
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[0],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[0],
+ &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0]);
+ } else { /* last_lpd_mode was TCX */
+ /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
+ * converting LSP coefficients again). */
+ FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
+ pAacDecoderStaticChannelInfo->lp_coeff_old[0],
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
+ pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
+ }
+ } /* case last_lpd_mode was ACELP is handled by CLpd_TcxDecode() */
+
+ if (fFacDataPresent && (core_mode_last != LPD)) {
+ int prev_frame_was_short;
+
+ prev_frame_was_short = FDKreadBit(hBs);
+
+ if (prev_frame_was_short) {
+ core_mode_last = pAacDecoderChannelInfo->data.usac.core_mode_last =
+ FD_SHORT;
+ pAacDecoderChannelInfo->data.usac.lpd_mode_last = 255;
+
+ if ((pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT) &&
+ CConcealment_GetLastFrameOk(
+ &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) {
+ /* USAC Conformance document:
+ short_fac_flag shall be encoded with a value of 1 if the
+ window_sequence of the previous frame was 2 (EIGHT_SHORT_SEQUENCE).
+ Otherwise short_fac_flag shall be encoded with a
+ value of 0. */
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ /* Assign memory */
+ pAacDecoderChannelInfo->data.usac.fac_data[0] =
+ CLpd_FAC_GetMemory(pAacDecoderChannelInfo, mod, &facGetMemState);
+
+ {
+ int err;
+
+ /* FAC for FD -> ACELP */
+ err = CLpd_FAC_Read(
+ hBs, pAacDecoderChannelInfo->data.usac.fac_data[0],
+ pAacDecoderChannelInfo->data.usac.fac_data_e,
+ CLpd_FAC_getLength(core_mode_last != FD_SHORT,
+ pAacDecoderChannelInfo->granuleLength),
+ 1, 0);
+ if (err != 0) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+ }
+
+bail:
+ if (error == AAC_DEC_OK) {
+ /* check consitency of last core/lpd mode values */
+ if ((pAacDecoderChannelInfo->data.usac.core_mode_last !=
+ pAacDecoderStaticChannelInfo->last_core_mode) &&
+ (pAacDecoderStaticChannelInfo->last_lpc_lost == 0)) {
+ /* Something got wrong! */
+ /* error = AAC_DEC_PARSE_ERROR; */ /* Throwing errors does not help */
+ } else if ((pAacDecoderChannelInfo->data.usac.core_mode_last == LPD) &&
+ (pAacDecoderChannelInfo->data.usac.lpd_mode_last !=
+ pAacDecoderStaticChannelInfo->last_lpd_mode) &&
+ (pAacDecoderStaticChannelInfo->last_lpc_lost == 0)) {
+ /* Something got wrong! */
+ /* error = AAC_DEC_PARSE_ERROR; */ /* Throwing errors does not help */
+ }
+ }
+
+ return error;
+}
+
+void CLpdChannelStream_Decode(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, UINT flags) {
+ UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
+ int k;
+ UCHAR last_lpd_mode;
+ int nbDiv = NB_DIV;
+
+ /* k is the frame index. If a frame is of size 40MS or 80MS,
+ this frame index is incremented 2 or 4 instead of 1 respectively. */
+ k = 0;
+ last_lpd_mode =
+ pAacDecoderChannelInfo->data.usac
+ .lpd_mode_last; /* could be different to what has been rendered */
+ while (k < nbDiv) {
+ if (mod[k] == 0) {
+ /* ACELP */
+
+ /* If FAC (fac_data[k] != NULL), and previous frame was TCX, apply (TCX)
+ * gains to FAC data */
+ if (last_lpd_mode > 0 && last_lpd_mode != 255 &&
+ pAacDecoderChannelInfo->data.usac.fac_data[k]) {
+ CFac_ApplyGains(pAacDecoderChannelInfo->data.usac.fac_data[k],
+ pAacDecoderChannelInfo->granuleLength,
+ pAacDecoderStaticChannelInfo->last_tcx_gain,
+ pAacDecoderStaticChannelInfo->last_alfd_gains,
+ (last_lpd_mode < 4) ? last_lpd_mode : 3);
+
+ pAacDecoderChannelInfo->data.usac.fac_data_e[k] +=
+ pAacDecoderStaticChannelInfo->last_tcx_gain_e;
+ }
+ } else {
+ /* TCX */
+ CLpd_TcxDecode(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ flags, mod[k], last_lpd_mode, k, 1 /* frameOk == 1 */
+ );
+
+ /* Store TCX gain scale for next possible FAC transition. */
+ pAacDecoderStaticChannelInfo->last_tcx_gain =
+ pAacDecoderChannelInfo->data.usac.tcx_gain[k];
+ pAacDecoderStaticChannelInfo->last_tcx_gain_e =
+ pAacDecoderChannelInfo->data.usac.tcx_gain_e[k];
+
+ /* If FAC (fac_data[k] != NULL), apply gains */
+ if (last_lpd_mode == 0 && pAacDecoderChannelInfo->data.usac.fac_data[k]) {
+ CFac_ApplyGains(
+ pAacDecoderChannelInfo->data.usac.fac_data[k],
+ pAacDecoderChannelInfo->granuleLength /* == fac_length */,
+ pAacDecoderChannelInfo->data.usac.tcx_gain[k],
+ pAacDecoderStaticChannelInfo->last_alfd_gains, mod[k]);
+
+ pAacDecoderChannelInfo->data.usac.fac_data_e[k] +=
+ pAacDecoderChannelInfo->data.usac.tcx_gain_e[k];
+ }
+ }
+
+ /* remember previous mode */
+ last_lpd_mode = mod[k];
+
+ /* Increase k to next frame */
+ k += (mod[k] == 0) ? 1 : (1 << (mod[k] - 1));
+ }
+}
+
+AAC_DECODER_ERROR CLpd_RenderTimeSignal(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
+ INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, UINT flags,
+ UINT strmFlags) {
+ UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ int k, i_offset;
+ int last_k;
+ int nrSamples = 0;
+ int facFB = 1;
+ int nbDiv = NB_DIV;
+ int lDiv = lFrame / nbDiv; /* length of division (acelp or tcx20 frame)*/
+ int lFac = lDiv / 2;
+ int nbSubfr =
+ lFrame / (nbDiv * L_SUBFR); /* number of subframes per division */
+ int nbSubfrSuperfr = nbDiv * nbSubfr;
+ int synSfd = (nbSubfrSuperfr / 2) - BPF_SFD;
+ int SynDelay = synSfd * L_SUBFR;
+ int aacDelay = lFrame / 2;
+
+ /*
+ In respect to the reference software, the synth pointer here is lagging by
+ aacDelay ( == SYN_DELAY + BPF_DELAY ) samples. The corresponding old
+ synthesis samples are handled by the IMDCT overlap.
+ */
+
+ FIXP_DBL *synth_buf =
+ pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1->synth_buf;
+ FIXP_DBL *synth = synth_buf + PIT_MAX_MAX - BPF_DELAY;
+ UCHAR last_lpd_mode, last_last_lpd_mode, last_lpc_lost, last_frame_lost;
+
+ INT pitch[NB_SUBFR_SUPERFR + SYN_SFD];
+ FIXP_DBL pit_gain[NB_SUBFR_SUPERFR + SYN_SFD];
+
+ const int *lg_table;
+ int lg_table_offset = 0;
+
+ UINT samplingRate = pSamplingRateInfo->samplingRate;
+
+ FDKmemclear(pitch, (NB_SUBFR_SUPERFR + SYN_SFD) * sizeof(INT));
+
+ if (flags & AACDEC_FLUSH) {
+ CLpd_Reset(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ flags & AACDEC_FLUSH);
+ frameOk = 0;
+ }
+
+ switch (lFrame) {
+ case 1024:
+ lg_table = &lg_table_ccfl[0][lg_table_offset];
+ break;
+ case 768:
+ lg_table = &lg_table_ccfl[1][lg_table_offset];
+ break;
+ default:
+ FDK_ASSERT(0);
+ return AAC_DEC_UNKNOWN;
+ }
+
+ last_frame_lost = !CConcealment_GetLastFrameOk(
+ &pAacDecoderStaticChannelInfo->concealmentInfo, 0);
+
+ /* Maintain LPD mode from previous frame */
+ if ((pAacDecoderStaticChannelInfo->last_core_mode == FD_LONG) ||
+ (pAacDecoderStaticChannelInfo->last_core_mode == FD_SHORT)) {
+ pAacDecoderStaticChannelInfo->last_lpd_mode = 255;
+ }
+
+ if (!frameOk) {
+ FIXP_DBL old_tcx_gain;
+ FIXP_SGL old_stab;
+ SCHAR old_tcx_gain_e;
+ int nLostSf;
+
+ last_lpd_mode = pAacDecoderStaticChannelInfo->last_lpd_mode;
+ old_tcx_gain = pAacDecoderStaticChannelInfo->last_tcx_gain;
+ old_tcx_gain_e = pAacDecoderStaticChannelInfo->last_tcx_gain_e;
+ old_stab = pAacDecoderStaticChannelInfo->oldStability;
+ nLostSf = pAacDecoderStaticChannelInfo->numLostLpdFrames;
+
+ /* patch the last LPD mode */
+ pAacDecoderChannelInfo->data.usac.lpd_mode_last = last_lpd_mode;
+
+ /* Do mode extrapolation and repeat the previous mode:
+ if previous mode = ACELP -> ACELP
+ if previous mode = TCX-20/40 -> TCX-20
+ if previous mode = TCX-80 -> TCX-80
+ notes:
+ - ACELP is not allowed after TCX (no pitch information to reuse)
+ - TCX-40 is not allowed in the mode repetition to keep the logic simple
+ */
+ switch (last_lpd_mode) {
+ case 0:
+ mod[0] = mod[1] = mod[2] = mod[3] = 0; /* -> ACELP concealment */
+ break;
+ case 3:
+ mod[0] = mod[1] = mod[2] = mod[3] = 3; /* -> TCX FD concealment */
+ break;
+ case 2:
+ mod[0] = mod[1] = mod[2] = mod[3] = 2; /* -> TCX FD concealment */
+ break;
+ case 1:
+ default:
+ mod[0] = mod[1] = mod[2] = mod[3] = 4; /* -> TCX TD concealment */
+ break;
+ }
+
+ /* LPC extrapolation */
+ CLpc_Conceal(pAacDecoderChannelInfo->data.usac.lsp_coeff,
+ pAacDecoderStaticChannelInfo->lpc4_lsf,
+ pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
+ /*(pAacDecoderStaticChannelInfo->numLostLpdFrames == 0) ||*/
+ (last_lpd_mode == 255));
+
+ if ((last_lpd_mode > 0) && (last_lpd_mode < 255)) {
+ /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
+ * converting LSP coefficients again). */
+ FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
+ pAacDecoderStaticChannelInfo->lp_coeff_old[0],
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
+ pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
+ } /* case last_lpd_mode was ACELP is handled by CLpd_TcxDecode() */
+ /* case last_lpd_mode was Time domain TCX concealment is handled after this
+ * "if (!frameOk)"-block */
+
+ /* k is the frame index. If a frame is of size 40MS or 80MS,
+ this frame index is incremented 2 or 4 instead of 1 respectively. */
+ k = 0;
+ while (k < nbDiv) {
+ pAacDecoderChannelInfo->data.usac.tcx_gain[k] = old_tcx_gain;
+ pAacDecoderChannelInfo->data.usac.tcx_gain_e[k] = old_tcx_gain_e;
+
+ /* restore stability value from last frame */
+ pAacDecoderChannelInfo->data.usac.aStability[k] = old_stab;
+
+ /* Increase k to next frame */
+ k += ((mod[k] & 0x3) == 0) ? 1 : (1 << ((mod[k] & 0x3) - 1));
+
+ nLostSf++;
+ }
+ } else {
+ if ((pAacDecoderStaticChannelInfo->last_lpd_mode == 4) && (mod[0] > 0)) {
+ /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
+ * converting LSP coefficients again). */
+ FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
+ pAacDecoderStaticChannelInfo->lp_coeff_old[0],
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
+ pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
+ }
+ }
+
+ Acelp_PreProcessing(synth_buf, pAacDecoderStaticChannelInfo->old_synth, pitch,
+ pAacDecoderStaticChannelInfo->old_T_pf, pit_gain,
+ pAacDecoderStaticChannelInfo->old_gain_pf, samplingRate,
+ &i_offset, lFrame, synSfd, nbSubfrSuperfr);
+
+ /* k is the frame index. If a frame is of size 40MS or 80MS,
+ this frame index is incremented 2 or 4 instead of 1 respectively. */
+ k = 0;
+ last_k = -1; /* mark invalid */
+ last_lpd_mode = pAacDecoderStaticChannelInfo->last_lpd_mode;
+ last_last_lpd_mode = pAacDecoderStaticChannelInfo->last_last_lpd_mode;
+ last_lpc_lost = pAacDecoderStaticChannelInfo->last_lpc_lost | last_frame_lost;
+
+ /* This buffer must be avalable for the case of FD->ACELP transition. The
+ beginning of the buffer is used after the BPF to overwrite the output signal.
+ Only the FAC area must be affected by the BPF */
+
+ while (k < nbDiv) {
+ if (frameOk == 0) {
+ pAacDecoderStaticChannelInfo->numLostLpdFrames++;
+ } else {
+ last_frame_lost |=
+ (pAacDecoderStaticChannelInfo->numLostLpdFrames > 0) ? 1 : 0;
+ pAacDecoderStaticChannelInfo->numLostLpdFrames = 0;
+ }
+ if (mod[k] == 0 || mod[k] == 4) {
+ /* ACELP or TCX time domain concealment */
+ FIXP_DBL *acelp_out;
+
+ /* FAC management */
+ if ((last_lpd_mode != 0) && (last_lpd_mode != 4)) /* TCX TD concealment */
+ {
+ FIXP_DBL *pFacData = NULL;
+
+ if (frameOk && !last_frame_lost) {
+ pFacData = pAacDecoderChannelInfo->data.usac.fac_data[k];
+ }
+
+ nrSamples += CLpd_FAC_Mdct2Acelp(
+ &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples, pFacData,
+ pAacDecoderChannelInfo->data.usac.fac_data_e[k],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[k],
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k],
+ lFrame - nrSamples,
+ CLpd_FAC_getLength(
+ (pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT) ||
+ (k > 0),
+ lFac),
+ (pAacDecoderStaticChannelInfo->last_core_mode != LPD) && (k == 0),
+ 0);
+
+ FDKmemcpy(
+ synth + nrSamples, pAacDecoderStaticChannelInfo->IMdct.overlap.time,
+ pAacDecoderStaticChannelInfo->IMdct.ov_offset * sizeof(FIXP_DBL));
+ {
+ FIXP_LPC *lp_prev =
+ pAacDecoderChannelInfo->data.usac
+ .lp_coeff[0]; /* init value does not real matter */
+ INT lp_prev_exp = pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0];
+
+ if (last_lpd_mode != 255) { /* last mode was tcx */
+ last_k = k - (1 << (last_lpd_mode - 1));
+ if (last_k < 0) {
+ lp_prev = pAacDecoderStaticChannelInfo->lp_coeff_old[1];
+ lp_prev_exp = pAacDecoderStaticChannelInfo->lp_coeff_old_exp[1];
+ } else {
+ lp_prev = pAacDecoderChannelInfo->data.usac.lp_coeff[last_k];
+ lp_prev_exp =
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[last_k];
+ }
+ }
+
+ CLpd_AcelpPrepareInternalMem(
+ synth + aacDelay + k * lDiv, last_lpd_mode,
+ (last_last_lpd_mode == 4) ? 0 : last_last_lpd_mode,
+ pAacDecoderChannelInfo->data.usac.lp_coeff[k],
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k], lp_prev,
+ lp_prev_exp, &pAacDecoderStaticChannelInfo->acelp, lFrame,
+ (last_frame_lost && k < 2), mod[k]);
+ }
+ } else {
+ if (k == 0 && pAacDecoderStaticChannelInfo->IMdct.ov_offset !=
+ lFrame / facFB / 2) {
+ pAacDecoderStaticChannelInfo->IMdct.ov_offset = lFrame / facFB / 2;
+ }
+ nrSamples += imdct_drain(&pAacDecoderStaticChannelInfo->IMdct,
+ synth + nrSamples, lFrame / facFB - nrSamples);
+ }
+
+ if (nrSamples >= lFrame / facFB) {
+ /* Write ACELP time domain samples into IMDCT overlap buffer at
+ * pAacDecoderStaticChannelInfo->IMdct.overlap.time +
+ * pAacDecoderStaticChannelInfo->IMdct.ov_offset
+ */
+ acelp_out = pAacDecoderStaticChannelInfo->IMdct.overlap.time +
+ pAacDecoderStaticChannelInfo->IMdct.ov_offset;
+
+ /* Account ACELP time domain output samples to overlap buffer */
+ pAacDecoderStaticChannelInfo->IMdct.ov_offset += lDiv;
+ } else {
+ /* Write ACELP time domain samples into output buffer at pTimeData +
+ * nrSamples */
+ acelp_out = synth + nrSamples;
+
+ /* Account ACELP time domain output samples to output buffer */
+ nrSamples += lDiv;
+ }
+
+ if (mod[k] == 4) {
+ pAacDecoderStaticChannelInfo->acelp.wsyn_rms = scaleValue(
+ pAacDecoderChannelInfo->data.usac.tcx_gain[k],
+ fixMin(0,
+ pAacDecoderChannelInfo->data.usac.tcx_gain_e[k] - SF_EXC));
+ CLpd_TcxTDConceal(&pAacDecoderStaticChannelInfo->acelp,
+ &pAacDecoderStaticChannelInfo->last_tcx_pitch,
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[k],
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[k + 1],
+ pAacDecoderChannelInfo->data.usac.aStability[k],
+ pAacDecoderStaticChannelInfo->numLostLpdFrames,
+ acelp_out, lFrame,
+ pAacDecoderStaticChannelInfo->last_tcx_noise_factor);
+
+ } else {
+ FDK_ASSERT(pAacDecoderChannelInfo->data.usac.aStability[k] >=
+ (FIXP_SGL)0);
+ CLpd_AcelpDecode(&pAacDecoderStaticChannelInfo->acelp, i_offset,
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[k],
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[k + 1],
+ pAacDecoderChannelInfo->data.usac.aStability[k],
+ &pAacDecoderChannelInfo->data.usac.acelp[k],
+ pAacDecoderStaticChannelInfo->numLostLpdFrames,
+ last_lpc_lost, k, acelp_out,
+ &pitch[(k * nbSubfr) + synSfd],
+ &pit_gain[(k * nbSubfr) + synSfd], lFrame);
+ }
+
+ if (mod[k] != 4) {
+ if (last_lpd_mode != 0 &&
+ pAacDecoderChannelInfo->data.usac
+ .bpf_control_info) { /* FD/TCX -> ACELP transition */
+ /* bass post-filter past FAC area (past two (one for FD short)
+ * subframes) */
+ int currentSf = synSfd + k * nbSubfr;
+
+ if ((k > 0) || (pAacDecoderStaticChannelInfo->last_core_mode !=
+ FD_SHORT)) { /* TCX or FD long -> ACELP */
+ pitch[currentSf - 2] = pitch[currentSf - 1] = pitch[currentSf];
+ pit_gain[currentSf - 2] = pit_gain[currentSf - 1] =
+ pit_gain[currentSf];
+ } else { /* FD short -> ACELP */
+ pitch[currentSf - 1] = pitch[currentSf];
+ pit_gain[currentSf - 1] = pit_gain[currentSf];
+ }
+ }
+ }
+ } else { /* TCX */
+ int lg = lg_table[mod[k]];
+ int isFullBandLpd = 0;
+
+ /* FAC management */
+ if ((last_lpd_mode == 0) || (last_lpd_mode == 4)) /* TCX TD concealment */
+ {
+ C_AALLOC_SCRATCH_START(fac_buf, FIXP_DBL, 1024 / 8);
+
+ /* pAacDecoderChannelInfo->data.usac.fac_data[k] == NULL means no FAC
+ * data available. */
+ if (last_frame_lost == 1 ||
+ pAacDecoderChannelInfo->data.usac.fac_data[k] == NULL) {
+ FDKmemclear(fac_buf, 1024 / 8 * sizeof(FIXP_DBL));
+ pAacDecoderChannelInfo->data.usac.fac_data[k] = fac_buf;
+ pAacDecoderChannelInfo->data.usac.fac_data_e[k] = 0;
+ }
+
+ nrSamples += CLpd_FAC_Acelp2Mdct(
+ &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples,
+ SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, k,
+ pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
+ pAacDecoderChannelInfo->specScale + k, 1,
+ pAacDecoderChannelInfo->data.usac.fac_data[k],
+ pAacDecoderChannelInfo->data.usac.fac_data_e[k],
+ pAacDecoderChannelInfo->granuleLength /* == fac_length */,
+ lFrame - nrSamples, lg,
+ FDKgetWindowSlope(lDiv,
+ GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ lDiv, pAacDecoderChannelInfo->data.usac.lp_coeff[k],
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k],
+ &pAacDecoderStaticChannelInfo->acelp,
+ pAacDecoderChannelInfo->data.usac.tcx_gain[k],
+ (last_frame_lost || !frameOk), 0 /* is not FD FAC */
+ ,
+ last_lpd_mode, k,
+ pAacDecoderChannelInfo
+ ->currAliasingSymmetry /* Note: The current aliasing
+ symmetry for a TCX (i.e. LPD)
+ frame must always be 0 */
+ );
+
+ pitch[(k * nbSubfr) + synSfd + 1] = pitch[(k * nbSubfr) + synSfd] =
+ pitch[(k * nbSubfr) + synSfd - 1];
+ pit_gain[(k * nbSubfr) + synSfd + 1] =
+ pit_gain[(k * nbSubfr) + synSfd] =
+ pit_gain[(k * nbSubfr) + synSfd - 1];
+
+ C_AALLOC_SCRATCH_END(fac_buf, FIXP_DBL, 1024 / 8);
+ } else {
+ int tl = lg;
+ int fl = lDiv;
+ int fr = lDiv;
+
+ nrSamples += imlt_block(
+ &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples,
+ SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, k,
+ pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
+ pAacDecoderChannelInfo->specScale + k, 1, lFrame - nrSamples, tl,
+ FDKgetWindowSlope(fl,
+ GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fl,
+ FDKgetWindowSlope(fr,
+ GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fr, pAacDecoderChannelInfo->data.usac.tcx_gain[k],
+ pAacDecoderChannelInfo->currAliasingSymmetry
+ ? MLT_FLAG_CURR_ALIAS_SYMMETRY
+ : 0);
+ }
+ }
+ /* remember previous mode */
+ last_last_lpd_mode = last_lpd_mode;
+ last_lpd_mode = mod[k];
+ last_lpc_lost = (frameOk == 0) ? 1 : 0;
+
+ /* Increase k to next frame */
+ last_k = k;
+ k += ((mod[k] & 0x3) == 0) ? 1 : (1 << (mod[k] - 1));
+ }
+
+ if (frameOk) {
+ /* assume data was ok => store for concealment */
+ FDK_ASSERT(pAacDecoderChannelInfo->data.usac.aStability[last_k] >=
+ (FIXP_SGL)0);
+ pAacDecoderStaticChannelInfo->oldStability =
+ pAacDecoderChannelInfo->data.usac.aStability[last_k];
+ FDKmemcpy(pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
+ pAacDecoderChannelInfo->data.usac.lsf_adaptive_mean_cand,
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ }
+
+ /* store past lp coeffs for next superframe (they are only valid and needed if
+ * last_lpd_mode was tcx) */
+ if (last_lpd_mode > 0) {
+ FDKmemcpy(pAacDecoderStaticChannelInfo->lp_coeff_old[0],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[nbDiv],
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0] =
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[nbDiv];
+ FDKmemcpy(pAacDecoderStaticChannelInfo->lp_coeff_old[1],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[last_k],
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ pAacDecoderStaticChannelInfo->lp_coeff_old_exp[1] =
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[last_k];
+ }
+
+ FDK_ASSERT(nrSamples == lFrame);
+
+ /* check whether usage of bass postfilter was de-activated in the bitstream;
+ if yes, set pitch gain to 0 */
+ if (!(pAacDecoderChannelInfo->data.usac.bpf_control_info)) {
+ if (mod[0] != 0 && (pAacDecoderStaticChannelInfo->old_bpf_control_info)) {
+ for (int i = 2; i < nbSubfrSuperfr; i++)
+ pit_gain[synSfd + i] = (FIXP_DBL)0;
+ } else {
+ for (int i = 0; i < nbSubfrSuperfr; i++)
+ pit_gain[synSfd + i] = (FIXP_DBL)0;
+ }
+ }
+
+ /* for bass postfilter */
+ for (int n = 0; n < synSfd; n++) {
+ pAacDecoderStaticChannelInfo->old_T_pf[n] = pitch[nbSubfrSuperfr + n];
+ pAacDecoderStaticChannelInfo->old_gain_pf[n] = pit_gain[nbSubfrSuperfr + n];
+ }
+
+ pAacDecoderStaticChannelInfo->old_bpf_control_info =
+ pAacDecoderChannelInfo->data.usac.bpf_control_info;
+
+ {
+ INT lookahead = -BPF_DELAY;
+ int copySamp = (mod[nbDiv - 1] == 0) ? (aacDelay) : (aacDelay - lFac);
+
+ /* Copy enough time domain samples from MDCT to synthesis buffer as needed
+ * by the bass postfilter */
+
+ lookahead += imdct_copy_ov_and_nr(&pAacDecoderStaticChannelInfo->IMdct,
+ synth + nrSamples, copySamp);
+
+ FDK_ASSERT(lookahead == copySamp - BPF_DELAY);
+
+ FIXP_DBL *p2_synth = synth + BPF_DELAY;
+
+ /* recalculate pitch gain to allow postfilering on FAC area */
+ for (int i = 0; i < nbSubfrSuperfr; i++) {
+ int T = pitch[i];
+ FIXP_DBL gain = pit_gain[i];
+
+ if (gain > (FIXP_DBL)0) {
+ gain = get_gain(&p2_synth[i * L_SUBFR], &p2_synth[(i * L_SUBFR) - T],
+ L_SUBFR);
+ pit_gain[i] = gain;
+ }
+ }
+
+ {
+ bass_pf_1sf_delay(p2_synth, pitch, pit_gain, lFrame, lFrame / facFB,
+ mod[nbDiv - 1] ? (SynDelay - (lDiv / 2)) : SynDelay,
+ pTimeData, pAacDecoderStaticChannelInfo->mem_bpf);
+ }
+ }
+
+ Acelp_PostProcessing(synth_buf, pAacDecoderStaticChannelInfo->old_synth,
+ pitch, pAacDecoderStaticChannelInfo->old_T_pf, lFrame,
+ synSfd, nbSubfrSuperfr);
+
+ /* Store last mode for next super frame */
+ { pAacDecoderStaticChannelInfo->last_core_mode = LPD; }
+ pAacDecoderStaticChannelInfo->last_lpd_mode = last_lpd_mode;
+ pAacDecoderStaticChannelInfo->last_last_lpd_mode = last_last_lpd_mode;
+ pAacDecoderStaticChannelInfo->last_lpc_lost = last_lpc_lost;
+
+ return error;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_lpd.h b/fdk-aac/libAACdec/src/usacdec_lpd.h
new file mode 100644
index 0000000..3e7938d
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_lpd.h
@@ -0,0 +1,198 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description: USAC Linear Prediction Domain coding
+
+*******************************************************************************/
+
+#ifndef USACDEC_LPD_H
+#define USACDEC_LPD_H
+
+#include "channelinfo.h"
+
+#define OPTIMIZE_AVG_PERFORMANCE
+
+/**
+ * \brief read a lpd_channel_stream.
+ * \param hBs a bit stream handle, where the lpd_channel_stream is located.
+ * \param pAacDecoderChannelInfo the channel context structure for storing read
+ * data.
+ * \param flags bit stream syntax flags.
+ * \return AAC_DECODER_ERROR error code.
+ */
+AAC_DECODER_ERROR CLpdChannelStream_Read(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, UINT flags);
+
+/**
+ * \brief decode one lpd_channel_stream and render the audio output.
+ * \param pAacDecoderChannelInfo struct holding the channel information to be
+ * rendered.
+ * \param pAacDecoderStaticChannelInfo struct holding the persistent channel
+ * information to be rendered.
+ * \param pSamplingRateInfo holds the sampling rate information
+ * \param elFlags holds the internal decoder flags
+ */
+void CLpdChannelStream_Decode(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, UINT flags);
+
+/**
+ * \brief generate time domain output signal for LPD channel streams
+ * \param pAacDecoderStaticChannelInfo
+ * \param pAacDecoderChannelInfo
+ * \param pTimeData pointer to output buffer
+ * \param samplesPerFrame amount of output samples
+ * \param pSamplingRateInfo holds the sampling rate information
+ * \param pWorkBuffer1 pointer to work buffer for temporal data
+ */
+AAC_DECODER_ERROR CLpd_RenderTimeSignal(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
+ INT samplesPerFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk,
+ UINT flags, UINT strmFlags);
+
+static inline INT CLpd_FAC_getLength(int fNotShortBlock, int fac_length_long) {
+ if (fNotShortBlock) {
+ return (fac_length_long);
+ } else {
+ return fac_length_long / 2;
+ }
+}
+
+void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
+ const FIXP_SGL *filt, INT stop, int len);
+
+/**
+ * \brief perform a low-frequency pitch enhancement on time domain signal
+ * \param[in] syn pointer to time domain input signal
+ * \param[in] synFB pointer to time domain input signal
+ * \param[in] upsampling factor
+ * \param[in] T_sf array with past decoded pitch period values for each subframe
+ * \param[in] non_zero_gain_flags indicates whether pitch gains of past
+ * subframes are zero or not, msb -> [1 BPF_DELAY subfr][7 SYN_DELAY subfr][16
+ * new subfr] <- lsb
+ * \param[in] l_frame length of filtering, must be multiple of L_SUBFR
+ * \param[in] l_next length of allowed look ahead on syn[i], i < l_frame+l_next
+ * \param[out] synth_out pointer to time domain output signal
+ * \param[in,out] mem_bpf pointer to filter memory (L_FILT+L_SUBFR)
+ */
+
+void bass_pf_1sf_delay(FIXP_DBL syn[], const INT T_sf[], FIXP_DBL *pit_gain,
+ const int frame_length, const INT l_frame,
+ const INT l_next, FIXP_PCM *synth_out,
+ FIXP_DBL mem_bpf[]);
+
+/**
+ * \brief random sign generator for FD and TCX noise filling
+ * \param[in,out] seed pointer to random seed
+ * \return if return value is zero use positive sign
+ * \Note: This code is also implemented as a copy in block.cpp, grep for
+ * "UsacRandomSign"
+ */
+FDK_INLINE
+int UsacRandomSign(ULONG *seed) {
+ *seed = (ULONG)((UINT64)(*seed) * 69069 + 5);
+
+ return (int)((*seed) & 0x10000);
+}
+
+void CFdp_Reset(CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo);
+
+#endif /* USACDEC_LPD_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_rom.cpp b/fdk-aac/libAACdec/src/usacdec_rom.cpp
new file mode 100644
index 0000000..ca3009e
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_rom.cpp
@@ -0,0 +1,1504 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): M. Jander
+
+ Description:
+
+*******************************************************************************/
+
+#include "usacdec_rom.h"
+
+#define NB_SPHERE 32
+#define NB_LEADER 37
+#define NB_LDSIGN 226
+#define NB_LDQ3 9
+#define NB_LDQ4 28
+
+/* For bass post filter */
+#define FL2FXCONST_SGL_FILT(a) FL2FXCONST_SGL(a*(1 << SF_FILT_LP))
+#define SF_FILT_LP 1
+
+/* table of factorial */
+const UINT fdk_dec_tab_factorial[8] = {5040, 720, 120, 24, 6, 2, 1, 1};
+
+/* Da - Absolute leaders */
+const UCHAR fdk_dec_Da[NB_LEADER][8] = {
+ {1, 1, 1, 1, 1, 1, 1, 1}, {2, 2, 0, 0, 0, 0, 0, 0},
+ {2, 2, 2, 2, 0, 0, 0, 0}, {3, 1, 1, 1, 1, 1, 1, 1},
+ {4, 0, 0, 0, 0, 0, 0, 0}, {2, 2, 2, 2, 2, 2, 0, 0},
+ {3, 3, 1, 1, 1, 1, 1, 1}, {4, 2, 2, 0, 0, 0, 0, 0},
+ {2, 2, 2, 2, 2, 2, 2, 2}, {3, 3, 3, 1, 1, 1, 1, 1},
+ {4, 2, 2, 2, 2, 0, 0, 0}, {4, 4, 0, 0, 0, 0, 0, 0},
+ {5, 1, 1, 1, 1, 1, 1, 1}, {3, 3, 3, 3, 1, 1, 1, 1},
+ {4, 2, 2, 2, 2, 2, 2, 0}, {4, 4, 2, 2, 0, 0, 0, 0},
+ {5, 3, 1, 1, 1, 1, 1, 1}, {6, 2, 0, 0, 0, 0, 0, 0},
+ {4, 4, 4, 0, 0, 0, 0, 0}, {6, 2, 2, 2, 0, 0, 0, 0},
+ {6, 4, 2, 0, 0, 0, 0, 0}, {7, 1, 1, 1, 1, 1, 1, 1},
+ {8, 0, 0, 0, 0, 0, 0, 0}, {6, 6, 0, 0, 0, 0, 0, 0},
+ {8, 2, 2, 0, 0, 0, 0, 0}, {8, 4, 0, 0, 0, 0, 0, 0},
+ {9, 1, 1, 1, 1, 1, 1, 1}, {10, 2, 0, 0, 0, 0, 0, 0},
+ {8, 8, 0, 0, 0, 0, 0, 0}, {10, 6, 0, 0, 0, 0, 0, 0},
+ {12, 0, 0, 0, 0, 0, 0, 0}, {12, 4, 0, 0, 0, 0, 0, 0},
+ {10, 10, 0, 0, 0, 0, 0, 0}, {14, 2, 0, 0, 0, 0, 0, 0},
+ {12, 8, 0, 0, 0, 0, 0, 0}, {16, 0, 0, 0, 0, 0, 0, 0},
+ {20, 0, 0, 0, 0, 0, 0, 0}};
+
+/* Ds - Sign codes of all signed leaders */
+const UCHAR fdk_dec_Ds[NB_LDSIGN] = {
+ 0, 3, 15, 63, 255, 0, 64, 192, 0, 16, 48, 112, 240, 1, 7,
+ 31, 127, 128, 131, 143, 191, 0, 128, 0, 4, 12, 28, 60, 124, 252,
+ 0, 3, 15, 63, 65, 71, 95, 192, 195, 207, 255, 0, 32, 96, 128,
+ 160, 224, 0, 1, 3, 7, 15, 31, 63, 127, 255, 1, 7, 31, 32,
+ 35, 47, 97, 103, 127, 224, 227, 239, 0, 8, 24, 56, 120, 128, 136,
+ 152, 184, 248, 0, 64, 192, 0, 3, 15, 63, 129, 135, 159, 255, 0,
+ 3, 15, 17, 23, 48, 51, 63, 113, 119, 240, 243, 255, 0, 2, 6,
+ 14, 30, 62, 126, 128, 130, 134, 142, 158, 190, 254, 0, 16, 48, 64,
+ 80, 112, 192, 208, 240, 1, 7, 31, 64, 67, 79, 127, 128, 131, 143,
+ 191, 193, 199, 223, 0, 64, 128, 192, 0, 32, 96, 224, 0, 16, 48,
+ 112, 128, 144, 176, 240, 0, 32, 64, 96, 128, 160, 192, 224, 1, 7,
+ 31, 127, 128, 131, 143, 191, 0, 128, 0, 64, 192, 0, 32, 96, 128,
+ 160, 224, 0, 64, 128, 192, 0, 3, 15, 63, 129, 135, 159, 255, 0,
+ 64, 128, 192, 0, 64, 192, 0, 64, 128, 192, 0, 128, 0, 64, 128,
+ 192, 0, 64, 192, 0, 64, 128, 192, 0, 64, 128, 192, 0, 128, 0,
+ 128};
+
+/* Ns - Number of signed leader associated to a given absolute leader */
+const UCHAR fdk_dec_Ns[NB_LEADER] = {
+ 5, 3, 5, 8, 2, 7, 11, 6, 9, 12, 10, 3, 8, 13, 14, 9, 14, 4, 4,
+ 8, 8, 8, 2, 3, 6, 4, 8, 4, 3, 4, 2, 4, 3, 4, 4, 2, 2};
+
+/* Ia - Position of the first signed leader associated to an absolute leader */
+const UCHAR fdk_dec_Ia[NB_LEADER] = {
+ 0, 5, 8, 13, 21, 23, 30, 41, 47, 56, 68, 78, 81,
+ 89, 102, 116, 125, 139, 143, 147, 155, 163, 171, 173, 176, 182,
+ 186, 194, 198, 201, 205, 207, 211, 214, 218, 222, 224};
+
+/* Is - Cardinalite offset of signed leaders */
+const USHORT fdk_dec_Is[NB_LDSIGN] = {
+ 0, 1, 29, 99, 127, 128, 156, 212, 256, 326, 606,
+ 1026, 1306, 1376, 1432, 1712, 1880, 1888, 1896, 2064, 2344, 240,
+ 248, 0, 28, 196, 616, 1176, 1596, 1764, 1792, 1820, 2240,
+ 2660, 2688, 3024, 4144, 4480, 4508, 4928, 5348, 2400, 2568, 2904,
+ 3072, 3240, 3576, 5376, 5377, 5385, 5413, 5469, 5539, 5595, 5623,
+ 5631, 5632, 5912, 6472, 6528, 6696, 8376, 9216, 10056, 11736, 11904,
+ 11960, 12520, 12800, 13080, 14200, 15880, 17000, 17280, 17560, 18680, 20360,
+ 21480, 3744, 3772, 3828, 21760, 21768, 21936, 22216, 22272, 22328, 22608,
+ 22776, 22784, 22854, 23274, 23344, 24464, 25584, 26004, 28524, 28944, 30064,
+ 31184, 31254, 31674, 31744, 31800, 32136, 32976, 34096, 34936, 35272, 35328,
+ 35384, 35720, 36560, 37680, 38520, 38856, 38912, 39332, 40172, 40592, 41432,
+ 43112, 43952, 44372, 45212, 45632, 45968, 47088, 47424, 47480, 48320, 49160,
+ 49216, 49272, 50112, 50952, 51008, 51344, 52464, 3856, 3912, 3968, 4024,
+ 52800, 52856, 53024, 53192, 53248, 53528, 54368, 55208, 55488, 55768, 56608,
+ 57448, 57728, 58064, 58400, 58736, 59072, 59408, 59744, 60080, 60416, 60472,
+ 60752, 60920, 60928, 60936, 61104, 61384, 4080, 4088, 61440, 61468, 61524,
+ 61552, 61720, 62056, 62224, 62392, 62728, 62896, 62952, 63008, 63064, 63120,
+ 63128, 63296, 63576, 63632, 63688, 63968, 64136, 64144, 64200, 64256, 64312,
+ 64368, 64396, 64452, 64480, 64536, 64592, 64648, 64704, 64712, 64720, 64776,
+ 64832, 64888, 64944, 64972, 65028, 65056, 65112, 65168, 65224, 65280, 65336,
+ 65392, 65448, 65504, 65512, 65520, 65528};
+
+/* A3 - Number of the absolute leaders in codebooks Q2 and Q3 */
+const UCHAR fdk_dec_A3[NB_LDQ3] = {0, 1, 4, 2, 3, 7, 11, 17, 22};
+
+/* A4 - Number of the absolute leaders in codebook Q4 */
+const UCHAR fdk_dec_A4[NB_LDQ4] = {5, 6, 8, 9, 10, 12, 13, 14, 15, 16,
+ 18, 19, 20, 21, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36};
+
+/* I3 - Cardinality offsets for absolute leaders in Q3 */
+const USHORT fdk_dec_I3[NB_LDQ3] = {0, 128, 240, 256, 1376,
+ 2400, 3744, 3856, 4080};
+
+/* I4 - Cardinality offset for absolute leaders in Q4 */
+const USHORT fdk_dec_I4[NB_LDQ4] = {
+ 0, 1792, 5376, 5632, 12800, 21760, 22784, 31744, 38912, 45632,
+ 52800, 53248, 57728, 60416, 61440, 61552, 62896, 63120, 64144, 64368,
+ 64480, 64704, 64720, 64944, 65056, 65280, 65504, 65520};
+
+/* Initial ISF memory for concealment case */
+#define LSFI(x) ((x) << (FRACT_BITS - LSF_SCALE - 1))
+
+const FIXP_LPC fdk_dec_lsf_init[16] = {1506, 3012, 4518, 6024, 7529, 9035,
+ 10541, 12047, 13553, 15059, 16565, 18071,
+ 19576, 21082, 22588, 24094};
+
+/* dico_lsf_abs_8b is scaled by 1/(1<<13) */
+#define DICO(x) FX_DBL2FXCONST_LPC(x >> (LSF_SCALE - 13))
+
+const FIXP_LPC fdk_dec_dico_lsf_abs_8b[] = {
+ DICO(0x05e57fe8), DICO(0x0ac00810), DICO(0x11ed8500), DICO(0x16d42ce0),
+ DICO(0x1beb1e20), DICO(0x217eaf40), DICO(0x2768c740), DICO(0x2d26f600),
+ DICO(0x32fe68c0), DICO(0x38b1d980), DICO(0x3e95bd80), DICO(0x446dab00),
+ DICO(0x4abfd280), DICO(0x5094b380), DICO(0x56ccb800), DICO(0x5c9aba00),
+ DICO(0x09660ca0), DICO(0x10ab4c00), DICO(0x15a16f20), DICO(0x19d3c780),
+ DICO(0x1ee99060), DICO(0x241d1200), DICO(0x29c83700), DICO(0x2f098f00),
+ DICO(0x34803fc0), DICO(0x3a37bc00), DICO(0x3ff55580), DICO(0x45da9280),
+ DICO(0x4bec6700), DICO(0x5169e300), DICO(0x57797c80), DICO(0x5d09ae80),
+ DICO(0x08a203b0), DICO(0x0d6ed1a0), DICO(0x152ccf20), DICO(0x19639dc0),
+ DICO(0x1d7e3e60), DICO(0x21f4a7c0), DICO(0x27b2f8c0), DICO(0x2dbb4480),
+ DICO(0x33ecde80), DICO(0x3982e100), DICO(0x3ea16100), DICO(0x43ab6080),
+ DICO(0x49534a80), DICO(0x4ea7e100), DICO(0x550d6300), DICO(0x5bcdcc80),
+ DICO(0x072dd048), DICO(0x0c654690), DICO(0x1436e940), DICO(0x19459680),
+ DICO(0x1e0041c0), DICO(0x2240dc80), DICO(0x26de4040), DICO(0x2b509b00),
+ DICO(0x309d8780), DICO(0x36151180), DICO(0x3c6c1200), DICO(0x42df6b80),
+ DICO(0x4a144400), DICO(0x50541280), DICO(0x56c34b80), DICO(0x5cb6c600),
+ DICO(0x051fef00), DICO(0x06b9fb48), DICO(0x0b4f9cc0), DICO(0x17e27800),
+ DICO(0x1b8c7340), DICO(0x1f772ca0), DICO(0x2478dc80), DICO(0x28242240),
+ DICO(0x2f27c640), DICO(0x33b03e80), DICO(0x381f20c0), DICO(0x3c662c00),
+ DICO(0x49565080), DICO(0x529b0f00), DICO(0x583ed080), DICO(0x5d8cec00),
+ DICO(0x071c4d18), DICO(0x097853b0), DICO(0x0f0f0690), DICO(0x157bf980),
+ DICO(0x1801f580), DICO(0x1deb0c20), DICO(0x2523da40), DICO(0x28534600),
+ DICO(0x2eb499c0), DICO(0x32eb5ac0), DICO(0x36749580), DICO(0x3a748200),
+ DICO(0x4325f700), DICO(0x515d8300), DICO(0x58a18700), DICO(0x5d722100),
+ DICO(0x06cbcd88), DICO(0x08bb6740), DICO(0x0dead310), DICO(0x152f0cc0),
+ DICO(0x18427640), DICO(0x1d9f2f20), DICO(0x22ba3b40), DICO(0x271a6e80),
+ DICO(0x2c677ec0), DICO(0x31061b00), DICO(0x349eef40), DICO(0x3c531b80),
+ DICO(0x4aed0580), DICO(0x4f8bbf80), DICO(0x54b74980), DICO(0x5bc9b700),
+ DICO(0x046410c8), DICO(0x06522ab0), DICO(0x0b6528c0), DICO(0x0f94bd90),
+ DICO(0x1a8f8b80), DICO(0x1ea57820), DICO(0x233ee180), DICO(0x27b3acc0),
+ DICO(0x2bd1d240), DICO(0x2fc4bcc0), DICO(0x3a98ea40), DICO(0x43d3f500),
+ DICO(0x49b37580), DICO(0x4e2afd00), DICO(0x55953300), DICO(0x5d36f600),
+ DICO(0x05d0f6c8), DICO(0x07e56d90), DICO(0x0be98080), DICO(0x0f956f30),
+ DICO(0x1259b3c0), DICO(0x1f08b240), DICO(0x25008c00), DICO(0x2900b180),
+ DICO(0x31ea6f00), DICO(0x352d1e00), DICO(0x3c970c80), DICO(0x45271200),
+ DICO(0x4b632280), DICO(0x5098a480), DICO(0x5672fc80), DICO(0x5c163180),
+ DICO(0x05bd81a0), DICO(0x07d4b8f0), DICO(0x0ce224b0), DICO(0x110abe20),
+ DICO(0x13dfeac0), DICO(0x17dedae0), DICO(0x2535c0c0), DICO(0x2a19da80),
+ DICO(0x2e5224c0), DICO(0x38ddeec0), DICO(0x3da99d80), DICO(0x42799100),
+ DICO(0x48973b00), DICO(0x4ea62880), DICO(0x53f77e80), DICO(0x5bd9c100),
+ DICO(0x0395cd50), DICO(0x058244b8), DICO(0x0af45520), DICO(0x1329cea0),
+ DICO(0x1a3970c0), DICO(0x1d9f2e00), DICO(0x21704400), DICO(0x277a34c0),
+ DICO(0x30215b40), DICO(0x33875040), DICO(0x3c159840), DICO(0x452fea00),
+ DICO(0x4981d200), DICO(0x4e15a980), DICO(0x54e84780), DICO(0x5c79ea00),
+ DICO(0x05413b98), DICO(0x08132a80), DICO(0x0dc7f050), DICO(0x13e25460),
+ DICO(0x1784bf80), DICO(0x1d630200), DICO(0x238bc880), DICO(0x28cc0880),
+ DICO(0x30da1a40), DICO(0x391e2200), DICO(0x415d8d00), DICO(0x48f13280),
+ DICO(0x4e300300), DICO(0x52e56580), DICO(0x5849fe80), DICO(0x5cdef400),
+ DICO(0x04a058c8), DICO(0x07569b88), DICO(0x0ef26610), DICO(0x13208140),
+ DICO(0x168c0500), DICO(0x1afec080), DICO(0x22a0abc0), DICO(0x2a057880),
+ DICO(0x2fd1c840), DICO(0x3703c680), DICO(0x3d326b80), DICO(0x43df2e80),
+ DICO(0x4a6f9000), DICO(0x50900d80), DICO(0x56c73f00), DICO(0x5cc3da80),
+ DICO(0x065c99e8), DICO(0x09060c50), DICO(0x0d1ef1c0), DICO(0x16bd9020),
+ DICO(0x1a04dae0), DICO(0x1e3c0580), DICO(0x25783700), DICO(0x29710ac0),
+ DICO(0x309cbb80), DICO(0x36c66280), DICO(0x3adb0580), DICO(0x41b37e00),
+ DICO(0x496ca700), DICO(0x4dab7600), DICO(0x52be6280), DICO(0x58fec480),
+ DICO(0x04640880), DICO(0x05a75ab8), DICO(0x0edba410), DICO(0x16e076a0),
+ DICO(0x198acec0), DICO(0x1eb5fae0), DICO(0x228c9000), DICO(0x29986c00),
+ DICO(0x2c780c80), DICO(0x38078dc0), DICO(0x3f42dc00), DICO(0x441ba900),
+ DICO(0x492f8080), DICO(0x4ed85d00), DICO(0x54605800), DICO(0x5d106a80),
+ DICO(0x045cb970), DICO(0x0627a828), DICO(0x0db35290), DICO(0x1778f780),
+ DICO(0x1a243c60), DICO(0x23c2dd40), DICO(0x27c57840), DICO(0x2f53cd80),
+ DICO(0x36f65600), DICO(0x3bc1b2c0), DICO(0x40c36500), DICO(0x46074180),
+ DICO(0x4b551b80), DICO(0x50a99700), DICO(0x569b6c80), DICO(0x5ca25780),
+ DICO(0x05ef2828), DICO(0x07d3adf8), DICO(0x0b5416d0), DICO(0x0f9adb70),
+ DICO(0x126e7360), DICO(0x1baff460), DICO(0x2b5decc0), DICO(0x31036200),
+ DICO(0x34ca7500), DICO(0x39681340), DICO(0x3da97100), DICO(0x4161ee00),
+ DICO(0x46a62e80), DICO(0x4d1b9380), DICO(0x530e0300), DICO(0x59ff0480),
+ DICO(0x04f5bc50), DICO(0x06e90d18), DICO(0x0c2af480), DICO(0x123f7400),
+ DICO(0x1530a160), DICO(0x18aa3dc0), DICO(0x1cc0a240), DICO(0x2cdb02c0),
+ DICO(0x32909a00), DICO(0x36bae640), DICO(0x3c917a80), DICO(0x40121900),
+ DICO(0x48a90d80), DICO(0x51ccc180), DICO(0x5884ea00), DICO(0x5dbc4280),
+ DICO(0x05791410), DICO(0x07b0dd80), DICO(0x0bec4190), DICO(0x13c30520),
+ DICO(0x17ac1900), DICO(0x1b6f1d00), DICO(0x26e54f40), DICO(0x2d4a8040),
+ DICO(0x311c6840), DICO(0x38ec4180), DICO(0x3f0c4340), DICO(0x427c5b00),
+ DICO(0x4886e480), DICO(0x504a0b00), DICO(0x56d48700), DICO(0x5c80f600),
+ DICO(0x04b58880), DICO(0x0743f0d8), DICO(0x0be95e20), DICO(0x0fd0d9b0),
+ DICO(0x1c2e11a0), DICO(0x2241af80), DICO(0x296e83c0), DICO(0x2f16adc0),
+ DICO(0x32cd6fc0), DICO(0x374ddec0), DICO(0x3da95f80), DICO(0x45d56c80),
+ DICO(0x4c6afa80), DICO(0x5141f380), DICO(0x5616b380), DICO(0x5c58f580),
+ DICO(0x03f4b368), DICO(0x05939890), DICO(0x09d95480), DICO(0x122cac60),
+ DICO(0x17e27e00), DICO(0x1f9dc680), DICO(0x26e26680), DICO(0x2ae64040),
+ DICO(0x2dd6cf40), DICO(0x3295c400), DICO(0x3e23b400), DICO(0x44fd0380),
+ DICO(0x4ad7a700), DICO(0x51295e80), DICO(0x594a9400), DICO(0x5e41aa00),
+ DICO(0x0424b9d8), DICO(0x05b30508), DICO(0x09380f20), DICO(0x0c9509c0),
+ DICO(0x18730860), DICO(0x219a9d40), DICO(0x24f699c0), DICO(0x289b2680),
+ DICO(0x2cb62240), DICO(0x36e88180), DICO(0x3e968800), DICO(0x48053c80),
+ DICO(0x4d6dca80), DICO(0x51d9a580), DICO(0x563e5a80), DICO(0x5c0b2b80),
+ DICO(0x03456ae8), DICO(0x04e49948), DICO(0x07dd0e88), DICO(0x0ed5cd30),
+ DICO(0x1b06e980), DICO(0x1de2b9c0), DICO(0x21160540), DICO(0x270a8240),
+ DICO(0x3352a280), DICO(0x3b8b6c00), DICO(0x40241400), DICO(0x43f60f80),
+ DICO(0x4a897900), DICO(0x51692a00), DICO(0x57449d00), DICO(0x5d497480),
+ DICO(0x04b94290), DICO(0x067e99d0), DICO(0x0ab06840), DICO(0x0e697070),
+ DICO(0x1745c460), DICO(0x22ee8040), DICO(0x2647e8c0), DICO(0x2bc2c680),
+ DICO(0x2fd57d00), DICO(0x37186680), DICO(0x3d074500), DICO(0x412b2800),
+ DICO(0x4579af00), DICO(0x4caff980), DICO(0x557add00), DICO(0x5c6ae780),
+ DICO(0x0423a090), DICO(0x05b9bca0), DICO(0x091b45d0), DICO(0x0c5b6d60),
+ DICO(0x194dd1c0), DICO(0x1fc85020), DICO(0x2486b080), DICO(0x2920af80),
+ DICO(0x2dd4f140), DICO(0x3598be40), DICO(0x3b9c1440), DICO(0x42d19280),
+ DICO(0x4a314280), DICO(0x50b00a00), DICO(0x56c55400), DICO(0x5d5ba300),
+ DICO(0x03e68b28), DICO(0x05a7b190), DICO(0x0917f000), DICO(0x0d247050),
+ DICO(0x19e637a0), DICO(0x2221a540), DICO(0x2777e540), DICO(0x2c103380),
+ DICO(0x30c2e040), DICO(0x389f1240), DICO(0x3f4a2c80), DICO(0x454a4c00),
+ DICO(0x4b0ab680), DICO(0x50cf6000), DICO(0x571c0700), DICO(0x5d2ef600),
+ DICO(0x04886f18), DICO(0x065103e8), DICO(0x0a607d40), DICO(0x0db91960),
+ DICO(0x13546f20), DICO(0x22f5e200), DICO(0x27064240), DICO(0x2e371d40),
+ DICO(0x33659240), DICO(0x38aa1c40), DICO(0x417bb280), DICO(0x47ca9480),
+ DICO(0x4dd6fb80), DICO(0x528e3480), DICO(0x57c49d80), DICO(0x5cc98100),
+ DICO(0x02db2370), DICO(0x04398848), DICO(0x07a8da38), DICO(0x10b90280),
+ DICO(0x1a2a4a20), DICO(0x20b1f640), DICO(0x277096c0), DICO(0x2dc568c0),
+ DICO(0x341b33c0), DICO(0x3a000640), DICO(0x40152880), DICO(0x45eeee00),
+ DICO(0x4c08c480), DICO(0x51bf0600), DICO(0x5799a180), DICO(0x5d23db80),
+ DICO(0x047b1498), DICO(0x06089848), DICO(0x0905af20), DICO(0x0bf13c20),
+ DICO(0x11fcf620), DICO(0x1f79cd00), DICO(0x257f6b40), DICO(0x2cfc2600),
+ DICO(0x31610040), DICO(0x35ea8280), DICO(0x3c774bc0), DICO(0x44417280),
+ DICO(0x4b432500), DICO(0x510e9480), DICO(0x56f2e480), DICO(0x5d282780),
+ DICO(0x02cfd0b0), DICO(0x042845d8), DICO(0x0a1fa610), DICO(0x15911fc0),
+ DICO(0x1bc07f00), DICO(0x2281d640), DICO(0x287abcc0), DICO(0x2ec6b400),
+ DICO(0x34a0d040), DICO(0x3aa4dcc0), DICO(0x4074d980), DICO(0x46726b80),
+ DICO(0x4c3bf900), DICO(0x52055100), DICO(0x57b20500), DICO(0x5d34da80),
+ DICO(0x04d4f768), DICO(0x06cad828), DICO(0x0b52a540), DICO(0x0ea224e0),
+ DICO(0x13c3f460), DICO(0x23808900), DICO(0x27d1cec0), DICO(0x2d6051c0),
+ DICO(0x33c5ff00), DICO(0x37ef2440), DICO(0x3d2a5300), DICO(0x43266000),
+ DICO(0x4a53a100), DICO(0x50acce80), DICO(0x57612100), DICO(0x5cdee380),
+ DICO(0x04039a88), DICO(0x0626dcb0), DICO(0x0c059620), DICO(0x12c3db20),
+ DICO(0x1bb9eb40), DICO(0x240fda00), DICO(0x2baab840), DICO(0x3177c5c0),
+ DICO(0x36cf2e40), DICO(0x3c025100), DICO(0x40bb8d00), DICO(0x45960800),
+ DICO(0x4adaca00), DICO(0x505a7300), DICO(0x566a6400), DICO(0x5c8ce000),
+ DICO(0x062891e8), DICO(0x09680810), DICO(0x0e9a11b0), DICO(0x1523e320),
+ DICO(0x1c57db00), DICO(0x21f22c80), DICO(0x28aeeb00), DICO(0x2e4fd600),
+ DICO(0x341cf000), DICO(0x3a5034c0), DICO(0x40600f80), DICO(0x461fde00),
+ DICO(0x4c368480), DICO(0x51dbbc00), DICO(0x57709780), DICO(0x5cce9880),
+ DICO(0x05d41f70), DICO(0x0a65bb30), DICO(0x132ddfa0), DICO(0x17d26820),
+ DICO(0x1e6d8380), DICO(0x24e68dc0), DICO(0x2b68c4c0), DICO(0x30fa2880),
+ DICO(0x361998c0), DICO(0x3aa1d640), DICO(0x3f942400), DICO(0x44d11680),
+ DICO(0x4ab8e580), DICO(0x50643b80), DICO(0x5697fe00), DICO(0x5cb3a780),
+ DICO(0x0707fa10), DICO(0x0cb8beb0), DICO(0x15011d20), DICO(0x1a4ad300),
+ DICO(0x20997080), DICO(0x26dbe240), DICO(0x2d907880), DICO(0x3307a3c0),
+ DICO(0x38819740), DICO(0x3d3e89c0), DICO(0x41ea2300), DICO(0x469ce200),
+ DICO(0x4be61680), DICO(0x51261b80), DICO(0x5716ef80), DICO(0x5cba2900),
+ DICO(0x084dc830), DICO(0x0f16f610), DICO(0x16ca2420), DICO(0x1bb58380),
+ DICO(0x22f00f00), DICO(0x296ba4c0), DICO(0x306d2600), DICO(0x362ca080),
+ DICO(0x3b86d280), DICO(0x3ffa96c0), DICO(0x446a5300), DICO(0x48d0fd00),
+ DICO(0x4d8a0800), DICO(0x525bf200), DICO(0x57f5aa00), DICO(0x5d569480),
+ DICO(0x08d664f0), DICO(0x110c8520), DICO(0x1865fa40), DICO(0x1efe3160),
+ DICO(0x26f38740), DICO(0x2d4608c0), DICO(0x32862500), DICO(0x374f8840),
+ DICO(0x3bfa9900), DICO(0x3ff5c8c0), DICO(0x4450c500), DICO(0x4918e680),
+ DICO(0x4e1d0f00), DICO(0x53342600), DICO(0x58a38e00), DICO(0x5dbbff00),
+ DICO(0x09143fd0), DICO(0x0f401c30), DICO(0x169c1ee0), DICO(0x1bcfb280),
+ DICO(0x2190dd00), DICO(0x27bf56c0), DICO(0x2e8e0640), DICO(0x34b67080),
+ DICO(0x3b534dc0), DICO(0x41134c00), DICO(0x467a3280), DICO(0x4bd63600),
+ DICO(0x50de8700), DICO(0x55657580), DICO(0x5a0cef00), DICO(0x5e8aa200),
+ DICO(0x06b5d860), DICO(0x0c8a5000), DICO(0x13343620), DICO(0x17a2abe0),
+ DICO(0x1caf7340), DICO(0x22a3f740), DICO(0x29059980), DICO(0x2ecff880),
+ DICO(0x34ce0f00), DICO(0x3ad32280), DICO(0x40f08d80), DICO(0x46d1d400),
+ DICO(0x4ca9df00), DICO(0x523b9580), DICO(0x57ea9b80), DICO(0x5d4a9a00),
+ DICO(0x03822fec), DICO(0x0522c670), DICO(0x099f89a0), DICO(0x12ddc9c0),
+ DICO(0x17c3d380), DICO(0x1d27ec20), DICO(0x2219e480), DICO(0x25fdf580),
+ DICO(0x329d6500), DICO(0x368ba040), DICO(0x3afedb00), DICO(0x430db980),
+ DICO(0x4a105380), DICO(0x51205080), DICO(0x5673b880), DICO(0x5ca2e500),
+ DICO(0x04e07408), DICO(0x06a13dc0), DICO(0x0b31c780), DICO(0x0e67fcd0),
+ DICO(0x13723240), DICO(0x1f87a840), DICO(0x2321ab00), DICO(0x2c604680),
+ DICO(0x310bc180), DICO(0x351eea40), DICO(0x3a2d6440), DICO(0x3e7ebac0),
+ DICO(0x4798ef80), DICO(0x50721100), DICO(0x57ff9880), DICO(0x5dc2e080),
+ DICO(0x05d626b8), DICO(0x07eaf140), DICO(0x0c5675b0), DICO(0x0eba7b00),
+ DICO(0x1a7f36c0), DICO(0x1f969200), DICO(0x244d8c00), DICO(0x29666440),
+ DICO(0x2c94b100), DICO(0x31865380), DICO(0x3713c000), DICO(0x3c228f40),
+ DICO(0x4296ed80), DICO(0x4dcbde00), DICO(0x56059a00), DICO(0x5c932d00),
+ DICO(0x07dceb20), DICO(0x0b533fe0), DICO(0x0eb18880), DICO(0x13124220),
+ DICO(0x167f74e0), DICO(0x1afbee40), DICO(0x229e2f80), DICO(0x26b05ec0),
+ DICO(0x2c7b4040), DICO(0x32806140), DICO(0x38da6540), DICO(0x3e495540),
+ DICO(0x444d3880), DICO(0x4e784400), DICO(0x5865f580), DICO(0x5e616180),
+ DICO(0x06395790), DICO(0x084b8f20), DICO(0x0d0e26a0), DICO(0x10897ac0),
+ DICO(0x14bcd080), DICO(0x1c5babe0), DICO(0x2108f9c0), DICO(0x274f8e80),
+ DICO(0x2b0ba180), DICO(0x305b8480), DICO(0x383ad300), DICO(0x3e34f440),
+ DICO(0x47f7aa00), DICO(0x4fdb5880), DICO(0x56b8c280), DICO(0x5d07d700),
+ DICO(0x051f0880), DICO(0x071b8fa8), DICO(0x0ce79c90), DICO(0x1005bd60),
+ DICO(0x14a4a080), DICO(0x183def40), DICO(0x1ee8d0a0), DICO(0x2c5b9bc0),
+ DICO(0x309f9dc0), DICO(0x35659380), DICO(0x3c0439c0), DICO(0x49603800),
+ DICO(0x5018a800), DICO(0x54862380), DICO(0x593edd80), DICO(0x5d415b80),
+ DICO(0x051c8108), DICO(0x06bd97d8), DICO(0x0b47d030), DICO(0x0d9c81a0),
+ DICO(0x178f0be0), DICO(0x1cdf7c80), DICO(0x2183db40), DICO(0x26ec7180),
+ DICO(0x2a3856c0), DICO(0x366c9b40), DICO(0x3d3611c0), DICO(0x42788100),
+ DICO(0x4981f200), DICO(0x4dd68380), DICO(0x55286a00), DICO(0x5cc72500),
+ DICO(0x06ee58c8), DICO(0x098b1310), DICO(0x0ccbd880), DICO(0x0f9d68f0),
+ DICO(0x1277ac40), DICO(0x1d71faa0), DICO(0x230d9480), DICO(0x276b8c00),
+ DICO(0x2ec77000), DICO(0x31f2a700), DICO(0x3bee0200), DICO(0x42250700),
+ DICO(0x466b7100), DICO(0x4de41980), DICO(0x56a08d80), DICO(0x5d700880),
+ DICO(0x062f1d80), DICO(0x091bcd30), DICO(0x0cd875e0), DICO(0x0fd42e60),
+ DICO(0x1322b980), DICO(0x1f11b480), DICO(0x2651e5c0), DICO(0x29f9b480),
+ DICO(0x2e238840), DICO(0x30fc58c0), DICO(0x37aa3040), DICO(0x3e9ac580),
+ DICO(0x44c6fd00), DICO(0x4eba4300), DICO(0x56fdad00), DICO(0x5d885700),
+ DICO(0x04213a78), DICO(0x05d028c0), DICO(0x09a1f9e0), DICO(0x0d28ae90),
+ DICO(0x151819a0), DICO(0x1c78c860), DICO(0x21d78f00), DICO(0x29992cc0),
+ DICO(0x2fbdc180), DICO(0x36bab700), DICO(0x3d4db1c0), DICO(0x4402a280),
+ DICO(0x4a920700), DICO(0x50988600), DICO(0x5717c100), DICO(0x5d52c200),
+ DICO(0x036af4bc), DICO(0x0514cf40), DICO(0x09ec2d30), DICO(0x113de160),
+ DICO(0x1991b700), DICO(0x20590bc0), DICO(0x23892a00), DICO(0x2654cd00),
+ DICO(0x2ff5c0c0), DICO(0x387ed380), DICO(0x3e305300), DICO(0x46137700),
+ DICO(0x4bc29100), DICO(0x4f96dd80), DICO(0x564aca00), DICO(0x5c4d9e80),
+ DICO(0x041051a0), DICO(0x0734dad8), DICO(0x1064e780), DICO(0x14d8bf00),
+ DICO(0x19727e40), DICO(0x1f7bede0), DICO(0x25b5ebc0), DICO(0x2c71fd40),
+ DICO(0x32813740), DICO(0x39340c80), DICO(0x3f974f40), DICO(0x45ca1580),
+ DICO(0x4be69f00), DICO(0x51c9c900), DICO(0x57a1ce80), DICO(0x5d0b2b00),
+ DICO(0x04b73008), DICO(0x06598b60), DICO(0x0b0aee00), DICO(0x15ac7ba0),
+ DICO(0x18b5e340), DICO(0x1f5308c0), DICO(0x23cfc4c0), DICO(0x27d3fdc0),
+ DICO(0x30138080), DICO(0x343c85c0), DICO(0x389cb540), DICO(0x42def900),
+ DICO(0x4aa6a000), DICO(0x4f719580), DICO(0x5585d080), DICO(0x5bc03f00),
+ DICO(0x05601b88), DICO(0x07616b88), DICO(0x0c22ba40), DICO(0x16bc8200),
+ DICO(0x192ebf80), DICO(0x1f71c120), DICO(0x25c59d00), DICO(0x28f76d00),
+ DICO(0x33dbdd80), DICO(0x39f40d80), DICO(0x3da0c880), DICO(0x432c1e00),
+ DICO(0x4aa19d80), DICO(0x51006f80), DICO(0x56a62e80), DICO(0x5c67d000),
+ DICO(0x053095d0), DICO(0x06c43fc8), DICO(0x0f80a460), DICO(0x139b4960),
+ DICO(0x1769ed80), DICO(0x1c828b00), DICO(0x21195980), DICO(0x26329800),
+ DICO(0x29f35900), DICO(0x2dc9df80), DICO(0x3795f0c0), DICO(0x43139b00),
+ DICO(0x4acae680), DICO(0x5048de00), DICO(0x57c11880), DICO(0x5db35900),
+ DICO(0x0466e180), DICO(0x05d31550), DICO(0x10cad200), DICO(0x168c2be0),
+ DICO(0x1a5e9580), DICO(0x1ef2d480), DICO(0x238db240), DICO(0x2920ce80),
+ DICO(0x2c80b4c0), DICO(0x30bb2700), DICO(0x38b257c0), DICO(0x46abd580),
+ DICO(0x4c30dd80), DICO(0x50e51880), DICO(0x5782ab80), DICO(0x5d23da80),
+ DICO(0x06700f78), DICO(0x085ec0a0), DICO(0x0c037280), DICO(0x16d90a60),
+ DICO(0x1bf46c00), DICO(0x1e6f4740), DICO(0x22c2c180), DICO(0x263fa2c0),
+ DICO(0x2c4a74c0), DICO(0x3642b040), DICO(0x3a476900), DICO(0x3ea12840),
+ DICO(0x46b6e880), DICO(0x4b5bad80), DICO(0x5152a500), DICO(0x5c1c6080),
+ DICO(0x041f8108), DICO(0x05ef1d98), DICO(0x0ce43300), DICO(0x11647cc0),
+ DICO(0x16e77fe0), DICO(0x1cdafc40), DICO(0x218832c0), DICO(0x26dd1b40),
+ DICO(0x2c776100), DICO(0x34f1eb80), DICO(0x3caf6100), DICO(0x45630a80),
+ DICO(0x4c0c5380), DICO(0x517ae980), DICO(0x567f4280), DICO(0x5c4bf900),
+ DICO(0x06673f18), DICO(0x091ee510), DICO(0x0d6ccb10), DICO(0x12503240),
+ DICO(0x158696e0), DICO(0x1f035420), DICO(0x24e6eac0), DICO(0x2a03bf40),
+ DICO(0x329aa000), DICO(0x375aafc0), DICO(0x3da133c0), DICO(0x45645600),
+ DICO(0x4c447c00), DICO(0x51a26b00), DICO(0x57917c00), DICO(0x5c557680),
+ DICO(0x04f84c18), DICO(0x06db4c30), DICO(0x0d53a940), DICO(0x1095cd20),
+ DICO(0x142b0b20), DICO(0x184229c0), DICO(0x20147280), DICO(0x25152740),
+ DICO(0x2db89fc0), DICO(0x35f3d200), DICO(0x400aa680), DICO(0x47a51c00),
+ DICO(0x4d9c5c00), DICO(0x525d1680), DICO(0x5832af00), DICO(0x5d27d580),
+ DICO(0x05c973d0), DICO(0x07c25810), DICO(0x0e928e50), DICO(0x12f5ad00),
+ DICO(0x16b2a800), DICO(0x1c2c9ce0), DICO(0x20b0f100), DICO(0x28be1940),
+ DICO(0x2d0f3c00), DICO(0x30a06f40), DICO(0x399e4340), DICO(0x46b48280),
+ DICO(0x4bbbc300), DICO(0x50283700), DICO(0x54a1a800), DICO(0x5ab20c80),
+ DICO(0x03df9390), DICO(0x055ff1e0), DICO(0x0bbeb640), DICO(0x17d906c0),
+ DICO(0x1ac20140), DICO(0x1fd84440), DICO(0x24502600), DICO(0x2a9fe640),
+ DICO(0x2ef79700), DICO(0x34cbed40), DICO(0x3c48cd00), DICO(0x43ccce80),
+ DICO(0x49b1d500), DICO(0x50145e00), DICO(0x56f16f80), DICO(0x5d46dd80),
+ DICO(0x04a69ef0), DICO(0x06470480), DICO(0x0defbd00), DICO(0x1590e900),
+ DICO(0x18114000), DICO(0x1bda6c60), DICO(0x1f64d160), DICO(0x28d8d640),
+ DICO(0x2d4e2880), DICO(0x34cfe380), DICO(0x3b7077c0), DICO(0x42f36a80),
+ DICO(0x49615580), DICO(0x4ff9d200), DICO(0x5657ef80), DICO(0x5cb91300),
+ DICO(0x038893dc), DICO(0x0535cdf0), DICO(0x0aabff80), DICO(0x146daaa0),
+ DICO(0x1848c700), DICO(0x1ce578c0), DICO(0x21116000), DICO(0x2b116d40),
+ DICO(0x32113500), DICO(0x3751a480), DICO(0x3e88c200), DICO(0x44cb1800),
+ DICO(0x4af1c200), DICO(0x5122b980), DICO(0x5782bc80), DICO(0x5d20be00),
+ DICO(0x03118434), DICO(0x04afe2e8), DICO(0x08f144f0), DICO(0x12c787c0),
+ DICO(0x1c32e4e0), DICO(0x1f701180), DICO(0x2362f740), DICO(0x2b995cc0),
+ DICO(0x3322c540), DICO(0x3951f200), DICO(0x3f7c2c80), DICO(0x4569c480),
+ DICO(0x4b2a6200), DICO(0x50905e80), DICO(0x56236680), DICO(0x5c32fa00),
+ DICO(0x0460c3b0), DICO(0x061e1378), DICO(0x0b07f610), DICO(0x166e0680),
+ DICO(0x18d0f020), DICO(0x21120340), DICO(0x24d4c000), DICO(0x29bafc00),
+ DICO(0x338c0740), DICO(0x36cfbc00), DICO(0x3f313900), DICO(0x47bf9c00),
+ DICO(0x4dd5d480), DICO(0x52848200), DICO(0x585add00), DICO(0x5cf7b480),
+ DICO(0x041a4bc8), DICO(0x05ca0920), DICO(0x0a3ae5b0), DICO(0x13fbb840),
+ DICO(0x1cdd3d00), DICO(0x209d5b80), DICO(0x27e78e80), DICO(0x2d1f4ec0),
+ DICO(0x32d84c80), DICO(0x3b8aa680), DICO(0x4289c180), DICO(0x46c33580),
+ DICO(0x4c23e580), DICO(0x51583180), DICO(0x56f52680), DICO(0x5c7a3d00),
+ DICO(0x03067404), DICO(0x05914038), DICO(0x10d33e60), DICO(0x17377180),
+ DICO(0x1d7f32a0), DICO(0x23848880), DICO(0x29d32200), DICO(0x2fb167c0),
+ DICO(0x356c8480), DICO(0x3b420280), DICO(0x4106d080), DICO(0x46d29280),
+ DICO(0x4c8a1200), DICO(0x52383300), DICO(0x57db8f80), DICO(0x5d61f200),
+ DICO(0x04baf368), DICO(0x06670a08), DICO(0x0e0cbd90), DICO(0x126299c0),
+ DICO(0x17ed7220), DICO(0x1e369900), DICO(0x22d7d300), DICO(0x2c0f9300),
+ DICO(0x2f5e7fc0), DICO(0x3b7c0d40), DICO(0x405aff80), DICO(0x44f2ef80),
+ DICO(0x4982b400), DICO(0x4e501380), DICO(0x539daa00), DICO(0x5c114b00),
+ DICO(0x0694c170), DICO(0x092d6890), DICO(0x0d0faee0), DICO(0x13800d00),
+ DICO(0x170f8d80), DICO(0x1bcd8240), DICO(0x246a8480), DICO(0x28bab640),
+ DICO(0x2f482ac0), DICO(0x36e736c0), DICO(0x3aaa68c0), DICO(0x3fc43500),
+ DICO(0x46e16000), DICO(0x4b3fbc00), DICO(0x4ff68e80), DICO(0x5aabf600),
+ DICO(0x05e849a0), DICO(0x0b485a80), DICO(0x14be52c0), DICO(0x1a079380),
+ DICO(0x1e8b1ce0), DICO(0x22fbca00), DICO(0x28c36a40), DICO(0x2e3b2a00),
+ DICO(0x34360b80), DICO(0x3a24cf00), DICO(0x3fff6200), DICO(0x45a6bf00),
+ DICO(0x4baf7800), DICO(0x51720e80), DICO(0x57560c80), DICO(0x5ce57e00),
+ DICO(0x0751da38), DICO(0x0f0949f0), DICO(0x18141860), DICO(0x1dfcb2c0),
+ DICO(0x24adbf00), DICO(0x296af240), DICO(0x2dbe60c0), DICO(0x3179ae40),
+ DICO(0x35ec4400), DICO(0x3ab76400), DICO(0x4034f400), DICO(0x45cfc700),
+ DICO(0x4bea6b00), DICO(0x516f5f00), DICO(0x57655300), DICO(0x5cfc0e00),
+ DICO(0x069900d0), DICO(0x0d379520), DICO(0x175d0560), DICO(0x1c4d92c0),
+ DICO(0x21407680), DICO(0x250d0340), DICO(0x29804940), DICO(0x2dfb9ac0),
+ DICO(0x337a1f80), DICO(0x39105fc0), DICO(0x3efd0380), DICO(0x44bce380),
+ DICO(0x4b07cc80), DICO(0x50ad7d00), DICO(0x56ddce80), DICO(0x5cb9a000),
+ DICO(0x069c6948), DICO(0x0a56ea10), DICO(0x0f7cca20), DICO(0x12d18680),
+ DICO(0x17036d00), DICO(0x1f4c1e80), DICO(0x262e5540), DICO(0x2b951e40),
+ DICO(0x3468ad40), DICO(0x3a2b2100), DICO(0x3f02f0c0), DICO(0x4383e400),
+ DICO(0x48374180), DICO(0x4d8eec80), DICO(0x54d74800), DICO(0x5c309600),
+ DICO(0x05a50158), DICO(0x0797e350), DICO(0x0cf1f230), DICO(0x14f3fb20),
+ DICO(0x17676400), DICO(0x20636780), DICO(0x2617ef80), DICO(0x29cbf700),
+ DICO(0x32ed57c0), DICO(0x374c3080), DICO(0x3b348e40), DICO(0x3fde0180),
+ DICO(0x44d38c00), DICO(0x4a8c6100), DICO(0x55f0e400), DICO(0x5dfed100),
+ DICO(0x04b74228), DICO(0x0623d3e0), DICO(0x0ab4c670), DICO(0x1bde7fa0),
+ DICO(0x1fcb6ac0), DICO(0x2344a540), DICO(0x275f7c40), DICO(0x2b7a8300),
+ DICO(0x31407440), DICO(0x35237700), DICO(0x38798540), DICO(0x3d0af340),
+ DICO(0x4224c980), DICO(0x49a17900), DICO(0x57702880), DICO(0x5dba4c00),
+ DICO(0x03c83c84), DICO(0x05cc52d8), DICO(0x0b644c10), DICO(0x129ab9a0),
+ DICO(0x1cee46c0), DICO(0x2152b080), DICO(0x247b1c00), DICO(0x27697180),
+ DICO(0x304f7500), DICO(0x3895d880), DICO(0x3c3a1740), DICO(0x413ace80),
+ DICO(0x462b0100), DICO(0x4ab07e00), DICO(0x50967580), DICO(0x5ba5e700),
+ DICO(0x06bcfda8), DICO(0x08c8b920), DICO(0x0de21530), DICO(0x1028d320),
+ DICO(0x168cfe00), DICO(0x20f78a40), DICO(0x248493c0), DICO(0x2c34bf80),
+ DICO(0x2ff88540), DICO(0x32d28c40), DICO(0x36d99640), DICO(0x4438e500),
+ DICO(0x4bacdb00), DICO(0x50343700), DICO(0x56b79080), DICO(0x5b694d00),
+ DICO(0x069109a0), DICO(0x0a73bc50), DICO(0x0e3c8330), DICO(0x13082620),
+ DICO(0x1c3a3760), DICO(0x200b5e80), DICO(0x256a4880), DICO(0x2b256ac0),
+ DICO(0x2f34afc0), DICO(0x35580200), DICO(0x3e0bd9c0), DICO(0x43d92900),
+ DICO(0x494e6e00), DICO(0x4f1a2780), DICO(0x5532a980), DICO(0x5a835a80),
+ DICO(0x04053450), DICO(0x05cb8fe0), DICO(0x097387b0), DICO(0x1121af00),
+ DICO(0x1abf62c0), DICO(0x1e39bbe0), DICO(0x243de300), DICO(0x2b440ec0),
+ DICO(0x2f2c1480), DICO(0x34697d80), DICO(0x405f8600), DICO(0x440b6f80),
+ DICO(0x47373100), DICO(0x4c764f80), DICO(0x55293780), DICO(0x5c59a780),
+ DICO(0x03c5b4a4), DICO(0x056fb380), DICO(0x09b8f910), DICO(0x13833fa0),
+ DICO(0x185eed60), DICO(0x1ce33d40), DICO(0x242e4100), DICO(0x282e5b80),
+ DICO(0x2cfe4d40), DICO(0x38a06d80), DICO(0x3e002240), DICO(0x423be400),
+ DICO(0x49a5e600), DICO(0x5092b780), DICO(0x57023d00), DICO(0x5d5f7c80),
+ DICO(0x077ada38), DICO(0x09d5ac70), DICO(0x0e58be30), DICO(0x14fb2040),
+ DICO(0x17fc9dc0), DICO(0x1c2c31e0), DICO(0x26cf1b00), DICO(0x2a91ba80),
+ DICO(0x2ed880c0), DICO(0x38cbf900), DICO(0x3d2fc700), DICO(0x405d2280),
+ DICO(0x439c1d00), DICO(0x4dd16800), DICO(0x5672c080), DICO(0x5d313880),
+ DICO(0x04272090), DICO(0x05d76e18), DICO(0x0b4d8080), DICO(0x12883f60),
+ DICO(0x17952180), DICO(0x2040d480), DICO(0x23e8cc00), DICO(0x2819c200),
+ DICO(0x2b871040), DICO(0x357c8f00), DICO(0x3caf9ac0), DICO(0x40a39380),
+ DICO(0x45bc2780), DICO(0x4e4aa300), DICO(0x568c2280), DICO(0x5cadc400),
+ DICO(0x0375b03c), DICO(0x056f0b40), DICO(0x0b0dc930), DICO(0x128c51e0),
+ DICO(0x189fa360), DICO(0x1c8197e0), DICO(0x1eed52a0), DICO(0x23ed4500),
+ DICO(0x2e5eb840), DICO(0x36415a40), DICO(0x3dcf6340), DICO(0x43126e80),
+ DICO(0x4aeb7f80), DICO(0x501e1280), DICO(0x5852b100), DICO(0x5d040d80),
+ DICO(0x06351b88), DICO(0x07f90ac0), DICO(0x0bab4ea0), DICO(0x18d04b40),
+ DICO(0x1f1e1480), DICO(0x219abcc0), DICO(0x261c31c0), DICO(0x2a611a00),
+ DICO(0x2e725480), DICO(0x36b511c0), DICO(0x3d362f00), DICO(0x40be6d80),
+ DICO(0x456dc400), DICO(0x4b74c580), DICO(0x55c82680), DICO(0x5e318480),
+ DICO(0x046212d8), DICO(0x05ca95e8), DICO(0x0a02d910), DICO(0x1ae58f40),
+ DICO(0x1e73ec20), DICO(0x2197d640), DICO(0x2581df00), DICO(0x29c83780),
+ DICO(0x31294300), DICO(0x356f8a40), DICO(0x3b97d240), DICO(0x4505cc80),
+ DICO(0x4b497600), DICO(0x504e8780), DICO(0x55644480), DICO(0x5bdedf80),
+ DICO(0x0514f798), DICO(0x06bd0d00), DICO(0x0fc31550), DICO(0x13dfb1a0),
+ DICO(0x17dda900), DICO(0x204a8c40), DICO(0x23095300), DICO(0x2d0da040),
+ DICO(0x31b2a540), DICO(0x34620180), DICO(0x3ab3e000), DICO(0x448ac300),
+ DICO(0x4be6a600), DICO(0x5114e280), DICO(0x562b0780), DICO(0x5b833c00),
+ DICO(0x070f5ef0), DICO(0x0919c2b0), DICO(0x0e778740), DICO(0x154db320),
+ DICO(0x177cfbe0), DICO(0x1ea66040), DICO(0x23666680), DICO(0x2839c400),
+ DICO(0x30cc4ec0), DICO(0x3444a280), DICO(0x38c93580), DICO(0x42a80e00),
+ DICO(0x4c433880), DICO(0x519e4f80), DICO(0x56ff8f80), DICO(0x5be18200),
+ DICO(0x066c5968), DICO(0x08a589f0), DICO(0x0ca4d7a0), DICO(0x0ffdefb0),
+ DICO(0x12943f40), DICO(0x1be84ee0), DICO(0x21276540), DICO(0x265a9540),
+ DICO(0x2e0de140), DICO(0x325148c0), DICO(0x3bd05d40), DICO(0x41e81780),
+ DICO(0x4b7cf400), DICO(0x53289400), DICO(0x597d9000), DICO(0x5e458e00),
+ DICO(0x04da3e40), DICO(0x06e8e1b0), DICO(0x0b9b1a20), DICO(0x11264bc0),
+ DICO(0x14f3d7e0), DICO(0x1cf9c100), DICO(0x23568f40), DICO(0x292b5380),
+ DICO(0x33878d40), DICO(0x38dac840), DICO(0x3d578200), DICO(0x4223a880),
+ DICO(0x473fb700), DICO(0x4c765500), DICO(0x546c6480), DICO(0x5c76d280),
+ DICO(0x05e63bb0), DICO(0x07a1a428), DICO(0x0ec4ff10), DICO(0x1348a100),
+ DICO(0x16204f40), DICO(0x1a0a6440), DICO(0x1e33f6c0), DICO(0x2ae8ccc0),
+ DICO(0x2ed5e6c0), DICO(0x32427600), DICO(0x379d9980), DICO(0x3c0f4080),
+ DICO(0x441ea680), DICO(0x4e592b00), DICO(0x56e27700), DICO(0x5da2e280),
+ DICO(0x0474de80), DICO(0x06167248), DICO(0x0ce650e0), DICO(0x135b4aa0),
+ DICO(0x16cea2a0), DICO(0x1d138ac0), DICO(0x220a84c0), DICO(0x275ca380),
+ DICO(0x2c300340), DICO(0x333b3d80), DICO(0x37a35080), DICO(0x40b83880),
+ DICO(0x494c4780), DICO(0x4ff71c80), DICO(0x56db2d80), DICO(0x5d0aac00),
+ DICO(0x0746cd00), DICO(0x09deff10), DICO(0x0e4a3560), DICO(0x14f005e0),
+ DICO(0x186a4de0), DICO(0x1cd0b240), DICO(0x22287bc0), DICO(0x26ced500),
+ DICO(0x2d57c440), DICO(0x31d943c0), DICO(0x364b0f80), DICO(0x3c85a040),
+ DICO(0x4240ca00), DICO(0x4a648080), DICO(0x54d12200), DICO(0x5d1a1c00),
+ DICO(0x05522eb0), DICO(0x0704efb8), DICO(0x0c66cd50), DICO(0x15aefca0),
+ DICO(0x184f7b00), DICO(0x1e4b26a0), DICO(0x22667640), DICO(0x284e4e00),
+ DICO(0x2d8be3c0), DICO(0x31376f00), DICO(0x39cd9800), DICO(0x3e46b740),
+ DICO(0x43af0380), DICO(0x4e1dec00), DICO(0x562ac500), DICO(0x5d45f580),
+ DICO(0x062f5708), DICO(0x08d079a0), DICO(0x0c1b4920), DICO(0x13f147c0),
+ DICO(0x1ae77c80), DICO(0x1d200ea0), DICO(0x236e4740), DICO(0x2b98d000),
+ DICO(0x2eefc600), DICO(0x34c674c0), DICO(0x3d36f540), DICO(0x411d8c00),
+ DICO(0x45c50300), DICO(0x4d207480), DICO(0x55603100), DICO(0x5c442d80),
+ DICO(0x0510bcd0), DICO(0x06ec00a0), DICO(0x0b639550), DICO(0x15daa2c0),
+ DICO(0x18c0ba60), DICO(0x1e0f7d60), DICO(0x24b05c80), DICO(0x280638c0),
+ DICO(0x314a6580), DICO(0x35e4b2c0), DICO(0x3aef2bc0), DICO(0x4158c280),
+ DICO(0x4d245100), DICO(0x53c69a80), DICO(0x597f1000), DICO(0x5dcb0080),
+ DICO(0x042cb748), DICO(0x05d710b0), DICO(0x0afe6130), DICO(0x1256cdc0),
+ DICO(0x15b8cd00), DICO(0x1dc72d20), DICO(0x2205fc00), DICO(0x2a3d0d00),
+ DICO(0x2f3ba600), DICO(0x33b3d840), DICO(0x3b5a5440), DICO(0x416c9d00),
+ DICO(0x497cdd80), DICO(0x50405e00), DICO(0x570ca980), DICO(0x5d3aa180),
+ DICO(0x0443b7b8), DICO(0x063d8588), DICO(0x0c76ef20), DICO(0x12709b40),
+ DICO(0x1649f0a0), DICO(0x20c522c0), DICO(0x24cde400), DICO(0x2ba78280),
+ DICO(0x3104c340), DICO(0x360b1740), DICO(0x3cd6a6c0), DICO(0x42573800),
+ DICO(0x48b18480), DICO(0x4fca1e00), DICO(0x5700c100), DICO(0x5cf14480),
+ DICO(0x05123628), DICO(0x06bf10b0), DICO(0x0bde7570), DICO(0x175b7ee0),
+ DICO(0x1a134460), DICO(0x20fa4100), DICO(0x25eda440), DICO(0x29c3b540),
+ DICO(0x318a1b40), DICO(0x35e0d500), DICO(0x3a147f00), DICO(0x3f08e980),
+ DICO(0x445d7580), DICO(0x4ec48c80), DICO(0x588bce80), DICO(0x5dfae300),
+ DICO(0x04c9e750), DICO(0x065224f8), DICO(0x0c6f1e30), DICO(0x1a2ffca0),
+ DICO(0x1cac6140), DICO(0x21c2a640), DICO(0x25fb8ac0), DICO(0x2ab90f00),
+ DICO(0x33189200), DICO(0x38088ac0), DICO(0x3bb7de40), DICO(0x40180800),
+ DICO(0x4453c300), DICO(0x4cdba880), DICO(0x54902680), DICO(0x5bb21700),
+ DICO(0x06958570), DICO(0x097f32b0), DICO(0x0cb418b0), DICO(0x141b6900),
+ DICO(0x1c8cfb00), DICO(0x1fab7920), DICO(0x2477c800), DICO(0x2aabed40),
+ DICO(0x2eb1a080), DICO(0x339f67c0), DICO(0x3abcc240), DICO(0x3f661b00),
+ DICO(0x45663280), DICO(0x4c680800), DICO(0x51703000), DICO(0x58a0e000),
+ DICO(0x069f6c88), DICO(0x095e1490), DICO(0x0cf442b0), DICO(0x10ea8d60),
+ DICO(0x1377b580), DICO(0x195ed480), DICO(0x26542b00), DICO(0x2c9ea700),
+ DICO(0x318d8ac0), DICO(0x364e5a40), DICO(0x3a0db000), DICO(0x3e1087c0),
+ DICO(0x450ca380), DICO(0x4c781d00), DICO(0x53cf7a00), DICO(0x5c7d1280),
+ DICO(0x06e51d98), DICO(0x09eb8d30), DICO(0x0e6683d0), DICO(0x129418a0),
+ DICO(0x1562fc80), DICO(0x1f708660), DICO(0x253f1000), DICO(0x293a16c0),
+ DICO(0x2e7c1d80), DICO(0x316e75c0), DICO(0x35a7fbc0), DICO(0x3bfbf780),
+ DICO(0x416a9200), DICO(0x4be36400), DICO(0x56dc7a80), DICO(0x5d64ea80),
+ DICO(0x0574d0c8), DICO(0x0748efd0), DICO(0x0b510860), DICO(0x0e219e00),
+ DICO(0x1299cc00), DICO(0x1ef706a0), DICO(0x22ca38c0), DICO(0x28820a00),
+ DICO(0x2cc635c0), DICO(0x31ef4740), DICO(0x3a5e89c0), DICO(0x42acaa00),
+ DICO(0x4b2bf500), DICO(0x515e0980), DICO(0x57949400), DICO(0x5d002500),
+ DICO(0x07c715d0), DICO(0x0b3fa110), DICO(0x0e745370), DICO(0x11e93560),
+ DICO(0x14bad680), DICO(0x189a0400), DICO(0x240b1240), DICO(0x2a6b3580),
+ DICO(0x2e5e1380), DICO(0x352072c0), DICO(0x3a5037c0), DICO(0x3e3726c0),
+ DICO(0x4725ed80), DICO(0x4f885900), DICO(0x54c8d580), DICO(0x5b261680),
+ DICO(0x075f02a8), DICO(0x0a214900), DICO(0x0e189de0), DICO(0x1376d5a0),
+ DICO(0x163d5c80), DICO(0x1a94b3e0), DICO(0x21376980), DICO(0x259c3140),
+ DICO(0x2e663bc0), DICO(0x337884c0), DICO(0x3a035c00), DICO(0x40b32c00),
+ DICO(0x4b21de00), DICO(0x53298f00), DICO(0x58788080), DICO(0x5cfa7c00),
+ DICO(0x05658988), DICO(0x0797f470), DICO(0x0d250810), DICO(0x102fc2a0),
+ DICO(0x13738fe0), DICO(0x1740bbc0), DICO(0x2491b380), DICO(0x28bc5800),
+ DICO(0x2c75a940), DICO(0x325cb500), DICO(0x37944740), DICO(0x405f2d80),
+ DICO(0x48eb8f00), DICO(0x50676f80), DICO(0x56f70380), DICO(0x5d62c000),
+ DICO(0x0531b540), DICO(0x06ae64c0), DICO(0x0cf7ad30), DICO(0x11c83000),
+ DICO(0x14edc980), DICO(0x18d436c0), DICO(0x1e184080), DICO(0x2603bb80),
+ DICO(0x2a2f2f80), DICO(0x33bdbe00), DICO(0x3a1066c0), DICO(0x42b9ff00),
+ DICO(0x4a617580), DICO(0x51619480), DICO(0x57ccd500), DICO(0x5d4d1600),
+ DICO(0x03e40bac), DICO(0x05f53158), DICO(0x0e76d3b0), DICO(0x17c157a0),
+ DICO(0x1ccb5bc0), DICO(0x250129c0), DICO(0x2b7d9d00), DICO(0x33224d80),
+ DICO(0x3966f600), DICO(0x3f399480), DICO(0x4449fc80), DICO(0x49401b80),
+ DICO(0x4e2ab580), DICO(0x53117000), DICO(0x5848e080), DICO(0x5d66a280),
+ DICO(0x041d4f60), DICO(0x070e8080), DICO(0x1390ec40), DICO(0x177c42c0),
+ DICO(0x1beb1400), DICO(0x208b0580), DICO(0x264cbb40), DICO(0x2bd30940),
+ DICO(0x30b30880), DICO(0x36978e80), DICO(0x3cb2a140), DICO(0x43f6b080),
+ DICO(0x4a881000), DICO(0x505ca780), DICO(0x569a5d80), DICO(0x5cae3580),
+ DICO(0x03f3c760), DICO(0x05564e08), DICO(0x09e310d0), DICO(0x1b9b3d00),
+ DICO(0x20909ac0), DICO(0x2382eec0), DICO(0x278c6700), DICO(0x2b34d500),
+ DICO(0x30fa2ac0), DICO(0x34d27d40), DICO(0x38e334c0), DICO(0x3d732440),
+ DICO(0x46d07800), DICO(0x51f4d400), DICO(0x57744f80), DICO(0x5d56bb80),
+ DICO(0x03abfdd8), DICO(0x0512b140), DICO(0x135f7500), DICO(0x19fcc4c0),
+ DICO(0x1d0b1b80), DICO(0x21eca540), DICO(0x258f8700), DICO(0x29e292c0),
+ DICO(0x2c51fe80), DICO(0x31e2a180), DICO(0x3c638640), DICO(0x44873a00),
+ DICO(0x4bb7e800), DICO(0x5078f700), DICO(0x57fc9b80), DICO(0x5def1c00),
+ DICO(0x04721ef0), DICO(0x06688158), DICO(0x0f65a5d0), DICO(0x14499840),
+ DICO(0x1bf5b8c0), DICO(0x1f33b700), DICO(0x264b6900), DICO(0x2c3e6780),
+ DICO(0x2ec8d440), DICO(0x323885c0), DICO(0x37143300), DICO(0x3bafa800),
+ DICO(0x49030480), DICO(0x54c16b00), DICO(0x58ec4b00), DICO(0x5d713d00),
+ DICO(0x03d114e4), DICO(0x067e5b40), DICO(0x10393420), DICO(0x14961300),
+ DICO(0x1a59cfa0), DICO(0x20854240), DICO(0x26b3f300), DICO(0x2e3e2840),
+ DICO(0x323bd300), DICO(0x37c49280), DICO(0x3d79e500), DICO(0x4352d880),
+ DICO(0x49e17980), DICO(0x4fc72f80), DICO(0x55c0c680), DICO(0x5c53c700),
+ DICO(0x053f5de8), DICO(0x075162b8), DICO(0x0fae8050), DICO(0x13ec0ee0),
+ DICO(0x17f92440), DICO(0x1f054440), DICO(0x24b15d40), DICO(0x2add4480),
+ DICO(0x2e306300), DICO(0x35420680), DICO(0x3c6b6e00), DICO(0x42fc0380),
+ DICO(0x4732e380), DICO(0x4ceb2200), DICO(0x522efe00), DICO(0x5aa12680),
+ DICO(0x06111728), DICO(0x08183c80), DICO(0x0d026650), DICO(0x14b41940),
+ DICO(0x17e37320), DICO(0x1c40b160), DICO(0x219c5400), DICO(0x26d88840),
+ DICO(0x2bfdfe00), DICO(0x315a2800), DICO(0x38cd7140), DICO(0x3de22740),
+ DICO(0x48ff1300), DICO(0x53ef4180), DICO(0x5a479380), DICO(0x5ea1e380),
+ DICO(0x07ea0fa8), DICO(0x0a844ef0), DICO(0x0e1023c0), DICO(0x1208d980),
+ DICO(0x15891360), DICO(0x1bebc380), DICO(0x2087da40), DICO(0x257ac940),
+ DICO(0x2caefa00), DICO(0x300defc0), DICO(0x376aa000), DICO(0x438aad80),
+ DICO(0x49f00500), DICO(0x4e023780), DICO(0x524e5800), DICO(0x5abcb980),
+ DICO(0x079cfc88), DICO(0x0a367240), DICO(0x0f224330), DICO(0x15b51540),
+ DICO(0x19065420), DICO(0x1ddbe0a0), DICO(0x23a99d80), DICO(0x28c2d340),
+ DICO(0x2f627e40), DICO(0x3487e080), DICO(0x38b76bc0), DICO(0x3d135580),
+ DICO(0x43799a80), DICO(0x489a5000), DICO(0x4ece6280), DICO(0x5a82f500),
+ DICO(0x06c37e40), DICO(0x093f0540), DICO(0x0e0d0c30), DICO(0x17487860),
+ DICO(0x1bf78020), DICO(0x20318000), DICO(0x260b8300), DICO(0x2c615980),
+ DICO(0x30c88440), DICO(0x36433b40), DICO(0x3bdb8c40), DICO(0x40050c80),
+ DICO(0x44062f80), DICO(0x48a8d480), DICO(0x4dd64d00), DICO(0x55abd380),
+ DICO(0x05e9e828), DICO(0x07f24330), DICO(0x0c8b4fe0), DICO(0x0ecd2820),
+ DICO(0x17f05c00), DICO(0x1fdb4560), DICO(0x24b4c940), DICO(0x2968d0c0),
+ DICO(0x2cbf3500), DICO(0x381eadc0), DICO(0x3d3baf40), DICO(0x42828080),
+ DICO(0x47f36300), DICO(0x4c8c6600), DICO(0x51d66f00), DICO(0x5a7e0300),
+ DICO(0x065c5cf8), DICO(0x08882540), DICO(0x0d887c70), DICO(0x112ac560),
+ DICO(0x150ccdc0), DICO(0x19e49c20), DICO(0x1eb65680), DICO(0x2a76e040),
+ DICO(0x2f65fc00), DICO(0x36d79cc0), DICO(0x3c85a900), DICO(0x408dc680),
+ DICO(0x44964700), DICO(0x4a98eb00), DICO(0x5528b500), DICO(0x5d660f80),
+ DICO(0x06b56230), DICO(0x08e340f0), DICO(0x0e1e4380), DICO(0x112d2d40),
+ DICO(0x158dfde0), DICO(0x227e6040), DICO(0x26bff7c0), DICO(0x2b73a100),
+ DICO(0x32199580), DICO(0x3585a240), DICO(0x398a5d40), DICO(0x3db8c6c0),
+ DICO(0x43905600), DICO(0x4945f800), DICO(0x4f310380), DICO(0x5a6d2400),
+ DICO(0x05cfc6f8), DICO(0x0832e650), DICO(0x0de82f80), DICO(0x1a1afe80),
+ DICO(0x1e9a1f80), DICO(0x221acd80), DICO(0x27fa00c0), DICO(0x2c4df980),
+ DICO(0x31e04bc0), DICO(0x38c9ed40), DICO(0x3db86080), DICO(0x428ec800),
+ DICO(0x48500500), DICO(0x4e1ca580), DICO(0x53d3f500), DICO(0x5aa6be00),
+ DICO(0x050cc4d0), DICO(0x070c2180), DICO(0x0c4ca980), DICO(0x0fce9f40),
+ DICO(0x14af4160), DICO(0x2206a780), DICO(0x25848e80), DICO(0x2c2b84c0),
+ DICO(0x35a39980), DICO(0x3914bd80), DICO(0x3caff580), DICO(0x3fcb0600),
+ DICO(0x4426b380), DICO(0x486c9700), DICO(0x4f730480), DICO(0x5afd3980),
+ DICO(0x05e40640), DICO(0x0830df50), DICO(0x0b9e83e0), DICO(0x158bacc0),
+ DICO(0x1d0692e0), DICO(0x2021e0c0), DICO(0x26572e00), DICO(0x2d58cc40),
+ DICO(0x30dd0f80), DICO(0x361d68c0), DICO(0x3e3086c0), DICO(0x42450800),
+ DICO(0x46c25800), DICO(0x4c45cf00), DICO(0x51dd4200), DICO(0x57326500),
+ DICO(0x04d32fa0), DICO(0x064ed2c0), DICO(0x0b07cd70), DICO(0x1c7f6da0),
+ DICO(0x213bc140), DICO(0x25051fc0), DICO(0x295cd1c0), DICO(0x2c9f4f80),
+ DICO(0x32271540), DICO(0x36a8ec80), DICO(0x3a8e6b40), DICO(0x3e137580),
+ DICO(0x42795480), DICO(0x4779b780), DICO(0x4f7d9600), DICO(0x5c09b000),
+ DICO(0x044b0748), DICO(0x05fee680), DICO(0x08f66960), DICO(0x11db5940),
+ DICO(0x219ede80), DICO(0x27fb96c0), DICO(0x2affc980), DICO(0x2eadc3c0),
+ DICO(0x32895700), DICO(0x37180d00), DICO(0x3d4bf880), DICO(0x41741980),
+ DICO(0x460d8280), DICO(0x4c34be80), DICO(0x54531e80), DICO(0x5c874000),
+ DICO(0x03e25dcc), DICO(0x069e8170), DICO(0x13b3d9c0), DICO(0x1a803260),
+ DICO(0x1ed3a4a0), DICO(0x23ea6380), DICO(0x2883b900), DICO(0x2e0ceac0),
+ DICO(0x3308e400), DICO(0x38796dc0), DICO(0x3e318e80), DICO(0x441da080),
+ DICO(0x4a892300), DICO(0x509b9f80), DICO(0x56caa380), DICO(0x5cc39e00),
+ DICO(0x05023038), DICO(0x06b6b4d8), DICO(0x0a449370), DICO(0x15b86ea0),
+ DICO(0x224a9200), DICO(0x272e6f40), DICO(0x2a617700), DICO(0x2e915d00),
+ DICO(0x3240ac40), DICO(0x37636300), DICO(0x3dd3ea80), DICO(0x420e1f80),
+ DICO(0x45bf0680), DICO(0x4a26d980), DICO(0x4f82a900), DICO(0x56576800),
+ DICO(0x03d630f4), DICO(0x082140a0), DICO(0x12644700), DICO(0x16b80cc0),
+ DICO(0x1ba90c40), DICO(0x21c38300), DICO(0x27dd1480), DICO(0x2e18ee00),
+ DICO(0x33fb72c0), DICO(0x39f9d980), DICO(0x40219300), DICO(0x4607fd00),
+ DICO(0x4c07e500), DICO(0x51ba8f00), DICO(0x57a24280), DICO(0x5d367700),
+ DICO(0x080a5880), DICO(0x0ef3f570), DICO(0x141fd6c0), DICO(0x17c163a0),
+ DICO(0x1c2840a0), DICO(0x2111fe00), DICO(0x27376bc0), DICO(0x2cc7edc0),
+ DICO(0x329b0100), DICO(0x386d3e40), DICO(0x3ec1bdc0), DICO(0x453f6200),
+ DICO(0x4bf16080), DICO(0x51bded00), DICO(0x57ba6800), DICO(0x5d2ffd80),
+ DICO(0x08643590), DICO(0x0e911f00), DICO(0x15911380), DICO(0x1ab5e180),
+ DICO(0x207ff600), DICO(0x26399b00), DICO(0x2cadae80), DICO(0x3276ca40),
+ DICO(0x389d9cc0), DICO(0x3eb22180), DICO(0x44570700), DICO(0x49d15800),
+ DICO(0x4f591300), DICO(0x54566a80), DICO(0x5967db00), DICO(0x5e307780),
+ DICO(0x07120fa8), DICO(0x0c791c60), DICO(0x112d3b60), DICO(0x149452a0),
+ DICO(0x19d2c100), DICO(0x202f1540), DICO(0x269c10c0), DICO(0x2be22880),
+ DICO(0x312a07c0), DICO(0x36984fc0), DICO(0x3c7ac3c0), DICO(0x435b5000),
+ DICO(0x4aa60280), DICO(0x50f50c00), DICO(0x5719f700), DICO(0x5cb98680),
+ DICO(0x05517c88), DICO(0x06ba0a70), DICO(0x0da167c0), DICO(0x19918440),
+ DICO(0x1bb37220), DICO(0x20681080), DICO(0x23dc6740), DICO(0x2a1403c0),
+ DICO(0x31a71580), DICO(0x34ff0600), DICO(0x395b7cc0), DICO(0x42019200),
+ DICO(0x4c818d00), DICO(0x513ff400), DICO(0x5731ce00), DICO(0x5c5f1180),
+ DICO(0x04f74ec0), DICO(0x067b4628), DICO(0x0dc4c9c0), DICO(0x19e9fa40),
+ DICO(0x1cf00a00), DICO(0x21602a80), DICO(0x25334a80), DICO(0x29b3a800),
+ DICO(0x2f9b3600), DICO(0x338c0540), DICO(0x370c3cc0), DICO(0x3abbc3c0),
+ DICO(0x4053a000), DICO(0x4f14d980), DICO(0x57e0b600), DICO(0x5d95e780),
+ DICO(0x05d844b8), DICO(0x07a05608), DICO(0x0b7837f0), DICO(0x161fb460),
+ DICO(0x19c31d00), DICO(0x1cf36280), DICO(0x20ccc200), DICO(0x24ae3980),
+ DICO(0x2e2b5800), DICO(0x3316af80), DICO(0x37432b00), DICO(0x4050b280),
+ DICO(0x4605be00), DICO(0x4cc78900), DICO(0x556d2080), DICO(0x5c578300),
+ DICO(0x0551b768), DICO(0x07024f60), DICO(0x1045fde0), DICO(0x16480120),
+ DICO(0x19974420), DICO(0x1ec2b280), DICO(0x228b30c0), DICO(0x295e0ec0),
+ DICO(0x2d8775c0), DICO(0x30ef1440), DICO(0x35978080), DICO(0x3a2ab480),
+ DICO(0x40229780), DICO(0x4da40980), DICO(0x5718e480), DICO(0x5d68d400),
+ DICO(0x03f903e4), DICO(0x06731580), DICO(0x0ecf4850), DICO(0x12e57920),
+ DICO(0x1a69ece0), DICO(0x1fe32700), DICO(0x2585b9c0), DICO(0x2aa006c0),
+ DICO(0x2f20ea80), DICO(0x37298bc0), DICO(0x3df2a000), DICO(0x44a6c600),
+ DICO(0x4b10de00), DICO(0x510fb880), DICO(0x5749c280), DICO(0x5d0b9480),
+ DICO(0x03c418fc), DICO(0x056c4cd0), DICO(0x0d0cf070), DICO(0x1907a2c0),
+ DICO(0x1be9bc00), DICO(0x21599480), DICO(0x25700e40), DICO(0x2c83e280),
+ DICO(0x329fa7c0), DICO(0x389f4cc0), DICO(0x3ef60900), DICO(0x44c19300),
+ DICO(0x4af56d00), DICO(0x512eec80), DICO(0x5772ad00), DICO(0x5d37f380),
+ DICO(0x04d57920), DICO(0x0716b5e0), DICO(0x0cb3bcc0), DICO(0x1197f740),
+ DICO(0x163e5fc0), DICO(0x2194e400), DICO(0x274bb600), DICO(0x2f5d7080),
+ DICO(0x361ee340), DICO(0x3b3b22c0), DICO(0x3f800400), DICO(0x4327ef80),
+ DICO(0x48b5d200), DICO(0x5116d300), DICO(0x59652e80), DICO(0x5e444d00),
+ DICO(0x0755b6b0), DICO(0x0b68c2c0), DICO(0x0f3441d0), DICO(0x124a01a0),
+ DICO(0x18910600), DICO(0x20911b80), DICO(0x281f7100), DICO(0x2e4dd640),
+ DICO(0x335bd8c0), DICO(0x37f14a80), DICO(0x3cab7b80), DICO(0x43be3180),
+ DICO(0x4beee100), DICO(0x52292180), DICO(0x57efea00), DICO(0x5d177300),
+ DICO(0x071a7748), DICO(0x0c6cf1b0), DICO(0x10db1500), DICO(0x143bca00),
+ DICO(0x1b86a900), DICO(0x22ed1d80), DICO(0x2a1f61c0), DICO(0x305f1400),
+ DICO(0x3645f580), DICO(0x3be45b00), DICO(0x4166ea80), DICO(0x46c3f200),
+ DICO(0x4c740400), DICO(0x51e30d00), DICO(0x57a37000), DICO(0x5cfc4980),
+ DICO(0x08cdd5b0), DICO(0x0daf9840), DICO(0x11cc02a0), DICO(0x1588ed40),
+ DICO(0x1cfef5e0), DICO(0x239f12c0), DICO(0x296d3b40), DICO(0x2e61c240),
+ DICO(0x333dc800), DICO(0x385d0000), DICO(0x3e1e5180), DICO(0x44196e00),
+ DICO(0x4a833000), DICO(0x503d7b80), DICO(0x56556680), DICO(0x5c410c00),
+ DICO(0x07372408), DICO(0x0d5c41f0), DICO(0x155dc140), DICO(0x1a9a3cc0),
+ DICO(0x21740980), DICO(0x27139f40), DICO(0x2c977040), DICO(0x30cfe5c0),
+ DICO(0x35381240), DICO(0x39b83140), DICO(0x3ef3fe80), DICO(0x44547200),
+ DICO(0x4a812800), DICO(0x5046c200), DICO(0x56957d00), DICO(0x5c85cd80),
+ DICO(0x06da6990), DICO(0x0bc41250), DICO(0x13d54800), DICO(0x1979c220),
+ DICO(0x1fad2f00), DICO(0x24bbe0c0), DICO(0x29c08f00), DICO(0x2e34b940),
+ DICO(0x32c89e40), DICO(0x376a2040), DICO(0x3cd81080), DICO(0x4267bd00),
+ DICO(0x48e8e800), DICO(0x4f150280), DICO(0x55cb1980), DICO(0x5c428b80),
+ DICO(0x087d45d0), DICO(0x0cf1ef20), DICO(0x135cba20), DICO(0x16fc7420),
+ DICO(0x1b2772e0), DICO(0x1fd4fe60), DICO(0x260a0b80), DICO(0x2bc54c00),
+ DICO(0x31694cc0), DICO(0x36d08080), DICO(0x3c245c80), DICO(0x41170900),
+ DICO(0x47b18600), DICO(0x4e706180), DICO(0x558d2000), DICO(0x5c428d00),
+ DICO(0x081e6490), DICO(0x0d16a7d0), DICO(0x124ccd20), DICO(0x154c20c0),
+ DICO(0x1945d8c0), DICO(0x1ee0b700), DICO(0x26a01f00), DICO(0x2d554e40),
+ DICO(0x3432eb80), DICO(0x3a605500), DICO(0x401d8980), DICO(0x45737680),
+ DICO(0x4b03cb00), DICO(0x50666780), DICO(0x56a0cd00), DICO(0x5cb46480),
+ DICO(0x06c58278), DICO(0x091b10b0), DICO(0x0e0e74f0), DICO(0x11faf980),
+ DICO(0x14a48600), DICO(0x1e6f7500), DICO(0x27f77100), DICO(0x2ab49940),
+ DICO(0x32a1f680), DICO(0x38cb2a80), DICO(0x3c3ff140), DICO(0x3f681cc0),
+ DICO(0x44310700), DICO(0x4fa21700), DICO(0x586c6180), DICO(0x5df74200),
+ DICO(0x06a3e478), DICO(0x09714400), DICO(0x0d90b7a0), DICO(0x12df2720),
+ DICO(0x1618f320), DICO(0x1ac52840), DICO(0x27612900), DICO(0x2e438e00),
+ DICO(0x322b6ac0), DICO(0x38022940), DICO(0x3d2a5180), DICO(0x40d76b80),
+ DICO(0x46671500), DICO(0x4c5bd480), DICO(0x517a2500), DICO(0x57775b00),
+ DICO(0x056c2230), DICO(0x07b8f9d8), DICO(0x0bc6e060), DICO(0x16ac2c80),
+ DICO(0x1a92fc00), DICO(0x1e15f000), DICO(0x28b73200), DICO(0x2cd9e5c0),
+ DICO(0x3196ecc0), DICO(0x3abae340), DICO(0x4040c580), DICO(0x44c18d80),
+ DICO(0x4c086800), DICO(0x50b78500), DICO(0x54e42600), DICO(0x5a549a80),
+ DICO(0x04f9fa10), DICO(0x07419358), DICO(0x0c3e15f0), DICO(0x174c1800),
+ DICO(0x1ab1fe60), DICO(0x23a12680), DICO(0x27955780), DICO(0x2d14b1c0),
+ DICO(0x35cefb00), DICO(0x39576700), DICO(0x3e82b780), DICO(0x42b6a680),
+ DICO(0x476d1880), DICO(0x4b6cdd00), DICO(0x52758680), DICO(0x5b69e500),
+ DICO(0x060b7ab0), DICO(0x081c05c0), DICO(0x0b540300), DICO(0x0f564270),
+ DICO(0x1210aa80), DICO(0x1771e060), DICO(0x25d73280), DICO(0x2e49e380),
+ DICO(0x319c1100), DICO(0x3771e700), DICO(0x3c532f40), DICO(0x40c9a900),
+ DICO(0x48cbf580), DICO(0x4f819980), DICO(0x566f9400), DICO(0x5cfdd980),
+ DICO(0x04efb7b8), DICO(0x0b8a3710), DICO(0x124fd520), DICO(0x1846dde0),
+ DICO(0x1e77a9e0), DICO(0x243ea800), DICO(0x2a4e3280), DICO(0x2ff532c0),
+ DICO(0x35d27680), DICO(0x3b8cdb00), DICO(0x41463000), DICO(0x4706c700),
+ DICO(0x4ca42d80), DICO(0x525d9200), DICO(0x57dabb80), DICO(0x5d59a800),
+ DICO(0x03620dec), DICO(0x095872e0), DICO(0x108d4920), DICO(0x16e9ea00),
+ DICO(0x1d60b2e0), DICO(0x235e9d00), DICO(0x29893b80), DICO(0x2f59a3c0),
+ DICO(0x3556b880), DICO(0x3b10bdc0), DICO(0x40f49500), DICO(0x469cc480),
+ DICO(0x4c762d00), DICO(0x51f16980), DICO(0x578c6d00), DICO(0x5c9b5a00),
+ DICO(0x05dd9bc0), DICO(0x079c5b20), DICO(0x0d319af0), DICO(0x18997040),
+ DICO(0x1c0a1980), DICO(0x20e926c0), DICO(0x25ca1640), DICO(0x29879340),
+ DICO(0x30b27040), DICO(0x36077340), DICO(0x39ac3d00), DICO(0x3d686cc0),
+ DICO(0x428e5f00), DICO(0x47c1bf80), DICO(0x4e720800), DICO(0x5b419880),
+ DICO(0x07694258), DICO(0x0b50db90), DICO(0x0f384950), DICO(0x140dac40),
+ DICO(0x17c50d80), DICO(0x1b49b300), DICO(0x24746200), DICO(0x2ce92fc0),
+ DICO(0x309fdac0), DICO(0x35c02a00), DICO(0x3aa3df00), DICO(0x3e1edb00),
+ DICO(0x431ad280), DICO(0x4b57f500), DICO(0x51463980), DICO(0x586b5200),
+ DICO(0x06401dd0), DICO(0x08d3d9b0), DICO(0x0ca0f510), DICO(0x10ed1920),
+ DICO(0x1451c2e0), DICO(0x2082f640), DICO(0x2872c0c0), DICO(0x2ca9da00),
+ DICO(0x3219cd00), DICO(0x35977300), DICO(0x3a8ba1c0), DICO(0x43d5f280),
+ DICO(0x49a51f00), DICO(0x4de9b400), DICO(0x5362ef80), DICO(0x59387300),
+ DICO(0x0589c430), DICO(0x07809918), DICO(0x0d086f80), DICO(0x10371c20),
+ DICO(0x151842c0), DICO(0x1bfcb1c0), DICO(0x22441040), DICO(0x2722b5c0),
+ DICO(0x2b603fc0), DICO(0x314465c0), DICO(0x40308b00), DICO(0x47d5a200),
+ DICO(0x4bf7e000), DICO(0x4f937200), DICO(0x5584eb00), DICO(0x5cb02200),
+ DICO(0x03b592f0), DICO(0x056ba738), DICO(0x0a8e2250), DICO(0x172436c0),
+ DICO(0x1ad35da0), DICO(0x1d72dc80), DICO(0x20cd3900), DICO(0x2a962940),
+ DICO(0x2f3b6700), DICO(0x33312b40), DICO(0x38dc6680), DICO(0x41659200),
+ DICO(0x4d36a380), DICO(0x52b00980), DICO(0x58c82800), DICO(0x5d741600),
+ DICO(0x05bdfe10), DICO(0x0756da20), DICO(0x0cd31fe0), DICO(0x130f1820),
+ DICO(0x1561caa0), DICO(0x1962ab20), DICO(0x1c310840), DICO(0x28bf6f80),
+ DICO(0x2d2d4500), DICO(0x3230f900), DICO(0x3ac2ea80), DICO(0x3ebe71c0),
+ DICO(0x48280700), DICO(0x50254900), DICO(0x5850a200), DICO(0x5e687200),
+ DICO(0x04e2b7e8), DICO(0x067f5430), DICO(0x0a8899a0), DICO(0x0d571560),
+ DICO(0x1c42f440), DICO(0x22e21fc0), DICO(0x27074340), DICO(0x2c493240),
+ DICO(0x2f7ece00), DICO(0x33959ec0), DICO(0x392d3000), DICO(0x459fc800),
+ DICO(0x4ba5f700), DICO(0x4fde7780), DICO(0x55f90380), DICO(0x5c928b00),
+ DICO(0x0557b940), DICO(0x075f0158), DICO(0x0bd8c540), DICO(0x0f4ee370),
+ DICO(0x141dc900), DICO(0x1b241f00), DICO(0x21c32a80), DICO(0x29a23980),
+ DICO(0x2e475380), DICO(0x3616f9c0), DICO(0x3a52a500), DICO(0x40345f00),
+ DICO(0x4763a500), DICO(0x4eb5bb80), DICO(0x561d4480), DICO(0x5d388580),
+ DICO(0x057d7d08), DICO(0x0738c240), DICO(0x0bf46e10), DICO(0x0ec93da0),
+ DICO(0x14ab3cc0), DICO(0x23d0f5c0), DICO(0x271e9900), DICO(0x2c0ee4c0),
+ DICO(0x301d1f00), DICO(0x33868040), DICO(0x37cdde00), DICO(0x3c805440),
+ DICO(0x43c69200), DICO(0x4f5c9a00), DICO(0x56eb3e80), DICO(0x5cdadc80),
+ DICO(0x06cdbab0), DICO(0x0999e600), DICO(0x0df39790), DICO(0x12ffc9a0),
+ DICO(0x15cfe7a0), DICO(0x1c599300), DICO(0x21afd600), DICO(0x26842bc0),
+ DICO(0x32067c00), DICO(0x368bb080), DICO(0x3c350c40), DICO(0x44e8be00),
+ DICO(0x4ac84000), DICO(0x4f9c1280), DICO(0x5449ec00), DICO(0x594d5880),
+ DICO(0x049a6bd0), DICO(0x06849f08), DICO(0x10592b40), DICO(0x168c1940),
+ DICO(0x1992df40), DICO(0x1e91b300), DICO(0x2237e100), DICO(0x2cd73a80),
+ DICO(0x30e7c100), DICO(0x361a45c0), DICO(0x3cdd1f40), DICO(0x41d5d100),
+ DICO(0x46f79480), DICO(0x4e44c880), DICO(0x55830e80), DICO(0x5d7c0680),
+ DICO(0x05087958), DICO(0x06fb7e40), DICO(0x0ac5ace0), DICO(0x14e91d80),
+ DICO(0x19ac68c0), DICO(0x1dbf7600), DICO(0x26f916c0), DICO(0x2bd2c980),
+ DICO(0x307f7900), DICO(0x38e07e40), DICO(0x3df7f1c0), DICO(0x41323d00),
+ DICO(0x44d2f480), DICO(0x48fb0480), DICO(0x51e17900), DICO(0x5c15d700),
+ DICO(0x0346cf40), DICO(0x05423408), DICO(0x0b640ce0), DICO(0x13055060),
+ DICO(0x1a8c0b60), DICO(0x1d8d2280), DICO(0x218b6500), DICO(0x2c385700),
+ DICO(0x30927b40), DICO(0x35d82880), DICO(0x3aa87e00), DICO(0x3da46a40),
+ DICO(0x45ea5280), DICO(0x511ecb80), DICO(0x57b53b00), DICO(0x5d491400),
+ DICO(0x056aa1c8), DICO(0x075a09a0), DICO(0x0a5d61d0), DICO(0x13cb9fe0),
+ DICO(0x1f924dc0), DICO(0x237a11c0), DICO(0x277d6b80), DICO(0x2c2ba440),
+ DICO(0x30195c80), DICO(0x35250cc0), DICO(0x3b718200), DICO(0x40113c80),
+ DICO(0x44df2680), DICO(0x49f0ed80), DICO(0x50791980), DICO(0x5ac10600),
+ DICO(0x046f1e50), DICO(0x061dd758), DICO(0x1236bec0), DICO(0x16c07340),
+ DICO(0x1a7399c0), DICO(0x1f61ee20), DICO(0x244b2280), DICO(0x2b803e40),
+ DICO(0x2eda5300), DICO(0x331210c0), DICO(0x3773bfc0), DICO(0x411c8400),
+ DICO(0x488ff380), DICO(0x4fad2700), DICO(0x55845000), DICO(0x5ca74c00),
+ DICO(0x04b456f0), DICO(0x05fca198), DICO(0x0ad056d0), DICO(0x19c3bfe0),
+ DICO(0x1d446100), DICO(0x20f67200), DICO(0x24a40b40), DICO(0x28d472c0),
+ DICO(0x2da813c0), DICO(0x31880200), DICO(0x35344f40), DICO(0x3ca7f340),
+ DICO(0x4aa94300), DICO(0x4f921500), DICO(0x5516d700), DICO(0x5c832880),
+ DICO(0x07f468c0), DICO(0x0bbb6e90), DICO(0x0f0f8730), DICO(0x143d6180),
+ DICO(0x198b84c0), DICO(0x1c6b30a0), DICO(0x219c8000), DICO(0x28795780),
+ DICO(0x2cce3d00), DICO(0x329b1100), DICO(0x3a8d2240), DICO(0x3f579080),
+ DICO(0x45a74400), DICO(0x4d000f80), DICO(0x52bd6880), DICO(0x5a743a80),
+ DICO(0x06979498), DICO(0x088fecf0), DICO(0x0f1dac90), DICO(0x12077160),
+ DICO(0x16d5b120), DICO(0x1c5465c0), DICO(0x21ad14c0), DICO(0x282be280),
+ DICO(0x2b66a380), DICO(0x2fa3f200), DICO(0x35a06500), DICO(0x3a458d00),
+ DICO(0x44aefc00), DICO(0x4e92f600), DICO(0x55b9fa80), DICO(0x5cfe0280),
+ DICO(0x0552b408), DICO(0x06f6ce38), DICO(0x0e8f8d80), DICO(0x1395e900),
+ DICO(0x17c7b440), DICO(0x1ec64dc0), DICO(0x236e2200), DICO(0x2abc0b80),
+ DICO(0x2e131240), DICO(0x32921100), DICO(0x372633c0), DICO(0x3ca97840),
+ DICO(0x496e5000), DICO(0x4f86a800), DICO(0x54072300), DICO(0x5be31c80),
+ DICO(0x0470c0b8), DICO(0x0662c468), DICO(0x0c493fd0), DICO(0x1a1949c0),
+ DICO(0x1febcc20), DICO(0x2364e900), DICO(0x2a0cce00), DICO(0x2f6f8140),
+ DICO(0x3418b000), DICO(0x3c5c7a40), DICO(0x42d39100), DICO(0x476c2b00),
+ DICO(0x4e11c300), DICO(0x53621500), DICO(0x583fd280), DICO(0x5ce26600),
+ DICO(0x04b006c0), DICO(0x09a1ed40), DICO(0x135aee00), DICO(0x193b5180),
+ DICO(0x1f3679a0), DICO(0x24fdbcc0), DICO(0x2b823e00), DICO(0x31835780),
+ DICO(0x37c74cc0), DICO(0x3df66780), DICO(0x43c18580), DICO(0x49465980),
+ DICO(0x4ed0ce00), DICO(0x53d6fb80), DICO(0x59064300), DICO(0x5deaa100),
+ DICO(0x03cbc49c), DICO(0x07735930), DICO(0x138aaa20), DICO(0x1a1e69a0),
+ DICO(0x21be93c0), DICO(0x2936f780), DICO(0x2fa76f80), DICO(0x34ae6b00),
+ DICO(0x396b7b80), DICO(0x3dbc6700), DICO(0x421a9100), DICO(0x46fd2180),
+ DICO(0x4c5dca80), DICO(0x51923b80), DICO(0x576d1300), DICO(0x5d288680),
+ DICO(0x03cab7d0), DICO(0x052c88b8), DICO(0x09ed24f0), DICO(0x1c261820),
+ DICO(0x209096c0), DICO(0x2361e080), DICO(0x27292800), DICO(0x2bbdc6c0),
+ DICO(0x3292da80), DICO(0x36866a40), DICO(0x3c4d5100), DICO(0x45233400),
+ DICO(0x4d928a00), DICO(0x52ca9d00), DICO(0x5820d000), DICO(0x5d903880),
+ DICO(0x03f83718), DICO(0x0540fa90), DICO(0x13028120), DICO(0x1ad6e160),
+ DICO(0x1d784880), DICO(0x22028900), DICO(0x25976b40), DICO(0x2b293700),
+ DICO(0x2ddb86c0), DICO(0x317c4340), DICO(0x34e62ec0), DICO(0x3b71bd00),
+ DICO(0x4bc34780), DICO(0x52982400), DICO(0x57fa2800), DICO(0x5f19cc00),
+ DICO(0x049ceb50), DICO(0x06a8d4e0), DICO(0x09db2470), DICO(0x120e3e60),
+ DICO(0x1c8ebb80), DICO(0x21221d00), DICO(0x2679bfc0), DICO(0x2b1e7600),
+ DICO(0x2ebbcf80), DICO(0x32d5afc0), DICO(0x3d1bef00), DICO(0x41b11a00),
+ DICO(0x45bb2d80), DICO(0x4cb70300), DICO(0x572fdc80), DICO(0x5d876e80),
+ DICO(0x04abda68), DICO(0x06698cd0), DICO(0x0ca87230), DICO(0x15086a80),
+ DICO(0x176cf4e0), DICO(0x22899440), DICO(0x268fc500), DICO(0x2ba2d940),
+ DICO(0x33505980), DICO(0x36944bc0), DICO(0x3b20c280), DICO(0x437e8f00),
+ DICO(0x4bf29e80), DICO(0x51776a80), DICO(0x57a77800), DICO(0x5cf6c180),
+ DICO(0x06d7f5c0), DICO(0x08fd3cc0), DICO(0x0d8807e0), DICO(0x1140d500),
+ DICO(0x146dfc80), DICO(0x1e9fbaa0), DICO(0x23d7bf00), DICO(0x28b2ae80),
+ DICO(0x2e5a9b00), DICO(0x327005c0), DICO(0x37736640), DICO(0x4001c500),
+ DICO(0x4a862b00), DICO(0x4f7a2e00), DICO(0x54a22080), DICO(0x5b76c380),
+ DICO(0x0671fb68), DICO(0x08e4bf30), DICO(0x0d801250), DICO(0x1176b820),
+ DICO(0x15128860), DICO(0x1ee21180), DICO(0x24799580), DICO(0x29415a40),
+ DICO(0x2efa2380), DICO(0x33fe5040), DICO(0x39bf6d00), DICO(0x3f28b380),
+ DICO(0x442b2280), DICO(0x493de680), DICO(0x54377700), DICO(0x5d3a5480),
+ DICO(0x065b7970), DICO(0x087820b0), DICO(0x0d8d6aa0), DICO(0x16718620),
+ DICO(0x1a3a8f40), DICO(0x1f4099c0), DICO(0x24d87b40), DICO(0x296d85c0),
+ DICO(0x2f887c80), DICO(0x342d1b40), DICO(0x3887fc40), DICO(0x3d758b40),
+ DICO(0x42641c80), DICO(0x47bf6980), DICO(0x55f82900), DICO(0x5e132a00),
+ DICO(0x05ddbc00), DICO(0x081f17a0), DICO(0x0bf23ac0), DICO(0x12fc8d60),
+ DICO(0x172bc440), DICO(0x1a833540), DICO(0x1e942200), DICO(0x21e477c0),
+ DICO(0x2e75da80), DICO(0x399efac0), DICO(0x3dfb6900), DICO(0x428b3780),
+ DICO(0x4922a080), DICO(0x4d4c1700), DICO(0x51bbee00), DICO(0x5b4cfc80),
+ DICO(0x06ecf380), DICO(0x08f83990), DICO(0x0cb55680), DICO(0x140b2860),
+ DICO(0x18084d00), DICO(0x1aff9940), DICO(0x1f5f6f00), DICO(0x224a3d80),
+ DICO(0x2b0f49c0), DICO(0x3613b280), DICO(0x39188f40), DICO(0x3efa3640),
+ DICO(0x4771e400), DICO(0x4ca32380), DICO(0x54627580), DICO(0x5cb91000),
+ DICO(0x069e7f98), DICO(0x0870c760), DICO(0x0d7b73a0), DICO(0x15ab1040),
+ DICO(0x18a4d220), DICO(0x1c4c1f20), DICO(0x1ffaf200), DICO(0x24142580),
+ DICO(0x30e47540), DICO(0x37340200), DICO(0x3a69af40), DICO(0x3ed471c0),
+ DICO(0x44157880), DICO(0x486b7f00), DICO(0x52ed2b00), DICO(0x5ce3a980),
+ DICO(0x047f1080), DICO(0x06463230), DICO(0x0b566e80), DICO(0x0edb9080),
+ DICO(0x128a2fa0), DICO(0x1748b340), DICO(0x210b2b00), DICO(0x28099b80),
+ DICO(0x2f519740), DICO(0x36fe82c0), DICO(0x3d924b80), DICO(0x43cd3c00),
+ DICO(0x4a774680), DICO(0x50d15f00), DICO(0x573b3580), DICO(0x5d4c1c00),
+ DICO(0x05fa6a68), DICO(0x0866e4c0), DICO(0x0d133cc0), DICO(0x156d6b20),
+ DICO(0x18abebe0), DICO(0x1d374900), DICO(0x23d23d00), DICO(0x27b370c0),
+ DICO(0x2f63ef00), DICO(0x352a0600), DICO(0x3a643a40), DICO(0x3f57f980),
+ DICO(0x457a7f00), DICO(0x520f6200), DICO(0x593b2c80), DICO(0x5e192b80),
+ DICO(0x04e4e0c8), DICO(0x067c3450), DICO(0x0acabe70), DICO(0x1865eec0),
+ DICO(0x1c5e9bc0), DICO(0x202facc0), DICO(0x24a609c0), DICO(0x28db7b00),
+ DICO(0x2efbd780), DICO(0x336fe5c0), DICO(0x3819a5c0), DICO(0x3e709b40),
+ DICO(0x4435ff80), DICO(0x4bd5fb80), DICO(0x5564a100), DICO(0x5d0a4980),
+ DICO(0x05a72f00), DICO(0x070199b0), DICO(0x0e654780), DICO(0x14fc7780),
+ DICO(0x174283c0), DICO(0x1b231480), DICO(0x1e7b9000), DICO(0x27a013c0),
+ DICO(0x2b42f500), DICO(0x2fd9ca00), DICO(0x3672a0c0), DICO(0x3cc23f40),
+ DICO(0x48299d80), DICO(0x4f92a800), DICO(0x564d7680), DICO(0x5d3ab580),
+ DICO(0x03e63764), DICO(0x05baa3f0), DICO(0x0ab2a300), DICO(0x12cc5f60),
+ DICO(0x19a8d5e0), DICO(0x1ea788e0), DICO(0x22cd50c0), DICO(0x25d48a00),
+ DICO(0x29924540), DICO(0x32762a00), DICO(0x3bba55c0), DICO(0x4222e800),
+ DICO(0x4aba1280), DICO(0x501d0b80), DICO(0x57091200), DICO(0x5d6bf180),
+ DICO(0x047daeb0), DICO(0x069548b8), DICO(0x0b002410), DICO(0x13ff7060),
+ DICO(0x186aec40), DICO(0x210db240), DICO(0x26f1ce80), DICO(0x2b73c9c0),
+ DICO(0x33d57240), DICO(0x385898c0), DICO(0x3eea8cc0), DICO(0x43c79b00),
+ DICO(0x496ec200), DICO(0x4e150780), DICO(0x54dcb700), DICO(0x5c3f7380),
+ DICO(0x079fd258), DICO(0x0b93bd50), DICO(0x0ff7d8b0), DICO(0x14bd4e00),
+ DICO(0x19536ae0), DICO(0x1d8b1640), DICO(0x23747cc0), DICO(0x2861f280),
+ DICO(0x2d7d2880), DICO(0x3583b040), DICO(0x3c3cab00), DICO(0x41b7b580),
+ DICO(0x498cfc80), DICO(0x506cbd00), DICO(0x57847600), DICO(0x5d05de80),
+ DICO(0x06434ec0), DICO(0x0805ccd0), DICO(0x0c4b4c00), DICO(0x13d551c0),
+ DICO(0x1685abe0), DICO(0x1a83ea60), DICO(0x1ddc3700), DICO(0x22bc4600),
+ DICO(0x2c7ca5c0), DICO(0x30a589c0), DICO(0x395a8700), DICO(0x40c92900),
+ DICO(0x472fae80), DICO(0x4f6f6e80), DICO(0x571b3f80), DICO(0x5d8e6980),
+ DICO(0x05ec21b0), DICO(0x079ee388), DICO(0x0e4b4580), DICO(0x11abf100),
+ DICO(0x16588ec0), DICO(0x1c984ec0), DICO(0x20a384c0), DICO(0x28d6be00),
+ DICO(0x2bcca740), DICO(0x3604b600), DICO(0x3f027280), DICO(0x434af000),
+ DICO(0x48dac280), DICO(0x4d7e8a00), DICO(0x51f61800), DICO(0x5a6d9380),
+ DICO(0x0552c6c0), DICO(0x070c22a0), DICO(0x0a411b50), DICO(0x0e3e5270),
+ DICO(0x1193bb60), DICO(0x1b177e00), DICO(0x275b2500), DICO(0x2b42bd80),
+ DICO(0x322d7e40), DICO(0x3a170880), DICO(0x3d66b580), DICO(0x41413280),
+ DICO(0x46a9ce80), DICO(0x4e4e3800), DICO(0x571f8380), DICO(0x5ddae380),
+ DICO(0x055602c0), DICO(0x06e69118), DICO(0x0c9d13f0), DICO(0x1090d500),
+ DICO(0x138d2280), DICO(0x171bf540), DICO(0x1b585180), DICO(0x288b9740),
+ DICO(0x2db202c0), DICO(0x3525e680), DICO(0x3c303900), DICO(0x4311df80),
+ DICO(0x49b92c00), DICO(0x509de900), DICO(0x56e9a080), DICO(0x5d523a80),
+ DICO(0x04e79810), DICO(0x069626e8), DICO(0x0a6cf680), DICO(0x0da668c0),
+ DICO(0x115872a0), DICO(0x2032eec0), DICO(0x25345dc0), DICO(0x2ae8ea40),
+ DICO(0x30224280), DICO(0x351ff640), DICO(0x3ce65a80), DICO(0x454bff00),
+ DICO(0x4ee08980), DICO(0x543b4280), DICO(0x59c19280), DICO(0x5ddfbb00),
+ DICO(0x03f0bb98), DICO(0x0588f4f0), DICO(0x0a862bc0), DICO(0x14ec76e0),
+ DICO(0x184b8a80), DICO(0x1f7bbd80), DICO(0x23f1a7c0), DICO(0x2c367900),
+ DICO(0x3234af80), DICO(0x35460ac0), DICO(0x38514c00), DICO(0x3d5f3540),
+ DICO(0x48394980), DICO(0x4fbdd380), DICO(0x56de0280), DICO(0x5d4e6500),
+ DICO(0x06050f28), DICO(0x08070af0), DICO(0x0be31240), DICO(0x0f5e53e0),
+ DICO(0x125f1740), DICO(0x215b1fc0), DICO(0x2883d880), DICO(0x2c181080),
+ DICO(0x32810280), DICO(0x35d56800), DICO(0x3a9b0880), DICO(0x3ffaaf80),
+ DICO(0x44c65500), DICO(0x4a45ae80), DICO(0x56b4ed80), DICO(0x5e4adc00),
+ DICO(0x0372bbb4), DICO(0x04ea4848), DICO(0x09b8de70), DICO(0x151b4a40),
+ DICO(0x1be65a00), DICO(0x207655c0), DICO(0x2720dd00), DICO(0x2fc6cc00),
+ DICO(0x35b063c0), DICO(0x39bd30c0), DICO(0x3dc5b580), DICO(0x42af7b00),
+ DICO(0x48d2bf00), DICO(0x4f46bb80), DICO(0x55f7ca80), DICO(0x5ca7e980),
+ DICO(0x033f868c), DICO(0x04d9a0e0), DICO(0x0a18d6d0), DICO(0x13da5580),
+ DICO(0x181ae880), DICO(0x207d8580), DICO(0x262022c0), DICO(0x2c6de040),
+ DICO(0x3321f100), DICO(0x3927f0c0), DICO(0x3f74ce40), DICO(0x4573e980),
+ DICO(0x4ba66c80), DICO(0x51a26100), DICO(0x57d3a800), DICO(0x5d52e780),
+ DICO(0x05189860), DICO(0x07231848), DICO(0x0b915710), DICO(0x0f05d6c0),
+ DICO(0x13bb0820), DICO(0x223adf00), DICO(0x26ce1ec0), DICO(0x2ce1ac00),
+ DICO(0x3401f6c0), DICO(0x3b8c2240), DICO(0x40e4a400), DICO(0x45674f00),
+ DICO(0x4b04b880), DICO(0x4f253200), DICO(0x54168600), DICO(0x58f52780),
+ DICO(0x0338d184), DICO(0x05205790), DICO(0x09abcd80), DICO(0x0f53ff60),
+ DICO(0x1a7fe900), DICO(0x1ef93860), DICO(0x238e2d80), DICO(0x2bd81bc0),
+ DICO(0x33161240), DICO(0x368cfb80), DICO(0x3a28b5c0), DICO(0x40c7a600),
+ DICO(0x4bac7780), DICO(0x524b7880), DICO(0x58638480), DICO(0x5da07b00),
+ DICO(0x04d06f38), DICO(0x065f1518), DICO(0x0c9b31b0), DICO(0x10570d40),
+ DICO(0x15e790a0), DICO(0x20f16380), DICO(0x246f23c0), DICO(0x2e222800),
+ DICO(0x3198bf00), DICO(0x34b84640), DICO(0x38f5b440), DICO(0x4312df80),
+ DICO(0x4d2d3000), DICO(0x5209ee80), DICO(0x579cf180), DICO(0x5cb37680),
+ DICO(0x042e6560), DICO(0x05eaff30), DICO(0x0a090d30), DICO(0x0d9f2ab0),
+ DICO(0x1a6f0260), DICO(0x209e0c00), DICO(0x25dc95c0), DICO(0x29f89840),
+ DICO(0x2f372840), DICO(0x3a301940), DICO(0x3f0e2e80), DICO(0x44465c80),
+ DICO(0x49207780), DICO(0x4dfdab80), DICO(0x532ec000), DICO(0x5acefd00),
+ DICO(0x04e18ad8), DICO(0x06d5b660), DICO(0x0b2a22d0), DICO(0x0e0e4ef0),
+ DICO(0x198304a0), DICO(0x1e4a25c0), DICO(0x23de37c0), DICO(0x290679c0),
+ DICO(0x2d523b00), DICO(0x337df940), DICO(0x37948100), DICO(0x3de07300),
+ DICO(0x49ee6e80), DICO(0x50576100), DICO(0x55fb1e00), DICO(0x5d080500),
+ DICO(0x05312308), DICO(0x070463f0), DICO(0x0daffba0), DICO(0x12d8c3c0),
+ DICO(0x163ab7a0), DICO(0x20c64c40), DICO(0x24c8fe40), DICO(0x2a6f65c0),
+ DICO(0x3055e100), DICO(0x34420d80), DICO(0x389ded00), DICO(0x3cc57640),
+ DICO(0x4280cd00), DICO(0x4e0a4c00), DICO(0x57675f00), DICO(0x5d87d480),
+ DICO(0x047bd598), DICO(0x06cb1498), DICO(0x0c359930), DICO(0x138165e0),
+ DICO(0x1cae3640), DICO(0x21647640), DICO(0x2836fac0), DICO(0x2cd7b840),
+ DICO(0x30d839c0), DICO(0x360c9440), DICO(0x3ae5ca40), DICO(0x40a93b00),
+ DICO(0x49401e80), DICO(0x4f739c80), DICO(0x54f33c00), DICO(0x5c190200),
+ DICO(0x051c0000), DICO(0x06b45258), DICO(0x0a5eee50), DICO(0x0d46fc30),
+ DICO(0x125bbc60), DICO(0x253d8cc0), DICO(0x2a1fd6c0), DICO(0x2df4cf80),
+ DICO(0x3239e3c0), DICO(0x35a683c0), DICO(0x3b0bb980), DICO(0x409b3d00),
+ DICO(0x46633580), DICO(0x4f2b0600), DICO(0x577cea80), DICO(0x5d86ef00),
+ DICO(0x03d19eec), DICO(0x07cce6d0), DICO(0x143b4b00), DICO(0x1a657880),
+ DICO(0x212e0280), DICO(0x2831fbc0), DICO(0x2f8ba080), DICO(0x35db8040),
+ DICO(0x3bf17f00), DICO(0x413eb100), DICO(0x46154900), DICO(0x4ae18080),
+ DICO(0x4f9ba180), DICO(0x5428ba00), DICO(0x590e9080), DICO(0x5de0d880),
+ DICO(0x08c7e720), DICO(0x0ff14810), DICO(0x1758cc40), DICO(0x1cc744c0),
+ DICO(0x23e45cc0), DICO(0x2b527940), DICO(0x32138580), DICO(0x37b77380),
+ DICO(0x3d7da480), DICO(0x4275a800), DICO(0x473ecf00), DICO(0x4bc7dc80),
+ DICO(0x50512400), DICO(0x54d2c600), DICO(0x598ce680), DICO(0x5e1e0800),
+ DICO(0x09167910), DICO(0x107644a0), DICO(0x171a59e0), DICO(0x1be1ea60),
+ DICO(0x21347680), DICO(0x265a5b00), DICO(0x2be41a40), DICO(0x3116e700),
+ DICO(0x368b0300), DICO(0x3c225e80), DICO(0x41a6e880), DICO(0x47631680),
+ DICO(0x4d47d900), DICO(0x52a28400), DICO(0x583f0e80), DICO(0x5d77bc80),
+ DICO(0x040bdf88), DICO(0x05b062a0), DICO(0x0b4a2f70), DICO(0x1b8cd880),
+ DICO(0x1ec58c40), DICO(0x23661880), DICO(0x2790ba80), DICO(0x2d0d6c40),
+ DICO(0x34f0bc40), DICO(0x3a353f80), DICO(0x3fc3bc40), DICO(0x44998700),
+ DICO(0x49b17080), DICO(0x4f31fa00), DICO(0x55311c80), DICO(0x5b5c8f80),
+ DICO(0x043e2bd0), DICO(0x0645b0f0), DICO(0x0ade5b90), DICO(0x0d653a90),
+ DICO(0x1bc224a0), DICO(0x1f623dc0), DICO(0x27e9a840), DICO(0x2c719bc0),
+ DICO(0x2f2ac040), DICO(0x32688300), DICO(0x36695c00), DICO(0x3b8abe40),
+ DICO(0x47153a80), DICO(0x52491b00), DICO(0x57ba7680), DICO(0x5ce6c300),
+ DICO(0x052940b8), DICO(0x06f28228), DICO(0x0a741c90), DICO(0x0daa3110),
+ DICO(0x113bb2e0), DICO(0x2010b640), DICO(0x2610f380), DICO(0x2a5c7740),
+ DICO(0x2f7703c0), DICO(0x3388d080), DICO(0x3ceabe40), DICO(0x42462a80),
+ DICO(0x47fb0e00), DICO(0x4f7ac480), DICO(0x5706f580), DICO(0x5d92b800),
+ DICO(0x03a134a4), DICO(0x05623470), DICO(0x090a0fe0), DICO(0x12f7d3e0),
+ DICO(0x1d63e440), DICO(0x20e6ac80), DICO(0x247da8c0), DICO(0x27d99600),
+ DICO(0x312e99c0), DICO(0x368fb380), DICO(0x3b3e3ec0), DICO(0x40fead80),
+ DICO(0x4888fa00), DICO(0x4fbd5600), DICO(0x5795a480), DICO(0x5d973000),
+ DICO(0x05697990), DICO(0x06f33800), DICO(0x0b298290), DICO(0x0de47a60),
+ DICO(0x12ef62a0), DICO(0x21e30a00), DICO(0x25f8ff00), DICO(0x2b2287c0),
+ DICO(0x2f11fc00), DICO(0x33138000), DICO(0x37b49f80), DICO(0x41325100),
+ DICO(0x4ab62800), DICO(0x501eae80), DICO(0x56228780), DICO(0x5c5d8300),
+ DICO(0x063830d8), DICO(0x08a76a30), DICO(0x0d376890), DICO(0x117d3a00),
+ DICO(0x1476e5c0), DICO(0x1e215720), DICO(0x24bcd680), DICO(0x29674ac0),
+ DICO(0x2faab340), DICO(0x33843a00), DICO(0x3822e900), DICO(0x3d30b6c0),
+ DICO(0x49cd5480), DICO(0x53187d00), DICO(0x591fe100), DICO(0x5db30f80),
+ DICO(0x05cdc378), DICO(0x075c50c8), DICO(0x0e01f830), DICO(0x12b70480),
+ DICO(0x15e333e0), DICO(0x192c9f40), DICO(0x1d2d6b80), DICO(0x2c09ca40),
+ DICO(0x2eea5cc0), DICO(0x32c89380), DICO(0x376a5b40), DICO(0x42a42600),
+ DICO(0x4c695900), DICO(0x5269e380), DICO(0x586d6c80), DICO(0x5cebdb80),
+ DICO(0x052bbb80), DICO(0x0702e268), DICO(0x0ca196d0), DICO(0x0f48cef0),
+ DICO(0x19d28b60), DICO(0x1ec44a40), DICO(0x24d40f00), DICO(0x29e1eac0),
+ DICO(0x2cafaa80), DICO(0x301bd4c0), DICO(0x357ec200), DICO(0x42254480),
+ DICO(0x4be32000), DICO(0x4f7a4a00), DICO(0x5447fc00), DICO(0x5cca6a00),
+ DICO(0x050fdd18), DICO(0x06c77e10), DICO(0x10561140), DICO(0x1564c340),
+ DICO(0x1867abe0), DICO(0x1f00fba0), DICO(0x22c06240), DICO(0x2aed7680),
+ DICO(0x2ecc24c0), DICO(0x32abb300), DICO(0x36b42340), DICO(0x3ed8f480),
+ DICO(0x4bbdfe80), DICO(0x516bf800), DICO(0x58688b00), DICO(0x5dd44980),
+ DICO(0x058aa130), DICO(0x07d69ba8), DICO(0x0d521f40), DICO(0x0ff37ba0),
+ DICO(0x18125ec0), DICO(0x1f3a4520), DICO(0x23349840), DICO(0x2c759580),
+ DICO(0x2fc21c00), DICO(0x33a42fc0), DICO(0x3dc92900), DICO(0x47befd00),
+ DICO(0x4ccd2480), DICO(0x5197a200), DICO(0x56a2ea00), DICO(0x5bdfa900),
+ DICO(0x05ac8640), DICO(0x076aec88), DICO(0x0e2e3230), DICO(0x114b6f40),
+ DICO(0x155d10a0), DICO(0x19bac600), DICO(0x1fbd75c0), DICO(0x2459c0c0),
+ DICO(0x28229b80), DICO(0x2f586fc0), DICO(0x3d0697c0), DICO(0x42a7a500),
+ DICO(0x49b0bb80), DICO(0x4e642e80), DICO(0x55774280), DICO(0x5d1a7900),
+ DICO(0x05efb470), DICO(0x0831c8a0), DICO(0x0d35ece0), DICO(0x13edc400),
+ DICO(0x16c8fec0), DICO(0x1bb25860), DICO(0x204f3140), DICO(0x277b8a40),
+ DICO(0x2fe9a000), DICO(0x33af7c40), DICO(0x3b7d2900), DICO(0x419c9a80),
+ DICO(0x4591dc80), DICO(0x4bdafd00), DICO(0x55638880), DICO(0x5cef2300),
+ DICO(0x05cf4988), DICO(0x078fa8c0), DICO(0x0c291950), DICO(0x12e05320),
+ DICO(0x155997e0), DICO(0x195df540), DICO(0x1c1b82c0), DICO(0x22c29400),
+ DICO(0x307edec0), DICO(0x34e829c0), DICO(0x3b1b5040), DICO(0x434de400),
+ DICO(0x496b9900), DICO(0x4ff88080), DICO(0x5604c480), DICO(0x5c84b080),
+ DICO(0x03679fa4), DICO(0x050d4a20), DICO(0x09feec10), DICO(0x100a21e0),
+ DICO(0x1483b260), DICO(0x1d76c780), DICO(0x24e75c80), DICO(0x2bd62880),
+ DICO(0x32350a40), DICO(0x38be01c0), DICO(0x3f05a280), DICO(0x45295e80),
+ DICO(0x4b554800), DICO(0x51618880), DICO(0x575a1500), DICO(0x5d109d80),
+ DICO(0x034ffd08), DICO(0x04dccea8), DICO(0x07e289b8), DICO(0x0d6950d0),
+ DICO(0x189acec0), DICO(0x1e3bf240), DICO(0x2535aa40), DICO(0x2b88d140),
+ DICO(0x329bbb00), DICO(0x386c3500), DICO(0x3e950800), DICO(0x44c43f00),
+ DICO(0x4b089780), DICO(0x51223280), DICO(0x574c9780), DICO(0x5d366400),
+ DICO(0x036d8db8), DICO(0x04fd88b8), DICO(0x09700a70), DICO(0x116b73c0),
+ DICO(0x17258c40), DICO(0x1fd03000), DICO(0x23fdf400), DICO(0x28e08dc0),
+ DICO(0x32d688c0), DICO(0x37920b00), DICO(0x3daaa080), DICO(0x46a16c00),
+ DICO(0x4f8c3100), DICO(0x54a13700), DICO(0x59d24b80), DICO(0x5cea4d80),
+ DICO(0x05797c88), DICO(0x080dc8f0), DICO(0x0bd21520), DICO(0x1095b540),
+ DICO(0x138fd400), DICO(0x1aed19c0), DICO(0x29fead00), DICO(0x2f70cec0),
+ DICO(0x3327df00), DICO(0x3a812d00), DICO(0x400a8380), DICO(0x449daa00),
+ DICO(0x4cd6b600), DICO(0x51f12400), DICO(0x56bdfd80), DICO(0x5be0a100),
+ DICO(0x04de6d78), DICO(0x072aed40), DICO(0x0c6fc460), DICO(0x0f260220),
+ DICO(0x179d00c0), DICO(0x1e8244e0), DICO(0x23867240), DICO(0x2baf7680),
+ DICO(0x2fa6d240), DICO(0x37e83d40), DICO(0x3d1cbfc0), DICO(0x439d0a00),
+ DICO(0x49fd3e00), DICO(0x50095e80), DICO(0x559f2080), DICO(0x5b889a00),
+ DICO(0x042f5c10), DICO(0x061ab3e8), DICO(0x0dd8f160), DICO(0x126e0b40),
+ DICO(0x16ea9040), DICO(0x20a31700), DICO(0x24608140), DICO(0x2ec65080),
+ DICO(0x334e1a40), DICO(0x38252100), DICO(0x3fff0900), DICO(0x46519a80),
+ DICO(0x4c5e0d80), DICO(0x518c5800), DICO(0x56c5b080), DICO(0x5c6ebb80),
+ DICO(0x045ce230), DICO(0x067547b0), DICO(0x0a21c670), DICO(0x1408b820),
+ DICO(0x1c0505c0), DICO(0x1e806c80), DICO(0x26d3c640), DICO(0x2ca573c0),
+ DICO(0x3014d880), DICO(0x377108c0), DICO(0x3f35cf80), DICO(0x43566100),
+ DICO(0x4a612900), DICO(0x5160c780), DICO(0x57d3e300), DICO(0x5d414b80),
+ DICO(0x04c8eda8), DICO(0x06a32320), DICO(0x09ab2590), DICO(0x14230760),
+ DICO(0x20fb23c0), DICO(0x24aa2880), DICO(0x285a2580), DICO(0x2c464ac0),
+ DICO(0x30098280), DICO(0x36232780), DICO(0x3e428d40), DICO(0x42982280),
+ DICO(0x47e60d80), DICO(0x4e1ecc00), DICO(0x55eb9200), DICO(0x5c81ed00),
+ DICO(0x040d0b90), DICO(0x0586c5c0), DICO(0x0bea2190), DICO(0x1dc8dd60),
+ DICO(0x20a07c40), DICO(0x2437e580), DICO(0x27ca5fc0), DICO(0x2d017980),
+ DICO(0x34100040), DICO(0x38d3afc0), DICO(0x3da9b700), DICO(0x42082480),
+ DICO(0x46586f00), DICO(0x4e3c3d80), DICO(0x55e1ee00), DICO(0x5c938d00),
+ DICO(0x03d18c64), DICO(0x05941d60), DICO(0x116b2560), DICO(0x19cc8820),
+ DICO(0x1ce930c0), DICO(0x22626080), DICO(0x26d2cf80), DICO(0x2ce2c980),
+ DICO(0x305361c0), DICO(0x34b65900), DICO(0x39ee5b40), DICO(0x41508400),
+ DICO(0x47ee1e80), DICO(0x50311180), DICO(0x56cb0c00), DICO(0x5d561680),
+ DICO(0x0af22cf0), DICO(0x154e1c60), DICO(0x1b44ff60), DICO(0x2087d0c0),
+ DICO(0x252f7380), DICO(0x28fe66c0), DICO(0x2d0e9800), DICO(0x30f7ee00),
+ DICO(0x3606d640), DICO(0x3bac0a40), DICO(0x417c3700), DICO(0x470c2900),
+ DICO(0x4cc20d00), DICO(0x51e55e80), DICO(0x576bc200), DICO(0x5caa7080),
+ DICO(0x043314e0), DICO(0x05cb47b0), DICO(0x0985df20), DICO(0x185a22c0),
+ DICO(0x1ea68300), DICO(0x21af9100), DICO(0x25cdcb40), DICO(0x297e0a80),
+ DICO(0x3142ac80), DICO(0x358bb040), DICO(0x3a1345c0), DICO(0x402ca580),
+ DICO(0x4d964780), DICO(0x5420cf80), DICO(0x592adf80), DICO(0x5dfe7a80),
+ DICO(0x04c70e20), DICO(0x062fd6f0), DICO(0x113c60a0), DICO(0x159e9900),
+ DICO(0x1933e5a0), DICO(0x1decffa0), DICO(0x22373400), DICO(0x27ed7180),
+ DICO(0x2a8349c0), DICO(0x2f78f940), DICO(0x3d5c8540), DICO(0x429c3500),
+ DICO(0x4936e300), DICO(0x4de08d00), DICO(0x52627700), DICO(0x5d822680),
+ DICO(0x04982770), DICO(0x06ab1ad8), DICO(0x0cba1090), DICO(0x10839d60),
+ DICO(0x1acd6a60), DICO(0x1f554560), DICO(0x2431c1c0), DICO(0x295db800),
+ DICO(0x2d374c00), DICO(0x31f2fd80), DICO(0x3a200480), DICO(0x416bea80),
+ DICO(0x4ba1ce00), DICO(0x52a88000), DICO(0x58d0db00), DICO(0x5d3e5800),
+ DICO(0x059e0e70), DICO(0x08166ba0), DICO(0x0c9df590), DICO(0x11de5f40),
+ DICO(0x14c08ea0), DICO(0x1c5ad6e0), DICO(0x24178ec0), DICO(0x28eb7640),
+ DICO(0x31626280), DICO(0x35d43100), DICO(0x3cad10c0), DICO(0x422e1480),
+ DICO(0x49baee00), DICO(0x53dd7180), DICO(0x5a17bb80), DICO(0x5e4bb180),
+ DICO(0x03c64d00), DICO(0x05de0b28), DICO(0x0ccb82b0), DICO(0x144b1c00),
+ DICO(0x19e39ec0), DICO(0x21e795c0), DICO(0x28149380), DICO(0x2f1ff7c0),
+ DICO(0x35b7c900), DICO(0x3c5f4800), DICO(0x42799c00), DICO(0x48746180),
+ DICO(0x4e8f4d00), DICO(0x53b98380), DICO(0x58d60000), DICO(0x5d71a000),
+ DICO(0x050a2990), DICO(0x071bdb88), DICO(0x0f0d76b0), DICO(0x17a78de0),
+ DICO(0x1aa20720), DICO(0x22eea3c0), DICO(0x276e9640), DICO(0x2ecc4d80),
+ DICO(0x335f7900), DICO(0x37838640), DICO(0x3c81be80), DICO(0x41a4e400),
+ DICO(0x476fa280), DICO(0x4f2ab780), DICO(0x56e87b80), DICO(0x5cbf2900),
+ DICO(0x06724c98), DICO(0x099f5e20), DICO(0x119bcec0), DICO(0x16be11a0),
+ DICO(0x19d53b00), DICO(0x1eb51360), DICO(0x2302c300), DICO(0x29c20d40),
+ DICO(0x30dd5200), DICO(0x36576a80), DICO(0x3e3e7540), DICO(0x45aa9f80),
+ DICO(0x4c833300), DICO(0x51d7ed00), DICO(0x57a4a380), DICO(0x5cce9100),
+ DICO(0x05588b60), DICO(0x075a70a0), DICO(0x0ef96e30), DICO(0x12ac1100),
+ DICO(0x1649dde0), DICO(0x1a50cdc0), DICO(0x22486140), DICO(0x27c7c800),
+ DICO(0x2e08bd80), DICO(0x355d20c0), DICO(0x3925a9c0), DICO(0x44e2b480),
+ DICO(0x4fa4e680), DICO(0x5470e180), DICO(0x595fee80), DICO(0x5d672f00),
+ DICO(0x04a781c0), DICO(0x060a89f0), DICO(0x111f56a0), DICO(0x16b93be0),
+ DICO(0x19ce9120), DICO(0x1e1fda60), DICO(0x2259f880), DICO(0x285cad80),
+ DICO(0x2b140ec0), DICO(0x2f069940), DICO(0x33bbce40), DICO(0x3dd3e6c0),
+ DICO(0x49154880), DICO(0x5008e380), DICO(0x568c4680), DICO(0x5da43780),
+ DICO(0x053ade38), DICO(0x0708a200), DICO(0x0bad43d0), DICO(0x1860cf40),
+ DICO(0x1c40dbe0), DICO(0x1f5a0120), DICO(0x25bcf7c0), DICO(0x29e0c840),
+ DICO(0x2f223840), DICO(0x390c8940), DICO(0x3e1d7340), DICO(0x41c6a000),
+ DICO(0x46cc2880), DICO(0x5006e280), DICO(0x5744e180), DICO(0x5d297780),
+ DICO(0x0401a3f0), DICO(0x07be4a08), DICO(0x14f5f1a0), DICO(0x1c348080),
+ DICO(0x226753c0), DICO(0x274b1b80), DICO(0x2c11a300), DICO(0x30798c00),
+ DICO(0x35598c80), DICO(0x3aab18c0), DICO(0x4030f380), DICO(0x45c7b400),
+ DICO(0x4be5be00), DICO(0x5180db80), DICO(0x57613b00), DICO(0x5cffff80),
+ DICO(0x084b3090), DICO(0x0fe5b3b0), DICO(0x16dfd480), DICO(0x1d0aa700),
+ DICO(0x24e08180), DICO(0x2b498640), DICO(0x30885b80), DICO(0x34ccc480),
+ DICO(0x38fedec0), DICO(0x3cdf9c40), DICO(0x41737600), DICO(0x46ab9800),
+ DICO(0x4c772e80), DICO(0x51e5b980), DICO(0x57df9900), DICO(0x5d5d7180),
+ DICO(0x09549f00), DICO(0x12b84da0), DICO(0x1aeaf1c0), DICO(0x2142a9c0),
+ DICO(0x275c9a00), DICO(0x2c260c80), DICO(0x3038c700), DICO(0x34081d00),
+ DICO(0x38612f40), DICO(0x3d0bf8c0), DICO(0x42473e00), DICO(0x47ecad80),
+ DICO(0x4db34380), DICO(0x52f0ab00), DICO(0x584cc980), DICO(0x5d62ae80),
+ DICO(0x0aeca1e0), DICO(0x14354700), DICO(0x19955ba0), DICO(0x1de331e0),
+ DICO(0x21cd60c0), DICO(0x25e72d80), DICO(0x2a402880), DICO(0x2efa64c0),
+ DICO(0x3478d9c0), DICO(0x3a889e80), DICO(0x40744e00), DICO(0x4626fe80),
+ DICO(0x4bd80900), DICO(0x51120f00), DICO(0x56d8d280), DICO(0x5c654400),
+ DICO(0x07a40af8), DICO(0x0e65ec20), DICO(0x14c76780), DICO(0x19b35a60),
+ DICO(0x1f76b7c0), DICO(0x24f512c0), DICO(0x2ae89f00), DICO(0x3036c3c0),
+ DICO(0x36041800), DICO(0x3bc4df80), DICO(0x41adb080), DICO(0x477fbb80),
+ DICO(0x4d5aa480), DICO(0x52cb0600), DICO(0x586f7280), DICO(0x5db40180),
+ DICO(0x03997610), DICO(0x06175db0), DICO(0x0ea8c9c0), DICO(0x14397000),
+ DICO(0x1ba34f60), DICO(0x22346680), DICO(0x28958080), DICO(0x2ea76840),
+ DICO(0x33ee68c0), DICO(0x39e769c0), DICO(0x3f862500), DICO(0x4579b080),
+ DICO(0x4b49cd00), DICO(0x5107da80), DICO(0x573cde00), DICO(0x5d090780),
+ DICO(0x046fc2f8), DICO(0x0640dbc0), DICO(0x09da7ab0), DICO(0x174e4220),
+ DICO(0x23dc8cc0), DICO(0x27016200), DICO(0x2a9a5240), DICO(0x2e6cc7c0),
+ DICO(0x321ced40), DICO(0x38ca2d00), DICO(0x41482680), DICO(0x451e3700),
+ DICO(0x4b90d800), DICO(0x50d0ba80), DICO(0x55602e80), DICO(0x5a465200),
+ DICO(0x03ca7e28), DICO(0x057c9dd0), DICO(0x0c9ff0e0), DICO(0x1957fae0),
+ DICO(0x1fef7860), DICO(0x27920c80), DICO(0x2cb233c0), DICO(0x32015c80),
+ DICO(0x36af4f40), DICO(0x3ac18240), DICO(0x3f93d8c0), DICO(0x44eaef80),
+ DICO(0x4aab5d80), DICO(0x50840e80), DICO(0x56c4cc80), DICO(0x5cb26600),
+ DICO(0x038d53f8), DICO(0x050d1118), DICO(0x0bc14690), DICO(0x18918000),
+ DICO(0x1e2a6ee0), DICO(0x24cc0c00), DICO(0x2a767d40), DICO(0x2e614940),
+ DICO(0x32859c40), DICO(0x377fd940), DICO(0x3d3a3e40), DICO(0x43e81380),
+ DICO(0x4aaac080), DICO(0x509e7800), DICO(0x57023a00), DICO(0x5d733c00),
+ DICO(0x04cfa5e0), DICO(0x06deeb38), DICO(0x0a501c40), DICO(0x136d8aa0),
+ DICO(0x17f16e40), DICO(0x1c119300), DICO(0x26154b00), DICO(0x2a0da100),
+ DICO(0x2f5935c0), DICO(0x37108d40), DICO(0x3aef07c0), DICO(0x3fccf340),
+ DICO(0x47e4a080), DICO(0x4d8de100), DICO(0x54eb6980), DICO(0x5cdb5380)};
+
+/* ACELP: table for decoding
+ adaptive codebook gain g_p (left column). Scaled by 2.0f.
+ innovative codebook gain g_c (right column). Scaled by 16.0f.
+*/
+const FIXP_SGL fdk_t_qua_gain7b[128 * 2] = {
+ 204, 441, 464, 1977, 869, 1077, 1072, 3062, 1281, 4759, 1647,
+ 1539, 1845, 7020, 1853, 634, 1995, 2336, 2351, 15400, 2661, 1165,
+ 2702, 3900, 2710, 10133, 3195, 1752, 3498, 2624, 3663, 849, 3984,
+ 5697, 4214, 3399, 4415, 1304, 4695, 2056, 5376, 4558, 5386, 676,
+ 5518, 23554, 5567, 7794, 5644, 3061, 5672, 1513, 5957, 2338, 6533,
+ 1060, 6804, 5998, 6820, 1767, 6937, 3837, 7277, 414, 7305, 2665,
+ 7466, 11304, 7942, 794, 8007, 1982, 8007, 1366, 8326, 3105, 8336,
+ 4810, 8708, 7954, 8989, 2279, 9031, 1055, 9247, 3568, 9283, 1631,
+ 9654, 6311, 9811, 2605, 10120, 683, 10143, 4179, 10245, 1946, 10335,
+ 1218, 10468, 9960, 10651, 3000, 10951, 1530, 10969, 5290, 11203, 2305,
+ 11325, 3562, 11771, 6754, 11839, 1849, 11941, 4495, 11954, 1298, 11975,
+ 15223, 11977, 883, 11986, 2842, 12438, 2141, 12593, 3665, 12636, 8367,
+ 12658, 1594, 12886, 2628, 12984, 4942, 13146, 1115, 13224, 524, 13341,
+ 3163, 13399, 1923, 13549, 5961, 13606, 1401, 13655, 2399, 13782, 3909,
+ 13868, 10923, 14226, 1723, 14232, 2939, 14278, 7528, 14439, 4598, 14451,
+ 984, 14458, 2265, 14792, 1403, 14818, 3445, 14899, 5709, 15017, 15362,
+ 15048, 1946, 15069, 2655, 15405, 9591, 15405, 4079, 15570, 7183, 15687,
+ 2286, 15691, 1624, 15699, 3068, 15772, 5149, 15868, 1205, 15970, 696,
+ 16249, 3584, 16338, 1917, 16424, 2560, 16483, 4438, 16529, 6410, 16620,
+ 11966, 16839, 8780, 17030, 3050, 17033, 18325, 17092, 1568, 17123, 5197,
+ 17351, 2113, 17374, 980, 17566, 26214, 17609, 3912, 17639, 32767, 18151,
+ 7871, 18197, 2516, 18202, 5649, 18679, 3283, 18930, 1370, 19271, 13757,
+ 19317, 4120, 19460, 1973, 19654, 10018, 19764, 6792, 19912, 5135, 20040,
+ 2841, 21234, 19833};
+
+/* ACELP: factor table for interpolation of LPC coeffs in LSP domain */
+const FIXP_SGL lsp_interpol_factor[2][NB_SUBFR] = {
+ {FL2FXCONST_SGL(0.125f), FL2FXCONST_SGL(0.375f), FL2FXCONST_SGL(0.625f),
+ FL2FXCONST_SGL(0.875f)}, /* for coreCoderFrameLength = 1024 */
+ {FL2FXCONST_SGL(0.166667f), FL2FXCONST_SGL(0.5f), FL2FXCONST_SGL(0.833333f),
+ 0x0} /* for coreCoderFrameLength = 768 */
+};
+
+/* For bass post filter */
+#ifndef TABLE_filt_lp
+const FIXP_SGL fdk_dec_filt_lp[1 + L_FILT] = {
+ FL2FXCONST_SGL_FILT(0.088250f), FL2FXCONST_SGL_FILT(0.086410f),
+ FL2FXCONST_SGL_FILT(0.081074f), FL2FXCONST_SGL_FILT(0.072768f),
+ FL2FXCONST_SGL_FILT(0.062294f), FL2FXCONST_SGL_FILT(0.050623f),
+ FL2FXCONST_SGL_FILT(0.038774f), FL2FXCONST_SGL_FILT(0.027692f),
+ FL2FXCONST_SGL_FILT(0.018130f), FL2FXCONST_SGL_FILT(0.010578f),
+ FL2FXCONST_SGL_FILT(0.005221f), FL2FXCONST_SGL_FILT(0.001946f),
+ FL2FXCONST_SGL_FILT(0.000385f)};
+#endif
+
+/* FAC window tables for coreCoderFrameLength = 1024 */
+const FIXP_WTB FacWindowSynth128[] = {
+ WTC(0x7fff6216), WTC(0x7ffa72d1), WTC(0x7ff09478), WTC(0x7fe1c76b),
+ WTC(0x7fce0c3e), WTC(0x7fb563b3), WTC(0x7f97cebd), WTC(0x7f754e80),
+ WTC(0x7f4de451), WTC(0x7f2191b4), WTC(0x7ef05860), WTC(0x7eba3a39),
+ WTC(0x7e7f3957), WTC(0x7e3f57ff), WTC(0x7dfa98a8), WTC(0x7db0fdf8),
+ WTC(0x7d628ac6), WTC(0x7d0f4218), WTC(0x7cb72724), WTC(0x7c5a3d50),
+ WTC(0x7bf88830), WTC(0x7b920b89), WTC(0x7b26cb4f), WTC(0x7ab6cba4),
+ WTC(0x7a4210d8), WTC(0x79c89f6e), WTC(0x794a7c12), WTC(0x78c7aba2),
+ WTC(0x78403329), WTC(0x77b417df), WTC(0x77235f2d), WTC(0x768e0ea6),
+ WTC(0x75f42c0b), WTC(0x7555bd4c), WTC(0x74b2c884), WTC(0x740b53fb),
+ WTC(0x735f6626), WTC(0x72af05a7), WTC(0x71fa3949), WTC(0x71410805),
+ WTC(0x708378ff), WTC(0x6fc19385), WTC(0x6efb5f12), WTC(0x6e30e34a),
+ WTC(0x6d6227fa), WTC(0x6c8f351c), WTC(0x6bb812d1), WTC(0x6adcc964),
+ WTC(0x69fd614a), WTC(0x6919e320), WTC(0x683257ab), WTC(0x6746c7d8),
+ WTC(0x66573cbb), WTC(0x6563bf92), WTC(0x646c59bf), WTC(0x637114cc),
+ WTC(0x6271fa69), WTC(0x616f146c), WTC(0x60686ccf), WTC(0x5f5e0db3),
+ WTC(0x5e50015d), WTC(0x5d3e5237), WTC(0x5c290acc), WTC(0x5b1035cf),
+ WTC(0x59f3de12), WTC(0x58d40e8c), WTC(0x57b0d256), WTC(0x568a34a9),
+ WTC(0x556040e2), WTC(0x5433027d), WTC(0x53028518), WTC(0x51ced46e),
+ WTC(0x5097fc5e), WTC(0x4f5e08e3), WTC(0x4e210617), WTC(0x4ce10034),
+ WTC(0x4b9e0390), WTC(0x4a581c9e), WTC(0x490f57ee), WTC(0x47c3c22f),
+ WTC(0x46756828), WTC(0x452456bd), WTC(0x43d09aed), WTC(0x427a41d0),
+ WTC(0x4121589b), WTC(0x3fc5ec98), WTC(0x3e680b2c), WTC(0x3d07c1d6),
+ WTC(0x3ba51e29), WTC(0x3a402dd2), WTC(0x38d8fe93), WTC(0x376f9e46),
+ WTC(0x36041ad9), WTC(0x34968250), WTC(0x3326e2c3), WTC(0x31b54a5e),
+ WTC(0x3041c761), WTC(0x2ecc681e), WTC(0x2d553afc), WTC(0x2bdc4e6f),
+ WTC(0x2a61b101), WTC(0x28e5714b), WTC(0x27679df4), WTC(0x25e845b6),
+ WTC(0x24677758), WTC(0x22e541af), WTC(0x2161b3a0), WTC(0x1fdcdc1b),
+ WTC(0x1e56ca1e), WTC(0x1ccf8cb3), WTC(0x1b4732ef), WTC(0x19bdcbf3),
+ WTC(0x183366e9), WTC(0x16a81305), WTC(0x151bdf86), WTC(0x138edbb1),
+ WTC(0x120116d5), WTC(0x1072a048), WTC(0x0ee38766), WTC(0x0d53db92),
+ WTC(0x0bc3ac35), WTC(0x0a3308bd), WTC(0x08a2009a), WTC(0x0710a345),
+ WTC(0x057f0035), WTC(0x03ed26e6), WTC(0x025b26d7), WTC(0x00c90f88),
+};
+const FIXP_WTB FacWindowZir128[] = {
+ WTC(0x7f36f078), WTC(0x7da4d929), WTC(0x7c12d91a), WTC(0x7a80ffcb),
+ WTC(0x78ef5cbb), WTC(0x775dff66), WTC(0x75ccf743), WTC(0x743c53cb),
+ WTC(0x72ac246e), WTC(0x711c789a), WTC(0x6f8d5fb8), WTC(0x6dfee92b),
+ WTC(0x6c71244f), WTC(0x6ae4207a), WTC(0x6957ecfb), WTC(0x67cc9917),
+ WTC(0x6642340d), WTC(0x64b8cd11), WTC(0x6330734d), WTC(0x61a935e2),
+ WTC(0x602323e5), WTC(0x5e9e4c60), WTC(0x5d1abe51), WTC(0x5b9888a8),
+ WTC(0x5a17ba4a), WTC(0x5898620c), WTC(0x571a8eb5), WTC(0x559e4eff),
+ WTC(0x5423b191), WTC(0x52aac504), WTC(0x513397e2), WTC(0x4fbe389f),
+ WTC(0x4e4ab5a2), WTC(0x4cd91d3d), WTC(0x4b697db0), WTC(0x49fbe527),
+ WTC(0x489061ba), WTC(0x4727016d), WTC(0x45bfd22e), WTC(0x445ae1d7),
+ WTC(0x42f83e2a), WTC(0x4197f4d4), WTC(0x403a1368), WTC(0x3edea765),
+ WTC(0x3d85be30), WTC(0x3c2f6513), WTC(0x3adba943), WTC(0x398a97d8),
+ WTC(0x383c3dd1), WTC(0x36f0a812), WTC(0x35a7e362), WTC(0x3461fc70),
+ WTC(0x331effcc), WTC(0x31def9e9), WTC(0x30a1f71d), WTC(0x2f6803a2),
+ WTC(0x2e312b92), WTC(0x2cfd7ae8), WTC(0x2bccfd83), WTC(0x2a9fbf1e),
+ WTC(0x2975cb57), WTC(0x284f2daa), WTC(0x272bf174), WTC(0x260c21ee),
+ WTC(0x24efca31), WTC(0x23d6f534), WTC(0x22c1adc9), WTC(0x21affea3),
+ WTC(0x20a1f24d), WTC(0x1f979331), WTC(0x1e90eb94), WTC(0x1d8e0597),
+ WTC(0x1c8eeb34), WTC(0x1b93a641), WTC(0x1a9c406e), WTC(0x19a8c345),
+ WTC(0x18b93828), WTC(0x17cda855), WTC(0x16e61ce0), WTC(0x16029eb6),
+ WTC(0x1523369c), WTC(0x1447ed2f), WTC(0x1370cae4), WTC(0x129dd806),
+ WTC(0x11cf1cb6), WTC(0x1104a0ee), WTC(0x103e6c7b), WTC(0x0f7c8701),
+ WTC(0x0ebef7fb), WTC(0x0e05c6b7), WTC(0x0d50fa59), WTC(0x0ca099da),
+ WTC(0x0bf4ac05), WTC(0x0b4d377c), WTC(0x0aaa42b4), WTC(0x0a0bd3f5),
+ WTC(0x0971f15a), WTC(0x08dca0d3), WTC(0x084be821), WTC(0x07bfccd7),
+ WTC(0x0738545e), WTC(0x06b583ee), WTC(0x06376092), WTC(0x05bdef28),
+ WTC(0x0549345c), WTC(0x04d934b1), WTC(0x046df477), WTC(0x040777d0),
+ WTC(0x03a5c2b0), WTC(0x0348d8dc), WTC(0x02f0bde8), WTC(0x029d753a),
+ WTC(0x024f0208), WTC(0x02056758), WTC(0x01c0a801), WTC(0x0180c6a9),
+ WTC(0x0145c5c7), WTC(0x010fa7a0), WTC(0x00de6e4c), WTC(0x00b21baf),
+ WTC(0x008ab180), WTC(0x00683143), WTC(0x004a9c4d), WTC(0x0031f3c2),
+ WTC(0x001e3895), WTC(0x000f6b88), WTC(0x00058d2f), WTC(0x00009dea),
+};
+const FIXP_WTB FacWindowSynth64[] = {
+ WTC(0x7ffd885a), WTC(0x7fe9cbc0), WTC(0x7fc25596), WTC(0x7f872bf3),
+ WTC(0x7f3857f6), WTC(0x7ed5e5c6), WTC(0x7e5fe493), WTC(0x7dd6668f),
+ WTC(0x7d3980ec), WTC(0x7c894bde), WTC(0x7bc5e290), WTC(0x7aef6323),
+ WTC(0x7a05eead), WTC(0x7909a92d), WTC(0x77fab989), WTC(0x76d94989),
+ WTC(0x75a585cf), WTC(0x745f9dd1), WTC(0x7307c3d0), WTC(0x719e2cd2),
+ WTC(0x7023109a), WTC(0x6e96a99d), WTC(0x6cf934fc), WTC(0x6b4af279),
+ WTC(0x698c246c), WTC(0x67bd0fbd), WTC(0x65ddfbd3), WTC(0x63ef3290),
+ WTC(0x61f1003f), WTC(0x5fe3b38d), WTC(0x5dc79d7c), WTC(0x5b9d1154),
+ WTC(0x59646498), WTC(0x571deefa), WTC(0x54ca0a4b), WTC(0x5269126e),
+ WTC(0x4ffb654d), WTC(0x4d8162c4), WTC(0x4afb6c98), WTC(0x4869e665),
+ WTC(0x45cd358f), WTC(0x4325c135), WTC(0x4073f21d), WTC(0x3db832a6),
+ WTC(0x3af2eeb7), WTC(0x382493b0), WTC(0x354d9057), WTC(0x326e54c7),
+ WTC(0x2f875262), WTC(0x2c98fbba), WTC(0x29a3c485), WTC(0x26a82186),
+ WTC(0x23a6887f), WTC(0x209f701c), WTC(0x1d934fe5), WTC(0x1a82a026),
+ WTC(0x176dd9de), WTC(0x145576b1), WTC(0x1139f0cf), WTC(0x0e1bc2e4),
+ WTC(0x0afb6805), WTC(0x07d95b9e), WTC(0x04b6195d), WTC(0x01921d20),
+};
+const FIXP_WTB FacWindowZir64[] = {
+ WTC(0x7e6de2e0), WTC(0x7b49e6a3), WTC(0x7826a462), WTC(0x750497fb),
+ WTC(0x71e43d1c), WTC(0x6ec60f31), WTC(0x6baa894f), WTC(0x68922622),
+ WTC(0x657d5fda), WTC(0x626cb01b), WTC(0x5f608fe4), WTC(0x5c597781),
+ WTC(0x5957de7a), WTC(0x565c3b7b), WTC(0x53670446), WTC(0x5078ad9e),
+ WTC(0x4d91ab39), WTC(0x4ab26fa9), WTC(0x47db6c50), WTC(0x450d1149),
+ WTC(0x4247cd5a), WTC(0x3f8c0de3), WTC(0x3cda3ecb), WTC(0x3a32ca71),
+ WTC(0x3796199b), WTC(0x35049368), WTC(0x327e9d3c), WTC(0x30049ab3),
+ WTC(0x2d96ed92), WTC(0x2b35f5b5), WTC(0x28e21106), WTC(0x269b9b68),
+ WTC(0x2462eeac), WTC(0x22386284), WTC(0x201c4c73), WTC(0x1e0effc1),
+ WTC(0x1c10cd70), WTC(0x1a22042d), WTC(0x1842f043), WTC(0x1673db94),
+ WTC(0x14b50d87), WTC(0x1306cb04), WTC(0x11695663), WTC(0x0fdcef66),
+ WTC(0x0e61d32e), WTC(0x0cf83c30), WTC(0x0ba0622f), WTC(0x0a5a7a31),
+ WTC(0x0926b677), WTC(0x08054677), WTC(0x06f656d3), WTC(0x05fa1153),
+ WTC(0x05109cdd), WTC(0x043a1d70), WTC(0x0376b422), WTC(0x02c67f14),
+ WTC(0x02299971), WTC(0x01a01b6d), WTC(0x012a1a3a), WTC(0x00c7a80a),
+ WTC(0x0078d40d), WTC(0x003daa6a), WTC(0x00163440), WTC(0x000277a6),
+};
+const FIXP_WTB FacWindowSynth32[] = {
+ WTC(0x7ff62182), WTC(0x7fa736b4), WTC(0x7f0991c4), WTC(0x7e1d93ea),
+ WTC(0x7ce3ceb2), WTC(0x7b5d039e), WTC(0x798a23b1), WTC(0x776c4edb),
+ WTC(0x7504d345), WTC(0x72552c85), WTC(0x6f5f02b2), WTC(0x6c242960),
+ WTC(0x68a69e81), WTC(0x64e88926), WTC(0x60ec3830), WTC(0x5cb420e0),
+ WTC(0x5842dd54), WTC(0x539b2af0), WTC(0x4ebfe8a5), WTC(0x49b41533),
+ WTC(0x447acd50), WTC(0x3f1749b8), WTC(0x398cdd32), WTC(0x33def287),
+ WTC(0x2e110a62), WTC(0x2826b928), WTC(0x2223a4c5), WTC(0x1c0b826a),
+ WTC(0x15e21445), WTC(0x0fab272b), WTC(0x096a9049), WTC(0x03242abf),
+};
+const FIXP_WTB FacWindowZir32[] = {
+ WTC(0x7cdbd541), WTC(0x76956fb7), WTC(0x7054d8d5), WTC(0x6a1debbb),
+ WTC(0x63f47d96), WTC(0x5ddc5b3b), WTC(0x57d946d8), WTC(0x51eef59e),
+ WTC(0x4c210d79), WTC(0x467322ce), WTC(0x40e8b648), WTC(0x3b8532b0),
+ WTC(0x364beacd), WTC(0x3140175b), WTC(0x2c64d510), WTC(0x27bd22ac),
+ WTC(0x234bdf20), WTC(0x1f13c7d0), WTC(0x1b1776da), WTC(0x1759617f),
+ WTC(0x13dbd6a0), WTC(0x10a0fd4e), WTC(0x0daad37b), WTC(0x0afb2cbb),
+ WTC(0x0893b125), WTC(0x0675dc4f), WTC(0x04a2fc62), WTC(0x031c314e),
+ WTC(0x01e26c16), WTC(0x00f66e3c), WTC(0x0058c94c), WTC(0x0009de7e),
+};
+
+/* FAC window tables for coreCoderFrameLength = 768 */
+const FIXP_WTB FacWindowSynth96[] = {
+ WTC(0x7ffee744), WTC(0x7ff62182), WTC(0x7fe49698), WTC(0x7fca47b9),
+ WTC(0x7fa736b4), WTC(0x7f7b65ef), WTC(0x7f46d86c), WTC(0x7f0991c4),
+ WTC(0x7ec3962a), WTC(0x7e74ea6a), WTC(0x7e1d93ea), WTC(0x7dbd98a4),
+ WTC(0x7d54ff2e), WTC(0x7ce3ceb2), WTC(0x7c6a0ef2), WTC(0x7be7c847),
+ WTC(0x7b5d039e), WTC(0x7ac9ca7a), WTC(0x7a2e26f2), WTC(0x798a23b1),
+ WTC(0x78ddcbf5), WTC(0x78292b8d), WTC(0x776c4edb), WTC(0x76a742d1),
+ WTC(0x75da14ef), WTC(0x7504d345), WTC(0x74278c72), WTC(0x73424fa0),
+ WTC(0x72552c85), WTC(0x71603361), WTC(0x706374ff), WTC(0x6f5f02b2),
+ WTC(0x6e52ee52), WTC(0x6d3f4a40), WTC(0x6c242960), WTC(0x6b019f1a),
+ WTC(0x69d7bf57), WTC(0x68a69e81), WTC(0x676e5183), WTC(0x662eedc3),
+ WTC(0x64e88926), WTC(0x639b3a0b), WTC(0x62471749), WTC(0x60ec3830),
+ WTC(0x5f8ab487), WTC(0x5e22a487), WTC(0x5cb420e0), WTC(0x5b3f42ae),
+ WTC(0x59c42381), WTC(0x5842dd54), WTC(0x56bb8a90), WTC(0x552e4605),
+ WTC(0x539b2af0), WTC(0x520254ef), WTC(0x5063e008), WTC(0x4ebfe8a5),
+ WTC(0x4d168b8b), WTC(0x4b67e5e4), WTC(0x49b41533), WTC(0x47fb3757),
+ WTC(0x463d6a87), WTC(0x447acd50), WTC(0x42b37e96), WTC(0x40e79d8c),
+ WTC(0x3f1749b8), WTC(0x3d42a2ec), WTC(0x3b69c947), WTC(0x398cdd32),
+ WTC(0x37abff5d), WTC(0x35c750bc), WTC(0x33def287), WTC(0x31f30638),
+ WTC(0x3003ad85), WTC(0x2e110a62), WTC(0x2c1b3efb), WTC(0x2a226db5),
+ WTC(0x2826b928), WTC(0x26284422), WTC(0x2427319d), WTC(0x2223a4c5),
+ WTC(0x201dc0ef), WTC(0x1e15a99a), WTC(0x1c0b826a), WTC(0x19ff6f2a),
+ WTC(0x17f193c5), WTC(0x15e21445), WTC(0x13d114d0), WTC(0x11beb9aa),
+ WTC(0x0fab272b), WTC(0x0d9681c2), WTC(0x0b80edf1), WTC(0x096a9049),
+ WTC(0x07538d6b), WTC(0x053c0a01), WTC(0x03242abf), WTC(0x010c1460),
+};
+const FIXP_WTB FacWindowZir96[] = {
+ WTC(0x7ef3eba0), WTC(0x7cdbd541), WTC(0x7ac3f5ff), WTC(0x78ac7295),
+ WTC(0x76956fb7), WTC(0x747f120f), WTC(0x72697e3e), WTC(0x7054d8d5),
+ WTC(0x6e414656), WTC(0x6c2eeb30), WTC(0x6a1debbb), WTC(0x680e6c3b),
+ WTC(0x660090d6), WTC(0x63f47d96), WTC(0x61ea5666), WTC(0x5fe23f11),
+ WTC(0x5ddc5b3b), WTC(0x5bd8ce63), WTC(0x59d7bbde), WTC(0x57d946d8),
+ WTC(0x55dd924b), WTC(0x53e4c105), WTC(0x51eef59e), WTC(0x4ffc527b),
+ WTC(0x4e0cf9c8), WTC(0x4c210d79), WTC(0x4a38af44), WTC(0x485400a3),
+ WTC(0x467322ce), WTC(0x449636b9), WTC(0x42bd5d14), WTC(0x40e8b648),
+ WTC(0x3f186274), WTC(0x3d4c816a), WTC(0x3b8532b0), WTC(0x39c29579),
+ WTC(0x3804c8a9), WTC(0x364beacd), WTC(0x34981a1c), WTC(0x32e97475),
+ WTC(0x3140175b), WTC(0x2f9c1ff8), WTC(0x2dfdab11), WTC(0x2c64d510),
+ WTC(0x2ad1b9fb), WTC(0x29447570), WTC(0x27bd22ac), WTC(0x263bdc7f),
+ WTC(0x24c0bd52), WTC(0x234bdf20), WTC(0x21dd5b79), WTC(0x20754b79),
+ WTC(0x1f13c7d0), WTC(0x1db8e8b7), WTC(0x1c64c5f5), WTC(0x1b1776da),
+ WTC(0x19d1123d), WTC(0x1891ae7d), WTC(0x1759617f), WTC(0x162840a9),
+ WTC(0x14fe60e6), WTC(0x13dbd6a0), WTC(0x12c0b5c0), WTC(0x11ad11ae),
+ WTC(0x10a0fd4e), WTC(0x0f9c8b01), WTC(0x0e9fcc9f), WTC(0x0daad37b),
+ WTC(0x0cbdb060), WTC(0x0bd8738e), WTC(0x0afb2cbb), WTC(0x0a25eb11),
+ WTC(0x0958bd2f), WTC(0x0893b125), WTC(0x07d6d473), WTC(0x0722340b),
+ WTC(0x0675dc4f), WTC(0x05d1d90e), WTC(0x05363586), WTC(0x04a2fc62),
+ WTC(0x041837b9), WTC(0x0395f10e), WTC(0x031c314e), WTC(0x02ab00d2),
+ WTC(0x0242675c), WTC(0x01e26c16), WTC(0x018b1596), WTC(0x013c69d6),
+ WTC(0x00f66e3c), WTC(0x00b92794), WTC(0x00849a11), WTC(0x0058c94c),
+ WTC(0x0035b847), WTC(0x001b6968), WTC(0x0009de7e), WTC(0x000118bc),
+};
+const FIXP_WTB FacWindowSynth48[] = {
+ WTC(0x7ffb9d15), WTC(0x7fd8878e), WTC(0x7f92661d), WTC(0x7f294bfd),
+ WTC(0x7e9d55fc), WTC(0x7deeaa7a), WTC(0x7d1d7958), WTC(0x7c29fbee),
+ WTC(0x7b1474fd), WTC(0x79dd3098), WTC(0x78848414), WTC(0x770acdec),
+ WTC(0x757075ac), WTC(0x73b5ebd1), WTC(0x71dba9ab), WTC(0x6fe2313c),
+ WTC(0x6dca0d14), WTC(0x6b93d02e), WTC(0x694015c3), WTC(0x66cf8120),
+ WTC(0x6442bd7e), WTC(0x619a7dce), WTC(0x5ed77c8a), WTC(0x5bfa7b82),
+ WTC(0x590443a7), WTC(0x55f5a4d2), WTC(0x52cf758f), WTC(0x4f9292dc),
+ WTC(0x4c3fdff4), WTC(0x48d84609), WTC(0x455cb40c), WTC(0x41ce1e65),
+ WTC(0x3e2d7eb1), WTC(0x3a7bd382), WTC(0x36ba2014), WTC(0x32e96c09),
+ WTC(0x2f0ac320), WTC(0x2b1f34eb), WTC(0x2727d486), WTC(0x2325b847),
+ WTC(0x1f19f97b), WTC(0x1b05b40f), WTC(0x16ea0646), WTC(0x12c8106f),
+ WTC(0x0ea0f48c), WTC(0x0a75d60e), WTC(0x0647d97c), WTC(0x02182427),
+};
+const FIXP_WTB FacWindowZir48[] = {
+ WTC(0x7de7dbd9), WTC(0x79b82684), WTC(0x758a29f2), WTC(0x715f0b74),
+ WTC(0x6d37ef91), WTC(0x6915f9ba), WTC(0x64fa4bf1), WTC(0x60e60685),
+ WTC(0x5cda47b9), WTC(0x58d82b7a), WTC(0x54e0cb15), WTC(0x50f53ce0),
+ WTC(0x4d1693f7), WTC(0x4945dfec), WTC(0x45842c7e), WTC(0x41d2814f),
+ WTC(0x3e31e19b), WTC(0x3aa34bf4), WTC(0x3727b9f7), WTC(0x33c0200c),
+ WTC(0x306d6d24), WTC(0x2d308a71), WTC(0x2a0a5b2e), WTC(0x26fbbc59),
+ WTC(0x2405847e), WTC(0x21288376), WTC(0x1e658232), WTC(0x1bbd4282),
+ WTC(0x19307ee0), WTC(0x16bfea3d), WTC(0x146c2fd2), WTC(0x1235f2ec),
+ WTC(0x101dcec4), WTC(0x0e245655), WTC(0x0c4a142f), WTC(0x0a8f8a54),
+ WTC(0x08f53214), WTC(0x077b7bec), WTC(0x0622cf68), WTC(0x04eb8b03),
+ WTC(0x03d60412), WTC(0x02e286a8), WTC(0x02115586), WTC(0x0162aa04),
+ WTC(0x00d6b403), WTC(0x006d99e3), WTC(0x00277872), WTC(0x000462eb),
+};
diff --git a/fdk-aac/libAACdec/src/usacdec_rom.h b/fdk-aac/libAACdec/src/usacdec_rom.h
new file mode 100644
index 0000000..f969e90
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_rom.h
@@ -0,0 +1,154 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): M. Jander
+
+ Description: re8.h
+
+*******************************************************************************/
+
+#ifndef USACDEC_ROM_H
+#define USACDEC_ROM_H
+
+#include "common_fix.h"
+#include "FDK_lpc.h"
+
+#include "usacdec_const.h"
+
+/* RE8 lattice quantiser constants */
+#define NB_SPHERE 32
+#define NB_LEADER 37
+#define NB_LDSIGN 226
+#define NB_LDQ3 9
+#define NB_LDQ4 28
+
+#define LSF_SCALE 13
+
+/* RE8 lattice quantiser tables */
+extern const UINT fdk_dec_tab_factorial[8];
+extern const UCHAR fdk_dec_Ia[NB_LEADER];
+extern const UCHAR fdk_dec_Ds[NB_LDSIGN];
+extern const USHORT fdk_dec_Is[NB_LDSIGN];
+extern const UCHAR fdk_dec_Ns[], fdk_dec_A3[], fdk_dec_A4[];
+extern const UCHAR fdk_dec_Da[][8];
+extern const USHORT fdk_dec_I3[], fdk_dec_I4[];
+
+/* temp float tables for LPC decoding */
+extern const FIXP_LPC fdk_dec_lsf_init[16];
+extern const FIXP_LPC fdk_dec_dico_lsf_abs_8b[16 * 256];
+
+/* ACELP tables */
+#define SF_QUA_GAIN7B 4
+extern const FIXP_SGL fdk_t_qua_gain7b[128 * 2];
+extern const FIXP_SGL lsp_interpol_factor[2][NB_SUBFR];
+
+/* For bass post filter */
+#define L_FILT 12 /* Delay of up-sampling filter */
+
+extern const FIXP_SGL fdk_dec_filt_lp[1 + L_FILT];
+
+extern const FIXP_WTB FacWindowSynth128[128];
+extern const FIXP_WTB FacWindowZir128[128];
+extern const FIXP_WTB FacWindowSynth64[64];
+extern const FIXP_WTB FacWindowZir64[64];
+extern const FIXP_WTB FacWindowSynth32[32];
+extern const FIXP_WTB FacWindowZir32[32];
+extern const FIXP_WTB FacWindowSynth96[96];
+extern const FIXP_WTB FacWindowZir96[96];
+extern const FIXP_WTB FacWindowSynth48[48];
+extern const FIXP_WTB FacWindowZir48[48];
+
+#endif /* USACDEC_ROM_H */
diff --git a/fdk-aac/libAACenc/include/aacenc_lib.h b/fdk-aac/libAACenc/include/aacenc_lib.h
new file mode 100644
index 0000000..231bbb4
--- /dev/null
+++ b/fdk-aac/libAACenc/include/aacenc_lib.h
@@ -0,0 +1,1733 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description:
+
+*******************************************************************************/
+
+/**
+ * \file aacenc_lib.h
+ * \brief FDK AAC Encoder library interface header file.
+ *
+\mainpage Introduction
+
+\section Scope
+
+This document describes the high-level interface and usage of the ISO/MPEG-2/4
+AAC Encoder library developed by the Fraunhofer Institute for Integrated
+Circuits (IIS).
+
+The library implements encoding on the basis of the MPEG-2 and MPEG-4 AAC
+Low-Complexity standard, and depending on the library's configuration, MPEG-4
+High-Efficiency AAC v2 and/or AAC-ELD standard.
+
+All references to SBR (Spectral Band Replication) are only applicable to HE-AAC
+or AAC-ELD versions of the library. All references to PS (Parametric Stereo) are
+only applicable to HE-AAC v2 versions of the library.
+
+\section encBasics Encoder Basics
+
+This document can only give a rough overview about the ISO/MPEG-2 and ISO/MPEG-4
+AAC audio coding standard. To understand all the terms in this document, you are
+encouraged to read the following documents.
+
+- ISO/IEC 13818-7 (MPEG-2 AAC), which defines the syntax of MPEG-2 AAC audio
+bitstreams.
+- ISO/IEC 14496-3 (MPEG-4 AAC, subparts 1 and 4), which defines the syntax of
+MPEG-4 AAC audio bitstreams.
+- Lutzky, Schuller, Gayer, Kr&auml;mer, Wabnik, "A guideline to audio codec
+delay", 116th AES Convention, May 8, 2004
+
+MPEG Advanced Audio Coding is based on a time-to-frequency mapping of the
+signal. The signal is partitioned into overlapping portions and transformed into
+frequency domain. The spectral components are then quantized and coded. \n An
+MPEG-2 or MPEG-4 AAC audio bitstream is composed of frames. Contrary to MPEG-1/2
+Layer-3 (mp3), the length of individual frames is not restricted to a fixed
+number of bytes, but can take on any length between 1 and 768 bytes.
+
+
+\page LIBUSE Library Usage
+
+\section InterfaceDescription API Files
+
+All API header files are located in the folder /include of the release package.
+All header files are provided for usage in C/C++ programs. The AAC encoder
+library API functions are located in aacenc_lib.h.
+
+In binary releases the encoder core resides in statically linkable libraries
+called for example libAACenc.a/libFDK.a (LINUX) or FDK_fastaaclib.lib (MS Visual
+C++) for the plain AAC-LC core encoder and libSBRenc.a (LINUX) or
+FDK_sbrEncLib.lib (MS Visual C++) for the SBR (Spectral Band Replication) and PS
+(Parametric Stereo) modules.
+
+\section CallingSequence Calling Sequence
+
+For encoding of ISO/MPEG-2/4 AAC bitstreams the following sequence is mandatory.
+Input read and output write functions as well as the corresponding open and
+close functions are left out, since they may be implemented differently
+according to the user's specific requirements. The example implementation uses
+file-based input/output.
+
+-# Call aacEncOpen() to allocate encoder instance with required \ref encOpen
+"configuration". \code HANDLE_AACENCODER hAacEncoder = NULL; if ( (ErrorStatus =
+aacEncOpen(&hAacEncoder,0,0)) != AACENC_OK ) { \endcode
+-# Call aacEncoder_SetParam() for each parameter to be set. AOT, samplingrate,
+channelMode, bitrate and transport type are \ref encParams "mandatory". \code
+ErrorStatus = aacEncoder_SetParam(hAacEncoder, parameter, value);
+\endcode
+-# Call aacEncEncode() with NULL parameters to \ref encReconf "initialize"
+encoder instance with present parameter set. \code ErrorStatus =
+aacEncEncode(hAacEncoder, NULL, NULL, NULL, NULL); \endcode
+-# Call aacEncInfo() to retrieve a configuration data block to be transmitted
+out of band. This is required when using RFC3640 or RFC3016 like transport.
+\code
+AACENC_InfoStruct encInfo;
+aacEncInfo(hAacEncoder, &encInfo);
+\endcode
+-# Encode input audio data in loop.
+\code
+do
+{
+\endcode
+Feed \ref feedInBuf "input buffer" with new audio data and provide input/output
+\ref bufDes "arguments" to aacEncEncode(). \code ErrorStatus =
+aacEncEncode(hAacEncoder, &inBufDesc, &outBufDesc, &inargs, &outargs); \endcode
+Write \ref writeOutData "output data" to file or audio device.
+\code
+} while (ErrorStatus==AACENC_OK);
+\endcode
+-# Call aacEncClose() and destroy encoder instance.
+\code
+aacEncClose(&hAacEncoder);
+\endcode
+
+
+\section encOpen Encoder Instance Allocation
+
+The assignment of the aacEncOpen() function is very flexible and can be used in
+the following way.
+- If the amount of memory consumption is not an issue, the encoder instance can
+be allocated for the maximum number of possible audio channels (for example 6 or
+8) with the full functional range supported by the library. This is the default
+open procedure for the AAC encoder if memory consumption does not need to be
+minimized. \code aacEncOpen(&hAacEncoder,0,0) \endcode
+- If the required MPEG-4 AOTs do not call for the full functional range of the
+library, encoder modules can be allocated selectively. \verbatim
+------------------------------------------------------
+ AAC | SBR | PS | MD | FLAGS | value
+-----+-----+-----+----+-----------------------+-------
+ X | - | - | - | (0x01) | 0x01
+ X | X | - | - | (0x01|0x02) | 0x03
+ X | X | X | - | (0x01|0x02|0x04) | 0x07
+ X | - | - | X | (0x01 |0x10) | 0x11
+ X | X | - | X | (0x01|0x02 |0x10) | 0x13
+ X | X | X | X | (0x01|0x02|0x04|0x10) | 0x17
+------------------------------------------------------
+ - AAC: Allocate AAC Core Encoder module.
+ - SBR: Allocate Spectral Band Replication module.
+ - PS: Allocate Parametric Stereo module.
+ - MD: Allocate Meta Data module within AAC encoder.
+\endverbatim
+\code aacEncOpen(&hAacEncoder,value,0) \endcode
+- Specifying the maximum number of channels to be supported in the encoder
+instance can be done as follows.
+ - For example allocate an encoder instance which supports 2 channels for all
+supported AOTs. The library itself may be capable of encoding up to 6 or 8
+channels but in this example only 2 channel encoding is required and thus only
+buffers for 2 channels are allocated to save data memory. \code
+aacEncOpen(&hAacEncoder,0,2) \endcode
+ - Additionally the maximum number of supported channels in the SBR module can
+be denoted separately.\n In this example the encoder instance provides a maximum
+of 6 channels out of which up to 2 channels support SBR. This encoder instance
+can produce for example 5.1 channel AAC-LC streams or stereo HE-AAC (v2)
+streams. HE-AAC 5.1 multi channel is not possible since only 2 out of 6 channels
+support SBR, which saves data memory. \code aacEncOpen(&hAacEncoder,0,6|(2<<8))
+\endcode \n
+
+\section bufDes Input/Output Arguments
+
+\subsection allocIOBufs Provide Buffer Descriptors
+In the present encoder API, the input and output buffers are described with \ref
+AACENC_BufDesc "buffer descriptors". This mechanism allows a flexible handling
+of input and output buffers without impact to the actual encoding call. Optional
+buffers are necessary e.g. for ancillary data, meta data input or additional
+output buffers describing superframing data in DAB+ or DRM+.\n At least one
+input buffer for audio input data and one output buffer for bitstream data must
+be allocated. The input buffer size can be a user defined multiple of the number
+of input channels. PCM input data will be copied from the user defined PCM
+buffer to an internal input buffer and so input data can be less than one AAC
+audio frame. The output buffer size should be 6144 bits per channel excluding
+the LFE channel. If the output data does not fit into the provided buffer, an
+AACENC_ERROR will be returned by aacEncEncode(). \code static INT_PCM
+inputBuffer[8*2048]; static UCHAR ancillaryBuffer[50]; static
+AACENC_MetaData metaDataSetup; static UCHAR outputBuffer[8192];
+\endcode
+
+All input and output buffer must be clustered in input and output buffer arrays.
+\code
+static void* inBuffer[] = { inputBuffer, ancillaryBuffer, &metaDataSetup
+}; static INT inBufferIds[] = { IN_AUDIO_DATA, IN_ANCILLRY_DATA,
+IN_METADATA_SETUP }; static INT inBufferSize[] = { sizeof(inputBuffer),
+sizeof(ancillaryBuffer), sizeof(metaDataSetup) }; static INT inBufferElSize[]
+= { sizeof(INT_PCM), sizeof(UCHAR), sizeof(AACENC_MetaData) };
+
+static void* outBuffer[] = { outputBuffer };
+static INT outBufferIds[] = { OUT_BITSTREAM_DATA };
+static INT outBufferSize[] = { sizeof(outputBuffer) };
+static INT outBufferElSize[] = { sizeof(UCHAR) };
+\endcode
+
+Allocate buffer descriptors
+\code
+AACENC_BufDesc inBufDesc;
+AACENC_BufDesc outBufDesc;
+\endcode
+
+Initialize input buffer descriptor
+\code
+inBufDesc.numBufs = sizeof(inBuffer)/sizeof(void*);
+inBufDesc.bufs = (void**)&inBuffer;
+inBufDesc.bufferIdentifiers = inBufferIds;
+inBufDesc.bufSizes = inBufferSize;
+inBufDesc.bufElSizes = inBufferElSize;
+\endcode
+
+Initialize output buffer descriptor
+\code
+outBufDesc.numBufs = sizeof(outBuffer)/sizeof(void*);
+outBufDesc.bufs = (void**)&outBuffer;
+outBufDesc.bufferIdentifiers = outBufferIds;
+outBufDesc.bufSizes = outBufferSize;
+outBufDesc.bufElSizes = outBufferElSize;
+\endcode
+
+\subsection argLists Provide Input/Output Argument Lists
+The input and output arguments of an aacEncEncode() call are described in
+argument structures. \code AACENC_InArgs inargs; AACENC_OutArgs outargs;
+\endcode
+
+\section feedInBuf Feed Input Buffer
+The input buffer should be handled as a modulo buffer. New audio data in the
+form of pulse-code- modulated samples (PCM) must be read from external and be
+fed to the input buffer depending on its fill level. The required sample bitrate
+(represented by the data type INT_PCM which is 16, 24 or 32 bits wide) is fixed
+and depends on library configuration (usually 16 bit). \code inargs.numInSamples
++= WAV_InputRead ( wavIn, &inputBuffer[inargs.numInSamples],
+ FDKmin(encInfo.inputChannels*encInfo.frameLength,
+ sizeof(inputBuffer) /
+ sizeof(INT_PCM)-inargs.numInSamples),
+ SAMPLE_BITS
+ );
+\endcode
+
+After the encoder's internal buffer is fed with incoming audio samples, and
+aacEncEncode() processed the new input data, update/move remaining samples in
+input buffer, simulating a modulo buffer: \code if (outargs.numInSamples>0) {
+ FDKmemmove( inputBuffer,
+ &inputBuffer[outargs.numInSamples],
+ sizeof(INT_PCM)*(inargs.numInSamples-outargs.numInSamples) );
+ inargs.numInSamples -= outargs.numInSamples;
+}
+\endcode
+
+\section writeOutData Output Bitstream Data
+If any AAC bitstream data is available, write it to output file or device. This
+can be done once the following condition is true: \code if
+(outargs.numOutBytes>0) {
+
+}
+\endcode
+
+If you use file I/O then for example call mpegFileWrite_Write() from the library
+libMpegFileWrite \code mpegFileWrite_Write(hMpegFile, outputBuffer,
+outargs.numOutBytes, aacEncoder_GetParam(hAacEncoder, AACENC_GRANULE_LENGTH));
+\endcode
+
+\section cfgMetaData Meta Data Configuration
+
+If the present library is configured with Metadata support, it is possible to
+insert meta data side info into the generated audio bitstream while encoding.
+
+To work with meta data the encoder instance has to be \ref encOpen "allocated"
+with meta data support. The meta data mode must be be configured with the
+::AACENC_METADATA_MODE parameter and aacEncoder_SetParam() function. \code
+aacEncoder_SetParam(hAacEncoder, AACENC_METADATA_MODE, 0-3); \endcode
+
+This configuration indicates how to embed meta data into bitstrem. Either no
+insertion, MPEG or ETSI style. The meta data itself must be specified within the
+meta data setup structure AACENC_MetaData.
+
+Changing one of the AACENC_MetaData setup parameters can be achieved from
+outside the library within ::IN_METADATA_SETUP input buffer. There is no need to
+supply meta data setup structure every frame. If there is no new meta setup data
+available, the encoder uses the previous setup or the default configuration in
+initial state.
+
+In general the audio compressor and limiter within the encoder library can be
+configured with the ::AACENC_METADATA_DRC_PROFILE parameter
+AACENC_MetaData::drc_profile and and AACENC_MetaData::comp_profile.
+\n
+
+\section encReconf Encoder Reconfiguration
+
+The encoder library allows reconfiguration of the encoder instance with new
+settings continuously between encoding frames. Each parameter to be changed must
+be set with a single aacEncoder_SetParam() call. The internal status of each
+parameter can be retrieved with an aacEncoder_GetParam() call.\n There is no
+stand-alone reconfiguration function available. When parameters were modified
+from outside the library, an internal control mechanism triggers the necessary
+reconfiguration process which will be applied at the beginning of the following
+aacEncEncode() call. This state can be observed from external via the
+AACENC_INIT_STATUS and aacEncoder_GetParam() function. The reconfiguration
+process can also be applied immediately when all parameters of an aacEncEncode()
+call are NULL with a valid encoder handle.\n\n The internal reconfiguration
+process can be controlled from extern with the following access. \code
+aacEncoder_SetParam(hAacEncoder, AACENC_CONTROL_STATE, AACENC_CTRLFLAGS);
+\endcode
+
+
+\section encParams Encoder Parametrization
+
+All parameteres listed in ::AACENC_PARAM can be modified within an encoder
+instance.
+
+\subsection encMandatory Mandatory Encoder Parameters
+The following parameters must be specified when the encoder instance is
+initialized. \code aacEncoder_SetParam(hAacEncoder, AACENC_AOT, value);
+aacEncoder_SetParam(hAacEncoder, AACENC_BITRATE, value);
+aacEncoder_SetParam(hAacEncoder, AACENC_SAMPLERATE, value);
+aacEncoder_SetParam(hAacEncoder, AACENC_CHANNELMODE, value);
+\endcode
+Beyond that is an internal auto mode which preinitizializes the ::AACENC_BITRATE
+parameter if the parameter was not set from extern. The bitrate depends on the
+number of effective channels and sampling rate and is determined as follows.
+\code
+AAC-LC (AOT_AAC_LC): 1.5 bits per sample
+HE-AAC (AOT_SBR): 0.625 bits per sample (dualrate sbr)
+HE-AAC (AOT_SBR): 1.125 bits per sample (downsampled sbr)
+HE-AAC v2 (AOT_PS): 0.5 bits per sample
+\endcode
+
+\subsection channelMode Channel Mode Configuration
+The input audio data is described with the ::AACENC_CHANNELMODE parameter in the
+aacEncoder_SetParam() call. It is not possible to use the encoder instance with
+a 'number of input channels' argument. Instead, the channelMode must be set as
+follows. \code aacEncoder_SetParam(hAacEncoder, AACENC_CHANNELMODE, value);
+\endcode The parameter is specified in ::CHANNEL_MODE and can be mapped from the
+number of input channels in the following way. \code CHANNEL_MODE chMode =
+MODE_INVALID;
+
+switch (nChannels) {
+ case 1: chMode = MODE_1; break;
+ case 2: chMode = MODE_2; break;
+ case 3: chMode = MODE_1_2; break;
+ case 4: chMode = MODE_1_2_1; break;
+ case 5: chMode = MODE_1_2_2; break;
+ case 6: chMode = MODE_1_2_2_1; break;
+ case 7: chMode = MODE_6_1; break;
+ case 8: chMode = MODE_7_1_BACK; break;
+ default:
+ chMode = MODE_INVALID;
+}
+return chMode;
+\endcode
+
+\subsection bitreservoir Bitreservoir Configuration
+In AAC, the default bitreservoir configuration depends on the chosen bitrate per
+frame and the number of effective channels. The size can be determined as below.
+\f[
+bitreservoir = nEffChannels*6144 - (bitrate*framelength/samplerate)
+\f]
+Due to audio quality concerns it is not recommended to change the bitreservoir
+size to a lower value than the default setting! However, for minimizing the
+delay for streaming applications or for achieving a constant size of the
+bitstream packages in each frame, it may be necessaray to change the
+bitreservoir size. This can be done with the ::AACENC_PEAK_BITRATE parameter.
+\code
+aacEncoder_SetParam(hAacEncoder, AACENC_PEAK_BITRATE, value);
+\endcode
+By setting ::AACENC_BITRATEMODE to fixed framing, the bitreservoir is disabled.
+A disabled bitreservoir results in a constant size for each bitstream package.
+Please note that especially at lower bitrates a disabled bitreservoir can
+downgrade the audio quality considerably! The default bitreservoir configuration
+can be achieved as follows. \code aacEncoder_SetParam(hAacEncoder,
+AACENC_BITRESERVOIR, -1); \endcode
+
+To achieve acceptable audio quality with a reduced bitreservoir size setting at
+least 1000 bits per audio channel is recommended. For a multichannel audio file
+with 5.1 channels the bitreservoir reduced to 5000 bits results in acceptable
+audio quality.
+
+
+\subsection vbrmode Variable Bitrate Mode
+The encoder provides various Variable Bitrate Modes that differ in audio quality
+and average overall bitrate. The given values are averages over time, different
+encoder settings and strongly depend on the type of audio signal. The VBR
+configurations can be adjusted via ::AACENC_BITRATEMODE encoder parameter.
+\verbatim
+--------------------------------------------
+ VBR_MODE | Approx. Bitrate in kbps/channel
+ | AAC-LC | AAC-LD/AC_ELD
+----------+---------------+-----------------
+ VBR_1 | 32 - 48 | 32 - 56
+ VBR_2 | 40 - 56 | 40 - 64
+ VBR_3 | 48 - 64 | 48 - 72
+ VBR_4 | 64 - 80 | 64 - 88
+ VBR_5 | 96 - 120 | 112 - 144
+--------------------------------------------
+\endverbatim
+The bitrate ranges apply for individual audio channels. In case of multichannel
+configurations the average bitrate might be estimated by multiplying with the
+number of effective channels. This corresponds to all audio input channels
+exclusively the low frequency channel. At configurations which are making use of
+downmix modules the AAC core channels respectively downmix channels shall be
+considered. For ::AACENC_AOT which are using SBR, the average bitrate can be
+estimated by using the ratio of 0.5 for dualrate SBR and 0.75 for downsampled
+SBR configurations.
+
+
+\subsection encQual Audio Quality Considerations
+The default encoder configuration is suggested to be used. Encoder tools such as
+TNS and PNS are activated by default and are internally controlled (see \ref
+BEHAVIOUR_TOOLS).
+
+There is an additional quality parameter called ::AACENC_AFTERBURNER. In the
+default configuration this quality switch is deactivated because it would cause
+a workload increase which might be significant. If workload is not an issue in
+the application we recommended to activate this feature. \code
+aacEncoder_SetParam(hAacEncoder, AACENC_AFTERBURNER, 0/1); \endcode
+
+\subsection encELD ELD Auto Configuration Mode
+For ELD configuration a so called auto configurator is available which
+configures SBR and the SBR ratio by itself. The configurator is used when the
+encoder parameter ::AACENC_SBR_MODE and ::AACENC_SBR_RATIO are not set
+explicitly.
+
+Based on sampling rate and chosen bitrate a reasonable SBR configuration will be
+used. \verbatim
+------------------------------------------------------------------
+ Sampling Rate | Total Bitrate | No. of | SBR | SBR Ratio
+ [kHz] | [bit/s] | Chan | |
+ | | | |
+---------------+-----------------+--------+-----+-----------------
+ ]min, 16[ | min - max | 1 | off | ---
+---------------+-----------------+--------------+-----------------
+ [16] | min - 27999 | 1 | on | downsampled SBR
+ | 28000 - max | 1 | off | ---
+---------------+-----------------+--------------+-----------------
+ ]16 - 24] | min - 39999 | 1 | on | downsampled SBR
+ | 40000 - max | 1 | off | ---
+---------------+-----------------+--------------+-----------------
+ ]24 - 32] | min - 27999 | 1 | on | dualrate SBR
+ | 28000 - 55999 | 1 | on | downsampled SBR
+ | 56000 - max | 1 | off | ---
+---------------+-----------------+--------------+-----------------
+ ]32 - 44.1] | min - 63999 | 1 | on | dualrate SBR
+ | 64000 - max | 1 | off | ---
+---------------+-----------------+--------------+-----------------
+ ]44.1 - 48] | min - 63999 | 1 | on | dualrate SBR
+ | 64000 - max | 1 | off | ---
+ | | | |
+---------------+-----------------+--------+-----+-----------------
+ ]min, 16[ | min - max | 2 | off | ---
+---------------+-----------------+--------------+-----------------
+ [16] | min - 31999 | 2 | on | downsampled SBR
+ | 32000 - 63999 | 2 | on | downsampled SBR
+ | 64000 - max | 2 | off | ---
+---------------+-----------------+--------------+-----------------
+ ]16 - 24] | min - 47999 | 2 | on | downsampled SBR
+ | 48000 - 79999 | 2 | on | downsampled SBR
+ | 80000 - max | 2 | off | ---
+---------------+-----------------+--------------+-----------------
+ ]24 - 32] | min - 31999 | 2 | on | dualrate SBR
+ | 32000 - 67999 | 2 | on | dualrate SBR
+ | 68000 - 95999 | 2 | on | downsampled SBR
+ | 96000 - max | 2 | off | ---
+---------------+-----------------+--------------+-----------------
+ ]32 - 44.1] | min - 43999 | 2 | on | dualrate SBR
+ | 44000 - 127999 | 2 | on | dualrate SBR
+ | 128000 - max | 2 | off | ---
+---------------+-----------------+--------------+-----------------
+ ]44.1 - 48] | min - 43999 | 2 | on | dualrate SBR
+ | 44000 - 127999 | 2 | on | dualrate SBR
+ | 128000 - max | 2 | off | ---
+ | | |
+------------------------------------------------------------------
+\endverbatim
+
+\subsection encDsELD Reduced Delay (Downscaled) Mode
+The downscaled mode of AAC-ELD reduces the algorithmic delay of AAC-ELD by
+virtually increasing the sampling rate. When using the downscaled mode, the
+bitrate should be increased for keeping the same audio quality level. For common
+signals, the bitrate should be increased by 25% for a downscale factor of 2.
+
+Currently, downscaling factors 2 and 4 are supported.
+To enable the downscaled mode in the encoder, the framelength parameter
+AACENC_GRANULE_LENGTH must be set accordingly to 256 or 240 for a downscale
+factor of 2 or 128 or 120 for a downscale factor of 4. The default values of 512
+or 480 mean that no downscaling is applied. \code
+aacEncoder_SetParam(hAacEncoder, AACENC_GRANULE_LENGTH, 256);
+aacEncoder_SetParam(hAacEncoder, AACENC_GRANULE_LENGTH, 128);
+\endcode
+
+Downscaled bitstreams are fully backwards compatible. However, the legacy
+decoder needs to support high sample rate, e.g. 96kHz. The signaled sampling
+rate is multiplied by the downscale factor. Although not required, downscaling
+should be applied when decoding downscaled bitstreams. It reduces CPU workload
+and the output will have the same sampling rate as the input. In an ideal
+configuration both encoder and decoder should run with the same downscale
+factor.
+
+The following table shows approximate filter bank delays in ms for common
+sampling rates(sr) at framesize(fs), and downscale factor(dsf), based on this
+formula: \f[ 1000 * fs / (dsf * sr) \f]
+
+\verbatim
+--------------------------------------
+ | 512/2 | 512/4 | 480/2 | 480/4
+------+-------+-------+-------+-------
+22050 | 17.41 | 8.71 | 16.33 | 8.16
+32000 | 12.00 | 6.00 | 11.25 | 5.62
+44100 | 8.71 | 4.35 | 8.16 | 4.08
+48000 | 8.00 | 4.00 | 7.50 | 3.75
+--------------------------------------
+\endverbatim
+
+\section audiochCfg Audio Channel Configuration
+The MPEG standard refers often to the so-called Channel Configuration. This
+Channel Configuration is used for a fixed Channel Mapping. The configurations
+1-7 and 11,12,14 are predefined in MPEG standard and used for implicit
+signalling within the encoded bitstream. For user defined Configurations the
+Channel Configuration is set to 0 and the Channel Mapping must be explecitly
+described with an appropriate Program Config Element. The present Encoder
+implementation does not allow the user to configure this Channel Configuration
+from extern. The Encoder implementation supports fixed Channel Modes which are
+mapped to Channel Configuration as follow. \verbatim
+----------------------------------------------------------------------------------------
+ ChannelMode | ChCfg | Height | front_El | side_El | back_El |
+lfe_El
+-----------------------+-------+--------+---------------+----------+----------+---------
+MODE_1 | 1 | NORM | SCE | | |
+MODE_2 | 2 | NORM | CPE | | |
+MODE_1_2 | 3 | NORM | SCE, CPE | | |
+MODE_1_2_1 | 4 | NORM | SCE, CPE | | SCE |
+MODE_1_2_2 | 5 | NORM | SCE, CPE | | CPE |
+MODE_1_2_2_1 | 6 | NORM | SCE, CPE | | CPE |
+LFE MODE_1_2_2_2_1 | 7 | NORM | SCE, CPE, CPE | | CPE
+| LFE MODE_6_1 | 11 | NORM | SCE, CPE | | CPE,
+SCE | LFE MODE_7_1_BACK | 12 | NORM | SCE, CPE | |
+CPE, CPE | LFE
+-----------------------+-------+--------+---------------+----------+----------+---------
+MODE_7_1_TOP_FRONT | 14 | NORM | SCE, CPE | | CPE |
+LFE | | TOP | CPE | | |
+-----------------------+-------+--------+---------------+----------+----------+---------
+MODE_7_1_REAR_SURROUND | 0 | NORM | SCE, CPE | | CPE, CPE |
+LFE MODE_7_1_FRONT_CENTER | 0 | NORM | SCE, CPE, CPE | | CPE
+| LFE
+----------------------------------------------------------------------------------------
+- NORM: Normal Height Layer. - TOP: Top Height Layer. - BTM: Bottom Height
+Layer.
+- SCE: Single Channel Element. - CPE: Channel Pair. - LFE: Low Frequency
+Element. \endverbatim
+
+The Table describes all fixed Channel Elements for each Channel Mode which are
+assigned to a speaker arrangement. The arrangement includes front, side, back
+and lfe Audio Channel Elements in the normal height layer, possibly followed by
+front, side, and back elements in the top and bottom layer (Channel
+Configuration 14). \n This mapping of Audio Channel Elements is defined in MPEG
+standard for Channel Config 1-7 and 11,12,14.\n In case of Channel Config 0 or
+writing matrix mixdown coefficients, the encoder enables the writing of Program
+Config Element itself as described in \ref encPCE. The configuration used in
+Program Config Element refers to the denoted Table.\n Beside the Channel Element
+assignment the Channel Modes are resposible for audio input data channel
+mapping. The Channel Mapping of the audio data depends on the selected
+::AACENC_CHANNELORDER which can be MPEG or WAV like order.\n Following table
+describes the complete channel mapping for both Channel Order configurations.
+\verbatim
+---------------------------------------------------------------------------------------
+ChannelMode | MPEG-Channelorder | WAV-Channelorder
+-----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
+MODE_1 | 0 | | | | | | | | 0 | | | | | |
+| MODE_2 | 0 | 1 | | | | | | | 0 | 1 | | | |
+| | MODE_1_2 | 0 | 1 | 2 | | | | | | 2 | 0 | 1 | |
+| | | MODE_1_2_1 | 0 | 1 | 2 | 3 | | | | | 2 | 0 | 1 | 3
+| | | | MODE_1_2_2 | 0 | 1 | 2 | 3 | 4 | | | | 2 | 0 | 1
+| 3 | 4 | | | MODE_1_2_2_1 | 0 | 1 | 2 | 3 | 4 | 5 | | | 2 | 0
+| 1 | 4 | 5 | 3 | | MODE_1_2_2_2_1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2
+| 6 | 7 | 0 | 1 | 4 | 5 | 3 MODE_6_1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
+| 2 | 0 | 1 | 4 | 5 | 6 | 3 | MODE_7_1_BACK | 0 | 1 | 2 | 3 | 4 | 5 | 6
+| 7 | 2 | 0 | 1 | 6 | 7 | 4 | 5 | 3 MODE_7_1_TOP_FRONT | 0 | 1 | 2 | 3 | 4 |
+5 | 6 | 7 | 2 | 0 | 1 | 4 | 5 | 3 | 6 | 7
+-----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
+MODE_7_1_REAR_SURROUND | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2 | 0 | 1 | 6 | 7 | 4 |
+5 | 3 MODE_7_1_FRONT_CENTER | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 2 | 6 | 7 | 0 | 1
+| 4 | 5 | 3
+---------------------------------------------------------------------------------------
+\endverbatim
+
+The denoted mapping is important for correct audio channel assignment when using
+MPEG or WAV ordering. The incoming audio channels are distributed MPEG like
+starting at the front channels and ending at the back channels. The distribution
+is used as described in Table concering Channel Config and fix channel elements.
+Please see the following example for clarification.
+
+\verbatim
+Example: MODE_1_2_2_1 - WAV-Channelorder 5.1
+------------------------------------------
+ Input Channel | Coder Channel
+--------------------+---------------------
+ 2 (front center) | 0 (SCE channel)
+ 0 (left center) | 1 (1st of 1st CPE)
+ 1 (right center) | 2 (2nd of 1st CPE)
+ 4 (left surround) | 3 (1st of 2nd CPE)
+ 5 (right surround) | 4 (2nd of 2nd CPE)
+ 3 (LFE) | 5 (LFE)
+------------------------------------------
+\endverbatim
+
+
+\section suppBitrates Supported Bitrates
+
+The FDK AAC Encoder provides a wide range of supported bitrates.
+The minimum and maximum allowed bitrate depends on the Audio Object Type. For
+AAC-LC the minimum bitrate is the bitrate that is required to write the most
+basic and minimal valid bitstream. It consists of the bitstream format header
+information and other static/mandatory information within the AAC payload. The
+maximum AAC framesize allowed by the MPEG-4 standard determines the maximum
+allowed bitrate for AAC-LC. For HE-AAC and HE-AAC v2 a library internal look-up
+table is used.
+
+A good working point in terms of audio quality, sampling rate and bitrate, is at
+1 to 1.5 bits/audio sample for AAC-LC, 0.625 bits/audio sample for dualrate
+HE-AAC, 1.125 bits/audio sample for downsampled HE-AAC and 0.5 bits/audio sample
+for HE-AAC v2. For example for one channel with a sampling frequency of 48 kHz,
+the range from 48 kbit/s to 72 kbit/s achieves reasonable audio quality for
+AAC-LC.
+
+For HE-AAC and HE-AAC v2 the lowest possible audio input sampling frequency is
+16 kHz because then the AAC-LC core encoder operates in dual rate mode at its
+lowest possible sampling frequency, which is 8 kHz. HE-AAC v2 requires stereo
+input audio data.
+
+Please note that in HE-AAC or HE-AAC v2 mode the encoder supports much higher
+bitrates than are appropriate for HE-AAC or HE-AAC v2. For example, at a bitrate
+of more than 64 kbit/s for a stereo audio signal at 44.1 kHz it usually makes
+sense to use AAC-LC, which will produce better audio quality at that bitrate
+than HE-AAC or HE-AAC v2.
+
+\section reommendedConfig Recommended Sampling Rate and Bitrate Combinations
+
+The following table provides an overview of recommended encoder configuration
+parameters which we determined by virtue of numerous listening tests.
+
+\subsection reommendedConfigLC AAC-LC, HE-AAC, HE-AACv2 in Dualrate SBR mode.
+\verbatim
+-----------------------------------------------------------------------------------
+Audio Object Type | Bit Rate Range | Supported | Preferred | No.
+of | [bit/s] | Sampling Rates | Sampl. | Chan. |
+| [kHz] | Rate | | |
+| [kHz] |
+-------------------+------------------+-----------------------+------------+-------
+AAC LC + SBR + PS | 8000 - 11999 | 22.05, 24.00 | 24.00 | 2
+AAC LC + SBR + PS | 12000 - 17999 | 32.00 | 32.00 | 2
+AAC LC + SBR + PS | 18000 - 39999 | 32.00, 44.10, 48.00 | 44.10 | 2
+AAC LC + SBR + PS | 40000 - 64000 | 32.00, 44.10, 48.00 | 48.00 | 2
+-------------------+------------------+-----------------------+------------+-------
+AAC LC + SBR | 8000 - 11999 | 22.05, 24.00 | 24.00 | 1
+AAC LC + SBR | 12000 - 17999 | 32.00 | 32.00 | 1
+AAC LC + SBR | 18000 - 39999 | 32.00, 44.10, 48.00 | 44.10 | 1
+AAC LC + SBR | 40000 - 64000 | 32.00, 44.10, 48.00 | 48.00 | 1
+-------------------+------------------+-----------------------+------------+-------
+AAC LC + SBR | 16000 - 27999 | 32.00, 44.10, 48.00 | 32.00 | 2
+AAC LC + SBR | 28000 - 63999 | 32.00, 44.10, 48.00 | 44.10 | 2
+AAC LC + SBR | 64000 - 128000 | 32.00, 44.10, 48.00 | 48.00 | 2
+-------------------+------------------+-----------------------+------------+-------
+AAC LC + SBR | 64000 - 69999 | 32.00, 44.10, 48.00 | 32.00 |
+5, 5.1 AAC LC + SBR | 70000 - 239999 | 32.00, 44.10, 48.00 | 44.10
+| 5, 5.1 AAC LC + SBR | 240000 - 319999 | 32.00, 44.10, 48.00 |
+48.00 | 5, 5.1
+-------------------+------------------+-----------------------+------------+-------
+AAC LC | 8000 - 15999 | 11.025, 12.00, 16.00 | 12.00 | 1
+AAC LC | 16000 - 23999 | 16.00 | 16.00 | 1
+AAC LC | 24000 - 31999 | 16.00, 22.05, 24.00 | 24.00 | 1
+AAC LC | 32000 - 55999 | 32.00 | 32.00 | 1
+AAC LC | 56000 - 160000 | 32.00, 44.10, 48.00 | 44.10 | 1
+AAC LC | 160001 - 288000 | 48.00 | 48.00 | 1
+-------------------+------------------+-----------------------+------------+-------
+AAC LC | 16000 - 23999 | 11.025, 12.00, 16.00 | 12.00 | 2
+AAC LC | 24000 - 31999 | 16.00 | 16.00 | 2
+AAC LC | 32000 - 39999 | 16.00, 22.05, 24.00 | 22.05 | 2
+AAC LC | 40000 - 95999 | 32.00 | 32.00 | 2
+AAC LC | 96000 - 111999 | 32.00, 44.10, 48.00 | 32.00 | 2
+AAC LC | 112000 - 320001 | 32.00, 44.10, 48.00 | 44.10 | 2
+AAC LC | 320002 - 576000 | 48.00 | 48.00 | 2
+-------------------+------------------+-----------------------+------------+-------
+AAC LC | 160000 - 239999 | 32.00 | 32.00 |
+5, 5.1 AAC LC | 240000 - 279999 | 32.00, 44.10, 48.00 | 32.00
+| 5, 5.1 AAC LC | 280000 - 800000 | 32.00, 44.10, 48.00 |
+44.10 | 5, 5.1
+-----------------------------------------------------------------------------------
+\endverbatim \n
+
+\subsection reommendedConfigLD AAC-LD, AAC-ELD, AAC-ELD with SBR in Dualrate SBR
+mode. Unlike to HE-AAC configuration the SBR is not covered by ELD audio object
+type and needs to be enabled explicitly. Use ::AACENC_SBR_MODE to configure SBR
+and its samplingrate ratio with ::AACENC_SBR_RATIO parameter. \verbatim
+-----------------------------------------------------------------------------------
+Audio Object Type | Bit Rate Range | Supported | Preferred | No.
+of | [bit/s] | Sampling Rates | Sampl. | Chan. |
+| [kHz] | Rate | | |
+| [kHz] |
+-------------------+------------------+-----------------------+------------+-------
+ELD + SBR | 18000 - 24999 | 32.00 - 44.10 | 32.00 | 1
+ELD + SBR | 25000 - 31999 | 32.00 - 48.00 | 32.00 | 1
+ELD + SBR | 32000 - 64000 | 32.00 - 48.00 | 48.00 | 1
+-------------------+------------------+-----------------------+------------+-------
+ELD + SBR | 32000 - 51999 | 32.00 - 48.00 | 44.10 | 2
+ELD + SBR | 52000 - 128000 | 32.00 - 48.00 | 48.00 | 2
+-------------------+------------------+-----------------------+------------+-------
+ELD + SBR | 78000 - 160000 | 32.00 - 48.00 | 48.00 | 3
+-------------------+------------------+-----------------------+------------+-------
+ELD + SBR | 104000 - 212000 | 32.00 - 48.00 | 48.00 | 4
+-------------------+------------------+-----------------------+------------+-------
+ELD + SBR | 130000 - 246000 | 32.00 - 48.00 | 48.00 |
+5, 5.1
+-------------------+------------------+-----------------------+------------+-------
+LD, ELD | 16000 - 19999 | 16.00 - 24.00 | 16.00 | 1
+LD, ELD | 20000 - 39999 | 16.00 - 32.00 | 24.00 | 1
+LD, ELD | 40000 - 49999 | 22.05 - 32.00 | 32.00 | 1
+LD, ELD | 50000 - 61999 | 24.00 - 44.10 | 32.00 | 1
+LD, ELD | 62000 - 84999 | 32.00 - 48.00 | 44.10 | 1
+LD, ELD | 85000 - 192000 | 44.10 - 48.00 | 48.00 | 1
+-------------------+------------------+-----------------------+------------+-------
+LD, ELD | 64000 - 75999 | 24.00 - 32.00 | 32.00 | 2
+LD, ELD | 76000 - 97999 | 24.00 - 44.10 | 32.00 | 2
+LD, ELD | 98000 - 135999 | 32.00 - 48.00 | 44.10 | 2
+LD, ELD | 136000 - 384000 | 44.10 - 48.00 | 48.00 | 2
+-------------------+------------------+-----------------------+------------+-------
+LD, ELD | 96000 - 113999 | 24.00 - 32.00 | 32.00 | 3
+LD, ELD | 114000 - 146999 | 24.00 - 44.10 | 32.00 | 3
+LD, ELD | 147000 - 203999 | 32.00 - 48.00 | 44.10 | 3
+LD, ELD | 204000 - 576000 | 44.10 - 48.00 | 48.00 | 3
+-------------------+------------------+-----------------------+------------+-------
+LD, ELD | 128000 - 151999 | 24.00 - 32.00 | 32.00 | 4
+LD, ELD | 152000 - 195999 | 24.00 - 44.10 | 32.00 | 4
+LD, ELD | 196000 - 271999 | 32.00 - 48.00 | 44.10 | 4
+LD, ELD | 272000 - 768000 | 44.10 - 48.00 | 48.00 | 4
+-------------------+------------------+-----------------------+------------+-------
+LD, ELD | 160000 - 189999 | 24.00 - 32.00 | 32.00 |
+5, 5.1 LD, ELD | 190000 - 244999 | 24.00 - 44.10 | 32.00
+| 5, 5.1 LD, ELD | 245000 - 339999 | 32.00 - 48.00 |
+44.10 | 5, 5.1 LD, ELD | 340000 - 960000 | 44.10 - 48.00 |
+48.00 | 5, 5.1
+-----------------------------------------------------------------------------------
+\endverbatim \n
+
+\subsection reommendedConfigELD AAC-ELD with SBR in Downsampled SBR mode.
+\verbatim
+-----------------------------------------------------------------------------------
+Audio Object Type | Bit Rate Range | Supported | Preferred | No.
+of | [bit/s] | Sampling Rates | Sampl. | Chan. |
+| [kHz] | Rate | | |
+| [kHz] |
+-------------------+------------------+-----------------------+------------+-------
+ELD + SBR | 18000 - 24999 | 16.00 - 22.05 | 22.05 | 1
+(downsampled SBR) | 25000 - 31999 | 16.00 - 24.00 | 24.00 | 1
+ | 32000 - 47999 | 22.05 - 32.00 | 32.00 | 1
+ | 48000 - 64000 | 22.05 - 48.00 | 32.00 | 1
+-------------------+------------------+-----------------------+------------+-------
+ELD + SBR | 32000 - 51999 | 16.00 - 24.00 | 24.00 | 2
+(downsampled SBR) | 52000 - 59999 | 22.05 - 24.00 | 24.00 | 2
+ | 60000 - 95999 | 22.05 - 32.00 | 32.00 | 2
+ | 96000 - 128000 | 22.05 - 48.00 | 32.00 | 2
+-------------------+------------------+-----------------------+------------+-------
+ELD + SBR | 78000 - 99999 | 22.05 - 24.00 | 24.00 | 3
+(downsampled SBR) | 100000 - 143999 | 22.05 - 32.00 | 32.00 | 3
+ | 144000 - 159999 | 22.05 - 48.00 | 32.00 | 3
+ | 160000 - 192000 | 32.00 - 48.00 | 32.00 | 3
+-------------------+------------------+-----------------------+------------+-------
+ELD + SBR | 104000 - 149999 | 22.05 - 24.00 | 24.00 | 4
+(downsampled SBR) | 150000 - 191999 | 22.05 - 32.00 | 32.00 | 4
+ | 192000 - 211999 | 22.05 - 48.00 | 32.00 | 4
+ | 212000 - 256000 | 32.00 - 48.00 | 32.00 | 4
+-------------------+------------------+-----------------------+------------+-------
+ELD + SBR | 130000 - 171999 | 22.05 - 24.00 | 24.00 |
+5, 5.1 (downsampled SBR) | 172000 - 239999 | 22.05 - 32.00 | 32.00
+| 5, 5.1 | 240000 - 320000 | 32.00 - 48.00 | 32.00 | 5, 5.1
+-----------------------------------------------------------------------------------
+\endverbatim \n
+
+\subsection reommendedConfigELDv2 AAC-ELD v2, AAC-ELD v2 with SBR.
+The ELD v2 212 configuration must be configured explicitly with
+::AACENC_CHANNELMODE parameter according MODE_212 value. SBR can be configured
+separately through ::AACENC_SBR_MODE and ::AACENC_SBR_RATIO parameter. Following
+configurations shall apply to both framelengths 480 and 512. For ELD v2
+configuration without SBR and framelength 480 the supported sampling rate is
+restricted to the range from 16 kHz up to 24 kHz. \verbatim
+-----------------------------------------------------------------------------------
+Audio Object Type | Bit Rate Range | Supported | Preferred | No.
+of | [bit/s] | Sampling Rates | Sampl. | Chan. |
+| [kHz] | Rate | | |
+| [kHz] |
+-------------------+------------------+-----------------------+------------+-------
+ELD-212 | 16000 - 19999 | 16.00 - 24.00 | 16.00 | 2
+(without SBR) | 20000 - 39999 | 16.00 - 32.00 | 24.00 | 2
+ | 40000 - 49999 | 22.05 - 32.00 | 32.00 | 2
+ | 50000 - 61999 | 24.00 - 44.10 | 32.00 | 2
+ | 62000 - 84999 | 32.00 - 48.00 | 44.10 | 2
+ | 85000 - 192000 | 44.10 - 48.00 | 48.00 | 2
+-------------------+------------------+-----------------------+------------+-------
+ELD-212 + SBR | 18000 - 20999 | 32.00 | 32.00 | 2
+(dualrate SBR) | 21000 - 25999 | 32.00 - 44.10 | 32.00 | 2
+ | 26000 - 31999 | 32.00 - 48.00 | 44.10 | 2
+ | 32000 - 64000 | 32.00 - 48.00 | 48.00 | 2
+-------------------+------------------+-----------------------+------------+-------
+ELD-212 + SBR | 18000 - 19999 | 16.00 - 22.05 | 22.05 | 2
+(downsampled SBR) | 20000 - 24999 | 16.00 - 24.00 | 22.05 | 2
+ | 25000 - 31999 | 16.00 - 24.00 | 24.00 | 2
+ | 32000 - 64000 | 24.00 - 24.00 | 24.00 | 2
+-------------------+------------------+-----------------------+------------+-------
+\endverbatim \n
+
+\page ENCODERBEHAVIOUR Encoder Behaviour
+
+\section BEHAVIOUR_BANDWIDTH Bandwidth
+
+The FDK AAC encoder usually does not use the full frequency range of the input
+signal, but restricts the bandwidth according to certain library-internal
+settings. They can be changed in the table "bandWidthTable" in the file
+bandwidth.cpp (if available).
+
+The encoder API provides the ::AACENC_BANDWIDTH parameter to adjust the
+bandwidth explicitly. \code aacEncoder_SetParam(hAacEncoder, AACENC_BANDWIDTH,
+value); \endcode
+
+However it is not recommended to change these settings, because they are based
+on numerous listening tests and careful tweaks to ensure the best overall
+encoding quality. Also, the maximum bandwidth that can be set manually by the
+user is 20kHz or fs/2, whichever value is smaller.
+
+Theoretically a signal of for example 48 kHz can contain frequencies up to 24
+kHz, but to use this full range in an audio encoder usually does not make sense.
+Usually the encoder has a very limited amount of bits to spend (typically 128
+kbit/s for stereo 48 kHz content) and to allow full range bandwidth would waste
+a lot of these bits for frequencies the human ear is hardly able to perceive
+anyway, if at all. Hence it is wise to use the available bits for the really
+important frequency range and just skip the rest. At lower bitrates (e. g. <= 80
+kbit/s for stereo 48 kHz content) the encoder will choose an even smaller
+bandwidth, because an encoded signal with smaller bandwidth and hence less
+artifacts sounds better than a signal with higher bandwidth but then more coding
+artefacts across all frequencies. These artefacts would occur if small bitrates
+and high bandwidths are chosen because the available bits are just not enough to
+encode all frequencies well.
+
+Unfortunately some people evaluate encoding quality based on possible bandwidth
+as well, but it is a double-edged sword considering the trade-off described
+above.
+
+Another aspect is workload consumption. The higher the allowed bandwidth, the
+more frequency lines have to be processed, which in turn increases the workload.
+
+\section FRAMESIZES_AND_BIT_RESERVOIR Frame Sizes & Bit Reservoir
+
+For AAC there is a difference between constant bit rate and constant frame
+length due to the so-called bit reservoir technique, which allows the encoder to
+use less bits in an AAC frame for those audio signal sections which are easy to
+encode, and then spend them at a later point in time for more complex audio
+sections. The extent to which this "bit exchange" is done is limited to allow
+for reliable and relatively low delay real time streaming. Therefore, for
+AAC-ELD, the bitreservoir is limited. It varies between 500 and 4000 bits/frame,
+depending on the bitrate/channel.
+- For a bitrate of 12kbps/channel and below, the AAC-ELD bitreservoir is 500
+bits/frame.
+- For a bitrate of 70kbps/channel and above, the AAC-ELD bitreservoir is 4000
+bits/frame.
+- Between 12kbps/channel and 70kbps/channel, the AAC-ELD bitrervoir is increased
+linearly.
+- For AAC-LC, the bitrate is only limited by the maximum AAC frame length. It
+is, regardless of the available bit reservoir, defined as 6144 bits per channel.
+
+Over a longer period in time the bitrate will be constant in the AAC constant
+bitrate mode, e.g. for ISDN transmission. This means that in AAC each bitstream
+frame will in general have a different length in bytes but over time it
+will reach the target bitrate.
+
+
+One could also make an MPEG compliant
+AAC encoder which always produces constant length packages for each AAC frame,
+but the audio quality would be considerably worse since the bit reservoir
+technique would have to be switched off completely. A higher bit rate would have
+to be used to get the same audio quality as with an enabled bit reservoir.
+
+For mp3 by the way, the same bit reservoir technique exists, but there each bit
+stream frame has a constant length for a given bit rate (ignoring the
+padding byte). In mp3 there is a so-called "back pointer" which tells
+the decoder which bits belong to the current mp3 frame - and in general some or
+many bits have been transmitted in an earlier mp3 frame. Basically this leads to
+the same "bit exchange between mp3 frames" as in AAC but with virtually constant
+length frames.
+
+This variable frame length at "constant bit rate" is not something special
+in this Fraunhofer IIS AAC encoder. AAC has been designed in that way.
+
+\subsection BEHAVIOUR_ESTIM_AVG_FRAMESIZES Estimating Average Frame Sizes
+
+A HE-AAC v1 or v2 audio frame contains 2048 PCM samples per channel (there is
+also one mode with 1920 samples per channel but this is only for special
+purposes such as DAB+ digital radio).
+
+The number of HE-AAC frames \f$N\_FRAMES\f$ per second at 44.1 kHz is:
+
+\f[
+N\_FRAMES = 44100 / 2048 = 21.5332
+\f]
+
+At a bit rate of 8 kbps the average number of bits per frame
+\f$N\_BITS\_PER\_FRAME\f$ is:
+
+\f[
+N\_BITS\_PER\_FRAME = 8000 / 21.5332 = 371.52
+\f]
+
+which is about 46.44 bytes per encoded frame.
+
+At a bit rate of 32 kbps, which is quite high for single channel HE-AAC v1, it
+is:
+
+\f[
+N\_BITS\_PER\_FRAME = 32000 / 21.5332 = 1486
+\f]
+
+which is about 185.76 bytes per encoded frame.
+
+These bits/frame figures are average figures where each AAC frame generally has
+a different size in bytes. To calculate the same for AAC-LC just use 1024
+instead of 2048 PCM samples per frame and channel. For AAC-LD/ELD it is either
+480 or 512 PCM samples per frame and channel.
+
+
+\section BEHAVIOUR_TOOLS Encoder Tools
+
+The AAC encoder supports TNS, PNS, MS, Intensity and activates these tools
+depending on the audio signal and the encoder configuration (i.e. bitrate or
+AOT). It is not required to configure these tools manually.
+
+PNS improves encoding quality only for certain bitrates. Therefore it makes
+sense to activate PNS only for these bitrates and save the processing power
+required for PNS (about 10 % of the encoder) when using other bitrates. This is
+done automatically inside the encoder library. PNS is disabled inside the
+encoder library if an MPEG-2 AOT is choosen since PNS is an MPEG-4 AAC feature.
+
+If SBR is activated, the encoder automatically deactivates PNS internally. If
+TNS is disabled but PNS is allowed, the encoder deactivates PNS calculation
+internally.
+
+*/
+
+#ifndef AACENC_LIB_H
+#define AACENC_LIB_H
+
+#include "machine_type.h"
+#include "FDK_audio.h"
+
+#define AACENCODER_LIB_VL0 4
+#define AACENCODER_LIB_VL1 0
+#define AACENCODER_LIB_VL2 0
+
+/**
+ * AAC encoder error codes.
+ */
+typedef enum {
+ AACENC_OK = 0x0000, /*!< No error happened. All fine. */
+
+ AACENC_INVALID_HANDLE =
+ 0x0020, /*!< Handle passed to function call was invalid. */
+ AACENC_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */
+ AACENC_UNSUPPORTED_PARAMETER = 0x0022, /*!< Parameter not available. */
+ AACENC_INVALID_CONFIG = 0x0023, /*!< Configuration not provided. */
+
+ AACENC_INIT_ERROR = 0x0040, /*!< General initialization error. */
+ AACENC_INIT_AAC_ERROR = 0x0041, /*!< AAC library initialization error. */
+ AACENC_INIT_SBR_ERROR = 0x0042, /*!< SBR library initialization error. */
+ AACENC_INIT_TP_ERROR = 0x0043, /*!< Transport library initialization error. */
+ AACENC_INIT_META_ERROR =
+ 0x0044, /*!< Meta data library initialization error. */
+ AACENC_INIT_MPS_ERROR = 0x0045, /*!< MPS library initialization error. */
+
+ AACENC_ENCODE_ERROR = 0x0060, /*!< The encoding process was interrupted by an
+ unexpected error. */
+
+ AACENC_ENCODE_EOF = 0x0080 /*!< End of file reached. */
+
+} AACENC_ERROR;
+
+/**
+ * AAC encoder buffer descriptors identifier.
+ * This identifier are used within buffer descriptors
+ * AACENC_BufDesc::bufferIdentifiers.
+ */
+typedef enum {
+ /* Input buffer identifier. */
+ IN_AUDIO_DATA = 0, /*!< Audio input buffer, interleaved INT_PCM samples. */
+ IN_ANCILLRY_DATA = 1, /*!< Ancillary data to be embedded into bitstream. */
+ IN_METADATA_SETUP = 2, /*!< Setup structure for embedding meta data. */
+
+ /* Output buffer identifier. */
+ OUT_BITSTREAM_DATA = 3, /*!< Buffer holds bitstream output data. */
+ OUT_AU_SIZES =
+ 4 /*!< Buffer contains sizes of each access unit. This information
+ is necessary for superframing. */
+
+} AACENC_BufferIdentifier;
+
+/**
+ * AAC encoder handle.
+ */
+typedef struct AACENCODER *HANDLE_AACENCODER;
+
+/**
+ * Provides some info about the encoder configuration.
+ */
+typedef struct {
+ UINT maxOutBufBytes; /*!< Maximum number of encoder bitstream bytes within one
+ frame. Size depends on maximum number of supported
+ channels in encoder instance. For superframing (as
+ used for example in DAB+), size has to be a multiple
+ accordingly. */
+
+ UINT maxAncBytes; /*!< Maximum number of ancillary data bytes which can be
+ inserted into bitstream within one frame. */
+
+ UINT inBufFillLevel; /*!< Internal input buffer fill level in samples per
+ channel. This parameter will automatically be cleared
+ if samplingrate or channel(Mode/Order) changes. */
+
+ UINT inputChannels; /*!< Number of input channels expected in encoding
+ process. */
+
+ UINT frameLength; /*!< Amount of input audio samples consumed each frame per
+ channel, depending on audio object type configuration. */
+
+ UINT nDelay; /*!< Codec delay in PCM samples/channel. Depends on framelength
+ and AOT. Does not include framing delay for filling up encoder
+ PCM input buffer. */
+
+ UINT nDelayCore; /*!< Codec delay in PCM samples/channel, w/o delay caused by
+ the decoder SBR module. This delay is needed to correctly
+ write edit lists for gapless playback. The decoder may not
+ know how much delay is introdcued by SBR, since it may not
+ know if SBR is active at all (implicit signaling),
+ therefore the deocder must take into account any delay
+ caused by the SBR module. */
+
+ UCHAR confBuf[64]; /*!< Configuration buffer in binary format as an
+ AudioSpecificConfig or StreamMuxConfig according to the
+ selected transport type. */
+
+ UINT confSize; /*!< Number of valid bytes in confBuf. */
+
+} AACENC_InfoStruct;
+
+/**
+ * Describes the input and output buffers for an aacEncEncode() call.
+ */
+typedef struct {
+ INT numBufs; /*!< Number of buffers. */
+ void **bufs; /*!< Pointer to vector containing buffer addresses. */
+ INT *bufferIdentifiers; /*!< Identifier of each buffer element. See
+ ::AACENC_BufferIdentifier. */
+ INT *bufSizes; /*!< Size of each buffer in 8-bit bytes. */
+ INT *bufElSizes; /*!< Size of each buffer element in bytes. */
+
+} AACENC_BufDesc;
+
+/**
+ * Defines the input arguments for an aacEncEncode() call.
+ */
+typedef struct {
+ INT numInSamples; /*!< Number of valid input audio samples (multiple of input
+ channels). */
+ INT numAncBytes; /*!< Number of ancillary data bytes to be encoded. */
+
+} AACENC_InArgs;
+
+/**
+ * Defines the output arguments for an aacEncEncode() call.
+ */
+typedef struct {
+ INT numOutBytes; /*!< Number of valid bitstream bytes generated during
+ aacEncEncode(). */
+ INT numInSamples; /*!< Number of input audio samples consumed by the encoder.
+ */
+ INT numAncBytes; /*!< Number of ancillary data bytes consumed by the encoder.
+ */
+ INT bitResState; /*!< State of the bit reservoir in bits. */
+
+} AACENC_OutArgs;
+
+/**
+ * Meta Data Compression Profiles.
+ */
+typedef enum {
+ AACENC_METADATA_DRC_NONE = 0, /*!< None. */
+ AACENC_METADATA_DRC_FILMSTANDARD = 1, /*!< Film standard. */
+ AACENC_METADATA_DRC_FILMLIGHT = 2, /*!< Film light. */
+ AACENC_METADATA_DRC_MUSICSTANDARD = 3, /*!< Music standard. */
+ AACENC_METADATA_DRC_MUSICLIGHT = 4, /*!< Music light. */
+ AACENC_METADATA_DRC_SPEECH = 5, /*!< Speech. */
+ AACENC_METADATA_DRC_NOT_PRESENT =
+ 256 /*!< Disable writing gain factor (used for comp_profile only). */
+
+} AACENC_METADATA_DRC_PROFILE;
+
+/**
+ * Meta Data setup structure.
+ */
+typedef struct {
+ AACENC_METADATA_DRC_PROFILE
+ drc_profile; /*!< MPEG DRC compression profile. See
+ ::AACENC_METADATA_DRC_PROFILE. */
+ AACENC_METADATA_DRC_PROFILE
+ comp_profile; /*!< ETSI heavy compression profile. See
+ ::AACENC_METADATA_DRC_PROFILE. */
+
+ INT drc_TargetRefLevel; /*!< Used to define expected level to:
+ Scaled with 16 bit. x*2^16. */
+ INT comp_TargetRefLevel; /*!< Adjust limiter to avoid overload.
+ Scaled with 16 bit. x*2^16. */
+
+ INT prog_ref_level_present; /*!< Flag, if prog_ref_level is present */
+ INT prog_ref_level; /*!< Programme Reference Level = Dialogue Level:
+ -31.75dB .. 0 dB ; stepsize: 0.25dB
+ Scaled with 16 bit. x*2^16.*/
+
+ UCHAR PCE_mixdown_idx_present; /*!< Flag, if dmx-idx should be written in
+ programme config element */
+ UCHAR ETSI_DmxLvl_present; /*!< Flag, if dmx-lvl should be written in
+ ETSI-ancData */
+
+ SCHAR centerMixLevel; /*!< Center downmix level (0...7, according to table) */
+ SCHAR surroundMixLevel; /*!< Surround downmix level (0...7, according to
+ table) */
+
+ UCHAR
+ dolbySurroundMode; /*!< Indication for Dolby Surround Encoding Mode.
+ - 0: Dolby Surround mode not indicated
+ - 1: 2-ch audio part is not Dolby surround encoded
+ - 2: 2-ch audio part is Dolby surround encoded */
+
+ UCHAR drcPresentationMode; /*!< Indicatin for DRC Presentation Mode.
+ - 0: Presentation mode not inticated
+ - 1: Presentation mode 1
+ - 2: Presentation mode 2 */
+
+ struct {
+ /* extended ancillary data */
+ UCHAR extAncDataEnable; /*< Indicates if MPEG4_ext_ancillary_data() exists.
+ - 0: No MPEG4_ext_ancillary_data().
+ - 1: Insert MPEG4_ext_ancillary_data(). */
+
+ UCHAR
+ extDownmixLevelEnable; /*< Indicates if ext_downmixing_levels() exists.
+ - 0: No ext_downmixing_levels().
+ - 1: Insert ext_downmixing_levels(). */
+ UCHAR extDownmixLevel_A; /*< Downmix level index A (0...7, according to
+ table) */
+ UCHAR extDownmixLevel_B; /*< Downmix level index B (0...7, according to
+ table) */
+
+ UCHAR dmxGainEnable; /*< Indicates if ext_downmixing_global_gains() exists.
+ - 0: No ext_downmixing_global_gains().
+ - 1: Insert ext_downmixing_global_gains(). */
+ INT dmxGain5; /*< Gain factor for downmix to 5 channels.
+ -15.75dB .. -15.75dB; stepsize: 0.25dB
+ Scaled with 16 bit. x*2^16.*/
+ INT dmxGain2; /*< Gain factor for downmix to 2 channels.
+ -15.75dB .. -15.75dB; stepsize: 0.25dB
+ Scaled with 16 bit. x*2^16.*/
+
+ UCHAR lfeDmxEnable; /*< Indicates if ext_downmixing_lfe_level() exists.
+ - 0: No ext_downmixing_lfe_level().
+ - 1: Insert ext_downmixing_lfe_level(). */
+ UCHAR lfeDmxLevel; /*< Downmix level index for LFE (0..15, according to
+ table) */
+
+ } ExtMetaData;
+
+} AACENC_MetaData;
+
+/**
+ * AAC encoder control flags.
+ *
+ * In interaction with the ::AACENC_CONTROL_STATE parameter it is possible to
+ * get information about the internal initialization process. It is also
+ * possible to overwrite the internal state from extern when necessary.
+ */
+typedef enum {
+ AACENC_INIT_NONE = 0x0000, /*!< Do not trigger initialization. */
+ AACENC_INIT_CONFIG =
+ 0x0001, /*!< Initialize all encoder modules configuration. */
+ AACENC_INIT_STATES = 0x0002, /*!< Reset all encoder modules history buffer. */
+ AACENC_INIT_TRANSPORT =
+ 0x1000, /*!< Initialize transport lib with new parameters. */
+ AACENC_RESET_INBUFFER =
+ 0x2000, /*!< Reset fill level of internal input buffer. */
+ AACENC_INIT_ALL = 0xFFFF /*!< Initialize all. */
+} AACENC_CTRLFLAGS;
+
+/**
+ * \brief AAC encoder setting parameters.
+ *
+ * Use aacEncoder_SetParam() function to configure, or use aacEncoder_GetParam()
+ * function to read the internal status of the following parameters.
+ */
+typedef enum {
+ AACENC_AOT =
+ 0x0100, /*!< Audio object type. See ::AUDIO_OBJECT_TYPE in FDK_audio.h.
+ - 2: MPEG-4 AAC Low Complexity.
+ - 5: MPEG-4 AAC Low Complexity with Spectral Band Replication
+ (HE-AAC).
+ - 29: MPEG-4 AAC Low Complexity with Spectral Band
+ Replication and Parametric Stereo (HE-AAC v2). This
+ configuration can be used only with stereo input audio data.
+ - 23: MPEG-4 AAC Low-Delay.
+ - 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. The ELD
+ v2 212 configuration can be configured by ::AACENC_CHANNELMODE
+ parameter.
+ - 129: MPEG-2 AAC Low Complexity.
+ - 132: MPEG-2 AAC Low Complexity with Spectral Band
+ Replication (HE-AAC).
+
+ Please note that the virtual MPEG-2 AOT's basically disables
+ non-existing Perceptual Noise Substitution tool in AAC encoder
+ and controls the MPEG_ID flag in adts header. The virtual
+ MPEG-2 AOT doesn't prohibit specific transport formats. */
+
+ AACENC_BITRATE = 0x0101, /*!< Total encoder bitrate. This parameter is
+ mandatory and interacts with ::AACENC_BITRATEMODE.
+ - CBR: Bitrate in bits/second.
+ - VBR: Variable bitrate. Bitrate argument will
+ be ignored. See \ref suppBitrates for details. */
+
+ AACENC_BITRATEMODE = 0x0102, /*!< Bitrate mode. Configuration can be different
+ kind of bitrate configurations:
+ - 0: Constant bitrate, use bitrate according
+ to ::AACENC_BITRATE. (default) Within none
+ LD/ELD ::AUDIO_OBJECT_TYPE, the CBR mode makes
+ use of full allowed bitreservoir. In contrast,
+ at Low-Delay ::AUDIO_OBJECT_TYPE the
+ bitreservoir is kept very small.
+ - 1: Variable bitrate mode, \ref vbrmode
+ "very low bitrate".
+ - 2: Variable bitrate mode, \ref vbrmode
+ "low bitrate".
+ - 3: Variable bitrate mode, \ref vbrmode
+ "medium bitrate".
+ - 4: Variable bitrate mode, \ref vbrmode
+ "high bitrate".
+ - 5: Variable bitrate mode, \ref vbrmode
+ "very high bitrate". */
+
+ AACENC_SAMPLERATE = 0x0103, /*!< Audio input data sampling rate. Encoder
+ supports following sampling rates: 8000, 11025,
+ 12000, 16000, 22050, 24000, 32000, 44100,
+ 48000, 64000, 88200, 96000 */
+
+ AACENC_SBR_MODE = 0x0104, /*!< Configure SBR independently of the chosen Audio
+ Object Type ::AUDIO_OBJECT_TYPE. This parameter
+ is for ELD audio object type only.
+ - -1: Use ELD SBR auto configurator (default).
+ - 0: Disable Spectral Band Replication.
+ - 1: Enable Spectral Band Replication. */
+
+ AACENC_GRANULE_LENGTH =
+ 0x0105, /*!< Core encoder (AAC) audio frame length in samples:
+ - 1024: Default configuration.
+ - 960: DRM/DAB+.
+ - 512: Default length in LD/ELD configuration.
+ - 480: Length in LD/ELD configuration.
+ - 256: Length for ELD reduced delay mode (x2).
+ - 240: Length for ELD reduced delay mode (x2).
+ - 128: Length for ELD reduced delay mode (x4).
+ - 120: Length for ELD reduced delay mode (x4). */
+
+ AACENC_CHANNELMODE = 0x0106, /*!< Set explicit channel mode. Channel mode must
+ match with number of input channels.
+ - 1-7, 11,12,14 and 33,34: MPEG channel
+ modes supported, see ::CHANNEL_MODE in
+ FDK_audio.h. */
+
+ AACENC_CHANNELORDER =
+ 0x0107, /*!< Input audio data channel ordering scheme:
+ - 0: MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE).
+ (default)
+ - 1: WAVE file format channel ordering (e. g. 5.1: L, R, C,
+ LFE, SL, SR). */
+
+ AACENC_SBR_RATIO =
+ 0x0108, /*!< Controls activation of downsampled SBR. With downsampled
+ SBR, the delay will be shorter. On the other hand, for
+ achieving the same quality level, downsampled SBR needs more
+ bits than dual-rate SBR. With downsampled SBR, the AAC encoder
+ will work at the same sampling rate as the SBR encoder (single
+ rate). Downsampled SBR is supported for AAC-ELD and HE-AACv1.
+ - 1: Downsampled SBR (default for ELD).
+ - 2: Dual-rate SBR (default for HE-AAC). */
+
+ AACENC_AFTERBURNER =
+ 0x0200, /*!< This parameter controls the use of the afterburner feature.
+ The afterburner is a type of analysis by synthesis algorithm
+ which increases the audio quality but also the required
+ processing power. It is recommended to always activate this if
+ additional memory consumption and processing power consumption
+ is not a problem. If increased MHz and memory consumption are
+ an issue then the MHz and memory cost of this optional module
+ need to be evaluated against the improvement in audio quality
+ on a case by case basis.
+ - 0: Disable afterburner (default).
+ - 1: Enable afterburner. */
+
+ AACENC_BANDWIDTH = 0x0203, /*!< Core encoder audio bandwidth:
+ - 0: Determine audio bandwidth internally
+ (default, see chapter \ref BEHAVIOUR_BANDWIDTH).
+ - 1 to fs/2: Audio bandwidth in Hertz. Limited
+ to 20kHz max. Not usable if SBR is active. This
+ setting is for experts only, better do not 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 types can be configured
+ in encoder library:
+ - 0: raw access units
+ - 1: ADIF bitstream format
+ - 2: ADTS bitstream format
+ - 6: Audio Mux Elements (LATM) with
+ muxConfigPresent = 1
+ - 7: Audio Mux Elements (LATM) with
+ muxConfigPresent = 0, out of band StreamMuxConfig
+ - 10: Audio Sync Stream (LOAS) */
+
+ AACENC_HEADER_PERIOD =
+ 0x0301, /*!< Frame count period for sending in-band configuration buffers
+ within LATM/LOAS transport layer. Additionally this parameter
+ configures the PCE repetition period in raw_data_block(). See
+ \ref encPCE.
+ - 0xFF: auto-mode default 10 for TT_MP4_ADTS, TT_MP4_LOAS and
+ TT_MP4_LATM_MCP1, otherwise 0.
+ - n: Frame count period. */
+
+ AACENC_SIGNALING_MODE =
+ 0x0302, /*!< Signaling mode of the extension AOT:
+ - 0: Implicit backward compatible signaling (default for
+ non-MPEG-4 based AOT's and for the transport formats ADIF and
+ ADTS)
+ - A stream that uses implicit signaling can be decoded
+ by every AAC decoder, even AAC-LC-only decoders
+ - An AAC-LC-only decoder will only decode the
+ low-frequency part of the stream, resulting in a band-limited
+ output
+ - This method works with all transport formats
+ - This method does not work with downsampled SBR
+ - 1: Explicit backward compatible signaling
+ - A stream that uses explicit backward compatible
+ signaling can be decoded by every AAC decoder, even AAC-LC-only
+ decoders
+ - An AAC-LC-only decoder will only decode the
+ low-frequency part of the stream, resulting in a band-limited
+ output
+ - A decoder not capable of decoding PS will only decode
+ the AAC-LC+SBR part. If the stream contained PS, the result
+ will be a a decoded mono downmix
+ - This method does not work with ADIF or ADTS. For
+ LOAS/LATM, it only works with AudioMuxVersion==1
+ - This method does work with downsampled SBR
+ - 2: Explicit hierarchical signaling (default for MPEG-4
+ based AOT's and for all transport formats excluding ADIF and
+ ADTS)
+ - A stream that uses explicit hierarchical signaling can
+ be decoded only by HE-AAC decoders
+ - An AAC-LC-only decoder will not decode a stream that
+ uses explicit hierarchical signaling
+ - A decoder not capable of decoding PS will not decode
+ the stream at all if it contained PS
+ - This method does not work with ADIF or ADTS. It works
+ with LOAS/LATM and the MPEG-4 File format
+ - This method does work with downsampled SBR
+
+ For making sure that the listener always experiences the
+ best audio quality, explicit hierarchical signaling should be
+ used. This makes sure that only a full HE-AAC-capable decoder
+ will decode those streams. The audio is played at full
+ bandwidth. For best backwards compatibility, it is recommended
+ to encode with implicit SBR signaling. A decoder capable of
+ AAC-LC only will then only decode the AAC part, which means the
+ decoded audio will sound band-limited.
+
+ For MPEG-2 transport types (ADTS,ADIF), only implicit
+ signaling is possible.
+
+ For LOAS and LATM, explicit backwards compatible signaling
+ only works together with AudioMuxVersion==1. The reason is
+ that, for explicit backwards compatible signaling, additional
+ information will be appended to the ASC. A decoder that is only
+ capable of decoding AAC-LC will skip this part. Nevertheless,
+ for jumping to the end of the ASC, it needs to know the ASC
+ length. Transmitting the length of the ASC is a feature of
+ AudioMuxVersion==1, it is not possible to transmit the length
+ of the ASC with AudioMuxVersion==0, therefore an AAC-LC-only
+ decoder will not be able to parse a LOAS/LATM stream that was
+ being encoded with AudioMuxVersion==0.
+
+ For downsampled SBR, explicit signaling is mandatory. The
+ reason for this is that the extension sampling frequency (which
+ is in case of SBR the sampling frequqncy of the SBR part) can
+ only be signaled in explicit mode.
+
+ For AAC-ELD, the SBR information is transmitted in the
+ ELDSpecific Config, which is part of the AudioSpecificConfig.
+ Therefore, the settings here will have no effect on AAC-ELD.*/
+
+ AACENC_TPSUBFRAMES =
+ 0x0303, /*!< Number of sub frames in a transport frame for LOAS/LATM or
+ ADTS (default 1).
+ - ADTS: Maximum number of sub frames restricted to 4.
+ - DAB+: Maximum number of sub frames restricted to 6.
+ - 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 transport layer:
+ - 0: No protection. (default)
+ - 1: CRC active for ADTS transport format. */
+
+ AACENC_ANCILLARY_BITRATE =
+ 0x0500, /*!< Constant ancillary data bitrate in bits/second.
+ - 0: Either no ancillary data or insert exact number of
+ bytes, denoted via input parameter, numAncBytes in
+ AACENC_InArgs.
+ - else: Insert ancillary data with specified bitrate. */
+
+ AACENC_METADATA_MODE = 0x0600, /*!< Configure Meta Data. See ::AACENC_MetaData
+ for further details:
+ - 0: Do not embed any metadata.
+ - 1: Embed dynamic_range_info metadata.
+ - 2: Embed dynamic_range_info and
+ ancillary_data metadata.
+ - 3: Embed ancillary_data metadata. */
+
+ AACENC_CONTROL_STATE =
+ 0xFF00, /*!< There is an automatic process which internally reconfigures
+ the encoder instance when a configuration parameter changed or
+ an error occured. This paramerter allows overwriting or getting
+ the control status of this process. See ::AACENC_CTRLFLAGS. */
+
+ AACENC_NONE = 0xFFFF /*!< ------ */
+
+} AACENC_PARAM;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Open an instance of the encoder.
+ *
+ * Allocate memory for an encoder instance with a functional range denoted by
+ * the function parameters. Preinitialize encoder instance with default
+ * configuration.
+ *
+ * \param phAacEncoder A pointer to an encoder handle. Initialized on return.
+ * \param encModules Specify encoder modules to be supported in this encoder
+ * instance:
+ * - 0x0: Allocate memory for all available encoder
+ * modules.
+ * - else: Select memory allocation regarding encoder
+ * modules. Following flags are possible and can be combined.
+ * - 0x01: AAC module.
+ * - 0x02: SBR module.
+ * - 0x04: PS module.
+ * - 0x08: MPS module.
+ * - 0x10: Metadata module.
+ * - example: (0x01|0x02|0x04|0x08|0x10) allocates
+ * all modules and is equivalent to default configuration denotet by 0x0.
+ * \param maxChannels Number of channels to be allocated. This parameter can
+ * be used in different ways:
+ * - 0: Allocate maximum number of AAC and SBR channels as
+ * supported by the library.
+ * - nChannels: Use same maximum number of channels for
+ * allocating memory in AAC and SBR module.
+ * - nChannels | (nSbrCh<<8): Number of SBR channels can be
+ * different to AAC channels to save data memory.
+ *
+ * \return
+ * - AACENC_OK, on succes.
+ * - AACENC_INVALID_HANDLE, AACENC_MEMORY_ERROR, AACENC_INVALID_CONFIG,
+ * on failure.
+ */
+AACENC_ERROR aacEncOpen(HANDLE_AACENCODER *phAacEncoder, const UINT encModules,
+ const UINT maxChannels);
+
+/**
+ * \brief Close the encoder instance.
+ *
+ * Deallocate encoder instance and free whole memory.
+ *
+ * \param phAacEncoder Pointer to the encoder handle to be deallocated.
+ *
+ * \return
+ * - AACENC_OK, on success.
+ * - AACENC_INVALID_HANDLE, on failure.
+ */
+AACENC_ERROR aacEncClose(HANDLE_AACENCODER *phAacEncoder);
+
+/**
+ * \brief Encode audio data.
+ *
+ * This function is mainly for encoding audio data. In addition the function can
+ * be used for an encoder (re)configuration process.
+ * - PCM input data will be retrieved from external input buffer until the fill
+ * level allows encoding a single frame. This functionality allows an external
+ * buffer with reduced size in comparison to the AAC or HE-AAC audio frame
+ * length.
+ * - If the value of the input samples argument is zero, just internal
+ * reinitialization will be applied if it is requested.
+ * - At the end of a file the flushing process can be triggerd via setting the
+ * value of the input samples argument to -1. The encoder delay lines are fully
+ * flushed when the encoder returns no valid bitstream data
+ * AACENC_OutArgs::numOutBytes. Furthermore the end of file is signaled by the
+ * return value AACENC_ENCODE_EOF.
+ * - If an error occured in the previous frame or any of the encoder parameters
+ * changed, an internal reinitialization process will be applied before encoding
+ * the incoming audio samples.
+ * - The function can also be used for an independent reconfiguration process
+ * without encoding. The first parameter has to be a valid encoder handle and
+ * all other parameters can be set to NULL.
+ * - If the size of the external bitbuffer in outBufDesc is not sufficient for
+ * writing the whole bitstream, an internal error will be the return value and a
+ * reconfiguration will be triggered.
+ *
+ * \param hAacEncoder A valid AAC encoder handle.
+ * \param inBufDesc Input buffer descriptor, see AACENC_BufDesc:
+ * - At least one input buffer with audio data is
+ * expected.
+ * - Optionally a second input buffer with
+ * ancillary data can be fed.
+ * \param outBufDesc Output buffer descriptor, see AACENC_BufDesc:
+ * - Provide one output buffer for the encoded
+ * bitstream.
+ * \param inargs Input arguments, see AACENC_InArgs.
+ * \param outargs Output arguments, AACENC_OutArgs.
+ *
+ * \return
+ * - AACENC_OK, on success.
+ * - AACENC_INVALID_HANDLE, AACENC_ENCODE_ERROR, on failure in encoding
+ * process.
+ * - AACENC_INVALID_CONFIG, AACENC_INIT_ERROR, AACENC_INIT_AAC_ERROR,
+ * AACENC_INIT_SBR_ERROR, AACENC_INIT_TP_ERROR, AACENC_INIT_META_ERROR,
+ * AACENC_INIT_MPS_ERROR, on failure in encoder initialization.
+ * - AACENC_UNSUPPORTED_PARAMETER, on incorrect input or output buffer
+ * descriptor initialization.
+ * - AACENC_ENCODE_EOF, when flushing fully concluded.
+ */
+AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
+ const AACENC_BufDesc *inBufDesc,
+ const AACENC_BufDesc *outBufDesc,
+ const AACENC_InArgs *inargs, AACENC_OutArgs *outargs);
+
+/**
+ * \brief Acquire info about present encoder instance.
+ *
+ * This function retrieves information of the encoder configuration. In addition
+ * to informative internal states, a configuration data block of the current
+ * encoder settings will be returned. The format is either Audio Specific Config
+ * in case of Raw Packets transport format or StreamMuxConfig in case of
+ * LOAS/LATM transport format. The configuration data block is binary coded as
+ * specified in ISO/IEC 14496-3 (MPEG-4 audio), to be used directly for MPEG-4
+ * File Format or RFC3016 or RFC3640 applications.
+ *
+ * \param hAacEncoder A valid AAC encoder handle.
+ * \param pInfo Pointer to AACENC_InfoStruct. Filled on return.
+ *
+ * \return
+ * - AACENC_OK, on succes.
+ * - AACENC_INIT_ERROR, on failure.
+ */
+AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder,
+ AACENC_InfoStruct *pInfo);
+
+/**
+ * \brief Set one single AAC encoder parameter.
+ *
+ * This function allows configuration of all encoder parameters specified in
+ * ::AACENC_PARAM. Each parameter must be set with a separate function call. An
+ * internal validation of the configuration value range will be done and an
+ * internal reconfiguration will be signaled. The actual configuration adoption
+ * is part of the subsequent aacEncEncode() call.
+ *
+ * \param hAacEncoder A valid AAC encoder handle.
+ * \param param Parameter to be set. See ::AACENC_PARAM.
+ * \param value Parameter value. See parameter description in
+ * ::AACENC_PARAM.
+ *
+ * \return
+ * - AACENC_OK, on success.
+ * - AACENC_INVALID_HANDLE, AACENC_UNSUPPORTED_PARAMETER,
+ * AACENC_INVALID_CONFIG, on failure.
+ */
+AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
+ const AACENC_PARAM param, const UINT value);
+
+/**
+ * \brief Get one single AAC encoder parameter.
+ *
+ * This function is the complement to aacEncoder_SetParam(). After encoder
+ * reinitialization with user defined settings, the internal status can be
+ * obtained of each parameter, specified with ::AACENC_PARAM.
+ *
+ * \param hAacEncoder A valid AAC encoder handle.
+ * \param param Parameter to be returned. See ::AACENC_PARAM.
+ *
+ * \return Internal configuration value of specifed parameter ::AACENC_PARAM.
+ */
+UINT aacEncoder_GetParam(const HANDLE_AACENCODER hAacEncoder,
+ const AACENC_PARAM param);
+
+/**
+ * \brief Get information about encoder library build.
+ *
+ * Fill a given LIB_INFO structure with library version information.
+ *
+ * \param info Pointer to an allocated LIB_INFO struct.
+ *
+ * \return
+ * - AACENC_OK, on success.
+ * - AACENC_INVALID_HANDLE, AACENC_INIT_ERROR, on failure.
+ */
+AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AACENC_LIB_H */
diff --git a/fdk-aac/libAACenc/src/aacEnc_ram.cpp b/fdk-aac/libAACenc/src/aacEnc_ram.cpp
new file mode 100644
index 0000000..77b1131
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacEnc_ram.cpp
@@ -0,0 +1,208 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Memory layout
+ \author Markus Lohwasser
+*/
+
+#include "aacEnc_ram.h"
+
+C_AALLOC_MEM(AACdynamic_RAM, FIXP_DBL, AAC_ENC_DYN_RAM_SIZE / sizeof(FIXP_DBL))
+
+/*
+ Static memory areas, must not be overwritten in other sections of the decoder
+ !
+*/
+
+/*
+ The structure AacEncoder contains all Encoder structures.
+*/
+
+C_ALLOC_MEM(Ram_aacEnc_AacEncoder, struct AAC_ENC, 1)
+
+/*
+ The structure PSY_INTERNAl contains all psych configuration and data pointer.
+ * PsyStatic holds last and current Psych data.
+ * PsyInputBuffer contains time input. Signal is needed at the beginning of
+ Psych. Memory can be reused after signal is in time domain.
+ * PsyData contains spectral, nrg and threshold information. Necessary data
+ are copied into PsyOut, so memory is available after leaving psych.
+ * TnsData, ChaosMeasure, PnsData are temporarily necessary, e.g. use memory
+ from PsyInputBuffer.
+*/
+
+C_ALLOC_MEM2(Ram_aacEnc_PsyElement, PSY_ELEMENT, 1, ((8)))
+
+C_ALLOC_MEM(Ram_aacEnc_PsyInternal, PSY_INTERNAL, 1)
+C_ALLOC_MEM2(Ram_aacEnc_PsyStatic, PSY_STATIC, 1, (8))
+
+C_ALLOC_MEM2(Ram_aacEnc_PsyInputBuffer, INT_PCM, MAX_INPUT_BUFFER_SIZE, (8))
+
+PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic(int n, UCHAR *dynamic_RAM) {
+ FDK_ASSERT(dynamic_RAM != 0);
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * (dynamic_RAM + P_BUF_1 + n*sizeof(PSY_DYNAMIC)) is sufficiently aligned, so
+ * the cast is safe */
+ return reinterpret_cast<PSY_DYNAMIC *>(reinterpret_cast<void *>(
+ dynamic_RAM + P_BUF_1 + n * sizeof(PSY_DYNAMIC)));
+}
+
+/*
+ The structure PSY_OUT holds all psychoaccoustic data needed
+ in quantization module
+*/
+C_ALLOC_MEM2(Ram_aacEnc_PsyOut, PSY_OUT, 1, (1))
+
+C_ALLOC_MEM2(Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT, 1, (1) * ((8)))
+C_ALLOC_MEM2(Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL, 1, (1) * (8))
+
+/*
+ The structure QC_STATE contains preinitialized settings and quantizer
+ structures.
+ * AdjustThreshold structure contains element-wise settings.
+ * ElementBits contains elemnt-wise bit consumption settings.
+ * When CRC is active, lookup table is necessary for fast crc calculation.
+ * Bitcounter contains buffer to find optimal codebooks and minimal bit
+ consumption. Values are temporarily, so dynamic memory can be used.
+*/
+
+C_ALLOC_MEM(Ram_aacEnc_QCstate, QC_STATE, 1)
+C_ALLOC_MEM(Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE, 1)
+
+C_ALLOC_MEM2(Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT, 1, ((8)))
+C_ALLOC_MEM2(Ram_aacEnc_ElementBits, ELEMENT_BITS, 1, ((8)))
+C_ALLOC_MEM(Ram_aacEnc_BitCntrState, struct BITCNTR_STATE, 1)
+
+INT *GetRam_aacEnc_BitLookUp(int n, UCHAR *dynamic_RAM) {
+ FDK_ASSERT(dynamic_RAM != 0);
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * (dynamic_RAM + P_BUF_1) is sufficiently aligned, so the cast is safe */
+ return reinterpret_cast<INT *>(
+ reinterpret_cast<void *>(dynamic_RAM + P_BUF_1));
+}
+INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR *dynamic_RAM) {
+ FDK_ASSERT(dynamic_RAM != 0);
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * (dynamic_RAM + P_BUF_1 + sizeof(INT)*(MAX_SFB_LONG*(CODE_BOOK_ESC_NDX+1)))
+ * is sufficiently aligned, so the cast is safe */
+ return reinterpret_cast<INT *>(reinterpret_cast<void *>(
+ dynamic_RAM + P_BUF_1 +
+ sizeof(INT) * (MAX_SFB_LONG * (CODE_BOOK_ESC_NDX + 1))));
+}
+
+/*
+ The structure QC_OUT contains settings and structures holding all necessary
+ information needed in bitstreamwriter.
+*/
+
+C_ALLOC_MEM2(Ram_aacEnc_QCout, QC_OUT, 1, (1))
+C_ALLOC_MEM2(Ram_aacEnc_QCelement, QC_OUT_ELEMENT, 1, (1) * ((8)))
+QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel(int n, UCHAR *dynamic_RAM) {
+ FDK_ASSERT(dynamic_RAM != 0);
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * (dynamic_RAM + P_BUF_0 + n*sizeof(QC_OUT_CHANNEL)) is sufficiently aligned,
+ * so the cast is safe */
+ return reinterpret_cast<QC_OUT_CHANNEL *>(reinterpret_cast<void *>(
+ dynamic_RAM + P_BUF_0 + n * sizeof(QC_OUT_CHANNEL)));
+}
diff --git a/fdk-aac/libAACenc/src/aacEnc_ram.h b/fdk-aac/libAACenc/src/aacEnc_ram.h
new file mode 100644
index 0000000..0775aae
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacEnc_ram.h
@@ -0,0 +1,249 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Memory layout
+ \author Markus Lohwasser
+*/
+
+#ifndef AACENC_RAM_H
+#define AACENC_RAM_H
+
+#include "common_fix.h"
+
+#include "aacenc.h"
+#include "psy_data.h"
+#include "interface.h"
+#include "psy_main.h"
+#include "bitenc.h"
+#include "bit_cnt.h"
+#include "psy_const.h"
+
+#define OUTPUTBUFFER_SIZE \
+ (8192) /*!< Output buffer size has to be at least 6144 bits per channel \
+ (768 bytes). FDK bitbuffer implementation expects buffer of \
+ size 2^n. */
+
+/*
+ Moved AAC_ENC struct definition from aac_enc.cpp into aacEnc_ram.h to get size
+ and respective static memory in aacEnc_ram.cpp. aac_enc.h is the outward
+ visible header file and putting the struct into would cause necessity of
+ additional visible header files outside library.
+*/
+
+/* define hBitstream size: max AAC framelength is 6144 bits/channel */
+/*#define BUFFER_BITSTR_SIZE ((6400*(8)/bbWordSize) +((bbWordSize - 1) /
+ * bbWordSize))*/
+
+struct AAC_ENC {
+ AACENC_CONFIG *config;
+
+ INT ancillaryBitsPerFrame; /* ancillary bits per frame calculated from
+ ancillary rate */
+
+ CHANNEL_MAPPING channelMapping;
+
+ QC_STATE *qcKernel;
+ QC_OUT *qcOut[(1)];
+
+ PSY_OUT *psyOut[(1)];
+ PSY_INTERNAL *psyKernel;
+
+ /* lifetime vars */
+
+ CHANNEL_MODE encoderMode;
+ INT bandwidth90dB;
+ AACENC_BITRATE_MODE bitrateMode;
+
+ INT dontWriteAdif; /* use: write ADIF header only before 1st frame */
+
+ FIXP_DBL *dynamic_RAM;
+
+ INT maxChannels; /* used while allocation */
+ INT maxElements;
+ INT maxFrames;
+
+ AUDIO_OBJECT_TYPE aot; /* AOT to be used while encoding. */
+};
+
+#define maxSize(a, b) (((a) > (b)) ? (a) : (b))
+
+#define BIT_LOOK_UP_SIZE \
+ (sizeof(INT) * (MAX_SFB_LONG * (CODE_BOOK_ESC_NDX + 1)))
+#define MERGE_GAIN_LOOK_UP_SIZE (sizeof(INT) * MAX_SFB_LONG)
+
+/* Size of AhFlag buffer in function FDKaacEnc_adaptThresholdsToPe() */
+#define ADJ_THR_AH_FLAG_SIZE (sizeof(UCHAR) * ((8)) * (2) * MAX_GROUPED_SFB)
+/* Size of ThrExp buffer in function FDKaacEnc_adaptThresholdsToPe() */
+#define ADJ_THR_THR_EXP_SIZE (sizeof(FIXP_DBL) * ((8)) * (2) * MAX_GROUPED_SFB)
+/* Size of sfbNActiveLinesLdData buffer in function FDKaacEnc_correctThresh() */
+#define ADJ_THR_ACT_LIN_LD_DATA_SIZE \
+ (sizeof(FIXP_DBL) * ((8)) * (2) * MAX_GROUPED_SFB)
+/* Total amount of dynamic buffer needed in adjust thresholds functionality */
+#define ADJ_THR_SIZE \
+ (ADJ_THR_AH_FLAG_SIZE + ADJ_THR_THR_EXP_SIZE + ADJ_THR_ACT_LIN_LD_DATA_SIZE)
+
+/* Dynamic RAM - Allocation */
+/*
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | P_BUF_0 | P_BUF_1 |
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | QC_OUT_CH | PSY_DYN |
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | | BitLookUp+MergeGainLookUp |
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | | AH_FLAG | THR_EXP | ACT_LIN_LD_DATA |
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | | Bitstream output buffer |
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++
+*/
+
+#define BUF_SIZE_0 (ALIGN_SIZE(sizeof(QC_OUT_CHANNEL) * (8)))
+#define BUF_SIZE_1 \
+ (ALIGN_SIZE(maxSize(maxSize(sizeof(PSY_DYNAMIC), \
+ (BIT_LOOK_UP_SIZE + MERGE_GAIN_LOOK_UP_SIZE)), \
+ ADJ_THR_SIZE)))
+
+#define P_BUF_0 (0)
+#define P_BUF_1 (P_BUF_0 + BUF_SIZE_0)
+
+#define AAC_ENC_DYN_RAM_SIZE (BUF_SIZE_0 + BUF_SIZE_1)
+
+H_ALLOC_MEM(AACdynamic_RAM, FIXP_DBL)
+/*
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+END - Dynamic RAM - Allocation */
+
+/*
+ See further Memory Allocation details in aacEnc_ram.cpp
+*/
+H_ALLOC_MEM(Ram_aacEnc_AacEncoder, AAC_ENC)
+
+H_ALLOC_MEM(Ram_aacEnc_PsyElement, PSY_ELEMENT)
+
+H_ALLOC_MEM(Ram_aacEnc_PsyInternal, PSY_INTERNAL)
+H_ALLOC_MEM(Ram_aacEnc_PsyStatic, PSY_STATIC)
+H_ALLOC_MEM(Ram_aacEnc_PsyInputBuffer, INT_PCM)
+
+PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic(int n, UCHAR *dynamic_RAM);
+
+H_ALLOC_MEM(Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL)
+
+H_ALLOC_MEM(Ram_aacEnc_PsyOut, PSY_OUT)
+H_ALLOC_MEM(Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT)
+
+H_ALLOC_MEM(Ram_aacEnc_QCstate, QC_STATE)
+H_ALLOC_MEM(Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE)
+
+H_ALLOC_MEM(Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT)
+H_ALLOC_MEM(Ram_aacEnc_ElementBits, ELEMENT_BITS)
+H_ALLOC_MEM(Ram_aacEnc_BitCntrState, BITCNTR_STATE)
+
+INT *GetRam_aacEnc_BitLookUp(int n, UCHAR *dynamic_RAM);
+INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR *dynamic_RAM);
+QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel(int n, UCHAR *dynamic_RAM);
+
+H_ALLOC_MEM(Ram_aacEnc_QCout, QC_OUT)
+H_ALLOC_MEM(Ram_aacEnc_QCelement, QC_OUT_ELEMENT)
+
+#endif /* #ifndef AACENC_RAM_H */
diff --git a/fdk-aac/libAACenc/src/aacEnc_rom.cpp b/fdk-aac/libAACenc/src/aacEnc_rom.cpp
new file mode 100644
index 0000000..ac0fa9d
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacEnc_rom.cpp
@@ -0,0 +1,2486 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description:
+
+*******************************************************************************/
+
+#include "aacEnc_rom.h"
+
+/*
+ Huffman Tables
+*/
+const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3] = {
+ {{{0x000b0009, 0x00090007, 0x000b0009},
+ {0x000a0008, 0x00070006, 0x000a0008},
+ {0x000b0009, 0x00090008, 0x000b0009}},
+ {{0x000a0008, 0x00070006, 0x000a0007},
+ {0x00070006, 0x00050005, 0x00070006},
+ {0x00090007, 0x00070006, 0x000a0008}},
+ {{0x000b0009, 0x00090007, 0x000b0008},
+ {0x00090008, 0x00070006, 0x00090008},
+ {0x000b0009, 0x00090007, 0x000b0009}}},
+ {{{0x00090008, 0x00070006, 0x00090007},
+ {0x00070006, 0x00050005, 0x00070006},
+ {0x00090007, 0x00070006, 0x00090008}},
+ {{0x00070006, 0x00050005, 0x00070006},
+ {0x00050005, 0x00010003, 0x00050005},
+ {0x00070006, 0x00050005, 0x00070006}},
+ {{0x00090008, 0x00070006, 0x00090007},
+ {0x00070006, 0x00050005, 0x00070006},
+ {0x00090008, 0x00070006, 0x00090008}}},
+ {{{0x000b0009, 0x00090007, 0x000b0009},
+ {0x00090008, 0x00070006, 0x00090008},
+ {0x000b0008, 0x00090007, 0x000b0009}},
+ {{0x000a0008, 0x00070006, 0x00090007},
+ {0x00070006, 0x00050004, 0x00070006},
+ {0x00090008, 0x00070006, 0x000a0007}},
+ {{0x000b0009, 0x00090007, 0x000b0009},
+ {0x000a0007, 0x00070006, 0x00090008},
+ {0x000b0009, 0x00090007, 0x000b0009}}}};
+
+const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3] = {
+ {{{0x00010004, 0x00040005, 0x00080008},
+ {0x00040005, 0x00050004, 0x00080008},
+ {0x00090009, 0x00090008, 0x000a000b}},
+ {{0x00040005, 0x00060005, 0x00090008},
+ {0x00060005, 0x00060004, 0x00090008},
+ {0x00090008, 0x00090007, 0x000a000a}},
+ {{0x00090009, 0x000a0008, 0x000d000b},
+ {0x00090008, 0x00090008, 0x000b000a},
+ {0x000b000b, 0x000a000a, 0x000c000b}}},
+ {{{0x00040004, 0x00060005, 0x000a0008},
+ {0x00060004, 0x00070004, 0x000a0008},
+ {0x000a0008, 0x000a0008, 0x000c000a}},
+ {{0x00050004, 0x00070004, 0x000b0008},
+ {0x00060004, 0x00070004, 0x000a0007},
+ {0x00090008, 0x00090007, 0x000b0009}},
+ {{0x00090008, 0x000a0008, 0x000d000a},
+ {0x00080007, 0x00090007, 0x000c0009},
+ {0x000a000a, 0x000b0009, 0x000c000a}}},
+ {{{0x00080008, 0x000a0008, 0x000f000b},
+ {0x00090008, 0x000b0007, 0x000f000a},
+ {0x000d000b, 0x000e000a, 0x0010000c}},
+ {{0x00080008, 0x000a0007, 0x000e000a},
+ {0x00090007, 0x000a0007, 0x000e0009},
+ {0x000c000a, 0x000c0009, 0x000f000b}},
+ {{0x000b000b, 0x000c000a, 0x0010000c},
+ {0x000a000a, 0x000b0009, 0x000f000b},
+ {0x000c000b, 0x000c000a, 0x000f000b}}}};
+
+const ULONG FDKaacEnc_huff_ltab5_6[9][9] = {
+ {0x000d000b, 0x000c000a, 0x000b0009, 0x000b0009, 0x000a0009, 0x000b0009,
+ 0x000b0009, 0x000c000a, 0x000d000b},
+ {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007,
+ 0x000a0008, 0x000b0009, 0x000c000a},
+ {0x000c0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006,
+ 0x00090006, 0x000a0008, 0x000b0009},
+ {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004,
+ 0x00080006, 0x00090007, 0x000b0009},
+ {0x000a0009, 0x00080007, 0x00070006, 0x00040004, 0x00010004, 0x00040004,
+ 0x00070006, 0x00080007, 0x000b0009},
+ {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004,
+ 0x00080006, 0x00090007, 0x000b0009},
+ {0x000b0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006,
+ 0x00090006, 0x000a0008, 0x000b0009},
+ {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007,
+ 0x000a0007, 0x000b0008, 0x000c000a},
+ {0x000d000b, 0x000c000a, 0x000c0009, 0x000b0009, 0x000a0009, 0x000a0009,
+ 0x000b0009, 0x000c000a, 0x000d000b}};
+
+const ULONG FDKaacEnc_huff_ltab7_8[8][8] = {
+ {0x00010005, 0x00030004, 0x00060005, 0x00070006, 0x00080007, 0x00090008,
+ 0x000a0009, 0x000b000a},
+ {0x00030004, 0x00040003, 0x00060004, 0x00070005, 0x00080006, 0x00080007,
+ 0x00090007, 0x00090008},
+ {0x00060005, 0x00060004, 0x00070004, 0x00080005, 0x00080006, 0x00090007,
+ 0x00090007, 0x000a0008},
+ {0x00070006, 0x00070005, 0x00080005, 0x00080006, 0x00090006, 0x00090007,
+ 0x000a0008, 0x000a0008},
+ {0x00080007, 0x00080006, 0x00090006, 0x00090006, 0x000a0007, 0x000a0007,
+ 0x000a0008, 0x000b0009},
+ {0x00090008, 0x00080007, 0x00090006, 0x00090007, 0x000a0007, 0x000a0008,
+ 0x000b0008, 0x000b000a},
+ {0x000a0009, 0x00090007, 0x00090007, 0x000a0008, 0x000a0008, 0x000b0008,
+ 0x000c0009, 0x000c0009},
+ {0x000b000a, 0x000a0008, 0x000a0008, 0x000a0008, 0x000b0009, 0x000b0009,
+ 0x000c0009, 0x000c000a}};
+
+const ULONG FDKaacEnc_huff_ltab9_10[13][13] = {
+ {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},
+ {0x00060006, 0x00060004, 0x00070005, 0x00080005, 0x00080006, 0x00090006,
+ 0x000a0007, 0x000a0008, 0x000a0008, 0x000b0009, 0x000c0009, 0x000c000a,
+ 0x000c000a},
+ {0x00080006, 0x00070005, 0x00080005, 0x00090005, 0x00090006, 0x000a0007,
+ 0x000a0007, 0x000b0008, 0x000b0008, 0x000b0009, 0x000c0009, 0x000c000a,
+ 0x000d000a},
+ {0x00090007, 0x00080006, 0x00090006, 0x00090006, 0x000a0006, 0x000a0007,
+ 0x000b0007, 0x000b0008, 0x000b0008, 0x000c0009, 0x000c0009, 0x000c000a,
+ 0x000d000a},
+ {0x000a0008, 0x00090007, 0x00090006, 0x000a0007, 0x000b0007, 0x000b0007,
+ 0x000b0008, 0x000c0008, 0x000b0008, 0x000c0009, 0x000c000a, 0x000d000a,
+ 0x000d000b},
+ {0x000b0009, 0x00090007, 0x000a0007, 0x000b0007, 0x000b0007, 0x000b0008,
+ 0x000c0008, 0x000c0009, 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a,
+ 0x000d000b},
+ {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000c0008,
+ 0x000c0009, 0x000d0009, 0x000d0009, 0x000d000a, 0x000d000a, 0x000d000b,
+ 0x000d000b},
+ {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000b0008,
+ 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a, 0x000e000a, 0x000d000b,
+ 0x000e000b},
+ {0x000b000a, 0x000a0009, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009,
+ 0x000c0009, 0x000c000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b,
+ 0x000e000c},
+ {0x000c000a, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009, 0x000c000a,
+ 0x000d000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b, 0x000e000b,
+ 0x000f000c},
+ {0x000c000b, 0x000b000a, 0x000c0009, 0x000c000a, 0x000c000a, 0x000d000a,
+ 0x000d000a, 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000b, 0x000f000b,
+ 0x000f000c},
+ {0x000d000b, 0x000c000a, 0x000c000a, 0x000c000a, 0x000d000a, 0x000d000a,
+ 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000c, 0x000e000c, 0x000e000c,
+ 0x000f000c}};
+
+const UCHAR FDKaacEnc_huff_ltab11[17][17] = {
+ {0x04, 0x05, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x0c, 0x0b, 0x0c, 0x0c, 0x0a},
+ {0x05, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0b, 0x08},
+ {0x06, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x07, 0x06, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x08},
+ {0x0a, 0x09, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0b, 0x08},
+ {0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0b, 0x0b, 0x08},
+ {0x0b, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x0b, 0x0a, 0x0b, 0x0b, 0x08},
+ {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x08},
+ {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x09},
+ {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x09},
+ {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x09},
+ {0x0c, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0c, 0x0c, 0x09},
+ {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x09, 0x05}};
+
+const UCHAR FDKaacEnc_huff_ltabscf[121] = {
+ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x12, 0x13, 0x12,
+ 0x11, 0x11, 0x10, 0x11, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0e,
+ 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0b,
+ 0x0c, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x07,
+ 0x06, 0x06, 0x05, 0x04, 0x03, 0x01, 0x04, 0x04, 0x05, 0x06, 0x06,
+ 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x10, 0x0f,
+ 0x10, 0x0f, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13};
+
+const USHORT FDKaacEnc_huff_ctab1[3][3][3][3] = {{{{0x07f8, 0x01f1, 0x07fd},
+ {0x03f5, 0x0068, 0x03f0},
+ {0x07f7, 0x01ec, 0x07f5}},
+ {{0x03f1, 0x0072, 0x03f4},
+ {0x0074, 0x0011, 0x0076},
+ {0x01eb, 0x006c, 0x03f6}},
+ {{0x07fc, 0x01e1, 0x07f1},
+ {0x01f0, 0x0061, 0x01f6},
+ {0x07f2, 0x01ea, 0x07fb}}},
+ {{{0x01f2, 0x0069, 0x01ed},
+ {0x0077, 0x0017, 0x006f},
+ {0x01e6, 0x0064, 0x01e5}},
+ {{0x0067, 0x0015, 0x0062},
+ {0x0012, 0x0000, 0x0014},
+ {0x0065, 0x0016, 0x006d}},
+ {{0x01e9, 0x0063, 0x01e4},
+ {0x006b, 0x0013, 0x0071},
+ {0x01e3, 0x0070, 0x01f3}}},
+ {{{0x07fe, 0x01e7, 0x07f3},
+ {0x01ef, 0x0060, 0x01ee},
+ {0x07f0, 0x01e2, 0x07fa}},
+ {{0x03f3, 0x006a, 0x01e8},
+ {0x0075, 0x0010, 0x0073},
+ {0x01f4, 0x006e, 0x03f7}},
+ {{0x07f6, 0x01e0, 0x07f9},
+ {0x03f2, 0x0066, 0x01f5},
+ {0x07ff, 0x01f7, 0x07f4}}}};
+
+const USHORT FDKaacEnc_huff_ctab2[3][3][3][3] = {{{{0x01f3, 0x006f, 0x01fd},
+ {0x00eb, 0x0023, 0x00ea},
+ {0x01f7, 0x00e8, 0x01fa}},
+ {{0x00f2, 0x002d, 0x0070},
+ {0x0020, 0x0006, 0x002b},
+ {0x006e, 0x0028, 0x00e9}},
+ {{0x01f9, 0x0066, 0x00f8},
+ {0x00e7, 0x001b, 0x00f1},
+ {0x01f4, 0x006b, 0x01f5}}},
+ {{{0x00ec, 0x002a, 0x006c},
+ {0x002c, 0x000a, 0x0027},
+ {0x0067, 0x001a, 0x00f5}},
+ {{0x0024, 0x0008, 0x001f},
+ {0x0009, 0x0000, 0x0007},
+ {0x001d, 0x000b, 0x0030}},
+ {{0x00ef, 0x001c, 0x0064},
+ {0x001e, 0x000c, 0x0029},
+ {0x00f3, 0x002f, 0x00f0}}},
+ {{{0x01fc, 0x0071, 0x01f2},
+ {0x00f4, 0x0021, 0x00e6},
+ {0x00f7, 0x0068, 0x01f8}},
+ {{0x00ee, 0x0022, 0x0065},
+ {0x0031, 0x0002, 0x0026},
+ {0x00ed, 0x0025, 0x006a}},
+ {{0x01fb, 0x0072, 0x01fe},
+ {0x0069, 0x002e, 0x00f6},
+ {0x01ff, 0x006d, 0x01f6}}}};
+
+const USHORT FDKaacEnc_huff_ctab3[3][3][3][3] = {{{{0x0000, 0x0009, 0x00ef},
+ {0x000b, 0x0019, 0x00f0},
+ {0x01eb, 0x01e6, 0x03f2}},
+ {{0x000a, 0x0035, 0x01ef},
+ {0x0034, 0x0037, 0x01e9},
+ {0x01ed, 0x01e7, 0x03f3}},
+ {{0x01ee, 0x03ed, 0x1ffa},
+ {0x01ec, 0x01f2, 0x07f9},
+ {0x07f8, 0x03f8, 0x0ff8}}},
+ {{{0x0008, 0x0038, 0x03f6},
+ {0x0036, 0x0075, 0x03f1},
+ {0x03eb, 0x03ec, 0x0ff4}},
+ {{0x0018, 0x0076, 0x07f4},
+ {0x0039, 0x0074, 0x03ef},
+ {0x01f3, 0x01f4, 0x07f6}},
+ {{0x01e8, 0x03ea, 0x1ffc},
+ {0x00f2, 0x01f1, 0x0ffb},
+ {0x03f5, 0x07f3, 0x0ffc}}},
+ {{{0x00ee, 0x03f7, 0x7ffe},
+ {0x01f0, 0x07f5, 0x7ffd},
+ {0x1ffb, 0x3ffa, 0xffff}},
+ {{0x00f1, 0x03f0, 0x3ffc},
+ {0x01ea, 0x03ee, 0x3ffb},
+ {0x0ff6, 0x0ffa, 0x7ffc}},
+ {{0x07f2, 0x0ff5, 0xfffe},
+ {0x03f4, 0x07f7, 0x7ffb},
+ {0x0ff7, 0x0ff9, 0x7ffa}}}};
+
+const USHORT FDKaacEnc_huff_ctab4[3][3][3][3] = {{{{0x0007, 0x0016, 0x00f6},
+ {0x0018, 0x0008, 0x00ef},
+ {0x01ef, 0x00f3, 0x07f8}},
+ {{0x0019, 0x0017, 0x00ed},
+ {0x0015, 0x0001, 0x00e2},
+ {0x00f0, 0x0070, 0x03f0}},
+ {{0x01ee, 0x00f1, 0x07fa},
+ {0x00ee, 0x00e4, 0x03f2},
+ {0x07f6, 0x03ef, 0x07fd}}},
+ {{{0x0005, 0x0014, 0x00f2},
+ {0x0009, 0x0004, 0x00e5},
+ {0x00f4, 0x00e8, 0x03f4}},
+ {{0x0006, 0x0002, 0x00e7},
+ {0x0003, 0x0000, 0x006b},
+ {0x00e3, 0x0069, 0x01f3}},
+ {{0x00eb, 0x00e6, 0x03f6},
+ {0x006e, 0x006a, 0x01f4},
+ {0x03ec, 0x01f0, 0x03f9}}},
+ {{{0x00f5, 0x00ec, 0x07fb},
+ {0x00ea, 0x006f, 0x03f7},
+ {0x07f9, 0x03f3, 0x0fff}},
+ {{0x00e9, 0x006d, 0x03f8},
+ {0x006c, 0x0068, 0x01f5},
+ {0x03ee, 0x01f2, 0x07f4}},
+ {{0x07f7, 0x03f1, 0x0ffe},
+ {0x03ed, 0x01f1, 0x07f5},
+ {0x07fe, 0x03f5, 0x07fc}}}};
+
+const USHORT FDKaacEnc_huff_ctab5[9][9] = {
+ {0x1fff, 0x0ff7, 0x07f4, 0x07e8, 0x03f1, 0x07ee, 0x07f9, 0x0ff8, 0x1ffd},
+ {0x0ffd, 0x07f1, 0x03e8, 0x01e8, 0x00f0, 0x01ec, 0x03ee, 0x07f2, 0x0ffa},
+ {0x0ff4, 0x03ef, 0x01f2, 0x00e8, 0x0070, 0x00ec, 0x01f0, 0x03ea, 0x07f3},
+ {0x07eb, 0x01eb, 0x00ea, 0x001a, 0x0008, 0x0019, 0x00ee, 0x01ef, 0x07ed},
+ {0x03f0, 0x00f2, 0x0073, 0x000b, 0x0000, 0x000a, 0x0071, 0x00f3, 0x07e9},
+ {0x07ef, 0x01ee, 0x00ef, 0x0018, 0x0009, 0x001b, 0x00eb, 0x01e9, 0x07ec},
+ {0x07f6, 0x03eb, 0x01f3, 0x00ed, 0x0072, 0x00e9, 0x01f1, 0x03ed, 0x07f7},
+ {0x0ff6, 0x07f0, 0x03e9, 0x01ed, 0x00f1, 0x01ea, 0x03ec, 0x07f8, 0x0ff9},
+ {0x1ffc, 0x0ffc, 0x0ff5, 0x07ea, 0x03f3, 0x03f2, 0x07f5, 0x0ffb, 0x1ffe}};
+
+const USHORT FDKaacEnc_huff_ctab6[9][9] = {
+ {0x07fe, 0x03fd, 0x01f1, 0x01eb, 0x01f4, 0x01ea, 0x01f0, 0x03fc, 0x07fd},
+ {0x03f6, 0x01e5, 0x00ea, 0x006c, 0x0071, 0x0068, 0x00f0, 0x01e6, 0x03f7},
+ {0x01f3, 0x00ef, 0x0032, 0x0027, 0x0028, 0x0026, 0x0031, 0x00eb, 0x01f7},
+ {0x01e8, 0x006f, 0x002e, 0x0008, 0x0004, 0x0006, 0x0029, 0x006b, 0x01ee},
+ {0x01ef, 0x0072, 0x002d, 0x0002, 0x0000, 0x0003, 0x002f, 0x0073, 0x01fa},
+ {0x01e7, 0x006e, 0x002b, 0x0007, 0x0001, 0x0005, 0x002c, 0x006d, 0x01ec},
+ {0x01f9, 0x00ee, 0x0030, 0x0024, 0x002a, 0x0025, 0x0033, 0x00ec, 0x01f2},
+ {0x03f8, 0x01e4, 0x00ed, 0x006a, 0x0070, 0x0069, 0x0074, 0x00f1, 0x03fa},
+ {0x07ff, 0x03f9, 0x01f6, 0x01ed, 0x01f8, 0x01e9, 0x01f5, 0x03fb, 0x07fc}};
+
+const USHORT FDKaacEnc_huff_ctab7[8][8] = {
+ {0x0000, 0x0005, 0x0037, 0x0074, 0x00f2, 0x01eb, 0x03ed, 0x07f7},
+ {0x0004, 0x000c, 0x0035, 0x0071, 0x00ec, 0x00ee, 0x01ee, 0x01f5},
+ {0x0036, 0x0034, 0x0072, 0x00ea, 0x00f1, 0x01e9, 0x01f3, 0x03f5},
+ {0x0073, 0x0070, 0x00eb, 0x00f0, 0x01f1, 0x01f0, 0x03ec, 0x03fa},
+ {0x00f3, 0x00ed, 0x01e8, 0x01ef, 0x03ef, 0x03f1, 0x03f9, 0x07fb},
+ {0x01ed, 0x00ef, 0x01ea, 0x01f2, 0x03f3, 0x03f8, 0x07f9, 0x07fc},
+ {0x03ee, 0x01ec, 0x01f4, 0x03f4, 0x03f7, 0x07f8, 0x0ffd, 0x0ffe},
+ {0x07f6, 0x03f0, 0x03f2, 0x03f6, 0x07fa, 0x07fd, 0x0ffc, 0x0fff}};
+
+const USHORT FDKaacEnc_huff_ctab8[8][8] = {
+ {0x000e, 0x0005, 0x0010, 0x0030, 0x006f, 0x00f1, 0x01fa, 0x03fe},
+ {0x0003, 0x0000, 0x0004, 0x0012, 0x002c, 0x006a, 0x0075, 0x00f8},
+ {0x000f, 0x0002, 0x0006, 0x0014, 0x002e, 0x0069, 0x0072, 0x00f5},
+ {0x002f, 0x0011, 0x0013, 0x002a, 0x0032, 0x006c, 0x00ec, 0x00fa},
+ {0x0071, 0x002b, 0x002d, 0x0031, 0x006d, 0x0070, 0x00f2, 0x01f9},
+ {0x00ef, 0x0068, 0x0033, 0x006b, 0x006e, 0x00ee, 0x00f9, 0x03fc},
+ {0x01f8, 0x0074, 0x0073, 0x00ed, 0x00f0, 0x00f6, 0x01f6, 0x01fd},
+ {0x03fd, 0x00f3, 0x00f4, 0x00f7, 0x01f7, 0x01fb, 0x01fc, 0x03ff}};
+
+const USHORT FDKaacEnc_huff_ctab9[13][13] = {
+ {0x0000, 0x0005, 0x0037, 0x00e7, 0x01de, 0x03ce, 0x03d9, 0x07c8, 0x07cd,
+ 0x0fc8, 0x0fdd, 0x1fe4, 0x1fec},
+ {0x0004, 0x000c, 0x0035, 0x0072, 0x00ea, 0x00ed, 0x01e2, 0x03d1, 0x03d3,
+ 0x03e0, 0x07d8, 0x0fcf, 0x0fd5},
+ {0x0036, 0x0034, 0x0071, 0x00e8, 0x00ec, 0x01e1, 0x03cf, 0x03dd, 0x03db,
+ 0x07d0, 0x0fc7, 0x0fd4, 0x0fe4},
+ {0x00e6, 0x0070, 0x00e9, 0x01dd, 0x01e3, 0x03d2, 0x03dc, 0x07cc, 0x07ca,
+ 0x07de, 0x0fd8, 0x0fea, 0x1fdb},
+ {0x01df, 0x00eb, 0x01dc, 0x01e6, 0x03d5, 0x03de, 0x07cb, 0x07dd, 0x07dc,
+ 0x0fcd, 0x0fe2, 0x0fe7, 0x1fe1},
+ {0x03d0, 0x01e0, 0x01e4, 0x03d6, 0x07c5, 0x07d1, 0x07db, 0x0fd2, 0x07e0,
+ 0x0fd9, 0x0feb, 0x1fe3, 0x1fe9},
+ {0x07c4, 0x01e5, 0x03d7, 0x07c6, 0x07cf, 0x07da, 0x0fcb, 0x0fda, 0x0fe3,
+ 0x0fe9, 0x1fe6, 0x1ff3, 0x1ff7},
+ {0x07d3, 0x03d8, 0x03e1, 0x07d4, 0x07d9, 0x0fd3, 0x0fde, 0x1fdd, 0x1fd9,
+ 0x1fe2, 0x1fea, 0x1ff1, 0x1ff6},
+ {0x07d2, 0x03d4, 0x03da, 0x07c7, 0x07d7, 0x07e2, 0x0fce, 0x0fdb, 0x1fd8,
+ 0x1fee, 0x3ff0, 0x1ff4, 0x3ff2},
+ {0x07e1, 0x03df, 0x07c9, 0x07d6, 0x0fca, 0x0fd0, 0x0fe5, 0x0fe6, 0x1feb,
+ 0x1fef, 0x3ff3, 0x3ff4, 0x3ff5},
+ {0x0fe0, 0x07ce, 0x07d5, 0x0fc6, 0x0fd1, 0x0fe1, 0x1fe0, 0x1fe8, 0x1ff0,
+ 0x3ff1, 0x3ff8, 0x3ff6, 0x7ffc},
+ {0x0fe8, 0x07df, 0x0fc9, 0x0fd7, 0x0fdc, 0x1fdc, 0x1fdf, 0x1fed, 0x1ff5,
+ 0x3ff9, 0x3ffb, 0x7ffd, 0x7ffe},
+ {0x1fe7, 0x0fcc, 0x0fd6, 0x0fdf, 0x1fde, 0x1fda, 0x1fe5, 0x1ff2, 0x3ffa,
+ 0x3ff7, 0x3ffc, 0x3ffd, 0x7fff}};
+
+const USHORT FDKaacEnc_huff_ctab10[13][13] = {
+ {0x0022, 0x0008, 0x001d, 0x0026, 0x005f, 0x00d3, 0x01cf, 0x03d0, 0x03d7,
+ 0x03ed, 0x07f0, 0x07f6, 0x0ffd},
+ {0x0007, 0x0000, 0x0001, 0x0009, 0x0020, 0x0054, 0x0060, 0x00d5, 0x00dc,
+ 0x01d4, 0x03cd, 0x03de, 0x07e7},
+ {0x001c, 0x0002, 0x0006, 0x000c, 0x001e, 0x0028, 0x005b, 0x00cd, 0x00d9,
+ 0x01ce, 0x01dc, 0x03d9, 0x03f1},
+ {0x0025, 0x000b, 0x000a, 0x000d, 0x0024, 0x0057, 0x0061, 0x00cc, 0x00dd,
+ 0x01cc, 0x01de, 0x03d3, 0x03e7},
+ {0x005d, 0x0021, 0x001f, 0x0023, 0x0027, 0x0059, 0x0064, 0x00d8, 0x00df,
+ 0x01d2, 0x01e2, 0x03dd, 0x03ee},
+ {0x00d1, 0x0055, 0x0029, 0x0056, 0x0058, 0x0062, 0x00ce, 0x00e0, 0x00e2,
+ 0x01da, 0x03d4, 0x03e3, 0x07eb},
+ {0x01c9, 0x005e, 0x005a, 0x005c, 0x0063, 0x00ca, 0x00da, 0x01c7, 0x01ca,
+ 0x01e0, 0x03db, 0x03e8, 0x07ec},
+ {0x01e3, 0x00d2, 0x00cb, 0x00d0, 0x00d7, 0x00db, 0x01c6, 0x01d5, 0x01d8,
+ 0x03ca, 0x03da, 0x07ea, 0x07f1},
+ {0x01e1, 0x00d4, 0x00cf, 0x00d6, 0x00de, 0x00e1, 0x01d0, 0x01d6, 0x03d1,
+ 0x03d5, 0x03f2, 0x07ee, 0x07fb},
+ {0x03e9, 0x01cd, 0x01c8, 0x01cb, 0x01d1, 0x01d7, 0x01df, 0x03cf, 0x03e0,
+ 0x03ef, 0x07e6, 0x07f8, 0x0ffa},
+ {0x03eb, 0x01dd, 0x01d3, 0x01d9, 0x01db, 0x03d2, 0x03cc, 0x03dc, 0x03ea,
+ 0x07ed, 0x07f3, 0x07f9, 0x0ff9},
+ {0x07f2, 0x03ce, 0x01e4, 0x03cb, 0x03d8, 0x03d6, 0x03e2, 0x03e5, 0x07e8,
+ 0x07f4, 0x07f5, 0x07f7, 0x0ffb},
+ {0x07fa, 0x03ec, 0x03df, 0x03e1, 0x03e4, 0x03e6, 0x03f0, 0x07e9, 0x07ef,
+ 0x0ff8, 0x0ffe, 0x0ffc, 0x0fff}};
+
+const USHORT FDKaacEnc_huff_ctab11[21][17] = {
+ {0x0000, 0x0006, 0x0019, 0x003d, 0x009c, 0x00c6, 0x01a7, 0x0390, 0x03c2,
+ 0x03df, 0x07e6, 0x07f3, 0x0ffb, 0x07ec, 0x0ffa, 0x0ffe, 0x038e},
+ {0x0005, 0x0001, 0x0008, 0x0014, 0x0037, 0x0042, 0x0092, 0x00af, 0x0191,
+ 0x01a5, 0x01b5, 0x039e, 0x03c0, 0x03a2, 0x03cd, 0x07d6, 0x00ae},
+ {0x0017, 0x0007, 0x0009, 0x0018, 0x0039, 0x0040, 0x008e, 0x00a3, 0x00b8,
+ 0x0199, 0x01ac, 0x01c1, 0x03b1, 0x0396, 0x03be, 0x03ca, 0x009d},
+ {0x003c, 0x0015, 0x0016, 0x001a, 0x003b, 0x0044, 0x0091, 0x00a5, 0x00be,
+ 0x0196, 0x01ae, 0x01b9, 0x03a1, 0x0391, 0x03a5, 0x03d5, 0x0094},
+ {0x009a, 0x0036, 0x0038, 0x003a, 0x0041, 0x008c, 0x009b, 0x00b0, 0x00c3,
+ 0x019e, 0x01ab, 0x01bc, 0x039f, 0x038f, 0x03a9, 0x03cf, 0x0093},
+ {0x00bf, 0x003e, 0x003f, 0x0043, 0x0045, 0x009e, 0x00a7, 0x00b9, 0x0194,
+ 0x01a2, 0x01ba, 0x01c3, 0x03a6, 0x03a7, 0x03bb, 0x03d4, 0x009f},
+ {0x01a0, 0x008f, 0x008d, 0x0090, 0x0098, 0x00a6, 0x00b6, 0x00c4, 0x019f,
+ 0x01af, 0x01bf, 0x0399, 0x03bf, 0x03b4, 0x03c9, 0x03e7, 0x00a8},
+ {0x01b6, 0x00ab, 0x00a4, 0x00aa, 0x00b2, 0x00c2, 0x00c5, 0x0198, 0x01a4,
+ 0x01b8, 0x038c, 0x03a4, 0x03c4, 0x03c6, 0x03dd, 0x03e8, 0x00ad},
+ {0x03af, 0x0192, 0x00bd, 0x00bc, 0x018e, 0x0197, 0x019a, 0x01a3, 0x01b1,
+ 0x038d, 0x0398, 0x03b7, 0x03d3, 0x03d1, 0x03db, 0x07dd, 0x00b4},
+ {0x03de, 0x01a9, 0x019b, 0x019c, 0x01a1, 0x01aa, 0x01ad, 0x01b3, 0x038b,
+ 0x03b2, 0x03b8, 0x03ce, 0x03e1, 0x03e0, 0x07d2, 0x07e5, 0x00b7},
+ {0x07e3, 0x01bb, 0x01a8, 0x01a6, 0x01b0, 0x01b2, 0x01b7, 0x039b, 0x039a,
+ 0x03ba, 0x03b5, 0x03d6, 0x07d7, 0x03e4, 0x07d8, 0x07ea, 0x00ba},
+ {0x07e8, 0x03a0, 0x01bd, 0x01b4, 0x038a, 0x01c4, 0x0392, 0x03aa, 0x03b0,
+ 0x03bc, 0x03d7, 0x07d4, 0x07dc, 0x07db, 0x07d5, 0x07f0, 0x00c1},
+ {0x07fb, 0x03c8, 0x03a3, 0x0395, 0x039d, 0x03ac, 0x03ae, 0x03c5, 0x03d8,
+ 0x03e2, 0x03e6, 0x07e4, 0x07e7, 0x07e0, 0x07e9, 0x07f7, 0x0190},
+ {0x07f2, 0x0393, 0x01be, 0x01c0, 0x0394, 0x0397, 0x03ad, 0x03c3, 0x03c1,
+ 0x03d2, 0x07da, 0x07d9, 0x07df, 0x07eb, 0x07f4, 0x07fa, 0x0195},
+ {0x07f8, 0x03bd, 0x039c, 0x03ab, 0x03a8, 0x03b3, 0x03b9, 0x03d0, 0x03e3,
+ 0x03e5, 0x07e2, 0x07de, 0x07ed, 0x07f1, 0x07f9, 0x07fc, 0x0193},
+ {0x0ffd, 0x03dc, 0x03b6, 0x03c7, 0x03cc, 0x03cb, 0x03d9, 0x03da, 0x07d3,
+ 0x07e1, 0x07ee, 0x07ef, 0x07f5, 0x07f6, 0x0ffc, 0x0fff, 0x019d},
+ {0x01c2, 0x00b5, 0x00a1, 0x0096, 0x0097, 0x0095, 0x0099, 0x00a0, 0x00a2,
+ 0x00ac, 0x00a9, 0x00b1, 0x00b3, 0x00bb, 0x00c0, 0x018f, 0x0004},
+ {0x0018, 0x002e, 0x0000, 0x005a, 0x00a5, 0x00f8, 0x00b7, 0x0094, 0x00f9,
+ 0x004d, 0x0021, 0x002b, 0x004f, 0x007b, 0x00bc, 0x0046, 0x0015},
+ {0x0042, 0x0037, 0x0078, 0x000d, 0x0068, 0x005f, 0x000d, 0x005e, 0x005a,
+ 0x00be, 0x0063, 0x007e, 0x001f, 0x0092, 0x001a, 0x00ab, 0x0032},
+ {0x00e6, 0x0037, 0x0000, 0x0058, 0x000b, 0x005a, 0x00e1, 0x005d, 0x0029,
+ 0x0017, 0x007e, 0x0069, 0x00aa, 0x0054, 0x0029, 0x0032, 0x0041},
+ {0x0046, 0x00ea, 0x0034, 0x00ea, 0x0011, 0x001b, 0x00a9, 0x0094, 0x00e2,
+ 0x0031, 0x00d0, 0x00e5, 0x0007, 0x0070, 0x0069, 0x003e, 0x0021}};
+
+const ULONG FDKaacEnc_huff_ctabscf[121] = {
+ 0x0003ffe8, 0x0003ffe6, 0x0003ffe7, 0x0003ffe5, 0x0007fff5, 0x0007fff1,
+ 0x0007ffed, 0x0007fff6, 0x0007ffee, 0x0007ffef, 0x0007fff0, 0x0007fffc,
+ 0x0007fffd, 0x0007ffff, 0x0007fffe, 0x0007fff7, 0x0007fff8, 0x0007fffb,
+ 0x0007fff9, 0x0003ffe4, 0x0007fffa, 0x0003ffe3, 0x0001ffef, 0x0001fff0,
+ 0x0000fff5, 0x0001ffee, 0x0000fff2, 0x0000fff3, 0x0000fff4, 0x0000fff1,
+ 0x00007ff6, 0x00007ff7, 0x00003ff9, 0x00003ff5, 0x00003ff7, 0x00003ff3,
+ 0x00003ff6, 0x00003ff2, 0x00001ff7, 0x00001ff5, 0x00000ff9, 0x00000ff7,
+ 0x00000ff6, 0x000007f9, 0x00000ff4, 0x000007f8, 0x000003f9, 0x000003f7,
+ 0x000003f5, 0x000001f8, 0x000001f7, 0x000000fa, 0x000000f8, 0x000000f6,
+ 0x00000079, 0x0000003a, 0x00000038, 0x0000001a, 0x0000000b, 0x00000004,
+ 0x00000000, 0x0000000a, 0x0000000c, 0x0000001b, 0x00000039, 0x0000003b,
+ 0x00000078, 0x0000007a, 0x000000f7, 0x000000f9, 0x000001f6, 0x000001f9,
+ 0x000003f4, 0x000003f6, 0x000003f8, 0x000007f5, 0x000007f4, 0x000007f6,
+ 0x000007f7, 0x00000ff5, 0x00000ff8, 0x00001ff4, 0x00001ff6, 0x00001ff8,
+ 0x00003ff8, 0x00003ff4, 0x0000fff0, 0x00007ff4, 0x0000fff6, 0x00007ff5,
+ 0x0003ffe2, 0x0007ffd9, 0x0007ffda, 0x0007ffdb, 0x0007ffdc, 0x0007ffdd,
+ 0x0007ffde, 0x0007ffd8, 0x0007ffd2, 0x0007ffd3, 0x0007ffd4, 0x0007ffd5,
+ 0x0007ffd6, 0x0007fff2, 0x0007ffdf, 0x0007ffe7, 0x0007ffe8, 0x0007ffe9,
+ 0x0007ffea, 0x0007ffeb, 0x0007ffe6, 0x0007ffe0, 0x0007ffe1, 0x0007ffe2,
+ 0x0007ffe3, 0x0007ffe4, 0x0007ffe5, 0x0007ffd7, 0x0007ffec, 0x0007fff4,
+ 0x0007fff3};
+
+/*
+ table of (0.50000...1.00000) ^0.75
+*/
+const FIXP_QTD FDKaacEnc_mTab_3_4[MANT_SIZE] = {
+ QTC(0x4c1bf829), QTC(0x4c3880de), QTC(0x4c550603), QTC(0x4c71879c),
+ QTC(0x4c8e05aa), QTC(0x4caa8030), QTC(0x4cc6f72f), QTC(0x4ce36aab),
+ QTC(0x4cffdaa4), QTC(0x4d1c471d), QTC(0x4d38b019), QTC(0x4d55159a),
+ QTC(0x4d7177a1), QTC(0x4d8dd631), QTC(0x4daa314b), QTC(0x4dc688f3),
+ QTC(0x4de2dd2a), QTC(0x4dff2df2), QTC(0x4e1b7b4d), QTC(0x4e37c53d),
+ QTC(0x4e540bc5), QTC(0x4e704ee6), QTC(0x4e8c8ea3), QTC(0x4ea8cafd),
+ QTC(0x4ec503f7), QTC(0x4ee13992), QTC(0x4efd6bd0), QTC(0x4f199ab4),
+ QTC(0x4f35c640), QTC(0x4f51ee75), QTC(0x4f6e1356), QTC(0x4f8a34e4),
+ QTC(0x4fa65321), QTC(0x4fc26e10), QTC(0x4fde85b2), QTC(0x4ffa9a0a),
+ QTC(0x5016ab18), QTC(0x5032b8e0), QTC(0x504ec362), QTC(0x506acaa1),
+ QTC(0x5086cea0), QTC(0x50a2cf5e), QTC(0x50becce0), QTC(0x50dac725),
+ QTC(0x50f6be31), QTC(0x5112b205), QTC(0x512ea2a3), QTC(0x514a900d),
+ QTC(0x51667a45), QTC(0x5182614c), QTC(0x519e4524), QTC(0x51ba25cf),
+ QTC(0x51d60350), QTC(0x51f1dda7), QTC(0x520db4d6), QTC(0x522988e0),
+ QTC(0x524559c6), QTC(0x52612789), QTC(0x527cf22d), QTC(0x5298b9b1),
+ QTC(0x52b47e19), QTC(0x52d03f65), QTC(0x52ebfd98), QTC(0x5307b8b4),
+ QTC(0x532370b9), QTC(0x533f25aa), QTC(0x535ad789), QTC(0x53768656),
+ QTC(0x53923215), QTC(0x53addac6), QTC(0x53c9806b), QTC(0x53e52306),
+ QTC(0x5400c298), QTC(0x541c5f24), QTC(0x5437f8ab), QTC(0x54538f2e),
+ QTC(0x546f22af), QTC(0x548ab330), QTC(0x54a640b3), QTC(0x54c1cb38),
+ QTC(0x54dd52c2), QTC(0x54f8d753), QTC(0x551458eb), QTC(0x552fd78d),
+ QTC(0x554b5339), QTC(0x5566cbf3), QTC(0x558241bb), QTC(0x559db492),
+ QTC(0x55b9247b), QTC(0x55d49177), QTC(0x55effb87), QTC(0x560b62ad),
+ QTC(0x5626c6eb), QTC(0x56422842), QTC(0x565d86b4), QTC(0x5678e242),
+ QTC(0x56943aee), QTC(0x56af90b9), QTC(0x56cae3a4), QTC(0x56e633b2),
+ QTC(0x570180e4), QTC(0x571ccb3b), QTC(0x573812b8), QTC(0x5753575e),
+ QTC(0x576e992e), QTC(0x5789d829), QTC(0x57a51450), QTC(0x57c04da6),
+ QTC(0x57db842b), QTC(0x57f6b7e1), QTC(0x5811e8c9), QTC(0x582d16e6),
+ QTC(0x58484238), QTC(0x58636ac0), QTC(0x587e9081), QTC(0x5899b37c),
+ QTC(0x58b4d3b1), QTC(0x58cff123), QTC(0x58eb0bd3), QTC(0x590623c2),
+ QTC(0x592138f2), QTC(0x593c4b63), QTC(0x59575b19), QTC(0x59726812),
+ QTC(0x598d7253), QTC(0x59a879da), QTC(0x59c37eab), QTC(0x59de80c6),
+ QTC(0x59f9802d), QTC(0x5a147ce0), QTC(0x5a2f76e2), QTC(0x5a4a6e34),
+ QTC(0x5a6562d6), QTC(0x5a8054cb), QTC(0x5a9b4414), QTC(0x5ab630b2),
+ QTC(0x5ad11aa6), QTC(0x5aec01f1), QTC(0x5b06e696), QTC(0x5b21c895),
+ QTC(0x5b3ca7ef), QTC(0x5b5784a6), QTC(0x5b725ebc), QTC(0x5b8d3631),
+ QTC(0x5ba80b06), QTC(0x5bc2dd3e), QTC(0x5bddacd9), QTC(0x5bf879d8),
+ QTC(0x5c13443d), QTC(0x5c2e0c09), QTC(0x5c48d13e), QTC(0x5c6393dc),
+ QTC(0x5c7e53e5), QTC(0x5c99115a), QTC(0x5cb3cc3c), QTC(0x5cce848d),
+ QTC(0x5ce93a4e), QTC(0x5d03ed80), QTC(0x5d1e9e24), QTC(0x5d394c3b),
+ QTC(0x5d53f7c7), QTC(0x5d6ea0c9), QTC(0x5d894742), QTC(0x5da3eb33),
+ QTC(0x5dbe8c9e), QTC(0x5dd92b84), QTC(0x5df3c7e5), QTC(0x5e0e61c3),
+ QTC(0x5e28f920), QTC(0x5e438dfc), QTC(0x5e5e2059), QTC(0x5e78b037),
+ QTC(0x5e933d99), QTC(0x5eadc87e), QTC(0x5ec850e9), QTC(0x5ee2d6da),
+ QTC(0x5efd5a53), QTC(0x5f17db54), QTC(0x5f3259e0), QTC(0x5f4cd5f6),
+ QTC(0x5f674f99), QTC(0x5f81c6c8), QTC(0x5f9c3b87), QTC(0x5fb6add4),
+ QTC(0x5fd11db3), QTC(0x5feb8b23), QTC(0x6005f626), QTC(0x60205ebd),
+ QTC(0x603ac4e9), QTC(0x605528ac), QTC(0x606f8a05), QTC(0x6089e8f7),
+ QTC(0x60a44583), QTC(0x60be9fa9), QTC(0x60d8f76b), QTC(0x60f34cca),
+ QTC(0x610d9fc7), QTC(0x6127f062), QTC(0x61423e9e), QTC(0x615c8a7a),
+ QTC(0x6176d3f9), QTC(0x61911b1b), QTC(0x61ab5fe1), QTC(0x61c5a24d),
+ QTC(0x61dfe25f), QTC(0x61fa2018), QTC(0x62145b7a), QTC(0x622e9485),
+ QTC(0x6248cb3b), QTC(0x6262ff9d), QTC(0x627d31ab), QTC(0x62976167),
+ QTC(0x62b18ed1), QTC(0x62cbb9eb), QTC(0x62e5e2b6), QTC(0x63000933),
+ QTC(0x631a2d62), QTC(0x63344f45), QTC(0x634e6edd), QTC(0x63688c2b),
+ QTC(0x6382a730), QTC(0x639cbfec), QTC(0x63b6d661), QTC(0x63d0ea90),
+ QTC(0x63eafc7a), QTC(0x64050c1f), QTC(0x641f1982), QTC(0x643924a2),
+ QTC(0x64532d80), QTC(0x646d341f), QTC(0x6487387e), QTC(0x64a13a9e),
+ QTC(0x64bb3a81), QTC(0x64d53828), QTC(0x64ef3393), QTC(0x65092cc4),
+ QTC(0x652323bb), QTC(0x653d1879), QTC(0x65570b00), QTC(0x6570fb50),
+ QTC(0x658ae96b), QTC(0x65a4d550), QTC(0x65bebf01), QTC(0x65d8a680),
+ QTC(0x65f28bcc), QTC(0x660c6ee8), QTC(0x66264fd3), QTC(0x66402e8f),
+ QTC(0x665a0b1c), QTC(0x6673e57d), QTC(0x668dbdb0), QTC(0x66a793b8),
+ QTC(0x66c16795), QTC(0x66db3949), QTC(0x66f508d4), QTC(0x670ed636),
+ QTC(0x6728a172), QTC(0x67426a87), QTC(0x675c3177), QTC(0x6775f643),
+ QTC(0x678fb8eb), QTC(0x67a97971), QTC(0x67c337d5), QTC(0x67dcf418),
+ QTC(0x67f6ae3b), QTC(0x6810663f), QTC(0x682a1c25), QTC(0x6843cfed),
+ QTC(0x685d8199), QTC(0x68773129), QTC(0x6890de9f), QTC(0x68aa89fa),
+ QTC(0x68c4333d), QTC(0x68ddda67), QTC(0x68f77f7a), QTC(0x69112277),
+ QTC(0x692ac35e), QTC(0x69446230), QTC(0x695dfeee), QTC(0x6977999a),
+ QTC(0x69913232), QTC(0x69aac8ba), QTC(0x69c45d31), QTC(0x69ddef98),
+ QTC(0x69f77ff0), QTC(0x6a110e3a), QTC(0x6a2a9a77), QTC(0x6a4424a8),
+ QTC(0x6a5daccc), QTC(0x6a7732e6), QTC(0x6a90b6f6), QTC(0x6aaa38fd),
+ QTC(0x6ac3b8fb), QTC(0x6add36f2), QTC(0x6af6b2e2), QTC(0x6b102ccd),
+ QTC(0x6b29a4b2), QTC(0x6b431a92), QTC(0x6b5c8e6f), QTC(0x6b76004a),
+ QTC(0x6b8f7022), QTC(0x6ba8ddf9), QTC(0x6bc249d0), QTC(0x6bdbb3a7),
+ QTC(0x6bf51b80), QTC(0x6c0e815a), QTC(0x6c27e537), QTC(0x6c414718),
+ QTC(0x6c5aa6fd), QTC(0x6c7404e7), QTC(0x6c8d60d7), QTC(0x6ca6bace),
+ QTC(0x6cc012cc), QTC(0x6cd968d2), QTC(0x6cf2bce1), QTC(0x6d0c0ef9),
+ QTC(0x6d255f1d), QTC(0x6d3ead4b), QTC(0x6d57f985), QTC(0x6d7143cc),
+ QTC(0x6d8a8c21), QTC(0x6da3d283), QTC(0x6dbd16f5), QTC(0x6dd65976),
+ QTC(0x6def9a08), QTC(0x6e08d8ab), QTC(0x6e221560), QTC(0x6e3b5027),
+ QTC(0x6e548902), QTC(0x6e6dbff1), QTC(0x6e86f4f5), QTC(0x6ea0280e),
+ QTC(0x6eb9593e), QTC(0x6ed28885), QTC(0x6eebb5e3), QTC(0x6f04e15a),
+ QTC(0x6f1e0aea), QTC(0x6f373294), QTC(0x6f505859), QTC(0x6f697c39),
+ QTC(0x6f829e35), QTC(0x6f9bbe4e), QTC(0x6fb4dc85), QTC(0x6fcdf8d9),
+ QTC(0x6fe7134d), QTC(0x70002be0), QTC(0x70194293), QTC(0x70325767),
+ QTC(0x704b6a5d), QTC(0x70647b76), QTC(0x707d8ab1), QTC(0x70969811),
+ QTC(0x70afa394), QTC(0x70c8ad3d), QTC(0x70e1b50c), QTC(0x70fabb01),
+ QTC(0x7113bf1d), QTC(0x712cc161), QTC(0x7145c1ce), QTC(0x715ec064),
+ QTC(0x7177bd24), QTC(0x7190b80f), QTC(0x71a9b124), QTC(0x71c2a866),
+ QTC(0x71db9dd4), QTC(0x71f49170), QTC(0x720d8339), QTC(0x72267331),
+ QTC(0x723f6159), QTC(0x72584db0), QTC(0x72713838), QTC(0x728a20f1),
+ QTC(0x72a307db), QTC(0x72bbecf9), QTC(0x72d4d049), QTC(0x72edb1ce),
+ QTC(0x73069187), QTC(0x731f6f75), QTC(0x73384b98), QTC(0x735125f3),
+ QTC(0x7369fe84), QTC(0x7382d54d), QTC(0x739baa4e), QTC(0x73b47d89),
+ QTC(0x73cd4efd), QTC(0x73e61eab), QTC(0x73feec94), QTC(0x7417b8b8),
+ QTC(0x74308319), QTC(0x74494bb6), QTC(0x74621291), QTC(0x747ad7aa),
+ QTC(0x74939b02), QTC(0x74ac5c98), QTC(0x74c51c6f), QTC(0x74ddda86),
+ QTC(0x74f696de), QTC(0x750f5178), QTC(0x75280a54), QTC(0x7540c174),
+ QTC(0x755976d7), QTC(0x75722a7e), QTC(0x758adc69), QTC(0x75a38c9b),
+ QTC(0x75bc3b12), QTC(0x75d4e7cf), QTC(0x75ed92d4), QTC(0x76063c21),
+ QTC(0x761ee3b6), QTC(0x76378994), QTC(0x76502dbc), QTC(0x7668d02e),
+ QTC(0x768170eb), QTC(0x769a0ff3), QTC(0x76b2ad47), QTC(0x76cb48e7),
+ QTC(0x76e3e2d5), QTC(0x76fc7b10), QTC(0x7715119a), QTC(0x772da673),
+ QTC(0x7746399b), QTC(0x775ecb13), QTC(0x77775adc), QTC(0x778fe8f6),
+ QTC(0x77a87561), QTC(0x77c1001f), QTC(0x77d98930), QTC(0x77f21095),
+ QTC(0x780a964d), QTC(0x78231a5b), QTC(0x783b9cbd), QTC(0x78541d75),
+ QTC(0x786c9c84), QTC(0x788519e9), QTC(0x789d95a6), QTC(0x78b60fbb),
+ QTC(0x78ce8828), QTC(0x78e6feef), QTC(0x78ff740f), QTC(0x7917e78a),
+ QTC(0x7930595f), QTC(0x7948c990), QTC(0x7961381d), QTC(0x7979a506),
+ QTC(0x7992104c), QTC(0x79aa79f0), QTC(0x79c2e1f1), QTC(0x79db4852),
+ QTC(0x79f3ad11), QTC(0x7a0c1031), QTC(0x7a2471b0), QTC(0x7a3cd191),
+ QTC(0x7a552fd3), QTC(0x7a6d8c76), QTC(0x7a85e77d), QTC(0x7a9e40e6),
+ QTC(0x7ab698b2), QTC(0x7aceeee3), QTC(0x7ae74378), QTC(0x7aff9673),
+ QTC(0x7b17e7d2), QTC(0x7b303799), QTC(0x7b4885c5), QTC(0x7b60d259),
+ QTC(0x7b791d55), QTC(0x7b9166b9), QTC(0x7ba9ae86), QTC(0x7bc1f4bc),
+ QTC(0x7bda395c), QTC(0x7bf27c66), QTC(0x7c0abddb), QTC(0x7c22fdbb),
+ QTC(0x7c3b3c07), QTC(0x7c5378c0), QTC(0x7c6bb3e5), QTC(0x7c83ed78),
+ QTC(0x7c9c2579), QTC(0x7cb45be9), QTC(0x7ccc90c7), QTC(0x7ce4c414),
+ QTC(0x7cfcf5d2), QTC(0x7d152600), QTC(0x7d2d549f), QTC(0x7d4581b0),
+ QTC(0x7d5dad32), QTC(0x7d75d727), QTC(0x7d8dff8f), QTC(0x7da6266a),
+ QTC(0x7dbe4bba), QTC(0x7dd66f7d), QTC(0x7dee91b6), QTC(0x7e06b264),
+ QTC(0x7e1ed188), QTC(0x7e36ef22), QTC(0x7e4f0b34), QTC(0x7e6725bd),
+ QTC(0x7e7f3ebd), QTC(0x7e975636), QTC(0x7eaf6c28), QTC(0x7ec78093),
+ QTC(0x7edf9378), QTC(0x7ef7a4d7), QTC(0x7f0fb4b1), QTC(0x7f27c307),
+ QTC(0x7f3fcfd8), QTC(0x7f57db25), QTC(0x7f6fe4ef), QTC(0x7f87ed36),
+ QTC(0x7f9ff3fb), QTC(0x7fb7f93e), QTC(0x7fcffcff), QTC(0x7fe7ff40)};
+
+/*
+ table of pow(2.0,0.25*q)/2.0, q[0..4)
+*/
+const FIXP_QTD FDKaacEnc_quantTableQ[4] = {QTC(0x40000000), QTC(0x4c1bf7ff),
+ QTC(0x5a82797f), QTC(0x6ba27e7f)};
+
+/*
+ table of pow(2.0,0.75*e)/8.0, e[0..4)
+*/
+const FIXP_QTD FDKaacEnc_quantTableE[4] = {QTC(0x10000000), QTC(0x1ae89f99),
+ QTC(0x2d413ccd), QTC(0x4c1bf828)};
+
+/*
+ table to count used number of bits
+*/
+const SHORT FDKaacEnc_sideInfoTabLong[] = {
+ 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
+ 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
+ 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
+ 0x0009, 0x0009, 0x0009, 0x0009, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e,
+ 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e,
+ 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e};
+
+const SHORT FDKaacEnc_sideInfoTabShort[] = {
+ 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x000a,
+ 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000d, 0x000d};
+
+/*
+ Psy Configuration constants
+*/
+
+const SFB_PARAM_LONG p_FDKaacEnc_8000_long_1024 = {
+ 40, {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16,
+ 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28,
+ 28, 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80}};
+const SFB_PARAM_SHORT p_FDKaacEnc_8000_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20}};
+
+const SFB_PARAM_LONG p_FDKaacEnc_11025_long_1024 = {
+ 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28,
+ 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_11025_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}};
+
+const SFB_PARAM_LONG p_FDKaacEnc_12000_long_1024 = {
+ 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28,
+ 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_12000_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}};
+
+const SFB_PARAM_LONG p_FDKaacEnc_16000_long_1024 = {
+ 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28,
+ 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_16000_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}};
+const SFB_PARAM_LONG p_FDKaacEnc_22050_long_1024 = {
+ 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24,
+ 28, 28, 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_22050_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20}};
+const SFB_PARAM_LONG p_FDKaacEnc_24000_long_1024 = {
+ 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24,
+ 28, 28, 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_24000_short_128 = {
+ 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20}};
+const SFB_PARAM_LONG p_FDKaacEnc_32000_long_1024 = {
+ 51, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}};
+const SFB_PARAM_SHORT p_FDKaacEnc_32000_short_128 = {
+ 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}};
+const SFB_PARAM_LONG p_FDKaacEnc_44100_long_1024 = {
+ 49, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96}};
+const SFB_PARAM_SHORT p_FDKaacEnc_44100_short_128 = {
+ 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}};
+const SFB_PARAM_LONG p_FDKaacEnc_48000_long_1024 = {
+ 49, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96}};
+const SFB_PARAM_SHORT p_FDKaacEnc_48000_short_128 = {
+ 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}};
+const SFB_PARAM_LONG p_FDKaacEnc_64000_long_1024 = {
+ 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8,
+ 8, 8, 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}};
+const SFB_PARAM_SHORT p_FDKaacEnc_64000_short_128 = {
+ 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}};
+const SFB_PARAM_LONG p_FDKaacEnc_88200_long_1024 = {
+ 41, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 16, 16, 24, 28,
+ 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_88200_short_128 = {
+ 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}};
+const SFB_PARAM_LONG p_FDKaacEnc_96000_long_1024 = {
+ 41, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 16, 16, 24, 28,
+ 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}};
+const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_128 = {
+ 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}};
+
+/*
+ TNS filter coefficients
+*/
+
+/*
+ 3 bit resolution
+*/
+const FIXP_LPC FDKaacEnc_tnsEncCoeff3[8] = {
+ FX_DBL2FXCONST_LPC(0x81f1d201), FX_DBL2FXCONST_LPC(0x91261481),
+ FX_DBL2FXCONST_LPC(0xadb92301), FX_DBL2FXCONST_LPC(0xd438af00),
+ FX_DBL2FXCONST_LPC(0x00000000), FX_DBL2FXCONST_LPC(0x37898080),
+ FX_DBL2FXCONST_LPC(0x64130dff), FX_DBL2FXCONST_LPC(0x7cca6fff)};
+const FIXP_LPC FDKaacEnc_tnsCoeff3Borders[8] = {
+ FX_DBL2FXCONST_LPC(0x80000001) /*-4*/,
+ FX_DBL2FXCONST_LPC(0x87b826df) /*-3*/,
+ FX_DBL2FXCONST_LPC(0x9df24154) /*-2*/,
+ FX_DBL2FXCONST_LPC(0xbfffffe5) /*-1*/,
+ FX_DBL2FXCONST_LPC(0xe9c5e578) /* 0*/,
+ FX_DBL2FXCONST_LPC(0x1c7b90f0) /* 1*/,
+ FX_DBL2FXCONST_LPC(0x4fce83a9) /* 2*/,
+ FX_DBL2FXCONST_LPC(0x7352f2c3) /* 3*/
+};
+
+/*
+ 4 bit resolution
+*/
+const FIXP_LPC FDKaacEnc_tnsEncCoeff4[16] = {
+ FX_DBL2FXCONST_LPC(0x808bc881), FX_DBL2FXCONST_LPC(0x84e2e581),
+ FX_DBL2FXCONST_LPC(0x8d6b4a01), FX_DBL2FXCONST_LPC(0x99da9201),
+ FX_DBL2FXCONST_LPC(0xa9c45701), FX_DBL2FXCONST_LPC(0xbc9dde81),
+ FX_DBL2FXCONST_LPC(0xd1c2d500), FX_DBL2FXCONST_LPC(0xe87ae540),
+ FX_DBL2FXCONST_LPC(0x00000000), FX_DBL2FXCONST_LPC(0x1a9cd9c0),
+ FX_DBL2FXCONST_LPC(0x340ff240), FX_DBL2FXCONST_LPC(0x4b3c8bff),
+ FX_DBL2FXCONST_LPC(0x5f1f5e7f), FX_DBL2FXCONST_LPC(0x6ed9eb7f),
+ FX_DBL2FXCONST_LPC(0x79bc387f), FX_DBL2FXCONST_LPC(0x7f4c7e7f)};
+const FIXP_LPC FDKaacEnc_tnsCoeff4Borders[16] = {
+ FX_DBL2FXCONST_LPC(0x80000001) /*-8*/,
+ FX_DBL2FXCONST_LPC(0x822deff0) /*-7*/,
+ FX_DBL2FXCONST_LPC(0x88a4bfe6) /*-6*/,
+ FX_DBL2FXCONST_LPC(0x932c159d) /*-5*/,
+ FX_DBL2FXCONST_LPC(0xa16827c2) /*-4*/,
+ FX_DBL2FXCONST_LPC(0xb2dcde27) /*-3*/,
+ FX_DBL2FXCONST_LPC(0xc6f20b91) /*-2*/,
+ FX_DBL2FXCONST_LPC(0xdcf89c64) /*-1*/,
+ FX_DBL2FXCONST_LPC(0xf4308ce1) /* 0*/,
+ FX_DBL2FXCONST_LPC(0x0d613054) /* 1*/,
+ FX_DBL2FXCONST_LPC(0x278dde80) /* 2*/,
+ FX_DBL2FXCONST_LPC(0x4000001b) /* 3*/,
+ FX_DBL2FXCONST_LPC(0x55a6127b) /* 4*/,
+ FX_DBL2FXCONST_LPC(0x678dde8f) /* 5*/,
+ FX_DBL2FXCONST_LPC(0x74ef0ed7) /* 6*/,
+ FX_DBL2FXCONST_LPC(0x7d33f0da) /* 7*/
+};
+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.4009894932098531), FL2FXCONST_DBL(0.4020259763004115),
+ FL2FXCONST_DBL(0.4030631278744227), FL2FXCONST_DBL(0.4041009470712695),
+ FL2FXCONST_DBL(0.4051394330330996), FL2FXCONST_DBL(0.4061785849048110),
+ FL2FXCONST_DBL(0.4072184018340380), FL2FXCONST_DBL(0.4082588829711372),
+ FL2FXCONST_DBL(0.4093000274691739), FL2FXCONST_DBL(0.4103418344839078),
+ FL2FXCONST_DBL(0.4113843031737798), FL2FXCONST_DBL(0.4124274326998980),
+ FL2FXCONST_DBL(0.4134712222260245), FL2FXCONST_DBL(0.4145156709185620),
+ FL2FXCONST_DBL(0.4155607779465400), FL2FXCONST_DBL(0.4166065424816022),
+ FL2FXCONST_DBL(0.4176529636979932), FL2FXCONST_DBL(0.4187000407725452),
+ FL2FXCONST_DBL(0.4197477728846652), FL2FXCONST_DBL(0.4207961592163222),
+ FL2FXCONST_DBL(0.4218451989520345), FL2FXCONST_DBL(0.4228948912788567),
+ FL2FXCONST_DBL(0.4239452353863673), FL2FXCONST_DBL(0.4249962304666564),
+ FL2FXCONST_DBL(0.4260478757143130), FL2FXCONST_DBL(0.4271001703264124),
+ FL2FXCONST_DBL(0.4281531135025046), FL2FXCONST_DBL(0.4292067044446017),
+ FL2FXCONST_DBL(0.4302609423571658), FL2FXCONST_DBL(0.4313158264470970),
+ FL2FXCONST_DBL(0.4323713559237216), FL2FXCONST_DBL(0.4334275299987803),
+ FL2FXCONST_DBL(0.4344843478864161), FL2FXCONST_DBL(0.4355418088031630),
+ FL2FXCONST_DBL(0.4365999119679339), FL2FXCONST_DBL(0.4376586566020096),
+ FL2FXCONST_DBL(0.4387180419290272), FL2FXCONST_DBL(0.4397780671749683),
+ FL2FXCONST_DBL(0.4408387315681480), FL2FXCONST_DBL(0.4419000343392039),
+ FL2FXCONST_DBL(0.4429619747210847), FL2FXCONST_DBL(0.4440245519490388),
+ FL2FXCONST_DBL(0.4450877652606038), FL2FXCONST_DBL(0.4461516138955953),
+ FL2FXCONST_DBL(0.4472160970960963), FL2FXCONST_DBL(0.4482812141064458),
+ FL2FXCONST_DBL(0.4493469641732286), FL2FXCONST_DBL(0.4504133465452648),
+ FL2FXCONST_DBL(0.4514803604735984), FL2FXCONST_DBL(0.4525480052114875),
+ FL2FXCONST_DBL(0.4536162800143939), FL2FXCONST_DBL(0.4546851841399719),
+ FL2FXCONST_DBL(0.4557547168480591), FL2FXCONST_DBL(0.4568248774006652),
+ FL2FXCONST_DBL(0.4578956650619623), FL2FXCONST_DBL(0.4589670790982746),
+ FL2FXCONST_DBL(0.4600391187780688), FL2FXCONST_DBL(0.4611117833719430),
+ FL2FXCONST_DBL(0.4621850721526184), FL2FXCONST_DBL(0.4632589843949278),
+ FL2FXCONST_DBL(0.4643335193758069), FL2FXCONST_DBL(0.4654086763742842),
+ FL2FXCONST_DBL(0.4664844546714713), FL2FXCONST_DBL(0.4675608535505532),
+ FL2FXCONST_DBL(0.4686378722967790), FL2FXCONST_DBL(0.4697155101974522),
+ FL2FXCONST_DBL(0.4707937665419216), FL2FXCONST_DBL(0.4718726406215713),
+ FL2FXCONST_DBL(0.4729521317298118), FL2FXCONST_DBL(0.4740322391620711),
+ FL2FXCONST_DBL(0.4751129622157845), FL2FXCONST_DBL(0.4761943001903867),
+ FL2FXCONST_DBL(0.4772762523873015), FL2FXCONST_DBL(0.4783588181099338),
+ FL2FXCONST_DBL(0.4794419966636599), FL2FXCONST_DBL(0.4805257873558190),
+ FL2FXCONST_DBL(0.4816101894957042), FL2FXCONST_DBL(0.4826952023945537),
+ FL2FXCONST_DBL(0.4837808253655421), FL2FXCONST_DBL(0.4848670577237714),
+ FL2FXCONST_DBL(0.4859538987862632), FL2FXCONST_DBL(0.4870413478719488),
+ FL2FXCONST_DBL(0.4881294043016621), FL2FXCONST_DBL(0.4892180673981298),
+ FL2FXCONST_DBL(0.4903073364859640), FL2FXCONST_DBL(0.4913972108916533),
+ FL2FXCONST_DBL(0.4924876899435545), FL2FXCONST_DBL(0.4935787729718844),
+ FL2FXCONST_DBL(0.4946704593087116), FL2FXCONST_DBL(0.4957627482879484),
+ FL2FXCONST_DBL(0.4968556392453423), FL2FXCONST_DBL(0.4979491315184684),
+ FL2FXCONST_DBL(0.4990432244467211), FL2FXCONST_DBL(0.5001379173713062),
+ FL2FXCONST_DBL(0.5012332096352328), FL2FXCONST_DBL(0.5023291005833056),
+ FL2FXCONST_DBL(0.5034255895621171), FL2FXCONST_DBL(0.5045226759200399),
+ FL2FXCONST_DBL(0.5056203590072181), FL2FXCONST_DBL(0.5067186381755611),
+ FL2FXCONST_DBL(0.5078175127787346), FL2FXCONST_DBL(0.5089169821721536),
+ FL2FXCONST_DBL(0.5100170457129749), FL2FXCONST_DBL(0.5111177027600893),
+ FL2FXCONST_DBL(0.5122189526741143), FL2FXCONST_DBL(0.5133207948173868),
+ FL2FXCONST_DBL(0.5144232285539552), FL2FXCONST_DBL(0.5155262532495726),
+ FL2FXCONST_DBL(0.5166298682716894), FL2FXCONST_DBL(0.5177340729894460),
+ FL2FXCONST_DBL(0.5188388667736652), FL2FXCONST_DBL(0.5199442489968457),
+ FL2FXCONST_DBL(0.5210502190331544), FL2FXCONST_DBL(0.5221567762584198),
+ FL2FXCONST_DBL(0.5232639200501247), FL2FXCONST_DBL(0.5243716497873989),
+ FL2FXCONST_DBL(0.5254799648510130), FL2FXCONST_DBL(0.5265888646233705),
+ FL2FXCONST_DBL(0.5276983484885021), FL2FXCONST_DBL(0.5288084158320574),
+ FL2FXCONST_DBL(0.5299190660412995), FL2FXCONST_DBL(0.5310302985050975),
+ FL2FXCONST_DBL(0.5321421126139198), FL2FXCONST_DBL(0.5332545077598274),
+ FL2FXCONST_DBL(0.5343674833364678), FL2FXCONST_DBL(0.5354810387390675),
+ FL2FXCONST_DBL(0.5365951733644262), FL2FXCONST_DBL(0.5377098866109097),
+ FL2FXCONST_DBL(0.5388251778784438), FL2FXCONST_DBL(0.5399410465685075),
+ FL2FXCONST_DBL(0.5410574920841272), FL2FXCONST_DBL(0.5421745138298695),
+ FL2FXCONST_DBL(0.5432921112118353), FL2FXCONST_DBL(0.5444102836376534),
+ FL2FXCONST_DBL(0.5455290305164744), FL2FXCONST_DBL(0.5466483512589642),
+ FL2FXCONST_DBL(0.5477682452772976), FL2FXCONST_DBL(0.5488887119851529),
+ FL2FXCONST_DBL(0.5500097507977050), FL2FXCONST_DBL(0.5511313611316194),
+ FL2FXCONST_DBL(0.5522535424050467), FL2FXCONST_DBL(0.5533762940376158),
+ FL2FXCONST_DBL(0.5544996154504284), FL2FXCONST_DBL(0.5556235060660528),
+ FL2FXCONST_DBL(0.5567479653085183), FL2FXCONST_DBL(0.5578729926033087),
+ FL2FXCONST_DBL(0.5589985873773569), FL2FXCONST_DBL(0.5601247490590389),
+ FL2FXCONST_DBL(0.5612514770781683), FL2FXCONST_DBL(0.5623787708659898),
+ FL2FXCONST_DBL(0.5635066298551742), FL2FXCONST_DBL(0.5646350534798125),
+ FL2FXCONST_DBL(0.5657640411754097), FL2FXCONST_DBL(0.5668935923788799),
+ FL2FXCONST_DBL(0.5680237065285404), FL2FXCONST_DBL(0.5691543830641059),
+ FL2FXCONST_DBL(0.5702856214266832), FL2FXCONST_DBL(0.5714174210587655),
+ FL2FXCONST_DBL(0.5725497814042271), FL2FXCONST_DBL(0.5736827019083177),
+ FL2FXCONST_DBL(0.5748161820176573), FL2FXCONST_DBL(0.5759502211802304),
+ FL2FXCONST_DBL(0.5770848188453810), FL2FXCONST_DBL(0.5782199744638067),
+ FL2FXCONST_DBL(0.5793556874875542), FL2FXCONST_DBL(0.5804919573700131),
+ FL2FXCONST_DBL(0.5816287835659116), FL2FXCONST_DBL(0.5827661655313104),
+ FL2FXCONST_DBL(0.5839041027235979), FL2FXCONST_DBL(0.5850425946014850),
+ FL2FXCONST_DBL(0.5861816406250000), FL2FXCONST_DBL(0.5873212402554834),
+ FL2FXCONST_DBL(0.5884613929555826), FL2FXCONST_DBL(0.5896020981892474),
+ FL2FXCONST_DBL(0.5907433554217242), FL2FXCONST_DBL(0.5918851641195517),
+ FL2FXCONST_DBL(0.5930275237505556), FL2FXCONST_DBL(0.5941704337838434),
+ FL2FXCONST_DBL(0.5953138936897999), FL2FXCONST_DBL(0.5964579029400819),
+ FL2FXCONST_DBL(0.5976024610076139), FL2FXCONST_DBL(0.5987475673665825),
+ FL2FXCONST_DBL(0.5998932214924321), FL2FXCONST_DBL(0.6010394228618597),
+ FL2FXCONST_DBL(0.6021861709528106), FL2FXCONST_DBL(0.6033334652444733),
+ FL2FXCONST_DBL(0.6044813052172748), FL2FXCONST_DBL(0.6056296903528761),
+ FL2FXCONST_DBL(0.6067786201341671), FL2FXCONST_DBL(0.6079280940452625),
+ FL2FXCONST_DBL(0.6090781115714966), FL2FXCONST_DBL(0.6102286721994192),
+ FL2FXCONST_DBL(0.6113797754167908), FL2FXCONST_DBL(0.6125314207125777),
+ FL2FXCONST_DBL(0.6136836075769482), FL2FXCONST_DBL(0.6148363355012674),
+ FL2FXCONST_DBL(0.6159896039780929), FL2FXCONST_DBL(0.6171434125011708),
+ FL2FXCONST_DBL(0.6182977605654305), FL2FXCONST_DBL(0.6194526476669808),
+ FL2FXCONST_DBL(0.6206080733031054), FL2FXCONST_DBL(0.6217640369722584),
+ FL2FXCONST_DBL(0.6229205381740598), FL2FXCONST_DBL(0.6240775764092919),
+ FL2FXCONST_DBL(0.6252351511798939), FL2FXCONST_DBL(0.6263932619889586),
+ FL2FXCONST_DBL(0.6275519083407275), FL2FXCONST_DBL(0.6287110897405869),
+ FL2FXCONST_DBL(0.6298708056950635), FL2FXCONST_DBL(0.6310310557118203),
+ FL2FXCONST_DBL(0.6321918392996523), FL2FXCONST_DBL(0.6333531559684823),
+ FL2FXCONST_DBL(0.6345150052293571), FL2FXCONST_DBL(0.6356773865944432),
+ FL2FXCONST_DBL(0.6368402995770224), FL2FXCONST_DBL(0.6380037436914881),
+ FL2FXCONST_DBL(0.6391677184533411), FL2FXCONST_DBL(0.6403322233791856),
+ FL2FXCONST_DBL(0.6414972579867254), FL2FXCONST_DBL(0.6426628217947594),
+ FL2FXCONST_DBL(0.6438289143231779), FL2FXCONST_DBL(0.6449955350929588),
+ FL2FXCONST_DBL(0.6461626836261636), FL2FXCONST_DBL(0.6473303594459330),
+ FL2FXCONST_DBL(0.6484985620764839), FL2FXCONST_DBL(0.6496672910431047),
+ FL2FXCONST_DBL(0.6508365458721518), FL2FXCONST_DBL(0.6520063260910459),
+ FL2FXCONST_DBL(0.6531766312282679), FL2FXCONST_DBL(0.6543474608133552),
+ FL2FXCONST_DBL(0.6555188143768979), FL2FXCONST_DBL(0.6566906914505349),
+ FL2FXCONST_DBL(0.6578630915669509), FL2FXCONST_DBL(0.6590360142598715),
+ FL2FXCONST_DBL(0.6602094590640603), FL2FXCONST_DBL(0.6613834255153149),
+ FL2FXCONST_DBL(0.6625579131504635), FL2FXCONST_DBL(0.6637329215073610),
+ FL2FXCONST_DBL(0.6649084501248851), FL2FXCONST_DBL(0.6660844985429335),
+ FL2FXCONST_DBL(0.6672610663024197), FL2FXCONST_DBL(0.6684381529452691),
+ FL2FXCONST_DBL(0.6696157580144163), FL2FXCONST_DBL(0.6707938810538011),
+ FL2FXCONST_DBL(0.6719725216083646), FL2FXCONST_DBL(0.6731516792240465),
+ FL2FXCONST_DBL(0.6743313534477807), FL2FXCONST_DBL(0.6755115438274927),
+ FL2FXCONST_DBL(0.6766922499120955), FL2FXCONST_DBL(0.6778734712514865),
+ FL2FXCONST_DBL(0.6790552073965435), FL2FXCONST_DBL(0.6802374578991223),
+ FL2FXCONST_DBL(0.6814202223120524), FL2FXCONST_DBL(0.6826035001891340),
+ FL2FXCONST_DBL(0.6837872910851345), FL2FXCONST_DBL(0.6849715945557853),
+ FL2FXCONST_DBL(0.6861564101577784), FL2FXCONST_DBL(0.6873417374487629),
+ FL2FXCONST_DBL(0.6885275759873420), FL2FXCONST_DBL(0.6897139253330697),
+ FL2FXCONST_DBL(0.6909007850464473), FL2FXCONST_DBL(0.6920881546889198),
+ FL2FXCONST_DBL(0.6932760338228737), FL2FXCONST_DBL(0.6944644220116332),
+ FL2FXCONST_DBL(0.6956533188194565), FL2FXCONST_DBL(0.6968427238115332),
+ FL2FXCONST_DBL(0.6980326365539813), FL2FXCONST_DBL(0.6992230566138435),
+ FL2FXCONST_DBL(0.7004139835590845), FL2FXCONST_DBL(0.7016054169585869),
+ FL2FXCONST_DBL(0.7027973563821499), FL2FXCONST_DBL(0.7039898014004843),
+ FL2FXCONST_DBL(0.7051827515852106), FL2FXCONST_DBL(0.7063762065088554),
+ FL2FXCONST_DBL(0.7075701657448483), FL2FXCONST_DBL(0.7087646288675196),
+ FL2FXCONST_DBL(0.7099595954520960), FL2FXCONST_DBL(0.7111550650746988),
+ FL2FXCONST_DBL(0.7123510373123402), FL2FXCONST_DBL(0.7135475117429202),
+ FL2FXCONST_DBL(0.7147444879452244), FL2FXCONST_DBL(0.7159419654989200),
+ FL2FXCONST_DBL(0.7171399439845538), FL2FXCONST_DBL(0.7183384229835486),
+ FL2FXCONST_DBL(0.7195374020782005), FL2FXCONST_DBL(0.7207368808516762),
+ FL2FXCONST_DBL(0.7219368588880097), FL2FXCONST_DBL(0.7231373357720997),
+ FL2FXCONST_DBL(0.7243383110897066), FL2FXCONST_DBL(0.7255397844274496),
+ FL2FXCONST_DBL(0.7267417553728043), FL2FXCONST_DBL(0.7279442235140992),
+ FL2FXCONST_DBL(0.7291471884405130), FL2FXCONST_DBL(0.7303506497420724),
+ FL2FXCONST_DBL(0.7315546070096487), FL2FXCONST_DBL(0.7327590598349553),
+ FL2FXCONST_DBL(0.7339640078105445), FL2FXCONST_DBL(0.7351694505298055),
+ FL2FXCONST_DBL(0.7363753875869610), FL2FXCONST_DBL(0.7375818185770647),
+ FL2FXCONST_DBL(0.7387887430959987), FL2FXCONST_DBL(0.7399961607404706),
+ FL2FXCONST_DBL(0.7412040711080108), FL2FXCONST_DBL(0.7424124737969701),
+ FL2FXCONST_DBL(0.7436213684065166), FL2FXCONST_DBL(0.7448307545366334),
+ FL2FXCONST_DBL(0.7460406317881158), FL2FXCONST_DBL(0.7472509997625686),
+ FL2FXCONST_DBL(0.7484618580624036), FL2FXCONST_DBL(0.7496732062908372),
+ FL2FXCONST_DBL(0.7508850440518872), FL2FXCONST_DBL(0.7520973709503704),
+ FL2FXCONST_DBL(0.7533101865919009), FL2FXCONST_DBL(0.7545234905828862),
+ FL2FXCONST_DBL(0.7557372825305252), FL2FXCONST_DBL(0.7569515620428062),
+ FL2FXCONST_DBL(0.7581663287285035), FL2FXCONST_DBL(0.7593815821971756),
+ FL2FXCONST_DBL(0.7605973220591619), FL2FXCONST_DBL(0.7618135479255810),
+ FL2FXCONST_DBL(0.7630302594083277), FL2FXCONST_DBL(0.7642474561200708),
+ FL2FXCONST_DBL(0.7654651376742505), FL2FXCONST_DBL(0.7666833036850760),
+ FL2FXCONST_DBL(0.7679019537675227), FL2FXCONST_DBL(0.7691210875373307),
+ FL2FXCONST_DBL(0.7703407046110011), FL2FXCONST_DBL(0.7715608046057948),
+ FL2FXCONST_DBL(0.7727813871397293), FL2FXCONST_DBL(0.7740024518315765),
+ FL2FXCONST_DBL(0.7752239983008605), FL2FXCONST_DBL(0.7764460261678551),
+ FL2FXCONST_DBL(0.7776685350535814), FL2FXCONST_DBL(0.7788915245798054),
+ FL2FXCONST_DBL(0.7801149943690360), FL2FXCONST_DBL(0.7813389440445223),
+ FL2FXCONST_DBL(0.7825633732302513), FL2FXCONST_DBL(0.7837882815509458),
+ FL2FXCONST_DBL(0.7850136686320621), FL2FXCONST_DBL(0.7862395340997874),
+ FL2FXCONST_DBL(0.7874658775810378), FL2FXCONST_DBL(0.7886926987034559),
+ FL2FXCONST_DBL(0.7899199970954088), FL2FXCONST_DBL(0.7911477723859853),
+ FL2FXCONST_DBL(0.7923760242049944), FL2FXCONST_DBL(0.7936047521829623),
+ FL2FXCONST_DBL(0.7948339559511308), FL2FXCONST_DBL(0.7960636351414546),
+ FL2FXCONST_DBL(0.7972937893865995), FL2FXCONST_DBL(0.7985244183199399),
+ FL2FXCONST_DBL(0.7997555215755570), FL2FXCONST_DBL(0.8009870987882359),
+ FL2FXCONST_DBL(0.8022191495934644), FL2FXCONST_DBL(0.8034516736274301),
+ FL2FXCONST_DBL(0.8046846705270185), FL2FXCONST_DBL(0.8059181399298110),
+ FL2FXCONST_DBL(0.8071520814740822), FL2FXCONST_DBL(0.8083864947987989),
+ FL2FXCONST_DBL(0.8096213795436166), FL2FXCONST_DBL(0.8108567353488784),
+ FL2FXCONST_DBL(0.8120925618556127), FL2FXCONST_DBL(0.8133288587055308),
+ FL2FXCONST_DBL(0.8145656255410253), FL2FXCONST_DBL(0.8158028620051674),
+ FL2FXCONST_DBL(0.8170405677417053), FL2FXCONST_DBL(0.8182787423950622),
+ FL2FXCONST_DBL(0.8195173856103341), FL2FXCONST_DBL(0.8207564970332875),
+ FL2FXCONST_DBL(0.8219960763103580), FL2FXCONST_DBL(0.8232361230886477),
+ FL2FXCONST_DBL(0.8244766370159234), FL2FXCONST_DBL(0.8257176177406150),
+ FL2FXCONST_DBL(0.8269590649118125), FL2FXCONST_DBL(0.8282009781792650),
+ FL2FXCONST_DBL(0.8294433571933784), FL2FXCONST_DBL(0.8306862016052132),
+ FL2FXCONST_DBL(0.8319295110664831), FL2FXCONST_DBL(0.8331732852295520),
+ FL2FXCONST_DBL(0.8344175237474336), FL2FXCONST_DBL(0.8356622262737878),
+ FL2FXCONST_DBL(0.8369073924629202), FL2FXCONST_DBL(0.8381530219697793),
+ FL2FXCONST_DBL(0.8393991144499545), FL2FXCONST_DBL(0.8406456695596752),
+ FL2FXCONST_DBL(0.8418926869558079), FL2FXCONST_DBL(0.8431401662958544),
+ FL2FXCONST_DBL(0.8443881072379507), FL2FXCONST_DBL(0.8456365094408642),
+ FL2FXCONST_DBL(0.8468853725639923), FL2FXCONST_DBL(0.8481346962673606),
+ FL2FXCONST_DBL(0.8493844802116208), FL2FXCONST_DBL(0.8506347240580492),
+ FL2FXCONST_DBL(0.8518854274685442), FL2FXCONST_DBL(0.8531365901056253),
+ FL2FXCONST_DBL(0.8543882116324307), FL2FXCONST_DBL(0.8556402917127157),
+ FL2FXCONST_DBL(0.8568928300108512), FL2FXCONST_DBL(0.8581458261918209),
+ FL2FXCONST_DBL(0.8593992799212207), FL2FXCONST_DBL(0.8606531908652563),
+ FL2FXCONST_DBL(0.8619075586907414), FL2FXCONST_DBL(0.8631623830650962),
+ FL2FXCONST_DBL(0.8644176636563452), FL2FXCONST_DBL(0.8656734001331161),
+ FL2FXCONST_DBL(0.8669295921646375), FL2FXCONST_DBL(0.8681862394207371),
+ FL2FXCONST_DBL(0.8694433415718407), FL2FXCONST_DBL(0.8707008982889695),
+ FL2FXCONST_DBL(0.8719589092437391), FL2FXCONST_DBL(0.8732173741083574),
+ FL2FXCONST_DBL(0.8744762925556232), FL2FXCONST_DBL(0.8757356642589241),
+ FL2FXCONST_DBL(0.8769954888922352), FL2FXCONST_DBL(0.8782557661301171),
+ FL2FXCONST_DBL(0.8795164956477146), FL2FXCONST_DBL(0.8807776771207545),
+ FL2FXCONST_DBL(0.8820393102255443), FL2FXCONST_DBL(0.8833013946389704),
+ FL2FXCONST_DBL(0.8845639300384969), FL2FXCONST_DBL(0.8858269161021629),
+ FL2FXCONST_DBL(0.8870903525085819), FL2FXCONST_DBL(0.8883542389369399),
+ FL2FXCONST_DBL(0.8896185750669933), FL2FXCONST_DBL(0.8908833605790678),
+ FL2FXCONST_DBL(0.8921485951540565), FL2FXCONST_DBL(0.8934142784734187),
+ FL2FXCONST_DBL(0.8946804102191776), FL2FXCONST_DBL(0.8959469900739191),
+ FL2FXCONST_DBL(0.8972140177207906), FL2FXCONST_DBL(0.8984814928434985),
+ FL2FXCONST_DBL(0.8997494151263077), FL2FXCONST_DBL(0.9010177842540390),
+ FL2FXCONST_DBL(0.9022865999120682), FL2FXCONST_DBL(0.9035558617863242),
+ FL2FXCONST_DBL(0.9048255695632878), FL2FXCONST_DBL(0.9060957229299895),
+ FL2FXCONST_DBL(0.9073663215740092), FL2FXCONST_DBL(0.9086373651834729),
+ FL2FXCONST_DBL(0.9099088534470528), FL2FXCONST_DBL(0.9111807860539647),
+ FL2FXCONST_DBL(0.9124531626939672), FL2FXCONST_DBL(0.9137259830573594),
+ FL2FXCONST_DBL(0.9149992468349805), FL2FXCONST_DBL(0.9162729537182071),
+ FL2FXCONST_DBL(0.9175471033989524), FL2FXCONST_DBL(0.9188216955696648),
+ FL2FXCONST_DBL(0.9200967299233258), FL2FXCONST_DBL(0.9213722061534494),
+ FL2FXCONST_DBL(0.9226481239540795), FL2FXCONST_DBL(0.9239244830197896),
+ FL2FXCONST_DBL(0.9252012830456805), FL2FXCONST_DBL(0.9264785237273793),
+ FL2FXCONST_DBL(0.9277562047610376), FL2FXCONST_DBL(0.9290343258433305),
+ FL2FXCONST_DBL(0.9303128866714547), FL2FXCONST_DBL(0.9315918869431275),
+ FL2FXCONST_DBL(0.9328713263565848), FL2FXCONST_DBL(0.9341512046105802),
+ FL2FXCONST_DBL(0.9354315214043836), FL2FXCONST_DBL(0.9367122764377792),
+ FL2FXCONST_DBL(0.9379934694110648), FL2FXCONST_DBL(0.9392751000250497),
+ FL2FXCONST_DBL(0.9405571679810542), FL2FXCONST_DBL(0.9418396729809072),
+ FL2FXCONST_DBL(0.9431226147269456), FL2FXCONST_DBL(0.9444059929220124),
+ FL2FXCONST_DBL(0.9456898072694558), FL2FXCONST_DBL(0.9469740574731275),
+ FL2FXCONST_DBL(0.9482587432373810), FL2FXCONST_DBL(0.9495438642670713),
+ FL2FXCONST_DBL(0.9508294202675522), FL2FXCONST_DBL(0.9521154109446763),
+ FL2FXCONST_DBL(0.9534018360047926), FL2FXCONST_DBL(0.9546886951547455),
+ FL2FXCONST_DBL(0.9559759881018738), FL2FXCONST_DBL(0.9572637145540087),
+ FL2FXCONST_DBL(0.9585518742194732), FL2FXCONST_DBL(0.9598404668070802),
+ FL2FXCONST_DBL(0.9611294920261317), FL2FXCONST_DBL(0.9624189495864168),
+ FL2FXCONST_DBL(0.9637088391982110), FL2FXCONST_DBL(0.9649991605722750),
+ FL2FXCONST_DBL(0.9662899134198524), FL2FXCONST_DBL(0.9675810974526697),
+ FL2FXCONST_DBL(0.9688727123829343), FL2FXCONST_DBL(0.9701647579233330),
+ FL2FXCONST_DBL(0.9714572337870316), FL2FXCONST_DBL(0.9727501396876727),
+ FL2FXCONST_DBL(0.9740434753393749), FL2FXCONST_DBL(0.9753372404567313),
+ FL2FXCONST_DBL(0.9766314347548087), FL2FXCONST_DBL(0.9779260579491460),
+ FL2FXCONST_DBL(0.9792211097557527), FL2FXCONST_DBL(0.9805165898911081),
+ FL2FXCONST_DBL(0.9818124980721600), FL2FXCONST_DBL(0.9831088340163232),
+ FL2FXCONST_DBL(0.9844055974414786), FL2FXCONST_DBL(0.9857027880659716),
+ FL2FXCONST_DBL(0.9870004056086111), FL2FXCONST_DBL(0.9882984497886684),
+ FL2FXCONST_DBL(0.9895969203258759), FL2FXCONST_DBL(0.9908958169404255),
+ FL2FXCONST_DBL(0.9921951393529680), FL2FXCONST_DBL(0.9934948872846116),
+ FL2FXCONST_DBL(0.9947950604569206), FL2FXCONST_DBL(0.9960956585919144),
+ FL2FXCONST_DBL(0.9973966814120665), FL2FXCONST_DBL(0.9986981286403025)};
+
+const FIXP_DBL FDKaacEnc_specExpMantTableCombElc[4][14] = {
+ {FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366),
+ FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000),
+ FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998),
+ FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366),
+ FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000),
+ FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998),
+ FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366)},
+
+ {FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408),
+ FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605),
+ FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935),
+ FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408),
+ FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605),
+ FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935),
+ FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408)},
+
+ {FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393),
+ FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476),
+ FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865),
+ FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393),
+ FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476),
+ FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865),
+ FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393)},
+
+ {FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477),
+ FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145),
+ FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172),
+ FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477),
+ FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145),
+ FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172),
+ FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477)}};
+
+const UCHAR FDKaacEnc_specExpTableComb[4][14] = {
+ {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18},
+ {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18},
+ {1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18},
+ {1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19}};
+
+#define WTS0 1
+#define WTS1 0
+#define WTS2 -2
+
+const FIXP_WTB ELDAnalysis512[1536] = {
+ /* part 0 */
+ WTC0(0xfac5a770), WTC0(0xfaafbab8), WTC0(0xfa996a40), WTC0(0xfa82bbd0),
+ WTC0(0xfa6bb538), WTC0(0xfa545c38), WTC0(0xfa3cb698), WTC0(0xfa24ca28),
+ WTC0(0xfa0c9ca8), WTC0(0xf9f433e8), WTC0(0xf9db9580), WTC0(0xf9c2c298),
+ WTC0(0xf9a9b800), WTC0(0xf9907250), WTC0(0xf976ee38), WTC0(0xf95d2b88),
+ WTC0(0xf9432d10), WTC0(0xf928f5c0), WTC0(0xf90e8868), WTC0(0xf8f3e400),
+ WTC0(0xf8d903a0), WTC0(0xf8bde238), WTC0(0xf8a27af0), WTC0(0xf886cde8),
+ WTC0(0xf86ae020), WTC0(0xf84eb6c0), WTC0(0xf83256f8), WTC0(0xf815c4b8),
+ WTC0(0xf7f902c0), WTC0(0xf7dc13b0), WTC0(0xf7befa60), WTC0(0xf7a1ba40),
+ WTC0(0xf78457c0), WTC0(0xf766d780), WTC0(0xf7493d90), WTC0(0xf72b8990),
+ WTC0(0xf70db5f0), WTC0(0xf6efbd30), WTC0(0xf6d19a20), WTC0(0xf6b352e0),
+ WTC0(0xf694f8c0), WTC0(0xf6769da0), WTC0(0xf6585310), WTC0(0xf63a28d0),
+ WTC0(0xf61c2c60), WTC0(0xf5fe6b10), WTC0(0xf5e0f250), WTC0(0xf5c3ceb0),
+ WTC0(0xf5a70be0), WTC0(0xf58ab5a0), WTC0(0xf56ed7b0), WTC0(0xf5537e40),
+ WTC0(0xf538b610), WTC0(0xf51e8bf0), WTC0(0xf5050c90), WTC0(0xf4ec4330),
+ WTC0(0xf4d439b0), WTC0(0xf4bcf9b0), WTC0(0xf4a68ce0), WTC0(0xf490fa80),
+ WTC0(0xf47c4760), WTC0(0xf4687830), WTC0(0xf4558f00), WTC0(0xf4434fc0),
+ WTC0(0xf4314070), WTC0(0xf41ee450), WTC0(0xf40bc130), WTC0(0xf3f799c0),
+ WTC0(0xf3e26d30), WTC0(0xf3cc3d70), WTC0(0xf3b50c80), WTC0(0xf39cdd60),
+ WTC0(0xf383b440), WTC0(0xf3699550), WTC0(0xf34e84c0), WTC0(0xf33286b0),
+ WTC0(0xf3159f10), WTC0(0xf2f7d1b0), WTC0(0xf2d92290), WTC0(0xf2b994d0),
+ WTC0(0xf2992ad0), WTC0(0xf277e6d0), WTC0(0xf255cb60), WTC0(0xf232dd00),
+ WTC0(0xf20f2240), WTC0(0xf1eaa1d0), WTC0(0xf1c56240), WTC0(0xf19f63d0),
+ WTC0(0xf178a0f0), WTC0(0xf15113a0), WTC0(0xf128b5c0), WTC0(0xf0ff7fd0),
+ WTC0(0xf0d56860), WTC0(0xf0aa6610), WTC0(0xf07e6fd0), WTC0(0xf0518190),
+ WTC0(0xf0239cd0), WTC0(0xeff4c320), WTC0(0xefc4f720), WTC0(0xef945080),
+ WTC0(0xef62fce0), WTC0(0xef312a40), WTC0(0xeeff05c0), WTC0(0xeecca2c0),
+ WTC0(0xee99faa0), WTC0(0xee6705a0), WTC0(0xee33bb60), WTC0(0xee000060),
+ WTC0(0xedcba660), WTC0(0xed967e80), WTC0(0xed605b80), WTC0(0xed293b40),
+ WTC0(0xecf146a0), WTC0(0xecb8a8a0), WTC0(0xec7f8bc0), WTC0(0xec461260),
+ WTC0(0xec0c5720), WTC0(0xebd27440), WTC0(0xeb988220), WTC0(0xeb5e7040),
+ WTC0(0xeb2404c0), WTC0(0xeae90440), WTC0(0xeaad33c0), WTC0(0xea7066c0),
+ WTC0(0xea327f60), WTC0(0xe9f36000), WTC0(0xe9b2ed60), WTC0(0xe9713920),
+ WTC0(0xe92e81e0), WTC0(0xe8eb08c0), WTC0(0xe8a70e60), WTC0(0xe862d8e0),
+ WTC0(0xe81eb340), WTC0(0xe7dae8a0), WTC0(0xe797c1a0), WTC0(0xe7554ca0),
+ WTC0(0xe7135dc0), WTC0(0xe6d1c6a0), WTC0(0xe6905720), WTC0(0xe64eb9c0),
+ WTC0(0xe60c7300), WTC0(0xe5c90600), WTC0(0xe583f920), WTC0(0xe53d1ce0),
+ WTC0(0xe4f48c80), WTC0(0xe4aa6640), WTC0(0xe45ecaa0), WTC0(0xe4120be0),
+ WTC0(0xe3c4ae60), WTC0(0xe3773860), WTC0(0xe32a2ea0), WTC0(0xe2ddeea0),
+ WTC0(0xe292af00), WTC0(0xe248a4a0), WTC0(0xe2000140), WTC0(0xe1b8b640),
+ WTC0(0xe1727440), WTC0(0xe12ce900), WTC0(0xe0e7c280), WTC0(0xe0a2b420),
+ WTC0(0xe05d76c0), WTC0(0xe017c360), WTC0(0xdfd15440), WTC0(0xdf8a0540),
+ WTC0(0xdf41d300), WTC0(0xdef8bb40), WTC0(0xdeaebd40), WTC0(0xde63e7c0),
+ WTC0(0xde185940), WTC0(0xddcc3180), WTC0(0xdd7f9000), WTC0(0xdd329e80),
+ WTC0(0xdce58e80), WTC0(0xdc989300), WTC0(0xdc4bde40), WTC0(0xdbff96c0),
+ WTC0(0xdbb3d780), WTC0(0xdb68bb80), WTC0(0xdb1e5c80), WTC0(0xdad4c380),
+ WTC0(0xda8be840), WTC0(0xda43c1c0), WTC0(0xd9fc4740), WTC0(0xd9b56640),
+ WTC0(0xd96f0440), WTC0(0xd9290600), WTC0(0xd8e35080), WTC0(0xd89dcd40),
+ WTC0(0xd8586b40), WTC0(0xd8131940), WTC0(0xd7cdc640), WTC0(0xd7886180),
+ WTC0(0xd742dc80), WTC0(0xd6fd2780), WTC0(0xd6b73400), WTC0(0xd670fd80),
+ WTC0(0xd62a8a40), WTC0(0xd5e3e080), WTC0(0xd59d0840), WTC0(0xd5562b80),
+ WTC0(0xd50f9540), WTC0(0xd4c992c0), WTC0(0xd4846f80), WTC0(0xd4405a80),
+ WTC0(0xd3fd6580), WTC0(0xd3bba140), WTC0(0xd37b1c80), WTC0(0xd33bb780),
+ WTC0(0xd2fd2400), WTC0(0xd2bf1240), WTC0(0xd2813300), WTC0(0xd2435ac0),
+ WTC0(0xd2057fc0), WTC0(0xd1c79a00), WTC0(0xd189a240), WTC0(0xd14b9dc0),
+ WTC0(0xd10d9e00), WTC0(0xd0cfb580), WTC0(0xd091f6c0), WTC0(0xd0548100),
+ WTC0(0xd0177f40), WTC0(0xcfdb1cc0), WTC0(0xcf9f84c0), WTC0(0xcf64d780),
+ WTC0(0xcf2b2b00), WTC0(0xcef29440), WTC0(0xcebb2640), WTC0(0xce84c000),
+ WTC0(0xce4f0bc0), WTC0(0xce19b200), WTC0(0xcde45d40), WTC0(0xcdaeedc0),
+ WTC0(0xcd7979c0), WTC0(0xcd4419c0), WTC0(0xcd0ee6c0), WTC0(0xccda0540),
+ WTC0(0xcca5a500), WTC0(0xcc71f640), WTC0(0xcc3f2800), WTC0(0xcc0d4300),
+ WTC0(0xcbdc2a00), WTC0(0xcbabbe80), WTC0(0xcb7be200), WTC0(0xcb4c8200),
+ WTC0(0xcb1d9800), WTC0(0xcaef1d40), WTC0(0xcac10bc0), WTC0(0xca936440),
+ WTC0(0xca662d00), WTC0(0xca396d40), WTC0(0xca0d2b80), WTC0(0xc9e16f80),
+ WTC0(0xc9b63f80), WTC0(0xc98ba2c0), WTC0(0xc961a000), WTC0(0xc9383ec0),
+ WTC0(0xc90a0440), WTC0(0xc8e0d280), WTC0(0xc8b73b80), WTC0(0xc88d4900),
+ WTC0(0xc86304c0), WTC0(0xc83878c0), WTC0(0xc80dae80), WTC0(0xc7e2afc0),
+ WTC0(0xc7b78640), WTC0(0xc78c3c40), WTC0(0xc760da80), WTC0(0xc7356640),
+ WTC0(0xc709de40), WTC0(0xc6de41c0), WTC0(0xc6b28fc0), WTC0(0xc686bd40),
+ WTC0(0xc65ab600), WTC0(0xc62e6580), WTC0(0xc601b880), WTC0(0xc5d4bac0),
+ WTC0(0xc5a79640), WTC0(0xc57a76c0), WTC0(0xc54d8780), WTC0(0xc520e840),
+ WTC0(0xc4f4acc0), WTC0(0xc4c8e880), WTC0(0xc49dad80), WTC0(0xc472e640),
+ WTC0(0xc44856c0), WTC0(0xc41dc140), WTC0(0xc3f2e940), WTC0(0xc3c7bc00),
+ WTC0(0xc39c4f00), WTC0(0xc370b9c0), WTC0(0xc34513c0), WTC0(0xc3197940),
+ WTC0(0xc2ee0a00), WTC0(0xc2c2e640), WTC0(0xc2982d80), WTC0(0xc26df5c0),
+ WTC0(0xc2444b00), WTC0(0xc21b3940), WTC0(0xc1f2cbc0), WTC0(0xc1cb05c0),
+ WTC0(0xc1a3e340), WTC0(0xc17d5f00), WTC0(0xc15773c0), WTC0(0xc1320940),
+ WTC0(0xc10cf480), WTC0(0xc0e80a00), WTC0(0xc0c31f00), WTC0(0xc09e2640),
+ WTC0(0xc0792ec0), WTC0(0xc0544940), WTC0(0xc02f86c0), WTC0(0xc00b04c0),
+ WTC0(0xbfe6ed01), WTC0(0xbfc36a01), WTC0(0xbfa0a581), WTC0(0xbf7eb581),
+ WTC0(0xbf5d9a81), WTC0(0xbf3d5501), WTC0(0xbf1de601), WTC0(0xbeff4801),
+ WTC0(0xbee17201), WTC0(0xbec45881), WTC0(0xbea7f301), WTC0(0xbe8c3781),
+ WTC0(0xbe712001), WTC0(0xbe56a381), WTC0(0xbe3cbc01), WTC0(0xbe236001),
+ WTC0(0xbe0a8581), WTC0(0xbdf22181), WTC0(0xbdda2a01), WTC0(0xbdc29a81),
+ WTC0(0xbdab7181), WTC0(0xbd94b001), WTC0(0xbd7e5581), WTC0(0xbd686681),
+ WTC0(0xbd52eb01), WTC0(0xbd3deb81), WTC0(0xbd297181), WTC0(0xbd158801),
+ WTC0(0xbd023f01), WTC0(0xbcefa601), WTC0(0xbcddcc81), WTC0(0xbcccbd01),
+ WTC0(0xbcbc7e01), WTC0(0xbcad1501), WTC0(0xbc9e8801), WTC0(0xbc90d481),
+ WTC0(0xbc83f201), WTC0(0xbc77d601), WTC0(0xbc6c7781), WTC0(0xbc61c401),
+ WTC0(0xbc57a301), WTC0(0xbc4dfb81), WTC0(0xbc44b481), WTC0(0xbc3bbc01),
+ WTC0(0xbc330781), WTC0(0xbc2a8c81), WTC0(0xbc224181), WTC0(0xbc1a2401),
+ WTC0(0xbc123b81), WTC0(0xbc0a8f01), WTC0(0xbc032601), WTC0(0xbbfc0f81),
+ WTC0(0xbbf56181), WTC0(0xbbef3301), WTC0(0xbbe99981), WTC0(0xbbe49d01),
+ WTC0(0xbbe03801), WTC0(0xbbdc6481), WTC0(0xbbd91b81), WTC0(0xbbd64d01),
+ WTC0(0xbbd3e101), WTC0(0xbbd1bd81), WTC0(0xbbcfca81), WTC0(0xbbce0601),
+ WTC0(0xbbcc8201), WTC0(0xbbcb5301), WTC0(0xbbca8d01), WTC0(0xbbca5081),
+ WTC0(0xbbcaca01), WTC0(0xbbcc2681), WTC0(0xbbce9181), WTC0(0xbbd21281),
+ WTC0(0xbbd68c81), WTC0(0xbbdbe201), WTC0(0xbbe1f401), WTC0(0xbbe89901),
+ WTC0(0xbbef9b81), WTC0(0xbbf6c601), WTC0(0xbbfde481), WTC0(0xbc04e381),
+ WTC0(0xbc0bcf81), WTC0(0xbc12b801), WTC0(0xbc19ab01), WTC0(0xbc20ae01),
+ WTC0(0xbc27bd81), WTC0(0xbc2ed681), WTC0(0xbc35f501), WTC0(0xbc3d1801),
+ WTC0(0xbc444081), WTC0(0xbc4b6e81), WTC0(0xbc52a381), WTC0(0xbc59df81),
+ WTC0(0xbc612301), WTC0(0xbc686e01), WTC0(0xbc6fc101), WTC0(0xbc771c01),
+ WTC0(0xbc7e7e01), WTC0(0xbc85e801), WTC0(0xbc8d5901), WTC0(0xbc94d201),
+ WTC0(0xbc9c5281), WTC0(0xbca3db01), WTC0(0xbcab6c01), WTC0(0xbcb30601),
+ WTC0(0xbcbaa801), WTC0(0xbcc25181), WTC0(0xbcca0301), WTC0(0xbcd1bb81),
+ WTC0(0xbcd97c81), WTC0(0xbce14601), WTC0(0xbce91801), WTC0(0xbcf0f381),
+ WTC0(0xbcf8d781), WTC0(0xbd00c381), WTC0(0xbd08b781), WTC0(0xbd10b381),
+ WTC0(0xbd18b781), WTC0(0xbd20c401), WTC0(0xbd28d981), WTC0(0xbd30f881),
+ WTC0(0xbd391f81), WTC0(0xbd414f01), WTC0(0xbd498601), WTC0(0xbd51c481),
+ WTC0(0xbd5a0b01), WTC0(0xbd625981), WTC0(0xbd6ab101), WTC0(0xbd731081),
+ WTC0(0xbd7b7781), WTC0(0xbd83e681), WTC0(0xbd8c5c01), WTC0(0xbd94d801),
+ WTC0(0xbd9d5b81), WTC0(0xbda5e601), WTC0(0xbdae7881), WTC0(0xbdb71201),
+ WTC0(0xbdbfb281), WTC0(0xbdc85981), WTC0(0xbdd10681), WTC0(0xbdd9b981),
+ WTC0(0xbde27201), WTC0(0xbdeb3101), WTC0(0xbdf3f701), WTC0(0xbdfcc301),
+ WTC0(0xbe059481), WTC0(0xbe0e6c01), WTC0(0xbe174781), WTC0(0xbe202801),
+ WTC0(0xbe290d01), WTC0(0xbe31f701), WTC0(0xbe3ae601), WTC0(0xbe43da81),
+ WTC0(0xbe4cd381), WTC0(0xbe55d001), WTC0(0xbe5ed081), WTC0(0xbe67d381),
+ WTC0(0xbe70da01), WTC0(0xbe79e481), WTC0(0xbe82f301), WTC0(0xbe8c0501),
+ WTC0(0xbe951a81), WTC0(0xbe9e3281), WTC0(0xbea74c81), WTC0(0xbeb06881),
+ WTC0(0xbeb98681), WTC0(0xbec2a781), WTC0(0xbecbca81), WTC0(0xbed4f081),
+ WTC0(0xbede1901), WTC0(0xbee74281), WTC0(0xbef06d01), WTC0(0xbef99901),
+ WTC0(0xbf02c581), WTC0(0xbf0bf381), WTC0(0xbf152381), WTC0(0xbf1e5501),
+ WTC0(0xbf278801), WTC0(0xbf30bb01), WTC0(0xbf39ee81), WTC0(0xbf432281),
+ WTC0(0xbf4c5681), WTC0(0xbf558b01), WTC0(0xbf5ec101), WTC0(0xbf67f801),
+ WTC0(0xbf712f01), WTC0(0xbf7a6681), WTC0(0xbf839d81), WTC0(0xbf8cd481),
+ WTC0(0xbf960b01), WTC0(0xbf9f4181), WTC0(0xbfa87901), WTC0(0xbfb1b101),
+ WTC0(0xbfbae981), WTC0(0xbfc42201), WTC0(0xbfcd5a01), WTC0(0xbfd69101),
+ WTC0(0xbfdfc781), WTC0(0xbfe8fc01), WTC0(0xbff22f81), WTC0(0xbffb6081),
+ /* part 1 */
+ WTC1(0x80093e01), WTC1(0x801b9b01), WTC1(0x802df701), WTC1(0x80405101),
+ WTC1(0x8052a881), WTC1(0x8064fc81), WTC1(0x80774c81), WTC1(0x80899881),
+ WTC1(0x809bdf01), WTC1(0x80ae1f81), WTC1(0x80c05a01), WTC1(0x80d28d81),
+ WTC1(0x80e4bb81), WTC1(0x80f6e481), WTC1(0x81090981), WTC1(0x811b2981),
+ WTC1(0x812d4481), WTC1(0x813f5981), WTC1(0x81516701), WTC1(0x81636d81),
+ WTC1(0x81756d81), WTC1(0x81876781), WTC1(0x81995c01), WTC1(0x81ab4b01),
+ WTC1(0x81bd3401), WTC1(0x81cf1581), WTC1(0x81e0ee81), WTC1(0x81f2bf81),
+ WTC1(0x82048881), WTC1(0x82164a81), WTC1(0x82280581), WTC1(0x8239b981),
+ WTC1(0x824b6601), WTC1(0x825d0901), WTC1(0x826ea201), WTC1(0x82803101),
+ WTC1(0x8291b601), WTC1(0x82a33281), WTC1(0x82b4a601), WTC1(0x82c61101),
+ WTC1(0x82d77201), WTC1(0x82e8c801), WTC1(0x82fa1181), WTC1(0x830b4f81),
+ WTC1(0x831c8101), WTC1(0x832da781), WTC1(0x833ec381), WTC1(0x834fd481),
+ WTC1(0x8360d901), WTC1(0x8371d081), WTC1(0x8382ba01), WTC1(0x83939501),
+ WTC1(0x83a46181), WTC1(0x83b52101), WTC1(0x83c5d381), WTC1(0x83d67881),
+ WTC1(0x83e70f01), WTC1(0x83f79681), WTC1(0x84080d81), WTC1(0x84187401),
+ WTC1(0x8428ca01), WTC1(0x84391081), WTC1(0x84494881), WTC1(0x84597081),
+ WTC1(0x84698881), WTC1(0x84798f81), WTC1(0x84898481), WTC1(0x84996701),
+ WTC1(0x84a93801), WTC1(0x84b8f801), WTC1(0x84c8a701), WTC1(0x84d84601),
+ WTC1(0x84e7d381), WTC1(0x84f74e01), WTC1(0x8506b581), WTC1(0x85160981),
+ WTC1(0x85254a81), WTC1(0x85347901), WTC1(0x85439601), WTC1(0x8552a181),
+ WTC1(0x85619a01), WTC1(0x85707f81), WTC1(0x857f5101), WTC1(0x858e0e01),
+ WTC1(0x859cb781), WTC1(0x85ab4f01), WTC1(0x85b9d481), WTC1(0x85c84801),
+ WTC1(0x85d6a981), WTC1(0x85e4f801), WTC1(0x85f33281), WTC1(0x86015981),
+ WTC1(0x860f6e01), WTC1(0x861d7081), WTC1(0x862b6201), WTC1(0x86394301),
+ WTC1(0x86471281), WTC1(0x8654d001), WTC1(0x86627b01), WTC1(0x86701381),
+ WTC1(0x867d9a81), WTC1(0x868b1001), WTC1(0x86987581), WTC1(0x86a5ca81),
+ WTC1(0x86b30f01), WTC1(0x86c04381), WTC1(0x86cd6681), WTC1(0x86da7901),
+ WTC1(0x86e77b81), WTC1(0x86f46d81), WTC1(0x87014f81), WTC1(0x870e2301),
+ WTC1(0x871ae981), WTC1(0x8727a381), WTC1(0x87345381), WTC1(0x8740f681),
+ WTC1(0x874d8681), WTC1(0x8759fd01), WTC1(0x87665481), WTC1(0x87729701),
+ WTC1(0x877ede01), WTC1(0x878b4301), WTC1(0x8797dd81), WTC1(0x87a48b01),
+ WTC1(0x87b0ef01), WTC1(0x87bcab81), WTC1(0x87c76201), WTC1(0x87d0ca81),
+ WTC1(0x87fdd781), WTC1(0x881dd301), WTC1(0x88423301), WTC1(0x886a8a81),
+ WTC1(0x88962981), WTC1(0x88c45e81), WTC1(0x88f47901), WTC1(0x8925f101),
+ WTC1(0x89586901), WTC1(0x898b8301), WTC1(0x89bee581), WTC1(0x89f26101),
+ WTC1(0x8a25f301), WTC1(0x8a599a81), WTC1(0x8a8d5801), WTC1(0x8ac13381),
+ WTC1(0x8af53e81), WTC1(0x8b298b81), WTC1(0x8b5e2c81), WTC1(0x8b933001),
+ WTC1(0x8bc8a401), WTC1(0x8bfe9401), WTC1(0x8c350d01), WTC1(0x8c6c1b01),
+ WTC1(0x8ca3cb01), WTC1(0x8cdc2901), WTC1(0x8d154081), WTC1(0x8d4f1b01),
+ WTC1(0x8d89be81), WTC1(0x8dc53001), WTC1(0x8e017581), WTC1(0x8e3e9481),
+ WTC1(0x8e7c9301), WTC1(0x8ebb7581), WTC1(0x8efb4181), WTC1(0x8f3bfb01),
+ WTC1(0x8f7da401), WTC1(0x8fc03f01), WTC1(0x9003ce81), WTC1(0x90485401),
+ WTC1(0x908dd101), WTC1(0x90d44781), WTC1(0x911bb981), WTC1(0x91642781),
+ WTC1(0x91ad9281), WTC1(0x91f7f981), WTC1(0x92435d01), WTC1(0x928fbe01),
+ WTC1(0x92dd1b01), WTC1(0x932b7501), WTC1(0x937acb01), WTC1(0x93cb1c81),
+ WTC1(0x941c6901), WTC1(0x946eaf81), WTC1(0x94c1ee01), WTC1(0x95162381),
+ WTC1(0x956b4f81), WTC1(0x95c17081), WTC1(0x96188501), WTC1(0x96708b81),
+ WTC1(0x96c98381), WTC1(0x97236b01), WTC1(0x977e4181), WTC1(0x97da0481),
+ WTC1(0x9836b201), WTC1(0x98944901), WTC1(0x98f2c601), WTC1(0x99522801),
+ WTC1(0x99b26c81), WTC1(0x9a139101), WTC1(0x9a759301), WTC1(0x9ad87081),
+ WTC1(0x9b3c2801), WTC1(0x9ba0b701), WTC1(0x9c061b81), WTC1(0x9c6c5481),
+ WTC1(0x9cd35f81), WTC1(0x9d3b3b81), WTC1(0x9da3e601), WTC1(0x9e0d5e01),
+ WTC1(0x9e779f81), WTC1(0x9ee2a901), WTC1(0x9f4e7801), WTC1(0x9fbb0981),
+ WTC1(0xa0285d81), WTC1(0xa0967201), WTC1(0xa1054701), WTC1(0xa174da81),
+ WTC1(0xa1e52a81), WTC1(0xa2563501), WTC1(0xa2c7f801), WTC1(0xa33a7201),
+ WTC1(0xa3ada281), WTC1(0xa4218801), WTC1(0xa4962181), WTC1(0xa50b6e81),
+ WTC1(0xa5816e81), WTC1(0xa5f81f81), WTC1(0xa66f8201), WTC1(0xa6e79401),
+ WTC1(0xa7605601), WTC1(0xa7d9c681), WTC1(0xa853e501), WTC1(0xa8ceb201),
+ WTC1(0xa94a2c01), WTC1(0xa9c65401), WTC1(0xaa432981), WTC1(0xaac0ad01),
+ WTC1(0xab3edf01), WTC1(0xabbdc001), WTC1(0xac3d5001), WTC1(0xacbd9081),
+ WTC1(0xad3e8101), WTC1(0xadc02281), WTC1(0xae427481), WTC1(0xaec57801),
+ WTC1(0xaf492f01), WTC1(0xafcd9a81), WTC1(0xb052bc01), WTC1(0xb0d89401),
+ WTC1(0xb15f2381), WTC1(0xb1e66a01), WTC1(0xb26e6881), WTC1(0xb2f71f01),
+ WTC1(0xb3808d81), WTC1(0xb40ab501), WTC1(0xb4959501), WTC1(0xb5212e81),
+ WTC1(0x4a6cf67f), WTC1(0x49dffeff), WTC1(0x495265ff), WTC1(0x48c4277f),
+ WTC1(0x4835407f), WTC1(0x47a5aeff), WTC1(0x471570ff), WTC1(0x468484ff),
+ WTC1(0x45f2eaff), WTC1(0x4560a2ff), WTC1(0x44cdad7f), WTC1(0x443a0c7f),
+ WTC1(0x43a5c07f), WTC1(0x4310caff), WTC1(0x427b2bff), WTC1(0x41e4e3ff),
+ WTC1(0x414df2ff), WTC1(0x40b6557f), WTC1(0x401e06ff), WTC1(0x3f8503c0),
+ WTC1(0x3eeb4e00), WTC1(0x3e50ebc0), WTC1(0x3db5e680), WTC1(0x3d1a4680),
+ WTC1(0x3c7e10c0), WTC1(0x3be14cc0), WTC1(0x3b4402c0), WTC1(0x3aa63800),
+ WTC1(0x3a07e840), WTC1(0x39690880), WTC1(0x38c98700), WTC1(0x38295b40),
+ WTC1(0x37888a80), WTC1(0x36e71d40), WTC1(0x36451d80), WTC1(0x35a29400),
+ WTC1(0x34ff8800), WTC1(0x345c04c0), WTC1(0x33b81940), WTC1(0x3313d200),
+ WTC1(0x326f3800), WTC1(0x31ca5600), WTC1(0x31253840), WTC1(0x307fe8c0),
+ WTC1(0x2fda6e40), WTC1(0x2f34ce40), WTC1(0x2e8f0e40), WTC1(0x2de92ec0),
+ WTC1(0x2d432780), WTC1(0x2c9cea40), WTC1(0x2bf66300), WTC1(0x2b4f88c0),
+ WTC1(0x2aa864c0), WTC1(0x2a010240), WTC1(0x29596e40), WTC1(0x28b1ba80),
+ WTC1(0x2809ff40), WTC1(0x27625b80), WTC1(0x26baf580), WTC1(0x2613e7c0),
+ WTC1(0x256d3dc0), WTC1(0x24c70300), WTC1(0x24214380), WTC1(0x237c0800),
+ WTC1(0x22d75400), WTC1(0x22332a80), WTC1(0x218f8cc0), WTC1(0x20ec7e40),
+ WTC1(0x204a04c0), WTC1(0x1fa82540), WTC1(0x1f06e300), WTC1(0x1e664000),
+ WTC1(0x1dc63bc0), WTC1(0x1d26d3c0), WTC1(0x1c8803a0), WTC1(0x1be9cc40),
+ WTC1(0x1b4c34c0), WTC1(0x1aaf4480), WTC1(0x1a130260), WTC1(0x197774a0),
+ WTC1(0x18dca260), WTC1(0x184294e0), WTC1(0x17a95840), WTC1(0x1710fd80),
+ WTC1(0x16799ce0), WTC1(0x15e35340), WTC1(0x154e41a0), WTC1(0x14ba8360),
+ WTC1(0x14282be0), WTC1(0x13975100), WTC1(0x13080aa0), WTC1(0x127a6240),
+ WTC1(0x11ee50a0), WTC1(0x1163cc80), WTC1(0x10dacb20), WTC1(0x105333a0),
+ WTC1(0x0fccdb30), WTC1(0x0f478f40), WTC1(0x0ec31700), WTC1(0x0e3f4e80),
+ WTC1(0x0dbc27f0), WTC1(0x0d399000), WTC1(0x0cb76d00), WTC1(0x0c359d50),
+ WTC1(0x0bb3fd50), WTC1(0x0b326bd0), WTC1(0x0ab0ca80), WTC1(0x0a2f0dc0),
+ WTC1(0x09ad40c0), WTC1(0x092b7a90), WTC1(0x08a9db80), WTC1(0x08285c80),
+ WTC1(0x07a6c7b8), WTC1(0x0724e4e0), WTC1(0x06a27b80), WTC1(0x061f52f8),
+ WTC1(0x059b2ad0), WTC1(0x0515b568), WTC1(0x048ea058), WTC1(0x04066408),
+ WTC1(0x037e52d8), WTC1(0x02f7d3c8), WTC1(0x0274614c), WTC1(0x01f63008),
+ WTC1(0x0180403a), WTC1(0x0115c442), WTC1(0x00ba09e2), WTC1(0x006f077c),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ /* part 2 */
+ WTC2(0xfff36be1), WTC2(0xffdafbc1), WTC2(0xffc28035), WTC2(0xffa9fe8a),
+ WTC2(0xff917c08), WTC2(0xff78fdfc), WTC2(0xff6089af), WTC2(0xff48246c),
+ WTC2(0xff2fd37f), WTC2(0xff179c31), WTC2(0xfeff83b6), WTC2(0xfee78d18),
+ WTC2(0xfecfb93e), WTC2(0xfeb808f2), WTC2(0xfea07d06), WTC2(0xfe8916b4),
+ WTC2(0xfe71d7a0), WTC2(0xfe5ac174), WTC2(0xfe43d5d6), WTC2(0xfe2d167e),
+ WTC2(0xfe16852e), WTC2(0xfe0023a6), WTC2(0xfde9f3f8), WTC2(0xfdd3ff7c),
+ WTC2(0xfdbe56c0), WTC2(0xfda90aa8), WTC2(0xfd942b78), WTC2(0xfd7fbb20),
+ WTC2(0xfd6bad50), WTC2(0xfd57f510), WTC2(0xfd44857c), WTC2(0xfd3153fc),
+ WTC2(0xfd1e5840), WTC2(0xfd0b8a0c), WTC2(0xfcf8e180), WTC2(0xfce65eec),
+ WTC2(0xfcd40ad0), WTC2(0xfcc1ee0c), WTC2(0xfcb011e8), WTC2(0xfc9e896c),
+ WTC2(0xfc8d716c), WTC2(0xfc7ce720), WTC2(0xfc6d072c), WTC2(0xfc5de09c),
+ WTC2(0xfc4f74e8), WTC2(0xfc41c4e8), WTC2(0xfc34d0dc), WTC2(0xfc288a68),
+ WTC2(0xfc1cd49c), WTC2(0xfc1191e0), WTC2(0xfc06a4d0), WTC2(0xfbfbf3e8),
+ WTC2(0xfbf16990), WTC2(0xfbe6f068), WTC2(0xfbdc7428), WTC2(0xfbd1fc68),
+ WTC2(0xfbc7ac50), WTC2(0xfbbda868), WTC2(0xfbb41500), WTC2(0xfbab1438),
+ WTC2(0xfba2c5f8), WTC2(0xfb9b4a00), WTC2(0xfb94bfa8), WTC2(0xfb8f3b48),
+ WTC2(0xfb8ac638), WTC2(0xfb876970), WTC2(0xfb852d20), WTC2(0xfb840ae0),
+ WTC2(0xfb83ed60), WTC2(0xfb84bec0), WTC2(0xfb866918), WTC2(0xfb88d4a8),
+ WTC2(0xfb8be810), WTC2(0xfb8f89d0), WTC2(0xfb93a080), WTC2(0xfb981418),
+ WTC2(0xfb9ccdf0), WTC2(0xfba1b770), WTC2(0xfba6bae0), WTC2(0xfbabd5c0),
+ WTC2(0xfbb118d8), WTC2(0xfbb695c0), WTC2(0xfbbc5e90), WTC2(0xfbc29030),
+ WTC2(0xfbc95268), WTC2(0xfbd0cd78), WTC2(0xfbd929c8), WTC2(0xfbe294d0),
+ WTC2(0xfbed4108), WTC2(0xfbf96118), WTC2(0xfc0726c8), WTC2(0xfc16b064),
+ WTC2(0xfc280890), WTC2(0xfc3b3920), WTC2(0xfc504a98), WTC2(0xfc67271c),
+ WTC2(0xfc7f9a74), WTC2(0xfc996f18), WTC2(0xfcb46eb8), WTC2(0xfcd050b0),
+ WTC2(0xfcecba24), WTC2(0xfd094f64), WTC2(0xfd25b720), WTC2(0xfd41ce40),
+ WTC2(0xfd5da7f8), WTC2(0xfd7959d8), WTC2(0xfd94fb74), WTC2(0xfdb0d3fc),
+ WTC2(0xfdcd5a34), WTC2(0xfdeb06e4), WTC2(0xfe0a5184), WTC2(0xfe2b92c4),
+ WTC2(0xfe4f0486), WTC2(0xfe74df54), WTC2(0xfe9d5886), WTC2(0xfec85b92),
+ WTC2(0xfef58a16), WTC2(0xff248275), WTC2(0xff54e401), WTC2(0xff866330),
+ WTC2(0xffb8c99b), WTC2(0xffebe1c9), WTC2(0x001f786a), WTC2(0x00538bf9),
+ WTC2(0x00884cbc), WTC2(0x00bded23), WTC2(0x00f49f54), WTC2(0x012c8ee4),
+ WTC2(0x0165e0d2), WTC2(0x01a0b9d6), WTC2(0x01dd3d80), WTC2(0x021b74d4),
+ WTC2(0x025b4e48), WTC2(0x029cb730), WTC2(0x02df9d0c), WTC2(0x0323f1a4),
+ WTC2(0x0369ab00), WTC2(0x03b0bf5c), WTC2(0x03f925a0), WTC2(0x0442e3d8),
+ WTC2(0x048e0f40), WTC2(0x04dabdb0), WTC2(0x05290430), WTC2(0x0578e428),
+ WTC2(0x05ca4b60), WTC2(0x061d26c0), WTC2(0x067163d8), WTC2(0x06c6ff10),
+ WTC2(0x071e03b0), WTC2(0x07767da0), WTC2(0x07d07918), WTC2(0x082c08e0),
+ WTC2(0x08894660), WTC2(0x08e84b70), WTC2(0x094930b0), WTC2(0x09abf8d0),
+ WTC2(0x0a109020), WTC2(0x0a76e210), WTC2(0x0adeda50), WTC2(0x0b486b80),
+ WTC2(0x0bb38f00), WTC2(0x0c203e80), WTC2(0x0c8e73e0), WTC2(0x0cfe2c30),
+ WTC2(0x0d6f6820), WTC2(0x0de22850), WTC2(0x0e566d90), WTC2(0x0ecc3dd0),
+ WTC2(0x0f43a3a0), WTC2(0x0fbca9f0), WTC2(0x10375b80), WTC2(0x10b3be20),
+ WTC2(0x1131d280), WTC2(0x11b19960), WTC2(0x123313a0), WTC2(0x12b64380),
+ WTC2(0x133b2d00), WTC2(0x13c1d440), WTC2(0x144a3d60), WTC2(0x14d46900),
+ WTC2(0x15605480), WTC2(0x15edfd20), WTC2(0x167d6040), WTC2(0x170e7e80),
+ WTC2(0x17a15b80), WTC2(0x1835fb00), WTC2(0x18cc60a0), WTC2(0x19648dc0),
+ WTC2(0x19fe80e0), WTC2(0x1a9a38a0), WTC2(0x1b37b3e0), WTC2(0x1bd6f400),
+ WTC2(0x1c77fd20), WTC2(0x1d1ad400), WTC2(0x1dbf7c80), WTC2(0x1e65f820),
+ WTC2(0x1f0e4540), WTC2(0x1fb861e0), WTC2(0x20644cc0), WTC2(0x21120640),
+ WTC2(0x21c19240), WTC2(0x2272f480), WTC2(0x23263000), WTC2(0x23db4580),
+ WTC2(0x24923340), WTC2(0x254af700), WTC2(0x26058e80), WTC2(0x26c1fa00),
+ WTC2(0x27803d00), WTC2(0x28405a40), WTC2(0x29025500), WTC2(0x29c62d40),
+ WTC2(0x2a8be0c0), WTC2(0x2b536cc0), WTC2(0x2c1ccf80), WTC2(0x2ce80840),
+ WTC2(0x2db519c0), WTC2(0x2e840600), WTC2(0x2f54cf80), WTC2(0x302775c0),
+ WTC2(0x30fbf640), WTC2(0x31d24e00), WTC2(0x32aa7a00), WTC2(0x338479c0),
+ WTC2(0x34604e40), WTC2(0x353df900), WTC2(0x361d7ac0), WTC2(0x36fed200),
+ WTC2(0x37e1fb40), WTC2(0x38c6f240), WTC2(0x39adb2c0), WTC2(0x3a963a00),
+ WTC2(0x3b808740), WTC2(0x3c6c9880), WTC2(0x3d5a6cc0), WTC2(0x3e4a0040),
+ WTC2(0x3f3b4bc0), WTC2(0x402e48ff), WTC2(0x4122f17f), WTC2(0x42193f7f),
+ WTC2(0x43112eff), WTC2(0x440abbff), WTC2(0x4505e2ff), WTC2(0x46029e7f),
+ WTC2(0x4700e9ff), WTC2(0x4800bfff), WTC2(0x49021bff), WTC2(0x4a050eff),
+ WTC2(0x4b09bc7f), WTC2(0x4c104aff), WTC2(0x4d18df7f), WTC2(0x4e23a07f),
+ WTC2(0x4f30b2ff), WTC2(0x50403c7f), WTC2(0x515262ff), WTC2(0x52674b7f),
+ WTC2(0x001678b2), WTC2(0x00061a3b), WTC2(0xfffb4622), WTC2(0xfff5ea94),
+ WTC2(0xfff5f5b9), WTC2(0xfffb55bd), WTC2(0x0005f8cb), WTC2(0x0015cd0c),
+ WTC2(0x002ac0ac), WTC2(0x0044c1d5), WTC2(0x0063beb2), WTC2(0x0087a56d),
+ WTC2(0x00b06431), WTC2(0x00dde929), WTC2(0x01102280), WTC2(0x0146fe5e),
+ WTC2(0x01826af2), WTC2(0x01c25662), WTC2(0x0206aedc), WTC2(0x024f6288),
+ WTC2(0x029c5f94), WTC2(0x02ed9424), WTC2(0x0342ee6c), WTC2(0x039c5c90),
+ WTC2(0x03f9ccbc), WTC2(0x045b2d18), WTC2(0x04c06bd8), WTC2(0x05297718),
+ WTC2(0x05963d10), WTC2(0x0606abe8), WTC2(0x067ab1c0), WTC2(0x06f23cd0),
+ WTC2(0x076d3b40), WTC2(0x07eb9b38), WTC2(0x086d4ae0), WTC2(0x08f23860),
+ WTC2(0x097a51f0), WTC2(0x0a0585b0), WTC2(0x0a93c1d0), WTC2(0x0b24f470),
+ WTC2(0x0bb90bc0), WTC2(0x0c4ff5f0), WTC2(0x0ce9a130), WTC2(0x0d85fb90),
+ WTC2(0x0e24f360), WTC2(0x0ec676b0), WTC2(0x0f6a73b0), WTC2(0x1010d880),
+ WTC2(0x10b99360), WTC2(0x11649280), WTC2(0x1211c400), WTC2(0x12c115e0),
+ WTC2(0x137276a0), WTC2(0x1425d420), WTC2(0x14db1ca0), WTC2(0x15923e60),
+ WTC2(0x164b2780), WTC2(0x1705c620), WTC2(0x17c20860), WTC2(0x187fdca0),
+ WTC2(0x193f30e0), WTC2(0x19fff340), WTC2(0x1ac21200), WTC2(0x1b857b40),
+ WTC2(0x1c4a1d40), WTC2(0x1d0fe600), WTC2(0x1dd6c3e0), WTC2(0x1e9ea4e0),
+ WTC2(0x1f677740), WTC2(0x20312940), WTC2(0x20fba8c0), WTC2(0x21c6e440),
+ WTC2(0x2292c9c0), WTC2(0x235f4780), WTC2(0x242c4b80), WTC2(0x24f9c400),
+ WTC2(0x25c79f40), WTC2(0x2695cb40), WTC2(0x27643680), WTC2(0x2832cec0),
+ WTC2(0x29018240), WTC2(0x29d03f80), WTC2(0x2a9ef480), WTC2(0x2b6d8f00),
+ WTC2(0x2c3bfdc0), WTC2(0x2d0a2ec0), WTC2(0x2dd81000), WTC2(0x2ea58fc0),
+ WTC2(0x2f729c40), WTC2(0x303f2380), WTC2(0x310b1400), WTC2(0x31d65b80),
+ WTC2(0x32a0e840), WTC2(0x336aa8c0), WTC2(0x34338ac0), WTC2(0x34fb7cc0),
+ WTC2(0x35c26cc0), WTC2(0x36884900), WTC2(0x374cff80), WTC2(0x38107e80),
+ WTC2(0x38d2b440), WTC2(0x39938ec0), WTC2(0x3a52fc40), WTC2(0x3b10eb00),
+ WTC2(0x3bcd4900), WTC2(0x3c880480), WTC2(0x3d410bc0), WTC2(0x3df84d00),
+ WTC2(0x3eadb600), WTC2(0x3f613540), WTC2(0x4012b8ff), WTC2(0x40c22eff),
+ WTC2(0x416f85ff), WTC2(0x421aab7f), WTC2(0x42c38e7f), WTC2(0x436a1c7f),
+ WTC2(0x440e437f), WTC2(0x44aff27f), WTC2(0x454f167f), WTC2(0x45eb9eff),
+ WTC2(0x468578ff), WTC2(0x471c937f), WTC2(0x47b0dc7f), WTC2(0x484241ff),
+ WTC2(0x48d0b1ff), WTC2(0x495c1a7f), WTC2(0x49e46a7f), WTC2(0x4a698f7f),
+ WTC2(0x4aeb77ff), WTC2(0x4b6a11ff), WTC2(0x4be54b7f), WTC2(0x4c5d12ff),
+ WTC2(0x4cd155ff), WTC2(0x4d4203ff), WTC2(0x4daf09ff), WTC2(0x4e18567f),
+ WTC2(0x4e7dd77f), WTC2(0x4edf7b7f), WTC2(0x4f3d307f), WTC2(0x4f96e47f),
+ WTC2(0x4fec85ff), WTC2(0x503e02ff), WTC2(0x508b497f), WTC2(0x50d447ff),
+ WTC2(0x5118ec7f), WTC2(0x515924ff), WTC2(0x5194dfff), WTC2(0x51cc0b7f),
+ WTC2(0x51fe95ff), WTC2(0x522c6cff), WTC2(0x52557eff), WTC2(0x5279b9ff),
+ WTC2(0x52990c7f), WTC2(0x52b364ff), WTC2(0x52c8b07f), WTC2(0x52d8ddff),
+ WTC2(0x52e3db7f), WTC2(0x52e996ff), WTC2(0x52e9ff7f), WTC2(0x52e501ff),
+ WTC2(0x52da8cff), WTC2(0x52ca8f7f), WTC2(0x52b4f67f), WTC2(0x5299b07f),
+ WTC2(0x5278ac7f), WTC2(0x5251d77f), WTC2(0x52251fff), WTC2(0x51f274ff),
+ WTC2(0x51b9c37f), WTC2(0x517af9ff), WTC2(0x5136077f), WTC2(0x50ead8ff),
+ WTC2(0x50995cff), WTC2(0x504181ff), WTC2(0x4fe335ff), WTC2(0x4f7e677f),
+ WTC2(0x4f1303ff), WTC2(0x4ea0f9ff), WTC2(0x4e2837ff), WTC2(0x4da8ab7f),
+ WTC2(0x4d2242ff), WTC2(0x4c94ecff), WTC2(0x4c0096ff), WTC2(0x4b652f7f),
+ WTC2(0x4ac2a4ff), WTC2(0x4a18e4ff), WTC2(0x4967ddff), WTC2(0x48af7e7f),
+ WTC2(0x47efb3ff), WTC2(0x47286cff), WTC2(0x4659ad7f), WTC2(0x45856f7f),
+ WTC2(0x44afa3ff), WTC2(0x43dc507f), WTC2(0x430f657f), WTC2(0x424ad47f),
+ WTC2(0x418e927f), WTC2(0x40da7bff), WTC2(0x402e6f7f), WTC2(0x3f8a3100),
+ WTC2(0x3eed6f40), WTC2(0x3e57d700), WTC2(0x3dc914c0), WTC2(0x3d40cc40),
+ WTC2(0x3cbe98c0), WTC2(0x3c421540), WTC2(0x3bcadbc0), WTC2(0x3b588880),
+ WTC2(0x3aeab780), WTC2(0x3a810540), WTC2(0x3a1b0e00), WTC2(0x39b86d00),
+ WTC2(0x3958bcc0), WTC2(0x38fb9700), WTC2(0x38a095c0), WTC2(0x38473d80),
+ WTC2(0x37eeff40), WTC2(0x37974b40), WTC2(0x373f9500), WTC2(0x36e7ae00),
+ WTC2(0x368fc4c0), WTC2(0x36380b80), WTC2(0x35e0b300), WTC2(0x3589c140),
+ WTC2(0x35331180), WTC2(0x34dc7c80), WTC2(0x3485dc80), WTC2(0x342f1600),
+ WTC2(0x33d81780), WTC2(0x3380d0c0), WTC2(0x33293100), WTC2(0x32d11800),
+ WTC2(0x32785780), WTC2(0x321ec0c0), WTC2(0x31c42680), WTC2(0x316885c0),
+ WTC2(0x310c0580), WTC2(0x30aecec0), WTC2(0x30510940), WTC2(0x2ff2b8c0),
+ WTC2(0x2f93bf40), WTC2(0x2f33fc00), WTC2(0x2ed350c0), WTC2(0x2e71ba80),
+ WTC2(0x2e0f5340), WTC2(0x2dac35c0), WTC2(0x2d487c80), WTC2(0x2ce431c0),
+ WTC2(0x2c7f4fc0), WTC2(0x2c19d080), WTC2(0x2bb3ad80), WTC2(0x2b4ce080),
+ WTC2(0x2ae56340), WTC2(0x2a7d2f80), WTC2(0x2a143f00), WTC2(0x29aa8b40)};
+
+const FIXP_WTB ELDAnalysis480[1440] = {
+ WTC0(0xfacfbef0), WTC0(0xfab88c18), WTC0(0xfaa0e520), WTC0(0xfa88d110),
+ WTC0(0xfa7056e8), WTC0(0xfa577db0), WTC0(0xfa3e4c70), WTC0(0xfa24ca28),
+ WTC0(0xfa0afde0), WTC0(0xf9f0eea0), WTC0(0xf9d6a2c8), WTC0(0xf9bc1ab8),
+ WTC0(0xf9a15230), WTC0(0xf9864510), WTC0(0xf96af058), WTC0(0xf94f55c0),
+ WTC0(0xf93378e0), WTC0(0xf9175d80), WTC0(0xf8fb0468), WTC0(0xf8de68b8),
+ WTC0(0xf8c18438), WTC0(0xf8a450d8), WTC0(0xf886cde8), WTC0(0xf8690148),
+ WTC0(0xf84af148), WTC0(0xf82ca410), WTC0(0xf80e1e18), WTC0(0xf7ef62a0),
+ WTC0(0xf7d074e0), WTC0(0xf7b15870), WTC0(0xf7921240), WTC0(0xf772a7a0),
+ WTC0(0xf7531e50), WTC0(0xf7337820), WTC0(0xf713afd0), WTC0(0xf6f3bea0),
+ WTC0(0xf6d39dc0), WTC0(0xf6b352e0), WTC0(0xf692f280), WTC0(0xf6729250),
+ WTC0(0xf65247a0), WTC0(0xf63224c0), WTC0(0xf6123a00), WTC0(0xf5f297c0),
+ WTC0(0xf5d34dd0), WTC0(0xf5b46b10), WTC0(0xf595fd90), WTC0(0xf5781390),
+ WTC0(0xf55abba0), WTC0(0xf53e0510), WTC0(0xf521ff70), WTC0(0xf506ba30),
+ WTC0(0xf4ec4330), WTC0(0xf4d2a680), WTC0(0xf4b9efe0), WTC0(0xf4a22ac0),
+ WTC0(0xf48b5f70), WTC0(0xf4759310), WTC0(0xf460cde0), WTC0(0xf44cfcc0),
+ WTC0(0xf439aff0), WTC0(0xf4264e00), WTC0(0xf4123d90), WTC0(0xf3fd1370),
+ WTC0(0xf3e6be00), WTC0(0xf3cf41a0), WTC0(0xf3b6a030), WTC0(0xf39cdd60),
+ WTC0(0xf381fe00), WTC0(0xf3660760), WTC0(0xf348fe70), WTC0(0xf32ae820),
+ WTC0(0xf30bc940), WTC0(0xf2eba690), WTC0(0xf2ca8480), WTC0(0xf2a86670),
+ WTC0(0xf2854f40), WTC0(0xf2614190), WTC0(0xf23c41e0), WTC0(0xf21657a0),
+ WTC0(0xf1ef8ae0), WTC0(0xf1c7e3e0), WTC0(0xf19f63d0), WTC0(0xf1760450),
+ WTC0(0xf14bbdf0), WTC0(0xf1208960), WTC0(0xf0f45cd0), WTC0(0xf0c72ce0),
+ WTC0(0xf098ee00), WTC0(0xf06996f0), WTC0(0xf0392620), WTC0(0xf0079e10),
+ WTC0(0xefd4ffc0), WTC0(0xefa15ca0), WTC0(0xef6ce600), WTC0(0xef37d460),
+ WTC0(0xef025f80), WTC0(0xeecca2c0), WTC0(0xee969760), WTC0(0xee603440),
+ WTC0(0xee296d20), WTC0(0xedf21c00), WTC0(0xedba07e0), WTC0(0xed80f640),
+ WTC0(0xed46bf40), WTC0(0xed0b7b00), WTC0(0xeccf5fc0), WTC0(0xec92a120),
+ WTC0(0xec556d60), WTC0(0xec17e700), WTC0(0xebda2d40), WTC0(0xeb9c5fa0),
+ WTC0(0xeb5e7040), WTC0(0xeb201b20), WTC0(0xeae117c0), WTC0(0xeaa12000),
+ WTC0(0xea600180), WTC0(0xea1d9940), WTC0(0xe9d9c160), WTC0(0xe99468a0),
+ WTC0(0xe94dc040), WTC0(0xe9061940), WTC0(0xe8bdc140), WTC0(0xe8750ae0),
+ WTC0(0xe82c4fa0), WTC0(0xe7e3ea40), WTC0(0xe79c35e0), WTC0(0xe7554ca0),
+ WTC0(0xe70efc00), WTC0(0xe6c90c20), WTC0(0xe6833f00), WTC0(0xe63d2300),
+ WTC0(0xe5f620a0), WTC0(0xe5ad9dc0), WTC0(0xe5632080), WTC0(0xe5169da0),
+ WTC0(0xe4c83e60), WTC0(0xe4782400), WTC0(0xe4269840), WTC0(0xe3d42dc0),
+ WTC0(0xe38188c0), WTC0(0xe32f4be0), WTC0(0xe2ddeea0), WTC0(0xe28db520),
+ WTC0(0xe23ee000), WTC0(0xe1f1a580), WTC0(0xe1a5e3a0), WTC0(0xe15b35a0),
+ WTC0(0xe1113860), WTC0(0xe0c78a00), WTC0(0xe07dd0e0), WTC0(0xe033b7c0),
+ WTC0(0xdfe8e680), WTC0(0xdf9d1fc0), WTC0(0xdf5055c0), WTC0(0xdf0287c0),
+ WTC0(0xdeb3b340), WTC0(0xde63e7c0), WTC0(0xde134a00), WTC0(0xddc20000),
+ WTC0(0xdd703180), WTC0(0xdd1e1280), WTC0(0xdccbe080), WTC0(0xdc79d980),
+ WTC0(0xdc283600), WTC0(0xdbd71e00), WTC0(0xdb86b140), WTC0(0xdb3710c0),
+ WTC0(0xdae850c0), WTC0(0xda9a6bc0), WTC0(0xda4d5640), WTC0(0xda010640),
+ WTC0(0xd9b56640), WTC0(0xd96a5700), WTC0(0xd91fb700), WTC0(0xd8d56600),
+ WTC0(0xd88b4a40), WTC0(0xd8414f00), WTC0(0xd7f75f80), WTC0(0xd7ad6740),
+ WTC0(0xd76352c0), WTC0(0xd7191040), WTC0(0xd6ce8c80), WTC0(0xd683bd00),
+ WTC0(0xd638a5c0), WTC0(0xd5ed4f80), WTC0(0xd5a1c240), WTC0(0xd5562b80),
+ WTC0(0xd50ae500), WTC0(0xd4c04c80), WTC0(0xd476bb40), WTC0(0xd42e62c0),
+ WTC0(0xd3e75680), WTC0(0xd3a1ad00), WTC0(0xd35d6780), WTC0(0xd31a4300),
+ WTC0(0xd2d7dc00), WTC0(0xd295d080), WTC0(0xd253d8c0), WTC0(0xd211df40),
+ WTC0(0xd1cfdbc0), WTC0(0xd18dc480), WTC0(0xd14b9dc0), WTC0(0xd1097c80),
+ WTC0(0xd0c77700), WTC0(0xd085a500), WTC0(0xd0442f40), WTC0(0xd0034a80),
+ WTC0(0xcfc32c00), WTC0(0xcf840400), WTC0(0xcf45f400), WTC0(0xcf0913c0),
+ WTC0(0xcecd8000), WTC0(0xce932c80), WTC0(0xce59bf40), WTC0(0xce20cd40),
+ WTC0(0xcde7ec40), WTC0(0xcdaeedc0), WTC0(0xcd75ea00), WTC0(0xcd3cfec0),
+ WTC0(0xcd044b40), WTC0(0xcccbff00), WTC0(0xcc945480), WTC0(0xcc5d8780),
+ WTC0(0xcc27c3c0), WTC0(0xcbf2fc40), WTC0(0xcbbf0a00), WTC0(0xcb8bc7c0),
+ WTC0(0xcb591880), WTC0(0xcb26f0c0), WTC0(0xcaf54980), WTC0(0xcac41ac0),
+ WTC0(0xca936440), WTC0(0xca632d80), WTC0(0xca337f00), WTC0(0xca046180),
+ WTC0(0xc9d5dd40), WTC0(0xc9a7fa80), WTC0(0xc97ac200), WTC0(0xc94e3c00),
+ WTC0(0xc91d1840), WTC0(0xc8f15980), WTC0(0xc8c52340), WTC0(0xc8988100),
+ WTC0(0xc86b7f00), WTC0(0xc83e28c0), WTC0(0xc8108a80), WTC0(0xc7e2afc0),
+ WTC0(0xc7b4a480), WTC0(0xc7867480), WTC0(0xc7582b40), WTC0(0xc729cc80),
+ WTC0(0xc6fb5700), WTC0(0xc6ccca40), WTC0(0xc69e2180), WTC0(0xc66f49c0),
+ WTC0(0xc64029c0), WTC0(0xc610a740), WTC0(0xc5e0bfc0), WTC0(0xc5b09e80),
+ WTC0(0xc5807900), WTC0(0xc5508440), WTC0(0xc520e840), WTC0(0xc4f1bdc0),
+ WTC0(0xc4c31d00), WTC0(0xc4951780), WTC0(0xc4678a00), WTC0(0xc43a28c0),
+ WTC0(0xc40ca800), WTC0(0xc3deccc0), WTC0(0xc3b09940), WTC0(0xc3822c00),
+ WTC0(0xc353a0c0), WTC0(0xc3251740), WTC0(0xc2f6b500), WTC0(0xc2c8a140),
+ WTC0(0xc29b02c0), WTC0(0xc26df5c0), WTC0(0xc2418940), WTC0(0xc215cbc0),
+ WTC0(0xc1eaca00), WTC0(0xc1c08680), WTC0(0xc196fb00), WTC0(0xc16e22c0),
+ WTC0(0xc145f040), WTC0(0xc11e3a80), WTC0(0xc0f6cc00), WTC0(0xc0cf6ec0),
+ WTC0(0xc0a802c0), WTC0(0xc0809280), WTC0(0xc0593340), WTC0(0xc031f880),
+ WTC0(0xc00b04c0), WTC0(0xbfe48981), WTC0(0xbfbebb81), WTC0(0xbf99cb01),
+ WTC0(0xbf75cc81), WTC0(0xbf52c101), WTC0(0xbf30a901), WTC0(0xbf0f8301),
+ WTC0(0xbeef4601), WTC0(0xbecfe601), WTC0(0xbeb15701), WTC0(0xbe938c81),
+ WTC0(0xbe767e81), WTC0(0xbe5a2301), WTC0(0xbe3e7201), WTC0(0xbe236001),
+ WTC0(0xbe08e181), WTC0(0xbdeee981), WTC0(0xbdd56b81), WTC0(0xbdbc6381),
+ WTC0(0xbda3d081), WTC0(0xbd8bb281), WTC0(0xbd740b81), WTC0(0xbd5ce281),
+ WTC0(0xbd464281), WTC0(0xbd303581), WTC0(0xbd1ac801), WTC0(0xbd060c81),
+ WTC0(0xbcf21601), WTC0(0xbcdef701), WTC0(0xbcccbd01), WTC0(0xbcbb7001),
+ WTC0(0xbcab1781), WTC0(0xbc9bb901), WTC0(0xbc8d5101), WTC0(0xbc7fd301),
+ WTC0(0xbc733401), WTC0(0xbc676501), WTC0(0xbc5c4c81), WTC0(0xbc51cb01),
+ WTC0(0xbc47c281), WTC0(0xbc3e1981), WTC0(0xbc34c081), WTC0(0xbc2bab01),
+ WTC0(0xbc22cd81), WTC0(0xbc1a2401), WTC0(0xbc11b681), WTC0(0xbc098d81),
+ WTC0(0xbc01b381), WTC0(0xbbfa3c01), WTC0(0xbbf34281), WTC0(0xbbece281),
+ WTC0(0xbbe73201), WTC0(0xbbe23281), WTC0(0xbbdddb01), WTC0(0xbbda2501),
+ WTC0(0xbbd70201), WTC0(0xbbd45601), WTC0(0xbbd20301), WTC0(0xbbcfea81),
+ WTC0(0xbbce0601), WTC0(0xbbcc6b01), WTC0(0xbbcb3201), WTC0(0xbbca7481),
+ WTC0(0xbbca5d01), WTC0(0xbbcb2281), WTC0(0xbbccfc81), WTC0(0xbbd01301),
+ WTC0(0xbbd45881), WTC0(0xbbd9a781), WTC0(0xbbdfdb81), WTC0(0xbbe6c801),
+ WTC0(0xbbee2f81), WTC0(0xbbf5d181), WTC0(0xbbfd6c01), WTC0(0xbc04e381),
+ WTC0(0xbc0c4581), WTC0(0xbc13a481), WTC0(0xbc1b1081), WTC0(0xbc228f01),
+ WTC0(0xbc2a1a81), WTC0(0xbc31af01), WTC0(0xbc394901), WTC0(0xbc40e881),
+ WTC0(0xbc488e81), WTC0(0xbc503b81), WTC0(0xbc57f101), WTC0(0xbc5fae81),
+ WTC0(0xbc677501), WTC0(0xbc6f4401), WTC0(0xbc771c01), WTC0(0xbc7efc81),
+ WTC0(0xbc86e581), WTC0(0xbc8ed701), WTC0(0xbc96d101), WTC0(0xbc9ed481),
+ WTC0(0xbca6e101), WTC0(0xbcaef701), WTC0(0xbcb71701), WTC0(0xbcbf4001),
+ WTC0(0xbcc77181), WTC0(0xbccfac01), WTC0(0xbcd7ef01), WTC0(0xbce03b81),
+ WTC0(0xbce89281), WTC0(0xbcf0f381), WTC0(0xbcf95e81), WTC0(0xbd01d281),
+ WTC0(0xbd0a4f81), WTC0(0xbd12d581), WTC0(0xbd1b6501), WTC0(0xbd23ff01),
+ WTC0(0xbd2ca281), WTC0(0xbd355081), WTC0(0xbd3e0801), WTC0(0xbd46c801),
+ WTC0(0xbd4f9101), WTC0(0xbd586281), WTC0(0xbd613d81), WTC0(0xbd6a2201),
+ WTC0(0xbd731081), WTC0(0xbd7c0781), WTC0(0xbd850701), WTC0(0xbd8e0e01),
+ WTC0(0xbd971c81), WTC0(0xbda03381), WTC0(0xbda95301), WTC0(0xbdb27b01),
+ WTC0(0xbdbbab01), WTC0(0xbdc4e301), WTC0(0xbdce2181), WTC0(0xbdd76701),
+ WTC0(0xbde0b301), WTC0(0xbdea0681), WTC0(0xbdf36101), WTC0(0xbdfcc301),
+ WTC0(0xbe062b81), WTC0(0xbe0f9a01), WTC0(0xbe190d81), WTC0(0xbe228681),
+ WTC0(0xbe2c0501), WTC0(0xbe358901), WTC0(0xbe3f1381), WTC0(0xbe48a301),
+ WTC0(0xbe523781), WTC0(0xbe5bd001), WTC0(0xbe656c01), WTC0(0xbe6f0c01),
+ WTC0(0xbe78b001), WTC0(0xbe825801), WTC0(0xbe8c0501), WTC0(0xbe95b581),
+ WTC0(0xbe9f6901), WTC0(0xbea91f01), WTC0(0xbeb2d681), WTC0(0xbebc9181),
+ WTC0(0xbec64e81), WTC0(0xbed00f81), WTC0(0xbed9d281), WTC0(0xbee39801),
+ WTC0(0xbeed5f01), WTC0(0xbef72681), WTC0(0xbf00ef81), WTC0(0xbf0aba01),
+ WTC0(0xbf148681), WTC0(0xbf1e5501), WTC0(0xbf282501), WTC0(0xbf31f501),
+ WTC0(0xbf3bc601), WTC0(0xbf459681), WTC0(0xbf4f6801), WTC0(0xbf593a01),
+ WTC0(0xbf630d81), WTC0(0xbf6ce201), WTC0(0xbf76b701), WTC0(0xbf808b81),
+ WTC0(0xbf8a5f81), WTC0(0xbf943301), WTC0(0xbf9e0701), WTC0(0xbfa7dc01),
+ WTC0(0xbfb1b101), WTC0(0xbfbb8701), WTC0(0xbfc55c81), WTC0(0xbfcf3181),
+ WTC0(0xbfd90601), WTC0(0xbfe2d901), WTC0(0xbfecaa81), WTC0(0xbff67a01),
+ /* part 1 */
+ WTC1(0x80130981), WTC1(0x80269f81), WTC1(0x803a3381), WTC1(0x804dc481),
+ WTC1(0x80615281), WTC1(0x8074dc01), WTC1(0x80886081), WTC1(0x809bdf01),
+ WTC1(0x80af5701), WTC1(0x80c2c781), WTC1(0x80d63101), WTC1(0x80e99401),
+ WTC1(0x80fcf181), WTC1(0x81104a01), WTC1(0x81239d81), WTC1(0x8136ea01),
+ WTC1(0x814a2f81), WTC1(0x815d6c01), WTC1(0x8170a181), WTC1(0x8183cf81),
+ WTC1(0x8196f781), WTC1(0x81aa1981), WTC1(0x81bd3401), WTC1(0x81d04681),
+ WTC1(0x81e34f81), WTC1(0x81f64f01), WTC1(0x82094581), WTC1(0x821c3401),
+ WTC1(0x822f1b01), WTC1(0x8241fa01), WTC1(0x8254cf01), WTC1(0x82679901),
+ WTC1(0x827a5801), WTC1(0x828d0b01), WTC1(0x829fb401), WTC1(0x82b25301),
+ WTC1(0x82c4e801), WTC1(0x82d77201), WTC1(0x82e9ef01), WTC1(0x82fc5f01),
+ WTC1(0x830ec081), WTC1(0x83211501), WTC1(0x83335c81), WTC1(0x83459881),
+ WTC1(0x8357c701), WTC1(0x8369e781), WTC1(0x837bf801), WTC1(0x838df801),
+ WTC1(0x839fe801), WTC1(0x83b1c881), WTC1(0x83c39a81), WTC1(0x83d55d01),
+ WTC1(0x83e70f01), WTC1(0x83f8b001), WTC1(0x840a3e81), WTC1(0x841bb981),
+ WTC1(0x842d2281), WTC1(0x843e7a81), WTC1(0x844fc081), WTC1(0x8460f581),
+ WTC1(0x84721701), WTC1(0x84832481), WTC1(0x84941d81), WTC1(0x84a50201),
+ WTC1(0x84b5d301), WTC1(0x84c69101), WTC1(0x84d73c01), WTC1(0x84e7d381),
+ WTC1(0x84f85581), WTC1(0x8508c181), WTC1(0x85191801), WTC1(0x85295881),
+ WTC1(0x85398481), WTC1(0x85499d01), WTC1(0x8559a081), WTC1(0x85698e81),
+ WTC1(0x85796601), WTC1(0x85892681), WTC1(0x8598d081), WTC1(0x85a86581),
+ WTC1(0x85b7e601), WTC1(0x85c75201), WTC1(0x85d6a981), WTC1(0x85e5eb81),
+ WTC1(0x85f51681), WTC1(0x86042c01), WTC1(0x86132c01), WTC1(0x86221801),
+ WTC1(0x8630f181), WTC1(0x863fb701), WTC1(0x864e6901), WTC1(0x865d0581),
+ WTC1(0x866b8d81), WTC1(0x867a0081), WTC1(0x86886001), WTC1(0x8696ad01),
+ WTC1(0x86a4e781), WTC1(0x86b30f01), WTC1(0x86c12401), WTC1(0x86cf2601),
+ WTC1(0x86dd1481), WTC1(0x86eaf081), WTC1(0x86f8ba81), WTC1(0x87067281),
+ WTC1(0x87141b01), WTC1(0x8721b481), WTC1(0x872f4201), WTC1(0x873cc201),
+ WTC1(0x874a2f01), WTC1(0x87578181), WTC1(0x8764b101), WTC1(0x8771c601),
+ WTC1(0x877ede01), WTC1(0x878c1881), WTC1(0x87998f01), WTC1(0x87a70e81),
+ WTC1(0x87b42481), WTC1(0x87c05e81), WTC1(0x87cb5101), WTC1(0x87d4ac81),
+ WTC1(0x87e73d81), WTC1(0x88124281), WTC1(0x88353501), WTC1(0x885f8481),
+ WTC1(0x888d3181), WTC1(0x88be1681), WTC1(0x88f13801), WTC1(0x8925f101),
+ WTC1(0x895bcd01), WTC1(0x89925a81), WTC1(0x89c92f81), WTC1(0x8a001f01),
+ WTC1(0x8a372881), WTC1(0x8a6e4a01), WTC1(0x8aa58681), WTC1(0x8adcee01),
+ WTC1(0x8b149701), WTC1(0x8b4c9701), WTC1(0x8b850281), WTC1(0x8bbde981),
+ WTC1(0x8bf75b01), WTC1(0x8c316681), WTC1(0x8c6c1b01), WTC1(0x8ca78781),
+ WTC1(0x8ce3ba81), WTC1(0x8d20c301), WTC1(0x8d5eaa01), WTC1(0x8d9d7781),
+ WTC1(0x8ddd3201), WTC1(0x8e1de001), WTC1(0x8e5f8881), WTC1(0x8ea23201),
+ WTC1(0x8ee5e301), WTC1(0x8f2aa101), WTC1(0x8f706f01), WTC1(0x8fb74f81),
+ WTC1(0x8fff4601), WTC1(0x90485401), WTC1(0x90927b81), WTC1(0x90ddc001),
+ WTC1(0x912a2201), WTC1(0x9177a301), WTC1(0x91c64301), WTC1(0x92160301),
+ WTC1(0x9266e281), WTC1(0x92b8e101), WTC1(0x930bff81), WTC1(0x93603d01),
+ WTC1(0x93b59901), WTC1(0x940c1281), WTC1(0x9463a881), WTC1(0x94bc5981),
+ WTC1(0x95162381), WTC1(0x95710601), WTC1(0x95ccff01), WTC1(0x962a0c81),
+ WTC1(0x96882e01), WTC1(0x96e76101), WTC1(0x9747a481), WTC1(0x97a8f681),
+ WTC1(0x980b5501), WTC1(0x986ebd81), WTC1(0x98d32d81), WTC1(0x9938a281),
+ WTC1(0x999f1981), WTC1(0x9a069001), WTC1(0x9a6f0381), WTC1(0x9ad87081),
+ WTC1(0x9b42d581), WTC1(0x9bae2f81), WTC1(0x9c1a7c81), WTC1(0x9c87ba81),
+ WTC1(0x9cf5e701), WTC1(0x9d650081), WTC1(0x9dd50481), WTC1(0x9e45f081),
+ WTC1(0x9eb7c101), WTC1(0x9f2a7281), WTC1(0x9f9e0301), WTC1(0xa0127081),
+ WTC1(0xa087b981), WTC1(0xa0fddd81), WTC1(0xa174da81), WTC1(0xa1ecae01),
+ WTC1(0xa2655581), WTC1(0xa2dece81), WTC1(0xa3591801), WTC1(0xa3d43001),
+ WTC1(0xa4501601), WTC1(0xa4ccc901), WTC1(0xa54a4701), WTC1(0xa5c89001),
+ WTC1(0xa647a301), WTC1(0xa6c77e01), WTC1(0xa7482101), WTC1(0xa7c98b01),
+ WTC1(0xa84bbb81), WTC1(0xa8ceb201), WTC1(0xa9526d81), WTC1(0xa9d6ef01),
+ WTC1(0xaa5c3601), WTC1(0xaae24301), WTC1(0xab691681), WTC1(0xabf0b181),
+ WTC1(0xac791401), WTC1(0xad023f01), WTC1(0xad8c3301), WTC1(0xae16f001),
+ WTC1(0xaea27681), WTC1(0xaf2ec901), WTC1(0xafbbe801), WTC1(0xb049d601),
+ WTC1(0xb0d89401), WTC1(0xb1682281), WTC1(0xb1f88181), WTC1(0xb289b181),
+ WTC1(0xb31bb301), WTC1(0xb3ae8601), WTC1(0xb4422b81), WTC1(0xb4d6a381),
+ WTC1(0x4a5a327f), WTC1(0x49c4adff), WTC1(0x492e637f), WTC1(0x48974f7f),
+ WTC1(0x47ff6d7f), WTC1(0x4766baff), WTC1(0x46cd35ff), WTC1(0x4632dd7f),
+ WTC1(0x4597b0ff), WTC1(0x44fbb1ff), WTC1(0x445eeaff), WTC1(0x43c165ff),
+ WTC1(0x4323227f), WTC1(0x4284277f), WTC1(0x41e48aff), WTC1(0x4144557f),
+ WTC1(0x40a3867f), WTC1(0x4001f5ff), WTC1(0x3f5f5d80), WTC1(0x3ebbad00),
+ WTC1(0x3e16ee40), WTC1(0x3d713d00), WTC1(0x3ccab700), WTC1(0x3c236500),
+ WTC1(0x3b7b5800), WTC1(0x3ad2ecc0), WTC1(0x3a2a6540), WTC1(0x3981b7c0),
+ WTC1(0x38d8ba00), WTC1(0x382f01c0), WTC1(0x37846240), WTC1(0x36d8eb00),
+ WTC1(0x362c9ec0), WTC1(0x357f7a00), WTC1(0x34d18340), WTC1(0x3422c900),
+ WTC1(0x33736c40), WTC1(0x32c39040), WTC1(0x32134280), WTC1(0x31629280),
+ WTC1(0x30b1a000), WTC1(0x30008380), WTC1(0x2f4f4240), WTC1(0x2e9df180),
+ WTC1(0x2decc780), WTC1(0x2d3bd640), WTC1(0x2c8b0cc0), WTC1(0x2bda3080),
+ WTC1(0x2b28ec80), WTC1(0x2a773500), WTC1(0x29c51b40), WTC1(0x291293c0),
+ WTC1(0x285f9280), WTC1(0x27ac35c0), WTC1(0x26f8ab40), WTC1(0x26454c00),
+ WTC1(0x25925600), WTC1(0x24dfd580), WTC1(0x242ddd40), WTC1(0x237c87c0),
+ WTC1(0x22cbe240), WTC1(0x221bef40), WTC1(0x216cb040), WTC1(0x20be2800),
+ WTC1(0x20105c80), WTC1(0x1f6352a0), WTC1(0x1eb71240), WTC1(0x1e0ba140),
+ WTC1(0x1d60fe40), WTC1(0x1cb723e0), WTC1(0x1c0e0300), WTC1(0x1b6596c0),
+ WTC1(0x1abde8a0), WTC1(0x1a16fbe0), WTC1(0x1970c680), WTC1(0x18cb4840),
+ WTC1(0x18268e20), WTC1(0x1782a0c0), WTC1(0x16df8960), WTC1(0x163d6300),
+ WTC1(0x159c52c0), WTC1(0x14fc87e0), WTC1(0x145e2c80), WTC1(0x13c15b60),
+ WTC1(0x13263240), WTC1(0x128cd9a0), WTC1(0x11f562a0), WTC1(0x115fc1c0),
+ WTC1(0x10cbf160), WTC1(0x1039f200), WTC1(0x0fa9a080), WTC1(0x0f1abd90),
+ WTC1(0x0e8d01d0), WTC1(0x0e003330), WTC1(0x0d743590), WTC1(0x0ce8ef40),
+ WTC1(0x0c5e1900), WTC1(0x0bd35d70), WTC1(0x0b488eb0), WTC1(0x0abd8410),
+ WTC1(0x0a320a00), WTC1(0x09a60e70), WTC1(0x0919ab00), WTC1(0x088d0de0),
+ WTC1(0x080065e0), WTC1(0x07739710), WTC1(0x06e65808), WTC1(0x06588348),
+ WTC1(0x05ca0ae0), WTC1(0x053aaaf8), WTC1(0x04a9faf0), WTC1(0x0417f698),
+ WTC1(0x03859ff4), WTC1(0x02f49be4), WTC1(0x0266b668), WTC1(0x01de554e),
+ WTC1(0x015f50ca), WTC1(0x00eb7e5d), WTC1(0x00904f24), WTC1(0x00212889),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000),
+ /* part 2 */
+ WTC2(0xfffece02), WTC2(0xffe4c3df), WTC2(0xffcaaa55), WTC2(0xffb087d1),
+ WTC2(0xff9662bf), WTC2(0xff7c418b), WTC2(0xff622aa0), WTC2(0xff48246c),
+ WTC2(0xff2e355a), WTC2(0xff1463db), WTC2(0xfefab608), WTC2(0xfee12f0a),
+ WTC2(0xfec7cfd2), WTC2(0xfeae995a), WTC2(0xfe958cc4), WTC2(0xfe7cabce),
+ WTC2(0xfe63f882), WTC2(0xfe4b74e0), WTC2(0xfe3322f6), WTC2(0xfe1b04dc),
+ WTC2(0xfe031ccc), WTC2(0xfdeb6cf0), WTC2(0xfdd3ff7c), WTC2(0xfdbce834),
+ WTC2(0xfda63bb8), WTC2(0xfd900c68), WTC2(0xfd7a590c), WTC2(0xfd6511b4),
+ WTC2(0xfd5026c0), WTC2(0xfd3b8954), WTC2(0xfd272df0), WTC2(0xfd130adc),
+ WTC2(0xfcff15ac), WTC2(0xfceb4a68), WTC2(0xfcd7b110), WTC2(0xfcc454d0),
+ WTC2(0xfcb14064), WTC2(0xfc9e896c), WTC2(0xfc8c5264), WTC2(0xfc7abef0),
+ WTC2(0xfc69f078), WTC2(0xfc59f5e8), WTC2(0xfc4acfec), WTC2(0xfc3c8060),
+ WTC2(0xfc2f0264), WTC2(0xfc223b7c), WTC2(0xfc160714), WTC2(0xfc0a4150),
+ WTC2(0xfbfec920), WTC2(0xfbf38320), WTC2(0xfbe855d0), WTC2(0xfbdd2740),
+ WTC2(0xfbd1fc68), WTC2(0xfbc6fea0), WTC2(0xfbbc5a48), WTC2(0xfbb23b48),
+ WTC2(0xfba8ca78), WTC2(0xfba02e50), WTC2(0xfb988de0), WTC2(0xfb920b40),
+ WTC2(0xfb8cb870), WTC2(0xfb889f68), WTC2(0xfb85cbe8), WTC2(0xfb843dd0),
+ WTC2(0xfb83df78), WTC2(0xfb8495d0), WTC2(0xfb864660), WTC2(0xfb88d4a8),
+ WTC2(0xfb8c21e8), WTC2(0xfb900f28), WTC2(0xfb947dc0), WTC2(0xfb9950c0),
+ WTC2(0xfb9e6d08), WTC2(0xfba3b658), WTC2(0xfba91908), WTC2(0xfbae9e08),
+ WTC2(0xfbb45bd0), WTC2(0xfbba66f8), WTC2(0xfbc0dcf0), WTC2(0xfbc7ead8),
+ WTC2(0xfbcfc200), WTC2(0xfbd89330), WTC2(0xfbe294d0), WTC2(0xfbee03d0),
+ WTC2(0xfbfb1de8), WTC2(0xfc0a1da4), WTC2(0xfc1b22e0), WTC2(0xfc2e38f0),
+ WTC2(0xfc436d48), WTC2(0xfc5abf7c), WTC2(0xfc74024c), WTC2(0xfc8ef2e8),
+ WTC2(0xfcab51ac), WTC2(0xfcc8d024), WTC2(0xfce704f0), WTC2(0xfd0580cc),
+ WTC2(0xfd23d4d0), WTC2(0xfd41ce40), WTC2(0xfd5f81b0), WTC2(0xfd7d08f0),
+ WTC2(0xfd9a8560), WTC2(0xfdb85938), WTC2(0xfdd71798), WTC2(0xfdf753b8),
+ WTC2(0xfe1993ee), WTC2(0xfe3e30f8), WTC2(0xfe656cba), WTC2(0xfe8f8fdc),
+ WTC2(0xfebca8a4), WTC2(0xfeec590e), WTC2(0xff1e285c), WTC2(0xff51a0b7),
+ WTC2(0xff866330), WTC2(0xffbc2cbb), WTC2(0xfff2bbff), WTC2(0x0029d79d),
+ WTC2(0x00618a22), WTC2(0x009a1185), WTC2(0x00d3aa8c), WTC2(0x010e8ff6),
+ WTC2(0x014af29e), WTC2(0x0188fe56), WTC2(0x01c8e108), WTC2(0x020ab3c4),
+ WTC2(0x024e68a8), WTC2(0x0293e824), WTC2(0x02db1bc8), WTC2(0x0323f1a4),
+ WTC2(0x036e5d6c), WTC2(0x03ba5320), WTC2(0x0407c938), WTC2(0x0456cad0),
+ WTC2(0x04a77288), WTC2(0x04f9db88), WTC2(0x054e1888), WTC2(0x05a41ef0),
+ WTC2(0x05fbd6e0), WTC2(0x065528c0), WTC2(0x06b00838), WTC2(0x070c7ee0),
+ WTC2(0x076a9bb0), WTC2(0x07ca6d10), WTC2(0x082c08e0), WTC2(0x088f8da0),
+ WTC2(0x08f51ac0), WTC2(0x095ccc20), WTC2(0x09c69f70), WTC2(0x0a327b40),
+ WTC2(0x0aa046d0), WTC2(0x0b0febb0), WTC2(0x0b815dd0), WTC2(0x0bf49600),
+ WTC2(0x0c698c50), WTC2(0x0ce03ba0), WTC2(0x0d58a380), WTC2(0x0dd2c510),
+ WTC2(0x0e4ea110), WTC2(0x0ecc3dd0), WTC2(0x0f4ba800), WTC2(0x0fcced10),
+ WTC2(0x10501960), WTC2(0x10d532a0), WTC2(0x115c39c0), WTC2(0x11e52fa0),
+ WTC2(0x12701560), WTC2(0x12fcef20), WTC2(0x138bc200), WTC2(0x141c9300),
+ WTC2(0x14af64a0), WTC2(0x154434e0), WTC2(0x15db0020), WTC2(0x1673c360),
+ WTC2(0x170e7e80), WTC2(0x17ab35e0), WTC2(0x1849ee40), WTC2(0x18eaaba0),
+ WTC2(0x198d6f00), WTC2(0x1a3236a0), WTC2(0x1ad90080), WTC2(0x1b81cc60),
+ WTC2(0x1c2c9da0), WTC2(0x1cd97980), WTC2(0x1d8865c0), WTC2(0x1e396540),
+ WTC2(0x1eec7700), WTC2(0x1fa198c0), WTC2(0x2058c840), WTC2(0x21120640),
+ WTC2(0x21cd5700), WTC2(0x228abec0), WTC2(0x234a4180), WTC2(0x240bdf80),
+ WTC2(0x24cf95c0), WTC2(0x259561c0), WTC2(0x265d4200), WTC2(0x27273840),
+ WTC2(0x27f348c0), WTC2(0x28c17700), WTC2(0x2991c500), WTC2(0x2a643080),
+ WTC2(0x2b38b680), WTC2(0x2c0f53c0), WTC2(0x2ce80840), WTC2(0x2dc2d680),
+ WTC2(0x2e9fc100), WTC2(0x2f7ecac0), WTC2(0x305ff280), WTC2(0x314334c0),
+ WTC2(0x32288e00), WTC2(0x330ffb80), WTC2(0x33f97d80), WTC2(0x34e515c0),
+ WTC2(0x35d2c5c0), WTC2(0x36c28d00), WTC2(0x37b467c0), WTC2(0x38a85080),
+ WTC2(0x399e4240), WTC2(0x3a963a00), WTC2(0x3b903600), WTC2(0x3c8c3480),
+ WTC2(0x3d8a3380), WTC2(0x3e8a2dc0), WTC2(0x3f8c1b40), WTC2(0x408ff2ff),
+ WTC2(0x4195ae7f), WTC2(0x429d477f), WTC2(0x43a6b87f), WTC2(0x44b1fdff),
+ WTC2(0x45bf11ff), WTC2(0x46cdee7f), WTC2(0x47de8cff), WTC2(0x48f0e77f),
+ WTC2(0x4a050eff), WTC2(0x4b1b2dff), WTC2(0x4c3372ff), WTC2(0x4d4e0bff),
+ WTC2(0x4e6b257f), WTC2(0x4f8aedff), WTC2(0x50ad92ff), WTC2(0x51d341ff),
+ WTC2(0x002006a9), WTC2(0x000bfb36), WTC2(0xfffe45ac), WTC2(0xfff6d064),
+ WTC2(0xfff585bc), WTC2(0xfffa500d), WTC2(0x000519b4), WTC2(0x0015cd0c),
+ WTC2(0x002c5470), WTC2(0x00489a3b), WTC2(0x006a88c8), WTC2(0x00920a74),
+ WTC2(0x00bf0999), WTC2(0x00f17092), WTC2(0x012929bc), WTC2(0x01661f70),
+ WTC2(0x01a83c0c), WTC2(0x01ef69e8), WTC2(0x023b9364), WTC2(0x028ca2d4),
+ WTC2(0x02e2829c), WTC2(0x033d1d10), WTC2(0x039c5c90), WTC2(0x04002b78),
+ WTC2(0x04687418), WTC2(0x04d520e0), WTC2(0x05461c18), WTC2(0x05bb5020),
+ WTC2(0x0634a758), WTC2(0x06b20c20), WTC2(0x073368c8), WTC2(0x07b8a7b0),
+ WTC2(0x0841b340), WTC2(0x08ce75b0), WTC2(0x095ed980), WTC2(0x09f2c900),
+ WTC2(0x0a8a2e80), WTC2(0x0b24f470), WTC2(0x0bc30510), WTC2(0x0c644ad0),
+ WTC2(0x0d08b010), WTC2(0x0db01f10), WTC2(0x0e5a8250), WTC2(0x0f07c400),
+ WTC2(0x0fb7cea0), WTC2(0x106a8c80), WTC2(0x111fe800), WTC2(0x11d7cb60),
+ WTC2(0x12922120), WTC2(0x134ed3a0), WTC2(0x140dcd00), WTC2(0x14cef7e0),
+ WTC2(0x15923e60), WTC2(0x16578b00), WTC2(0x171ec820), WTC2(0x17e7e020),
+ WTC2(0x18b2bd20), WTC2(0x197f49c0), WTC2(0x1a4d7040), WTC2(0x1b1d1b00),
+ WTC2(0x1bee3460), WTC2(0x1cc0a6a0), WTC2(0x1d945c40), WTC2(0x1e693f80),
+ WTC2(0x1f3f3ac0), WTC2(0x20163880), WTC2(0x20ee22c0), WTC2(0x21c6e440),
+ WTC2(0x22a06740), WTC2(0x237a9600), WTC2(0x24555ac0), WTC2(0x2530a040),
+ WTC2(0x260c5080), WTC2(0x26e85600), WTC2(0x27c49b00), WTC2(0x28a10a00),
+ WTC2(0x297d8d80), WTC2(0x2a5a0f80), WTC2(0x2b367a80), WTC2(0x2c12b8c0),
+ WTC2(0x2ceeb500), WTC2(0x2dca5940), WTC2(0x2ea58fc0), WTC2(0x2f804340),
+ WTC2(0x305a5dc0), WTC2(0x3133ca00), WTC2(0x320c7200), WTC2(0x32e44000),
+ WTC2(0x33bb1ec0), WTC2(0x3490f880), WTC2(0x3565b7c0), WTC2(0x36394640),
+ WTC2(0x370b8f00), WTC2(0x37dc7c00), WTC2(0x38abf7c0), WTC2(0x3979ecc0),
+ WTC2(0x3a464500), WTC2(0x3b10eb00), WTC2(0x3bd9c940), WTC2(0x3ca0c9c0),
+ WTC2(0x3d65d740), WTC2(0x3e28dc00), WTC2(0x3ee9c240), WTC2(0x3fa87480),
+ WTC2(0x4064dcff), WTC2(0x411ee67f), WTC2(0x41d67a7f), WTC2(0x428b847f),
+ WTC2(0x433ded7f), WTC2(0x43eda0ff), WTC2(0x449a887f), WTC2(0x45448f7f),
+ WTC2(0x45eb9eff), WTC2(0x468fa1ff), WTC2(0x473082ff), WTC2(0x47ce2c7f),
+ WTC2(0x4868887f), WTC2(0x48ff80ff), WTC2(0x499300ff), WTC2(0x4a22f2ff),
+ WTC2(0x4aaf407f), WTC2(0x4b37d47f), WTC2(0x4bbc997f), WTC2(0x4c3d78ff),
+ WTC2(0x4cba5e7f), WTC2(0x4d33337f), WTC2(0x4da7e27f), WTC2(0x4e18567f),
+ WTC2(0x4e8478ff), WTC2(0x4eec347f), WTC2(0x4f4f737f), WTC2(0x4fae20ff),
+ WTC2(0x500825ff), WTC2(0x505d6dff), WTC2(0x50ade37f), WTC2(0x50f96f7f),
+ WTC2(0x513ffdff), WTC2(0x518177ff), WTC2(0x51bdc87f), WTC2(0x51f4d9ff),
+ WTC2(0x5226967f), WTC2(0x5252e87f), WTC2(0x5279b9ff), WTC2(0x529af5ff),
+ WTC2(0x52b6867f), WTC2(0x52cc55ff), WTC2(0x52dc4eff), WTC2(0x52e65aff),
+ WTC2(0x52ea657f), WTC2(0x52e857ff), WTC2(0x52e01d7f), WTC2(0x52d19fff),
+ WTC2(0x52bcc9ff), WTC2(0x52a1857f), WTC2(0x527fbd7f), WTC2(0x52575b7f),
+ WTC2(0x52284a7f), WTC2(0x51f274ff), WTC2(0x51b5c47f), WTC2(0x5172247f),
+ WTC2(0x51277dff), WTC2(0x50d5bc7f), WTC2(0x507cc9ff), WTC2(0x501c90ff),
+ WTC2(0x4fb4fb7f), WTC2(0x4f45f3ff), WTC2(0x4ecf64ff), WTC2(0x4e5138ff),
+ WTC2(0x4dcb597f), WTC2(0x4d3db1ff), WTC2(0x4ca82bff), WTC2(0x4c0ab27f),
+ WTC2(0x4b652f7f), WTC2(0x4ab78d7f), WTC2(0x4a01b67f), WTC2(0x4943957f),
+ WTC2(0x487d12ff), WTC2(0x47ae1f7f), WTC2(0x46d68f7f), WTC2(0x45f7187f),
+ WTC2(0x4513597f), WTC2(0x4430467f), WTC2(0x4352d2ff), WTC2(0x427e6bff),
+ WTC2(0x41b390ff), WTC2(0x40f2077f), WTC2(0x4039a87f), WTC2(0x3f8a3100),
+ WTC2(0x3ee33e00), WTC2(0x3e446ac0), WTC2(0x3dad5180), WTC2(0x3d1d7fc0),
+ WTC2(0x3c947b00), WTC2(0x3c11c7c0), WTC2(0x3b94ebc0), WTC2(0x3b1d6dc0),
+ WTC2(0x3aaad480), WTC2(0x3a3ca740), WTC2(0x39d26c40), WTC2(0x396ba8c0),
+ WTC2(0x3907e080), WTC2(0x38a69800), WTC2(0x38473d80), WTC2(0x37e923c0),
+ WTC2(0x378b9b80), WTC2(0x372e0380), WTC2(0x36d03a80), WTC2(0x36727f00),
+ WTC2(0x36150e40), WTC2(0x35b81540), WTC2(0x355b8000), WTC2(0x34ff1dc0),
+ WTC2(0x34a2bfc0), WTC2(0x34463e80), WTC2(0x33e982c0), WTC2(0x338c7880),
+ WTC2(0x332f0bc0), WTC2(0x32d11800), WTC2(0x327265c0), WTC2(0x3212bbc0),
+ WTC2(0x31b1e740), WTC2(0x314fef00), WTC2(0x30ed0540), WTC2(0x30895c80),
+ WTC2(0x30251880), WTC2(0x2fc02880), WTC2(0x2f5a6480), WTC2(0x2ef3a480),
+ WTC2(0x2e8bd640), WTC2(0x2e231100), WTC2(0x2db97680), WTC2(0x2d4f2700),
+ WTC2(0x2ce431c0), WTC2(0x2c789080), WTC2(0x2c0c3bc0), WTC2(0x2b9f2bc0),
+ WTC2(0x2b315940), WTC2(0x2ac2bc00), WTC2(0x2a534cc0), WTC2(0x29e303c0)};
+
+const FIXP_WTB ELDAnalysis256[768] = {
+ WTC(0xfababde8), WTC(0xfa8e1e6a), WTC(0xfa6012a9), WTC(0xfa30c8dd),
+ WTC(0xfa006f4b), WTC(0xf9cf32c4), WTC(0xf99d1cc8), WTC(0xf96a148d),
+ WTC(0xf936184d), WTC(0xf9013d5b), WTC(0xf8cb7b67), WTC(0xf894ace0),
+ WTC(0xf85cd28e), WTC(0xf82413f8), WTC(0xf7ea90af), WTC(0xf7b05ee6),
+ WTC(0xf7759b0b), WTC(0xf73a671f), WTC(0xf6febea3), WTC(0xf6c27a0e),
+ WTC(0xf685ca33), WTC(0xf6493907), WTC(0xf60d437b), WTC(0xf5d2551f),
+ WTC(0xf598d273), WTC(0xf561199e), WTC(0xf52b8c6f), WTC(0xf4f8907d),
+ WTC(0xf4c87fdf), WTC(0xf49ba806), WTC(0xf4724286), WTC(0xf44c6127),
+ WTC(0xf4282435), WTC(0xf401ceae), WTC(0xf3d775a1), WTC(0xf3a91477),
+ WTC(0xf376c33f), WTC(0xf340a328), WTC(0xf306d4d6), WTC(0xf2c9775c),
+ WTC(0xf288a3ed), WTC(0xf2446e2a), WTC(0xf1fcfa45), WTC(0xf1b27b2d),
+ WTC(0xf164f3f4), WTC(0xf114365c), WTC(0xf0c00532), WTC(0xf06817a9),
+ WTC(0xf00c4ea4), WTC(0xefacbc7f), WTC(0xef4a205f), WTC(0xeee5dc33),
+ WTC(0xee808a0d), WTC(0xee19eeb2), WTC(0xedb12f6e), WTC(0xed44e8eb),
+ WTC(0xecd50a13), WTC(0xec62d8dd), WTC(0xebef68b2), WTC(0xeb7b805c),
+ WTC(0xeb069af4), WTC(0xea8eef1c), WTC(0xea131c86), WTC(0xe99234c6),
+ WTC(0xe90cd9c2), WTC(0xe884f65b), WTC(0xe7fcbd6d), WTC(0xe7767300),
+ WTC(0xe6f289d0), WTC(0xe66f958a), WTC(0xe5eae99f), WTC(0xe560c403),
+ WTC(0xe4cfaaa1), WTC(0xe43887dc), WTC(0xe39dedc4), WTC(0xe303f190),
+ WTC(0xe26d7f5d), WTC(0xe1dc34ff), WTC(0xe14f9ced), WTC(0xe0c53cd0),
+ WTC(0xe03ab085), WTC(0xdfadc948), WTC(0xdf1d640c), WTC(0xde896bb6),
+ WTC(0xddf256ad), WTC(0xdd591e3d), WTC(0xdcbf0aec), WTC(0xdc25ab0a),
+ WTC(0xdb8e334c), WTC(0xdaf97794), WTC(0xda67bed9), WTC(0xd9d8c524),
+ WTC(0xd94bfa62), WTC(0xd8c089b5), WTC(0xd835c151), WTC(0xd7ab1704),
+ WTC(0xd7200906), WTC(0xd69420dc), WTC(0xd6073c0d), WTC(0xd5799615),
+ WTC(0xd4ec7c87), WTC(0xd46241c9), WTC(0xd3dc5bde), WTC(0xd35b4a79),
+ WTC(0xd2de1032), WTC(0xd26246f5), WTC(0xd1e68ed2), WTC(0xd16aa0a4),
+ WTC(0xd0eea5d2), WTC(0xd073302b), WTC(0xcff93749), WTC(0xcf820f45),
+ WTC(0xcf0ebb30), WTC(0xce9fd702), WTC(0xce34596c), WTC(0xcdc9a803),
+ WTC(0xcd5ec5d6), WTC(0xccf468ec), WTC(0xcc8bb41e), WTC(0xcc2619cc),
+ WTC(0xcbc3e090), WTC(0xcb6422f5), WTC(0xcb064d2f), WTC(0xcaaa2a6d),
+ WTC(0xca4fbdc9), WTC(0xc9f73c43), WTC(0xc9a0dc9b), WTC(0xc94cdd02),
+ WTC(0xc8f578a4), WTC(0xc8a24d15), WTC(0xc84dc71f), WTC(0xc7f83516),
+ WTC(0xc7a1e4b9), WTC(0xc74b22b1), WTC(0xc6f41284), WTC(0xc69cabc1),
+ WTC(0xc644986d), WTC(0xc5eb4167), WTC(0xc5910312), WTC(0xc5372c7f),
+ WTC(0xc4deba2e), WTC(0xc4883eca), WTC(0xc43310f0), WTC(0xc3dd5c5a),
+ WTC(0xc3868802), WTC(0xc32f431d), WTC(0xc2d86c9e), WTC(0xc28300a6),
+ WTC(0xc22fae33), WTC(0xc1ded3f7), WTC(0xc1908d7d), WTC(0xc144b0ed),
+ WTC(0xc0fa7cee), WTC(0xc0b0a3b5), WTC(0xc066b8d3), WTC(0xc01d3b32),
+ WTC(0xbfd5161c), WTC(0xbf8f92af), WTC(0xbf4d5cea), WTC(0xbf0e7d5e),
+ WTC(0xbed2ce3a), WTC(0xbe9a0062), WTC(0xbe63cec2), WTC(0xbe2ffd2f),
+ WTC(0xbdfe4565), WTC(0xbdce5568), WTC(0xbda003df), WTC(0xbd735018),
+ WTC(0xbd485b2c), WTC(0xbd1f69bd), WTC(0xbcf8db7c), WTC(0xbcd52b0a),
+ WTC(0xbcb4ae4a), WTC(0xbc979382), WTC(0xbc7dcbab), WTC(0xbc6709dc),
+ WTC(0xbc52c1b1), WTC(0xbc402f2b), WTC(0xbc2ec37b), WTC(0xbc1e2cb3),
+ WTC(0xbc0e5d5f), WTC(0xbbff8f23), WTC(0xbbf238d2), WTC(0xbbe707d4),
+ WTC(0xbbde3c63), WTC(0xbbd7a658), WTC(0xbbd2c7f0), WTC(0xbbcee18b),
+ WTC(0xbbcbdebb), WTC(0xbbca5ab1), WTC(0xbbcb5622), WTC(0xbbd032e4),
+ WTC(0xbbd91d4d), WTC(0xbbe53757), WTC(0xbbf32f54), WTC(0xbc016781),
+ WTC(0xbc0f433a), WTC(0xbc1d2aa4), WTC(0xbc2b4912), WTC(0xbc3985df),
+ WTC(0xbc47d6b9), WTC(0xbc564099), WTC(0xbc64c78a), WTC(0xbc736d96),
+ WTC(0xbc823210), WTC(0xbc911484), WTC(0xbca015b8), WTC(0xbcaf37eb),
+ WTC(0xbcbe7bc3), WTC(0xbccdde4d), WTC(0xbcdd6037), WTC(0xbced049a),
+ WTC(0xbcfccc81), WTC(0xbd0cb482), WTC(0xbd1cbcaa), WTC(0xbd2ce7ea),
+ WTC(0xbd3d363b), WTC(0xbd4da445), WTC(0xbd5e312d), WTC(0xbd6edfd1),
+ WTC(0xbd7fae14), WTC(0xbd90991b), WTC(0xbda19fcf), WTC(0xbdb2c464),
+ WTC(0xbdc4053b), WTC(0xbdd55f4b), WTC(0xbde6d0a0), WTC(0xbdf85c51),
+ WTC(0xbe09ffa3), WTC(0xbe1bb724), WTC(0xbe2d8160), WTC(0xbe3f5f98),
+ WTC(0xbe515144), WTC(0xbe6351a9), WTC(0xbe755ebd), WTC(0xbe877b8e),
+ WTC(0xbe99a63d), WTC(0xbeabda45), WTC(0xbebe16b0), WTC(0xbed05d1c),
+ WTC(0xbee2ada9), WTC(0xbef502e2), WTC(0xbf075c40), WTC(0xbf19bc0b),
+ WTC(0xbf2c217f), WTC(0xbf3e887a), WTC(0xbf50f09d), WTC(0xbf635c77),
+ WTC(0xbf75cac0), WTC(0xbf883905), WTC(0xbf9aa62b), WTC(0xbfad14f1),
+ WTC(0xbfbf85c7), WTC(0xbfd1f592), WTC(0xbfe461fc), WTC(0xbff6c86a),
+ WTC(0x80126c8d), WTC(0x80372448), WTC(0x805bd2fd), WTC(0x80807315),
+ WTC(0x80a4fffa), WTC(0x80c9748d), WTC(0x80edd08b), WTC(0x81121a23),
+ WTC(0x81364fde), WTC(0x815a6b16), WTC(0x817e6b36), WTC(0x81a25433),
+ WTC(0x81c625c8), WTC(0x81e9d801), WTC(0x820d6a5c), WTC(0x8230e060),
+ WTC(0x825438c0), WTC(0x82776ac7), WTC(0x829a7555), WTC(0x82bd5ca3),
+ WTC(0x82e01e80), WTC(0x8302b200), WTC(0x83251590), WTC(0x83474d79),
+ WTC(0x8369566f), WTC(0x838b2957), WTC(0x83acc2d9), WTC(0x83ce27c1),
+ WTC(0x83ef54b9), WTC(0x841042d1), WTC(0x8430ef15), WTC(0x84515e84),
+ WTC(0x84718e32), WTC(0x84917804), WTC(0x84b11a25), WTC(0x84d0788d),
+ WTC(0x84ef9322), WTC(0x850e61ec), WTC(0x852ce400), WTC(0x854b1e0a),
+ WTC(0x85690f2c), WTC(0x8586b207), WTC(0x85a4057b), WTC(0x85c1107d),
+ WTC(0x85ddd335), WTC(0x85fa485e), WTC(0x86167172), WTC(0x8632549d),
+ WTC(0x864df388), WTC(0x8669497e), WTC(0x86845757), WTC(0x869f2218),
+ WTC(0x86b9ab5a), WTC(0x86d3f1bf), WTC(0x86edf68f), WTC(0x8707baf1),
+ WTC(0x872147e0), WTC(0x873aa6fc), WTC(0x8753c571), WTC(0x876c76e6),
+ WTC(0x87850ab7), WTC(0x879e373b), WTC(0x87b6ea37), WTC(0x87cc4188),
+ WTC(0x880d4300), WTC(0x8855e9ff), WTC(0x88acfca0), WTC(0x890d0f94),
+ WTC(0x8971e7d5), WTC(0x89d8a0c1), WTC(0x8a3fc425), WTC(0x8aa74105),
+ WTC(0x8b0f5b93), WTC(0x8b78a107), WTC(0x8be38bb3), WTC(0x8c508092),
+ WTC(0x8cbfe384), WTC(0x8d3214f1), WTC(0x8da75d21), WTC(0x8e1fe96c),
+ WTC(0x8e9be76a), WTC(0x8f1b806c), WTC(0x8f9ed314), WTC(0x9025f26a),
+ WTC(0x90b0ecea), WTC(0x913fd0eb), WTC(0x91d2a684), WTC(0x92696dea),
+ WTC(0x93042868), WTC(0x93a2d456), WTC(0x94456d20), WTC(0x94ebe9e5),
+ WTC(0x95964178), WTC(0x96446a05), WTC(0x96f65958), WTC(0x97ac059a),
+ WTC(0x98656089), WTC(0x99225a80), WTC(0x99e2e2e8), WTC(0x9aa6e666),
+ WTC(0x9b6e54b8), WTC(0x9c391d99), WTC(0x9d07338a), WTC(0x9dd8888d),
+ WTC(0x9ead0b5c), WTC(0x9f84a871), WTC(0xa05f4fb3), WTC(0xa13cf913),
+ WTC(0xa21d9891), WTC(0xa3011e27), WTC(0xa3e77eb4), WTC(0xa4d0b190),
+ WTC(0xa5bcb0d7), WTC(0xa6ab750c), WTC(0xa79cf884), WTC(0xa89135cb),
+ WTC(0xa9882a44), WTC(0xaa81d578), WTC(0xab7e39a6), WTC(0xac7d5a36),
+ WTC(0xad7f3ba5), WTC(0xae83dfed), WTC(0xaf8b4e16), WTC(0xb095911c),
+ WTC(0xb1a2afd1), WTC(0xb2b2ac9f), WTC(0xb3c58807), WTC(0xb4db4d5e),
+ WTC(0x4a268ead), WTC(0x490b5ba7), WTC(0x47ed8d30), WTC(0x46cd10c5),
+ WTC(0x45a9dcc1), WTC(0x4483f267), WTC(0x435b5aeb), WTC(0x42301d12),
+ WTC(0x41023a15), WTC(0x3fd19bf1), WTC(0x3e9e31e1), WTC(0x3d682986),
+ WTC(0x3c2fc001), WTC(0x3af52d8f), WTC(0x39b88b7d), WTC(0x38798642),
+ WTC(0x3737e6d3), WTC(0x35f3e98a), WTC(0x34add45c), WTC(0x33660083),
+ WTC(0x321ccf3a), WTC(0x30d2963e), WTC(0x2f87a28f), WTC(0x2e3c22cd),
+ WTC(0x2cf010e5), WTC(0x2ba2ffe5), WTC(0x2a54ba93), WTC(0x290596f5),
+ WTC(0x27b62806), WTC(0x266762b8), WTC(0x251a11b1), WTC(0x23ce94f9),
+ WTC(0x22852ddb), WTC(0x213df340), WTC(0x1ff90185), WTC(0x1eb67d94),
+ WTC(0x1d767485), WTC(0x1c38d477), WTC(0x1afda747), WTC(0x19c5248b),
+ WTC(0x188f8259), WTC(0x175d0d40), WTC(0x162e5320), WTC(0x150436cd),
+ WTC(0x13df8d3f), WTC(0x12c102f1), WTC(0x11a8dd65), WTC(0x1096d490),
+ WTC(0x0f8a1755), WTC(0x0e811dcd), WTC(0x0d7acb9a), WTC(0x0c767d00),
+ WTC(0x0b7334d9), WTC(0x0a6fef31), WTC(0x096c5a87), WTC(0x08691adb),
+ WTC(0x0765e395), WTC(0x06610309), WTC(0x0558a0d2), WTC(0x044a946c),
+ WTC(0x033acb52), WTC(0x0234706f), WTC(0x014939dc), WTC(0x00928577),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xffe73593), WTC(0xffb63fcf), WTC(0xff853c1f), WTC(0xff5454d7),
+ WTC(0xff23b44b), WTC(0xfef38417), WTC(0xfec3dc9a), WTC(0xfe94c511),
+ WTC(0xfe664753), WTC(0xfe387086), WTC(0xfe0b4e63), WTC(0xfddef15c),
+ WTC(0xfdb3a3f6), WTC(0xfd89e611), WTC(0xfd61c750), WTC(0xfd3ae585),
+ WTC(0xfd14ec09), WTC(0xfcef9b06), WTC(0xfccaf509), WTC(0xfca74180),
+ WTC(0xfc8518a3), WTC(0xfc655c7a), WTC(0xfc488545), WTC(0xfc2e9998),
+ WTC(0xfc1726bb), WTC(0xfc01463f), WTC(0xfbec2c64), WTC(0xfbd735ce),
+ WTC(0xfbc29e8e), WTC(0xfbaf8042), WTC(0xfb9eeba0), WTC(0xfb91dc05),
+ WTC(0xfb88f420), WTC(0xfb8479eb), WTC(0xfb84398b), WTC(0xfb87884b),
+ WTC(0xfb8da8bf), WTC(0xfb95d020), WTC(0xfb9f3e49), WTC(0xfba9448a),
+ WTC(0xfbb3cf10), WTC(0xfbbf67e7), WTC(0xfbccf65d), WTC(0xfbddba58),
+ WTC(0xfbf31f46), WTC(0xfc0eb236), WTC(0xfc3164f0), WTC(0xfc5b8269),
+ WTC(0xfc8c5bcd), WTC(0xfcc248ee), WTC(0xfcfb056c), WTC(0xfd33cc26),
+ WTC(0xfd6b84ee), WTC(0xfda2d9e7), WTC(0xfddc03fb), WTC(0xfe1aaf57),
+ WTC(0xfe61a0af), WTC(0xfeb28df7), WTC(0xff0cd343), WTC(0xff6d8388),
+ WTC(0xffd24331), WTC(0x00396fe3), WTC(0x00a2fb3e), WTC(0x01107050),
+ WTC(0x01831900), WTC(0x01fc2377), WTC(0x027bd1fc), WTC(0x03019a2d),
+ WTC(0x038d0a88), WTC(0x041dd88f), WTC(0x04b43495), WTC(0x0550c1ef),
+ WTC(0x05f38bd6), WTC(0x069c0523), WTC(0x074a114e), WTC(0x07fe0ceb),
+ WTC(0x08b88e33), WTC(0x097a5965), WTC(0x0a438318), WTC(0x0b137046),
+ WTC(0x0be9b5ab), WTC(0x0cc61fa9), WTC(0x0da897b2), WTC(0x0e9123b3),
+ WTC(0x0f7ff200), WTC(0x10755696), WTC(0x11717f94), WTC(0x127474a0),
+ WTC(0x137e489d), WTC(0x148f1b02), WTC(0x15a6f15e), WTC(0x16c5b7c9),
+ WTC(0x17eb72b1), WTC(0x19183e51), WTC(0x1a4c2444), WTC(0x1b871b1c),
+ WTC(0x1cc92e92), WTC(0x1e127ffc), WTC(0x1f6319b9), WTC(0x20baef78),
+ WTC(0x221a0861), WTC(0x23807f94), WTC(0x24ee5a89), WTC(0x2663898d),
+ WTC(0x27e0101e), WTC(0x2964058d), WTC(0x2aef6bcf), WTC(0x2c8230fc),
+ WTC(0x2e1c545b), WTC(0x2fbde72b), WTC(0x3166e76f), WTC(0x33173f5d),
+ WTC(0x34cee8c3), WTC(0x368debe1), WTC(0x38543d4f), WTC(0x3a21bd94),
+ WTC(0x3bf6576f), WTC(0x3dd1ff07), WTC(0x3fb4948e), WTC(0x419de414),
+ WTC(0x438dc202), WTC(0x45840e7d), WTC(0x4780a435), WTC(0x4983609f),
+ WTC(0x4b8cc548), WTC(0x4d9df796), WTC(0x4fb81f46), WTC(0x51dc8690),
+ WTC(0x000d970d), WTC(0xfff7ea67), WTC(0xfff7fc3d), WTC(0x000d3de2),
+ WTC(0x003720ad), WTC(0x007515f1), WTC(0x00c68f04), WTC(0x012afd3b),
+ WTC(0x01a1d1ec), WTC(0x022a7e69), WTC(0x02c47408), WTC(0x036f2420),
+ WTC(0x042a0001), WTC(0x04f47905), WTC(0x05ce007e), WTC(0x06b607be),
+ WTC(0x07ac0028), WTC(0x08af5b01), WTC(0x09bf89a7), WTC(0x0adbfd6d),
+ WTC(0x0c042798), WTC(0x0d377997), WTC(0x0e7564b5), WTC(0x0fbd5a3a),
+ WTC(0x110ecb85), WTC(0x126929fb), WTC(0x13cbe6e6), WTC(0x15367376),
+ WTC(0x16a8413f), WTC(0x1820c15f), WTC(0x199f6568), WTC(0x1b239e6b),
+ WTC(0x1cacdde2), WTC(0x1e3a951a), WTC(0x1fcc356f), WTC(0x2161301f),
+ WTC(0x22f8f6b7), WTC(0x2492fa4a), WTC(0x262eac3f), WTC(0x27cb7e20),
+ WTC(0x2968e0c4), WTC(0x2b064625), WTC(0x2ca31f1a), WTC(0x2e3edd2a),
+ WTC(0x2fd8f19f), WTC(0x3170ce00), WTC(0x3305e32c), WTC(0x3497a2df),
+ WTC(0x36257e78), WTC(0x37aee70b), WTC(0x39334e05), WTC(0x3ab22498),
+ WTC(0x3c2adc2c), WTC(0x3d9ce645), WTC(0x3f07b3ef), WTC(0x406ab6ca),
+ WTC(0x41c56001), WTC(0x4317214a), WTC(0x445f6b34), WTC(0x459daf5d),
+ WTC(0x46d15f56), WTC(0x47f9ed71), WTC(0x4916d11f), WTC(0x4a275770),
+ WTC(0x4b2b2fff), WTC(0x4c219eae), WTC(0x4d0a20cb), WTC(0x4de4288e),
+ WTC(0x4eaf263d), WTC(0x4f6a8bb8), WTC(0x5015ca33), WTC(0x50b052dd),
+ WTC(0x51399757), WTC(0x51b108c6), WTC(0x5216190a), WTC(0x5268387c),
+ WTC(0x52a6d933), WTC(0x52d16c19), WTC(0x52e7628b), WTC(0x52e82ea3),
+ WTC(0x52d3407d), WTC(0x52a80a28), WTC(0x5265fd43), WTC(0x520c8a1d),
+ WTC(0x519b22c8), WTC(0x511138e0), WTC(0x506e3c82), WTC(0x4fb1a037),
+ WTC(0x4edad4e3), WTC(0x4de94c2d), WTC(0x4cdc76d8), WTC(0x4bb3c683),
+ WTC(0x4a6eacd2), WTC(0x490c9abe), WTC(0x478d04f1), WTC(0x45f00420),
+ WTC(0x4445673f), WTC(0x42ac0d2e), WTC(0x41338364), WTC(0x3fdb5b58),
+ WTC(0x3ea1c30f), WTC(0x3d842780), WTC(0x3c7fa763), WTC(0x3b911b96),
+ WTC(0x3ab560bf), WTC(0x39e95908), WTC(0x3929debb), WTC(0x3873bd4d),
+ WTC(0x37c31db2), WTC(0x3713a59c), WTC(0x3663deb2), WTC(0x35b52f23),
+ WTC(0x3507c61e), WTC(0x345a7f42), WTC(0x33ac7e0c), WTC(0x32fd366f),
+ WTC(0x324baa28), WTC(0x319674e9), WTC(0x30dd7e1a), WTC(0x3021f3e8),
+ WTC(0x2f63f903), WTC(0x2ea2a1aa), WTC(0x2dddd97b), WTC(0x2d166985),
+ WTC(0x2c4ca42f), WTC(0x2b805cca), WTC(0x2ab162aa), WTC(0x29df7b17),
+};
+
+const FIXP_WTB ELDAnalysis240[720] = {
+ WTC(0xfab9477b), WTC(0xfa899344), WTC(0xfa5845dd), WTC(0xfa259762),
+ WTC(0xf9f1c005), WTC(0xf9bcefe6), WTC(0xf9871e8b), WTC(0xf9503397),
+ WTC(0xf9183f47), WTC(0xf8df4eac), WTC(0xf8a53ba7), WTC(0xf869f0be),
+ WTC(0xf82d9759), WTC(0xf7f0593e), WTC(0xf7b2520a), WTC(0xf773a37c),
+ WTC(0xf73475ce), WTC(0xf6f4bedd), WTC(0xf6b455a8), WTC(0xf6739525),
+ WTC(0xf6332510), WTC(0xf5f3938b), WTC(0xf5b56073), WTC(0xf57900bd),
+ WTC(0xf53ee82d), WTC(0xf5079149), WTC(0xf4d36ffc), WTC(0xf4a2e526),
+ WTC(0xf4763d91), WTC(0xf44d9872), WTC(0xf426eaed), WTC(0xf3fdc161),
+ WTC(0xf3d001ff), WTC(0xf39dafcc), WTC(0xf366eb43), WTC(0xf32bdcdc),
+ WTC(0xf2ecab80), WTC(0xf2a97b34), WTC(0xf26265ae), WTC(0xf2178a6f),
+ WTC(0xf1c92458), WTC(0xf17752b9), WTC(0xf121e6ac), WTC(0xf0c89a63),
+ WTC(0xf06b15ef), WTC(0xf0092e86), WTC(0xefa2fd42), WTC(0xef397ebc),
+ WTC(0xeece51c6), WTC(0xee61e8b6), WTC(0xedf3d92e), WTC(0xed82c330),
+ WTC(0xed0d58bb), WTC(0xec94891b), WTC(0xec19d435), WTC(0xeb9e4e4e),
+ WTC(0xeb221000), WTC(0xeaa32422), WTC(0xea1fb440), WTC(0xe99695d2),
+ WTC(0xe90859ab), WTC(0xe8775114), WTC(0xe7e62b37), WTC(0xe7578147),
+ WTC(0xe6cb3ac1), WTC(0xe63f5696), WTC(0xe5afe916), WTC(0xe519090f),
+ WTC(0xe47aab0d), WTC(0xe3d6c2d0), WTC(0xe331dae7), WTC(0xe29031e1),
+ WTC(0xe1f40926), WTC(0xe15d87d2), WTC(0xe0c9d727), WTC(0xe0360ad5),
+ WTC(0xdf9f81af), WTC(0xdf04f9f9), WTC(0xde66697f), WTC(0xddc48ca1),
+ WTC(0xdd20a42a), WTC(0xdc7c6853), WTC(0xdbd9a476), WTC(0xdb398a8c),
+ WTC(0xda9cd7c2), WTC(0xda0365cf), WTC(0xd96cad85), WTC(0xd8d7b7a3),
+ WTC(0xd8439e8c), WTC(0xd7afb73d), WTC(0xd71b6347), WTC(0xd686149a),
+ WTC(0xd5efab2c), WTC(0xd558877e), WTC(0xd4c29dbc), WTC(0xd430a0aa),
+ WTC(0xd3a3d490), WTC(0xd31c588f), WTC(0xd297e075), WTC(0xd213ef33),
+ WTC(0xd18fd566), WTC(0xd10b8d3f), WTC(0xd087b250), WTC(0xd0054ef2),
+ WTC(0xcf85f94a), WTC(0xcf0af5f7), WTC(0xce94faf5), WTC(0xce229409),
+ WTC(0xcdb0b5f8), WTC(0xcd3ec554), WTC(0xcccdbf58), WTC(0xcc5f39d5),
+ WTC(0xcbf49ef5), WTC(0xcb8d5f73), WTC(0xcb28801c), WTC(0xcac5a265),
+ WTC(0xca64ad2e), WTC(0xca05d7fd), WTC(0xc9a96602), WTC(0xc94f9f79),
+ WTC(0xc8f2b954), WTC(0xc899e795), WTC(0xc83f94aa), WTC(0xc7e41f63),
+ WTC(0xc787e69f), WTC(0xc72b3fd0), WTC(0xc6ce3f0f), WTC(0xc670c175),
+ WTC(0xc61224cf), WTC(0xc5b21fec), WTC(0xc55202a4), WTC(0xc4f3353a),
+ WTC(0xc4968597), WTC(0xc43b93f2), WTC(0xc3e03d26), WTC(0xc383a011),
+ WTC(0xc3268aed), WTC(0xc2ca1039), WTC(0xc26f5bcc), WTC(0xc21726c9),
+ WTC(0xc1c1d5b2), WTC(0xc16f66ba), WTC(0xc11f76d9), WTC(0xc0d0a9f6),
+ WTC(0xc081cddb), WTC(0xc0333180), WTC(0xbfe5bb54), WTC(0xbf9aee90),
+ WTC(0xbf53d587), WTC(0xbf108855), WTC(0xbed0de05), WTC(0xbe9477d7),
+ WTC(0xbe5b030f), WTC(0xbe243642), WTC(0xbdefb72f), WTC(0xbdbd29df),
+ WTC(0xbd8c71ab), WTC(0xbd5d99cb), WTC(0xbd30e375), WTC(0xbd06afcc),
+ WTC(0xbcdf8c7f), WTC(0xbcbbf704), WTC(0xbc9c307e), WTC(0xbc803b86),
+ WTC(0xbc67c0c7), WTC(0xbc521d3d), WTC(0xbc3e6561), WTC(0xbc2bf2cb),
+ WTC(0xbc1a6872), WTC(0xbc09ce15), WTC(0xbbfa764f), WTC(0xbbed1356),
+ WTC(0xbbe257fa), WTC(0xbbda4099), WTC(0xbbd46a31), WTC(0xbbcffa76),
+ WTC(0xbbcc766d), WTC(0xbbca782f), WTC(0xbbcb16c7), WTC(0xbbcff77c),
+ WTC(0xbbd978e6), WTC(0xbbe68e5f), WTC(0xbbf593ed), WTC(0xbc04a834),
+ WTC(0xbc136941), WTC(0xbc2252c3), WTC(0xbc31723d), WTC(0xbc40ab92),
+ WTC(0xbc4ffe2d), WTC(0xbc5f7072), WTC(0xbc6f0520), WTC(0xbc7ebd23),
+ WTC(0xbc8e9746), WTC(0xbc9e942f), WTC(0xbcaeb633), WTC(0xbcbefe8b),
+ WTC(0xbccf69bb), WTC(0xbcdff92e), WTC(0xbcf0b04f), WTC(0xbd018ebd),
+ WTC(0xbd129192), WTC(0xbd23b9b8), WTC(0xbd350afb), WTC(0xbd46820e),
+ WTC(0xbd581bfc), WTC(0xbd69db11), WTC(0xbd7bbf57), WTC(0xbd8dc584),
+ WTC(0xbd9feaad), WTC(0xbdb231a4), WTC(0xbdc498ea), WTC(0xbdd71cd1),
+ WTC(0xbde9bb57), WTC(0xbdfc77d9), WTC(0xbe0f4e93), WTC(0xbe223ae5),
+ WTC(0xbe353cf5), WTC(0xbe485689), WTC(0xbe5b8329), WTC(0xbe6ebe88),
+ WTC(0xbe820afd), WTC(0xbe956811), WTC(0xbea8d109), WTC(0xbebc4352),
+ WTC(0xbecfc0fb), WTC(0xbee34a07), WTC(0xbef6d884), WTC(0xbf0a6bb1),
+ WTC(0xbf1e0685), WTC(0xbf31a685), WTC(0xbf45483c), WTC(0xbf58eb6b),
+ WTC(0xbf6c9376), WTC(0xbf803c90), WTC(0xbf93e4b9), WTC(0xbfa78d05),
+ WTC(0xbfbb3830), WTC(0xbfcee339), WTC(0xbfe28aa9), WTC(0xbff62b89),
+ WTC(0x8013a5f4), WTC(0x803acfd6), WTC(0x8061eec7), WTC(0x8088fc73),
+ WTC(0x80aff270), WTC(0x80d6cbe5), WTC(0x80fd8c2a), WTC(0x812437a8),
+ WTC(0x814ac94f), WTC(0x81713adc), WTC(0x81979098), WTC(0x81bdccb7),
+ WTC(0x81e3e738), WTC(0x8209dd04), WTC(0x822fb23a), WTC(0x825565bb),
+ WTC(0x827aed94), WTC(0x82a04909), WTC(0x82c57c85), WTC(0x82ea831c),
+ WTC(0x830f539d), WTC(0x8333eeba), WTC(0x8358585a), WTC(0x837c882e),
+ WTC(0x83a07742), WTC(0x83c428a5), WTC(0x83e79c4c), WTC(0x840aca65),
+ WTC(0x842dad81), WTC(0x84504ac0), WTC(0x84729fb1), WTC(0x8494a4f1),
+ WTC(0x84b65932), WTC(0x84d7c0f8), WTC(0x84f8d936), WTC(0x85199a59),
+ WTC(0x853a05a1), WTC(0x855a2023), WTC(0x8579e46e), WTC(0x85994d55),
+ WTC(0x85b86190), WTC(0x85d723e6), WTC(0x85f58fa9), WTC(0x8613a3ce),
+ WTC(0x863167b5), WTC(0x864eddfe), WTC(0x866c0138), WTC(0x8688d2e4),
+ WTC(0x86a55901), WTC(0x86c19497), WTC(0x86dd8390), WTC(0x86f9288f),
+ WTC(0x871487e0), WTC(0x872fadd0), WTC(0x874a9a1e), WTC(0x876519d0),
+ WTC(0x877f471e), WTC(0x8799fb36), WTC(0x87b48b97), WTC(0x87cba021),
+ WTC(0x880f67ae), WTC(0x885e0f91), WTC(0x88bc84cd), WTC(0x89244640),
+ WTC(0x8990a45d), WTC(0x89fe6766), WTC(0x8a6c9065), WTC(0x8adb31e6),
+ WTC(0x8b4ad5b3), WTC(0x8bbc2068), WTC(0x8c2f93ff), WTC(0x8ca5a922),
+ WTC(0x8d1ed72d), WTC(0x8d9b7ddb), WTC(0x8e1bd6cc), WTC(0x8ea01924),
+ WTC(0x8f287716), WTC(0x8fb5143e), WTC(0x9046074e), WTC(0x90db612b),
+ WTC(0x91753263), WTC(0x92138094), WTC(0x92b64cf3), WTC(0x935d96c9),
+ WTC(0x94095a56), WTC(0x94b98fd4), WTC(0x956e2a87), WTC(0x96271ff6),
+ WTC(0x96e46309), WTC(0x97a5e80d), WTC(0x986b9e55), WTC(0x993572af),
+ WTC(0x9a0350ce), WTC(0x9ad52154), WTC(0x9baad10f), WTC(0x9c844cdd),
+ WTC(0x9d618437), WTC(0x9e4265b2), WTC(0x9f26d9ad), WTC(0xa00ec9b0),
+ WTC(0xa0fa2916), WTC(0xa1e8ec20), WTC(0xa2daffa4), WTC(0xa3d05468),
+ WTC(0xa4c8e007), WTC(0xa5c49ae4), WTC(0xa6c37c24), WTC(0xa7c57d03),
+ WTC(0xa8ca9750), WTC(0xa9d2c7f2), WTC(0xaade0f6f), WTC(0xabec7177),
+ WTC(0xacfdf2b1), WTC(0xae129740), WTC(0xaf2a6321), WTC(0xb04563a6),
+ WTC(0xb163a2e6), WTC(0xb28524c4), WTC(0xb3a9eaf7), WTC(0xb4d1ff1b),
+ WTC(0x4a1d2880), WTC(0x48eee56e), WTC(0x47bda882), WTC(0x46895c79),
+ WTC(0x4551f8a1), WTC(0x4417817b), WTC(0x42da023d), WTC(0x419980ca),
+ WTC(0x4055f463), WTC(0x3f0f3b51), WTC(0x3dc56e18), WTC(0x3c78d943),
+ WTC(0x3b29bf3d), WTC(0x39d84ea0), WTC(0x3884337d), WTC(0x372d2371),
+ WTC(0x35d364ea), WTC(0x34774cef), WTC(0x33194d3a), WTC(0x31b9d586),
+ WTC(0x30594fcf), WTC(0x2ef80b63), WTC(0x2d9630d5), WTC(0x2c337c00),
+ WTC(0x2acf6a9e), WTC(0x296a3205), WTC(0x28046825), WTC(0x269f1752),
+ WTC(0x253b5314), WTC(0x23d9993f), WTC(0x227a3c77), WTC(0x211d59a0),
+ WTC(0x1fc314fd), WTC(0x1e6b9834), WTC(0x1d16eb58), WTC(0x1bc4f82e),
+ WTC(0x1a75e481), WTC(0x1929f389), WTC(0x17e16ee3), WTC(0x169cd758),
+ WTC(0x155d1ae5), WTC(0x14235182), WTC(0x12f051de), WTC(0x11c4993b),
+ WTC(0x109fdf4c), WTC(0x0f81351c), WTC(0x0e66c5e6), WTC(0x0d4f4b16),
+ WTC(0x0c39f013), WTC(0x0b25765d), WTC(0x0a10c51e), WTC(0x08fbee35),
+ WTC(0x07e7986f), WTC(0x06d25fe7), WTC(0x05ba1b52), WTC(0x049c33b7),
+ WTC(0x0379ceb9), WTC(0x025ee7c7), WTC(0x015edc1c), WTC(0x00978deb),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xffe59474), WTC(0xffb158f8), WTC(0xff7d1275), WTC(0xff48f44c),
+ WTC(0xff1531e3), WTC(0xfee1faa9), WTC(0xfeaf626e), WTC(0xfe7d7227),
+ WTC(0xfe4c383f), WTC(0xfe1bc4ff), WTC(0xfdec297f), WTC(0xfdbd9f6c),
+ WTC(0xfd90bbf0), WTC(0xfd65ba73), WTC(0xfd3c2d32), WTC(0xfd13ab35),
+ WTC(0xfcebe811), WTC(0xfcc4eeae), WTC(0xfc9f1d64), WTC(0xfc7b48b0),
+ WTC(0xfc5a7282), WTC(0xfc3cef9b), WTC(0xfc229f4c), WTC(0xfc0a9e29),
+ WTC(0xfbf3dccb), WTC(0xfbdd80c3), WTC(0xfbc7556c), WTC(0xfbb289cf),
+ WTC(0xfba06f99), WTC(0xfb923aca), WTC(0xfb88bb57), WTC(0xfb84457f),
+ WTC(0xfb848c2e), WTC(0xfb88bd28), WTC(0xfb8feda1), WTC(0xfb9928eb),
+ WTC(0xfba38b9e), WTC(0xfbae711c), WTC(0xfbba3538), WTC(0xfbc7af9d),
+ WTC(0xfbd8485e), WTC(0xfbeda238), WTC(0xfc099de4), WTC(0xfc2d981f),
+ WTC(0xfc59fd0d), WTC(0xfc8e1583), WTC(0xfcc7e0d7), WTC(0xfd048d03),
+ WTC(0xfd40dfaf), WTC(0xfd7c1d35), WTC(0xfdb767cc), WTC(0xfdf64a9f),
+ WTC(0xfe3d0242), WTC(0xfe8e3316), WTC(0xfeead2b9), WTC(0xff4fff8c),
+ WTC(0xffba7b11), WTC(0x00281cae), WTC(0x009847d1), WTC(0x010cb653),
+ WTC(0x01870639), WTC(0x02089db5), WTC(0x0291b571), WTC(0x0321a4c1),
+ WTC(0x03b7eda0), WTC(0x04544c7f), WTC(0x04f74134), WTC(0x05a16810),
+ WTC(0x06525829), WTC(0x070994d4), WTC(0x07c767ba), WTC(0x088c69b8),
+ WTC(0x09598634), WTC(0x0a2f14ca), WTC(0x0b0c677b), WTC(0x0bf0f576),
+ WTC(0x0cdc7f73), WTC(0x0dceed54), WTC(0x0ec84a00), WTC(0x0fc8db86),
+ WTC(0x10d10278), WTC(0x11e0e05e), WTC(0x12f880cc), WTC(0x1418049b),
+ WTC(0x153f86b3), WTC(0x166ef5a3), WTC(0x17a64878), WTC(0x18e59dde),
+ WTC(0x1a2d088b), WTC(0x1b7c7e41), WTC(0x1cd40ab7), WTC(0x1e33d542),
+ WTC(0x1f9be7a5), WTC(0x210c344f), WTC(0x2284cb85), WTC(0x2405ca48),
+ WTC(0x258f2b7f), WTC(0x2720e063), WTC(0x28bafd49), WTC(0x2a5d950c),
+ WTC(0x2c0896e4), WTC(0x2dbbf7d4), WTC(0x2f77ca28), WTC(0x313c1273),
+ WTC(0x3308b7e4), WTC(0x34ddb0ec), WTC(0x36bb06b7), WTC(0x38a0a935),
+ WTC(0x3a8e7270), WTC(0x3c844ca9), WTC(0x3e82267e), WTC(0x4087ccfa),
+ WTC(0x42950352), WTC(0x44a99ce7), WTC(0x46c57093), WTC(0x48e84dbe),
+ WTC(0x4b127506), WTC(0x4d452d29), WTC(0x4f81e066), WTC(0x51ca11c4),
+ WTC(0x000c82e8), WTC(0xfff6f40c), WTC(0xfffa1260), WTC(0x001530bf),
+ WTC(0x0047a202), WTC(0x0090b903), WTC(0x00efc89f), WTC(0x016423af),
+ WTC(0x01ed1d0e), WTC(0x028a0796), WTC(0x033a3620), WTC(0x03fcfb89),
+ WTC(0x04d1aaaa), WTC(0x05b7965c), WTC(0x06ae1179), WTC(0x07b46ee8),
+ WTC(0x08ca0173), WTC(0x09ee1c00), WTC(0x0b201162), WTC(0x0c5f346e),
+ WTC(0x0daad808), WTC(0x0f024f17), WTC(0x1064ec4b), WTC(0x11d202c4),
+ WTC(0x1348e514), WTC(0x14c8e62f), WTC(0x1651590a), WTC(0x17e19051),
+ WTC(0x1978df27), WTC(0x1b169812), WTC(0x1cba0e15), WTC(0x1e629407),
+ WTC(0x200f7cd4), WTC(0x21c01b29), WTC(0x2373c228), WTC(0x2529c453),
+ WTC(0x26e174b9), WTC(0x289a262f), WTC(0x2a532bba), WTC(0x2c0bd7b2),
+ WTC(0x2dc37d92), WTC(0x2f796fce), WTC(0x312d017a), WTC(0x32dd8513),
+ WTC(0x348a4dde), WTC(0x3632aeb3), WTC(0x37d5fa29), WTC(0x39738334),
+ WTC(0x3b0a9c99), WTC(0x3c9a9926), WTC(0x3e22cc21), WTC(0x3fa287dc),
+ WTC(0x41191f89), WTC(0x4285e5fc), WTC(0x43e82e02), WTC(0x453f4a40),
+ WTC(0x468a8dd9), WTC(0x47c94c23), WTC(0x48fadc7c), WTC(0x4a1e75f9),
+ WTC(0x4b339ecf), WTC(0x4c3981b1), WTC(0x4d2f7cd3), WTC(0x4e14e381),
+ WTC(0x4ee90804), WTC(0x4fab3d6a), WTC(0x505ad6bd), WTC(0x50f726a3),
+ WTC(0x517f7fea), WTC(0x51f335fd), WTC(0x52519b0f), WTC(0x529a01f2),
+ WTC(0x52cbbe31), WTC(0x52e621d9), WTC(0x52e880aa), WTC(0x52d22c7a),
+ WTC(0x52a278a5), WTC(0x5258b880), WTC(0x51f43e1d), WTC(0x51745c38),
+ WTC(0x50d8669e), WTC(0x501faf0e), WTC(0x4f49897e), WTC(0x4e554804),
+ WTC(0x4d423d9e), WTC(0x4c0fbd8b), WTC(0x4abd1a4d), WTC(0x4949a698),
+ WTC(0x47b4b7f9), WTC(0x45fe2b6d), WTC(0x44375019), WTC(0x4284e96e),
+ WTC(0x40f7efa2), WTC(0x3f8f8b33), WTC(0x3e494311), WTC(0x3d21e35b),
+ WTC(0x3c15c621), WTC(0x3b2115f3), WTC(0x3a4008aa), WTC(0x396ed2a6),
+ WTC(0x38a99a1d), WTC(0x37ec1177), WTC(0x3730f154), WTC(0x36756c15),
+ WTC(0x35bafb0d), WTC(0x35020093), WTC(0x34492381), WTC(0x338f6226),
+ WTC(0x32d40a34), WTC(0x3215bd73), WTC(0x315302ce), WTC(0x308c7c41),
+ WTC(0x2fc3532f), WTC(0x2ef6de8f), WTC(0x2e265a7f), WTC(0x2d527bfd),
+ WTC(0x2c7bf035), WTC(0x2ba2975b), WTC(0x2ac63552), WTC(0x29e686ca),
+};
+
+const FIXP_WTB ELDAnalysis128[384] = {
+ WTC(0xfaa49e98), WTC(0xfa48929f), WTC(0xf9e7eb39), WTC(0xf983b829),
+ WTC(0xf91bc5cb), WTC(0xf8b0376f), WTC(0xf8408d62), WTC(0xf7cd8c1e),
+ WTC(0xf7580da3), WTC(0xf6e0b0dc), WTC(0xf667753c), WTC(0xf5efa4cf),
+ WTC(0xf57cb6de), WTC(0xf511b62b), WTC(0xf4b1a860), WTC(0xf45ee8f8),
+ WTC(0xf415710d), WTC(0xf3c0c4f3), WTC(0xf35c2af9), WTC(0xf2e89620),
+ WTC(0xf266f3cb), WTC(0xf1d819bf), WTC(0xf13cff2f), WTC(0xf09489d2),
+ WTC(0xefdcfa80), WTC(0xef182059), WTC(0xee4d6c60), WTC(0xed7b8da7),
+ WTC(0xec9c27b1), WTC(0xebb57d0d), WTC(0xeacb3918), WTC(0xe9d35591),
+ WTC(0xe8c9176e), WTC(0xe7b93e42), WTC(0xe6b10e47), WTC(0xe5a6b875),
+ WTC(0xe484c345), WTC(0xe3509f1b), WTC(0xe224254c), WTC(0xe10a4e18),
+ WTC(0xdff4a668), WTC(0xded3d881), WTC(0xdda5ed98), WTC(0xdc722d13),
+ WTC(0xdb437360), WTC(0xda1fefed), WTC(0xd90623b2), WTC(0xd7f070f5),
+ WTC(0xd6da361b), WTC(0xd5c0786f), WTC(0xd4a6e188), WTC(0xd39b37b4),
+ WTC(0xd2a01ff2), WTC(0xd1a8a05c), WTC(0xd0b0cf47), WTC(0xcfbd3527),
+ WTC(0xced6b8d7), WTC(0xcdff0a66), WTC(0xcd2978a4), WTC(0xcc587183),
+ WTC(0xcb93bfdb), WTC(0xcad80773), WTC(0xca233c2b), WTC(0xc9768b5e),
+ WTC(0xc8cc130c), WTC(0xc8231acd), WTC(0xc7768de4), WTC(0xc6c86bdf),
+ WTC(0xc6181aa1), WTC(0xc563f6ce), WTC(0xc4b33a2a), WTC(0xc4085fcf),
+ WTC(0xc35ae72e), WTC(0xc2ad7adf), WTC(0xc206ed94), WTC(0xc16a5744),
+ WTC(0xc0d59625), WTC(0xc041e21b), WTC(0xbfb1ee05), WTC(0xbf2d82ea),
+ WTC(0xbeb60fe9), WTC(0xbe499da8), WTC(0xbde61891), WTC(0xbd8975b6),
+ WTC(0xbd339d36), WTC(0xbce6a08b), WTC(0xbca5b2f9), WTC(0xbc721002),
+ WTC(0xbc494d41), WTC(0xbc266160), WTC(0xbc06d14f), WTC(0xbbec52c7),
+ WTC(0xbbdaaf79), WTC(0xbbd0be99), WTC(0xbbcae139), WTC(0xbbcd359c),
+ WTC(0xbbded5d3), WTC(0xbbfa58cf), WTC(0xbc162f9d), WTC(0xbc326534),
+ WTC(0xbc4f081c), WTC(0xbc6c1678), WTC(0xbc899f93), WTC(0xbca7a263),
+ WTC(0xbcc62954), WTC(0xbce52ddc), WTC(0xbd04bc7f), WTC(0xbd24cd8f),
+ WTC(0xbd456998), WTC(0xbd668428), WTC(0xbd88207c), WTC(0xbdaa2e4b),
+ WTC(0xbdccaf3e), WTC(0xbdef932c), WTC(0xbe12d936), WTC(0xbe366dd6),
+ WTC(0xbe5a4fd9), WTC(0xbe7e6b49), WTC(0xbea2bf3f), WTC(0xbec738b5),
+ WTC(0xbeebd791), WTC(0xbf108b49), WTC(0xbf3554aa), WTC(0xbf5a25cf),
+ WTC(0xbf7f020b), WTC(0xbfa3dd25), WTC(0xbfc8be1e), WTC(0xbfed95f6),
+ WTC(0x8024c933), WTC(0x806e24fb), WTC(0x80b73d96), WTC(0x80fff78c),
+ WTC(0x8148612f), WTC(0x8190626e), WTC(0x81d8030a), WTC(0x821f28e1),
+ WTC(0x8265d6be), WTC(0x82abed56), WTC(0x82f16e40), WTC(0x833636d2),
+ WTC(0x837a470a), WTC(0x83bd7be6), WTC(0x83ffd415), WTC(0x84412e66),
+ WTC(0x84818c4f), WTC(0x84c0d18c), WTC(0x84ff0429), WTC(0x853c09a5),
+ WTC(0x8577eacf), WTC(0x85b29402), WTC(0x85ec17bf), WTC(0x86246b50),
+ WTC(0x865ba7d7), WTC(0x8691c4c0), WTC(0x86c6d72a), WTC(0x86fae06c),
+ WTC(0x872dfcd1), WTC(0x87602c6a), WTC(0x87918a27), WTC(0x87c22ef8),
+ WTC(0x882f7c20), WTC(0x88dc38ab), WTC(0x89a52f47), WTC(0x8a737635),
+ WTC(0x8b43d08d), WTC(0x8c19be9f), WTC(0x8cf89ce7), WTC(0x8de337e9),
+ WTC(0x8edb3e02), WTC(0x8fe1e815), WTC(0x90f7e107), WTC(0x921d8b95),
+ WTC(0x9353008c), WTC(0x94982fd7), WTC(0x95ecdc6d), WTC(0x9750b87f),
+ WTC(0x98c36ad6), WTC(0x9a447674), WTC(0x9bd34e9c), WTC(0x9d6f76fa),
+ WTC(0x9f18780d), WTC(0xa0cdc487), WTC(0xa28eff8e), WTC(0xa45bbe4b),
+ WTC(0xa633baaf), WTC(0xa816bff0), WTC(0xaa04a90d), WTC(0xabfd7205),
+ WTC(0xae01356b), WTC(0xb0101477), WTC(0xb22a5244), WTC(0xb4500b02),
+ WTC(0x499946f3), WTC(0x475da5af), WTC(0x45173dce), WTC(0x42c610ad),
+ WTC(0x406a44b0), WTC(0x3e037ce8), WTC(0x3b92b806), WTC(0x39195cd0),
+ WTC(0x36962f17), WTC(0x340a1b28), WTC(0x3177cde6), WTC(0x2ee1f20d),
+ WTC(0x2c49b0d6), WTC(0x29ad3d74), WTC(0x270e9ec1), WTC(0x2474132f),
+ WTC(0x21e14a01), WTC(0x1f57704e), WTC(0x1cd758ce), WTC(0x1a610d48),
+ WTC(0x17f5db88), WTC(0x1598a188), WTC(0x134f7a40), WTC(0x111f1ca0),
+ WTC(0x0f053b83), WTC(0x0cf871db), WTC(0x0af19e60), WTC(0x08eaa56d),
+ WTC(0x06e3c473), WTC(0x04d25cc9), WTC(0x02b59b4d), WTC(0x00e5bc4c),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xffcebf14), WTC(0xff6cc249), WTC(0xff0b8bda), WTC(0xfeac3e5f),
+ WTC(0xfe4f4638), WTC(0xfdf5052f), WTC(0xfd9e8cf4), WTC(0xfd4e34ea),
+ WTC(0xfd023142), WTC(0xfcb8f6f7), WTC(0xfc74e090), WTC(0xfc3b33e8),
+ WTC(0xfc0c1254), WTC(0xfbe1b2eb), WTC(0xfbb8ce73), WTC(0xfb97e511),
+ WTC(0xfb86273d), WTC(0xfb857a3e), WTC(0xfb918813), WTC(0xfba43692),
+ WTC(0xfbb96f24), WTC(0xfbd4dcc3), WTC(0xfc000cd5), WTC(0xfc458653),
+ WTC(0xfca6cd98), WTC(0xfd178c8e), WTC(0xfd872979), WTC(0xfdfa721e),
+ WTC(0xfe88c77c), WTC(0xff3c8b5c), WTC(0x00059ebc), WTC(0x00d91db0),
+ WTC(0x01bec555), WTC(0x02bdfb80), WTC(0x03d4c846), WTC(0x0501ad53),
+ WTC(0x064719b2), WTC(0x07a34a2b), WTC(0x0918814b), WTC(0x0aaaaa6b),
+ WTC(0x0c5728b9), WTC(0x0e1c1a0f), WTC(0x0ff9ccd1), WTC(0x11f21ffb),
+ WTC(0x1405d073), WTC(0x1635776b), WTC(0x1880f4e5), WTC(0x1ae8bdcb),
+ WTC(0x1d6cede3), WTC(0x200e1d93), WTC(0x22cc56fd), WTC(0x25a80858),
+ WTC(0x28a11bdd), WTC(0x2bb7e363), WTC(0x2eec2f0f), WTC(0x323e298d),
+ WTC(0x35ad7f0b), WTC(0x393a1989), WTC(0x3ce34a65), WTC(0x40a8683d),
+ WTC(0x44881c94), WTC(0x48813cb3), WTC(0x4c94523d), WTC(0x50c8eff0),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x0053a1ea), WTC(0x00f67066),
+ WTC(0x01e3f61b), WTC(0x0317bdaf), WTC(0x048d51ca), WTC(0x06403d11),
+ WTC(0x082c0a34), WTC(0x0a4c43d2), WTC(0x0c9c748e), WTC(0x0f182718),
+ WTC(0x11bae616), WTC(0x14803c1b), WTC(0x1763b3e6), WTC(0x1a60d832),
+ WTC(0x1d73336b), WTC(0x20965068), WTC(0x23c5b9d6), WTC(0x26fcfa1a),
+ WTC(0x2a379c30), WTC(0x2d712a75), WTC(0x30a52fba), WTC(0x33cf36a9),
+ WTC(0x36eaca15), WTC(0x39f3743b), WTC(0x3ce4bfc2), WTC(0x3fba37b8),
+ WTC(0x426f6671), WTC(0x44ffd6e8), WTC(0x47671326), WTC(0x49a0b2d0),
+ WTC(0x4ba81be1), WTC(0x4d78fd1e), WTC(0x4f0ed503), WTC(0x50652e28),
+ WTC(0x51779351), WTC(0x52418fbe), WTC(0x52bead75), WTC(0x52ea76cc),
+ WTC(0x52c07793), WTC(0x523c3918), WTC(0x5159470e), WTC(0x50132b36),
+ WTC(0x4e657128), WTC(0x4c4ba31d), WTC(0x49c14b60), WTC(0x46c1e9e4),
+ WTC(0x4374e179), WTC(0x408377b1), WTC(0x3e0fa0aa), WTC(0x3c05d584),
+ WTC(0x3a4d9888), WTC(0x38cdd8fa), WTC(0x376b75c4), WTC(0x360c51a7),
+ WTC(0x34b12fdc), WTC(0x33550d9f), WTC(0x31f1955c), WTC(0x307ffcb2),
+ WTC(0x2f03c44d), WTC(0x2d7a6b86), WTC(0x2be6d3d4), WTC(0x2a48d219),
+};
+
+const FIXP_WTB ELDAnalysis120[360] = {
+ WTC(0xfaa1a40a), WTC(0xfa3f173d), WTC(0xf9d7760c), WTC(0xf96bcc12),
+ WTC(0xf8fbe82c), WTC(0xf887bb26), WTC(0xf80f131a), WTC(0xf7930d03),
+ WTC(0xf714aeaf), WTC(0xf693f5a1), WTC(0xf613385b), WTC(0xf596ef0e),
+ WTC(0xf522dcc4), WTC(0xf4bab1f6), WTC(0xf461700c), WTC(0xf412e1fe),
+ WTC(0xf3b769b1), WTC(0xf349eaca), WTC(0xf2cb9164), WTC(0xf23d6d7b),
+ WTC(0xf1a0ab28), WTC(0xf0f5c20f), WTC(0xf03aadd9), WTC(0xef6e8c66),
+ WTC(0xee984910), WTC(0xedbbcbf8), WTC(0xecd1435b), WTC(0xebdc1b77),
+ WTC(0xeae31338), WTC(0xe9dbea9a), WTC(0xe8c005ea), WTC(0xe79e7068),
+ WTC(0xe6856dce), WTC(0xe5657c79), WTC(0xe42928e9), WTC(0xe2e0756e),
+ WTC(0xe1a83cf5), WTC(0xe0801fab), WTC(0xdf52bfeb), WTC(0xde15d1b1),
+ WTC(0xdcce71ba), WTC(0xdb8931bf), WTC(0xda4fbbe8), WTC(0xd9220a98),
+ WTC(0xd7f9af0c), WTC(0xd6d0e1df), WTC(0xd5a41f15), WTC(0xd4790330),
+ WTC(0xd35f84b8), WTC(0xd255e881), WTC(0xd14daf00), WTC(0xd04638e2),
+ WTC(0xcf47dff7), WTC(0xce5b8850), WTC(0xcd77b1d6), WTC(0xcc960ec0),
+ WTC(0xcbc0a6a4), WTC(0xcaf6d4f7), WTC(0xca34fa7d), WTC(0xc97c26c0),
+ WTC(0xc8c6868a), WTC(0xc811f873), WTC(0xc7599db8), WTC(0xc69f9780),
+ WTC(0xc5e24043), WTC(0xc5226384), WTC(0xc468f547), WTC(0xc3b20be9),
+ WTC(0xc2f826f0), WTC(0xc242ea02), WTC(0xc19844ae), WTC(0xc0f80714),
+ WTC(0xc05a6da1), WTC(0xbfbfe6d3), WTC(0xbf31b5b4), WTC(0xbeb24843),
+ WTC(0xbe3f4cb4), WTC(0xbdd63599), WTC(0xbd74c6b2), WTC(0xbd1b7128),
+ WTC(0xbccd4b41), WTC(0xbc8dc08e), WTC(0xbc5ca2bd), WTC(0xbc3509f1),
+ WTC(0xbc11f904), WTC(0xbbf37848), WTC(0xbbddfb6b), WTC(0xbbd214ea),
+ WTC(0xbbcb3a11), WTC(0xbbcce581), WTC(0xbbdfa6ba), WTC(0xbbfd2fa5),
+ WTC(0xbc1ad516), WTC(0xbc390c16), WTC(0xbc57b323), WTC(0xbc76dd1f),
+ WTC(0xbc969172), WTC(0xbcb6d611), WTC(0xbcd7ac8e), WTC(0xbcf91af9),
+ WTC(0xbd1b20bd), WTC(0xbd3dc1f5), WTC(0xbd60f678), WTC(0xbd84bec7),
+ WTC(0xbda909c0), WTC(0xbdcdd76e), WTC(0xbdf3161c), WTC(0xbe18c1e5),
+ WTC(0xbe3ec6c5), WTC(0xbe651f19), WTC(0xbe8bb78b), WTC(0xbeb288e1),
+ WTC(0xbed9848b), WTC(0xbf00a16f), WTC(0xbf27d681), WTC(0xbf4f1958),
+ WTC(0xbf76680e), WTC(0xbf9db85c), WTC(0xbfc50e09), WTC(0xbfec5bdf),
+ WTC(0x80273bdb), WTC(0x807577de), WTC(0x80c3630d), WTC(0x8110e4cb),
+ WTC(0x815e05da), WTC(0x81aab20f), WTC(0x81f6e68e), WTC(0x824290d0),
+ WTC(0x828da04c), WTC(0x82d8061f), WTC(0x8321a740), WTC(0x836a77f9),
+ WTC(0x83b2574f), WTC(0x83f93cc1), WTC(0x843f04a6), WTC(0x8483acd1),
+ WTC(0x84c71639), WTC(0x850944da), WTC(0x854a1d3a), WTC(0x8589a437),
+ WTC(0x85c7ccf9), WTC(0x8604a42f), WTC(0x86402cfb), WTC(0x867a740d),
+ WTC(0x86b37ff2), WTC(0x86eb5f6f), WTC(0x87222109), WTC(0x8757eb5f),
+ WTC(0x878c8341), WTC(0x87c0be51), WTC(0x88345fca), WTC(0x88ef97fb),
+ WTC(0x89c778c5), WTC(0x8aa3cc20), WTC(0x8b833d56), WTC(0x8c6a42a9),
+ WTC(0x8d5cb787), WTC(0x8e5d7787), WTC(0x8f6e3c5b), WTC(0x90902640),
+ WTC(0x91c3ca28), WTC(0x9309622d), WTC(0x9460e7d0), WTC(0x95ca1ad2),
+ WTC(0x97449dff), WTC(0x98d00612), WTC(0x9a6bbc19), WTC(0x9c17164d),
+ WTC(0x9dd180fc), WTC(0x9f9a6304), WTC(0xa1711f56), WTC(0xa355425e),
+ WTC(0xa5465846), WTC(0xa744190f), WTC(0xa94e4ca9), WTC(0xab64dcf0),
+ WTC(0xad87e068), WTC(0xafb77bfa), WTC(0xb1f3fb2b), WTC(0xb43d885c),
+ WTC(0x49866451), WTC(0x4723e56b), WTC(0x44b51e8d), WTC(0x423a2180),
+ WTC(0x3fb2fe0f), WTC(0x3d1f78f2), WTC(0x3a8153b7), WTC(0x37d906ff),
+ WTC(0x35259e7e), WTC(0x3269ba18), WTC(0x2fa8c1ea), WTC(0x2ce4fbab),
+ WTC(0x2a1cebd5), WTC(0x27519ac1), WTC(0x248a2de9), WTC(0x21cb7a79),
+ WTC(0x1f16fc13), WTC(0x1c6d9a50), WTC(0x19cf83c1), WTC(0x173e9943),
+ WTC(0x14bf6a71), WTC(0x12598f74), WTC(0x100fe27f), WTC(0x0ddab46a),
+ WTC(0x0bafab9d), WTC(0x09864fc7), WTC(0x075d3ac8), WTC(0x052c0fc2),
+ WTC(0x02ea842b), WTC(0x00f21d19), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xffcb7b4d), WTC(0xff62fb20), WTC(0xfefb82e2), WTC(0xfe965482),
+ WTC(0xfe33e4bf), WTC(0xfdd4b9b5), WTC(0xfd7b04ec), WTC(0xfd27cfe4),
+ WTC(0xfcd84cfd), WTC(0xfc8ce1d4), WTC(0xfc4b45e1), WTC(0xfc1666da),
+ WTC(0xfbe8af26), WTC(0xfbbcad9e), WTC(0xfb98c6ad), WTC(0xfb85dd87),
+ WTC(0xfb86355b), WTC(0xfb94589b), WTC(0xfba8ed8a), WTC(0xfbc0a735),
+ WTC(0xfbe23f8d), WTC(0xfc1a92c4), WTC(0xfc73315f), WTC(0xfce611a1),
+ WTC(0xfd5e94d9), WTC(0xfdd61cab), WTC(0xfe6427fd), WTC(0xff1c92da),
+ WTC(0xfff10542), WTC(0x00d1d58a), WTC(0x01c6daab), WTC(0x02d8dbc3),
+ WTC(0x040557a6), WTC(0x054b6f91), WTC(0x06ad2b2b), WTC(0x0828f4c5),
+ WTC(0x09c348d1), WTC(0x0b7dcb56), WTC(0x0d54d98e), WTC(0x0f47a599),
+ WTC(0x1157fa1b), WTC(0x138743ae), WTC(0x15d6423f), WTC(0x1844f0ae),
+ WTC(0x1ad3c273), WTC(0x1d82e65c), WTC(0x205306e1), WTC(0x23443d5c),
+ WTC(0x2656fae8), WTC(0x298b3a5a), WTC(0x2ce13a7d), WTC(0x3058e0e3),
+ WTC(0x33f22950), WTC(0x37acd0b2), WTC(0x3b885e6b), WTC(0x3f840412),
+ WTC(0x439e65ee), WTC(0x47d6014e), WTC(0x4c2aa857), WTC(0x50a46876),
+ WTC(0xfffe9b02), WTC(0x0004ac61), WTC(0x0069639d), WTC(0x0127578b),
+ WTC(0x02391efe), WTC(0x039950cc), WTC(0x054283bf), WTC(0x072f4eba),
+ WTC(0x095a488c), WTC(0x0bbe0802), WTC(0x0e5523f9), WTC(0x111a332e),
+ WTC(0x1407cca2), WTC(0x171886f5), WTC(0x1a46f927), WTC(0x1d8db9e1),
+ WTC(0x20e7600d), WTC(0x244e82a3), WTC(0x27bdb846), WTC(0x2b2f97a8),
+ WTC(0x2e9eb7ea), WTC(0x3205afd1), WTC(0x355f161c), WTC(0x38a581d7),
+ WTC(0x3bd3894a), WTC(0x3ee3c398), WTC(0x41d0c7ae), WTC(0x44952cb8),
+ WTC(0x472b8856), WTC(0x498e7eee), WTC(0x4bb88245), WTC(0x4da44d9f),
+ WTC(0x4f4c6b7d), WTC(0x50ab7298), WTC(0x51bbfa11), WTC(0x527898fb),
+ WTC(0x52dbe5f2), WTC(0x52e07778), WTC(0x5280e51f), WTC(0x51b7c4f1),
+ WTC(0x507fadc7), WTC(0x4ed336dd), WTC(0x4cacf749), WTC(0x4a078534),
+ WTC(0x46dd6dcc), WTC(0x43599e22), WTC(0x403f48da), WTC(0x3db1ed89),
+ WTC(0x3b98bd24), WTC(0x39d5b003), WTC(0x384a3292), WTC(0x36d328ff),
+ WTC(0x355e63a6), WTC(0x33ec69d8), WTC(0x32755ebd), WTC(0x30f01fce),
+ WTC(0x2f5d9646), WTC(0x2dbcc615), WTC(0x2c0fa145), WTC(0x2a56ce53),
+};
diff --git a/fdk-aac/libAACenc/src/aacEnc_rom.h b/fdk-aac/libAACenc/src/aacEnc_rom.h
new file mode 100644
index 0000000..fd50cab
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacEnc_rom.h
@@ -0,0 +1,217 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Memory layout
+ \author Markus Lohwasser
+*/
+
+#ifndef AACENC_ROM_H
+#define AACENC_ROM_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+#include "psy_configuration.h"
+#include "FDK_tools_rom.h"
+#include "FDK_lpc.h"
+
+/*
+ Huffman Tables
+*/
+extern const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3];
+extern const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3];
+extern const ULONG FDKaacEnc_huff_ltab5_6[9][9];
+extern const ULONG FDKaacEnc_huff_ltab7_8[8][8];
+extern const ULONG FDKaacEnc_huff_ltab9_10[13][13];
+extern const UCHAR FDKaacEnc_huff_ltab11[17][17];
+extern const UCHAR FDKaacEnc_huff_ltabscf[121];
+extern const USHORT FDKaacEnc_huff_ctab1[3][3][3][3];
+extern const USHORT FDKaacEnc_huff_ctab2[3][3][3][3];
+extern const USHORT FDKaacEnc_huff_ctab3[3][3][3][3];
+extern const USHORT FDKaacEnc_huff_ctab4[3][3][3][3];
+extern const USHORT FDKaacEnc_huff_ctab5[9][9];
+extern const USHORT FDKaacEnc_huff_ctab6[9][9];
+extern const USHORT FDKaacEnc_huff_ctab7[8][8];
+extern const USHORT FDKaacEnc_huff_ctab8[8][8];
+extern const USHORT FDKaacEnc_huff_ctab9[13][13];
+extern const USHORT FDKaacEnc_huff_ctab10[13][13];
+extern const USHORT FDKaacEnc_huff_ctab11[21][17];
+extern const ULONG FDKaacEnc_huff_ctabscf[121];
+
+/*
+ quantizer
+*/
+#define MANT_DIGITS 9
+#define MANT_SIZE (1 << MANT_DIGITS)
+
+#if defined(ARCH_PREFER_MULT_32x16)
+#define FIXP_QTD FIXP_SGL
+#define QTC FX_DBL2FXCONST_SGL
+#else
+#define FIXP_QTD FIXP_DBL
+#define QTC
+#endif
+
+extern const FIXP_QTD FDKaacEnc_mTab_3_4[MANT_SIZE];
+extern const FIXP_QTD FDKaacEnc_quantTableQ[4];
+extern const FIXP_QTD FDKaacEnc_quantTableE[4];
+
+extern const FIXP_DBL FDKaacEnc_mTab_4_3Elc[512];
+extern const FIXP_DBL FDKaacEnc_specExpMantTableCombElc[4][14];
+extern const UCHAR FDKaacEnc_specExpTableComb[4][14];
+
+/*
+ table to count used number of bits
+*/
+extern const SHORT FDKaacEnc_sideInfoTabLong[];
+extern const SHORT FDKaacEnc_sideInfoTabShort[];
+
+/*
+ Psy Configuration constants
+*/
+extern const SFB_PARAM_LONG p_FDKaacEnc_8000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_8000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_11025_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_11025_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_12000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_12000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_16000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_16000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_22050_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_22050_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_24000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_24000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_32000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_32000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_44100_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_44100_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_48000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_48000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_64000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_64000_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_88200_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_88200_short_128;
+extern const SFB_PARAM_LONG p_FDKaacEnc_96000_long_1024;
+extern const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_128;
+
+/*
+ TNS filter coefficients
+*/
+extern const FIXP_LPC FDKaacEnc_tnsEncCoeff3[8];
+extern const FIXP_LPC FDKaacEnc_tnsCoeff3Borders[8];
+extern const FIXP_LPC FDKaacEnc_tnsEncCoeff4[16];
+extern const FIXP_LPC FDKaacEnc_tnsCoeff4Borders[16];
+
+#define WTC0 WTC
+#define WTC1 WTC
+#define WTC2 WTC
+
+extern const FIXP_WTB ELDAnalysis512[1536];
+extern const FIXP_WTB ELDAnalysis480[1440];
+extern const FIXP_WTB ELDAnalysis256[768];
+extern const FIXP_WTB ELDAnalysis240[720];
+extern const FIXP_WTB ELDAnalysis128[384];
+extern const FIXP_WTB ELDAnalysis120[360];
+
+#endif /* #ifndef AACENC_ROM_H */
diff --git a/fdk-aac/libAACenc/src/aacenc.cpp b/fdk-aac/libAACenc/src/aacenc.cpp
new file mode 100644
index 0000000..372df31
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc.cpp
@@ -0,0 +1,1057 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Schug / A. Groeschel
+
+ Description: fast aac coder functions
+
+*******************************************************************************/
+
+#include "aacenc.h"
+
+#include "bitenc.h"
+#include "interface.h"
+#include "psy_configuration.h"
+#include "psy_main.h"
+#include "qc_main.h"
+#include "bandwidth.h"
+#include "channel_map.h"
+#include "tns_func.h"
+#include "aacEnc_ram.h"
+
+#include "genericStds.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 */
+
+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, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
+ INT sampleRate);
+
+INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot,
+ INT coreSamplingRate, INT frameLength, INT nChannels,
+ INT nChannelsEff, INT bitRate, INT averageBits,
+ INT *pAverageBitsPerFrame,
+ AACENC_BITRATE_MODE bitrateMode, INT nSubFrames) {
+ INT transportBits, prevBitRate, averageBitsPerFrame, minBitrate = 0, iter = 0;
+ INT minBitsPerFrame = 40 * nChannels;
+ if (isLowDelay(aot)) {
+ minBitrate = 8000 * nChannelsEff;
+ }
+
+ do {
+ prevBitRate = bitRate;
+ averageBitsPerFrame =
+ FDKaacEnc_CalcBitsPerFrame(bitRate, frameLength, coreSamplingRate) /
+ nSubFrames;
+
+ if (pAverageBitsPerFrame != NULL) {
+ *pAverageBitsPerFrame = averageBitsPerFrame;
+ }
+
+ if (hTpEnc != NULL) {
+ transportBits = transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame);
+ } else {
+ /* Assume some worst case */
+ transportBits = 208;
+ }
+
+ bitRate = fMax(bitRate,
+ fMax(minBitrate,
+ FDKaacEnc_CalcBitrate((minBitsPerFrame + transportBits),
+ frameLength, coreSamplingRate)));
+ FDK_ASSERT(bitRate >= 0);
+
+ bitRate = fMin(bitRate, FDKaacEnc_CalcBitrate(
+ (nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN),
+ frameLength, coreSamplingRate));
+ FDK_ASSERT(bitRate >= 0);
+
+ } while (prevBitRate != bitRate && iter++ < 3);
+
+ //fprintf(stderr, "FDKaacEnc_LimitBitrate(): bitRate=%d\n", bitRate);
+ return bitRate;
+}
+
+typedef struct {
+ AACENC_BITRATE_MODE bitrateMode;
+ int chanBitrate[2]; /* mono/stereo settings */
+} CONFIG_TAB_ENTRY_VBR;
+
+static const CONFIG_TAB_ENTRY_VBR configTabVBR[] = {
+ {AACENC_BR_MODE_CBR, {0, 0}},
+ {AACENC_BR_MODE_VBR_1, {32000, 20000}},
+ {AACENC_BR_MODE_VBR_2, {40000, 32000}},
+ {AACENC_BR_MODE_VBR_3, {56000, 48000}},
+ {AACENC_BR_MODE_VBR_4, {72000, 64000}},
+ {AACENC_BR_MODE_VBR_5, {112000, 96000}}};
+
+/*-----------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_GetVBRBitrate
+ description: Get VBR bitrate from vbr quality
+ input params: int vbrQuality (VBR0, VBR1, VBR2)
+ channelMode
+ returns: vbr bitrate
+
+ ------------------------------------------------------------------------------*/
+INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,
+ CHANNEL_MODE channelMode) {
+ INT bitrate = 0;
+ INT monoStereoMode = 0; /* default mono */
+
+ if (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) {
+ monoStereoMode = 1;
+ }
+
+ switch (bitrateMode) {
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode];
+ break;
+ case AACENC_BR_MODE_INVALID:
+ case AACENC_BR_MODE_CBR:
+ case AACENC_BR_MODE_SFR:
+ case AACENC_BR_MODE_FF:
+ default:
+ bitrate = 0;
+ break;
+ }
+
+ /* convert channel bitrate to overall bitrate*/
+ bitrate *= FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
+
+ return bitrate;
+}
+
+/**
+ * \brief Convert encoder bitreservoir value for transport library.
+ *
+ * \param hAacEnc Encoder handle
+ *
+ * \return Corrected bitreservoir level used in transport library.
+ */
+static INT FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc) {
+ INT transportBitreservoir = 0;
+
+ switch (hAacEnc->bitrateMode) {
+ case AACENC_BR_MODE_CBR:
+ transportBitreservoir =
+ hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */
+ break;
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ transportBitreservoir = FDK_INT_MAX; /* signal variable bitrate */
+ break;
+ case AACENC_BR_MODE_SFR:
+ transportBitreservoir = 0; /* super framing and fixed framing */
+ break; /* without bitreservoir signaling */
+ default:
+ case AACENC_BR_MODE_INVALID:
+ transportBitreservoir = 0; /* invalid configuration*/
+ }
+
+ if (hAacEnc->config->audioMuxVersion == 2) {
+ transportBitreservoir =
+ MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff;
+ }
+
+ return transportBitreservoir;
+}
+
+INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder) {
+ return FDKaacEnc_EncBitresToTpBitres(hAacEncoder);
+}
+
+/*-----------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_AacInitDefaultConfig
+ description: gives reasonable default configuration
+ returns: ---
+
+ ------------------------------------------------------------------------------*/
+void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) {
+ /* make the preinitialization of the structs flexible */
+ FDKmemclear(config, sizeof(AACENC_CONFIG));
+
+ /* default ancillary */
+ config->anc_Rate = 0; /* no ancillary data */
+ config->ancDataBitRate = 0; /* no additional consumed bitrate */
+
+ /* default configurations */
+ config->bitRate = -1; /* bitrate must be set*/
+ config->averageBits =
+ -1; /* instead of bitrate/s we can configure bits/superframe */
+ config->bitrateMode =
+ AACENC_BR_MODE_CBR; /* set bitrate mode to constant bitrate */
+ config->bandWidth = 0; /* get bandwidth from table */
+ config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */
+ config->usePns =
+ 1; /* depending on channelBitrate this might be set to 0 later */
+ config->useIS = 1; /* Intensity Stereo Configuration */
+ config->useMS = 1; /* MS Stereo tool */
+ config->framelength = -1; /* Framesize not configured */
+ config->syntaxFlags = 0; /* default syntax with no specialities */
+ config->epConfig = -1; /* no ER syntax -> no additional error protection */
+ config->nSubFrames = 1; /* default, no sub frames */
+ config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */
+ config->channelMode = MODE_UNKNOWN;
+ config->minBitsPerFrame = -1; /* minum number of bits in each AU */
+ config->maxBitsPerFrame = -1; /* minum number of bits in each AU */
+ config->audioMuxVersion = -1; /* audio mux version not configured */
+ config->downscaleFactor =
+ 1; /* downscale factor for ELD reduced delay mode, 1 is normal ELD */
+}
+
+/*---------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_Open
+ description: allocate and initialize a new encoder instance
+ returns: error code
+
+ ---------------------------------------------------------------------------*/
+AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, const INT nElements,
+ const INT nChannels, const INT nSubFrames) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ AAC_ENC *hAacEnc = NULL;
+ UCHAR *dynamicRAM = NULL;
+
+ if (phAacEnc == NULL) {
+ return AAC_ENC_INVALID_HANDLE;
+ }
+
+ /* allocate encoder structure */
+ hAacEnc = GetRam_aacEnc_AacEncoder();
+ if (hAacEnc == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ FDKmemclear(hAacEnc, sizeof(AAC_ENC));
+
+ if (NULL == (hAacEnc->dynamic_RAM = GetAACdynamic_RAM())) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ dynamicRAM = (UCHAR *)hAacEnc->dynamic_RAM;
+
+ /* allocate the Psy aud Psy Out structure */
+ ErrorStatus =
+ FDKaacEnc_PsyNew(&hAacEnc->psyKernel, nElements, nChannels, dynamicRAM);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, nElements, nChannels,
+ nSubFrames, dynamicRAM);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ /* allocate the Q&C Out structure */
+ ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, nElements, nChannels,
+ nSubFrames, dynamicRAM);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ /* allocate the Q&C kernel */
+ ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, nElements, dynamicRAM);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ hAacEnc->maxChannels = nChannels;
+ hAacEnc->maxElements = nElements;
+ hAacEnc->maxFrames = nSubFrames;
+
+bail:
+ *phAacEnc = hAacEnc;
+ return ErrorStatus;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_Initialize(
+ HANDLE_AAC_ENC hAacEnc,
+ AACENC_CONFIG *config, /* pre-initialized config struct */
+ HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ INT psyBitrate, tnsMask; // INT profile = 1;
+ CHANNEL_MAPPING *cm = NULL;
+
+ INT mbfac_e, qbw;
+ FIXP_DBL mbfac, bw_ratio;
+ QC_INIT qcInit;
+ INT averageBitsPerFrame = 0;
+ int bitresMin = 0; /* the bitreservoir is always big for AAC-LC */
+ const CHANNEL_MODE prevChannelMode = hAacEnc->encoderMode;
+
+ if (config == NULL) return AAC_ENC_INVALID_HANDLE;
+
+ /******************* sanity checks *******************/
+
+ /* check config structure */
+ if (config->nChannels < 1 || config->nChannels > (8)) {
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ /* check sample rate */
+ switch (config->sampleRate) {
+ case 8000:
+ case 11025:
+ case 12000:
+ case 16000:
+ case 22050:
+ case 24000:
+ case 32000:
+ case 44100:
+ case 48000:
+ case 64000:
+ case 88200:
+ case 96000:
+ break;
+ default:
+ return AAC_ENC_UNSUPPORTED_SAMPLINGRATE;
+ }
+
+ /* bitrate has to be set */
+ if (config->bitRate == -1) {
+ return AAC_ENC_UNSUPPORTED_BITRATE;
+ }
+
+ INT superframe_size = 110*8*(config->bitRate/8000);
+ INT frames_per_superframe = 6;
+ INT staticBits = 0;
+ if((config->syntaxFlags & AC_DAB) && hTpEnc) {
+ staticBits = transportEnc_GetStaticBits(hTpEnc, 0);
+ switch(config->sampleRate) {
+ case 48000:
+ frames_per_superframe=6;
+ break;
+ case 32000:
+ frames_per_superframe=4;
+ break;
+ case 24000:
+ frames_per_superframe=3;
+ break;
+ case 16000:
+ frames_per_superframe=2;
+ break;
+ }
+
+ //config->nSubFrames = frames_per_superframe;
+ //fprintf(stderr, "DAB+ superframe size=%d\n", superframe_size);
+ config->bitRate = (superframe_size - 16*(frames_per_superframe-1) - staticBits) * 1000/120;
+ //fprintf(stderr, "DAB+ tuned bitrate=%d\n", config->bitRate);
+ config->maxBitsPerFrame = (superframe_size - 16*(frames_per_superframe-1) - staticBits) / frames_per_superframe;
+ config->maxBitsPerFrame += 7; /*padding*/
+ //config->bitreservoir=(superframe_size - 16*(frames_per_superframe-1) - staticBits - 2*8)/frames_per_superframe;
+ //fprintf(stderr, "DAB+ tuned maxBitsPerFrame=%d\n", (superframe_size - 16*(frames_per_superframe-1) - staticBits)/frames_per_superframe);
+ }
+
+ /* check bit rate */
+
+ if (FDKaacEnc_LimitBitrate(
+ hTpEnc, config->audioObjectType, config->sampleRate,
+ config->framelength, config->nChannels,
+ FDKaacEnc_GetChannelModeConfiguration(config->channelMode)
+ ->nChannelsEff,
+ config->bitRate, config->averageBits, &averageBitsPerFrame,
+ config->bitrateMode, config->nSubFrames) != config->bitRate &&
+ !(AACENC_BR_MODE_IS_VBR(config->bitrateMode))) {
+ return AAC_ENC_UNSUPPORTED_BITRATE;
+ }
+
+ if (config->syntaxFlags & AC_ER_VCB11) {
+ return AAC_ENC_UNSUPPORTED_ER_FORMAT;
+ }
+ if (config->syntaxFlags & AC_ER_HCR) {
+ return AAC_ENC_UNSUPPORTED_ER_FORMAT;
+ }
+
+ /* check frame length */
+ switch (config->framelength) {
+ case 1024:
+ case 960:
+ if (isLowDelay(config->audioObjectType)) {
+ return AAC_ENC_INVALID_FRAME_LENGTH;
+ }
+ break;
+ case 128:
+ case 256:
+ case 512:
+ case 120:
+ case 240:
+ case 480:
+ if (!isLowDelay(config->audioObjectType)) {
+ return AAC_ENC_INVALID_FRAME_LENGTH;
+ }
+ break;
+ default:
+ return AAC_ENC_INVALID_FRAME_LENGTH;
+ }
+
+ if (config->anc_Rate != 0) {
+ ErrorStatus = FDKaacEnc_InitCheckAncillary(
+ config->bitRate, config->framelength, config->anc_Rate,
+ &hAacEnc->ancillaryBitsPerFrame, config->sampleRate);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ /* update estimated consumed bitrate */
+ config->ancDataBitRate +=
+ FDKaacEnc_CalcBitrate(hAacEnc->ancillaryBitsPerFrame,
+ config->framelength, config->sampleRate);
+ }
+
+ /* maximal allowed DSE bytes in frame */
+ config->maxAncBytesPerAU =
+ fMin((256), fMax(0, FDKaacEnc_CalcBitsPerFrame(
+ (config->bitRate - (config->nChannels * 8000)),
+ config->framelength, config->sampleRate) >>
+ 3));
+
+ /* bind config to hAacEnc->config */
+ hAacEnc->config = config;
+
+ /* set hAacEnc->bitrateMode */
+ hAacEnc->bitrateMode = config->bitrateMode;
+
+ hAacEnc->encoderMode = config->channelMode;
+
+ ErrorStatus = FDKaacEnc_InitChannelMapping(
+ hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ cm = &hAacEnc->channelMapping;
+
+ ErrorStatus = FDKaacEnc_DetermineBandWidth(
+ config->bandWidth, config->bitRate - config->ancDataBitRate,
+ hAacEnc->bitrateMode, config->sampleRate, config->framelength, cm,
+ hAacEnc->encoderMode, &hAacEnc->config->bandWidth);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ hAacEnc->bandwidth90dB = (INT)hAacEnc->config->bandWidth;
+
+ tnsMask = config->useTns ? TNS_ENABLE_MASK : 0x0;
+ psyBitrate = config->bitRate - config->ancDataBitRate;
+
+ if ((hAacEnc->encoderMode != prevChannelMode) || (initFlags != 0)) {
+ /* Reinitialize psych states in case of channel configuration change ore if
+ * full reset requested. */
+ ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, hAacEnc->psyOut,
+ hAacEnc->maxFrames, hAacEnc->maxChannels,
+ config->audioObjectType, cm);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+ }
+
+ ErrorStatus = FDKaacEnc_psyMainInit(
+ hAacEnc->psyKernel, config->audioObjectType, cm, config->sampleRate,
+ config->framelength, psyBitrate, tnsMask, hAacEnc->bandwidth90dB,
+ config->usePns, config->useIS, config->useMS, config->syntaxFlags,
+ initFlags);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ ErrorStatus = FDKaacEnc_QCOutInit(hAacEnc->qcOut, hAacEnc->maxFrames, cm);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ qcInit.channelMapping = &hAacEnc->channelMapping;
+ qcInit.sceCpe = 0;
+
+ if (AACENC_BR_MODE_IS_VBR(config->bitrateMode)) {
+ qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
+ qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
+ qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
+ 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 {
+ INT bitreservoir = -1; /* default bitrservoir size*/
+ if (isLowDelay(config->audioObjectType)) {
+ INT brPerChannel = config->bitRate / config->nChannels;
+ brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
+
+ /* bitreservoir =
+ * (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes;
+ */
+ 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 */
+ bitreservoir = bitreservoir & ~7; /* align to bytes */
+ bitresMin = BITRES_MIN_LD;
+ }
+
+ int maxBitres;
+ qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
+ maxBitres =
+ (MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff) - qcInit.averageBits;
+ qcInit.bitRes =
+ (bitreservoir != -1) ? fMin(bitreservoir, maxBitres) : maxBitres;
+
+ 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 =
+ 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 = (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.isLowDelay = isLowDelay(config->audioObjectType) ? 1 : 0;
+ qcInit.nSubFrames = config->nSubFrames;
+ qcInit.padding.paddingRest = config->sampleRate;
+
+ if (qcInit.bitRes >= bitresMin * config->nChannels) {
+ qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
+ } else if (qcInit.bitRes > 0) {
+ qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
+ } else {
+ qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */
+ }
+
+ /* Configure bitrate distribution strategy. */
+ switch (config->channelMode) {
+ case MODE_1_2:
+ case MODE_1_2_1:
+ case MODE_1_2_2:
+ case MODE_1_2_2_1:
+ case MODE_6_1:
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_BACK:
+ case MODE_7_1_TOP_FRONT:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER:
+ qcInit.bitDistributionMode = 0; /* over all elements bitrate estimation */
+ break;
+ case MODE_1:
+ case MODE_2:
+ default: /* all non mpeg defined channel modes */
+ qcInit.bitDistributionMode = 1; /* element-wise bit bitrate estimation */
+ } /* config->channelMode */
+
+ /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG *
+ * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */
+ bw_ratio =
+ fDivNorm((FIXP_DBL)(10 * config->framelength * hAacEnc->bandwidth90dB),
+ (FIXP_DBL)(config->sampleRate), &qbw);
+ qcInit.meanPe =
+ fMax((INT)scaleValue(bw_ratio, qbw + 1 - (DFRACT_BITS - 1)), 1);
+
+ /* Calc maxBitFac, scale it to 24 bit accuracy */
+ mbfac = fDivNorm(qcInit.maxBits, qcInit.averageBits / qcInit.nSubFrames,
+ &mbfac_e);
+ qcInit.maxBitFac = scaleValue(mbfac, -(DFRACT_BITS - 1 - 24 - mbfac_e));
+
+ switch (config->bitrateMode) {
+ case AACENC_BR_MODE_CBR:
+ qcInit.bitrateMode = QCDATA_BR_MODE_CBR;
+ break;
+ case AACENC_BR_MODE_VBR_1:
+ qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1;
+ break;
+ case AACENC_BR_MODE_VBR_2:
+ qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2;
+ break;
+ case AACENC_BR_MODE_VBR_3:
+ qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3;
+ break;
+ case AACENC_BR_MODE_VBR_4:
+ qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4;
+ break;
+ case AACENC_BR_MODE_VBR_5:
+ qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5;
+ break;
+ case AACENC_BR_MODE_SFR:
+ qcInit.bitrateMode = QCDATA_BR_MODE_SFR;
+ break;
+ case AACENC_BR_MODE_FF:
+ qcInit.bitrateMode = QCDATA_BR_MODE_FF;
+ break;
+ default:
+ ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE;
+ goto bail;
+ }
+
+ qcInit.invQuant = (config->useRequant) ? 2 : 0;
+
+ /* maxIterations should be set to the maximum number of requantization
+ * iterations that are allowed before the crash recovery functionality is
+ * activated. This setting should be adjusted to the processing power
+ * available, i.e. to the processing power headroom in one frame that is still
+ * left after normal encoding without requantization. Please note that if
+ * activated this functionality is used most likely only in cases where the
+ * encoder is operating beyond recommended settings, i.e. the audio quality is
+ * suboptimal anyway. Activating the crash recovery does not further reduce
+ * audio quality significantly in these cases. */
+ if (isLowDelay(config->audioObjectType)) {
+ qcInit.maxIterations = 2;
+ } else {
+ qcInit.maxIterations = 5;
+ }
+
+ qcInit.bitrate = config->bitRate - config->ancDataBitRate;
+
+ qcInit.staticBits = transportEnc_GetStaticBits(
+ hTpEnc, qcInit.averageBits / qcInit.nSubFrames);
+
+ ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit, initFlags);
+ if (ErrorStatus != AAC_ENC_OK) goto bail;
+
+ /* Map virtual aot's to intern aot used in bitstream writer. */
+ switch (hAacEnc->config->audioObjectType) {
+ case AOT_MP2_AAC_LC:
+ hAacEnc->aot = AOT_AAC_LC;
+ break;
+ case AOT_MP2_SBR:
+ hAacEnc->aot = AOT_SBR;
+ break;
+ default:
+ hAacEnc->aot = hAacEnc->config->audioObjectType;
+ }
+
+ /* common things */
+
+ return AAC_ENC_OK;
+
+bail:
+
+ return ErrorStatus;
+}
+
+/*---------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_EncodeFrame
+ description: encodes one frame
+ returns: error code
+
+ ---------------------------------------------------------------------------*/
+AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame(
+ HANDLE_AAC_ENC hAacEnc, /* encoder handle */
+ HANDLE_TRANSPORTENC hTpEnc, INT_PCM *RESTRICT inputBuffer,
+ const UINT inputBufferBufSize, INT *nOutBytes,
+ AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ int el, n, c = 0;
+ UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS];
+
+ CHANNEL_MAPPING *cm = &hAacEnc->channelMapping;
+
+ PSY_OUT *psyOut = hAacEnc->psyOut[c];
+ QC_OUT *qcOut = hAacEnc->qcOut[c];
+
+ FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR));
+
+ qcOut->elementExtBits = 0; /* sum up all extended bit of each element */
+ qcOut->staticBits = 0; /* sum up side info bits of each element */
+ qcOut->totalNoRedPe = 0; /* sum up PE */
+
+ /* advance psychoacoustics */
+ for (el = 0; el < cm->nElements; el++) {
+ ELEMENT_INFO elInfo = cm->elInfo[el];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ int ch;
+
+ /* update pointer!*/
+ for (ch = 0; ch < elInfo.nChannelsInEl; ch++) {
+ PSY_OUT_CHANNEL *psyOutChan =
+ psyOut->psyOutElement[el]->psyOutChannel[ch];
+ QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch];
+
+ psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum;
+ psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy;
+ psyOutChan->sfbEnergy = qcOutChan->sfbEnergy;
+ psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData;
+ psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData;
+ psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData;
+ }
+
+ ErrorStatus = FDKaacEnc_psyMain(
+ elInfo.nChannelsInEl, hAacEnc->psyKernel->psyElement[el],
+ hAacEnc->psyKernel->psyDynamic, hAacEnc->psyKernel->psyConf,
+ psyOut->psyOutElement[el], inputBuffer, inputBufferBufSize,
+ cm->elInfo[el].ChannelIndex, cm->nChannels);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ /* FormFactor, Pe and staticBitDemand calculation */
+ ErrorStatus = FDKaacEnc_QCMainPrepare(
+ &elInfo, hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el],
+ psyOut->psyOutElement[el], qcOut->qcElement[el], hAacEnc->aot,
+ hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ /*-------------------------------------------- */
+
+ qcOut->qcElement[el]->extBitsUsed = 0;
+ qcOut->qcElement[el]->nExtensions = 0;
+ /* reset extension payload */
+ FDKmemclear(&qcOut->qcElement[el]->extension,
+ (1) * sizeof(QC_OUT_EXTENSION));
+
+ for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
+ if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == el) &&
+ (extPayload[n].dataSize > 0) && (extPayload[n].pData != NULL)) {
+ int idx = qcOut->qcElement[el]->nExtensions++;
+
+ qcOut->qcElement[el]->extension[idx].type =
+ extPayload[n].dataType; /* Perform a sanity check on the type? */
+ qcOut->qcElement[el]->extension[idx].nPayloadBits =
+ extPayload[n].dataSize;
+ qcOut->qcElement[el]->extension[idx].pPayload = extPayload[n].pData;
+ /* Now ask the bitstream encoder how many bits we need to encode the
+ * data with the current bitstream syntax: */
+ qcOut->qcElement[el]->extBitsUsed += FDKaacEnc_writeExtensionData(
+ NULL, &qcOut->qcElement[el]->extension[idx], 0, 0,
+ hAacEnc->config->syntaxFlags, hAacEnc->aot,
+ hAacEnc->config->epConfig);
+ extPayloadUsed[n] = 1;
+ }
+ }
+
+ /* sum up extension and static bits for all channel elements */
+ qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed;
+ qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed;
+
+ /* sum up pe */
+ qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe;
+ }
+ }
+
+ qcOut->nExtensions = 0;
+ qcOut->globalExtBits = 0;
+
+ /* reset extension payload */
+ FDKmemclear(&qcOut->extension, (2 + 2) * sizeof(QC_OUT_EXTENSION));
+
+ /* Add extension payload not assigned to an channel element
+ (Ancillary data is the only supported type up to now) */
+ for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
+ if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == -1) &&
+ (extPayload[n].pData != NULL)) {
+ UINT payloadBits = 0;
+
+ if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
+ if (hAacEnc->ancillaryBitsPerFrame) {
+ /* granted frame dse bitrate */
+ payloadBits = hAacEnc->ancillaryBitsPerFrame;
+ } else {
+ /* write anc data if bitrate constraint fulfilled */
+ if ((extPayload[n].dataSize >> 3) <=
+ hAacEnc->config->maxAncBytesPerAU) {
+ payloadBits = extPayload[n].dataSize;
+ }
+ }
+ payloadBits = fixMin(extPayload[n].dataSize, payloadBits);
+ } else {
+ payloadBits = extPayload[n].dataSize;
+ }
+
+ if (payloadBits > 0) {
+ int idx = qcOut->nExtensions++;
+
+ qcOut->extension[idx].type =
+ extPayload[n].dataType; /* Perform a sanity check on the type? */
+ qcOut->extension[idx].nPayloadBits = payloadBits;
+ qcOut->extension[idx].pPayload = extPayload[n].pData;
+ /* Now ask the bitstream encoder how many bits we need to encode the
+ * data with the current bitstream syntax: */
+ qcOut->globalExtBits += FDKaacEnc_writeExtensionData(
+ NULL, &qcOut->extension[idx], 0, 0, hAacEnc->config->syntaxFlags,
+ hAacEnc->aot, hAacEnc->config->epConfig);
+ if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
+ /* substract the processed bits */
+ extPayload[n].dataSize -= payloadBits;
+ }
+ extPayloadUsed[n] = 1;
+ }
+ }
+ }
+
+ if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE | AC_ER))) {
+ qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */
+ }
+
+ /* build bitstream all nSubFrames */
+ {
+ INT totalBits = 0; /* Total AU bits */
+ ;
+ INT avgTotalBits = 0;
+
+ /*-------------------------------------------- */
+ /* Get average total bits */
+ /*-------------------------------------------- */
+ {
+ /* frame wise bitrate adaption */
+ FDKaacEnc_AdjustBitrate(
+ hAacEnc->qcKernel, cm, &avgTotalBits, hAacEnc->config->bitRate,
+ hAacEnc->config->sampleRate, hAacEnc->config->framelength);
+
+ /* adjust super frame bitrate */
+ avgTotalBits *= hAacEnc->config->nSubFrames;
+ }
+
+ /* Make first estimate of transport header overhead.
+ Take maximum possible frame size into account to prevent bitreservoir
+ underrun. */
+ hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits(
+ hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot);
+
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+
+ ErrorStatus = FDKaacEnc_QCMain(
+ hAacEnc->qcKernel, hAacEnc->psyOut, hAacEnc->qcOut, avgTotalBits, cm,
+ hAacEnc->aot, hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+ /*-------------------------------------------- */
+
+ /*-------------------------------------------- */
+ ErrorStatus = FDKaacEnc_updateFillBits(
+ cm, hAacEnc->qcKernel, hAacEnc->qcKernel->elementBits, hAacEnc->qcOut);
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ /*-------------------------------------------- */
+ ErrorStatus = FDKaacEnc_FinalizeBitConsumption(
+ cm, hAacEnc->qcKernel, qcOut, qcOut->qcElement, hTpEnc, hAacEnc->aot,
+ hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+ /*-------------------------------------------- */
+ totalBits += qcOut->totalBits;
+
+ /*-------------------------------------------- */
+ FDKaacEnc_updateBitres(cm, hAacEnc->qcKernel, hAacEnc->qcOut);
+
+ /*-------------------------------------------- */
+
+ /* for ( all sub frames ) ... */
+ /* write bitstream header */
+ if (TRANSPORTENC_OK !=
+ transportEnc_WriteAccessUnit(hTpEnc, totalBits,
+ FDKaacEnc_EncBitresToTpBitres(hAacEnc),
+ cm->nChannelsEff)) {
+ return AAC_ENC_UNKNOWN;
+ }
+
+ /* write bitstream */
+ ErrorStatus = FDKaacEnc_WriteBitstream(
+ hTpEnc, cm, qcOut, psyOut, hAacEnc->qcKernel, hAacEnc->aot,
+ hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ /* transportEnc_EndAccessUnit() is being called inside
+ * FDKaacEnc_WriteBitstream() */
+ if (TRANSPORTENC_OK != transportEnc_GetFrame(hTpEnc, nOutBytes)) {
+ return AAC_ENC_UNKNOWN;
+ }
+
+ } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */
+
+ /*-------------------------------------------- */
+ return AAC_ENC_OK;
+}
+
+/*---------------------------------------------------------------------------
+
+ functionname:FDKaacEnc_Close
+ description: delete encoder instance
+ returns:
+
+ ---------------------------------------------------------------------------*/
+
+void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc) /* encoder handle */
+{
+ if (*phAacEnc == NULL) {
+ return;
+ }
+ AAC_ENC *hAacEnc = (AAC_ENC *)*phAacEnc;
+
+ if (hAacEnc->dynamic_RAM != NULL) FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM);
+
+ FDKaacEnc_PsyClose(&hAacEnc->psyKernel, hAacEnc->psyOut);
+
+ FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut);
+
+ FreeRam_aacEnc_AacEncoder(phAacEnc);
+}
+
+/* The following functions are in this source file only for convenience and */
+/* need not be visible outside of a possible encoder library. */
+
+/* basic defines for ancillary data */
+#define MAX_ANCRATE 19200 /* ancillary rate >= 19200 isn't valid */
+
+/*---------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_InitCheckAncillary
+ description: initialize and check ancillary data struct
+ return: if success or NULL if error
+
+ ---------------------------------------------------------------------------*/
+static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
+ INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
+ INT sampleRate) {
+ /* don't use negative ancillary rates */
+ if (ancillaryRate < -1) return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
+
+ /* check if ancillary rate is ok */
+ if ((ancillaryRate != (-1)) && (ancillaryRate != 0)) {
+ /* ancRate <= 15% of bitrate && ancRate < 19200 */
+ if ((ancillaryRate >= MAX_ANCRATE) ||
+ ((ancillaryRate * 20) > (bitRate * 3))) {
+ return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
+ }
+ } else if (ancillaryRate == -1) {
+ /* if no special ancRate is requested but a ancillary file is
+ stated, then generate a ancillary rate matching to the bitrate */
+ if (bitRate >= (MAX_ANCRATE * 10)) {
+ /* ancillary rate is 19199 */
+ ancillaryRate = (MAX_ANCRATE - 1);
+ } else { /* 10% of bitrate */
+ ancillaryRate = bitRate / 10;
+ }
+ }
+
+ /* make ancillaryBitsPerFrame byte align */
+ *ancillaryBitsPerFrame =
+ FDKaacEnc_CalcBitsPerFrame(ancillaryRate, framelength, sampleRate) & ~0x7;
+
+ return AAC_ENC_OK;
+}
diff --git a/fdk-aac/libAACenc/src/aacenc.h b/fdk-aac/libAACenc/src/aacenc.h
new file mode 100644
index 0000000..291ea54
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc.h
@@ -0,0 +1,394 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Schug / A. Groeschel
+
+ Description: fast aac coder interface library functions
+
+*******************************************************************************/
+
+#ifndef AACENC_H
+#define AACENC_H
+
+#include "common_fix.h"
+#include "FDK_audio.h"
+
+#include "tpenc_lib.h"
+
+#include "sbr_encoder.h"
+
+#define MIN_BUFSIZE_PER_EFF_CHAN 6144
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * AAC-LC error codes.
+ */
+typedef enum {
+ AAC_ENC_OK = 0x0000, /*!< All fine. */
+
+ AAC_ENC_UNKNOWN = 0x0002, /*!< Error condition is of unknown reason, or from
+ another module. */
+
+ /* initialization errors */
+ aac_enc_init_error_start = 0x2000,
+ AAC_ENC_INVALID_HANDLE = 0x2020, /*!< The handle passed to the function call
+ was invalid (probably NULL). */
+ AAC_ENC_INVALID_FRAME_LENGTH =
+ 0x2080, /*!< Invalid frame length (must be 1024 or 960). */
+ AAC_ENC_INVALID_N_CHANNELS =
+ 0x20e0, /*!< Invalid amount of audio input channels. */
+ AAC_ENC_INVALID_SFB_TABLE = 0x2140, /*!< Internal encoder error. */
+
+ AAC_ENC_UNSUPPORTED_AOT =
+ 0x3000, /*!< The Audio Object Type (AOT) is not supported. */
+ AAC_ENC_UNSUPPORTED_FILTERBANK =
+ 0x3010, /*!< Filterbank type is not supported. */
+ AAC_ENC_UNSUPPORTED_BITRATE =
+ 0x3020, /*!< The chosen bitrate is not supported. */
+ AAC_ENC_UNSUPPORTED_BITRATE_MODE =
+ 0x3028, /*!< Unsupported bit rate mode (CBR or VBR). */
+ AAC_ENC_UNSUPPORTED_ANC_BITRATE =
+ 0x3040, /*!< Unsupported ancillay bitrate. */
+ AAC_ENC_UNSUPPORTED_ANC_MODE = 0x3060,
+ AAC_ENC_UNSUPPORTED_TRANSPORT_TYPE =
+ 0x3080, /*!< The bitstream format is not supported. */
+ AAC_ENC_UNSUPPORTED_ER_FORMAT =
+ 0x30a0, /*!< The error resilience tool format is not supported. */
+ AAC_ENC_UNSUPPORTED_EPCONFIG =
+ 0x30c0, /*!< The error protection format is not supported. */
+ AAC_ENC_UNSUPPORTED_CHANNELCONFIG =
+ 0x30e0, /*!< The channel configuration (either number or arrangement) is
+ not supported. */
+ AAC_ENC_UNSUPPORTED_SAMPLINGRATE =
+ 0x3100, /*!< Sample rate of audio input is not supported. */
+ AAC_ENC_NO_MEMORY = 0x3120, /*!< Could not allocate memory. */
+ AAC_ENC_PE_INIT_TABLE_NOT_FOUND = 0x3140, /*!< Internal encoder error. */
+
+ aac_enc_init_error_end,
+
+ /* encode errors */
+ aac_enc_error_start = 0x4000,
+ AAC_ENC_QUANT_ERROR = 0x4020, /*!< Too many bits used in quantization. */
+ AAC_ENC_WRITTEN_BITS_ERROR =
+ 0x4040, /*!< Unexpected number of written bits, differs to
+ calculated number of bits. */
+ AAC_ENC_PNS_TABLE_ERROR = 0x4060, /*!< PNS level out of range. */
+ AAC_ENC_GLOBAL_GAIN_TOO_HIGH = 0x4080, /*!< Internal quantizer error. */
+ AAC_ENC_BITRES_TOO_LOW = 0x40a0, /*!< Too few bits in bit reservoir. */
+ AAC_ENC_BITRES_TOO_HIGH = 0x40a1, /*!< Too many bits in bit reservoir. */
+ AAC_ENC_INVALID_CHANNEL_BITRATE = 0x4100,
+ AAC_ENC_INVALID_ELEMENTINFO_TYPE = 0x4120, /*!< Internal encoder error. */
+
+ AAC_ENC_WRITE_SCAL_ERROR = 0x41e0, /*!< Error writing scalefacData. */
+ AAC_ENC_WRITE_SEC_ERROR = 0x4200, /*!< Error writing sectionData. */
+ AAC_ENC_WRITE_SPEC_ERROR = 0x4220, /*!< Error writing spectralData. */
+ aac_enc_error_end
+
+} AAC_ENCODER_ERROR;
+/*-------------------------- defines --------------------------------------*/
+
+#define ANC_DATA_BUFFERSIZE 1024 /* ancBuffer size */
+
+#define MAX_TOTAL_EXT_PAYLOADS ((((8)) * (1)) + (2 + 2))
+
+typedef enum {
+ AACENC_BR_MODE_INVALID = -1, /*!< Invalid bitrate mode. */
+ AACENC_BR_MODE_CBR = 0, /*!< Constant bitrate mode. */
+ AACENC_BR_MODE_VBR_1 = 1, /*!< Variable bitrate mode, very low bitrate. */
+ AACENC_BR_MODE_VBR_2 = 2, /*!< Variable bitrate mode, low bitrate. */
+ AACENC_BR_MODE_VBR_3 = 3, /*!< Variable bitrate mode, medium bitrate. */
+ AACENC_BR_MODE_VBR_4 = 4, /*!< Variable bitrate mode, high bitrate. */
+ AACENC_BR_MODE_VBR_5 = 5, /*!< Variable bitrate mode, very high bitrate. */
+ AACENC_BR_MODE_FF = 6, /*!< Fixed frame mode. */
+ AACENC_BR_MODE_SFR = 7 /*!< Superframe mode. */
+
+} AACENC_BITRATE_MODE;
+
+#define AACENC_BR_MODE_IS_VBR(brMode) ((brMode >= 1) && (brMode <= 5))
+
+typedef enum {
+
+ CH_ORDER_MPEG =
+ 0, /*!< MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE) */
+ CH_ORDER_WAV, /*!< WAV fileformat channel ordering (e. g. 5.1: L, R, C, LFE,
+ SL, SR) */
+ CH_ORDER_WG4 /*!< WG4 fileformat channel ordering (e. g. 5.1: L, R, SL, SR, C, LFE) */
+
+} CHANNEL_ORDER;
+
+/*-------------------- structure definitions ------------------------------*/
+
+struct AACENC_CONFIG {
+ INT sampleRate; /* encoder sample rate */
+ INT bitRate; /* encoder bit rate in bits/sec */
+ INT ancDataBitRate; /* additional bits consumed by anc data or sbr have to be
+ consiedered while configuration */
+
+ INT nSubFrames; /* number of frames in super frame (not ADTS/LATM subframes !)
+ */
+ AUDIO_OBJECT_TYPE audioObjectType; /* Audio Object Type */
+
+ INT averageBits; /* encoder bit rate in bits/superframe */
+ AACENC_BITRATE_MODE bitrateMode; /* encoder bitrate mode (CBR/VBR) */
+ INT nChannels; /* number of channels to process */
+ CHANNEL_ORDER channelOrder; /* input Channel ordering scheme. */
+ INT bandWidth; /* targeted audio bandwidth in Hz */
+ CHANNEL_MODE channelMode; /* encoder channel mode configuration */
+ INT framelength; /* used frame size */
+
+ UINT syntaxFlags; /* bitstreams syntax configuration */
+ SCHAR epConfig; /* error protection configuration */
+
+ INT anc_Rate; /* ancillary rate, 0 (disabled), -1 (default) else desired rate
+ */
+ UINT maxAncBytesPerAU;
+ INT minBitsPerFrame; /* minimum number of bits in AU */
+ INT maxBitsPerFrame; /* maximum number of bits in AU */
+
+ INT audioMuxVersion; /* audio mux version in loas/latm transport format */
+
+ UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */
+
+ UCHAR useTns; /* flag: use temporal noise shaping */
+ UCHAR usePns; /* flag: use perceptual noise substitution */
+ UCHAR useIS; /* flag: use intensity coding */
+ UCHAR useMS; /* flag: use ms stereo tool */
+
+ UCHAR useRequant; /* flag: use afterburner */
+
+ UINT downscaleFactor;
+};
+
+typedef struct {
+ UCHAR *pData; /* pointer to extension payload data */
+ UINT dataSize; /* extension payload data size in bits */
+ EXT_PAYLOAD_TYPE dataType; /* extension payload data type */
+ INT associatedChElement; /* number of the channel element the data is assigned
+ to */
+} AACENC_EXT_PAYLOAD;
+
+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
+ * \param hTpEnc transport encoder handle
+ * \param aot audio object type
+ * \param coreSamplingRate the sample rate to be used for the AAC encoder
+ * \param frameLength the frameLength to be used for the AAC encoder
+ * \param nChannels number of total channels
+ * \param nChannelsEff number of effective channels
+ * \param bitRate the initial bit rate value for which the closest valid bit
+ * rate value is searched for
+ * \param averageBits average bits per frame for fixed framing. Set to -1 if not
+ * available.
+ * \param optional pointer where the current bits per frame are stored into.
+ * \param bitrateMode the current bit rate mode
+ * \param nSubFrames number of sub frames for super framing (not transport
+ * frames).
+ * \return a valid bit rate value as close as possible or identical to bitRate
+ */
+INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot,
+ INT coreSamplingRate, INT frameLength, INT nChannels,
+ INT nChannelsEff, INT bitRate, INT averageBits,
+ INT *pAverageBitsPerFrame,
+ AACENC_BITRATE_MODE bitrateMode, INT nSubFrames);
+
+/**
+ * \brief Get current state of the bit reservoir
+ * \param hAacEncoder encoder handle
+ * \return bit reservoir state in bits
+ */
+INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder);
+
+/*-----------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_GetVBRBitrate
+ description: Get VBR bitrate from vbr quality
+ input params: int vbrQuality (VBR0, VBR1, VBR2)
+ channelMode
+ returns: vbr bitrate
+
+------------------------------------------------------------------------------*/
+INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,
+ CHANNEL_MODE channelMode);
+
+/*-----------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_AacInitDefaultConfig
+ description: gives reasonable default configuration
+ returns: ---
+
+ ------------------------------------------------------------------------------*/
+void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config);
+
+/*---------------------------------------------------------------------------
+
+ functionname:FDKaacEnc_Open
+ description: allocate and initialize a new encoder instance
+ returns: 0 if success
+
+ ---------------------------------------------------------------------------*/
+AAC_ENCODER_ERROR FDKaacEnc_Open(
+ HANDLE_AAC_ENC
+ *phAacEnc, /* pointer to an encoder handle, initialized on return */
+ const INT nElements, /* number of maximal elements in instance to support */
+ const INT nChannels, /* number of maximal channels in instance to support */
+ const INT nSubFrames); /* support superframing in instance */
+
+AAC_ENCODER_ERROR FDKaacEnc_Initialize(
+ HANDLE_AAC_ENC
+ hAacEncoder, /* pointer to an encoder handle, initialized on return */
+ AACENC_CONFIG *config, /* pre-initialized config struct */
+ HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags);
+
+/*---------------------------------------------------------------------------
+
+ functionname: FDKaacEnc_EncodeFrame
+ description: encode one frame
+ returns: 0 if success
+
+ ---------------------------------------------------------------------------*/
+
+AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame(
+ HANDLE_AAC_ENC hAacEnc, /* encoder handle */
+ HANDLE_TRANSPORTENC hTpEnc, INT_PCM *inputBuffer,
+ const UINT inputBufferBufSize, INT *numOutBytes,
+ AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]);
+
+/*---------------------------------------------------------------------------
+
+ functionname:FDKaacEnc_Close
+ description: delete encoder instance
+ returns:
+
+ ---------------------------------------------------------------------------*/
+
+void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc); /* encoder handle */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AACENC_H */
diff --git a/fdk-aac/libAACenc/src/aacenc_lib.cpp b/fdk-aac/libAACenc/src/aacenc_lib.cpp
new file mode 100644
index 0000000..aaa6c74
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc_lib.cpp
@@ -0,0 +1,2575 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: FDK HE-AAC Encoder interface library functions
+
+*******************************************************************************/
+#include <stdio.h>
+#include "aacenc_lib.h"
+#include "FDK_audio.h"
+#include "aacenc.h"
+
+#include "aacEnc_ram.h"
+#include "FDK_core.h" /* FDK_tools versioning info */
+
+/* Encoder library info */
+#define AACENCODER_LIB_VL0 4
+#define AACENCODER_LIB_VL1 0
+#define AACENCODER_LIB_VL2 0
+#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_TIME __TIME__
+#endif
+
+#include "pcm_utils.h"
+
+#include "sbr_encoder.h"
+#include "../src/sbrenc_ram.h"
+#include "channel_map.h"
+
+#include "psy_const.h"
+#include "bitenc.h"
+
+#include "tpenc_lib.h"
+
+#include "metadata_main.h"
+#include "mps_main.h"
+#include "sacenc_lib.h"
+
+#define SBL(fl) \
+ (fl / \
+ 8) /*!< Short block length (hardcoded to 8 short blocks per long block) */
+#define BSLA(fl) \
+ (4 * SBL(fl) + SBL(fl) / 2) /*!< AAC block switching look-ahead */
+#define DELAY_AAC(fl) (fl + BSLA(fl)) /*!< MDCT + blockswitching */
+#define DELAY_AACLD(fl) (fl) /*!< MDCT delay (no framing delay included) */
+#define DELAY_AACELD(fl) \
+ ((fl) / 2) /*!< ELD FB delay (no framing delay included) */
+
+#define MAX_DS_DELAY (100) /*!< Maximum downsampler delay in SBR. */
+#define INPUTBUFFER_SIZE \
+ (2 * (1024) + MAX_DS_DELAY + 1537) /*!< Audio input samples + downsampler \
+ delay + sbr/aac delay compensation */
+
+#define DEFAULT_HEADER_PERIOD_REPETITION_RATE \
+ 10 /*!< Default header repetition rate used in transport library and for SBR \
+ header. */
+
+////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Flags to characterize encoder modules to be supported in present instance.
+ */
+enum {
+ ENC_MODE_FLAG_AAC = 0x0001,
+ ENC_MODE_FLAG_SBR = 0x0002,
+ ENC_MODE_FLAG_PS = 0x0004,
+ ENC_MODE_FLAG_SAC = 0x0008,
+ ENC_MODE_FLAG_META = 0x0010
+};
+
+////////////////////////////////////////////////////////////////////////////////////
+typedef struct {
+ AUDIO_OBJECT_TYPE userAOT; /*!< Audio Object Type. */
+ UINT userSamplerate; /*!< Sampling frequency. */
+ UINT nChannels; /*!< will be set via channelMode. */
+ CHANNEL_MODE userChannelMode;
+ UINT userBitrate;
+ UINT userBitrateMode;
+ UINT userBandwidth;
+ UINT userAfterburner;
+ UINT userFramelength;
+ UINT userAncDataRate;
+ UINT userPeakBitrate;
+
+ UCHAR userTns; /*!< Use TNS coding. */
+ UCHAR userPns; /*!< Use PNS coding. */
+ UCHAR userIntensity; /*!< Use Intensity coding. */
+
+ TRANSPORT_TYPE userTpType; /*!< Transport type */
+ UCHAR userTpSignaling; /*!< Extension AOT signaling mode. */
+ UCHAR userTpNsubFrames; /*!< Number of sub frames in a transport frame for
+ LOAS/LATM or ADTS (default 1). */
+ UCHAR userTpAmxv; /*!< AudioMuxVersion to be used for LATM (default 0). */
+ UCHAR userTpProtection;
+ UCHAR userTpHeaderPeriod; /*!< Parameter used to configure LATM/LOAS SMC rate.
+ Moreover this parameters is used to configure
+ repetition rate of PCE in raw_data_block. */
+
+ UCHAR userErTools; /*!< Use VCB11, HCR and/or RVLC ER tool. */
+ UINT userPceAdditions; /*!< Configure additional bits in PCE. */
+
+ UCHAR userMetaDataMode; /*!< Meta data library configuration. */
+
+ UCHAR userSbrEnabled; /*!< Enable SBR for ELD. */
+ UINT userSbrRatio; /*!< SBR sampling rate ratio. Dual- or single-rate. */
+
+ UINT userDownscaleFactor;
+
+} USER_PARAM;
+
+/**
+ * SBR extenxion payload struct provides buffers to be filled in SBR encoder
+ * library.
+ */
+typedef struct {
+ UCHAR data[(1)][(8)][MAX_PAYLOAD_SIZE]; /*!< extension payload data buffer */
+ UINT dataSize[(1)][(8)]; /*!< extension payload data size in bits */
+} SBRENC_EXT_PAYLOAD;
+
+////////////////////////////////////////////////////////////////////////////////////
+
+/****************************************************************************
+ Structure Definitions
+****************************************************************************/
+
+typedef struct AACENC_CONFIG *HANDLE_AACENC_CONFIG;
+
+struct AACENCODER {
+ USER_PARAM extParam;
+ CODER_CONFIG coderConfig;
+
+ /* AAC */
+ AACENC_CONFIG aacConfig;
+ HANDLE_AAC_ENC hAacEnc;
+
+ /* SBR */
+ HANDLE_SBR_ENCODER hEnvEnc; /* SBR encoder */
+ SBRENC_EXT_PAYLOAD *pSbrPayload; /* SBR extension payload */
+
+ /* Meta Data */
+ HANDLE_FDK_METADATA_ENCODER hMetadataEnc;
+ INT metaDataAllowed; /* Signal whether chosen configuration allows metadata.
+ Necessary for delay compensation. Metadata mode is a
+ separate parameter. */
+
+ HANDLE_MPS_ENCODER hMpsEnc;
+
+ /* Transport */
+ HANDLE_TRANSPORTENC hTpEnc;
+
+ INT_PCM
+ *inputBuffer; /* Internal input buffer. Input source for AAC encoder */
+ UCHAR *outBuffer; /* Internal bitstream buffer */
+
+ INT inputBufferSize; /* Size of internal input buffer */
+ INT inputBufferSizePerChannel; /* Size of internal input buffer per channel */
+ INT outBufferInBytes; /* Size of internal bitstream buffer*/
+
+ INT inputBufferOffset; /* Where to write new input samples. */
+
+ INT nSamplesToRead; /* number of input samples neeeded for encoding one frame
+ */
+ INT nSamplesRead; /* number of input samples already in input buffer */
+ INT nZerosAppended; /* appended zeros at end of file*/
+ INT nDelay; /* codec delay */
+ INT nDelayCore; /* codec delay, w/o the SBR decoder delay */
+
+ AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS];
+
+ ULONG InitFlags; /* internal status to treggier re-initialization */
+
+ /* Memory allocation info. */
+ INT nMaxAacElements;
+ INT nMaxAacChannels;
+ INT nMaxSbrElements;
+ INT nMaxSbrChannels;
+
+ UINT encoder_modis;
+
+ /* Capability flags */
+ UINT CAPF_tpEnc;
+};
+
+typedef struct {
+ /* input */
+ ULONG nChannels; /*!< Number of audio channels. */
+ ULONG samplingRate; /*!< Encoder output sampling rate. */
+ ULONG bitrateRange; /*!< Lower bitrate range for config entry. */
+
+ /* output*/
+ UCHAR sbrMode; /*!< 0: ELD sbr off,
+ 1: ELD with downsampled sbr,
+ 2: ELD with dualrate sbr. */
+ CHANNEL_MODE chMode; /*!< Channel mode. */
+
+} ELD_SBR_CONFIGURATOR;
+
+/**
+ * \brief This table defines ELD/SBR default configurations.
+ */
+static const ELD_SBR_CONFIGURATOR eldSbrAutoConfigTab[] = {
+ {1, 48000, 0, 2, MODE_1}, {1, 48000, 64000, 0, MODE_1},
+
+ {1, 44100, 0, 2, MODE_1}, {1, 44100, 64000, 0, MODE_1},
+
+ {1, 32000, 0, 2, MODE_1}, {1, 32000, 28000, 1, MODE_1},
+ {1, 32000, 56000, 0, MODE_1},
+
+ {1, 24000, 0, 1, MODE_1}, {1, 24000, 40000, 0, MODE_1},
+
+ {1, 16000, 0, 1, MODE_1}, {1, 16000, 28000, 0, MODE_1},
+
+ {1, 15999, 0, 0, MODE_1},
+
+ {2, 48000, 0, 2, MODE_2}, {2, 48000, 44000, 2, MODE_2},
+ {2, 48000, 128000, 0, MODE_2},
+
+ {2, 44100, 0, 2, MODE_2}, {2, 44100, 44000, 2, MODE_2},
+ {2, 44100, 128000, 0, MODE_2},
+
+ {2, 32000, 0, 2, MODE_2}, {2, 32000, 32000, 2, MODE_2},
+ {2, 32000, 68000, 1, MODE_2}, {2, 32000, 96000, 0, MODE_2},
+
+ {2, 24000, 0, 1, MODE_2}, {2, 24000, 48000, 1, MODE_2},
+ {2, 24000, 80000, 0, MODE_2},
+
+ {2, 16000, 0, 1, MODE_2}, {2, 16000, 32000, 1, MODE_2},
+ {2, 16000, 64000, 0, MODE_2},
+
+ {2, 15999, 0, 0, MODE_2}
+
+};
+
+/*
+ * \brief Configure SBR for ELD configuration.
+ *
+ * This function finds default SBR configuration for ELD based on number of
+ * channels, sampling rate and bitrate.
+ *
+ * \param nChannels Number of audio channels.
+ * \param samplingRate Audio signal sampling rate.
+ * \param bitrate Encoder bitrate.
+ *
+ * \return - pointer to eld sbr configuration.
+ * - NULL, on failure.
+ */
+static const ELD_SBR_CONFIGURATOR *eldSbrConfigurator(const ULONG nChannels,
+ const ULONG samplingRate,
+ const ULONG bitrate) {
+ int i;
+ const ELD_SBR_CONFIGURATOR *pSetup = NULL;
+
+ for (i = 0;
+ i < (int)(sizeof(eldSbrAutoConfigTab) / sizeof(ELD_SBR_CONFIGURATOR));
+ i++) {
+ if ((nChannels == eldSbrAutoConfigTab[i].nChannels) &&
+ (samplingRate <= eldSbrAutoConfigTab[i].samplingRate) &&
+ (bitrate >= eldSbrAutoConfigTab[i].bitrateRange)) {
+ pSetup = &eldSbrAutoConfigTab[i];
+ }
+ }
+
+ return pSetup;
+}
+
+static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) {
+ INT sbrUsed = 0;
+
+ /* Note: Even if implicit signalling was selected, The AOT itself here is not
+ * AOT_AAC_LC */
+ if ((hAacConfig->audioObjectType == AOT_SBR) ||
+ (hAacConfig->audioObjectType == AOT_PS) ||
+ (hAacConfig->audioObjectType == AOT_MP2_SBR) ||
+ (hAacConfig->audioObjectType == AOT_DABPLUS_SBR) ||
+ (hAacConfig->audioObjectType == AOT_DABPLUS_PS)) {
+ sbrUsed = 1;
+ }
+ if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD &&
+ (hAacConfig->syntaxFlags & AC_SBR_PRESENT)) {
+ sbrUsed = 1;
+ }
+
+ return (sbrUsed);
+}
+
+static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType) {
+ INT psUsed = 0;
+
+ if ((audioObjectType == AOT_PS) ||
+ (audioObjectType == AOT_DABPLUS_PS)) {
+ psUsed = 1;
+ }
+
+ return (psUsed);
+}
+
+static CHANNEL_MODE GetCoreChannelMode(
+ const CHANNEL_MODE channelMode, const AUDIO_OBJECT_TYPE audioObjectType) {
+ CHANNEL_MODE mappedChannelMode = channelMode;
+ if ((isPsActive(audioObjectType) && (channelMode == MODE_2)) ||
+ (channelMode == MODE_212)) {
+ mappedChannelMode = MODE_1;
+ }
+ return mappedChannelMode;
+}
+
+static SBR_PS_SIGNALING getSbrSignalingMode(
+ const AUDIO_OBJECT_TYPE audioObjectType, const TRANSPORT_TYPE transportType,
+ const UCHAR transportSignaling, const UINT sbrRatio)
+
+{
+ SBR_PS_SIGNALING sbrSignaling;
+
+ if (transportType == TT_UNKNOWN || sbrRatio == 0) {
+ sbrSignaling = SIG_UNKNOWN; /* Needed parameters have not been set */
+ return sbrSignaling;
+ } else {
+ sbrSignaling =
+ SIG_EXPLICIT_HIERARCHICAL; /* default: explicit hierarchical signaling
+ */
+ }
+
+ if ((audioObjectType == AOT_AAC_LC) || (audioObjectType == AOT_SBR) ||
+ (audioObjectType == AOT_PS) || (audioObjectType == AOT_MP2_AAC_LC) ||
+ (audioObjectType == AOT_MP2_SBR) ||
+ (audioObjectType == AOT_DABPLUS_SBR) ||
+ (audioObjectType == AOT_DABPLUS_PS)) {
+ switch (transportType) {
+ case TT_MP4_ADIF:
+ case TT_MP4_ADTS:
+ sbrSignaling = SIG_IMPLICIT; /* For MPEG-2 transport types, only
+ implicit signaling is possible */
+ break;
+
+ case TT_MP4_RAW:
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LOAS:
+ default:
+ if (transportSignaling == 0xFF) {
+ /* Defaults */
+ sbrSignaling = SIG_EXPLICIT_HIERARCHICAL;
+ } else {
+ /* User set parameters */
+ /* Attention: Backward compatible explicit signaling does only work
+ * with AMV1 for LATM/LOAS */
+ sbrSignaling = (SBR_PS_SIGNALING)transportSignaling;
+ }
+ break;
+ }
+ }
+
+ return sbrSignaling;
+}
+
+/****************************************************************************
+ Allocate Encoder
+****************************************************************************/
+
+H_ALLOC_MEM(_AacEncoder, AACENCODER)
+C_ALLOC_MEM(_AacEncoder, struct AACENCODER, 1)
+
+/*
+ * Map Encoder specific config structures to CODER_CONFIG.
+ */
+static void FDKaacEnc_MapConfig(CODER_CONFIG *const cc,
+ const USER_PARAM *const extCfg,
+ const SBR_PS_SIGNALING sbrSignaling,
+ const HANDLE_AACENC_CONFIG hAacConfig) {
+ AUDIO_OBJECT_TYPE transport_AOT = AOT_NULL_OBJECT;
+ FDKmemclear(cc, sizeof(CODER_CONFIG));
+
+ cc->flags = 0;
+
+ cc->samplesPerFrame = hAacConfig->framelength;
+ cc->samplingRate = hAacConfig->sampleRate;
+ cc->extSamplingRate = extCfg->userSamplerate;
+
+ /* Map virtual aot to transport aot. */
+ switch (hAacConfig->audioObjectType) {
+ case AOT_MP2_AAC_LC:
+ case AOT_DABPLUS_AAC_LC:
+ transport_AOT = AOT_AAC_LC;
+ break;
+ case AOT_MP2_SBR:
+ case AOT_DABPLUS_SBR:
+ transport_AOT = AOT_SBR;
+ cc->flags |= CC_SBR;
+ break;
+ case AOT_DABPLUS_PS:
+ transport_AOT = AOT_PS;
+ cc->flags |= CC_SBR;
+ break;
+ default:
+ transport_AOT = hAacConfig->audioObjectType;
+ }
+
+ if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
+ cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0;
+ cc->flags |= (hAacConfig->syntaxFlags & AC_LD_MPS) ? CC_SAC : 0;
+ }
+
+ /* transport type is usually AAC-LC. */
+ if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) {
+ cc->aot = AOT_AAC_LC;
+ } else {
+ cc->aot = transport_AOT;
+ }
+
+ /* Configure extension aot. */
+ if (sbrSignaling == SIG_IMPLICIT) {
+ cc->extAOT = AOT_NULL_OBJECT; /* implicit */
+ } else {
+ if ((sbrSignaling == SIG_EXPLICIT_BW_COMPATIBLE) &&
+ ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS))) {
+ cc->extAOT = AOT_SBR; /* explicit backward compatible */
+ } else {
+ cc->extAOT = transport_AOT; /* explicit hierarchical */
+ }
+ }
+
+ if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) {
+ cc->sbrPresent = 1;
+ if (transport_AOT == AOT_PS) {
+ cc->psPresent = 1;
+ }
+ }
+ cc->sbrSignaling = sbrSignaling;
+
+ if (hAacConfig->downscaleFactor > 1) {
+ cc->downscaleSamplingRate = cc->samplingRate;
+ cc->samplingRate *= hAacConfig->downscaleFactor;
+ cc->extSamplingRate *= hAacConfig->downscaleFactor;
+ }
+
+ cc->bitRate = hAacConfig->bitRate;
+ cc->noChannels = hAacConfig->nChannels;
+ cc->flags |= CC_IS_BASELAYER;
+ cc->channelMode = hAacConfig->channelMode;
+
+if (extCfg->userTpType == TT_DABPLUS && hAacConfig->nSubFrames==1) {
+ switch(hAacConfig->sampleRate) {
+ case 48000:
+ cc->nSubFrames=6;
+ break;
+ case 32000:
+ cc->nSubFrames=4;
+ break;
+ case 24000:
+ cc->nSubFrames=3;
+ break;
+ case 16000:
+ cc->nSubFrames=2;
+ break;
+ }
+ //fprintf(stderr, "hAacConfig->nSubFrames=%d hAacConfig->sampleRate=%d\n", hAacConfig->nSubFrames, hAacConfig->sampleRate);
+ } else {
+ cc->nSubFrames = (hAacConfig->nSubFrames > 1 && extCfg->userTpNsubFrames == 1)
+ ? hAacConfig->nSubFrames
+ : extCfg->userTpNsubFrames;
+ }
+
+ cc->flags |= (extCfg->userTpProtection) ? CC_PROTECTION : 0;
+
+ if (extCfg->userTpHeaderPeriod != 0xFF) {
+ cc->headerPeriod = extCfg->userTpHeaderPeriod;
+ } else { /* auto-mode */
+ switch (extCfg->userTpType) {
+ case TT_MP4_ADTS:
+ case TT_MP4_LOAS:
+ case TT_MP4_LATM_MCP1:
+ cc->headerPeriod = DEFAULT_HEADER_PERIOD_REPETITION_RATE;
+ break;
+ default:
+ cc->headerPeriod = 0;
+ }
+ }
+
+ /* Mpeg-4 signaling for transport library. */
+ switch (hAacConfig->audioObjectType) {
+ case AOT_MP2_AAC_LC:
+ case AOT_MP2_SBR:
+ cc->flags &= ~CC_MPEG_ID; /* Required for ADTS. */
+ cc->extAOT = AOT_NULL_OBJECT;
+ break;
+ default:
+ cc->flags |= CC_MPEG_ID;
+ }
+
+ /* ER-tools signaling. */
+ cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0;
+ cc->flags |= (hAacConfig->syntaxFlags & AC_ER_HCR) ? CC_HCR : 0;
+ cc->flags |= (hAacConfig->syntaxFlags & AC_ER_RVLC) ? CC_RVLC : 0;
+
+ /* Matrix mixdown coefficient configuration. */
+ if ((extCfg->userPceAdditions & 0x1) && (hAacConfig->epConfig == -1) &&
+ ((cc->channelMode == MODE_1_2_2) || (cc->channelMode == MODE_1_2_2_1))) {
+ cc->matrixMixdownA = ((extCfg->userPceAdditions >> 1) & 0x3) + 1;
+ cc->flags |= (extCfg->userPceAdditions >> 3) & 0x1 ? CC_PSEUDO_SURROUND : 0;
+ } else {
+ cc->matrixMixdownA = 0;
+ }
+
+ cc->channelConfigZero = 0;
+}
+
+/*
+ * Validate prefilled pointers within buffer descriptor.
+ *
+ * \param pBufDesc Pointer to buffer descriptor
+
+ * \return - AACENC_OK, all fine.
+ * - AACENC_INVALID_HANDLE, on missing pointer initializiation.
+ * - AACENC_UNSUPPORTED_PARAMETER, on incorrect buffer descriptor
+ initialization.
+ */
+static AACENC_ERROR validateBufDesc(const AACENC_BufDesc *pBufDesc) {
+ AACENC_ERROR err = AACENC_OK;
+
+ if (pBufDesc != NULL) {
+ int i;
+ if ((pBufDesc->bufferIdentifiers == NULL) || (pBufDesc->bufSizes == NULL) ||
+ (pBufDesc->bufElSizes == NULL) || (pBufDesc->bufs == NULL)) {
+ err = AACENC_UNSUPPORTED_PARAMETER;
+ goto bail;
+ }
+ for (i = 0; i < pBufDesc->numBufs; i++) {
+ if (pBufDesc->bufs[i] == NULL) {
+ err = AACENC_UNSUPPORTED_PARAMETER;
+ goto bail;
+ }
+ }
+ } else {
+ err = AACENC_INVALID_HANDLE;
+ }
+bail:
+ return err;
+}
+
+/*
+ * Examine buffer descriptor regarding choosen identifier.
+ *
+ * \param pBufDesc Pointer to buffer descriptor
+ * \param identifier Buffer identifier to look for.
+
+ * \return - Buffer descriptor index.
+ * -1, if there is no entry available.
+ */
+static INT getBufDescIdx(const AACENC_BufDesc *pBufDesc,
+ const AACENC_BufferIdentifier identifier) {
+ INT i, idx = -1;
+
+ if (pBufDesc != NULL) {
+ for (i = 0; i < pBufDesc->numBufs; i++) {
+ if ((AACENC_BufferIdentifier)pBufDesc->bufferIdentifiers[i] ==
+ identifier) {
+ idx = i;
+ break;
+ }
+ }
+ }
+ return idx;
+}
+
+/****************************************************************************
+ Function Declarations
+****************************************************************************/
+
+AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
+ USER_PARAM *config) {
+ /* make reasonable default settings */
+ FDKaacEnc_AacInitDefaultConfig(hAacConfig);
+
+ /* clear configuration structure and copy default settings */
+ FDKmemclear(config, sizeof(USER_PARAM));
+
+ /* copy encoder configuration settings */
+ config->nChannels = hAacConfig->nChannels;
+ config->userAOT = hAacConfig->audioObjectType = AOT_AAC_LC;
+ config->userSamplerate = hAacConfig->sampleRate;
+ config->userChannelMode = hAacConfig->channelMode;
+ config->userBitrate = hAacConfig->bitRate;
+ config->userBitrateMode = hAacConfig->bitrateMode;
+ config->userPeakBitrate = (UINT)-1;
+ config->userBandwidth = hAacConfig->bandWidth;
+ config->userTns = hAacConfig->useTns;
+ config->userPns = hAacConfig->usePns;
+ config->userIntensity = hAacConfig->useIS;
+ config->userAfterburner = hAacConfig->useRequant;
+ config->userFramelength = (UINT)-1;
+
+ config->userDownscaleFactor = 1;
+
+ /* initialize transport parameters */
+ config->userTpType = TT_UNKNOWN;
+ config->userTpAmxv = 0;
+ config->userTpSignaling = 0xFF; /* choose signaling automatically */
+ config->userTpNsubFrames = 1;
+ config->userTpProtection = 0; /* not crc protected*/
+ config->userTpHeaderPeriod = 0xFF; /* header period in auto mode */
+ config->userPceAdditions = 0; /* no matrix mixdown coefficient */
+ config->userMetaDataMode = 0; /* do not embed any meta data info */
+
+ config->userAncDataRate = 0;
+
+ /* SBR rate is set to 0 here, which means it should be set automatically
+ in FDKaacEnc_AdjustEncSettings() if the user did not set a rate
+ expilicitely. */
+ config->userSbrRatio = 0;
+
+ /* SBR enable set to -1 means to inquire ELD audio configurator for reasonable
+ * configuration. */
+ config->userSbrEnabled = (UCHAR)-1;
+
+ return AAC_ENC_OK;
+}
+
+static void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping,
+ SBR_ELEMENT_INFO *sbrElInfo, INT bitRate) {
+ INT codebits = bitRate;
+ int el;
+
+ /* Copy Element info */
+ for (el = 0; el < channelMapping->nElements; el++) {
+ sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0];
+ sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1];
+ sbrElInfo[el].elType = channelMapping->elInfo[el].elType;
+ sbrElInfo[el].bitRate =
+ fMultIfloor(channelMapping->elInfo[el].relativeBits, bitRate);
+ sbrElInfo[el].instanceTag = channelMapping->elInfo[el].instanceTag;
+ sbrElInfo[el].nChannelsInEl = channelMapping->elInfo[el].nChannelsInEl;
+ sbrElInfo[el].fParametricStereo = 0;
+ sbrElInfo[el].fDualMono = 0;
+
+ codebits -= sbrElInfo[el].bitRate;
+ }
+ sbrElInfo[0].bitRate += codebits;
+}
+
+static INT aacEncoder_LimitBitrate(const HANDLE_TRANSPORTENC hTpEnc,
+ const INT samplingRate,
+ const INT frameLength, const INT nChannels,
+ const CHANNEL_MODE channelMode, INT bitRate,
+ const INT nSubFrames, const INT sbrActive,
+ const INT sbrDownSampleRate,
+ const UINT syntaxFlags,
+ const AUDIO_OBJECT_TYPE aot) {
+ INT coreSamplingRate;
+ CHANNEL_MAPPING cm;
+
+ FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm);
+
+ if (sbrActive) {
+ coreSamplingRate =
+ samplingRate >>
+ (sbrEncoder_IsSingleRatePossible(aot) ? (sbrDownSampleRate - 1) : 1);
+ } else {
+ coreSamplingRate = samplingRate;
+ }
+
+ /* Limit bit rate in respect to the core coder */
+ bitRate = FDKaacEnc_LimitBitrate(hTpEnc, aot, coreSamplingRate, frameLength,
+ nChannels, cm.nChannelsEff, bitRate, -1,
+ NULL, AACENC_BR_MODE_INVALID, nSubFrames);
+
+ /* Limit bit rate in respect to available SBR modes if active */
+ if (sbrActive) {
+ int numIterations = 0;
+ INT initialBitrate, adjustedBitrate;
+ adjustedBitrate = bitRate;
+
+ /* Find total bitrate which provides valid configuration for each SBR
+ * element. */
+ do {
+ int e;
+ SBR_ELEMENT_INFO sbrElInfo[((8))];
+ FDK_ASSERT(cm.nElements <= ((8)));
+
+ initialBitrate = adjustedBitrate;
+
+ /* Get bit rate for each SBR element */
+ aacEncDistributeSbrBits(&cm, sbrElInfo, initialBitrate);
+
+ for (e = 0; e < cm.nElements; e++) {
+ INT sbrElementBitRateIn, sbrBitRateOut;
+
+ if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) {
+ continue;
+ }
+ sbrElementBitRateIn = sbrElInfo[e].bitRate;
+
+ sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn,
+ cm.elInfo[e].nChannelsInEl,
+ coreSamplingRate, aot);
+
+ if (sbrBitRateOut == 0) {
+ return 0;
+ }
+
+ /* If bitrates don't match, distribution and limiting needs to be
+ determined again. Abort element loop and restart with adapted
+ bitrate. */
+ if (sbrElementBitRateIn != sbrBitRateOut) {
+ if (sbrElementBitRateIn < sbrBitRateOut) {
+ adjustedBitrate = fMax(initialBitrate,
+ (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut + 8),
+ cm.elInfo[e].relativeBits));
+ break;
+ }
+
+ if (sbrElementBitRateIn > sbrBitRateOut) {
+ adjustedBitrate = fMin(initialBitrate,
+ (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut - 8),
+ cm.elInfo[e].relativeBits));
+ break;
+ }
+
+ } /* sbrElementBitRateIn != sbrBitRateOut */
+
+ } /* elements */
+
+ numIterations++; /* restrict iteration to worst case of num elements */
+
+ } while ((initialBitrate != adjustedBitrate) &&
+ (numIterations <= cm.nElements));
+
+ /* Unequal bitrates mean that no reasonable bitrate configuration found. */
+ bitRate = (initialBitrate == adjustedBitrate) ? adjustedBitrate : 0;
+ }
+
+ /* Limit bit rate in respect to available MPS modes if active */
+ if ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS) &&
+ (channelMode == MODE_1)) {
+ bitRate = FDK_MpegsEnc_GetClosestBitRate(
+ aot, MODE_212, samplingRate, (sbrActive) ? sbrDownSampleRate : 0,
+ bitRate);
+ }
+
+ //fprintf(stderr, "aacEncoder_LimitBitrate(): bitRate=%d\n", bitRate);
+ return bitRate;
+}
+
+/*
+ * \brief Get CBR bitrate
+ *
+ * \hAacConfig Internal encoder config
+ * \return Bitrate
+ */
+static INT FDKaacEnc_GetCBRBitrate(const HANDLE_AACENC_CONFIG hAacConfig,
+ const INT userSbrRatio) {
+ INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
+ ->nChannelsEff *
+ hAacConfig->sampleRate;
+
+ if (isPsActive(hAacConfig->audioObjectType)) {
+ bitrate = 1 * bitrate; /* 0.5 bit per sample */
+ } else if (isSbrActive(hAacConfig)) {
+ if ((userSbrRatio == 2) ||
+ ((userSbrRatio == 0) &&
+ (hAacConfig->audioObjectType != AOT_ER_AAC_ELD))) {
+ bitrate = (bitrate + (bitrate >> 2)) >> 1; /* 0.625 bits per sample */
+ }
+ if ((userSbrRatio == 1) ||
+ ((userSbrRatio == 0) &&
+ (hAacConfig->audioObjectType == AOT_ER_AAC_ELD))) {
+ bitrate = (bitrate + (bitrate >> 3)); /* 1.125 bits per sample */
+ }
+ } else {
+ bitrate = bitrate + (bitrate >> 1); /* 1.5 bits per sample */
+ }
+
+ return bitrate;
+}
+
+/*
+ * \brief Consistency check of given USER_PARAM struct and
+ * copy back configuration from public struct into internal
+ * encoder configuration struct.
+ *
+ * \hAacEncoder Internal encoder config which is to be updated
+ * \param config User provided config (public struct)
+ * \return returns always AAC_ENC_OK
+ */
+static AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
+ USER_PARAM *config) {
+ AACENC_ERROR err = AACENC_OK;
+
+ /* Get struct pointers. */
+ HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig;
+
+ /* Encoder settings update. */
+ hAacConfig->sampleRate = config->userSamplerate;
+ if (config->userDownscaleFactor > 1) {
+ hAacConfig->useTns = 0;
+ hAacConfig->usePns = 0;
+ hAacConfig->useIS = 0;
+ } else {
+ hAacConfig->useTns = config->userTns;
+ hAacConfig->usePns = config->userPns;
+ hAacConfig->useIS = config->userIntensity;
+ }
+
+ hAacConfig->audioObjectType = config->userAOT;
+ hAacConfig->channelMode =
+ GetCoreChannelMode(config->userChannelMode, hAacConfig->audioObjectType);
+ hAacConfig->nChannels =
+ FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannels;
+ hAacConfig->bitrateMode = (AACENC_BITRATE_MODE)config->userBitrateMode;
+ hAacConfig->bandWidth = config->userBandwidth;
+ hAacConfig->useRequant = config->userAfterburner;
+
+ hAacConfig->anc_Rate = config->userAncDataRate;
+ hAacConfig->syntaxFlags = 0;
+ hAacConfig->epConfig = -1;
+
+ if (hAacConfig->audioObjectType != AOT_ER_AAC_ELD &&
+ config->userDownscaleFactor > 1) {
+ return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD
+ */
+ }
+ if (config->userDownscaleFactor > 1 && config->userSbrEnabled == 1) {
+ return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD
+ w/o SBR */
+ }
+ if (config->userDownscaleFactor > 1 && config->userChannelMode == 128) {
+ return AACENC_INVALID_CONFIG; /* disallow downscaling for AAC-ELDv2 */
+ }
+
+ 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. */
+ switch (config->userAOT) {
+ case AOT_MP2_AAC_LC:
+ case AOT_MP2_SBR:
+ hAacConfig->usePns = 0;
+ FDK_FALLTHROUGH;
+ case AOT_AAC_LC:
+ case AOT_SBR:
+ case AOT_PS:
+ config->userTpType =
+ (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_ADTS;
+ hAacConfig->framelength = (config->userFramelength != (UINT)-1)
+ ? config->userFramelength
+ : 1024;
+ if (hAacConfig->framelength != 1024 && hAacConfig->framelength != 960) {
+ return AACENC_INVALID_CONFIG;
+ }
+ break;
+
+ case AOT_DABPLUS_SBR:
+ case AOT_DABPLUS_PS:
+ hAacConfig->syntaxFlags |= ((config->userSbrEnabled) ? AC_SBR_PRESENT : 0);
+ case AOT_DABPLUS_AAC_LC:
+ config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_DABPLUS;
+ hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 960;
+ if (hAacConfig->framelength != 960) {
+ return AACENC_INVALID_CONFIG;
+ }
+ config->userTpSignaling=2;
+ if(config->userTpType == TT_DABPLUS)
+ hAacConfig->syntaxFlags |= AC_DAB;
+ break;
+
+ case AOT_ER_AAC_LD:
+ hAacConfig->epConfig = 0;
+ hAacConfig->syntaxFlags |= AC_ER | AC_LD;
+ hAacConfig->syntaxFlags |=
+ ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
+ hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
+ hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0);
+ config->userTpType =
+ (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
+ hAacConfig->framelength =
+ (config->userFramelength != (UINT)-1) ? config->userFramelength : 512;
+ if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) {
+ return AACENC_INVALID_CONFIG;
+ }
+ break;
+ case AOT_ER_AAC_ELD:
+ hAacConfig->epConfig = 0;
+ hAacConfig->syntaxFlags |= AC_ER | AC_ELD;
+ hAacConfig->syntaxFlags |=
+ ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
+ hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
+ hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0);
+ hAacConfig->syntaxFlags |=
+ ((config->userSbrEnabled == 1) ? AC_SBR_PRESENT : 0);
+ hAacConfig->syntaxFlags |=
+ ((config->userChannelMode == MODE_212) ? AC_LD_MPS : 0);
+ config->userTpType =
+ (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
+ hAacConfig->framelength =
+ (config->userFramelength != (UINT)-1) ? config->userFramelength : 512;
+
+ hAacConfig->downscaleFactor = config->userDownscaleFactor;
+
+ switch (config->userDownscaleFactor) {
+ case 1:
+ break;
+ case 2:
+ case 4:
+ hAacConfig->syntaxFlags |= AC_ELD_DOWNSCALE;
+ break;
+ default:
+ return AACENC_INVALID_CONFIG;
+ }
+
+ if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480 &&
+ hAacConfig->framelength != 256 && hAacConfig->framelength != 240 &&
+ hAacConfig->framelength != 128 && hAacConfig->framelength != 120) {
+ return AACENC_INVALID_CONFIG;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Initialize SBR parameters */
+ if ((config->userSbrRatio == 0) && (isSbrActive(hAacConfig))) {
+ /* Automatic SBR ratio configuration
+ * - downsampled SBR for ELD
+ * - otherwise always dualrate SBR
+ */
+ if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
+ hAacConfig->sbrRatio = ((hAacConfig->syntaxFlags & AC_LD_MPS) &&
+ (hAacConfig->sampleRate >= 27713))
+ ? 2
+ : 1;
+ } else {
+ hAacConfig->sbrRatio = 2;
+ }
+ } else {
+ /* SBR ratio has been set by the user, so use it. */
+ hAacConfig->sbrRatio = isSbrActive(hAacConfig) ? config->userSbrRatio : 0;
+ }
+
+ /* Set default bitrate */
+ hAacConfig->bitRate = config->userBitrate;
+
+ switch (hAacConfig->bitrateMode) {
+ case AACENC_BR_MODE_CBR:
+ /* Set default bitrate if no external bitrate declared. */
+ if (config->userBitrate == (UINT)-1) {
+ hAacConfig->bitRate =
+ FDKaacEnc_GetCBRBitrate(hAacConfig, config->userSbrRatio);
+ }
+ hAacConfig->averageBits = -1;
+ break;
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ /* Get bitrate in VBR configuration */
+ /* In VBR mode; SBR-modul depends on bitrate, core encoder on bitrateMode.
+ */
+ hAacConfig->bitRate = FDKaacEnc_GetVBRBitrate(hAacConfig->bitrateMode,
+ hAacConfig->channelMode);
+ break;
+ default:
+ return AACENC_INVALID_CONFIG;
+ }
+
+ /* set bitreservoir size */
+ switch (hAacConfig->bitrateMode) {
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ case AACENC_BR_MODE_CBR:
+ 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;
+ }
+ break;
+ default:
+ return AACENC_INVALID_CONFIG;
+ }
+
+ /* Max bits per frame limitation depending on transport format. */
+ if ((config->userTpNsubFrames > 1)) {
+ int maxFrameLength = 8 * hAacEncoder->outBufferInBytes;
+ switch (config->userTpType) {
+ case TT_MP4_LOAS:
+ maxFrameLength =
+ fMin(maxFrameLength, 8 * (1 << 13)) / config->userTpNsubFrames;
+ break;
+ case TT_MP4_ADTS:
+ maxFrameLength = fMin(maxFrameLength, 8 * ((1 << 13) - 1)) /
+ config->userTpNsubFrames;
+ break;
+ default:
+ maxFrameLength = -1;
+ }
+ if (maxFrameLength != -1) {
+ if (hAacConfig->maxBitsPerFrame > maxFrameLength) {
+ return AACENC_INVALID_CONFIG;
+ } else if (hAacConfig->maxBitsPerFrame == -1) {
+ hAacConfig->maxBitsPerFrame = maxFrameLength;
+ }
+ }
+ }
+
+ if ((hAacConfig->audioObjectType == AOT_ER_AAC_ELD) &&
+ !(hAacConfig->syntaxFlags & AC_ELD_DOWNSCALE) &&
+ (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio == 0) &&
+ ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0)) {
+ const ELD_SBR_CONFIGURATOR *pConfig = NULL;
+
+ if (NULL !=
+ (pConfig = eldSbrConfigurator(
+ FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
+ ->nChannels,
+ hAacConfig->sampleRate, hAacConfig->bitRate))) {
+ hAacConfig->syntaxFlags |= (pConfig->sbrMode == 0) ? 0 : AC_SBR_PRESENT;
+ hAacConfig->syntaxFlags |= (pConfig->chMode == MODE_212) ? AC_LD_MPS : 0;
+ hAacConfig->channelMode =
+ GetCoreChannelMode(pConfig->chMode, hAacConfig->audioObjectType);
+ hAacConfig->nChannels =
+ FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
+ ->nChannels;
+ hAacConfig->sbrRatio =
+ (pConfig->sbrMode == 0) ? 0 : (pConfig->sbrMode == 1) ? 1 : 2;
+ }
+ }
+
+ {
+ UCHAR tpSignaling =
+ getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType,
+ config->userTpSignaling, hAacConfig->sbrRatio);
+
+ if ((hAacConfig->audioObjectType == AOT_AAC_LC ||
+ hAacConfig->audioObjectType == AOT_SBR ||
+ hAacConfig->audioObjectType == AOT_PS) &&
+ (config->userTpType == TT_MP4_LATM_MCP1 ||
+ config->userTpType == TT_MP4_LATM_MCP0 ||
+ config->userTpType == TT_MP4_LOAS) &&
+ (tpSignaling == 1) && (config->userTpAmxv == 0)) {
+ /* For backward compatible explicit signaling, AMV1 has to be active */
+ return AACENC_INVALID_CONFIG;
+ }
+
+ if ((hAacConfig->audioObjectType == AOT_AAC_LC ||
+ hAacConfig->audioObjectType == AOT_SBR ||
+ hAacConfig->audioObjectType == AOT_PS) &&
+ (tpSignaling == 0) && (hAacConfig->sbrRatio == 1)) {
+ /* Downsampled SBR has to be signaled explicitely (for transmission of SBR
+ * sampling fequency) */
+ return AACENC_INVALID_CONFIG;
+ }
+ }
+
+ switch (hAacConfig->bitrateMode) {
+ case AACENC_BR_MODE_CBR:
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ /* We need the frame length to call aacEncoder_LimitBitrate() */
+ if (0 >= (hAacConfig->bitRate = aacEncoder_LimitBitrate(
+ NULL, hAacConfig->sampleRate, hAacConfig->framelength,
+ hAacConfig->nChannels, hAacConfig->channelMode,
+ hAacConfig->bitRate, hAacConfig->nSubFrames,
+ isSbrActive(hAacConfig), hAacConfig->sbrRatio,
+ hAacConfig->syntaxFlags, hAacConfig->audioObjectType))) {
+ return AACENC_INVALID_CONFIG;
+ }
+ break;
+ default:
+ break;
+ }
+
+#if 0 // TODO Is this still needed?
+ /* We need the frame length to call aacEncoder_LimitBitrate() */
+ hAacConfig->bitRate = aacEncoder_LimitBitrate(
+ NULL,
+ hAacConfig->sampleRate,
+ hAacConfig->framelength,
+ hAacConfig->nChannels,
+ hAacConfig->channelMode,
+ hAacConfig->bitRate,
+ hAacConfig->nSubFrames,
+ isSbrActive(hAacConfig),
+ hAacConfig->sbrRatio,
+ hAacConfig->audioObjectType
+ );
+#endif
+
+/* Configure PNS */
+ if (AACENC_BR_MODE_IS_VBR(hAacConfig->bitrateMode) /* VBR without PNS. */
+ || (hAacConfig->useTns == 0)) /* TNS required. */
+ {
+ hAacConfig->usePns = 0;
+ }
+
+ if (hAacConfig->epConfig >= 0) {
+ hAacConfig->syntaxFlags |= AC_ER;
+ if (((INT)hAacConfig->channelMode < 1) ||
+ ((INT)hAacConfig->channelMode > 14)) {
+ return AACENC_INVALID_CONFIG; /* Channel config 0 not supported. */
+ }
+ }
+
+ if ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0) {
+ if (FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode,
+ hAacConfig->nChannels) != AAC_ENC_OK) {
+ return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is
+ just a check-up */
+ }
+ }
+
+ if ((hAacConfig->nChannels > hAacEncoder->nMaxAacChannels) ||
+ ((FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
+ ->nChannelsEff > hAacEncoder->nMaxSbrChannels) &&
+ isSbrActive(hAacConfig))) {
+ return AACENC_INVALID_CONFIG; /* not enough channels allocated */
+ }
+
+ /* Meta data restriction. */
+ switch (hAacConfig->audioObjectType) {
+ /* Allow metadata support */
+ case AOT_AAC_LC:
+ case AOT_SBR:
+ case AOT_PS:
+ case AOT_MP2_AAC_LC:
+ case AOT_MP2_SBR:
+ hAacEncoder->metaDataAllowed = 1;
+ if (!((((INT)hAacConfig->channelMode >= 1) &&
+ ((INT)hAacConfig->channelMode <= 14)) ||
+ (MODE_7_1_REAR_SURROUND == hAacConfig->channelMode) ||
+ (MODE_7_1_FRONT_CENTER == hAacConfig->channelMode))) {
+ config->userMetaDataMode = 0;
+ }
+ break;
+ /* Prohibit metadata support */
+ default:
+ hAacEncoder->metaDataAllowed = 0;
+ }
+
+ return err;
+}
+
+static INT aacenc_SbrCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
+ const INT sampleRateIn, const INT sampleRateOut,
+ const INT samplesPerFrame,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const MP4_ELEMENT_ID elementID,
+ const INT elementIndex, const UCHAR harmonicSbr,
+ const UCHAR stereoConfigIndex,
+ const UCHAR configMode, UCHAR *configChanged,
+ const INT downscaleFactor) {
+ HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;
+
+ sbrEncoder_GetHeader(hAacEncoder->hEnvEnc, hBs, elementIndex, 0);
+
+ return 0;
+}
+
+INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const INT samplingRate, const INT frameSize,
+ const INT stereoConfigIndex,
+ const INT coreSbrFrameLengthIndex, const INT configBytes,
+ const UCHAR configMode, UCHAR *configChanged) {
+ HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;
+
+ return (FDK_MpegsEnc_WriteSpatialSpecificConfig(hAacEncoder->hMpsEnc, hBs));
+}
+
+static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ULONG InitFlags,
+ USER_PARAM *config) {
+ AACENC_ERROR err = AACENC_OK;
+
+ INT aacBufferOffset = 0;
+ HANDLE_SBR_ENCODER *hSbrEncoder = &hAacEncoder->hEnvEnc;
+ HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig;
+
+ hAacEncoder->nZerosAppended = 0; /* count appended zeros */
+
+ INT frameLength = hAacConfig->framelength;
+
+ if ((InitFlags & AACENC_INIT_CONFIG)) {
+ CHANNEL_MODE prevChMode = hAacConfig->channelMode;
+
+ /* Verify settings and update: config -> heAacEncoder */
+ if ((err = FDKaacEnc_AdjustEncSettings(hAacEncoder, config)) != AACENC_OK) {
+ return err;
+ }
+ frameLength = hAacConfig->framelength; /* adapt temporal framelength */
+
+ /* Seamless channel reconfiguration in sbr not fully implemented */
+ if ((prevChMode != hAacConfig->channelMode) && isSbrActive(hAacConfig)) {
+ InitFlags |= AACENC_INIT_STATES;
+ }
+ }
+
+ /* Clear input buffer */
+ if (InitFlags == AACENC_INIT_ALL) {
+ FDKmemclear(hAacEncoder->inputBuffer,
+ sizeof(INT_PCM) * hAacEncoder->inputBufferSize);
+ }
+
+ if ((InitFlags & AACENC_INIT_CONFIG)) {
+ aacBufferOffset = 0;
+ switch (hAacConfig->audioObjectType) {
+ case AOT_ER_AAC_LD:
+ hAacEncoder->nDelay = DELAY_AACLD(hAacConfig->framelength);
+ break;
+ case AOT_ER_AAC_ELD:
+ hAacEncoder->nDelay = DELAY_AACELD(hAacConfig->framelength);
+ break;
+ default:
+ hAacEncoder->nDelay =
+ DELAY_AAC(hAacConfig->framelength); /* AAC encoder delay */
+ }
+
+ hAacConfig->ancDataBitRate = 0;
+ }
+
+ if ((NULL != hAacEncoder->hEnvEnc) && isSbrActive(hAacConfig) &&
+ ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) {
+ INT sbrError;
+ UINT initFlag = 0;
+ SBR_ELEMENT_INFO sbrElInfo[(8)];
+ CHANNEL_MAPPING channelMapping;
+ CHANNEL_MODE channelMode = isPsActive(hAacConfig->audioObjectType)
+ ? config->userChannelMode
+ : hAacConfig->channelMode;
+ INT numChannels = isPsActive(hAacConfig->audioObjectType)
+ ? config->nChannels
+ : hAacConfig->nChannels;
+
+ if (FDKaacEnc_InitChannelMapping(channelMode, hAacConfig->channelOrder,
+ &channelMapping) != AAC_ENC_OK) {
+ return AACENC_INIT_ERROR;
+ }
+
+ /* Check return value and if the SBR encoder can handle enough elements */
+ if (channelMapping.nElements > (8)) {
+ return AACENC_INIT_ERROR;
+ }
+
+ aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate);
+
+ initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0;
+
+ /* Let the SBR encoder take a look at the configuration and change if
+ * required. */
+ sbrError = sbrEncoder_Init(
+ *hSbrEncoder, sbrElInfo, channelMapping.nElements,
+ hAacEncoder->inputBuffer, hAacEncoder->inputBufferSizePerChannel,
+ &hAacConfig->bandWidth, &aacBufferOffset, &numChannels,
+ hAacConfig->syntaxFlags, &hAacConfig->sampleRate, &hAacConfig->sbrRatio,
+ &frameLength, hAacConfig->audioObjectType, &hAacEncoder->nDelay,
+ (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC,
+ (config->userTpHeaderPeriod != 0xFF)
+ ? config->userTpHeaderPeriod
+ : DEFAULT_HEADER_PERIOD_REPETITION_RATE,
+ initFlag);
+
+ /* Suppress AOT reconfiguration and check error status. */
+ if ((sbrError) || (numChannels != hAacConfig->nChannels)) {
+ return AACENC_INIT_SBR_ERROR;
+ }
+
+ if (numChannels == 1) {
+ hAacConfig->channelMode = MODE_1;
+ }
+
+ /* Never use PNS if SBR is active */
+ if (hAacConfig->usePns) {
+ hAacConfig->usePns = 0;
+ }
+
+ /* estimated bitrate consumed by SBR or PS */
+ hAacConfig->ancDataBitRate = sbrEncoder_GetEstimateBitrate(*hSbrEncoder);
+
+ } /* sbr initialization */
+
+ if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) {
+ int coreCoderDelay = DELAY_AACELD(hAacConfig->framelength);
+
+ if (isSbrActive(hAacConfig)) {
+ coreCoderDelay = hAacConfig->sbrRatio * coreCoderDelay +
+ sbrEncoder_GetInputDataDelay(*hSbrEncoder);
+ }
+
+ if (MPS_ENCODER_OK !=
+ FDK_MpegsEnc_Init(hAacEncoder->hMpsEnc, hAacConfig->audioObjectType,
+ config->userSamplerate, hAacConfig->bitRate,
+ isSbrActive(hAacConfig) ? hAacConfig->sbrRatio : 0,
+ frameLength, /* for dual rate sbr this value is
+ already multiplied by 2 */
+ hAacEncoder->inputBufferSizePerChannel,
+ coreCoderDelay)) {
+ return AACENC_INIT_MPS_ERROR;
+ }
+ }
+ hAacEncoder->nDelay =
+ fMax(FDK_MpegsEnc_GetDelay(hAacEncoder->hMpsEnc), hAacEncoder->nDelay);
+
+ /*
+ * Initialize Transport - Module.
+ */
+ if ((InitFlags & AACENC_INIT_TRANSPORT)) {
+ UINT flags = 0;
+
+ FDKaacEnc_MapConfig(
+ &hAacEncoder->coderConfig, config,
+ getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType,
+ config->userTpSignaling, hAacConfig->sbrRatio),
+ hAacConfig);
+
+ /* create flags for transport encoder */
+ if (config->userTpAmxv != 0) {
+ flags |= TP_FLAG_LATM_AMV;
+ }
+ /* Clear output buffer */
+ FDKmemclear(hAacEncoder->outBuffer,
+ hAacEncoder->outBufferInBytes * sizeof(UCHAR));
+
+ /* Initialize Bitstream encoder */
+ if (transportEnc_Init(hAacEncoder->hTpEnc, hAacEncoder->outBuffer,
+ hAacEncoder->outBufferInBytes, config->userTpType,
+ &hAacEncoder->coderConfig, flags) != 0) {
+ return AACENC_INIT_TP_ERROR;
+ }
+
+ } /* transport initialization */
+
+ /*
+ * Initialize AAC - Core.
+ */
+ if ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES)) {
+ if (FDKaacEnc_Initialize(
+ hAacEncoder->hAacEnc, hAacConfig, hAacEncoder->hTpEnc,
+ (InitFlags & AACENC_INIT_STATES) ? 1 : 0) != AAC_ENC_OK) {
+ return AACENC_INIT_AAC_ERROR;
+ }
+
+ } /* aac initialization */
+
+ /*
+ * Initialize Meta Data - Encoder.
+ */
+ if (hAacEncoder->hMetadataEnc && (hAacEncoder->metaDataAllowed != 0) &&
+ ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) {
+ INT inputDataDelay = DELAY_AAC(hAacConfig->framelength);
+
+ if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) {
+ inputDataDelay = hAacConfig->sbrRatio * inputDataDelay +
+ sbrEncoder_GetInputDataDelay(*hSbrEncoder);
+ }
+
+ if (FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc,
+ ((InitFlags & AACENC_INIT_STATES) ? 1 : 0),
+ config->userMetaDataMode, inputDataDelay,
+ frameLength, config->userSamplerate,
+ config->nChannels, config->userChannelMode,
+ hAacConfig->channelOrder) != 0) {
+ return AACENC_INIT_META_ERROR;
+ }
+
+ hAacEncoder->nDelay += FDK_MetadataEnc_GetDelay(hAacEncoder->hMetadataEnc);
+ }
+
+ /* Get custom delay, i.e. the codec delay w/o the decoder's SBR- or MPS delay
+ */
+ if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) {
+ hAacEncoder->nDelayCore =
+ hAacEncoder->nDelay -
+ fMax(0, FDK_MpegsEnc_GetDecDelay(hAacEncoder->hMpsEnc));
+ } else if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) {
+ hAacEncoder->nDelayCore =
+ hAacEncoder->nDelay -
+ fMax(0, sbrEncoder_GetSbrDecDelay(hAacEncoder->hEnvEnc));
+ } else {
+ hAacEncoder->nDelayCore = hAacEncoder->nDelay;
+ }
+
+ /*
+ * Update pointer to working buffer.
+ */
+ if ((InitFlags & AACENC_INIT_CONFIG)) {
+ hAacEncoder->inputBufferOffset = aacBufferOffset;
+
+ hAacEncoder->nSamplesToRead = frameLength * config->nChannels;
+
+ } /* parameter changed */
+
+ return AACENC_OK;
+}
+
+AACENC_ERROR aacEncOpen(HANDLE_AACENCODER *phAacEncoder, const UINT encModules,
+ const UINT maxChannels) {
+ AACENC_ERROR err = AACENC_OK;
+ HANDLE_AACENCODER hAacEncoder = NULL;
+
+ if (phAacEncoder == NULL) {
+ err = AACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* allocate memory */
+ hAacEncoder = Get_AacEncoder();
+
+ if (hAacEncoder == NULL) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+
+ FDKmemclear(hAacEncoder, sizeof(AACENCODER));
+
+ /* Specify encoder modules to be allocated. */
+ if (encModules == 0) {
+ C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
+ LIB_INFO(*pLibInfo)
+ [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo;
+ FDKinitLibInfo(*pLibInfo);
+ aacEncGetLibInfo(*pLibInfo);
+
+ hAacEncoder->encoder_modis = ENC_MODE_FLAG_AAC;
+ if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_HQ) {
+ hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SBR;
+ }
+ if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_PS_MPEG) {
+ hAacEncoder->encoder_modis |= ENC_MODE_FLAG_PS;
+ }
+ if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_AACENC) & CAPF_AAC_DRC) {
+ hAacEncoder->encoder_modis |= ENC_MODE_FLAG_META;
+ }
+ hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SAC;
+
+ C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
+ } else {
+ hAacEncoder->encoder_modis = encModules;
+ }
+
+ /* Determine max channel configuration. */
+ if (maxChannels == 0) {
+ hAacEncoder->nMaxAacChannels = (8);
+ hAacEncoder->nMaxSbrChannels = (8);
+ } else {
+ hAacEncoder->nMaxAacChannels = (maxChannels & 0x00FF);
+ if ((hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR)) {
+ hAacEncoder->nMaxSbrChannels = (maxChannels & 0xFF00)
+ ? (maxChannels >> 8)
+ : hAacEncoder->nMaxAacChannels;
+ }
+
+ if ((hAacEncoder->nMaxAacChannels > (8)) ||
+ (hAacEncoder->nMaxSbrChannels > (8))) {
+ err = AACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ } /* maxChannels==0 */
+
+ /* Max number of elements could be tuned any more. */
+ hAacEncoder->nMaxAacElements = fixMin(((8)), hAacEncoder->nMaxAacChannels);
+ hAacEncoder->nMaxSbrElements = fixMin((8), hAacEncoder->nMaxSbrChannels);
+
+ /* In case of memory overlay, allocate memory out of libraries */
+
+ if (hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR | ENC_MODE_FLAG_PS))
+ hAacEncoder->inputBufferSizePerChannel = INPUTBUFFER_SIZE;
+ else
+ hAacEncoder->inputBufferSizePerChannel = (1024);
+
+ hAacEncoder->inputBufferSize =
+ hAacEncoder->nMaxAacChannels * hAacEncoder->inputBufferSizePerChannel;
+
+ if (NULL == (hAacEncoder->inputBuffer = (INT_PCM *)FDKcalloc(
+ hAacEncoder->inputBufferSize, sizeof(INT_PCM)))) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+
+ /* Open SBR Encoder */
+ if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR) {
+ if (sbrEncoder_Open(
+ &hAacEncoder->hEnvEnc, hAacEncoder->nMaxSbrElements,
+ hAacEncoder->nMaxSbrChannels,
+ (hAacEncoder->encoder_modis & ENC_MODE_FLAG_PS) ? 1 : 0)) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+
+ if (NULL == (hAacEncoder->pSbrPayload = (SBRENC_EXT_PAYLOAD *)FDKcalloc(
+ 1, sizeof(SBRENC_EXT_PAYLOAD)))) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+ } /* (encoder_modis&ENC_MODE_FLAG_SBR) */
+
+ /* Open Aac Encoder */
+ if (FDKaacEnc_Open(&hAacEncoder->hAacEnc, hAacEncoder->nMaxAacElements,
+ hAacEncoder->nMaxAacChannels, (1)) != AAC_ENC_OK) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+
+ /* Bitstream output buffer */
+ hAacEncoder->outBufferInBytes =
+ 1 << (DFRACT_BITS - CntLeadingZeros(fixMax(
+ 1, ((1) * hAacEncoder->nMaxAacChannels * 6144) >>
+ 2))); /* buffer has to be 2^n */
+ if (NULL == (hAacEncoder->outBuffer = (UCHAR *)FDKcalloc(
+ hAacEncoder->outBufferInBytes, sizeof(UCHAR)))) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+
+ /* Open Meta Data Encoder */
+ if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_META) {
+ if (FDK_MetadataEnc_Open(&hAacEncoder->hMetadataEnc,
+ (UINT)hAacEncoder->nMaxAacChannels)) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+ } /* (encoder_modis&ENC_MODE_FLAG_META) */
+
+ /* Open MPEG Surround Encoder */
+ if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SAC) {
+ if (MPS_ENCODER_OK != FDK_MpegsEnc_Open(&hAacEncoder->hMpsEnc)) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ }
+ } /* (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SAC) */
+
+ /* Open Transport Encoder */
+ if (transportEnc_Open(&hAacEncoder->hTpEnc) != 0) {
+ err = AACENC_MEMORY_ERROR;
+ goto bail;
+ } else {
+ C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
+
+ LIB_INFO(*pLibInfo)
+ [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo;
+
+ FDKinitLibInfo(*pLibInfo);
+ transportEnc_GetLibInfo(*pLibInfo);
+
+ /* Get capabilty flag for transport encoder. */
+ hAacEncoder->CAPF_tpEnc = FDKlibInfo_getCapabilities(*pLibInfo, FDK_TPENC);
+
+ C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
+ }
+ if (transportEnc_RegisterSbrCallback(hAacEncoder->hTpEnc, aacenc_SbrCallback,
+ hAacEncoder) != 0) {
+ err = AACENC_INIT_TP_ERROR;
+ goto bail;
+ }
+ if (transportEnc_RegisterSscCallback(hAacEncoder->hTpEnc, aacenc_SscCallback,
+ hAacEncoder) != 0) {
+ err = AACENC_INIT_TP_ERROR;
+ goto bail;
+ }
+
+ /* Initialize encoder instance with default parameters. */
+ aacEncDefaultConfig(&hAacEncoder->aacConfig, &hAacEncoder->extParam);
+
+ /* Initialize headerPeriod in coderConfig for aacEncoder_GetParam(). */
+ hAacEncoder->coderConfig.headerPeriod =
+ hAacEncoder->extParam.userTpHeaderPeriod;
+
+ /* All encoder modules have to be initialized */
+ hAacEncoder->InitFlags = AACENC_INIT_ALL;
+
+ /* Return encoder instance */
+ *phAacEncoder = hAacEncoder;
+
+ return err;
+
+bail:
+ aacEncClose(&hAacEncoder);
+
+ return err;
+}
+
+AACENC_ERROR aacEncClose(HANDLE_AACENCODER *phAacEncoder) {
+ AACENC_ERROR err = AACENC_OK;
+
+ if (phAacEncoder == NULL) {
+ err = AACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ if (*phAacEncoder != NULL) {
+ HANDLE_AACENCODER hAacEncoder = *phAacEncoder;
+
+ if (hAacEncoder->inputBuffer != NULL) {
+ FDKfree(hAacEncoder->inputBuffer);
+ hAacEncoder->inputBuffer = NULL;
+ }
+ if (hAacEncoder->outBuffer != NULL) {
+ FDKfree(hAacEncoder->outBuffer);
+ hAacEncoder->outBuffer = NULL;
+ }
+
+ if (hAacEncoder->hEnvEnc) {
+ sbrEncoder_Close(&hAacEncoder->hEnvEnc);
+ }
+ if (hAacEncoder->pSbrPayload != NULL) {
+ FDKfree(hAacEncoder->pSbrPayload);
+ hAacEncoder->pSbrPayload = NULL;
+ }
+ if (hAacEncoder->hAacEnc) {
+ FDKaacEnc_Close(&hAacEncoder->hAacEnc);
+ }
+
+ transportEnc_Close(&hAacEncoder->hTpEnc);
+
+ if (hAacEncoder->hMetadataEnc) {
+ FDK_MetadataEnc_Close(&hAacEncoder->hMetadataEnc);
+ }
+ if (hAacEncoder->hMpsEnc) {
+ FDK_MpegsEnc_Close(&hAacEncoder->hMpsEnc);
+ }
+
+ Free_AacEncoder(phAacEncoder);
+ }
+
+bail:
+ return err;
+}
+
+AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
+ const AACENC_BufDesc *inBufDesc,
+ const AACENC_BufDesc *outBufDesc,
+ const AACENC_InArgs *inargs,
+ AACENC_OutArgs *outargs) {
+ AACENC_ERROR err = AACENC_OK;
+ INT i, nBsBytes = 0;
+ INT outBytes[(1)];
+ int nExtensions = 0;
+ int ancDataExtIdx = -1;
+
+ /* deal with valid encoder handle */
+ if (hAacEncoder == NULL) {
+ err = AACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /*
+ * Adjust user settings and trigger reinitialization.
+ */
+ if (hAacEncoder->InitFlags != 0) {
+ err =
+ aacEncInit(hAacEncoder, hAacEncoder->InitFlags, &hAacEncoder->extParam);
+
+ if (err != AACENC_OK) {
+ /* keep init flags alive! */
+ goto bail;
+ }
+ hAacEncoder->InitFlags = AACENC_INIT_NONE;
+ }
+
+ if (outargs != NULL) {
+ FDKmemclear(outargs, sizeof(AACENC_OutArgs));
+ }
+
+ if (outBufDesc != NULL) {
+ for (i = 0; i < outBufDesc->numBufs; i++) {
+ if (outBufDesc->bufs[i] != NULL) {
+ FDKmemclear(outBufDesc->bufs[i], outBufDesc->bufSizes[i]);
+ }
+ }
+ }
+
+ /*
+ * If only encoder handle given, independent (re)initialization can be
+ * triggered.
+ */
+ if ((inBufDesc == NULL) && (outBufDesc == NULL) && (inargs == NULL) &&
+ (outargs == NULL)) {
+ goto bail;
+ }
+
+ /* check if buffer descriptors are filled out properly. */
+ if ((inargs == NULL) || (outargs == NULL) ||
+ ((AACENC_OK != validateBufDesc(inBufDesc)) &&
+ (inargs->numInSamples > 0)) ||
+ (AACENC_OK != validateBufDesc(outBufDesc))) {
+ err = AACENC_UNSUPPORTED_PARAMETER;
+ goto bail;
+ }
+
+ /* reset buffer wich signals number of valid bytes in output bitstream buffer
+ */
+ FDKmemclear(outBytes, hAacEncoder->aacConfig.nSubFrames * sizeof(INT));
+
+ /*
+ * Manage incoming audio samples.
+ */
+ if ((inBufDesc != NULL) && (inargs->numInSamples > 0) &&
+ (getBufDescIdx(inBufDesc, IN_AUDIO_DATA) != -1)) {
+ /* Fetch data until nSamplesToRead reached */
+ INT idx = getBufDescIdx(inBufDesc, IN_AUDIO_DATA);
+ INT newSamples =
+ fixMax(0, fixMin(inargs->numInSamples, hAacEncoder->nSamplesToRead -
+ hAacEncoder->nSamplesRead));
+ INT_PCM *pIn =
+ hAacEncoder->inputBuffer +
+ (hAacEncoder->inputBufferOffset + hAacEncoder->nSamplesRead) /
+ hAacEncoder->aacConfig.nChannels;
+
+ /* Copy new input samples to internal buffer */
+ if (inBufDesc->bufElSizes[idx] == (INT)sizeof(INT_PCM)) {
+ FDK_deinterleave((INT_PCM *)inBufDesc->bufs[idx], pIn,
+ hAacEncoder->extParam.nChannels,
+ newSamples / hAacEncoder->extParam.nChannels,
+ hAacEncoder->inputBufferSizePerChannel);
+ } else if (inBufDesc->bufElSizes[idx] > (INT)sizeof(INT_PCM)) {
+ FDK_deinterleave((LONG *)inBufDesc->bufs[idx], pIn,
+ hAacEncoder->extParam.nChannels,
+ newSamples / hAacEncoder->extParam.nChannels,
+ hAacEncoder->inputBufferSizePerChannel);
+ } else {
+ FDK_deinterleave((SHORT *)inBufDesc->bufs[idx], pIn,
+ hAacEncoder->extParam.nChannels,
+ newSamples / hAacEncoder->extParam.nChannels,
+ hAacEncoder->inputBufferSizePerChannel);
+ }
+ hAacEncoder->nSamplesRead += newSamples;
+
+ /* Number of fetched input buffer samples. */
+ outargs->numInSamples = newSamples;
+ }
+
+ /* input buffer completely filled ? */
+ if (hAacEncoder->nSamplesRead < hAacEncoder->nSamplesToRead) {
+ /* - eof reached and flushing enabled, or
+ - return to main and wait for further incoming audio samples */
+ if (inargs->numInSamples == -1) {
+ if ((hAacEncoder->nZerosAppended < hAacEncoder->nDelay)) {
+ int nZeros = (hAacEncoder->nSamplesToRead - hAacEncoder->nSamplesRead) /
+ hAacEncoder->extParam.nChannels;
+
+ FDK_ASSERT(nZeros >= 0);
+
+ /* clear out until end-of-buffer */
+ if (nZeros) {
+ for (i = 0; i < (int)hAacEncoder->extParam.nChannels; i++) {
+ FDKmemclear(hAacEncoder->inputBuffer +
+ i * hAacEncoder->inputBufferSizePerChannel +
+ (hAacEncoder->inputBufferOffset +
+ hAacEncoder->nSamplesRead) /
+ hAacEncoder->extParam.nChannels,
+ sizeof(INT_PCM) * nZeros);
+ }
+ hAacEncoder->nZerosAppended += nZeros;
+ hAacEncoder->nSamplesRead = hAacEncoder->nSamplesToRead;
+ }
+ } else { /* flushing completed */
+ err = AACENC_ENCODE_EOF; /* eof reached */
+ goto bail;
+ }
+ } else { /* inargs->numInSamples!= -1 */
+ goto bail; /* not enough samples in input buffer and no flushing enabled
+ */
+ }
+ }
+
+ /* init payload */
+ FDKmemclear(hAacEncoder->extPayload,
+ sizeof(AACENC_EXT_PAYLOAD) * MAX_TOTAL_EXT_PAYLOADS);
+ for (i = 0; i < MAX_TOTAL_EXT_PAYLOADS; i++) {
+ hAacEncoder->extPayload[i].associatedChElement = -1;
+ }
+ if (hAacEncoder->pSbrPayload != NULL) {
+ FDKmemclear(hAacEncoder->pSbrPayload, sizeof(*hAacEncoder->pSbrPayload));
+ }
+
+ /*
+ * Calculate Meta Data info.
+ */
+ if ((hAacEncoder->hMetadataEnc != NULL) &&
+ (hAacEncoder->metaDataAllowed != 0)) {
+ const AACENC_MetaData *pMetaData = NULL;
+ AACENC_EXT_PAYLOAD *pMetaDataExtPayload = NULL;
+ UINT nMetaDataExtensions = 0;
+ INT matrix_mixdown_idx = 0;
+
+ /* New meta data info available ? */
+ if (getBufDescIdx(inBufDesc, IN_METADATA_SETUP) != -1) {
+ pMetaData =
+ (AACENC_MetaData *)
+ inBufDesc->bufs[getBufDescIdx(inBufDesc, IN_METADATA_SETUP)];
+ }
+
+ FDK_MetadataEnc_Process(
+ hAacEncoder->hMetadataEnc,
+ hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset /
+ hAacEncoder->coderConfig.noChannels,
+ hAacEncoder->inputBufferSizePerChannel, hAacEncoder->nSamplesRead,
+ pMetaData, &pMetaDataExtPayload, &nMetaDataExtensions,
+ &matrix_mixdown_idx);
+
+ for (i = 0; i < (INT)nMetaDataExtensions;
+ i++) { /* Get meta data extension payload. */
+ hAacEncoder->extPayload[nExtensions++] = pMetaDataExtPayload[i];
+ }
+
+ if ((matrix_mixdown_idx != -1) &&
+ ((hAacEncoder->extParam.userChannelMode == MODE_1_2_2) ||
+ (hAacEncoder->extParam.userChannelMode == MODE_1_2_2_1))) {
+ /* Set matrix mixdown coefficient. */
+ UINT pceValue = (UINT)((0 << 3) | ((matrix_mixdown_idx & 0x3) << 1) | 1);
+ if (hAacEncoder->extParam.userPceAdditions != pceValue) {
+ hAacEncoder->extParam.userPceAdditions = pceValue;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ }
+ }
+
+ /*
+ * Encode MPS data.
+ */
+ if ((hAacEncoder->hMpsEnc != NULL) &&
+ (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) {
+ AACENC_EXT_PAYLOAD mpsExtensionPayload;
+ FDKmemclear(&mpsExtensionPayload, sizeof(AACENC_EXT_PAYLOAD));
+
+ if (MPS_ENCODER_OK !=
+ FDK_MpegsEnc_Process(
+ hAacEncoder->hMpsEnc,
+ hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset /
+ hAacEncoder->coderConfig.noChannels,
+ hAacEncoder->nSamplesRead, &mpsExtensionPayload)) {
+ err = AACENC_ENCODE_ERROR;
+ goto bail;
+ }
+
+ if ((mpsExtensionPayload.pData != NULL) &&
+ ((mpsExtensionPayload.dataSize != 0))) {
+ hAacEncoder->extPayload[nExtensions++] = mpsExtensionPayload;
+ }
+ }
+
+ if ((NULL != hAacEncoder->hEnvEnc) && (NULL != hAacEncoder->pSbrPayload) &&
+ isSbrActive(&hAacEncoder->aacConfig)) {
+ INT nPayload = 0;
+
+ /*
+ * Encode SBR data.
+ */
+ if (sbrEncoder_EncodeFrame(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer,
+ hAacEncoder->inputBufferSizePerChannel,
+ hAacEncoder->pSbrPayload->dataSize[nPayload],
+ hAacEncoder->pSbrPayload->data[nPayload])) {
+ err = AACENC_ENCODE_ERROR;
+ goto bail;
+ } else {
+ /* Add SBR extension payload */
+ for (i = 0; i < (8); i++) {
+ if (hAacEncoder->pSbrPayload->dataSize[nPayload][i] > 0) {
+ hAacEncoder->extPayload[nExtensions].pData =
+ hAacEncoder->pSbrPayload->data[nPayload][i];
+ {
+ hAacEncoder->extPayload[nExtensions].dataSize =
+ hAacEncoder->pSbrPayload->dataSize[nPayload][i];
+ hAacEncoder->extPayload[nExtensions].associatedChElement = i;
+ }
+ hAacEncoder->extPayload[nExtensions].dataType =
+ EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set
+ EXT_SBR_DATA_CRC */
+ nExtensions++; /* or EXT_SBR_DATA according to configuration. */
+ FDK_ASSERT(nExtensions <= MAX_TOTAL_EXT_PAYLOADS);
+ }
+ }
+ nPayload++;
+ }
+ } /* sbrEnabled */
+
+ if ((inargs->numAncBytes > 0) &&
+ (getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA) != -1)) {
+ INT idx = getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA);
+ hAacEncoder->extPayload[nExtensions].dataSize = inargs->numAncBytes * 8;
+ hAacEncoder->extPayload[nExtensions].pData = (UCHAR *)inBufDesc->bufs[idx];
+ hAacEncoder->extPayload[nExtensions].dataType = EXT_DATA_ELEMENT;
+ hAacEncoder->extPayload[nExtensions].associatedChElement = -1;
+ ancDataExtIdx = nExtensions; /* store index */
+ nExtensions++;
+ }
+
+ /*
+ * Encode AAC - Core.
+ */
+ if (FDKaacEnc_EncodeFrame(hAacEncoder->hAacEnc, hAacEncoder->hTpEnc,
+ hAacEncoder->inputBuffer,
+ hAacEncoder->inputBufferSizePerChannel, outBytes,
+ hAacEncoder->extPayload) != AAC_ENC_OK) {
+ err = AACENC_ENCODE_ERROR;
+ goto bail;
+ }
+
+ if (ancDataExtIdx >= 0) {
+ outargs->numAncBytes =
+ inargs->numAncBytes -
+ (hAacEncoder->extPayload[ancDataExtIdx].dataSize >> 3);
+ }
+
+ /* samples exhausted */
+ hAacEncoder->nSamplesRead -= hAacEncoder->nSamplesToRead;
+
+ /*
+ * Delay balancing buffer handling
+ */
+ if (isSbrActive(&hAacEncoder->aacConfig)) {
+ sbrEncoder_UpdateBuffers(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer,
+ hAacEncoder->inputBufferSizePerChannel);
+ }
+
+ /*
+ * Make bitstream public
+ */
+ if ((outBufDesc != NULL) && (outBufDesc->numBufs >= 1)) {
+ INT bsIdx = getBufDescIdx(outBufDesc, OUT_BITSTREAM_DATA);
+ INT auIdx = getBufDescIdx(outBufDesc, OUT_AU_SIZES);
+
+ for (i = 0, nBsBytes = 0; i < hAacEncoder->aacConfig.nSubFrames; i++) {
+ nBsBytes += outBytes[i];
+
+ if (auIdx != -1) {
+ ((INT *)outBufDesc->bufs[auIdx])[i] = outBytes[i];
+ }
+ }
+
+ if ((bsIdx != -1) && (outBufDesc->bufSizes[bsIdx] >= nBsBytes)) {
+ FDKmemcpy(outBufDesc->bufs[bsIdx], hAacEncoder->outBuffer,
+ sizeof(UCHAR) * nBsBytes);
+ outargs->numOutBytes = nBsBytes;
+ outargs->bitResState =
+ FDKaacEnc_GetBitReservoirState(hAacEncoder->hAacEnc);
+ } else {
+ /* output buffer too small, can't write valid bitstream */
+ err = AACENC_ENCODE_ERROR;
+ goto bail;
+ }
+ }
+
+bail:
+ if (err == AACENC_ENCODE_ERROR) {
+ /* All encoder modules have to be initialized */
+ hAacEncoder->InitFlags = AACENC_INIT_ALL;
+ }
+
+ return err;
+}
+
+static AAC_ENCODER_ERROR aacEncGetConf(HANDLE_AACENCODER hAacEncoder,
+ UINT *size, UCHAR *confBuffer) {
+ FDK_BITSTREAM tmpConf;
+ UINT confType;
+ UCHAR buf[64];
+ int err;
+
+ /* Init bit buffer */
+ FDKinitBitStream(&tmpConf, buf, 64, 0, BS_WRITER);
+
+ /* write conf in tmp buffer */
+ err = transportEnc_GetConf(hAacEncoder->hTpEnc, &hAacEncoder->coderConfig,
+ &tmpConf, &confType);
+
+ /* copy data to outbuffer: length in bytes */
+ FDKbyteAlign(&tmpConf, 0);
+
+ /* Check buffer size */
+ if (FDKgetValidBits(&tmpConf) > ((*size) << 3)) return AAC_ENC_UNKNOWN;
+
+ FDKfetchBuffer(&tmpConf, confBuffer, size);
+
+ if (err != 0)
+ return AAC_ENC_UNKNOWN;
+ else
+ return AAC_ENC_OK;
+}
+
+AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info) {
+ int i = 0;
+
+ if (info == NULL) {
+ return AACENC_INVALID_HANDLE;
+ }
+
+ FDK_toolsGetLibInfo(info);
+ transportEnc_GetLibInfo(info);
+ sbrEncoder_GetLibInfo(info);
+ FDK_MpegsEnc_GetLibInfo(info);
+
+ /* search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) {
+ return AACENC_INIT_ERROR;
+ }
+
+ info[i].module_id = FDK_AACENC;
+ info[i].build_date = AACENCODER_LIB_BUILD_DATE;
+ info[i].build_time = AACENCODER_LIB_BUILD_TIME;
+ info[i].title = AACENCODER_LIB_TITLE;
+ info[i].version =
+ LIB_VERSION(AACENCODER_LIB_VL0, AACENCODER_LIB_VL1, AACENCODER_LIB_VL2);
+ ;
+ LIB_VERSION_STRING(&info[i]);
+
+ /* Capability flags */
+ info[i].flags = 0 | CAPF_AAC_1024 | CAPF_AAC_LC | CAPF_AAC_960| CAPF_AAC_512 |
+ CAPF_AAC_480 | CAPF_AAC_DRC | CAPF_AAC_ELD_DOWNSCALE;
+ /* End of flags */
+
+ return AACENC_OK;
+}
+
+AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
+ const AACENC_PARAM param, const UINT value) {
+ AACENC_ERROR err = AACENC_OK;
+ USER_PARAM *settings = &hAacEncoder->extParam;
+
+ /* check encoder handle */
+ if (hAacEncoder == NULL) {
+ err = AACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* apply param value */
+ switch (param) {
+ case AACENC_AOT:
+ if (settings->userAOT != (AUDIO_OBJECT_TYPE)value) {
+ /* check if AOT matches the allocated modules */
+ switch (value) {
+ case AOT_PS:
+ case AOT_DABPLUS_PS:
+ if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) {
+ err = AACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ FDK_FALLTHROUGH;
+ case AOT_SBR:
+ case AOT_MP2_SBR:
+ case AOT_DABPLUS_SBR:
+ if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) {
+ err = AACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ FDK_FALLTHROUGH;
+ case AOT_AAC_LC:
+ case AOT_MP2_AAC_LC:
+ case AOT_DABPLUS_AAC_LC:
+ case AOT_ER_AAC_LD:
+ case AOT_ER_AAC_ELD:
+ if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) {
+ err = AACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ break;
+ default:
+ err = AACENC_INVALID_CONFIG;
+ goto bail;
+ } /* switch value */
+ settings->userAOT = (AUDIO_OBJECT_TYPE)value;
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_BITRATE:
+ if (settings->userBitrate != value) {
+ settings->userBitrate = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_BITRATEMODE:
+ if (settings->userBitrateMode != value) {
+ switch (value) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 7:
+ case 8:
+ settings->userBitrateMode = value;
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
+ break;
+ default:
+ err = AACENC_INVALID_CONFIG;
+ break;
+ } /* switch value */
+ }
+ break;
+ case AACENC_SAMPLERATE:
+ if (settings->userSamplerate != value) {
+ if (!((value == 8000) || (value == 11025) || (value == 12000) ||
+ (value == 16000) || (value == 22050) || (value == 24000) ||
+ (value == 32000) || (value == 44100) || (value == 48000) ||
+ (value == 64000) || (value == 88200) || (value == 96000))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userSamplerate = value;
+ hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_CHANNELMODE:
+ if (settings->userChannelMode != (CHANNEL_MODE)value) {
+ if (((CHANNEL_MODE)value == MODE_212) &&
+ (NULL != hAacEncoder->hMpsEnc)) {
+ settings->userChannelMode = (CHANNEL_MODE)value;
+ settings->nChannels = 2;
+ } else {
+ const CHANNEL_MODE_CONFIG_TAB *pConfig =
+ FDKaacEnc_GetChannelModeConfiguration((CHANNEL_MODE)value);
+ if (pConfig == NULL) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ if ((pConfig->nElements > hAacEncoder->nMaxAacElements) ||
+ (pConfig->nChannelsEff > hAacEncoder->nMaxAacChannels)) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+
+ settings->userChannelMode = (CHANNEL_MODE)value;
+ settings->nChannels = pConfig->nChannels;
+ }
+ hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
+ if (!((value >= 1) && (value <= 6))) {
+ hAacEncoder->InitFlags |= AACENC_INIT_STATES;
+ }
+ }
+ break;
+ case AACENC_BANDWIDTH:
+ if (settings->userBandwidth != value) {
+ settings->userBandwidth = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
+ }
+ break;
+ case AACENC_CHANNELORDER:
+ if (hAacEncoder->aacConfig.channelOrder != (CHANNEL_ORDER)value) {
+ if (!((value == 0) || (value == 1) || (value == 2))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ hAacEncoder->aacConfig.channelOrder = (CHANNEL_ORDER)value;
+ hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_AFTERBURNER:
+ if (settings->userAfterburner != value) {
+ if (!((value == 0) || (value == 1))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userAfterburner = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
+ }
+ break;
+ case AACENC_GRANULE_LENGTH:
+ if (settings->userFramelength != value) {
+ switch (value) {
+ case 1024:
+ case 960:
+ case 512:
+ case 480:
+ case 256:
+ case 240:
+ case 128:
+ case 120:
+ if ((value << 1) == 480 || (value << 1) == 512) {
+ settings->userDownscaleFactor = 2;
+ } else if ((value << 2) == 480 || (value << 2) == 512) {
+ settings->userDownscaleFactor = 4;
+ }
+ settings->userFramelength = value;
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
+ break;
+ default:
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ }
+ break;
+ case AACENC_SBR_RATIO:
+ if (settings->userSbrRatio != value) {
+ if (!((value == 0) || (value == 1) || (value == 2))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userSbrRatio = value;
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_SBR_MODE:
+ if ((settings->userSbrEnabled != value) &&
+ (NULL != hAacEncoder->hEnvEnc)) {
+ settings->userSbrEnabled = value;
+ hAacEncoder->InitFlags |=
+ AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_TRANSMUX:
+ if (settings->userTpType != (TRANSPORT_TYPE)value) {
+ TRANSPORT_TYPE type = (TRANSPORT_TYPE)value;
+ UINT flags = hAacEncoder->CAPF_tpEnc;
+
+ if (!(((type == TT_MP4_ADIF) && (flags & CAPF_ADIF)) ||
+ ((type == TT_MP4_ADTS) && (flags & CAPF_ADTS)) ||
+ ((type == TT_MP4_LATM_MCP0) &&
+ ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
+ ((type == TT_MP4_LATM_MCP1) &&
+ ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
+ ((type == TT_MP4_LOAS) && (flags & CAPF_LOAS)) ||
+ ((type == TT_MP4_RAW) && (flags & CAPF_RAWPACKETS)) ||
+ ((type == TT_DABPLUS) && ((flags & CAPF_DAB_AAC) && (flags & CAPF_RAWPACKETS))) )) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpType = (TRANSPORT_TYPE)value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_SIGNALING_MODE:
+ if (settings->userTpSignaling != value) {
+ if (!((value == 0) || (value == 1) || (value == 2))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpSignaling = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_PROTECTION:
+ if (settings->userTpProtection != value) {
+ if (!((value == 0) || (value == 1))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpProtection = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_HEADER_PERIOD:
+ if (settings->userTpHeaderPeriod != value) {
+ if (!(((INT)value >= 0) && (value <= 255))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpHeaderPeriod = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ 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:
+ if (settings->userTpNsubFrames != value) {
+ if (!((value >= 1) && (value <= 6))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpNsubFrames = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ break;
+ case AACENC_ANCILLARY_BITRATE:
+ if (settings->userAncDataRate != value) {
+ settings->userAncDataRate = value;
+ }
+ break;
+ case AACENC_CONTROL_STATE:
+ if (hAacEncoder->InitFlags != value) {
+ if (value & AACENC_RESET_INBUFFER) {
+ hAacEncoder->nSamplesRead = 0;
+ }
+ hAacEncoder->InitFlags = value;
+ }
+ break;
+ case AACENC_METADATA_MODE:
+ if ((UINT)settings->userMetaDataMode != value) {
+ if (!(((INT)value >= 0) && ((INT)value <= 3))) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userMetaDataMode = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
+ }
+ break;
+ case AACENC_PEAK_BITRATE:
+ if (settings->userPeakBitrate != value) {
+ settings->userPeakBitrate = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
+ }
+ break;
+ default:
+ err = AACENC_UNSUPPORTED_PARAMETER;
+ break;
+ } /* switch(param) */
+
+bail:
+ return err;
+}
+
+UINT aacEncoder_GetParam(const HANDLE_AACENCODER hAacEncoder,
+ const AACENC_PARAM param) {
+ UINT value = 0;
+ USER_PARAM *settings = &hAacEncoder->extParam;
+
+ /* check encoder handle */
+ if (hAacEncoder == NULL) {
+ goto bail;
+ }
+
+ /* apply param value */
+ switch (param) {
+ case AACENC_AOT:
+ value = (UINT)hAacEncoder->aacConfig.audioObjectType;
+ break;
+ case AACENC_BITRATE:
+ switch (hAacEncoder->aacConfig.bitrateMode) {
+ case AACENC_BR_MODE_CBR:
+ value = (UINT)hAacEncoder->aacConfig.bitRate;
+ break;
+ default:
+ value = (UINT)-1;
+ }
+ break;
+ case AACENC_BITRATEMODE:
+ value = (UINT)((hAacEncoder->aacConfig.bitrateMode != AACENC_BR_MODE_FF)
+ ? hAacEncoder->aacConfig.bitrateMode
+ : AACENC_BR_MODE_CBR);
+ break;
+ case AACENC_SAMPLERATE:
+ value = (UINT)hAacEncoder->coderConfig.extSamplingRate;
+ break;
+ case AACENC_CHANNELMODE:
+ if ((MODE_1 == hAacEncoder->aacConfig.channelMode) &&
+ (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) {
+ value = MODE_212;
+ } else {
+ value = (UINT)hAacEncoder->aacConfig.channelMode;
+ }
+ break;
+ case AACENC_BANDWIDTH:
+ value = (UINT)hAacEncoder->aacConfig.bandWidth;
+ break;
+ case AACENC_CHANNELORDER:
+ value = (UINT)hAacEncoder->aacConfig.channelOrder;
+ break;
+ case AACENC_AFTERBURNER:
+ value = (UINT)hAacEncoder->aacConfig.useRequant;
+ break;
+ case AACENC_GRANULE_LENGTH:
+ value = (UINT)hAacEncoder->aacConfig.framelength;
+ break;
+ case AACENC_SBR_RATIO:
+ value = isSbrActive(&hAacEncoder->aacConfig)
+ ? hAacEncoder->aacConfig.sbrRatio
+ : 0;
+ break;
+ case AACENC_SBR_MODE:
+ value =
+ (UINT)(hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0;
+ break;
+ case AACENC_TRANSMUX:
+ value = (UINT)settings->userTpType;
+ break;
+ case AACENC_SIGNALING_MODE:
+ value = (UINT)getSbrSignalingMode(
+ hAacEncoder->aacConfig.audioObjectType, settings->userTpType,
+ settings->userTpSignaling, hAacEncoder->aacConfig.sbrRatio);
+ break;
+ case AACENC_PROTECTION:
+ value = (UINT)settings->userTpProtection;
+ break;
+ case AACENC_HEADER_PERIOD:
+ value = (UINT)hAacEncoder->coderConfig.headerPeriod;
+ break;
+ case AACENC_AUDIOMUXVER:
+ value = (UINT)hAacEncoder->aacConfig.audioMuxVersion;
+ break;
+ case AACENC_TPSUBFRAMES:
+ value = (UINT)settings->userTpNsubFrames;
+ break;
+ case AACENC_ANCILLARY_BITRATE:
+ value = (UINT)hAacEncoder->aacConfig.anc_Rate;
+ break;
+ case AACENC_CONTROL_STATE:
+ value = (UINT)hAacEncoder->InitFlags;
+ break;
+ case AACENC_METADATA_MODE:
+ value = (hAacEncoder->metaDataAllowed == 0)
+ ? 0
+ : (UINT)settings->userMetaDataMode;
+ 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:
+ // err = MPS_INVALID_PARAMETER;
+ break;
+ } /* switch(param) */
+
+bail:
+ return value;
+}
+
+AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder,
+ AACENC_InfoStruct *pInfo) {
+ AACENC_ERROR err = AACENC_OK;
+
+ FDKmemclear(pInfo, sizeof(AACENC_InfoStruct));
+ pInfo->confSize = 64; /* pre-initialize */
+
+ pInfo->maxOutBufBytes = ((hAacEncoder->nMaxAacChannels * 6144) + 7) >> 3;
+ pInfo->maxAncBytes = hAacEncoder->aacConfig.maxAncBytesPerAU;
+ pInfo->inBufFillLevel =
+ hAacEncoder->nSamplesRead / hAacEncoder->extParam.nChannels;
+ pInfo->inputChannels = hAacEncoder->extParam.nChannels;
+ pInfo->frameLength =
+ hAacEncoder->nSamplesToRead / hAacEncoder->extParam.nChannels;
+ pInfo->nDelay = hAacEncoder->nDelay;
+ pInfo->nDelayCore = hAacEncoder->nDelayCore;
+
+ /* Get encoder configuration */
+ if (aacEncGetConf(hAacEncoder, &pInfo->confSize, &pInfo->confBuf[0]) !=
+ AAC_ENC_OK) {
+ err = AACENC_INIT_ERROR;
+ goto bail;
+ }
+bail:
+ return err;
+}
diff --git a/fdk-aac/libAACenc/src/aacenc_pns.cpp b/fdk-aac/libAACenc/src/aacenc_pns.cpp
new file mode 100644
index 0000000..f0571d6
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc_pns.cpp
@@ -0,0 +1,541 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: pns.c
+
+*******************************************************************************/
+
+#include "aacenc_pns.h"
+
+#include "psy_data.h"
+#include "pnsparam.h"
+#include "noisedet.h"
+#include "bit_cnt.h"
+#include "interface.h"
+
+/* minCorrelationEnergy = (1.0e-10f)^2 ~ 2^-67 = 2^-47 * 2^-20 */
+static const FIXP_DBL minCorrelationEnergy =
+ FL2FXCONST_DBL(0.0); /* FL2FXCONST_DBL((float)FDKpow(2.0,-47)); */
+/* noiseCorrelationThresh = 0.6^2 */
+static const FIXP_DBL noiseCorrelationThresh = FL2FXCONST_DBL(0.36);
+
+static void FDKaacEnc_FDKaacEnc_noiseDetection(
+ PNS_CONFIG *pnsConf, PNS_DATA *pnsData, const INT sfbActive,
+ const INT *sfbOffset, INT tnsOrder, INT tnsPredictionGain, INT tnsActive,
+ FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality);
+
+static void FDKaacEnc_CalcNoiseNrgs(const INT sfbActive, INT *pnsFlag,
+ FIXP_DBL *sfbEnergyLdData, INT *noiseNrg);
+
+/*****************************************************************************
+
+ functionname: initPnsConfiguration
+ description: fill pnsConf with pns parameters
+ returns: error status
+ input: PNS Config struct (modified)
+ bitrate, samplerate, usePns,
+ number of sfb's, pointer to sfb offset
+ output: error code
+
+*****************************************************************************/
+
+AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(
+ PNS_CONFIG *pnsConf, INT bitRate, INT sampleRate, INT usePns, INT sfbCnt,
+ const INT *sfbOffset, const INT numChan, const INT isLC) {
+ AAC_ENCODER_ERROR ErrorStatus;
+
+ /* init noise detection */
+ ErrorStatus = FDKaacEnc_GetPnsParam(&pnsConf->np, bitRate, sampleRate, sfbCnt,
+ sfbOffset, &usePns, numChan, isLC);
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ pnsConf->minCorrelationEnergy = minCorrelationEnergy;
+ pnsConf->noiseCorrelationThresh = noiseCorrelationThresh;
+
+ pnsConf->usePns = usePns;
+
+ return AAC_ENC_OK;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_PnsDetect
+ description: do decision, if PNS shall used or not
+ returns:
+ input: pns config structure
+ pns data structure (modified),
+ lastWindowSequence (long or short blocks)
+ sfbActive
+ pointer to Sfb Energy, Threshold, Offset
+ pointer to mdct Spectrum
+ length of each group
+ pointer to tonality calculated in chaosmeasure
+ tns order and prediction gain
+ calculated noiseNrg at active PNS
+ output: pnsFlag in pns data structure
+
+*****************************************************************************/
+void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, PNS_DATA *pnsData,
+ const INT lastWindowSequence, const INT sfbActive,
+ const INT maxSfbPerGroup, FIXP_DBL *sfbThresholdLdData,
+ const INT *sfbOffset, FIXP_DBL *mdctSpectrum,
+ INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality,
+ INT tnsOrder, INT tnsPredictionGain, INT tnsActive,
+ FIXP_DBL *sfbEnergyLdData, INT *noiseNrg)
+
+{
+ int sfb;
+ int startNoiseSfb;
+
+ /* Reset pns info. */
+ FDKmemclear(pnsData->pnsFlag, sizeof(pnsData->pnsFlag));
+ for (sfb = 0; sfb < MAX_GROUPED_SFB; sfb++) {
+ noiseNrg[sfb] = NO_NOISE_PNS;
+ }
+
+ /* Disable PNS and skip detection in certain cases. */
+ if (pnsConf->usePns == 0) {
+ return;
+ } else {
+ /* AAC - LC core encoder */
+ if ((pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) &&
+ (lastWindowSequence == SHORT_WINDOW)) {
+ return;
+ }
+ /* AAC - (E)LD core encoder */
+ if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) &&
+ (pnsConf->np.detectionAlgorithmFlags & JUST_LONG_WINDOW) &&
+ (lastWindowSequence != LONG_WINDOW)) {
+ return;
+ }
+ }
+
+ /*
+ call noise detection
+ */
+ FDKaacEnc_FDKaacEnc_noiseDetection(
+ pnsConf, pnsData, sfbActive, sfbOffset, tnsOrder, tnsPredictionGain,
+ tnsActive, mdctSpectrum, sfbMaxScaleSpec, sfbtonality);
+
+ /* set startNoiseSfb (long) */
+ startNoiseSfb = pnsConf->np.startSfb;
+
+ /* Set noise substitution status */
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ /* No PNS below startNoiseSfb */
+ if (sfb < startNoiseSfb) {
+ pnsData->pnsFlag[sfb] = 0;
+ continue;
+ }
+
+ /*
+ do noise substitution if
+ fuzzy measure is high enough
+ sfb freq > minimum sfb freq
+ signal in coder band is not masked
+ */
+
+ if ((pnsData->noiseFuzzyMeasure[sfb] > FL2FXCONST_SGL(0.5)) &&
+ ((sfbThresholdLdData[sfb] +
+ FL2FXCONST_DBL(0.5849625f /
+ 64.0f)) /* thr * 1.5 = thrLd +ld(1.5)/64 */
+ < sfbEnergyLdData[sfb])) {
+ /*
+ mark in psyout flag array that we will code
+ this band with PNS
+ */
+ pnsData->pnsFlag[sfb] = 1; /* PNS_ON */
+ } else {
+ pnsData->pnsFlag[sfb] = 0; /* PNS_OFF */
+ }
+
+ /* no PNS if LTP is active */
+ }
+
+ /* avoid PNS holes */
+ if ((pnsData->noiseFuzzyMeasure[0] > FL2FXCONST_SGL(0.5f)) &&
+ (pnsData->pnsFlag[1])) {
+ pnsData->pnsFlag[0] = 1;
+ }
+
+ for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) {
+ if ((pnsData->noiseFuzzyMeasure[sfb] > pnsConf->np.gapFillThr) &&
+ (pnsData->pnsFlag[sfb - 1]) && (pnsData->pnsFlag[sfb + 1])) {
+ pnsData->pnsFlag[sfb] = 1;
+ }
+ }
+
+ if (maxSfbPerGroup > 0) {
+ /* avoid PNS hole */
+ if ((pnsData->noiseFuzzyMeasure[maxSfbPerGroup - 1] >
+ pnsConf->np.gapFillThr) &&
+ (pnsData->pnsFlag[maxSfbPerGroup - 2])) {
+ pnsData->pnsFlag[maxSfbPerGroup - 1] = 1;
+ }
+ /* avoid single PNS band */
+ if (pnsData->pnsFlag[maxSfbPerGroup - 2] == 0) {
+ pnsData->pnsFlag[maxSfbPerGroup - 1] = 0;
+ }
+ }
+
+ /* avoid single PNS bands */
+ if (pnsData->pnsFlag[1] == 0) {
+ pnsData->pnsFlag[0] = 0;
+ }
+
+ for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) {
+ if ((pnsData->pnsFlag[sfb - 1] == 0) && (pnsData->pnsFlag[sfb + 1] == 0)) {
+ pnsData->pnsFlag[sfb] = 0;
+ }
+ }
+
+ /*
+ calculate noiseNrg's
+ */
+ FDKaacEnc_CalcNoiseNrgs(sfbActive, pnsData->pnsFlag, sfbEnergyLdData,
+ noiseNrg);
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_FDKaacEnc_noiseDetection
+ description: wrapper for noisedet.c
+ returns:
+ input: pns config structure
+ pns data structure (modified),
+ sfbActive
+ tns order and prediction gain
+ pointer to mdct Spectrumand Sfb Energy
+ pointer to Sfb tonality
+ output: noiseFuzzyMeasure in structure pnsData
+ flags tonal / nontonal
+
+*****************************************************************************/
+static void FDKaacEnc_FDKaacEnc_noiseDetection(
+ PNS_CONFIG *pnsConf, PNS_DATA *pnsData, const INT sfbActive,
+ const INT *sfbOffset, int tnsOrder, INT tnsPredictionGain, INT tnsActive,
+ FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality) {
+ INT condition = TRUE;
+ if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY)) {
+ condition = (tnsOrder > 3);
+ }
+ /*
+ no PNS if heavy TNS activity
+ clear pnsData->noiseFuzzyMeasure
+ */
+ if ((pnsConf->np.detectionAlgorithmFlags & USE_TNS_GAIN_THR) &&
+ (tnsPredictionGain >= pnsConf->np.tnsGainThreshold) && condition &&
+ !((pnsConf->np.detectionAlgorithmFlags & USE_TNS_PNS) &&
+ (tnsPredictionGain >= pnsConf->np.tnsPNSGainThreshold) &&
+ (tnsActive))) {
+ /* clear all noiseFuzzyMeasure */
+ FDKmemclear(pnsData->noiseFuzzyMeasure, sfbActive * sizeof(FIXP_SGL));
+ } else {
+ /*
+ call noise detection, output in pnsData->noiseFuzzyMeasure,
+ use real mdct spectral data
+ */
+ FDKaacEnc_noiseDetect(mdctSpectrum, sfbMaxScaleSpec, sfbActive, sfbOffset,
+ pnsData->noiseFuzzyMeasure, &pnsConf->np,
+ sfbtonality);
+ }
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_CalcNoiseNrgs
+ description: Calculate the NoiseNrg's
+ returns:
+ input: sfbActive
+ if pnsFlag calculate NoiseNrg
+ pointer to sfbEnergy and groupLen
+ pointer to noiseNrg (modified)
+ output: noiseNrg's in pnsFlaged sfb's
+
+*****************************************************************************/
+
+static void FDKaacEnc_CalcNoiseNrgs(const INT sfbActive, INT *RESTRICT pnsFlag,
+ FIXP_DBL *RESTRICT sfbEnergyLdData,
+ INT *RESTRICT noiseNrg) {
+ int sfb;
+ INT tmp = (-LOG_NORM_PCM) << 2;
+
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ if (pnsFlag[sfb]) {
+ INT nrg = (-sfbEnergyLdData[sfb] + FL2FXCONST_DBL(0.5f / 64.0f)) >>
+ (DFRACT_BITS - 1 - 7);
+ noiseNrg[sfb] = tmp - nrg;
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_CodePnsChannel
+ description: Execute pns decission
+ returns:
+ input: sfbActive
+ pns config structure
+ use PNS if pnsFlag
+ pointer to Sfb Energy, noiseNrg, Threshold
+ output: set sfbThreshold high to code pe with 0,
+ noiseNrg marks flag for pns coding
+
+*****************************************************************************/
+
+void FDKaacEnc_CodePnsChannel(const INT sfbActive, PNS_CONFIG *pnsConf,
+ INT *RESTRICT pnsFlag,
+ FIXP_DBL *RESTRICT sfbEnergyLdData,
+ INT *RESTRICT noiseNrg,
+ FIXP_DBL *RESTRICT sfbThresholdLdData) {
+ INT sfb;
+ INT lastiNoiseEnergy = 0;
+ INT firstPNSband = 1; /* TRUE for first PNS-coded band */
+
+ /* no PNS */
+ if (!pnsConf->usePns) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ /* no PNS coding */
+ noiseNrg[sfb] = NO_NOISE_PNS;
+ }
+ return;
+ }
+
+ /* code PNS */
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ if (pnsFlag[sfb]) {
+ /* high sfbThreshold causes pe = 0 */
+ if (noiseNrg[sfb] != NO_NOISE_PNS)
+ sfbThresholdLdData[sfb] =
+ sfbEnergyLdData[sfb] + FL2FXCONST_DBL(1.0f / LD_DATA_SCALING);
+
+ /* set noiseNrg in valid region */
+ if (!firstPNSband) {
+ INT deltaiNoiseEnergy = noiseNrg[sfb] - lastiNoiseEnergy;
+
+ if (deltaiNoiseEnergy > CODE_BOOK_PNS_LAV)
+ noiseNrg[sfb] -= deltaiNoiseEnergy - CODE_BOOK_PNS_LAV;
+ else if (deltaiNoiseEnergy < -CODE_BOOK_PNS_LAV)
+ noiseNrg[sfb] -= deltaiNoiseEnergy + CODE_BOOK_PNS_LAV;
+ } else {
+ firstPNSband = 0;
+ }
+ lastiNoiseEnergy = noiseNrg[sfb];
+ } else {
+ /* no PNS coding */
+ noiseNrg[sfb] = NO_NOISE_PNS;
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_PreProcessPnsChannelPair
+ description: Calculate the correlation of noise in a channel pair
+
+ returns:
+ input: sfbActive
+ pointer to sfb energies left, right and mid channel
+ pns config structure
+ pns data structure left and right (modified)
+
+ output: noiseEnergyCorrelation in pns data structure
+
+*****************************************************************************/
+
+void FDKaacEnc_PreProcessPnsChannelPair(
+ const INT sfbActive, FIXP_DBL *RESTRICT sfbEnergyLeft,
+ FIXP_DBL *RESTRICT sfbEnergyRight, FIXP_DBL *RESTRICT sfbEnergyLeftLD,
+ FIXP_DBL *RESTRICT sfbEnergyRightLD, FIXP_DBL *RESTRICT sfbEnergyMid,
+ PNS_CONFIG *RESTRICT pnsConf, PNS_DATA *pnsDataLeft,
+ PNS_DATA *pnsDataRight) {
+ INT sfb;
+ FIXP_DBL ccf;
+
+ if (!pnsConf->usePns) return;
+
+ FIXP_DBL *RESTRICT pNoiseEnergyCorrelationL =
+ pnsDataLeft->noiseEnergyCorrelation;
+ FIXP_DBL *RESTRICT pNoiseEnergyCorrelationR =
+ pnsDataRight->noiseEnergyCorrelation;
+
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ FIXP_DBL quot = (sfbEnergyLeftLD[sfb] >> 1) + (sfbEnergyRightLD[sfb] >> 1);
+
+ if (quot < FL2FXCONST_DBL(-32.0f / (float)LD_DATA_SCALING))
+ ccf = FL2FXCONST_DBL(0.0f);
+ else {
+ FIXP_DBL accu =
+ sfbEnergyMid[sfb] -
+ (((sfbEnergyLeft[sfb] >> 1) + (sfbEnergyRight[sfb] >> 1)) >> 1);
+ INT sign = (accu < FL2FXCONST_DBL(0.0f)) ? 1 : 0;
+ accu = fixp_abs(accu);
+
+ ccf = CalcLdData(accu) +
+ FL2FXCONST_DBL((float)1.0f / (float)LD_DATA_SCALING) -
+ quot; /* ld(accu*2) = ld(accu) + 1 */
+ ccf = (ccf >= FL2FXCONST_DBL(0.0))
+ ? ((FIXP_DBL)MAXVAL_DBL)
+ : (sign) ? -CalcInvLdData(ccf) : CalcInvLdData(ccf);
+ }
+
+ pNoiseEnergyCorrelationL[sfb] = ccf;
+ pNoiseEnergyCorrelationR[sfb] = ccf;
+ }
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_PostProcessPnsChannelPair
+ description: if PNS used at left and right channel,
+ use msMask to flag correlation
+ returns:
+ input: sfbActive
+ pns config structure
+ pns data structure left and right (modified)
+ pointer to msMask, flags correlation by pns coding (modified)
+ Digest of MS coding
+ output: pnsFlag in pns data structure,
+ msFlag in msMask (flags correlation)
+
+*****************************************************************************/
+
+void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive,
+ PNS_CONFIG *pnsConf,
+ PNS_DATA *pnsDataLeft,
+ PNS_DATA *pnsDataRight,
+ INT *RESTRICT msMask, INT *msDigest) {
+ INT sfb;
+
+ if (!pnsConf->usePns) return;
+
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ /*
+ MS post processing
+ */
+ if (msMask[sfb]) {
+ if ((pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb])) {
+ /* AAC only: Standard */
+ /* do this to avoid ms flags in layers that should not have it */
+ if (pnsDataLeft->noiseEnergyCorrelation[sfb] <=
+ pnsConf->noiseCorrelationThresh) {
+ msMask[sfb] = 0;
+ *msDigest = MS_SOME;
+ }
+ } else {
+ /*
+ No PNS coding
+ */
+ pnsDataLeft->pnsFlag[sfb] = 0;
+ pnsDataRight->pnsFlag[sfb] = 0;
+ }
+ }
+
+ /*
+ Use MS flag to signal noise correlation if
+ pns is active in both channels
+ */
+ if ((pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb])) {
+ if (pnsDataLeft->noiseEnergyCorrelation[sfb] >
+ pnsConf->noiseCorrelationThresh) {
+ msMask[sfb] = 1;
+ *msDigest = MS_SOME;
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACenc/src/aacenc_pns.h b/fdk-aac/libAACenc/src/aacenc_pns.h
new file mode 100644
index 0000000..4938fcf
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc_pns.h
@@ -0,0 +1,124 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: pns.h
+
+*******************************************************************************/
+
+#ifndef AACENC_PNS_H
+#define AACENC_PNS_H
+
+#include "common_fix.h"
+#include "pnsparam.h"
+
+#define NO_NOISE_PNS FDK_INT_MIN
+
+typedef struct {
+ NOISEPARAMS np;
+ FIXP_DBL minCorrelationEnergy;
+ FIXP_DBL noiseCorrelationThresh;
+ INT usePns;
+} PNS_CONFIG;
+
+typedef struct {
+ FIXP_SGL noiseFuzzyMeasure[MAX_GROUPED_SFB];
+ FIXP_DBL noiseEnergyCorrelation[MAX_GROUPED_SFB];
+ INT pnsFlag[MAX_GROUPED_SFB];
+} PNS_DATA;
+
+#endif /* AACENC_PNS_H */
diff --git a/fdk-aac/libAACenc/src/aacenc_tns.cpp b/fdk-aac/libAACenc/src/aacenc_tns.cpp
new file mode 100644
index 0000000..3436150
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc_tns.cpp
@@ -0,0 +1,1210 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Alex Groeschel, Tobias Chalupka
+
+ Description: Temporal noise shaping
+
+*******************************************************************************/
+
+#include "aacenc_tns.h"
+#include "psy_const.h"
+#include "psy_configuration.h"
+#include "tns_func.h"
+#include "aacEnc_rom.h"
+#include "aacenc_tns.h"
+#include "FDK_lpc.h"
+
+#define FILTER_DIRECTION 0 /* 0 = up, 1 = down */
+
+static const FIXP_DBL acfWindowLong[12 + 3 + 1] = {
+ 0x7fffffff, 0x7fb80000, 0x7ee00000, 0x7d780000, 0x7b800000, 0x78f80000,
+ 0x75e00000, 0x72380000, 0x6e000000, 0x69380000, 0x63e00000, 0x5df80000,
+ 0x57800000, 0x50780000, 0x48e00000, 0x40b80000};
+
+static const FIXP_DBL acfWindowShort[4 + 3 + 1] = {
+ 0x7fffffff, 0x7e000000, 0x78000000, 0x6e000000,
+ 0x60000000, 0x4e000000, 0x38000000, 0x1e000000};
+
+typedef struct {
+ INT bitRateFrom[2]; /* noneSbr=0, useSbr=1 */
+ INT bitRateTo[2]; /* noneSbr=0, useSbr=1 */
+ TNS_PARAMETER_TABULATED paramTab[2]; /* mono=0, stereo=1 */
+
+} TNS_INFO_TAB;
+
+#define TNS_TIMERES_SCALE (1)
+#define FL2_TIMERES_FIX(a) (FL2FXCONST_DBL(a / (float)(1 << TNS_TIMERES_SCALE)))
+
+static const TNS_INFO_TAB tnsInfoTab[] = {
+ {{16000, 13500},
+ {32000, 28000},
+ {{{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 12},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)},
+ 1},
+ {{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 12},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)},
+ 1}}},
+ {{32001, 28001},
+ {60000, 52000},
+ {{{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 10},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)},
+ 1},
+ {{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 10},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)},
+ 1}}},
+ {{60001, 52001},
+ {384000, 384000},
+ {{{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 8},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)},
+ 1},
+ {{1, 1},
+ {1437, 1500},
+ {1400, 600},
+ {12, 8},
+ {FILTER_DIRECTION, FILTER_DIRECTION},
+ {3, 1},
+ {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)},
+ 1}}}};
+
+typedef struct {
+ INT samplingRate;
+ SCHAR maxBands[2]; /* long=0; short=1 */
+
+} TNS_MAX_TAB_ENTRY;
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab1024[] = {
+ {96000, {31, 9}}, {88200, {31, 9}}, {64000, {34, 10}}, {48000, {40, 14}},
+ {44100, {42, 14}}, {32000, {51, 14}}, {24000, {46, 14}}, {22050, {46, 14}},
+ {16000, {42, 14}}, {12000, {42, 14}}, {11025, {42, 14}}, {8000, {39, 14}}};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab960[] =
+{
+ { 96000, { 31, 9}},
+ { 88200, { 31, 9}},
+ { 64000, { 34, 10}},
+ { 48000, { 49, 14}},
+ { 44100, { 49, 14}},
+ { 32000, { 49, 14}},
+ { 24000, { 46, 15}},
+ { 22050, { 46, 14}},
+ { 16000, { 46, 15}},
+ { 12000, { 42, 15}},
+ { 11025, { 42, 15}},
+ { 8000, { 40, 15}}
+};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab120[] = {
+ {48000, {12, -1}}, /* 48000 */
+ {44100, {12, -1}}, /* 44100 */
+ {32000, {15, -1}}, /* 32000 */
+ {24000, {15, -1}}, /* 24000 */
+ {22050, {15, -1}} /* 22050 */
+};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab128[] = {
+ {48000, {12, -1}}, /* 48000 */
+ {44100, {12, -1}}, /* 44100 */
+ {32000, {15, -1}}, /* 32000 */
+ {24000, {15, -1}}, /* 24000 */
+ {22050, {15, -1}} /* 22050 */
+};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab240[] = {
+ {96000, {22, -1}}, /* 96000 */
+ {48000, {22, -1}}, /* 48000 */
+ {44100, {22, -1}}, /* 44100 */
+ {32000, {21, -1}}, /* 32000 */
+ {24000, {21, -1}}, /* 24000 */
+ {22050, {21, -1}} /* 22050 */
+};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab256[] = {
+ {96000, {25, -1}}, /* 96000 */
+ {48000, {25, -1}}, /* 48000 */
+ {44100, {25, -1}}, /* 44100 */
+ {32000, {24, -1}}, /* 32000 */
+ {24000, {24, -1}}, /* 24000 */
+ {22050, {24, -1}} /* 22050 */
+};
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab480[] = {{48000, {31, -1}},
+ {44100, {32, -1}},
+ {32000, {37, -1}},
+ {24000, {30, -1}},
+ {22050, {30, -1}}};
+
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab512[] = {{48000, {31, -1}},
+ {44100, {32, -1}},
+ {32000, {37, -1}},
+ {24000, {31, -1}},
+ {22050, {31, -1}}};
+
+static void FDKaacEnc_Parcor2Index(const FIXP_LPC *parcor, INT *RESTRICT index,
+ const INT order, const INT bitsPerCoeff);
+
+static void FDKaacEnc_Index2Parcor(const INT *index, FIXP_LPC *RESTRICT parcor,
+ const INT order, const INT bitsPerCoeff);
+
+static void FDKaacEnc_CalcGaussWindow(FIXP_DBL *win, const int winSize,
+ const INT samplingRate,
+ const INT transformResolution,
+ const FIXP_DBL timeResolution,
+ const INT timeResolution_e);
+
+static const TNS_PARAMETER_TABULATED *FDKaacEnc_GetTnsParam(const INT bitRate,
+ const INT channels,
+ const INT sbrLd) {
+ int i;
+ const TNS_PARAMETER_TABULATED *tnsConfigTab = NULL;
+
+ for (i = 0; i < (int)(sizeof(tnsInfoTab) / sizeof(TNS_INFO_TAB)); i++) {
+ if ((bitRate >= tnsInfoTab[i].bitRateFrom[sbrLd ? 1 : 0]) &&
+ bitRate <= tnsInfoTab[i].bitRateTo[sbrLd ? 1 : 0]) {
+ tnsConfigTab = &tnsInfoTab[i].paramTab[(channels == 1) ? 0 : 1];
+ }
+ }
+
+ return tnsConfigTab;
+}
+
+static INT getTnsMaxBands(const INT sampleRate, const INT granuleLength,
+ const INT isShortBlock) {
+ int i;
+ INT numBands = -1;
+ const TNS_MAX_TAB_ENTRY *pMaxBandsTab = NULL;
+ int maxBandsTabSize = 0;
+
+ switch (granuleLength) {
+ case 960:
+ pMaxBandsTab = tnsMaxBandsTab960;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab960) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 1024:
+ pMaxBandsTab = tnsMaxBandsTab1024;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab1024) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 120:
+ pMaxBandsTab = tnsMaxBandsTab120;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab120) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 128:
+ pMaxBandsTab = tnsMaxBandsTab128;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab128) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 240:
+ pMaxBandsTab = tnsMaxBandsTab240;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab240) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 256:
+ pMaxBandsTab = tnsMaxBandsTab256;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab256) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 480:
+ pMaxBandsTab = tnsMaxBandsTab480;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab480) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ case 512:
+ pMaxBandsTab = tnsMaxBandsTab512;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab512) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
+ default:
+ numBands = -1;
+ }
+
+ if (pMaxBandsTab != NULL) {
+ for (i = 0; i < maxBandsTabSize; i++) {
+ numBands = pMaxBandsTab[i].maxBands[(!isShortBlock) ? 0 : 1];
+ if (sampleRate >= pMaxBandsTab[i].samplingRate) {
+ break;
+ }
+ }
+ }
+
+ return numBands;
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacEnc_FreqToBandWidthRounding
+
+ Returns index of nearest band border
+
+ \param frequency
+ \param sampling frequency
+ \param total number of bands
+ \param pointer to table of band borders
+
+ \return band border
+****************************************************************************/
+
+INT FDKaacEnc_FreqToBandWidthRounding(const INT freq, const INT fs,
+ const INT numOfBands,
+ const INT *bandStartOffset) {
+ INT lineNumber, band;
+
+ /* assert(freq >= 0); */
+ lineNumber = (freq * bandStartOffset[numOfBands] * 4 / fs + 1) / 2;
+
+ /* freq > fs/2 */
+ if (lineNumber >= bandStartOffset[numOfBands]) return numOfBands;
+
+ /* find band the line number lies in */
+ for (band = 0; band < numOfBands; band++) {
+ if (bandStartOffset[band + 1] > lineNumber) break;
+ }
+
+ /* round to nearest band border */
+ if (lineNumber - bandStartOffset[band] >
+ bandStartOffset[band + 1] - lineNumber) {
+ band++;
+ }
+
+ return (band);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_InitTnsConfiguration
+ description: fill TNS_CONFIG structure with sensible content
+ returns:
+ input: bitrate, samplerate, number of channels,
+ blocktype (long or short),
+ TNS Config struct (modified),
+ psy config struct,
+ tns active flag
+ output:
+
+*****************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(
+ INT bitRate, INT sampleRate, INT channels, INT blockType, INT granuleLength,
+ INT isLowDelay, INT ldSbrPresent, TNS_CONFIG *tC, PSY_CONFIGURATION *pC,
+ INT active, INT useTnsPeak) {
+ int i;
+ // float acfTimeRes = (blockType == SHORT_WINDOW) ? 0.125f : 0.046875f;
+
+ if (channels <= 0) return (AAC_ENCODER_ERROR)1;
+
+ tC->isLowDelay = isLowDelay;
+
+ /* initialize TNS filter flag, order, and coefficient resolution (in bits per
+ * coeff) */
+ tC->tnsActive = (active) ? TRUE : FALSE;
+ tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */
+ if (bitRate < 16000) tC->maxOrder -= 2;
+ tC->coefRes = (blockType == SHORT_WINDOW) ? 3 : 4;
+
+ /* LPC stop line: highest MDCT line to be coded, but do not go beyond
+ * TNS_MAX_BANDS! */
+ tC->lpcStopBand = getTnsMaxBands(sampleRate, granuleLength,
+ (blockType == SHORT_WINDOW) ? 1 : 0);
+
+ if (tC->lpcStopBand < 0) {
+ return (AAC_ENCODER_ERROR)1;
+ }
+
+ tC->lpcStopBand = fMin(tC->lpcStopBand, pC->sfbActive);
+ tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand];
+
+ switch (granuleLength) {
+ case 960:
+ case 1024:
+ /* TNS start line: skip lower MDCT lines to prevent artifacts due to
+ * filter mismatch */
+ if (blockType == SHORT_WINDOW) {
+ tC->lpcStartBand[LOFILT] = 0;
+ } else {
+ tC->lpcStartBand[LOFILT] =
+ (sampleRate < 9391) ? 2 : ((sampleRate < 18783) ? 4 : 8);
+ }
+ tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]];
+
+ i = tC->lpcStopBand;
+ while (pC->sfbOffset[i] >
+ (tC->lpcStartLine[LOFILT] +
+ (tC->lpcStopLine - tC->lpcStartLine[LOFILT]) / 4))
+ i--;
+ tC->lpcStartBand[HIFILT] = i;
+ tC->lpcStartLine[HIFILT] = pC->sfbOffset[i];
+
+ tC->confTab.threshOn[HIFILT] = 1437;
+ tC->confTab.threshOn[LOFILT] = 1500;
+
+ tC->confTab.tnsLimitOrder[HIFILT] = tC->maxOrder;
+ tC->confTab.tnsLimitOrder[LOFILT] = fMax(0, tC->maxOrder - 7);
+
+ tC->confTab.tnsFilterDirection[HIFILT] = FILTER_DIRECTION;
+ tC->confTab.tnsFilterDirection[LOFILT] = FILTER_DIRECTION;
+
+ tC->confTab.acfSplit[HIFILT] =
+ -1; /* signal Merged4to2QuartersAutoCorrelation in
+ FDKaacEnc_MergedAutoCorrelation*/
+ tC->confTab.acfSplit[LOFILT] =
+ -1; /* signal Merged4to2QuartersAutoCorrelation in
+ FDKaacEnc_MergedAutoCorrelation */
+
+ tC->confTab.filterEnabled[HIFILT] = 1;
+ tC->confTab.filterEnabled[LOFILT] = 1;
+ tC->confTab.seperateFiltersAllowed = 1;
+
+ /* compute autocorrelation window based on maximum filter order for given
+ * block type */
+ /* for (i = 0; i <= tC->maxOrder + 3; i++) {
+ float acfWinTemp = acfTimeRes * i;
+ acfWindow[i] = FL2FXCONST_DBL(1.0f - acfWinTemp * acfWinTemp);
+ }
+ */
+ if (blockType == SHORT_WINDOW) {
+ FDKmemcpy(tC->acfWindow[HIFILT], acfWindowShort,
+ fMin((LONG)sizeof(acfWindowShort),
+ (LONG)sizeof(tC->acfWindow[HIFILT])));
+ FDKmemcpy(tC->acfWindow[LOFILT], acfWindowShort,
+ fMin((LONG)sizeof(acfWindowShort),
+ (LONG)sizeof(tC->acfWindow[HIFILT])));
+ } else {
+ FDKmemcpy(tC->acfWindow[HIFILT], acfWindowLong,
+ fMin((LONG)sizeof(acfWindowLong),
+ (LONG)sizeof(tC->acfWindow[HIFILT])));
+ FDKmemcpy(tC->acfWindow[LOFILT], acfWindowLong,
+ fMin((LONG)sizeof(acfWindowLong),
+ (LONG)sizeof(tC->acfWindow[HIFILT])));
+ }
+ break;
+ case 480:
+ case 512: {
+ const TNS_PARAMETER_TABULATED *pCfg =
+ FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent);
+ if (pCfg != NULL) {
+ FDKmemcpy(&(tC->confTab), pCfg, sizeof(tC->confTab));
+
+ tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWidthRounding(
+ pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt,
+ pC->sfbOffset);
+ tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]];
+ tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWidthRounding(
+ pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt,
+ pC->sfbOffset);
+ tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]];
+
+ 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);
+ } else {
+ tC->tnsActive =
+ FALSE; /* no configuration available, disable tns tool */
+ }
+ } break;
+ default:
+ tC->tnsActive = FALSE; /* no configuration available, disable tns tool */
+ }
+
+ return AAC_ENC_OK;
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacEnc_ScaleUpSpectrum
+
+ Scales up spectrum lines in a given frequency section
+
+ \param scaled spectrum
+ \param original spectrum
+ \param frequency line to start scaling
+ \param frequency line to enc scaling
+
+ \return scale factor
+
+****************************************************************************/
+static inline INT FDKaacEnc_ScaleUpSpectrum(FIXP_DBL *dest, const FIXP_DBL *src,
+ const INT startLine,
+ const INT stopLine) {
+ INT i, scale;
+
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.f);
+
+ /* Get highest value in given spectrum */
+ for (i = startLine; i < stopLine; i++) {
+ maxVal = fixMax(maxVal, fixp_abs(src[i]));
+ }
+ scale = CountLeadingBits(maxVal);
+
+ /* Scale spectrum according to highest value */
+ for (i = startLine; i < stopLine; i++) {
+ dest[i] = src[i] << scale;
+ }
+
+ return scale;
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacEnc_CalcAutoCorrValue
+
+ Calculate autocorellation value for one lag
+
+ \param pointer to spectrum
+ \param start line
+ \param stop line
+ \param lag to be calculated
+ \param scaling of the lag
+
+****************************************************************************/
+static inline FIXP_DBL FDKaacEnc_CalcAutoCorrValue(const FIXP_DBL *spectrum,
+ const INT startLine,
+ const INT stopLine,
+ const INT lag,
+ const INT scale) {
+ int i;
+ FIXP_DBL result = FL2FXCONST_DBL(0.f);
+
+ /* This versions allows to save memory accesses, when computing pow2 */
+ /* It is of interest for ARM, XTENSA without parallel memory access */
+ if (lag == 0) {
+ for (i = startLine; i < stopLine; i++) {
+ result += (fPow2(spectrum[i]) >> scale);
+ }
+ } else {
+ for (i = startLine; i < (stopLine - lag); i++) {
+ result += (fMult(spectrum[i], spectrum[i + lag]) >> scale);
+ }
+ }
+
+ return result;
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacEnc_AutoCorrNormFac
+
+ Autocorrelation function for 1st and 2nd half of the spectrum
+
+ \param pointer to spectrum
+ \param pointer to autocorrelation window
+ \param filter start line
+
+****************************************************************************/
+static inline FIXP_DBL FDKaacEnc_AutoCorrNormFac(const FIXP_DBL value,
+ const INT scale, INT *sc) {
+#define HLM_MIN_NRG 0.0000000037252902984619140625f /* 2^-28 */
+#define MAX_INV_NRGFAC (1.f / HLM_MIN_NRG)
+
+ FIXP_DBL retValue;
+ FIXP_DBL A, B;
+
+ if (scale >= 0) {
+ A = value;
+ B = FL2FXCONST_DBL(HLM_MIN_NRG) >> fixMin(DFRACT_BITS - 1, scale);
+ } else {
+ A = value >> fixMin(DFRACT_BITS - 1, (-scale));
+ B = FL2FXCONST_DBL(HLM_MIN_NRG);
+ }
+
+ if (A > B) {
+ int shift = 0;
+ FIXP_DBL tmp = invSqrtNorm2(value, &shift);
+
+ retValue = fMult(tmp, tmp);
+ *sc += (2 * shift);
+ } else {
+ /* MAX_INV_NRGFAC*FDKpow(2,-28) = 1/2^-28 * 2^-28 = 1.0 */
+ retValue =
+ /*FL2FXCONST_DBL(MAX_INV_NRGFAC*FDKpow(2,-28))*/ (FIXP_DBL)MAXVAL_DBL;
+ *sc += scale + 28;
+ }
+
+ return retValue;
+}
+
+static void FDKaacEnc_MergedAutoCorrelation(
+ const FIXP_DBL *spectrum, const INT isLowDelay,
+ const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER + 3 + 1],
+ const INT lpcStartLine[MAX_NUM_OF_FILTERS], const INT lpcStopLine,
+ const INT maxOrder, const INT acfSplit[MAX_NUM_OF_FILTERS], FIXP_DBL *_rxx1,
+ FIXP_DBL *_rxx2) {
+ int i, idx0, idx1, idx2, idx3, idx4, lag;
+ FIXP_DBL rxx1_0, rxx2_0, rxx3_0, rxx4_0;
+
+ /* buffer for temporal spectrum */
+ C_ALLOC_SCRATCH_START(pSpectrum, FIXP_DBL, (1024))
+
+ /* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters
+ */
+ if ((acfSplit[LOFILT] == -1) || (acfSplit[HIFILT] == -1)) {
+ /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the
+ * spectrum */
+ idx0 = lpcStartLine[LOFILT];
+ i = lpcStopLine - lpcStartLine[LOFILT];
+ idx1 = idx0 + i / 4;
+ idx2 = idx0 + i / 2;
+ idx3 = idx0 + i * 3 / 4;
+ idx4 = lpcStopLine;
+ } else {
+ FDK_ASSERT(acfSplit[LOFILT] == 1);
+ FDK_ASSERT(acfSplit[HIFILT] == 3);
+ i = (lpcStopLine - lpcStartLine[HIFILT]) / 3;
+ idx0 = lpcStartLine[LOFILT];
+ idx1 = lpcStartLine[HIFILT];
+ idx2 = idx1 + i;
+ idx3 = idx2 + i;
+ idx4 = lpcStopLine;
+ }
+
+ /* copy spectrum to temporal buffer and scale up as much as possible */
+ INT sc1 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx0, idx1);
+ INT sc2 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx1, idx2);
+ INT sc3 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx2, idx3);
+ INT sc4 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx3, idx4);
+
+ /* get scaling values for summation */
+ INT nsc1, nsc2, nsc3, nsc4;
+ for (nsc1 = 1; (1 << nsc1) < (idx1 - idx0); nsc1++)
+ ;
+ for (nsc2 = 1; (1 << nsc2) < (idx2 - idx1); nsc2++)
+ ;
+ for (nsc3 = 1; (1 << nsc3) < (idx3 - idx2); nsc3++)
+ ;
+ for (nsc4 = 1; (1 << nsc4) < (idx4 - idx3); nsc4++)
+ ;
+
+ /* compute autocorrelation value at lag zero, i. e. energy, for each quarter
+ */
+ rxx1_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, 0, nsc1);
+ rxx2_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx1, idx2, 0, nsc2);
+ rxx3_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx2, idx3, 0, nsc3);
+ rxx4_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx3, idx4, 0, nsc4);
+
+ /* compute energy normalization factors, i. e. 1/energy (saves some divisions)
+ */
+ if (rxx1_0 != FL2FXCONST_DBL(0.f)) {
+ INT sc_fac1 = -1;
+ FIXP_DBL fac1 =
+ FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2 * sc1) + nsc1), &sc_fac1);
+ _rxx1[0] = scaleValue(fMult(rxx1_0, fac1), sc_fac1);
+
+ if (isLowDelay) {
+ for (lag = 1; lag <= maxOrder; 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) {
+ FIXP_DBL x1 =
+ FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1);
+ _rxx1[lag] = fMult(scaleValue(fMult(x1, fac1), sc_fac1),
+ acfWindow[LOFILT][3 * lag]);
+ }
+ }
+ }
+ }
+
+ /* auto corr over upper 3/4 of spectrum */
+ if (!((rxx2_0 == FL2FXCONST_DBL(0.f)) && (rxx3_0 == FL2FXCONST_DBL(0.f)) &&
+ (rxx4_0 == FL2FXCONST_DBL(0.f)))) {
+ FIXP_DBL fac2, fac3, fac4;
+ fac2 = fac3 = fac4 = FL2FXCONST_DBL(0.f);
+ INT sc_fac2, sc_fac3, sc_fac4;
+ sc_fac2 = sc_fac3 = sc_fac4 = 0;
+
+ if (rxx2_0 != FL2FXCONST_DBL(0.f)) {
+ fac2 = FDKaacEnc_AutoCorrNormFac(rxx2_0, ((-2 * sc2) + nsc2), &sc_fac2);
+ sc_fac2 -= 2;
+ }
+ if (rxx3_0 != FL2FXCONST_DBL(0.f)) {
+ fac3 = FDKaacEnc_AutoCorrNormFac(rxx3_0, ((-2 * sc3) + nsc3), &sc_fac3);
+ sc_fac3 -= 2;
+ }
+ if (rxx4_0 != FL2FXCONST_DBL(0.f)) {
+ fac4 = FDKaacEnc_AutoCorrNormFac(rxx4_0, ((-2 * sc4) + nsc4), &sc_fac4);
+ sc_fac4 -= 2;
+ }
+
+ _rxx2[0] = scaleValue(fMult(rxx2_0, fac2), sc_fac2) +
+ scaleValue(fMult(rxx3_0, fac3), sc_fac3) +
+ scaleValue(fMult(rxx4_0, fac4), sc_fac4);
+
+ for (lag = 1; lag <= maxOrder; lag++) {
+ /* merge quarters 2, 3, 4 into one autocorrelation; quarter 1 stays
+ * separate */
+ FIXP_DBL x2 = scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(
+ pSpectrum, idx1, idx2, lag, nsc2),
+ fac2),
+ sc_fac2) +
+ scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(
+ pSpectrum, idx2, idx3, lag, nsc3),
+ fac3),
+ sc_fac3) +
+ scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(
+ pSpectrum, idx3, idx4, lag, nsc4),
+ fac4),
+ sc_fac4);
+
+ _rxx2[lag] = fMult(x2, acfWindow[HIFILT][lag]);
+ }
+ }
+
+ C_ALLOC_SCRATCH_END(pSpectrum, FIXP_DBL, (1024))
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_TnsDetect
+ description: do decision, if TNS shall be used or not
+ returns:
+ input: tns data structure (modified),
+ tns config structure,
+ scalefactor size and table,
+ spectrum,
+ subblock num, blocktype,
+ sfb-wise energy.
+
+*****************************************************************************/
+INT FDKaacEnc_TnsDetect(TNS_DATA *tnsData, const TNS_CONFIG *tC,
+ TNS_INFO *tnsInfo, INT sfbCnt, const FIXP_DBL *spectrum,
+ INT subBlockNumber, INT blockType) {
+ /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the
+ * spectrum. */
+ FIXP_DBL rxx1[TNS_MAX_ORDER + 1]; /* higher part */
+ FIXP_DBL rxx2[TNS_MAX_ORDER + 1]; /* lower part */
+ FIXP_LPC parcor_tmp[TNS_MAX_ORDER];
+
+ int i;
+
+ FDKmemclear(rxx1, sizeof(rxx1));
+ FDKmemclear(rxx2, sizeof(rxx2));
+
+ TNS_SUBBLOCK_INFO *tsbi =
+ (blockType == SHORT_WINDOW)
+ ? &tnsData->dataRaw.Short.subBlockInfo[subBlockNumber]
+ : &tnsData->dataRaw.Long.subBlockInfo;
+
+ tnsData->filtersMerged = FALSE;
+
+ tsbi->tnsActive[HIFILT] = FALSE;
+ tsbi->predictionGain[HIFILT] = 1000;
+ tsbi->tnsActive[LOFILT] = FALSE;
+ tsbi->predictionGain[LOFILT] = 1000;
+
+ tnsInfo->numOfFilters[subBlockNumber] = 0;
+ tnsInfo->coefRes[subBlockNumber] = tC->coefRes;
+ for (i = 0; i < tC->maxOrder; i++) {
+ tnsInfo->coef[subBlockNumber][HIFILT][i] =
+ tnsInfo->coef[subBlockNumber][LOFILT][i] = 0;
+ }
+
+ tnsInfo->length[subBlockNumber][HIFILT] =
+ tnsInfo->length[subBlockNumber][LOFILT] = 0;
+ tnsInfo->order[subBlockNumber][HIFILT] =
+ tnsInfo->order[subBlockNumber][LOFILT] = 0;
+
+ if ((tC->tnsActive) && (tC->maxOrder > 0)) {
+ int sumSqrCoef;
+
+ FDKaacEnc_MergedAutoCorrelation(
+ spectrum, tC->isLowDelay, tC->acfWindow, tC->lpcStartLine,
+ tC->lpcStopLine, tC->maxOrder, tC->confTab.acfSplit, rxx1, rxx2);
+
+ /* compute higher TNS filter coefficients in lattice form (ParCor) with
+ * LeRoux-Gueguen/Schur algorithm */
+ {
+ FIXP_DBL predictionGain_m;
+ INT predictionGain_e;
+
+ CLpc_AutoToParcor(rxx2, 0, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT],
+ &predictionGain_m, &predictionGain_e);
+ tsbi->predictionGain[HIFILT] =
+ (INT)fMultNorm(predictionGain_m, predictionGain_e, 1000, 31, 31);
+ }
+
+ /* non-linear quantization of TNS lattice coefficients with given resolution
+ */
+ FDKaacEnc_Parcor2Index(parcor_tmp, tnsInfo->coef[subBlockNumber][HIFILT],
+ tC->confTab.tnsLimitOrder[HIFILT], tC->coefRes);
+
+ /* reduce filter order by truncating trailing zeros, compute sum(abs(coefs))
+ */
+ for (i = tC->confTab.tnsLimitOrder[HIFILT] - 1; i >= 0; i--) {
+ if (tnsInfo->coef[subBlockNumber][HIFILT][i] != 0) {
+ break;
+ }
+ }
+
+ tnsInfo->order[subBlockNumber][HIFILT] = i + 1;
+
+ sumSqrCoef = 0;
+ for (; i >= 0; i--) {
+ sumSqrCoef += tnsInfo->coef[subBlockNumber][HIFILT][i] *
+ tnsInfo->coef[subBlockNumber][HIFILT][i];
+ }
+
+ tnsInfo->direction[subBlockNumber][HIFILT] =
+ tC->confTab.tnsFilterDirection[HIFILT];
+ tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[HIFILT];
+
+ /* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small
+ */
+ if ((tsbi->predictionGain[HIFILT] > tC->confTab.threshOn[HIFILT]) ||
+ (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT] / 2 + 2))) {
+ tsbi->tnsActive[HIFILT] = TRUE;
+ tnsInfo->numOfFilters[subBlockNumber]++;
+
+ /* compute second filter for lower quarter; only allowed for long windows!
+ */
+ if ((blockType != SHORT_WINDOW) && (tC->confTab.filterEnabled[LOFILT]) &&
+ (tC->confTab.seperateFiltersAllowed)) {
+ /* compute second filter for lower frequencies */
+
+ /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen
+ * algorithm */
+ INT predGain;
+ {
+ FIXP_DBL predictionGain_m;
+ INT predictionGain_e;
+
+ CLpc_AutoToParcor(rxx1, 0, parcor_tmp,
+ tC->confTab.tnsLimitOrder[LOFILT],
+ &predictionGain_m, &predictionGain_e);
+ predGain =
+ (INT)fMultNorm(predictionGain_m, predictionGain_e, 1000, 31, 31);
+ }
+
+ /* non-linear quantization of TNS lattice coefficients with given
+ * resolution */
+ FDKaacEnc_Parcor2Index(parcor_tmp,
+ tnsInfo->coef[subBlockNumber][LOFILT],
+ tC->confTab.tnsLimitOrder[LOFILT], tC->coefRes);
+
+ /* reduce filter order by truncating trailing zeros, compute
+ * sum(abs(coefs)) */
+ for (i = tC->confTab.tnsLimitOrder[LOFILT] - 1; i >= 0; i--) {
+ if (tnsInfo->coef[subBlockNumber][LOFILT][i] != 0) {
+ break;
+ }
+ }
+ tnsInfo->order[subBlockNumber][LOFILT] = i + 1;
+
+ sumSqrCoef = 0;
+ for (; i >= 0; i--) {
+ sumSqrCoef += tnsInfo->coef[subBlockNumber][LOFILT][i] *
+ tnsInfo->coef[subBlockNumber][LOFILT][i];
+ }
+
+ tnsInfo->direction[subBlockNumber][LOFILT] =
+ tC->confTab.tnsFilterDirection[LOFILT];
+ tnsInfo->length[subBlockNumber][LOFILT] =
+ tC->lpcStartBand[HIFILT] - tC->lpcStartBand[LOFILT];
+
+ /* filter lower quarter if gain is high enough, but not if it's too high
+ */
+ if (((predGain > tC->confTab.threshOn[LOFILT]) &&
+ (predGain < (16000 * tC->confTab.tnsLimitOrder[LOFILT]))) ||
+ ((sumSqrCoef > 9) &&
+ (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]))) {
+ /* compare lower to upper filter; if they are very similar, merge them
+ */
+ tsbi->tnsActive[LOFILT] = TRUE;
+ sumSqrCoef = 0;
+ for (i = 0; i < tC->confTab.tnsLimitOrder[LOFILT]; i++) {
+ sumSqrCoef += fAbs(tnsInfo->coef[subBlockNumber][HIFILT][i] -
+ tnsInfo->coef[subBlockNumber][LOFILT][i]);
+ }
+ if ((sumSqrCoef < 2) &&
+ (tnsInfo->direction[subBlockNumber][LOFILT] ==
+ tnsInfo->direction[subBlockNumber][HIFILT])) {
+ tnsData->filtersMerged = TRUE;
+ tnsInfo->length[subBlockNumber][HIFILT] =
+ sfbCnt - tC->lpcStartBand[LOFILT];
+ for (; i < tnsInfo->order[subBlockNumber][HIFILT]; i++) {
+ if (fAbs(tnsInfo->coef[subBlockNumber][HIFILT][i]) > 1) {
+ break;
+ }
+ }
+ for (i--; i >= 0; i--) {
+ if (tnsInfo->coef[subBlockNumber][HIFILT][i] != 0) {
+ break;
+ }
+ }
+ if (i < tnsInfo->order[subBlockNumber][HIFILT]) {
+ tnsInfo->order[subBlockNumber][HIFILT] = i + 1;
+ }
+ } else {
+ tnsInfo->numOfFilters[subBlockNumber]++;
+ }
+ } /* filter lower part */
+ tsbi->predictionGain[LOFILT] = predGain;
+
+ } /* second filter allowed */
+ } /* if predictionGain > 1437 ... */
+ } /* maxOrder > 0 && tnsActive */
+
+ return 0;
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacLdEnc_TnsSync
+
+ synchronize TNS parameters when TNS gain difference small (relative)
+
+ \param pointer to TNS data structure (destination)
+ \param pointer to TNS data structure (source)
+ \param pointer to TNS config structure
+ \param number of sub-block
+ \param block type
+
+ \return void
+****************************************************************************/
+void FDKaacEnc_TnsSync(TNS_DATA *tnsDataDest, const TNS_DATA *tnsDataSrc,
+ TNS_INFO *tnsInfoDest, TNS_INFO *tnsInfoSrc,
+ const INT blockTypeDest, const INT blockTypeSrc,
+ const TNS_CONFIG *tC) {
+ int i, w, absDiff, nWindows;
+ TNS_SUBBLOCK_INFO *sbInfoDest;
+ const TNS_SUBBLOCK_INFO *sbInfoSrc;
+
+ /* if one channel contains short blocks and the other not, do not synchronize
+ */
+ if ((blockTypeSrc == SHORT_WINDOW && blockTypeDest != SHORT_WINDOW) ||
+ (blockTypeDest == SHORT_WINDOW && blockTypeSrc != SHORT_WINDOW)) {
+ return;
+ }
+
+ if (blockTypeDest != SHORT_WINDOW) {
+ sbInfoDest = &tnsDataDest->dataRaw.Long.subBlockInfo;
+ sbInfoSrc = &tnsDataSrc->dataRaw.Long.subBlockInfo;
+ nWindows = 1;
+ } else {
+ sbInfoDest = &tnsDataDest->dataRaw.Short.subBlockInfo[0];
+ sbInfoSrc = &tnsDataSrc->dataRaw.Short.subBlockInfo[0];
+ nWindows = 8;
+ }
+
+ for (w = 0; w < nWindows; w++) {
+ const TNS_SUBBLOCK_INFO *pSbInfoSrcW = sbInfoSrc + w;
+ TNS_SUBBLOCK_INFO *pSbInfoDestW = sbInfoDest + w;
+ INT doSync = 1, absDiffSum = 0;
+
+ /* if TNS is active in at least one channel, check if ParCor coefficients of
+ * higher filter are similar */
+ if (pSbInfoDestW->tnsActive[HIFILT] || pSbInfoSrcW->tnsActive[HIFILT]) {
+ for (i = 0; i < tC->maxOrder; i++) {
+ absDiff = fAbs(tnsInfoDest->coef[w][HIFILT][i] -
+ tnsInfoSrc->coef[w][HIFILT][i]);
+ absDiffSum += absDiff;
+ /* if coefficients diverge too much between channels, do not synchronize
+ */
+ if ((absDiff > 1) || (absDiffSum > 2)) {
+ doSync = 0;
+ break;
+ }
+ }
+
+ if (doSync) {
+ /* if no significant difference was detected, synchronize coefficient
+ * sets */
+ if (pSbInfoSrcW->tnsActive[HIFILT]) {
+ /* no dest filter, or more dest than source filters: use one dest
+ * filter */
+ if ((!pSbInfoDestW->tnsActive[HIFILT]) ||
+ ((pSbInfoDestW->tnsActive[HIFILT]) &&
+ (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w]))) {
+ pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 1;
+ }
+ tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged;
+ tnsInfoDest->order[w][HIFILT] = tnsInfoSrc->order[w][HIFILT];
+ tnsInfoDest->length[w][HIFILT] = tnsInfoSrc->length[w][HIFILT];
+ tnsInfoDest->direction[w][HIFILT] = tnsInfoSrc->direction[w][HIFILT];
+ tnsInfoDest->coefCompress[w][HIFILT] =
+ tnsInfoSrc->coefCompress[w][HIFILT];
+
+ for (i = 0; i < tC->maxOrder; i++) {
+ tnsInfoDest->coef[w][HIFILT][i] = tnsInfoSrc->coef[w][HIFILT][i];
+ }
+ } else
+ pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 0;
+ }
+ }
+ }
+}
+
+/***************************************************************************/
+/*!
+ \brief FDKaacEnc_TnsEncode
+
+ perform TNS encoding
+
+ \param pointer to TNS info structure
+ \param pointer to TNS data structure
+ \param number of sfbs
+ \param pointer to TNS config structure
+ \param low-pass line
+ \param pointer to spectrum
+ \param number of sub-block
+ \param block type
+
+ \return ERROR STATUS
+****************************************************************************/
+INT FDKaacEnc_TnsEncode(TNS_INFO *tnsInfo, TNS_DATA *tnsData,
+ const INT numOfSfb, const TNS_CONFIG *tC,
+ const INT lowPassLine, FIXP_DBL *spectrum,
+ const INT subBlockNumber, const INT blockType) {
+ INT i, startLine, stopLine;
+
+ if (((blockType == SHORT_WINDOW) &&
+ (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber]
+ .tnsActive[HIFILT])) ||
+ ((blockType != SHORT_WINDOW) &&
+ (!tnsData->dataRaw.Long.subBlockInfo.tnsActive[HIFILT]))) {
+ return 1;
+ }
+
+ startLine = (tnsData->filtersMerged) ? tC->lpcStartLine[LOFILT]
+ : tC->lpcStartLine[HIFILT];
+ stopLine = tC->lpcStopLine;
+
+ for (i = 0; i < tnsInfo->numOfFilters[subBlockNumber]; i++) {
+ INT lpcGainFactor;
+ FIXP_LPC LpcCoeff[TNS_MAX_ORDER];
+ FIXP_DBL workBuffer[TNS_MAX_ORDER];
+ FIXP_LPC parcor_tmp[TNS_MAX_ORDER];
+
+ FDKaacEnc_Index2Parcor(tnsInfo->coef[subBlockNumber][i], parcor_tmp,
+ tnsInfo->order[subBlockNumber][i], tC->coefRes);
+
+ lpcGainFactor = CLpc_ParcorToLpc(
+ parcor_tmp, LpcCoeff, tnsInfo->order[subBlockNumber][i], workBuffer);
+
+ FDKmemclear(workBuffer, TNS_MAX_ORDER * sizeof(FIXP_DBL));
+ CLpc_Analysis(&spectrum[startLine], stopLine - startLine, LpcCoeff,
+ lpcGainFactor, tnsInfo->order[subBlockNumber][i], workBuffer,
+ NULL);
+
+ /* update for second filter */
+ startLine = tC->lpcStartLine[LOFILT];
+ stopLine = tC->lpcStartLine[HIFILT];
+ }
+
+ return (0);
+}
+
+static void FDKaacEnc_CalcGaussWindow(FIXP_DBL *win, const int winSize,
+ const INT samplingRate,
+ const INT transformResolution,
+ const FIXP_DBL timeResolution,
+ const INT timeResolution_e) {
+#define PI_E (2)
+#define PI_M FL2FXCONST_DBL(3.1416f / (float)(1 << PI_E))
+
+#define EULER_E (2)
+#define EULER_M FL2FXCONST_DBL(2.7183 / (float)(1 << EULER_E))
+
+#define COEFF_LOOP_SCALE (4)
+
+ INT i, e1, e2, gaussExp_e;
+ FIXP_DBL gaussExp_m;
+
+ /* calc. window exponent from time resolution:
+ *
+ * gaussExp = PI * samplingRate * 0.001f * timeResolution /
+ * transformResolution; gaussExp = -0.5f * gaussExp * gaussExp;
+ */
+ gaussExp_m = fMultNorm(
+ timeResolution,
+ fMult(PI_M,
+ fDivNorm((FIXP_DBL)(samplingRate),
+ (FIXP_DBL)(LONG)(transformResolution * 1000.f), &e1)),
+ &e2);
+ gaussExp_m = -fPow2Div2(gaussExp_m);
+ gaussExp_e = 2 * (e1 + e2 + timeResolution_e + PI_E);
+
+ FDK_ASSERT(winSize < (1 << COEFF_LOOP_SCALE));
+
+ /* calc. window coefficients
+ * win[i] = (float)exp( gaussExp * (i+0.5) * (i+0.5) );
+ */
+ for (i = 0; i < winSize; i++) {
+ win[i] = fPow(
+ EULER_M, EULER_E,
+ fMult(gaussExp_m,
+ fPow2((i * FL2FXCONST_DBL(1.f / (float)(1 << COEFF_LOOP_SCALE)) +
+ FL2FXCONST_DBL(.5f / (float)(1 << COEFF_LOOP_SCALE))))),
+ gaussExp_e + 2 * COEFF_LOOP_SCALE, &e1);
+
+ win[i] = scaleValueSaturate(win[i], e1);
+ }
+}
+
+static INT FDKaacEnc_Search3(FIXP_LPC parcor) {
+ INT i, index = 0;
+
+ for (i = 0; i < 8; i++) {
+ if (parcor > FDKaacEnc_tnsCoeff3Borders[i]) index = i;
+ }
+ return (index - 4);
+}
+
+static INT FDKaacEnc_Search4(FIXP_LPC parcor) {
+ INT i, index = 0;
+
+ for (i = 0; i < 16; i++) {
+ if (parcor > FDKaacEnc_tnsCoeff4Borders[i]) index = i;
+ }
+ return (index - 8);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_Parcor2Index
+
+*****************************************************************************/
+static void FDKaacEnc_Parcor2Index(const FIXP_LPC *parcor, INT *RESTRICT index,
+ const INT order, const INT bitsPerCoeff) {
+ INT i;
+ for (i = 0; i < order; i++) {
+ if (bitsPerCoeff == 3)
+ index[i] = FDKaacEnc_Search3(parcor[i]);
+ else
+ index[i] = FDKaacEnc_Search4(parcor[i]);
+ }
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_Index2Parcor
+ description: inverse quantization for reflection coefficients
+ returns: -
+ input: quantized values, ptr. to reflection coefficients,
+ no. of coefficients, resolution
+ output: reflection coefficients
+
+*****************************************************************************/
+static void FDKaacEnc_Index2Parcor(const INT *index, FIXP_LPC *RESTRICT parcor,
+ const INT order, const INT bitsPerCoeff) {
+ INT i;
+ for (i = 0; i < order; i++)
+ parcor[i] = bitsPerCoeff == 4 ? FDKaacEnc_tnsEncCoeff4[index[i] + 8]
+ : FDKaacEnc_tnsEncCoeff3[index[i] + 4];
+}
diff --git a/fdk-aac/libAACenc/src/aacenc_tns.h b/fdk-aac/libAACenc/src/aacenc_tns.h
new file mode 100644
index 0000000..a37f978
--- /dev/null
+++ b/fdk-aac/libAACenc/src/aacenc_tns.h
@@ -0,0 +1,213 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Alex Groeschel
+
+ Description: Temporal noise shaping
+
+*******************************************************************************/
+
+#ifndef AACENC_TNS_H
+#define AACENC_TNS_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+
+#ifndef PI
+#define PI 3.1415926535897931f
+#endif
+
+/**
+ * TNS_ENABLE_MASK
+ * This bitfield defines which TNS features are enabled
+ * The TNS mask is composed of 4 bits.
+ * tnsMask |= 0x1; activate TNS short blocks
+ * tnsMask |= 0x2; activate TNS for long blocks
+ * tnsMask |= 0x4; activate TNS PEAK tool for short blocks
+ * tnsMask |= 0x8; activate TNS PEAK tool for long blocks
+ */
+#define TNS_ENABLE_MASK 0xf
+
+/* TNS max filter order for Low Complexity MPEG4 profile */
+#define TNS_MAX_ORDER 12
+
+#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 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*/
+ TNS_PARAMETER_TABULATED confTab;
+ INT isLowDelay;
+ INT tnsActive;
+ INT maxOrder; /* max. order of tns filter */
+ INT coefRes;
+ FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER + 3 + 1];
+ /* now some things that only probably can be done at Init time;
+ could be they have to be split up for each individual (short) window or
+ even filter. */
+ INT lpcStartBand[MAX_NUM_OF_FILTERS];
+ INT lpcStartLine[MAX_NUM_OF_FILTERS];
+ INT lpcStopBand;
+ INT lpcStopLine;
+
+} TNS_CONFIG;
+
+typedef struct {
+ INT tnsActive[MAX_NUM_OF_FILTERS];
+ INT predictionGain[MAX_NUM_OF_FILTERS];
+} TNS_SUBBLOCK_INFO;
+
+typedef struct { /*changed at runTime*/
+ TNS_SUBBLOCK_INFO subBlockInfo[TRANS_FAC];
+ FIXP_DBL ratioMultTable[TRANS_FAC][MAX_SFB_SHORT];
+} TNS_DATA_SHORT;
+
+typedef struct { /*changed at runTime*/
+ TNS_SUBBLOCK_INFO subBlockInfo;
+ FIXP_DBL ratioMultTable[MAX_SFB_LONG];
+} TNS_DATA_LONG;
+
+/* can be implemented as union */
+typedef shouldBeUnion {
+ TNS_DATA_LONG Long;
+ TNS_DATA_SHORT Short;
+}
+TNS_DATA_RAW;
+
+typedef struct {
+ INT numOfSubblocks;
+ TNS_DATA_RAW dataRaw;
+ INT tnsMaxScaleSpec;
+ INT filtersMerged;
+} TNS_DATA;
+
+typedef struct {
+ INT numOfFilters[TRANS_FAC];
+ INT coefRes[TRANS_FAC];
+ INT length[TRANS_FAC][MAX_NUM_OF_FILTERS];
+ INT order[TRANS_FAC][MAX_NUM_OF_FILTERS];
+ INT direction[TRANS_FAC][MAX_NUM_OF_FILTERS];
+ INT coefCompress[TRANS_FAC][MAX_NUM_OF_FILTERS];
+ /* for Long: length TNS_MAX_ORDER (12 for LC) is required -> 12 */
+ /* for Short: length TRANS_FAC*TNS_MAX_ORDER (only 5 for short LC) is required
+ * -> 8*5=40 */
+ /* Currently TRANS_FAC*TNS_MAX_ORDER = 8*12 = 96 (for LC) is used (per
+ * channel)! Memory could be saved here! */
+ INT coef[TRANS_FAC][MAX_NUM_OF_FILTERS][TNS_MAX_ORDER];
+} TNS_INFO;
+
+INT FDKaacEnc_FreqToBandWidthRounding(const INT freq, const INT fs,
+ const INT numOfBands,
+ const INT *bandStartOffset);
+
+#endif /* AACENC_TNS_H */
diff --git a/fdk-aac/libAACenc/src/adj_thr.cpp b/fdk-aac/libAACenc/src/adj_thr.cpp
new file mode 100644
index 0000000..6e19680
--- /dev/null
+++ b/fdk-aac/libAACenc/src/adj_thr.cpp
@@ -0,0 +1,2924 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Threshold compensation
+
+*******************************************************************************/
+
+#include "adj_thr.h"
+#include "sf_estim.h"
+#include "aacEnc_ram.h"
+
+#define NUM_NRG_LEVS (8)
+#define INV_INT_TAB_SIZE (8)
+static const FIXP_DBL invInt[INV_INT_TAB_SIZE] = {
+ 0x7fffffff, 0x7fffffff, 0x40000000, 0x2aaaaaaa,
+ 0x20000000, 0x19999999, 0x15555555, 0x12492492};
+
+#define INV_SQRT4_TAB_SIZE (8)
+static const FIXP_DBL invSqrt4[INV_SQRT4_TAB_SIZE] = {
+ 0x7fffffff, 0x7fffffff, 0x6ba27e65, 0x61424bb5,
+ 0x5a827999, 0x55994845, 0x51c8e33c, 0x4eb160d1};
+
+/*static const INT invRedExp = 4;*/
+static const FIXP_DBL SnrLdMin1 =
+ (FIXP_DBL)0xfcad0ddf; /*FL2FXCONST_DBL(FDKlog(0.316)/FDKlog(2.0)/LD_DATA_SCALING);*/
+static const FIXP_DBL SnrLdMin2 =
+ (FIXP_DBL)0x0351e1a2; /*FL2FXCONST_DBL(FDKlog(3.16)
+ /FDKlog(2.0)/LD_DATA_SCALING);*/
+static const FIXP_DBL SnrLdFac =
+ (FIXP_DBL)0xff5b2c3e; /*FL2FXCONST_DBL(FDKlog(0.8)
+ /FDKlog(2.0)/LD_DATA_SCALING);*/
+
+static const FIXP_DBL SnrLdMin3 =
+ (FIXP_DBL)0xfe000000; /*FL2FXCONST_DBL(FDKlog(0.5)
+ /FDKlog(2.0)/LD_DATA_SCALING);*/
+static const FIXP_DBL SnrLdMin4 =
+ (FIXP_DBL)0x02000000; /*FL2FXCONST_DBL(FDKlog(2.0)
+ /FDKlog(2.0)/LD_DATA_SCALING);*/
+static const FIXP_DBL SnrLdMin5 =
+ (FIXP_DBL)0xfc000000; /*FL2FXCONST_DBL(FDKlog(0.25)
+ /FDKlog(2.0)/LD_DATA_SCALING);*/
+
+/*
+The bits2Pe factors are choosen for the case that some times
+the crash recovery strategy will be activated once.
+*/
+#define AFTERBURNER_STATI 2
+#define MAX_ALLOWED_EL_CHANNELS 2
+
+typedef struct {
+ INT bitrate;
+ FIXP_DBL bits2PeFactor[AFTERBURNER_STATI][MAX_ALLOWED_EL_CHANNELS];
+} BIT_PE_SFAC;
+
+typedef struct {
+ INT sampleRate;
+ const BIT_PE_SFAC *pPeTab;
+ INT nEntries;
+
+} BITS2PE_CFG_TAB;
+
+#define FL2B2PE(value) FL2FXCONST_DBL((value) / (1 << 2))
+
+static const BIT_PE_SFAC S_Bits2PeTab16000[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {10000,
+ {{FL2B2PE(1.60f), FL2B2PE(0.00f)}, {FL2B2PE(1.40f), FL2B2PE(0.00f)}}},
+ {24000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}},
+ {32000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {48000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.80f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}},
+ {64000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.20f), FL2B2PE(1.60f)}}},
+ {96000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}},
+ {128000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.80f)}}},
+ {148000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.40f)}}}};
+
+static const BIT_PE_SFAC S_Bits2PeTab22050[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {16000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}},
+ {24000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.40f), FL2B2PE(1.00f)}}},
+ {32000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.40f), FL2B2PE(1.20f)}}},
+ {48000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.20f), FL2B2PE(1.40f)}}},
+ {64000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {96000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}},
+ {128000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.80f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}},
+ {148000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}}};
+
+static const BIT_PE_SFAC S_Bits2PeTab24000[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {16000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}},
+ {24000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.20f)}, {FL2B2PE(1.40f), FL2B2PE(1.00f)}}},
+ {32000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.40f), FL2B2PE(0.80f)}}},
+ {48000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.40f)}}},
+ {64000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {96000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}},
+ {128000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.80f)}}},
+ {148000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.80f)}}}};
+
+static const BIT_PE_SFAC S_Bits2PeTab32000[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {16000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.40f)}, {FL2B2PE(0.80f), FL2B2PE(0.80f)}}},
+ {24000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.60f)}}},
+ {32000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}},
+ {48000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(1.20f)}}},
+ {64000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}},
+ {96000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {128000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}},
+ {148000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}},
+ {160000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}},
+ {200000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}},
+ {320000,
+ {{FL2B2PE(3.20f), FL2B2PE(1.80f)}, {FL2B2PE(3.20f), FL2B2PE(1.80f)}}}};
+
+static const BIT_PE_SFAC S_Bits2PeTab44100[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {16000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(0.80f), FL2B2PE(1.00f)}}},
+ {24000,
+ {{FL2B2PE(1.00f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}},
+ {32000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(0.80f), FL2B2PE(0.60f)}}},
+ {48000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}},
+ {64000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(1.00f)}}},
+ {96000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.20f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}},
+ {128000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {148000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}},
+ {160000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}},
+ {200000,
+ {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}},
+ {320000,
+ {{FL2B2PE(3.20f), FL2B2PE(1.60f)}, {FL2B2PE(3.20f), FL2B2PE(1.60f)}}}};
+
+static const BIT_PE_SFAC S_Bits2PeTab48000[] = {
+ /* bitrate| afterburner off | afterburner on | | nCh=1
+ | nCh=2 | nCh=1 | nCh=2 */
+ {16000,
+ {{FL2B2PE(1.40f), FL2B2PE(0.00f)}, {FL2B2PE(0.80f), FL2B2PE(0.00f)}}},
+ {24000,
+ {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}},
+ {32000,
+ {{FL2B2PE(1.00f), FL2B2PE(1.20f)}, {FL2B2PE(0.60f), FL2B2PE(0.80f)}}},
+ {48000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.00f)}, {FL2B2PE(0.80f), FL2B2PE(0.80f)}}},
+ {64000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(1.00f)}}},
+ {96000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}},
+ {128000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {148000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {160000,
+ {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {200000,
+ {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}},
+ {320000,
+ {{FL2B2PE(3.20f), FL2B2PE(1.60f)}, {FL2B2PE(3.20f), FL2B2PE(1.60f)}}}};
+
+static const BITS2PE_CFG_TAB bits2PeConfigTab[] = {
+ {16000, S_Bits2PeTab16000, sizeof(S_Bits2PeTab16000) / sizeof(BIT_PE_SFAC)},
+ {22050, S_Bits2PeTab22050, sizeof(S_Bits2PeTab22050) / sizeof(BIT_PE_SFAC)},
+ {24000, S_Bits2PeTab24000, sizeof(S_Bits2PeTab24000) / sizeof(BIT_PE_SFAC)},
+ {32000, S_Bits2PeTab32000, sizeof(S_Bits2PeTab32000) / sizeof(BIT_PE_SFAC)},
+ {44100, S_Bits2PeTab44100, sizeof(S_Bits2PeTab44100) / sizeof(BIT_PE_SFAC)},
+ {48000, S_Bits2PeTab48000,
+ sizeof(S_Bits2PeTab48000) / sizeof(BIT_PE_SFAC)}};
+
+/* values for avoid hole flag */
+enum _avoid_hole_state { NO_AH = 0, AH_INACTIVE = 1, AH_ACTIVE = 2 };
+
+/* Q format definitions */
+#define Q_BITFAC \
+ (24) /* Q scaling used in FDKaacEnc_bitresCalcBitFac() calculation */
+#define Q_AVGBITS (17) /* scale bit values */
+
+/*****************************************************************************
+ functionname: FDKaacEnc_InitBits2PeFactor
+ description: retrieve bits2PeFactor from table
+*****************************************************************************/
+static void FDKaacEnc_InitBits2PeFactor(
+ FIXP_DBL *bits2PeFactor_m, INT *bits2PeFactor_e, const INT bitRate,
+ const INT nChannels, const INT sampleRate, const INT advancedBitsToPe,
+ const INT dZoneQuantEnable, const INT invQuant) {
+ /**** 1) Set default bits2pe factor ****/
+ FIXP_DBL bit2PE_m = FL2FXCONST_DBL(1.18f / (1 << (1)));
+ INT bit2PE_e = 1;
+
+ /**** 2) For AAC-(E)LD, make use of advanced bits to pe factor table ****/
+ if (advancedBitsToPe && nChannels <= (2)) {
+ int i;
+ const BIT_PE_SFAC *peTab = NULL;
+ INT size = 0;
+
+ /*** 2.1) Get correct table entry ***/
+ for (i = 0; i < (INT)(sizeof(bits2PeConfigTab) / sizeof(BITS2PE_CFG_TAB));
+ i++) {
+ if (sampleRate >= bits2PeConfigTab[i].sampleRate) {
+ peTab = bits2PeConfigTab[i].pPeTab;
+ size = bits2PeConfigTab[i].nEntries;
+ }
+ }
+
+ if ((peTab != NULL) && (size != 0)) {
+ INT startB = -1; /* bitrate entry in table that is the next-lower to
+ actual bitrate */
+ INT stopB = -1; /* bitrate entry in table that is the next-higher to
+ actual bitrate */
+ FIXP_DBL startPF =
+ FL2FXCONST_DBL(0.0f); /* bits2PE factor entry in table that is the
+ next-lower to actual bits2PE factor */
+ FIXP_DBL stopPF = FL2FXCONST_DBL(0.0f); /* bits2PE factor entry in table
+ that is the next-higher to
+ actual bits2PE factor */
+ FIXP_DBL slope = FL2FXCONST_DBL(
+ 0.0f); /* the slope from the start bits2Pe entry to the next one */
+ const int qualityIdx = (invQuant == 0) ? 0 : 1;
+
+ if (bitRate >= peTab[size - 1].bitrate) {
+ /* Chosen bitrate is higher than the highest bitrate in table.
+ The slope for extrapolating the bits2PE factor must be zero.
+ Values are set accordingly. */
+ startB = peTab[size - 1].bitrate;
+ stopB =
+ bitRate +
+ 1; /* Can be an arbitrary value greater than startB and bitrate. */
+ startPF = peTab[size - 1].bits2PeFactor[qualityIdx][nChannels - 1];
+ stopPF = peTab[size - 1].bits2PeFactor[qualityIdx][nChannels - 1];
+ } else {
+ for (i = 0; i < size - 1; i++) {
+ if ((peTab[i].bitrate <= bitRate) &&
+ (peTab[i + 1].bitrate > bitRate)) {
+ startB = peTab[i].bitrate;
+ stopB = peTab[i + 1].bitrate;
+ startPF = peTab[i].bits2PeFactor[qualityIdx][nChannels - 1];
+ stopPF = peTab[i + 1].bits2PeFactor[qualityIdx][nChannels - 1];
+ break;
+ }
+ }
+ }
+
+ /*** 2.2) Configuration available? ***/
+ if (startB != -1) {
+ /** 2.2.1) linear interpolate to actual PEfactor **/
+ FIXP_DBL bit2PE = 0;
+
+ const FIXP_DBL maxBit2PE = FL2FXCONST_DBL(3.f / 4.f);
+
+ /* bit2PE = ((stopPF-startPF)/(stopB-startB))*(bitRate-startB)+startPF;
+ */
+ slope = fDivNorm(bitRate - startB, stopB - startB);
+ bit2PE = fMult(slope, stopPF - startPF) + startPF;
+
+ bit2PE = fMin(maxBit2PE, bit2PE);
+
+ /** 2.2.2) sanity check if bits2pe value is high enough **/
+ if (bit2PE >= (FL2FXCONST_DBL(0.35f) >> 2)) {
+ bit2PE_m = bit2PE;
+ bit2PE_e = 2; /* table is fixed scaled */
+ }
+ } /* br */
+ } /* sr */
+ } /* advancedBitsToPe */
+
+ 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_e = bit2PE_e;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_bits2pe2
+description: convert from bits to pe
+*****************************************************************************/
+FDK_INLINE INT FDKaacEnc_bits2pe2(const INT bits, const FIXP_DBL factor_m,
+ const INT factor_e) {
+ return (INT)(fMult(factor_m, (FIXP_DBL)(bits << Q_AVGBITS)) >>
+ (Q_AVGBITS - factor_e));
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_calcThreshExp
+description: loudness calculation (threshold to the power of redExp)
+*****************************************************************************/
+static void FDKaacEnc_calcThreshExp(
+ FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB],
+ const QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)], const INT nChannels) {
+ INT ch, sfb, sfbGrp;
+ FIXP_DBL thrExpLdData;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ thrExpLdData = psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb] >> 2;
+ thrExp[ch][sfbGrp + sfb] = CalcInvLdData(thrExpLdData);
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_adaptMinSnr
+ description: reduce minSnr requirements for bands with relative low
+energies
+*****************************************************************************/
+static void FDKaacEnc_adaptMinSnr(
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ const MINSNR_ADAPT_PARAM *const msaParam, const INT nChannels) {
+ INT ch, sfb, sfbGrp, nSfb;
+ FIXP_DBL avgEnLD64, dbRatio, minSnrRed;
+ FIXP_DBL minSnrLimitLD64 =
+ FL2FXCONST_DBL(-0.00503012648262f); /* ld64(0.8f) */
+ FIXP_DBL nSfbLD64;
+ FIXP_DBL accu;
+
+ FIXP_DBL msaParam_maxRed = msaParam->maxRed;
+ FIXP_DBL msaParam_startRatio = msaParam->startRatio;
+ FIXP_DBL msaParam_redRatioFac =
+ fMult(msaParam->redRatioFac, FL2FXCONST_DBL(0.3010299956f));
+ FIXP_DBL msaParam_redOffs = msaParam->redOffs;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ /* calc average energy per scalefactor band */
+ nSfb = 0;
+ accu = FL2FXCONST_DBL(0.0f);
+
+ DWORD_ALIGNED(psyOutChannel[ch]->sfbEnergy);
+
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ int maxSfbPerGroup = psyOutChannel[ch]->maxSfbPerGroup;
+ nSfb += maxSfbPerGroup;
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ accu += psyOutChannel[ch]->sfbEnergy[sfbGrp + sfb] >> 6;
+ }
+ }
+
+ if ((accu == FL2FXCONST_DBL(0.0f)) || (nSfb == 0)) {
+ avgEnLD64 = FL2FXCONST_DBL(-1.0f);
+ } else {
+ nSfbLD64 = CalcLdInt(nSfb);
+ avgEnLD64 = CalcLdData(accu);
+ avgEnLD64 = avgEnLD64 + FL2FXCONST_DBL(0.09375f) -
+ nSfbLD64; /* 0.09375f: compensate shift with 6 */
+ }
+
+ /* reduce minSnr requirement by minSnr^minSnrRed dependent on avgEn/sfbEn */
+ int maxSfbPerGroup = psyOutChannel[ch]->maxSfbPerGroup;
+ int sfbCnt = psyOutChannel[ch]->sfbCnt;
+ int sfbPerGroup = psyOutChannel[ch]->sfbPerGroup;
+
+ for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) {
+ FIXP_DBL *RESTRICT psfbEnergyLdData =
+ &qcOutChannel[ch]->sfbEnergyLdData[sfbGrp];
+ FIXP_DBL *RESTRICT psfbMinSnrLdData =
+ &qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp];
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ FIXP_DBL sfbEnergyLdData = *psfbEnergyLdData++;
+ FIXP_DBL sfbMinSnrLdData = *psfbMinSnrLdData;
+ dbRatio = avgEnLD64 - sfbEnergyLdData;
+ int update = (msaParam_startRatio < dbRatio) ? 1 : 0;
+ minSnrRed = msaParam_redOffs + fMult(msaParam_redRatioFac,
+ dbRatio); /* scaled by 1.0f/64.0f*/
+ minSnrRed =
+ fixMax(minSnrRed, msaParam_maxRed); /* scaled by 1.0f/64.0f*/
+ minSnrRed = (fMult(sfbMinSnrLdData, minSnrRed)) << 6;
+ minSnrRed = fixMin(minSnrLimitLD64, minSnrRed);
+ *psfbMinSnrLdData++ = update ? minSnrRed : sfbMinSnrLdData;
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_initAvoidHoleFlag
+description: determine bands where avoid hole is not necessary resp. possible
+*****************************************************************************/
+static void FDKaacEnc_initAvoidHoleFlag(
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ UCHAR ahFlag[(2)][MAX_GROUPED_SFB], const struct TOOLSINFO *const toolsInfo,
+ const INT nChannels, const AH_PARAM *const ahParam) {
+ INT ch, sfb, sfbGrp;
+ FIXP_DBL sfbEn, sfbEnm1;
+ FIXP_DBL sfbEnLdData;
+ FIXP_DBL avgEnLdData;
+
+ /* decrease spread energy by 3dB for long blocks, resp. 2dB for shorts
+ (avoid more holes in long blocks) */
+ for (ch = 0; ch < nChannels; ch++) {
+ QC_OUT_CHANNEL *const qcOutChan = qcOutChannel[ch];
+
+ if (psyOutChannel[ch]->lastWindowSequence != SHORT_WINDOW) {
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup)
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++)
+ qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] >>= 1;
+ } else {
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup)
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++)
+ qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] = fMult(
+ FL2FXCONST_DBL(0.63f), qcOutChan->sfbSpreadEnergy[sfbGrp + sfb]);
+ }
+ }
+
+ /* increase minSnr for local peaks, decrease it for valleys */
+ if (ahParam->modifyMinSnr) {
+ for (ch = 0; ch < nChannels; ch++) {
+ QC_OUT_CHANNEL *const qcOutChan = qcOutChannel[ch];
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ FIXP_DBL sfbEnp1, avgEn;
+ if (sfb > 0)
+ sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp + sfb - 1];
+ else
+ sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp + sfb];
+
+ if (sfb < psyOutChannel[ch]->maxSfbPerGroup - 1)
+ sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp + sfb + 1];
+ else
+ sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp + sfb];
+
+ avgEn = (sfbEnm1 >> 1) + (sfbEnp1 >> 1);
+ avgEnLdData = CalcLdData(avgEn);
+ sfbEn = qcOutChan->sfbEnergy[sfbGrp + sfb];
+ sfbEnLdData = qcOutChan->sfbEnergyLdData[sfbGrp + sfb];
+ /* peak ? */
+ if (sfbEn > avgEn) {
+ FIXP_DBL tmpMinSnrLdData;
+ if (psyOutChannel[ch]->lastWindowSequence == LONG_WINDOW)
+ tmpMinSnrLdData =
+ fixMax(SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData),
+ (FIXP_DBL)SnrLdMin1);
+ else
+ tmpMinSnrLdData =
+ fixMax(SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData),
+ (FIXP_DBL)SnrLdMin3);
+
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] = fixMin(
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb], tmpMinSnrLdData);
+ }
+ /* valley ? */
+ if (((sfbEnLdData + (FIXP_DBL)SnrLdMin4) < (FIXP_DBL)avgEnLdData) &&
+ (sfbEn > FL2FXCONST_DBL(0.0))) {
+ FIXP_DBL tmpMinSnrLdData = avgEnLdData - sfbEnLdData -
+ (FIXP_DBL)SnrLdMin4 +
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb];
+ tmpMinSnrLdData = fixMin((FIXP_DBL)SnrLdFac, tmpMinSnrLdData);
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] =
+ fixMin(tmpMinSnrLdData,
+ (FIXP_DBL)(qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] +
+ SnrLdMin2));
+ }
+ }
+ }
+ }
+ }
+
+ /* stereo: adapt the minimum requirements sfbMinSnr of mid and
+ side channels to avoid spending unnoticable bits */
+ if (nChannels == 2) {
+ QC_OUT_CHANNEL *qcOutChanM = qcOutChannel[0];
+ QC_OUT_CHANNEL *qcOutChanS = qcOutChannel[1];
+ const PSY_OUT_CHANNEL *const psyOutChanM = psyOutChannel[0];
+ for (sfbGrp = 0; sfbGrp < psyOutChanM->sfbCnt;
+ sfbGrp += psyOutChanM->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChanM->maxSfbPerGroup; sfb++) {
+ if (toolsInfo->msMask[sfbGrp + sfb]) {
+ FIXP_DBL maxSfbEnLd =
+ fixMax(qcOutChanM->sfbEnergyLdData[sfbGrp + sfb],
+ qcOutChanS->sfbEnergyLdData[sfbGrp + sfb]);
+ FIXP_DBL maxThrLd, sfbMinSnrTmpLd;
+
+ if (((SnrLdMin5 >> 1) + (maxSfbEnLd >> 1) +
+ (qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] >> 1)) <=
+ FL2FXCONST_DBL(-0.5f))
+ maxThrLd = FL2FXCONST_DBL(-1.0f);
+ else
+ maxThrLd = SnrLdMin5 + maxSfbEnLd +
+ qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb];
+
+ if (qcOutChanM->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f))
+ sfbMinSnrTmpLd =
+ maxThrLd - qcOutChanM->sfbEnergyLdData[sfbGrp + sfb];
+ else
+ sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f);
+
+ qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] =
+ fixMax(qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb], sfbMinSnrTmpLd);
+
+ if (qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] <= FL2FXCONST_DBL(0.0f))
+ qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] = fixMin(
+ qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb], (FIXP_DBL)SnrLdFac);
+
+ if (qcOutChanS->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f))
+ sfbMinSnrTmpLd =
+ maxThrLd - qcOutChanS->sfbEnergyLdData[sfbGrp + sfb];
+ else
+ sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f);
+
+ qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] =
+ fixMax(qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb], sfbMinSnrTmpLd);
+
+ if (qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] <= FL2FXCONST_DBL(0.0f))
+ qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] = fixMin(
+ qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb], (FIXP_DBL)SnrLdFac);
+
+ if (qcOutChanM->sfbEnergy[sfbGrp + sfb] >
+ qcOutChanM->sfbSpreadEnergy[sfbGrp + sfb])
+ qcOutChanS->sfbSpreadEnergy[sfbGrp + sfb] = fMult(
+ qcOutChanS->sfbEnergy[sfbGrp + sfb], FL2FXCONST_DBL(0.9f));
+
+ if (qcOutChanS->sfbEnergy[sfbGrp + sfb] >
+ qcOutChanS->sfbSpreadEnergy[sfbGrp + sfb])
+ qcOutChanM->sfbSpreadEnergy[sfbGrp + sfb] = fMult(
+ qcOutChanM->sfbEnergy[sfbGrp + sfb], FL2FXCONST_DBL(0.9f));
+
+ } /* if (toolsInfo->msMask[sfbGrp+sfb]) */
+ } /* sfb */
+ } /* sfbGrp */
+ } /* nChannels==2 */
+
+ /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */
+ for (ch = 0; ch < nChannels; ch++) {
+ QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch];
+ const PSY_OUT_CHANNEL *const psyOutChan = psyOutChannel[ch];
+ for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt;
+ sfbGrp += psyOutChan->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) {
+ if ((qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] >
+ qcOutChan->sfbEnergy[sfbGrp + sfb]) ||
+ (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f))) {
+ ahFlag[ch][sfbGrp + sfb] = NO_AH;
+ } else {
+ ahFlag[ch][sfbGrp + sfb] = AH_INACTIVE;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * \brief Calculate constants that do not change during successive pe
+ * calculations.
+ *
+ * \param peData Pointer to structure containing PE data of
+ * current element.
+ * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding
+ * nChannels elements.
+ * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding
+ * nChannels elements.
+ * \param nChannels Number of channels in element.
+ * \param peOffset Fixed PE offset defined while
+ * FDKaacEnc_AdjThrInit() depending on bitrate.
+ *
+ * \return void
+ */
+static void FDKaacEnc_preparePe(PE_DATA *const peData,
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ const QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const INT nChannels, const INT peOffset) {
+ INT ch;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ const PSY_OUT_CHANNEL *const psyOutChan = psyOutChannel[ch];
+ FDKaacEnc_prepareSfbPe(
+ &peData->peChannelData[ch], psyOutChan->sfbEnergyLdData,
+ psyOutChan->sfbThresholdLdData, qcOutChannel[ch]->sfbFormFactorLdData,
+ psyOutChan->sfbOffsets, psyOutChan->sfbCnt, psyOutChan->sfbPerGroup,
+ psyOutChan->maxSfbPerGroup);
+ }
+ peData->offset = peOffset;
+}
+
+/**
+ * \brief Calculate weighting factor for threshold adjustment.
+ *
+ * Calculate weighting factor to be applied at energies and thresholds in ld64
+ * format.
+ *
+ * \param peData, Pointer to PE data in current element.
+ * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding
+ * nChannels elements.
+ * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding
+ * nChannels elements.
+ * \param toolsInfo Pointer to tools info struct of current element.
+ * \param adjThrStateElement Pointer to ATS_ELEMENT holding enFacPatch
+ * states.
+ * \param nChannels Number of channels in element.
+ * \param usePatchTool Apply the weighting tool 0 (no) else (yes).
+ *
+ * \return void
+ */
+static void FDKaacEnc_calcWeighting(
+ const PE_DATA *const peData,
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const struct TOOLSINFO *const toolsInfo,
+ ATS_ELEMENT *const adjThrStateElement, const INT nChannels,
+ const INT usePatchTool) {
+ int ch, noShortWindowInFrame = TRUE;
+ INT exePatchM = 0;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ if (psyOutChannel[ch]->lastWindowSequence == SHORT_WINDOW) {
+ noShortWindowInFrame = FALSE;
+ }
+ FDKmemclear(qcOutChannel[ch]->sfbEnFacLd,
+ MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+ }
+
+ if (usePatchTool == 0) {
+ return; /* tool is disabled */
+ }
+
+ for (ch = 0; ch < nChannels; ch++) {
+ const PSY_OUT_CHANNEL *const psyOutChan = psyOutChannel[ch];
+
+ if (noShortWindowInFrame) { /* retain energy ratio between blocks of
+ different length */
+
+ FIXP_DBL nrgSum14, nrgSum12, nrgSum34, nrgTotal;
+ FIXP_DBL nrgFacLd_14, nrgFacLd_12, nrgFacLd_34;
+ INT usePatch, exePatch;
+ int sfb, sfbGrp, nLinesSum = 0;
+
+ nrgSum14 = nrgSum12 = nrgSum34 = nrgTotal = FL2FXCONST_DBL(0.f);
+
+ /* calculate flatness of audible spectrum, i.e. spectrum above masking
+ * threshold. */
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ FIXP_DBL nrgFac12 = CalcInvLdData(
+ psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1); /* nrg^(1/2) */
+ FIXP_DBL nrgFac14 = CalcInvLdData(
+ psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 2); /* nrg^(1/4) */
+
+ /* maximal number of bands is 64, results scaling factor 6 */
+ nLinesSum += peData->peChannelData[ch]
+ .sfbNLines[sfbGrp + sfb]; /* relevant lines */
+ nrgTotal +=
+ (psyOutChan->sfbEnergy[sfbGrp + sfb] >> 6); /* sum up nrg */
+ nrgSum12 += (nrgFac12 >> 6); /* sum up nrg^(2/4) */
+ nrgSum14 += (nrgFac14 >> 6); /* sum up nrg^(1/4) */
+ nrgSum34 += (fMult(nrgFac14, nrgFac12) >> 6); /* sum up nrg^(3/4) */
+ }
+ }
+
+ nrgTotal = CalcLdData(nrgTotal); /* get ld64 of total nrg */
+
+ nrgFacLd_14 =
+ CalcLdData(nrgSum14) - nrgTotal; /* ld64(nrgSum14/nrgTotal) */
+ nrgFacLd_12 =
+ CalcLdData(nrgSum12) - nrgTotal; /* ld64(nrgSum12/nrgTotal) */
+ nrgFacLd_34 =
+ CalcLdData(nrgSum34) - nrgTotal; /* ld64(nrgSum34/nrgTotal) */
+
+ /* Note: nLinesSum cannot be larger than the number of total lines, thats
+ * taken care of in line_pe.cpp FDKaacEnc_prepareSfbPe() */
+ adjThrStateElement->chaosMeasureEnFac[ch] =
+ fMax(FL2FXCONST_DBL(0.1875f),
+ fDivNorm(nLinesSum, psyOutChan->sfbOffsets[psyOutChan->sfbCnt]));
+
+ usePatch = (adjThrStateElement->chaosMeasureEnFac[ch] >
+ FL2FXCONST_DBL(0.78125f));
+ exePatch = ((usePatch) && (adjThrStateElement->lastEnFacPatch[ch]));
+
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ INT sfbExePatch;
+ /* for MS coupled SFBs, also execute patch in side channel if done in
+ * mid channel */
+ if ((ch == 1) && (toolsInfo->msMask[sfbGrp + sfb])) {
+ sfbExePatch = exePatchM;
+ } else {
+ sfbExePatch = exePatch;
+ }
+
+ if ((sfbExePatch) &&
+ (psyOutChan->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.f))) {
+ /* execute patch based on spectral flatness calculated above */
+ if (adjThrStateElement->chaosMeasureEnFac[ch] >
+ FL2FXCONST_DBL(0.8125f)) {
+ qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] =
+ ((nrgFacLd_14 +
+ (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] +
+ (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1))) >>
+ 1); /* sfbEnergy^(3/4) */
+ } else if (adjThrStateElement->chaosMeasureEnFac[ch] >
+ FL2FXCONST_DBL(0.796875f)) {
+ qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] =
+ ((nrgFacLd_12 + psyOutChan->sfbEnergyLdData[sfbGrp + sfb]) >>
+ 1); /* sfbEnergy^(2/4) */
+ } else {
+ qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] =
+ ((nrgFacLd_34 +
+ (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1)) >>
+ 1); /* sfbEnergy^(1/4) */
+ }
+ qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] =
+ fixMin(qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb], (FIXP_DBL)0);
+ }
+ }
+ } /* sfb loop */
+
+ adjThrStateElement->lastEnFacPatch[ch] = usePatch;
+ exePatchM = exePatch;
+ } else {
+ /* !noShortWindowInFrame */
+ adjThrStateElement->chaosMeasureEnFac[ch] = FL2FXCONST_DBL(0.75f);
+ adjThrStateElement->lastEnFacPatch[ch] =
+ TRUE; /* allow use of sfbEnFac patch in upcoming frame */
+ }
+
+ } /* ch loop */
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_calcPe
+description: calculate pe for both channels
+*****************************************************************************/
+static void FDKaacEnc_calcPe(const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ const QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ PE_DATA *const peData, const INT nChannels) {
+ INT ch;
+
+ peData->pe = peData->offset;
+ peData->constPart = 0;
+ peData->nActiveLines = 0;
+ for (ch = 0; ch < nChannels; ch++) {
+ PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
+
+ FDKaacEnc_calcSfbPe(
+ peChanData, qcOutChannel[ch]->sfbWeightedEnergyLdData,
+ qcOutChannel[ch]->sfbThresholdLdData, psyOutChannel[ch]->sfbCnt,
+ psyOutChannel[ch]->sfbPerGroup, psyOutChannel[ch]->maxSfbPerGroup,
+ psyOutChannel[ch]->isBook, psyOutChannel[ch]->isScale);
+
+ peData->pe += peChanData->pe;
+ peData->constPart += peChanData->constPart;
+ peData->nActiveLines += peChanData->nActiveLines;
+ }
+}
+
+void FDKaacEnc_peCalculation(PE_DATA *const peData,
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const struct TOOLSINFO *const toolsInfo,
+ ATS_ELEMENT *const adjThrStateElement,
+ const INT nChannels) {
+ /* constants that will not change during successive pe calculations */
+ FDKaacEnc_preparePe(peData, psyOutChannel, qcOutChannel, nChannels,
+ adjThrStateElement->peOffset);
+
+ /* calculate weighting factor for threshold adjustment */
+ FDKaacEnc_calcWeighting(peData, psyOutChannel, qcOutChannel, toolsInfo,
+ adjThrStateElement, nChannels, 1);
+ {
+ /* no weighting of threholds and energies for mlout */
+ /* weight energies and thresholds */
+ int ch;
+ for (ch = 0; ch < nChannels; ch++) {
+ int sfb, sfbGrp;
+ QC_OUT_CHANNEL *pQcOutCh = qcOutChannel[ch];
+
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ pQcOutCh->sfbWeightedEnergyLdData[sfb + sfbGrp] =
+ pQcOutCh->sfbEnergyLdData[sfb + sfbGrp] -
+ pQcOutCh->sfbEnFacLd[sfb + sfbGrp];
+ pQcOutCh->sfbThresholdLdData[sfb + sfbGrp] -=
+ pQcOutCh->sfbEnFacLd[sfb + sfbGrp];
+ }
+ }
+ }
+ }
+
+ /* pe without reduction */
+ FDKaacEnc_calcPe(psyOutChannel, qcOutChannel, peData, nChannels);
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_FDKaacEnc_calcPeNoAH
+description: sum the pe data only for bands where avoid hole is inactive
+*****************************************************************************/
+#define CONSTPART_HEADROOM 4
+static void FDKaacEnc_FDKaacEnc_calcPeNoAH(
+ INT *const pe, INT *const constPart, INT *const nActiveLines,
+ const PE_DATA *const peData, const UCHAR ahFlag[(2)][MAX_GROUPED_SFB],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)], const INT nChannels) {
+ INT ch, sfb, sfbGrp;
+
+ INT pe_tmp = peData->offset;
+ INT constPart_tmp = 0;
+ INT nActiveLines_tmp = 0;
+ for (ch = 0; ch < nChannels; ch++) {
+ const PE_CHANNEL_DATA *const peChanData = &peData->peChannelData[ch];
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ if (ahFlag[ch][sfbGrp + sfb] < AH_ACTIVE) {
+ pe_tmp += peChanData->sfbPe[sfbGrp + sfb];
+ constPart_tmp +=
+ peChanData->sfbConstPart[sfbGrp + sfb] >> CONSTPART_HEADROOM;
+ nActiveLines_tmp += peChanData->sfbNActiveLines[sfbGrp + sfb];
+ }
+ }
+ }
+ }
+ /* correct scaled pe and constPart values */
+ *pe = pe_tmp >> PE_CONSTPART_SHIFT;
+ *constPart = constPart_tmp >> (PE_CONSTPART_SHIFT - CONSTPART_HEADROOM);
+
+ *nActiveLines = nActiveLines_tmp;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_reduceThresholdsCBR
+description: apply reduction formula
+*****************************************************************************/
+static const FIXP_DBL limitThrReducedLdData =
+ (FIXP_DBL)0x00008000; /*FL2FXCONST_DBL(FDKpow(2.0,-LD_DATA_SCALING/4.0));*/
+
+static void FDKaacEnc_reduceThresholdsCBR(
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ UCHAR ahFlag[(2)][MAX_GROUPED_SFB],
+ const FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], const INT nChannels,
+ const FIXP_DBL redVal_m, const SCHAR redVal_e) {
+ INT ch, sfb, sfbGrp;
+ FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData;
+ FIXP_DBL sfbThrExp;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch];
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb];
+ sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp + sfb];
+ sfbThrExp = thrExp[ch][sfbGrp + sfb];
+ if ((sfbEnLdData > sfbThrLdData) &&
+ (ahFlag[ch][sfbGrp + sfb] != AH_ACTIVE)) {
+ /* threshold reduction formula:
+ float tmp = thrExp[ch][sfb]+redVal;
+ tmp *= tmp;
+ sfbThrReduced = tmp*tmp;
+ */
+ int minScale = fixMin(CountLeadingBits(sfbThrExp),
+ CountLeadingBits(redVal_m) - redVal_e) -
+ 1;
+
+ /* 4*log( sfbThrExp + redVal ) */
+ sfbThrReducedLdData =
+ CalcLdData(fAbs(scaleValue(sfbThrExp, minScale) +
+ scaleValue(redVal_m, redVal_e + minScale))) -
+ (FIXP_DBL)(minScale << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
+ sfbThrReducedLdData <<= 2;
+
+ /* avoid holes */
+ if ((sfbThrReducedLdData >
+ (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData)) &&
+ (ahFlag[ch][sfbGrp + sfb] != NO_AH)) {
+ if (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] >
+ (FL2FXCONST_DBL(-1.0f) - sfbEnLdData)) {
+ sfbThrReducedLdData = fixMax(
+ (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData),
+ sfbThrLdData);
+ } else
+ sfbThrReducedLdData = sfbThrLdData;
+ ahFlag[ch][sfbGrp + sfb] = AH_ACTIVE;
+ }
+
+ /* minimum of 29 dB Ratio for Thresholds */
+ if ((sfbEnLdData + (FIXP_DBL)MAXVAL_DBL) >
+ FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)) {
+ sfbThrReducedLdData = fixMax(
+ sfbThrReducedLdData,
+ (sfbEnLdData - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)));
+ }
+
+ qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData;
+ }
+ }
+ }
+ }
+}
+
+/* similar to prepareSfbPe1() */
+static FIXP_DBL FDKaacEnc_calcChaosMeasure(
+ const PSY_OUT_CHANNEL *const psyOutChannel,
+ const FIXP_DBL *const sfbFormFactorLdData) {
+#define SCALE_FORM_FAC \
+ (4) /* (SCALE_FORM_FAC+FORM_FAC_SHIFT) >= ld(FRAME_LENGTH)*/
+#define SCALE_NRGS (8)
+#define SCALE_NLINES (16)
+#define SCALE_NRGS_SQRT4 (2) /* 0.25 * SCALE_NRGS */
+#define SCALE_NLINES_P34 (12) /* 0.75 * SCALE_NLINES */
+
+ INT sfbGrp, sfb;
+ FIXP_DBL chaosMeasure;
+ INT frameNLines = 0;
+ FIXP_DBL frameFormFactor = FL2FXCONST_DBL(0.f);
+ FIXP_DBL frameEnergy = FL2FXCONST_DBL(0.f);
+
+ for (sfbGrp = 0; sfbGrp < psyOutChannel->sfbCnt;
+ sfbGrp += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ if (psyOutChannel->sfbEnergyLdData[sfbGrp + sfb] >
+ psyOutChannel->sfbThresholdLdData[sfbGrp + sfb]) {
+ frameFormFactor += (CalcInvLdData(sfbFormFactorLdData[sfbGrp + sfb]) >>
+ SCALE_FORM_FAC);
+ frameNLines += (psyOutChannel->sfbOffsets[sfbGrp + sfb + 1] -
+ psyOutChannel->sfbOffsets[sfbGrp + sfb]);
+ frameEnergy += (psyOutChannel->sfbEnergy[sfbGrp + sfb] >> SCALE_NRGS);
+ }
+ }
+ }
+
+ if (frameNLines > 0) {
+ /* frameNActiveLines = frameFormFactor*2^FORM_FAC_SHIFT * ((frameEnergy
+ *2^SCALE_NRGS)/frameNLines)^-0.25 chaosMeasure = frameNActiveLines /
+ frameNLines */
+ chaosMeasure = CalcInvLdData(
+ (((CalcLdData(frameFormFactor) >> 1) -
+ (CalcLdData(frameEnergy) >> (2 + 1))) -
+ (fMultDiv2(FL2FXCONST_DBL(0.75f),
+ CalcLdData((FIXP_DBL)frameNLines
+ << (DFRACT_BITS - 1 - SCALE_NLINES))) -
+ (((FIXP_DBL)(-((-SCALE_FORM_FAC + SCALE_NRGS_SQRT4 - FORM_FAC_SHIFT +
+ SCALE_NLINES_P34)
+ << (DFRACT_BITS - 1 - LD_DATA_SHIFT)))) >>
+ 1)))
+ << 1);
+ } else {
+ /* assuming total chaos, if no sfb is above thresholds */
+ chaosMeasure = FL2FXCONST_DBL(1.f);
+ }
+
+ return chaosMeasure;
+}
+
+/* apply reduction formula for VBR-mode */
+static void FDKaacEnc_reduceThresholdsVBR(
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ UCHAR ahFlag[(2)][MAX_GROUPED_SFB],
+ const FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], const INT nChannels,
+ const FIXP_DBL vbrQualFactor, FIXP_DBL *const chaosMeasureOld) {
+ INT ch, sfbGrp, sfb;
+ FIXP_DBL chGroupEnergy[TRANS_FAC][2]; /*energy for each group and channel*/
+ FIXP_DBL chChaosMeasure[2];
+ FIXP_DBL frameEnergy = FL2FXCONST_DBL(1e-10f);
+ FIXP_DBL chaosMeasure = FL2FXCONST_DBL(0.f);
+ FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrExp;
+ FIXP_DBL sfbThrReducedLdData;
+ FIXP_DBL chaosMeasureAvg;
+ INT groupCnt; /* loop counter */
+ FIXP_DBL redVal[TRANS_FAC]; /* reduction values; in short-block case one
+ redVal for each group */
+ QC_OUT_CHANNEL *qcOutChan = NULL;
+ const PSY_OUT_CHANNEL *psyOutChan = NULL;
+
+#define SCALE_GROUP_ENERGY (8)
+
+#define CONST_CHAOS_MEAS_AVG_FAC_0 (FL2FXCONST_DBL(0.25f))
+#define CONST_CHAOS_MEAS_AVG_FAC_1 (FL2FXCONST_DBL(1.f - 0.25f))
+
+#define MIN_LDTHRESH (FL2FXCONST_DBL(-0.515625f))
+
+ for (ch = 0; ch < nChannels; ch++) {
+ psyOutChan = psyOutChannel[ch];
+
+ /* adding up energy for each channel and each group separately */
+ FIXP_DBL chEnergy = FL2FXCONST_DBL(0.f);
+ groupCnt = 0;
+
+ for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt;
+ sfbGrp += psyOutChan->sfbPerGroup, groupCnt++) {
+ chGroupEnergy[groupCnt][ch] = FL2FXCONST_DBL(0.f);
+ for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) {
+ chGroupEnergy[groupCnt][ch] +=
+ (psyOutChan->sfbEnergy[sfbGrp + sfb] >> SCALE_GROUP_ENERGY);
+ }
+ chEnergy += chGroupEnergy[groupCnt][ch];
+ }
+ frameEnergy += chEnergy;
+
+ /* chaosMeasure */
+ if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) {
+ chChaosMeasure[ch] = FL2FXCONST_DBL(
+ 0.5f); /* assume a constant chaos measure of 0.5f for short blocks */
+ } else {
+ chChaosMeasure[ch] = FDKaacEnc_calcChaosMeasure(
+ psyOutChannel[ch], qcOutChannel[ch]->sfbFormFactorLdData);
+ }
+ chaosMeasure += fMult(chChaosMeasure[ch], chEnergy);
+ }
+
+ if (frameEnergy > chaosMeasure) {
+ INT scale = CntLeadingZeros(frameEnergy) - 1;
+ FIXP_DBL num = chaosMeasure << scale;
+ FIXP_DBL denum = frameEnergy << scale;
+ chaosMeasure = schur_div(num, denum, 16);
+ } else {
+ chaosMeasure = FL2FXCONST_DBL(1.f);
+ }
+
+ chaosMeasureAvg = fMult(CONST_CHAOS_MEAS_AVG_FAC_0, chaosMeasure) +
+ fMult(CONST_CHAOS_MEAS_AVG_FAC_1,
+ *chaosMeasureOld); /* averaging chaos measure */
+ *chaosMeasureOld = chaosMeasure = (fixMin(
+ chaosMeasure, chaosMeasureAvg)); /* use min-value, safe for next frame */
+
+ /* characteristic curve
+ chaosMeasure = 0.2f + 0.7f/0.3f * (chaosMeasure - 0.2f);
+ chaosMeasure = fixMin(1.0f, fixMax(0.1f, chaosMeasure));
+ constants scaled by 4.f
+ */
+ chaosMeasure = ((FL2FXCONST_DBL(0.2f) >> 2) +
+ fMult(FL2FXCONST_DBL(0.7f / (4.f * 0.3f)),
+ (chaosMeasure - FL2FXCONST_DBL(0.2f))));
+ chaosMeasure =
+ (fixMin((FIXP_DBL)(FL2FXCONST_DBL(1.0f) >> 2),
+ fixMax((FIXP_DBL)(FL2FXCONST_DBL(0.1f) >> 2), chaosMeasure)))
+ << 2;
+
+ /* calculation of reduction value */
+ if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) { /* short-blocks */
+ FDK_ASSERT(TRANS_FAC == 8);
+#define WIN_TYPE_SCALE (3)
+
+ groupCnt = 0;
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[0]->sfbCnt;
+ sfbGrp += psyOutChannel[0]->sfbPerGroup, groupCnt++) {
+ FIXP_DBL groupEnergy = FL2FXCONST_DBL(0.f);
+
+ for (ch = 0; ch < nChannels; ch++) {
+ groupEnergy +=
+ chGroupEnergy[groupCnt]
+ [ch]; /* adding up the channels groupEnergy */
+ }
+
+ FDK_ASSERT(psyOutChannel[0]->groupLen[groupCnt] <= INV_INT_TAB_SIZE);
+ groupEnergy = fMult(
+ groupEnergy,
+ invInt[psyOutChannel[0]->groupLen[groupCnt]]); /* correction of
+ group energy */
+ groupEnergy = fixMin(groupEnergy,
+ frameEnergy >> WIN_TYPE_SCALE); /* do not allow an
+ higher redVal as
+ calculated
+ framewise */
+
+ groupEnergy >>=
+ 2; /* 2*WIN_TYPE_SCALE = 6 => 6+2 = 8 ==> 8/4 = int number */
+
+ redVal[groupCnt] =
+ fMult(fMult(vbrQualFactor, chaosMeasure),
+ CalcInvLdData(CalcLdData(groupEnergy) >> 2))
+ << (int)((2 + (2 * WIN_TYPE_SCALE) + SCALE_GROUP_ENERGY) >> 2);
+ }
+ } else { /* long-block */
+
+ redVal[0] = fMult(fMult(vbrQualFactor, chaosMeasure),
+ CalcInvLdData(CalcLdData(frameEnergy) >> 2))
+ << (int)(SCALE_GROUP_ENERGY >> 2);
+ }
+
+ for (ch = 0; ch < nChannels; ch++) {
+ qcOutChan = qcOutChannel[ch];
+ psyOutChan = psyOutChannel[ch];
+
+ for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt;
+ sfbGrp += psyOutChan->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) {
+ sfbEnLdData = (qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb]);
+ sfbThrLdData = (qcOutChan->sfbThresholdLdData[sfbGrp + sfb]);
+ sfbThrExp = thrExp[ch][sfbGrp + sfb];
+
+ if ((sfbThrLdData >= MIN_LDTHRESH) && (sfbEnLdData > sfbThrLdData) &&
+ (ahFlag[ch][sfbGrp + sfb] != AH_ACTIVE)) {
+ /* Short-Window */
+ if (psyOutChannel[ch]->lastWindowSequence == SHORT_WINDOW) {
+ const int groupNumber = (int)sfb / psyOutChan->sfbPerGroup;
+
+ FDK_ASSERT(INV_SQRT4_TAB_SIZE > psyOutChan->groupLen[groupNumber]);
+
+ sfbThrExp =
+ fMult(sfbThrExp,
+ fMult(FL2FXCONST_DBL(2.82f / 4.f),
+ invSqrt4[psyOutChan->groupLen[groupNumber]]))
+ << 2;
+
+ if (sfbThrExp <= (limitThrReducedLdData - redVal[groupNumber])) {
+ sfbThrReducedLdData = FL2FXCONST_DBL(-1.0f);
+ } else {
+ if ((FIXP_DBL)redVal[groupNumber] >=
+ FL2FXCONST_DBL(1.0f) - sfbThrExp)
+ sfbThrReducedLdData = FL2FXCONST_DBL(0.0f);
+ else {
+ /* threshold reduction formula */
+ sfbThrReducedLdData =
+ CalcLdData(sfbThrExp + redVal[groupNumber]);
+ sfbThrReducedLdData <<= 2;
+ }
+ }
+ sfbThrReducedLdData +=
+ (CalcLdInt(psyOutChan->groupLen[groupNumber]) -
+ ((FIXP_DBL)6 << (DFRACT_BITS - 1 - LD_DATA_SHIFT)));
+ }
+
+ /* Long-Window */
+ else {
+ if ((FIXP_DBL)redVal[0] >= FL2FXCONST_DBL(1.0f) - sfbThrExp) {
+ sfbThrReducedLdData = FL2FXCONST_DBL(0.0f);
+ } else {
+ /* threshold reduction formula */
+ sfbThrReducedLdData = CalcLdData(sfbThrExp + redVal[0]);
+ sfbThrReducedLdData <<= 2;
+ }
+ }
+
+ /* avoid holes */
+ if (((sfbThrReducedLdData - sfbEnLdData) >
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb]) &&
+ (ahFlag[ch][sfbGrp + sfb] != NO_AH)) {
+ if (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] >
+ (FL2FXCONST_DBL(-1.0f) - sfbEnLdData)) {
+ sfbThrReducedLdData = fixMax(
+ (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData),
+ sfbThrLdData);
+ } else
+ sfbThrReducedLdData = sfbThrLdData;
+ ahFlag[ch][sfbGrp + sfb] = AH_ACTIVE;
+ }
+
+ if (sfbThrReducedLdData < FL2FXCONST_DBL(-0.5f))
+ sfbThrReducedLdData = FL2FXCONST_DBL(-1.f);
+
+ /* minimum of 29 dB Ratio for Thresholds */
+ if ((sfbEnLdData + FL2FXCONST_DBL(1.0f)) >
+ FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)) {
+ sfbThrReducedLdData = fixMax(
+ sfbThrReducedLdData,
+ sfbEnLdData - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING));
+ }
+
+ sfbThrReducedLdData = fixMax(MIN_LDTHRESH, sfbThrReducedLdData);
+
+ qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData;
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_correctThresh
+description: if pe difference deltaPe between desired pe and real pe is small
+enough, the difference can be distributed among the scale factor bands. New
+thresholds can be derived from this pe-difference
+*****************************************************************************/
+static void FDKaacEnc_correctThresh(
+ const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))],
+ const PSY_OUT_ELEMENT *const psyOutElement[((8))],
+ UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB],
+ const FIXP_DBL thrExp[((8))][(2)][MAX_GROUPED_SFB], const FIXP_DBL redVal_m,
+ const SCHAR redVal_e, const INT deltaPe, const INT processElements,
+ const INT elementOffset) {
+ INT ch, sfb, sfbGrp;
+ QC_OUT_CHANNEL *qcOutChan;
+ PSY_OUT_CHANNEL *psyOutChan;
+ PE_CHANNEL_DATA *peChanData;
+ FIXP_DBL thrFactorLdData;
+ FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData;
+ FIXP_DBL *sfbPeFactorsLdData[((8))][(2)];
+ FIXP_DBL(*sfbNActiveLinesLdData)[(2)][MAX_GROUPED_SFB];
+
+ INT normFactorInt;
+ FIXP_DBL normFactorLdData;
+
+ INT nElements = elementOffset + processElements;
+ INT elementId;
+
+ /* scratch is empty; use temporal memory from quantSpec in QC_OUT_CHANNEL */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ /* The reinterpret_cast is used to suppress a compiler warning. We know
+ * that qcElement[elementId]->qcOutChannel[ch]->quantSpec is sufficiently
+ * aligned, so the cast is safe */
+ sfbPeFactorsLdData[elementId][ch] =
+ reinterpret_cast<FIXP_DBL *>(reinterpret_cast<void *>(
+ qcElement[elementId]->qcOutChannel[ch]->quantSpec));
+ }
+ }
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * qcElement[0]->dynMem_SfbNActiveLinesLdData is sufficiently aligned, so the
+ * cast is safe */
+ sfbNActiveLinesLdData = reinterpret_cast<FIXP_DBL(*)[(2)][MAX_GROUPED_SFB]>(
+ reinterpret_cast<void *>(qcElement[0]->dynMem_SfbNActiveLinesLdData));
+
+ /* for each sfb calc relative factors for pe changes */
+ normFactorInt = 0;
+
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ psyOutChan = psyOutElement[elementId]->psyOutChannel[ch];
+ peChanData = &qcElement[elementId]->peData.peChannelData[ch];
+
+ for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt;
+ sfbGrp += psyOutChan->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) {
+ if (peChanData->sfbNActiveLines[sfbGrp + sfb] == 0) {
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] =
+ FL2FXCONST_DBL(-1.0f);
+ } else {
+ /* Both CalcLdInt and CalcLdData can be used!
+ * No offset has to be subtracted, because sfbNActiveLinesLdData
+ * is shorted while thrFactor calculation */
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] =
+ CalcLdInt(peChanData->sfbNActiveLines[sfbGrp + sfb]);
+ }
+ if (((ahFlag[elementId][ch][sfbGrp + sfb] < AH_ACTIVE) ||
+ (deltaPe > 0)) &&
+ peChanData->sfbNActiveLines[sfbGrp + sfb] != 0) {
+ if (thrExp[elementId][ch][sfbGrp + sfb] > -redVal_m) {
+ /* sfbPeFactors[ch][sfbGrp+sfb] =
+ peChanData->sfbNActiveLines[sfbGrp+sfb] /
+ (thrExp[elementId][ch][sfbGrp+sfb] +
+ redVal[elementId]); */
+
+ int minScale =
+ fixMin(
+ CountLeadingBits(thrExp[elementId][ch][sfbGrp + sfb]),
+ CountLeadingBits(redVal_m) - redVal_e) -
+ 1;
+
+ /* sumld = ld64( sfbThrExp + redVal ) */
+ FIXP_DBL sumLd =
+ CalcLdData(scaleValue(thrExp[elementId][ch][sfbGrp + sfb],
+ minScale) +
+ scaleValue(redVal_m, redVal_e + minScale)) -
+ (FIXP_DBL)(minScale << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
+
+ if (sumLd < FL2FXCONST_DBL(0.f)) {
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] =
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] -
+ sumLd;
+ } else {
+ if (sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] >
+ (FL2FXCONST_DBL(-1.f) + sumLd)) {
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] =
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] -
+ sumLd;
+ } else {
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] =
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb];
+ }
+ }
+
+ normFactorInt += (INT)CalcInvLdData(
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb]);
+ } else
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] =
+ FL2FXCONST_DBL(1.0f);
+ } else
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] =
+ FL2FXCONST_DBL(-1.0f);
+ }
+ }
+ }
+ }
+ }
+
+ /* normFactorLdData = ld64(deltaPe/normFactorInt) */
+ normFactorLdData =
+ CalcLdData((FIXP_DBL)((deltaPe < 0) ? (-deltaPe) : (deltaPe))) -
+ CalcLdData((FIXP_DBL)normFactorInt);
+
+ /* distribute the pe difference to the scalefactors
+ and calculate the according thresholds */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ qcOutChan = qcElement[elementId]->qcOutChannel[ch];
+ psyOutChan = psyOutElement[elementId]->psyOutChannel[ch];
+ peChanData = &qcElement[elementId]->peData.peChannelData[ch];
+
+ for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt;
+ sfbGrp += psyOutChan->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) {
+ if (peChanData->sfbNActiveLines[sfbGrp + sfb] > 0) {
+ /* pe difference for this sfb */
+ if ((sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] ==
+ FL2FXCONST_DBL(-1.0f)) ||
+ (deltaPe == 0)) {
+ thrFactorLdData = FL2FXCONST_DBL(0.f);
+ } else {
+ /* new threshold */
+ FIXP_DBL tmp = CalcInvLdData(
+ sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] +
+ normFactorLdData -
+ sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] -
+ FL2FXCONST_DBL((float)LD_DATA_SHIFT / LD_DATA_SCALING));
+
+ /* limit thrFactor to 60dB */
+ tmp = (deltaPe < 0) ? tmp : (-tmp);
+ thrFactorLdData =
+ fMin(tmp, FL2FXCONST_DBL(20.f / LD_DATA_SCALING));
+ }
+
+ /* new threshold */
+ sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp + sfb];
+ sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb];
+
+ if (thrFactorLdData < FL2FXCONST_DBL(0.f)) {
+ if (sfbThrLdData > (FL2FXCONST_DBL(-1.f) - thrFactorLdData)) {
+ sfbThrReducedLdData = sfbThrLdData + thrFactorLdData;
+ } else {
+ sfbThrReducedLdData = FL2FXCONST_DBL(-1.f);
+ }
+ } else {
+ sfbThrReducedLdData = sfbThrLdData + thrFactorLdData;
+ }
+
+ /* avoid hole */
+ if ((sfbThrReducedLdData - sfbEnLdData >
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb]) &&
+ (ahFlag[elementId][ch][sfbGrp + sfb] == AH_INACTIVE)) {
+ /* sfbThrReduced = max(psyOutChan[ch]->sfbMinSnr[i] * sfbEn,
+ * sfbThr); */
+ if (sfbEnLdData >
+ (sfbThrLdData - qcOutChan->sfbMinSnrLdData[sfbGrp + sfb])) {
+ sfbThrReducedLdData =
+ qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData;
+ } else {
+ sfbThrReducedLdData = sfbThrLdData;
+ }
+ ahFlag[elementId][ch][sfbGrp + sfb] = AH_ACTIVE;
+ }
+
+ qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_reduceMinSnr
+ description: if the desired pe can not be reached, reduce pe by
+ reducing minSnr
+*****************************************************************************/
+static void FDKaacEnc_reduceMinSnr(
+ const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))],
+ const PSY_OUT_ELEMENT *const psyOutElement[((8))],
+ const UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB], const INT desiredPe,
+ INT *const redPeGlobal, const INT processElements, const INT elementOffset)
+
+{
+ INT ch, elementId, globalMaxSfb = 0;
+ const INT nElements = elementOffset + processElements;
+ INT newGlobalPe = *redPeGlobal;
+
+ if (newGlobalPe <= desiredPe) {
+ goto bail;
+ }
+
+ /* global maximum of maxSfbPerGroup */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ globalMaxSfb =
+ fMax(globalMaxSfb,
+ psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup);
+ }
+ }
+ }
+
+ /* as long as globalPE is above desirePE reduce SNR to 1.0 dB, starting at
+ * highest SFB */
+ while ((newGlobalPe > desiredPe) && (--globalMaxSfb >= 0)) {
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ QC_OUT_CHANNEL *qcOutChan = qcElement[elementId]->qcOutChannel[ch];
+ PSY_OUT_CHANNEL *psyOutChan =
+ psyOutElement[elementId]->psyOutChannel[ch];
+
+ /* try to reduce SNR of channel's uppermost SFB(s) */
+ if (globalMaxSfb < psyOutChan->maxSfbPerGroup) {
+ INT sfb, deltaPe = 0;
+
+ for (sfb = globalMaxSfb; sfb < psyOutChan->sfbCnt;
+ sfb += psyOutChan->sfbPerGroup) {
+ if (ahFlag[elementId][ch][sfb] != NO_AH &&
+ qcOutChan->sfbMinSnrLdData[sfb] < SnrLdFac &&
+ (qcOutChan->sfbWeightedEnergyLdData[sfb] >
+ qcOutChan->sfbThresholdLdData[sfb] - SnrLdFac)) {
+ /* increase threshold to new minSnr of 1dB */
+ qcOutChan->sfbMinSnrLdData[sfb] = SnrLdFac;
+ qcOutChan->sfbThresholdLdData[sfb] =
+ qcOutChan->sfbWeightedEnergyLdData[sfb] + SnrLdFac;
+
+ /* calc new pe */
+ /* C2 + C3*ld(1/0.8) = 1.5 */
+ deltaPe -= peData->peChannelData[ch].sfbPe[sfb];
+
+ /* sfbPe = 1.5 * sfbNLines */
+ peData->peChannelData[ch].sfbPe[sfb] =
+ (3 * peData->peChannelData[ch].sfbNLines[sfb])
+ << (PE_CONSTPART_SHIFT - 1);
+ deltaPe += peData->peChannelData[ch].sfbPe[sfb];
+ }
+
+ } /* sfb loop */
+
+ deltaPe >>= PE_CONSTPART_SHIFT;
+ peData->pe += deltaPe;
+ peData->peChannelData[ch].pe += deltaPe;
+ newGlobalPe += deltaPe;
+
+ } /* if globalMaxSfb < maxSfbPerGroup */
+
+ /* stop if enough has been saved */
+ if (newGlobalPe <= desiredPe) {
+ goto bail;
+ }
+
+ } /* ch loop */
+ } /* != ID_DSE */
+ } /* elementId loop */
+ } /* while ( newGlobalPe > desiredPe) && (--globalMaxSfb >= 0) ) */
+
+bail:
+ /* update global PE */
+ *redPeGlobal = newGlobalPe;
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_allowMoreHoles
+ description: if the desired pe can not be reached, some more scalefactor
+ bands have to be quantized to zero
+*****************************************************************************/
+static void FDKaacEnc_allowMoreHoles(
+ const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))],
+ const PSY_OUT_ELEMENT *const psyOutElement[((8))],
+ const ATS_ELEMENT *const AdjThrStateElement[((8))],
+ UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB], const INT desiredPe,
+ const INT currentPe, const int processElements, const int elementOffset) {
+ INT elementId;
+ INT nElements = elementOffset + processElements;
+ INT actPe = currentPe;
+
+ if (actPe <= desiredPe) {
+ return; /* nothing to do */
+ }
+
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT ch, sfb, sfbGrp;
+
+ PE_DATA *peData = &qcElement[elementId]->peData;
+ const INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+
+ QC_OUT_CHANNEL *qcOutChannel[(2)] = {NULL};
+ PSY_OUT_CHANNEL *psyOutChannel[(2)] = {NULL};
+
+ for (ch = 0; ch < nChannels; ch++) {
+ /* init pointers */
+ qcOutChannel[ch] = qcElement[elementId]->qcOutChannel[ch];
+ psyOutChannel[ch] = psyOutElement[elementId]->psyOutChannel[ch];
+
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = psyOutChannel[ch]->maxSfbPerGroup;
+ sfb < psyOutChannel[ch]->sfbPerGroup; sfb++) {
+ peData->peChannelData[ch].sfbPe[sfbGrp + sfb] = 0;
+ }
+ }
+ }
+
+ /* for MS allow hole in the channel with less energy */
+ if (nChannels == 2 && psyOutChannel[0]->lastWindowSequence ==
+ psyOutChannel[1]->lastWindowSequence) {
+ for (sfb = psyOutChannel[0]->maxSfbPerGroup - 1; sfb >= 0; sfb--) {
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[0]->sfbCnt;
+ sfbGrp += psyOutChannel[0]->sfbPerGroup) {
+ if (psyOutElement[elementId]->toolsInfo.msMask[sfbGrp + sfb]) {
+ FIXP_DBL EnergyLd_L =
+ qcOutChannel[0]->sfbWeightedEnergyLdData[sfbGrp + sfb];
+ FIXP_DBL EnergyLd_R =
+ qcOutChannel[1]->sfbWeightedEnergyLdData[sfbGrp + sfb];
+
+ /* allow hole in side channel ? */
+ if ((ahFlag[elementId][1][sfbGrp + sfb] != NO_AH) &&
+ (((FL2FXCONST_DBL(-0.02065512648f) >> 1) +
+ (qcOutChannel[0]->sfbMinSnrLdData[sfbGrp + sfb] >> 1)) >
+ ((EnergyLd_R >> 1) - (EnergyLd_L >> 1)))) {
+ ahFlag[elementId][1][sfbGrp + sfb] = NO_AH;
+ qcOutChannel[1]->sfbThresholdLdData[sfbGrp + sfb] =
+ FL2FXCONST_DBL(0.015625f) + EnergyLd_R;
+ actPe -= peData->peChannelData[1].sfbPe[sfbGrp + sfb] >>
+ PE_CONSTPART_SHIFT;
+ }
+ /* allow hole in mid channel ? */
+ else if ((ahFlag[elementId][0][sfbGrp + sfb] != NO_AH) &&
+ (((FL2FXCONST_DBL(-0.02065512648f) >> 1) +
+ (qcOutChannel[1]->sfbMinSnrLdData[sfbGrp + sfb] >>
+ 1)) > ((EnergyLd_L >> 1) - (EnergyLd_R >> 1)))) {
+ ahFlag[elementId][0][sfbGrp + sfb] = NO_AH;
+ qcOutChannel[0]->sfbThresholdLdData[sfbGrp + sfb] =
+ FL2FXCONST_DBL(0.015625f) + EnergyLd_L;
+ actPe -= peData->peChannelData[0].sfbPe[sfbGrp + sfb] >>
+ PE_CONSTPART_SHIFT;
+ } /* if (ahFlag) */
+ } /* if MS */
+ } /* sfbGrp */
+ if (actPe <= desiredPe) {
+ return; /* stop if enough has been saved */
+ }
+ } /* sfb */
+ } /* MS possible ? */
+
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+
+ if (actPe > desiredPe) {
+ /* more holes necessary? subsequently erase bands starting with low energies
+ */
+ INT ch, sfb, sfbGrp;
+ INT minSfb, maxSfb;
+ INT enIdx, ahCnt, done;
+ INT startSfb[(8)];
+ INT sfbCnt[(8)];
+ INT sfbPerGroup[(8)];
+ INT maxSfbPerGroup[(8)];
+ FIXP_DBL avgEn;
+ FIXP_DBL minEnLD64;
+ FIXP_DBL avgEnLD64;
+ FIXP_DBL enLD64[NUM_NRG_LEVS];
+ INT avgEn_e;
+
+ /* get the scaling factor over all audio elements and channels */
+ maxSfb = 0;
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ for (sfbGrp = 0;
+ sfbGrp < psyOutElement[elementId]->psyOutChannel[ch]->sfbCnt;
+ sfbGrp +=
+ psyOutElement[elementId]->psyOutChannel[ch]->sfbPerGroup) {
+ maxSfb +=
+ psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup;
+ }
+ }
+ }
+ }
+ avgEn_e =
+ (DFRACT_BITS - fixnormz_D((LONG)fMax(0, maxSfb - 1))); /* ilog2() */
+
+ ahCnt = 0;
+ maxSfb = 0;
+ minSfb = MAX_SFB;
+ avgEn = FL2FXCONST_DBL(0.0f);
+ minEnLD64 = FL2FXCONST_DBL(0.0f);
+
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ const INT chIdx = cm->elInfo[elementId].ChannelIndex[ch];
+ QC_OUT_CHANNEL *qcOutChannel = qcElement[elementId]->qcOutChannel[ch];
+ PSY_OUT_CHANNEL *psyOutChannel =
+ psyOutElement[elementId]->psyOutChannel[ch];
+
+ maxSfbPerGroup[chIdx] = psyOutChannel->maxSfbPerGroup;
+ sfbCnt[chIdx] = psyOutChannel->sfbCnt;
+ sfbPerGroup[chIdx] = psyOutChannel->sfbPerGroup;
+
+ maxSfb = fMax(maxSfb, psyOutChannel->maxSfbPerGroup);
+
+ if (psyOutChannel->lastWindowSequence != SHORT_WINDOW) {
+ startSfb[chIdx] = AdjThrStateElement[elementId]->ahParam.startSfbL;
+ } else {
+ startSfb[chIdx] = AdjThrStateElement[elementId]->ahParam.startSfbS;
+ }
+
+ minSfb = fMin(minSfb, startSfb[chIdx]);
+
+ sfbGrp = 0;
+ sfb = startSfb[chIdx];
+
+ do {
+ for (; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ if ((ahFlag[elementId][ch][sfbGrp + sfb] != NO_AH) &&
+ (qcOutChannel->sfbWeightedEnergyLdData[sfbGrp + sfb] >
+ qcOutChannel->sfbThresholdLdData[sfbGrp + sfb])) {
+ minEnLD64 = fixMin(minEnLD64,
+ qcOutChannel->sfbEnergyLdData[sfbGrp + sfb]);
+ avgEn += qcOutChannel->sfbEnergy[sfbGrp + sfb] >> avgEn_e;
+ ahCnt++;
+ }
+ }
+
+ sfbGrp += psyOutChannel->sfbPerGroup;
+ sfb = startSfb[chIdx];
+
+ } while (sfbGrp < psyOutChannel->sfbCnt);
+ }
+ } /* (cm->elInfo[elementId].elType != ID_DSE) */
+ } /* (elementId = elementOffset;elementId<nElements;elementId++) */
+
+ if ((avgEn == FL2FXCONST_DBL(0.0f)) || (ahCnt == 0)) {
+ avgEnLD64 = FL2FXCONST_DBL(0.0f);
+ } else {
+ avgEnLD64 = CalcLdData(avgEn) +
+ (FIXP_DBL)(avgEn_e << (DFRACT_BITS - 1 - LD_DATA_SHIFT)) -
+ CalcLdInt(ahCnt);
+ }
+
+ /* calc some energy borders between minEn and avgEn */
+
+ /* for (enIdx = 0; enIdx < NUM_NRG_LEVS; enIdx++) {
+ en[enIdx] = (2.0f*enIdx+1.0f)/(2.0f*NUM_NRG_LEVS-1.0f);
+ } */
+ enLD64[0] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.06666667f));
+ enLD64[1] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.20000000f));
+ enLD64[2] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.33333334f));
+ enLD64[3] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.46666667f));
+ enLD64[4] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.60000002f));
+ enLD64[5] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.73333335f));
+ enLD64[6] =
+ minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.86666667f));
+ enLD64[7] = minEnLD64 + (avgEnLD64 - minEnLD64);
+
+ done = 0;
+ enIdx = 0;
+ sfb = maxSfb - 1;
+
+ while (!done) {
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ PE_DATA *peData = &qcElement[elementId]->peData;
+ for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) {
+ const INT chIdx = cm->elInfo[elementId].ChannelIndex[ch];
+ QC_OUT_CHANNEL *qcOutChannel =
+ qcElement[elementId]->qcOutChannel[ch];
+ if (sfb >= startSfb[chIdx] && sfb < maxSfbPerGroup[chIdx]) {
+ for (sfbGrp = 0; sfbGrp < sfbCnt[chIdx];
+ sfbGrp += sfbPerGroup[chIdx]) {
+ /* sfb energy below border ? */
+ if (ahFlag[elementId][ch][sfbGrp + sfb] != NO_AH &&
+ qcOutChannel->sfbEnergyLdData[sfbGrp + sfb] <
+ enLD64[enIdx]) {
+ /* allow hole */
+ ahFlag[elementId][ch][sfbGrp + sfb] = NO_AH;
+ qcOutChannel->sfbThresholdLdData[sfbGrp + sfb] =
+ FL2FXCONST_DBL(0.015625f) +
+ qcOutChannel->sfbWeightedEnergyLdData[sfbGrp + sfb];
+ actPe -= peData->peChannelData[ch].sfbPe[sfbGrp + sfb] >>
+ PE_CONSTPART_SHIFT;
+ }
+ if (actPe <= desiredPe) {
+ return; /* stop if enough has been saved */
+ }
+ } /* sfbGrp */
+ } /* sfb */
+ } /* nChannelsInEl */
+ } /* ID_DSE */
+ } /* elementID */
+
+ sfb--;
+ if (sfb < minSfb) {
+ /* restart with next energy border */
+ sfb = maxSfb;
+ enIdx++;
+ if (enIdx >= NUM_NRG_LEVS) {
+ done = 1;
+ }
+ }
+ } /* done */
+ } /* (actPe <= desiredPe) */
+}
+
+/* reset avoid hole flags from AH_ACTIVE to AH_INACTIVE */
+static void FDKaacEnc_resetAHFlags(
+ UCHAR ahFlag[(2)][MAX_GROUPED_SFB], const INT nChannels,
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)]) {
+ int ch, sfb, sfbGrp;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) {
+ if (ahFlag[ch][sfbGrp + sfb] == AH_ACTIVE) {
+ ahFlag[ch][sfbGrp + sfb] = AH_INACTIVE;
+ }
+ }
+ }
+ }
+}
+
+static FIXP_DBL CalcRedValPower(FIXP_DBL num, FIXP_DBL denum, INT *scaling) {
+ FIXP_DBL value = FL2FXCONST_DBL(0.f);
+
+ if (num >= FL2FXCONST_DBL(0.f)) {
+ value = fDivNorm(num, denum, scaling);
+ } else {
+ value = -fDivNorm(-num, denum, scaling);
+ }
+ value = f2Pow(value, *scaling, scaling);
+
+ return value;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_adaptThresholdsToPe
+description: two guesses for the reduction value and one final correction of
+the thresholds
+*****************************************************************************/
+static void FDKaacEnc_adaptThresholdsToPe(
+ const CHANNEL_MAPPING *const cm,
+ ATS_ELEMENT *const AdjThrStateElement[((8))],
+ QC_OUT_ELEMENT *const qcElement[((8))],
+ const PSY_OUT_ELEMENT *const psyOutElement[((8))], const INT desiredPe,
+ const INT maxIter2ndGuess, const INT processElements,
+ const INT elementOffset) {
+ FIXP_DBL reductionValue_m;
+ SCHAR reductionValue_e;
+ UCHAR(*pAhFlag)[(2)][MAX_GROUPED_SFB];
+ FIXP_DBL(*pThrExp)[(2)][MAX_GROUPED_SFB];
+ int iter;
+
+ INT constPartGlobal, noRedPeGlobal, nActiveLinesGlobal, redPeGlobal;
+ constPartGlobal = noRedPeGlobal = nActiveLinesGlobal = redPeGlobal = 0;
+
+ int elementId;
+
+ int nElements = elementOffset + processElements;
+ if (nElements > cm->nElements) {
+ nElements = cm->nElements;
+ }
+
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * qcElement[0]->dynMem_Ah_Flag is sufficiently aligned, so the cast is safe
+ */
+ pAhFlag = reinterpret_cast<UCHAR(*)[(2)][MAX_GROUPED_SFB]>(
+ reinterpret_cast<void *>(qcElement[0]->dynMem_Ah_Flag));
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * qcElement[0]->dynMem_Thr_Exp is sufficiently aligned, so the cast is safe
+ */
+ pThrExp = reinterpret_cast<FIXP_DBL(*)[(2)][MAX_GROUPED_SFB]>(
+ reinterpret_cast<void *>(qcElement[0]->dynMem_Thr_Exp));
+
+ /* ------------------------------------------------------- */
+ /* Part I: Initialize data structures and variables... */
+ /* ------------------------------------------------------- */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ /* thresholds to the power of redExp */
+ FDKaacEnc_calcThreshExp(
+ pThrExp[elementId], qcElement[elementId]->qcOutChannel,
+ psyOutElement[elementId]->psyOutChannel, nChannels);
+
+ /* lower the minSnr requirements for low energies compared to the average
+ energy in this frame */
+ FDKaacEnc_adaptMinSnr(qcElement[elementId]->qcOutChannel,
+ psyOutElement[elementId]->psyOutChannel,
+ &AdjThrStateElement[elementId]->minSnrAdaptParam,
+ nChannels);
+
+ /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */
+ FDKaacEnc_initAvoidHoleFlag(
+ qcElement[elementId]->qcOutChannel,
+ psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId],
+ &psyOutElement[elementId]->toolsInfo, nChannels,
+ &AdjThrStateElement[elementId]->ahParam);
+
+ /* sum up */
+ constPartGlobal += peData->constPart;
+ noRedPeGlobal += peData->pe;
+ nActiveLinesGlobal += fixMax((INT)peData->nActiveLines, 1);
+
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+
+ /*
+ First guess of reduction value:
+ avgThrExp = (float)pow(2.0f, (constPartGlobal - noRedPeGlobal)/(4.0f *
+ nActiveLinesGlobal)); redVal = (float)pow(2.0f, (constPartGlobal -
+ desiredPe)/(4.0f * nActiveLinesGlobal)) - avgThrExp; redVal = max(0.f,
+ redVal);
+ */
+ int redVal_e, avgThrExp_e, result_e;
+ FIXP_DBL redVal_m, avgThrExp_m;
+
+ redVal_m = CalcRedValPower(constPartGlobal - desiredPe,
+ 4 * nActiveLinesGlobal, &redVal_e);
+ avgThrExp_m = CalcRedValPower(constPartGlobal - noRedPeGlobal,
+ 4 * nActiveLinesGlobal, &avgThrExp_e);
+ result_e = fMax(redVal_e, avgThrExp_e) + 1;
+
+ reductionValue_m = fMax(FL2FXCONST_DBL(0.f),
+ scaleValue(redVal_m, redVal_e - result_e) -
+ scaleValue(avgThrExp_m, avgThrExp_e - result_e));
+ reductionValue_e = result_e;
+
+ /* ----------------------------------------------------------------------- */
+ /* Part II: Calculate bit consumption of initial bit constraints setup */
+ /* ----------------------------------------------------------------------- */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ /* reduce thresholds */
+ FDKaacEnc_reduceThresholdsCBR(
+ qcElement[elementId]->qcOutChannel,
+ psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId],
+ pThrExp[elementId], nChannels, reductionValue_m, reductionValue_e);
+
+ /* pe after first guess */
+ FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel,
+ qcElement[elementId]->qcOutChannel, peData, nChannels);
+
+ redPeGlobal += peData->pe;
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+
+ /* -------------------------------------------------- */
+ /* Part III: Iterate until bit constraints are met */
+ /* -------------------------------------------------- */
+ iter = 0;
+ while ((fixp_abs(redPeGlobal - desiredPe) >
+ fMultI(FL2FXCONST_DBL(0.05f), desiredPe)) &&
+ (iter < maxIter2ndGuess)) {
+ INT desiredPeNoAHGlobal;
+ INT redPeNoAHGlobal = 0;
+ INT constPartNoAHGlobal = 0;
+ INT nActiveLinesNoAHGlobal = 0;
+
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT redPeNoAH, constPartNoAH, nActiveLinesNoAH;
+ INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ /* pe for bands where avoid hole is inactive */
+ FDKaacEnc_FDKaacEnc_calcPeNoAH(
+ &redPeNoAH, &constPartNoAH, &nActiveLinesNoAH, peData,
+ pAhFlag[elementId], psyOutElement[elementId]->psyOutChannel,
+ nChannels);
+
+ redPeNoAHGlobal += redPeNoAH;
+ constPartNoAHGlobal += constPartNoAH;
+ nActiveLinesNoAHGlobal += nActiveLinesNoAH;
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+
+ /* Calculate new redVal ... */
+ if (desiredPe < redPeGlobal) {
+ /* new desired pe without bands where avoid hole is active */
+ desiredPeNoAHGlobal = desiredPe - (redPeGlobal - redPeNoAHGlobal);
+
+ /* limit desiredPeNoAH to positive values, as the PE can not become
+ * negative */
+ desiredPeNoAHGlobal = fMax(0, desiredPeNoAHGlobal);
+
+ /* second guess (only if there are bands left where avoid hole is
+ * inactive)*/
+ if (nActiveLinesNoAHGlobal > 0) {
+ /*
+ avgThrExp = (float)pow(2.0f, (constPartNoAHGlobal - redPeNoAHGlobal) /
+ (4.0f * nActiveLinesNoAHGlobal)); redVal += (float)pow(2.0f,
+ (constPartNoAHGlobal - desiredPeNoAHGlobal) / (4.0f *
+ nActiveLinesNoAHGlobal)) - avgThrExp; redVal = max(0.0f, redVal);
+ */
+
+ redVal_m = CalcRedValPower(constPartNoAHGlobal - desiredPeNoAHGlobal,
+ 4 * nActiveLinesNoAHGlobal, &redVal_e);
+ avgThrExp_m = CalcRedValPower(constPartNoAHGlobal - redPeNoAHGlobal,
+ 4 * nActiveLinesNoAHGlobal, &avgThrExp_e);
+ result_e = fMax(reductionValue_e, fMax(redVal_e, avgThrExp_e) + 1) + 1;
+
+ reductionValue_m =
+ fMax(FL2FXCONST_DBL(0.f),
+ scaleValue(reductionValue_m, reductionValue_e - result_e) +
+ scaleValue(redVal_m, redVal_e - result_e) -
+ scaleValue(avgThrExp_m, avgThrExp_e - result_e));
+ reductionValue_e = result_e;
+
+ } /* nActiveLinesNoAHGlobal > 0 */
+ } else {
+ /* redVal *= redPeGlobal/desiredPe; */
+ int sc0, sc1;
+ reductionValue_m = fMultNorm(
+ reductionValue_m,
+ fDivNorm((FIXP_DBL)redPeGlobal, (FIXP_DBL)desiredPe, &sc0), &sc1);
+ reductionValue_e += sc0 + sc1;
+
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ FDKaacEnc_resetAHFlags(pAhFlag[elementId],
+ cm->elInfo[elementId].nChannelsInEl,
+ psyOutElement[elementId]->psyOutChannel);
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+ }
+
+ redPeGlobal = 0;
+ /* Calculate new redVal's PE... */
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ /* reduce thresholds */
+ FDKaacEnc_reduceThresholdsCBR(
+ qcElement[elementId]->qcOutChannel,
+ psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId],
+ pThrExp[elementId], nChannels, reductionValue_m, reductionValue_e);
+
+ /* pe after second guess */
+ FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel,
+ qcElement[elementId]->qcOutChannel, peData, nChannels);
+ redPeGlobal += peData->pe;
+
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+
+ iter++;
+ } /* EOF while */
+
+ /* ------------------------------------------------------- */
+ /* Part IV: if still required, further reduce constraints */
+ /* ------------------------------------------------------- */
+ /* 1.0* 1.15* 1.20*
+ * desiredPe desiredPe desiredPe
+ * | | |
+ * ...XXXXXXXXXXXXXXXXXXXXXXXXXXX| |
+ * | | |XXXXXXXXXXX...
+ * | |XXXXXXXXXXX|
+ * --- A --- | --- B --- | --- C ---
+ *
+ * (X): redPeGlobal
+ * (A): FDKaacEnc_correctThresh()
+ * (B): FDKaacEnc_allowMoreHoles()
+ * (C): FDKaacEnc_reduceMinSnr()
+ */
+
+ /* correct thresholds to get closer to the desired pe */
+ if (redPeGlobal > desiredPe) {
+ FDKaacEnc_correctThresh(cm, qcElement, psyOutElement, pAhFlag, pThrExp,
+ reductionValue_m, reductionValue_e,
+ desiredPe - redPeGlobal, processElements,
+ elementOffset);
+
+ /* update PE */
+ redPeGlobal = 0;
+ for (elementId = elementOffset; elementId < nElements; elementId++) {
+ if (cm->elInfo[elementId].elType != ID_DSE) {
+ INT nChannels = cm->elInfo[elementId].nChannelsInEl;
+ PE_DATA *peData = &qcElement[elementId]->peData;
+
+ /* pe after correctThresh */
+ FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel,
+ qcElement[elementId]->qcOutChannel, peData, nChannels);
+ redPeGlobal += peData->pe;
+
+ } /* EOF DSE-suppression */
+ } /* EOF for all elements... */
+ }
+
+ if (redPeGlobal > desiredPe) {
+ /* reduce pe by reducing minSnr requirements */
+ FDKaacEnc_reduceMinSnr(
+ cm, qcElement, psyOutElement, pAhFlag,
+ (fMultI(FL2FXCONST_DBL(0.15f), desiredPe) + desiredPe), &redPeGlobal,
+ processElements, elementOffset);
+
+ /* reduce pe by allowing additional spectral holes */
+ FDKaacEnc_allowMoreHoles(cm, qcElement, psyOutElement, AdjThrStateElement,
+ pAhFlag, desiredPe, redPeGlobal, processElements,
+ elementOffset);
+ }
+}
+
+/* similar to FDKaacEnc_adaptThresholdsToPe(), for VBR-mode */
+static void FDKaacEnc_AdaptThresholdsVBR(
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ ATS_ELEMENT *const AdjThrStateElement,
+ const struct TOOLSINFO *const toolsInfo, const INT nChannels) {
+ UCHAR(*pAhFlag)[MAX_GROUPED_SFB];
+ FIXP_DBL(*pThrExp)[MAX_GROUPED_SFB];
+
+ /* allocate scratch memory */
+ C_ALLOC_SCRATCH_START(_pAhFlag, UCHAR, (2) * MAX_GROUPED_SFB)
+ C_ALLOC_SCRATCH_START(_pThrExp, FIXP_DBL, (2) * MAX_GROUPED_SFB)
+ pAhFlag = (UCHAR(*)[MAX_GROUPED_SFB])_pAhFlag;
+ pThrExp = (FIXP_DBL(*)[MAX_GROUPED_SFB])_pThrExp;
+
+ /* thresholds to the power of redExp */
+ FDKaacEnc_calcThreshExp(pThrExp, qcOutChannel, psyOutChannel, nChannels);
+
+ /* lower the minSnr requirements for low energies compared to the average
+ energy in this frame */
+ FDKaacEnc_adaptMinSnr(qcOutChannel, psyOutChannel,
+ &AdjThrStateElement->minSnrAdaptParam, nChannels);
+
+ /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */
+ FDKaacEnc_initAvoidHoleFlag(qcOutChannel, psyOutChannel, pAhFlag, toolsInfo,
+ nChannels, &AdjThrStateElement->ahParam);
+
+ /* reduce thresholds */
+ FDKaacEnc_reduceThresholdsVBR(qcOutChannel, psyOutChannel, pAhFlag, pThrExp,
+ nChannels, AdjThrStateElement->vbrQualFactor,
+ &AdjThrStateElement->chaosMeasureOld);
+
+ /* free scratch memory */
+ C_ALLOC_SCRATCH_END(_pThrExp, FIXP_DBL, (2) * MAX_GROUPED_SFB)
+ C_ALLOC_SCRATCH_END(_pAhFlag, UCHAR, (2) * MAX_GROUPED_SFB)
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_calcBitSave
+ description: Calculates percentage of bit save, see figure below
+ returns:
+ input: parameters and bitres-fullness
+ output: percentage of bit save
+
+*****************************************************************************/
+/*
+ bitsave
+ maxBitSave(%)| clipLow
+ |---\
+ | \
+ | \
+ | \
+ | \
+ |--------\--------------> bitres
+ | \
+ minBitSave(%)| \------------
+ clipHigh maxBitres
+*/
+static FIXP_DBL FDKaacEnc_calcBitSave(FIXP_DBL fillLevel,
+ const FIXP_DBL clipLow,
+ const FIXP_DBL clipHigh,
+ const FIXP_DBL minBitSave,
+ const FIXP_DBL maxBitSave,
+ const FIXP_DBL bitsave_slope) {
+ FIXP_DBL bitsave;
+
+ fillLevel = fixMax(fillLevel, clipLow);
+ fillLevel = fixMin(fillLevel, clipHigh);
+
+ bitsave = maxBitSave - fMult((fillLevel - clipLow), bitsave_slope);
+
+ return (bitsave);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_calcBitSpend
+ description: Calculates percentage of bit spend, see figure below
+ returns:
+ input: parameters and bitres-fullness
+ output: percentage of bit spend
+
+*****************************************************************************/
+/*
+ bitspend clipHigh
+ maxBitSpend(%)| /-----------maxBitres
+ | /
+ | /
+ | /
+ | /
+ | /
+ |----/-----------------> bitres
+ | /
+ minBitSpend(%)|--/
+ clipLow
+*/
+static FIXP_DBL FDKaacEnc_calcBitSpend(FIXP_DBL fillLevel,
+ const FIXP_DBL clipLow,
+ const FIXP_DBL clipHigh,
+ const FIXP_DBL minBitSpend,
+ const FIXP_DBL maxBitSpend,
+ const FIXP_DBL bitspend_slope) {
+ FIXP_DBL bitspend;
+
+ fillLevel = fixMax(fillLevel, clipLow);
+ fillLevel = fixMin(fillLevel, clipHigh);
+
+ bitspend = minBitSpend + fMult(fillLevel - clipLow, bitspend_slope);
+
+ return (bitspend);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_adjustPeMinMax()
+ description: adjusts peMin and peMax parameters over time
+ returns:
+ input: current pe, peMin, peMax, bitres size
+ output: adjusted peMin/peMax
+
+*****************************************************************************/
+static void FDKaacEnc_adjustPeMinMax(const INT currPe, INT *peMin, INT *peMax) {
+ FIXP_DBL minFacHi = FL2FXCONST_DBL(0.3f), maxFacHi = (FIXP_DBL)MAXVAL_DBL,
+ minFacLo = FL2FXCONST_DBL(0.14f), maxFacLo = FL2FXCONST_DBL(0.07f);
+ INT diff;
+
+ INT minDiff_fix = fMultI(FL2FXCONST_DBL(0.1666666667f), currPe);
+
+ if (currPe > *peMax) {
+ diff = (currPe - *peMax);
+ *peMin += fMultI(minFacHi, diff);
+ *peMax += fMultI(maxFacHi, diff);
+ } else if (currPe < *peMin) {
+ diff = (*peMin - currPe);
+ *peMin -= fMultI(minFacLo, diff);
+ *peMax -= fMultI(maxFacLo, diff);
+ } else {
+ *peMin += fMultI(minFacHi, (currPe - *peMin));
+ *peMax -= fMultI(maxFacLo, (*peMax - currPe));
+ }
+
+ if ((*peMax - *peMin) < minDiff_fix) {
+ INT peMax_fix = *peMax, peMin_fix = *peMin;
+ FIXP_DBL partLo_fix, partHi_fix;
+
+ partLo_fix = (FIXP_DBL)fixMax(0, currPe - peMin_fix);
+ partHi_fix = (FIXP_DBL)fixMax(0, peMax_fix - currPe);
+
+ peMax_fix =
+ (INT)(currPe + fMultI(fDivNorm(partHi_fix, (partLo_fix + partHi_fix)),
+ minDiff_fix));
+ peMin_fix =
+ (INT)(currPe - fMultI(fDivNorm(partLo_fix, (partLo_fix + partHi_fix)),
+ minDiff_fix));
+ peMin_fix = fixMax(0, peMin_fix);
+
+ *peMax = peMax_fix;
+ *peMin = peMin_fix;
+ }
+}
+
+/*****************************************************************************
+
+ functionname: BitresCalcBitFac
+ description: calculates factor of spending bits for one frame
+ 1.0 : take all frame dynpart bits
+ >1.0 : take all frame dynpart bits + bitres
+ <1.0 : put bits in bitreservoir
+ returns: BitFac
+ input: bitres-fullness, pe, blockType, parameter-settings
+ output:
+
+*****************************************************************************/
+/*
+ bitfac(%) pemax
+ bitspend(%) | /-----------maxBitres
+ | /
+ | /
+ | /
+ | /
+ | /
+ |----/-----------------> pe
+ | /
+ bitsave(%) |--/
+ pemin
+*/
+
+void FDKaacEnc_bitresCalcBitFac(const INT bitresBits, const INT maxBitresBits,
+ const INT pe, const INT lastWindowSequence,
+ const INT avgBits, const FIXP_DBL maxBitFac,
+ const ADJ_THR_STATE *const AdjThr,
+ ATS_ELEMENT *const adjThrChan,
+ FIXP_DBL *const pBitresFac,
+ INT *const pBitresFac_e) {
+ const BRES_PARAM *bresParam;
+ INT pex;
+ FIXP_DBL fillLevel;
+ INT fillLevel_e = 0;
+
+ FIXP_DBL bitresFac;
+ INT bitresFac_e;
+
+ FIXP_DBL bitSave, bitSpend;
+ FIXP_DBL bitsave_slope, bitspend_slope;
+ FIXP_DBL fillLevel_fix = MAXVAL_DBL;
+
+ FIXP_DBL slope = MAXVAL_DBL;
+
+ if (lastWindowSequence != SHORT_WINDOW) {
+ bresParam = &(AdjThr->bresParamLong);
+ bitsave_slope = FL2FXCONST_DBL(0.466666666);
+ bitspend_slope = FL2FXCONST_DBL(0.666666666);
+ } else {
+ bresParam = &(AdjThr->bresParamShort);
+ bitsave_slope = (FIXP_DBL)0x2E8BA2E9;
+ bitspend_slope = (FIXP_DBL)0x7fffffff;
+ }
+
+ // fillLevel = (float)(bitresBits+avgBits) / (float)(maxBitresBits + avgBits);
+ if (bitresBits < maxBitresBits) {
+ fillLevel_fix = fDivNorm(bitresBits, maxBitresBits);
+ }
+
+ pex = fMax(pe, adjThrChan->peMin);
+ pex = fMin(pex, adjThrChan->peMax);
+
+ bitSave = FDKaacEnc_calcBitSave(
+ fillLevel_fix, bresParam->clipSaveLow, bresParam->clipSaveHigh,
+ bresParam->minBitSave, bresParam->maxBitSave, bitsave_slope);
+
+ bitSpend = FDKaacEnc_calcBitSpend(
+ fillLevel_fix, bresParam->clipSpendLow, bresParam->clipSpendHigh,
+ bresParam->minBitSpend, bresParam->maxBitSpend, bitspend_slope);
+
+ slope = schur_div((pex - adjThrChan->peMin),
+ (adjThrChan->peMax - adjThrChan->peMin), 31);
+
+ /* scale down by 1 bit because the result of the following addition can be
+ * bigger than 1 (though smaller than 2) */
+ bitresFac = ((FIXP_DBL)(MAXVAL_DBL >> 1) - (bitSave >> 1));
+ bitresFac_e = 1; /* exp=1 */
+ bitresFac = fMultAddDiv2(bitresFac, slope, bitSpend + bitSave); /* exp=1 */
+
+ /*** limit bitresFac for small bitreservoir ***/
+ fillLevel = fDivNorm(bitresBits, avgBits, &fillLevel_e);
+ if (fillLevel_e < 0) {
+ fillLevel = scaleValue(fillLevel, fillLevel_e);
+ fillLevel_e = 0;
+ }
+ /* shift down value by 1 because of summation, ... */
+ fillLevel >>= 1;
+ fillLevel_e += 1;
+ /* ..., this summation: */
+ fillLevel += scaleValue(FL2FXCONST_DBL(0.7f), -fillLevel_e);
+ /* set bitresfactor to same exponent as fillLevel */
+ if (scaleValue(bitresFac, -fillLevel_e + 1) > fillLevel) {
+ bitresFac = fillLevel;
+ bitresFac_e = fillLevel_e;
+ }
+
+ /* limit bitresFac for high bitrates */
+ if (scaleValue(bitresFac, bitresFac_e - (DFRACT_BITS - 1 - 24)) > maxBitFac) {
+ bitresFac = maxBitFac;
+ bitresFac_e = (DFRACT_BITS - 1 - 24);
+ }
+
+ FDKaacEnc_adjustPeMinMax(pe, &adjThrChan->peMin, &adjThrChan->peMax);
+
+ /* output values */
+ *pBitresFac = bitresFac;
+ *pBitresFac_e = bitresFac_e;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjThrNew
+description: allocate ADJ_THR_STATE
+*****************************************************************************/
+INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE **phAdjThr, INT nElements) {
+ INT err = 0;
+ INT i;
+ ADJ_THR_STATE *hAdjThr = GetRam_aacEnc_AdjustThreshold();
+ if (hAdjThr == NULL) {
+ err = 1;
+ goto bail;
+ }
+
+ for (i = 0; i < nElements; i++) {
+ hAdjThr->adjThrStateElem[i] = GetRam_aacEnc_AdjThrStateElement(i);
+ if (hAdjThr->adjThrStateElem[i] == NULL) {
+ err = 1;
+ goto bail;
+ }
+ }
+
+bail:
+ *phAdjThr = hAdjThr;
+ return err;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjThrInit
+description: initialize ADJ_THR_STATE
+*****************************************************************************/
+void FDKaacEnc_AdjThrInit(
+ ADJ_THR_STATE *const hAdjThr, const INT meanPe, const INT invQuant,
+ const CHANNEL_MAPPING *const channelMapping, const INT sampleRate,
+ const INT totalBitrate, const INT isLowDelay,
+ const AACENC_BITRES_MODE bitResMode, const INT dZoneQuantEnable,
+ const INT bitDistributionMode, const FIXP_DBL vbrQualFactor) {
+ INT i;
+
+ FIXP_DBL POINT8 = FL2FXCONST_DBL(0.8f);
+ FIXP_DBL POINT6 = FL2FXCONST_DBL(0.6f);
+
+ if (bitDistributionMode == 1) {
+ hAdjThr->bitDistributionMode = AACENC_BD_MODE_INTRA_ELEMENT;
+ } else {
+ hAdjThr->bitDistributionMode = AACENC_BD_MODE_INTER_ELEMENT;
+ }
+
+ /* 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 =
+ (isLowDelay != 0 || channelMapping->nElements > 1) ? 3 : 1;
+
+ /* common for all elements: */
+ /* parameters for bitres control */
+ hAdjThr->bresParamLong.clipSaveLow =
+ (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */
+ hAdjThr->bresParamLong.clipSaveHigh =
+ (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */
+ hAdjThr->bresParamLong.minBitSave =
+ (FIXP_DBL)0xf999999a; /* FL2FXCONST_DBL(-0.05f); */
+ hAdjThr->bresParamLong.maxBitSave =
+ (FIXP_DBL)0x26666666; /* FL2FXCONST_DBL(0.3f); */
+ hAdjThr->bresParamLong.clipSpendLow =
+ (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */
+ hAdjThr->bresParamLong.clipSpendHigh =
+ (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */
+ hAdjThr->bresParamLong.minBitSpend =
+ (FIXP_DBL)0xf3333333; /* FL2FXCONST_DBL(-0.10f); */
+ hAdjThr->bresParamLong.maxBitSpend =
+ (FIXP_DBL)0x33333333; /* FL2FXCONST_DBL(0.4f); */
+
+ hAdjThr->bresParamShort.clipSaveLow =
+ (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */
+ hAdjThr->bresParamShort.clipSaveHigh =
+ (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */
+ hAdjThr->bresParamShort.minBitSave =
+ (FIXP_DBL)0x00000000; /* FL2FXCONST_DBL(0.0f); */
+ hAdjThr->bresParamShort.maxBitSave =
+ (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */
+ hAdjThr->bresParamShort.clipSpendLow =
+ (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */
+ hAdjThr->bresParamShort.clipSpendHigh =
+ (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */
+ hAdjThr->bresParamShort.minBitSpend =
+ (FIXP_DBL)0xf9999998; /* FL2FXCONST_DBL(-0.05f); */
+ hAdjThr->bresParamShort.maxBitSpend =
+ (FIXP_DBL)0x40000000; /* FL2FXCONST_DBL(0.5f); */
+
+ /* specific for each element: */
+ for (i = 0; i < channelMapping->nElements; i++) {
+ const FIXP_DBL relativeBits = channelMapping->elInfo[i].relativeBits;
+ const INT nChannelsInElement = channelMapping->elInfo[i].nChannelsInEl;
+ const INT bitrateInElement =
+ (relativeBits != (FIXP_DBL)MAXVAL_DBL)
+ ? (INT)fMultNorm(relativeBits, (FIXP_DBL)totalBitrate)
+ : totalBitrate;
+ const INT chBitrate = bitrateInElement >> (nChannelsInElement == 1 ? 0 : 1);
+
+ ATS_ELEMENT *atsElem = hAdjThr->adjThrStateElem[i];
+ MINSNR_ADAPT_PARAM *msaParam = &atsElem->minSnrAdaptParam;
+
+ /* parameters for bitres control */
+ if (isLowDelay) {
+ atsElem->peMin = fMultI(POINT8, meanPe);
+ atsElem->peMax = fMultI(POINT6, meanPe) << 1;
+ } else {
+ atsElem->peMin = fMultI(POINT8, meanPe) >> 1;
+ atsElem->peMax = fMultI(POINT6, meanPe);
+ }
+
+ /* for use in FDKaacEnc_reduceThresholdsVBR */
+ atsElem->chaosMeasureOld = FL2FXCONST_DBL(0.3f);
+
+ /* additional pe offset to correct pe2bits for low bitrates */
+ /* ---- no longer necessary, set by table ----- */
+ atsElem->peOffset = 0;
+
+ /* vbr initialisation */
+ atsElem->vbrQualFactor = vbrQualFactor;
+ if (chBitrate < 32000) {
+ atsElem->peOffset =
+ fixMax(50, 100 - fMultI((FIXP_DBL)0x666667, chBitrate));
+ }
+
+ /* avoid hole parameters */
+ if (chBitrate >= 20000) {
+ atsElem->ahParam.modifyMinSnr = TRUE;
+ atsElem->ahParam.startSfbL = 15;
+ atsElem->ahParam.startSfbS = 3;
+ } else {
+ atsElem->ahParam.modifyMinSnr = FALSE;
+ atsElem->ahParam.startSfbL = 0;
+ atsElem->ahParam.startSfbS = 0;
+ }
+
+ /* minSnr adaptation */
+ msaParam->maxRed = FL2FXCONST_DBL(0.00390625f); /* 0.25f/64.0f */
+ /* start adaptation of minSnr for avgEn/sfbEn > startRatio */
+ msaParam->startRatio = FL2FXCONST_DBL(0.05190512648f); /* ld64(10.0f) */
+ /* maximum minSnr reduction to minSnr^maxRed is reached for
+ avgEn/sfbEn >= maxRatio */
+ /* msaParam->maxRatio = 1000.0f; */
+ /*msaParam->redRatioFac = ((float)1.0f - msaParam->maxRed) /
+ * ((float)10.0f*log10(msaParam->startRatio/msaParam->maxRatio)/log10(2.0f)*(float)0.3010299956f);*/
+ msaParam->redRatioFac = FL2FXCONST_DBL(-0.375f); /* -0.0375f * 10.0f */
+ /*msaParam->redOffs = (float)1.0f - msaParam->redRatioFac * (float)10.0f *
+ * log10(msaParam->startRatio)/log10(2.0f) * (float)0.3010299956f;*/
+ msaParam->redOffs = FL2FXCONST_DBL(0.021484375); /* 1.375f/64.0f */
+
+ /* init pe correction */
+ atsElem->peCorrectionFactor_m = FL2FXCONST_DBL(0.5f); /* 1.0 */
+ atsElem->peCorrectionFactor_e = 1;
+
+ atsElem->dynBitsLast = -1;
+ atsElem->peLast = 0;
+
+ /* init bits to pe factor */
+
+ /* init bits2PeFactor */
+ FDKaacEnc_InitBits2PeFactor(
+ &atsElem->bits2PeFactor_m, &atsElem->bits2PeFactor_e, bitrateInElement,
+ nChannelsInElement, sampleRate, isLowDelay, dZoneQuantEnable, invQuant);
+
+ } /* for nElements */
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_FDKaacEnc_calcPeCorrection
+ description: calc desired pe
+*****************************************************************************/
+static void FDKaacEnc_FDKaacEnc_calcPeCorrection(
+ FIXP_DBL *const correctionFac_m, INT *const correctionFac_e,
+ const INT peAct, const INT peLast, const INT bitsLast,
+ const FIXP_DBL bits2PeFactor_m, const INT bits2PeFactor_e) {
+ if ((bitsLast > 0) && (peAct < 1.5f * peLast) && (peAct > 0.7f * peLast) &&
+ (FDKaacEnc_bits2pe2(bitsLast,
+ fMult(FL2FXCONST_DBL(1.2f / 2.f), bits2PeFactor_m),
+ bits2PeFactor_e + 1) > peLast) &&
+ (FDKaacEnc_bits2pe2(bitsLast,
+ fMult(FL2FXCONST_DBL(0.65f), bits2PeFactor_m),
+ bits2PeFactor_e) < peLast)) {
+ FIXP_DBL corrFac = *correctionFac_m;
+
+ int scaling = 0;
+ FIXP_DBL denum = (FIXP_DBL)FDKaacEnc_bits2pe2(bitsLast, bits2PeFactor_m,
+ bits2PeFactor_e);
+ FIXP_DBL newFac = fDivNorm((FIXP_DBL)peLast, denum, &scaling);
+
+ /* dead zone, newFac and corrFac are scaled by 0.5 */
+ if ((FIXP_DBL)peLast <= denum) { /* ratio <= 1.f */
+ newFac = fixMax(
+ scaleValue(fixMin(fMult(FL2FXCONST_DBL(1.1f / 2.f), newFac),
+ scaleValue(FL2FXCONST_DBL(1.f / 2.f), -scaling)),
+ scaling),
+ FL2FXCONST_DBL(0.85f / 2.f));
+ } else { /* ratio < 1.f */
+ newFac = fixMax(
+ fixMin(scaleValue(fMult(FL2FXCONST_DBL(0.9f / 2.f), newFac), scaling),
+ FL2FXCONST_DBL(1.15f / 2.f)),
+ FL2FXCONST_DBL(1.f / 2.f));
+ }
+
+ if (((newFac > FL2FXCONST_DBL(1.f / 2.f)) &&
+ (corrFac < FL2FXCONST_DBL(1.f / 2.f))) ||
+ ((newFac < FL2FXCONST_DBL(1.f / 2.f)) &&
+ (corrFac > FL2FXCONST_DBL(1.f / 2.f)))) {
+ corrFac = FL2FXCONST_DBL(1.f / 2.f);
+ }
+
+ /* faster adaptation towards 1.0, slower in the other direction */
+ if ((corrFac < FL2FXCONST_DBL(1.f / 2.f) && newFac < corrFac) ||
+ (corrFac > FL2FXCONST_DBL(1.f / 2.f) && newFac > corrFac)) {
+ corrFac = fMult(FL2FXCONST_DBL(0.85f), corrFac) +
+ fMult(FL2FXCONST_DBL(0.15f), newFac);
+ } else {
+ corrFac = fMult(FL2FXCONST_DBL(0.7f), corrFac) +
+ fMult(FL2FXCONST_DBL(0.3f), newFac);
+ }
+
+ corrFac = fixMax(fixMin(corrFac, FL2FXCONST_DBL(1.15f / 2.f)),
+ FL2FXCONST_DBL(0.85 / 2.f));
+
+ *correctionFac_m = corrFac;
+ *correctionFac_e = 1;
+ } else {
+ *correctionFac_m = FL2FXCONST_DBL(1.f / 2.f);
+ *correctionFac_e = 1;
+ }
+}
+
+static void FDKaacEnc_calcPeCorrectionLowBitRes(
+ FIXP_DBL *const correctionFac_m, INT *const correctionFac_e,
+ const INT peLast, const INT bitsLast, const INT bitresLevel,
+ const INT nChannels, const FIXP_DBL bits2PeFactor_m,
+ const INT bits2PeFactor_e) {
+ /* tuning params */
+ const FIXP_DBL amp = FL2FXCONST_DBL(0.005);
+ const FIXP_DBL maxDiff = FL2FXCONST_DBL(0.25f);
+
+ if (bitsLast > 0) {
+ /* Estimate deviation of granted and used dynamic bits in previous frame, in
+ * PE units */
+ const int bitsBalLast =
+ peLast - FDKaacEnc_bits2pe2(bitsLast, bits2PeFactor_m, bits2PeFactor_e);
+
+ /* reserve n bits per channel */
+ int headroom = (bitresLevel >= 50 * nChannels) ? 0 : (100 * nChannels);
+
+ /* in PE units */
+ headroom = FDKaacEnc_bits2pe2(headroom, bits2PeFactor_m, bits2PeFactor_e);
+
+ /*
+ * diff = amp * ((bitsBalLast - headroom) / (bitresLevel + headroom)
+ * diff = max ( min ( diff, maxDiff, -maxDiff)) / 2
+ */
+ FIXP_DBL denominator = (FIXP_DBL)FDKaacEnc_bits2pe2(
+ bitresLevel, bits2PeFactor_m, bits2PeFactor_e) +
+ (FIXP_DBL)headroom;
+
+ int scaling = 0;
+ FIXP_DBL diff =
+ (bitsBalLast >= headroom)
+ ? fMult(amp, fDivNorm((FIXP_DBL)(bitsBalLast - headroom),
+ denominator, &scaling))
+ : -fMult(amp, fDivNorm(-(FIXP_DBL)(bitsBalLast - headroom),
+ denominator, &scaling));
+
+ scaling -= 1; /* divide by 2 */
+
+ diff = (scaling <= 0)
+ ? fMax(fMin(diff >> (-scaling), maxDiff >> 1), -maxDiff >> 1)
+ : fMax(fMin(diff, maxDiff >> (1 + scaling)),
+ -maxDiff >> (1 + scaling))
+ << scaling;
+
+ /*
+ * corrFac += diff
+ * corrFac = max ( min ( corrFac/2.f, 1.f/2.f, 0.75f/2.f ) )
+ */
+ *correctionFac_m =
+ fMax(fMin((*correctionFac_m) + diff, FL2FXCONST_DBL(1.0f / 2.f)),
+ FL2FXCONST_DBL(0.75f / 2.f));
+ *correctionFac_e = 1;
+ } else {
+ *correctionFac_m = FL2FXCONST_DBL(0.75 / 2.f);
+ *correctionFac_e = 1;
+ }
+}
+
+void FDKaacEnc_DistributeBits(
+ ADJ_THR_STATE *adjThrState, ATS_ELEMENT *AdjThrStateElement,
+ PSY_OUT_CHANNEL *psyOutChannel[(2)], PE_DATA *peData, INT *grantedPe,
+ INT *grantedPeCorr, const INT nChannels, const INT commonWindow,
+ const INT grantedDynBits, const INT bitresBits, const INT maxBitresBits,
+ const FIXP_DBL maxBitFac, const AACENC_BITRES_MODE bitResMode) {
+ FIXP_DBL bitFactor;
+ INT bitFactor_e;
+ INT noRedPe = peData->pe;
+
+ /* prefer short windows for calculation of bitFactor */
+ INT curWindowSequence = LONG_WINDOW;
+ if (nChannels == 2) {
+ if ((psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) ||
+ (psyOutChannel[1]->lastWindowSequence == SHORT_WINDOW)) {
+ curWindowSequence = SHORT_WINDOW;
+ }
+ } else {
+ curWindowSequence = psyOutChannel[0]->lastWindowSequence;
+ }
+
+ if (grantedDynBits >= 1) {
+ if (bitResMode != AACENC_BR_MODE_FULL) {
+ /* small or disabled bitreservoir */
+ *grantedPe = FDKaacEnc_bits2pe2(grantedDynBits,
+ AdjThrStateElement->bits2PeFactor_m,
+ AdjThrStateElement->bits2PeFactor_e);
+ } else {
+ /* factor dependend on current fill level and pe */
+ FDKaacEnc_bitresCalcBitFac(
+ bitresBits, maxBitresBits, noRedPe, curWindowSequence, grantedDynBits,
+ maxBitFac, adjThrState, AdjThrStateElement, &bitFactor, &bitFactor_e);
+
+ /* desired pe for actual frame */
+ /* Worst case max of grantedDynBits is = 1024 * 5.27 * 2 */
+ *grantedPe = FDKaacEnc_bits2pe2(
+ grantedDynBits, fMult(bitFactor, AdjThrStateElement->bits2PeFactor_m),
+ AdjThrStateElement->bits2PeFactor_e + bitFactor_e);
+ }
+ } else {
+ *grantedPe = 0; /* prevent divsion by 0 */
+ }
+
+ /* correction of pe value */
+ switch (bitResMode) {
+ case AACENC_BR_MODE_DISABLED:
+ case AACENC_BR_MODE_REDUCED:
+ /* correction of pe value for low bitres */
+ FDKaacEnc_calcPeCorrectionLowBitRes(
+ &AdjThrStateElement->peCorrectionFactor_m,
+ &AdjThrStateElement->peCorrectionFactor_e, AdjThrStateElement->peLast,
+ AdjThrStateElement->dynBitsLast, bitresBits, nChannels,
+ AdjThrStateElement->bits2PeFactor_m,
+ AdjThrStateElement->bits2PeFactor_e);
+ break;
+ case AACENC_BR_MODE_FULL:
+ default:
+ /* correction of pe value for high bitres */
+ FDKaacEnc_FDKaacEnc_calcPeCorrection(
+ &AdjThrStateElement->peCorrectionFactor_m,
+ &AdjThrStateElement->peCorrectionFactor_e,
+ fixMin(*grantedPe, noRedPe), AdjThrStateElement->peLast,
+ AdjThrStateElement->dynBitsLast, AdjThrStateElement->bits2PeFactor_m,
+ AdjThrStateElement->bits2PeFactor_e);
+ break;
+ }
+
+ *grantedPeCorr =
+ (INT)(fMult((FIXP_DBL)(*grantedPe << Q_AVGBITS),
+ AdjThrStateElement->peCorrectionFactor_m) >>
+ (Q_AVGBITS - AdjThrStateElement->peCorrectionFactor_e));
+
+ /* update last pe */
+ AdjThrStateElement->peLast = *grantedPe;
+ AdjThrStateElement->dynBitsLast = -1;
+}
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjustThresholds
+description: adjust thresholds
+*****************************************************************************/
+void FDKaacEnc_AdjustThresholds(
+ ADJ_THR_STATE *const hAdjThr, QC_OUT_ELEMENT *const qcElement[((8))],
+ QC_OUT *const qcOut, const PSY_OUT_ELEMENT *const psyOutElement[((8))],
+ const INT CBRbitrateMode, const CHANNEL_MAPPING *const cm) {
+ int i;
+
+ if (CBRbitrateMode) {
+ /* In case, no bits must be shifted between different elements, */
+ /* an element-wise execution of the pe-dependent threshold- */
+ /* adaption becomes necessary... */
+ if (hAdjThr->bitDistributionMode == AACENC_BD_MODE_INTRA_ELEMENT) {
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* qcElement[i]->grantedPe = 2000; */ /* Use this only for debugging
+ */
+ // if (totalGrantedPeCorr < totalNoRedPe) {
+ if (qcElement[i]->grantedPeCorr < qcElement[i]->peData.pe) {
+ /* calc threshold necessary for desired pe */
+ FDKaacEnc_adaptThresholdsToPe(
+ cm, hAdjThr->adjThrStateElem, qcElement, psyOutElement,
+ qcElement[i]->grantedPeCorr, hAdjThr->maxIter2ndGuess,
+ 1, /* Process only 1 element */
+ i /* Process exactly THIS element */
+ );
+ }
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+ } /* -end- element loop */
+ } /* AACENC_BD_MODE_INTRA_ELEMENT */
+ else if (hAdjThr->bitDistributionMode == AACENC_BD_MODE_INTER_ELEMENT) {
+ /* Use global Pe to obtain the thresholds? */
+ if (qcOut->totalGrantedPeCorr < qcOut->totalNoRedPe) {
+ /* add equal loadness quantization noise to match the */
+ /* desired pe calc threshold necessary for desired pe */
+ /* Now carried out globally to cover all(!) channels. */
+ FDKaacEnc_adaptThresholdsToPe(cm, hAdjThr->adjThrStateElem, qcElement,
+ psyOutElement, qcOut->totalGrantedPeCorr,
+ hAdjThr->maxIter2ndGuess,
+ cm->nElements, /* Process all elements */
+ 0); /* Process exactly THIS element */
+ } else {
+ /* In case global pe doesn't need to be reduced check each element to
+ hold estimated bitrate below maximum element bitrate. */
+ for (i = 0; i < cm->nElements; i++) {
+ if ((cm->elInfo[i].elType == ID_SCE) ||
+ (cm->elInfo[i].elType == ID_CPE) ||
+ (cm->elInfo[i].elType == ID_LFE)) {
+ /* Element pe applies to dynamic bits of maximum element bitrate. */
+ const int maxElementPe = FDKaacEnc_bits2pe2(
+ (cm->elInfo[i].nChannelsInEl * MIN_BUFSIZE_PER_EFF_CHAN) -
+ qcElement[i]->staticBitsUsed - qcElement[i]->extBitsUsed,
+ hAdjThr->adjThrStateElem[i]->bits2PeFactor_m,
+ hAdjThr->adjThrStateElem[i]->bits2PeFactor_e);
+
+ if (maxElementPe < qcElement[i]->peData.pe) {
+ FDKaacEnc_adaptThresholdsToPe(
+ cm, hAdjThr->adjThrStateElem, qcElement, psyOutElement,
+ maxElementPe, hAdjThr->maxIter2ndGuess, 1, i);
+ }
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+ } /* -end- element loop */
+ } /* (qcOut->totalGrantedPeCorr < qcOut->totalNoRedPe) */
+ } /* AACENC_BD_MODE_INTER_ELEMENT */
+ } else {
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* for VBR-mode */
+ FDKaacEnc_AdaptThresholdsVBR(
+ qcElement[i]->qcOutChannel, psyOutElement[i]->psyOutChannel,
+ hAdjThr->adjThrStateElem[i], &psyOutElement[i]->toolsInfo,
+ cm->elInfo[i].nChannelsInEl);
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+
+ } /* -end- element loop */
+ }
+ for (i = 0; i < cm->nElements; i++) {
+ int ch, sfb, sfbGrp;
+ /* no weighting of threholds and energies for mlout */
+ /* weight energies and thresholds */
+ for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
+ QC_OUT_CHANNEL *pQcOutCh = qcElement[i]->qcOutChannel[ch];
+ for (sfbGrp = 0; sfbGrp < psyOutElement[i]->psyOutChannel[ch]->sfbCnt;
+ sfbGrp += psyOutElement[i]->psyOutChannel[ch]->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutElement[i]->psyOutChannel[ch]->maxSfbPerGroup;
+ sfb++) {
+ pQcOutCh->sfbThresholdLdData[sfb + sfbGrp] +=
+ pQcOutCh->sfbEnFacLd[sfb + sfbGrp];
+ }
+ }
+ }
+ }
+}
+
+void FDKaacEnc_AdjThrClose(ADJ_THR_STATE **phAdjThr) {
+ INT i;
+ ADJ_THR_STATE *hAdjThr = *phAdjThr;
+
+ if (hAdjThr != NULL) {
+ for (i = 0; i < ((8)); i++) {
+ if (hAdjThr->adjThrStateElem[i] != NULL) {
+ FreeRam_aacEnc_AdjThrStateElement(&hAdjThr->adjThrStateElem[i]);
+ }
+ }
+ FreeRam_aacEnc_AdjustThreshold(phAdjThr);
+ }
+}
diff --git a/fdk-aac/libAACenc/src/adj_thr.h b/fdk-aac/libAACenc/src/adj_thr.h
new file mode 100644
index 0000000..1f5f998
--- /dev/null
+++ b/fdk-aac/libAACenc/src/adj_thr.h
@@ -0,0 +1,166 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Threshold compensation
+
+*******************************************************************************/
+
+#ifndef ADJ_THR_H
+#define ADJ_THR_H
+
+#include "common_fix.h"
+#include "adj_thr_data.h"
+#include "qc_data.h"
+#include "line_pe.h"
+#include "interface.h"
+
+/*****************************************************************************
+ functionname: FDKaacEnc_peCalculation
+ description:
+*****************************************************************************/
+void FDKaacEnc_peCalculation(PE_DATA *const peData,
+ const PSY_OUT_CHANNEL *const psyOutChannel[(2)],
+ QC_OUT_CHANNEL *const qcOutChannel[(2)],
+ const struct TOOLSINFO *const toolsInfo,
+ ATS_ELEMENT *const adjThrStateElement,
+ const INT nChannels);
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjThrNew
+description: allocate ADJ_THR_STATE
+*****************************************************************************/
+INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE **phAdjThr, INT nElements);
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjThrInit
+description: initialize ADJ_THR_STATE
+*****************************************************************************/
+void FDKaacEnc_AdjThrInit(
+ ADJ_THR_STATE *const hAdjThr, const INT meanPe, const INT invQuant,
+ const CHANNEL_MAPPING *const channelMapping, const INT sampleRate,
+ const INT totalBitrate, const INT isLowDelay,
+ const AACENC_BITRES_MODE bitResMode, const INT dZoneQuantEnable,
+ const INT bitDistributionMode, const FIXP_DBL vbrQualFactor);
+
+/*****************************************************************************
+functionname: FDKaacEnc_DistributeBits
+description:
+*****************************************************************************/
+void FDKaacEnc_DistributeBits(
+ ADJ_THR_STATE *adjThrState, ATS_ELEMENT *AdjThrStateElement,
+ PSY_OUT_CHANNEL *psyOutChannel[(2)], PE_DATA *peData, INT *grantedPe,
+ INT *grantedPeCorr, const INT nChannels, const INT commonWindow,
+ const INT avgBits, const INT bitresBits, const INT maxBitresBits,
+ const FIXP_DBL maxBitFac, const AACENC_BITRES_MODE bitResMode);
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjustThresholds
+description: adjust thresholds
+*****************************************************************************/
+void FDKaacEnc_AdjustThresholds(
+ ADJ_THR_STATE *const hAdjThr, QC_OUT_ELEMENT *const qcElement[((8))],
+ QC_OUT *const qcOut, const PSY_OUT_ELEMENT *const psyOutElement[((8))],
+ const INT CBRbitrateMode, const CHANNEL_MAPPING *const cm);
+
+/*****************************************************************************
+functionname: FDKaacEnc_AdjThrClose
+description:
+*****************************************************************************/
+void FDKaacEnc_AdjThrClose(ADJ_THR_STATE **hAdjThr);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/adj_thr_data.h b/fdk-aac/libAACenc/src/adj_thr_data.h
new file mode 100644
index 0000000..4cd1299
--- /dev/null
+++ b/fdk-aac/libAACenc/src/adj_thr_data.h
@@ -0,0 +1,175 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Schug / A. Groeschel
+
+ Description: threshold calculations
+
+*******************************************************************************/
+
+#ifndef ADJ_THR_DATA_H
+#define ADJ_THR_DATA_H
+
+#include "psy_const.h"
+
+typedef enum {
+ AACENC_BD_MODE_INTER_ELEMENT = 0,
+ AACENC_BD_MODE_INTRA_ELEMENT = 1
+} AACENC_BIT_DISTRIBUTION_MODE;
+
+typedef enum {
+ AACENC_BR_MODE_FULL = 0,
+ AACENC_BR_MODE_REDUCED = 1,
+ AACENC_BR_MODE_DISABLED = 2
+} AACENC_BITRES_MODE;
+
+typedef struct {
+ FIXP_DBL clipSaveLow, clipSaveHigh;
+ FIXP_DBL minBitSave, maxBitSave;
+ FIXP_DBL clipSpendLow, clipSpendHigh;
+ FIXP_DBL minBitSpend, maxBitSpend;
+} BRES_PARAM;
+
+typedef struct {
+ INT modifyMinSnr;
+ INT startSfbL, startSfbS;
+} AH_PARAM;
+
+typedef struct {
+ FIXP_DBL maxRed;
+ FIXP_DBL startRatio;
+ FIXP_DBL maxRatio;
+ FIXP_DBL redRatioFac;
+ FIXP_DBL redOffs;
+} MINSNR_ADAPT_PARAM;
+
+typedef struct {
+ /* parameters for bitreservoir control */
+ INT peMin, peMax;
+ /* constant offset to pe */
+ INT peOffset;
+ /* constant PeFactor */
+ FIXP_DBL bits2PeFactor_m;
+ INT bits2PeFactor_e;
+ /* avoid hole parameters */
+ AH_PARAM ahParam;
+ /* parameters for adaptation of minSnr */
+ MINSNR_ADAPT_PARAM minSnrAdaptParam;
+
+ /* values for correction of pe */
+ INT peLast;
+ INT dynBitsLast;
+ FIXP_DBL peCorrectionFactor_m;
+ INT peCorrectionFactor_e;
+
+ /* vbr encoding */
+ FIXP_DBL vbrQualFactor;
+ FIXP_DBL chaosMeasureOld;
+
+ /* threshold weighting */
+ FIXP_DBL chaosMeasureEnFac[(2)];
+ INT lastEnFacPatch[(2)];
+
+} ATS_ELEMENT;
+
+typedef struct {
+ BRES_PARAM bresParamLong, bresParamShort;
+ ATS_ELEMENT* adjThrStateElem[((8))];
+ AACENC_BIT_DISTRIBUTION_MODE bitDistributionMode;
+ INT maxIter2ndGuess;
+} ADJ_THR_STATE;
+
+#endif
diff --git a/fdk-aac/libAACenc/src/band_nrg.cpp b/fdk-aac/libAACenc/src/band_nrg.cpp
new file mode 100644
index 0000000..fb22dbb
--- /dev/null
+++ b/fdk-aac/libAACenc/src/band_nrg.cpp
@@ -0,0 +1,361 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Band/Line energy calculations
+
+*******************************************************************************/
+
+#include "band_nrg.h"
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CalcSfbMaxScaleSpec
+ description:
+ input:
+ output:
+*****************************************************************************/
+void FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *RESTRICT mdctSpectrum,
+ const INT *RESTRICT bandOffset,
+ INT *RESTRICT sfbMaxScaleSpec,
+ const INT numBands) {
+ INT i, j;
+ FIXP_DBL maxSpc, tmp;
+
+ for (i = 0; i < numBands; i++) {
+ maxSpc = (FIXP_DBL)0;
+
+ DWORD_ALIGNED(mdctSpectrum);
+
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ tmp = fixp_abs(mdctSpectrum[j]);
+ maxSpc = fixMax(maxSpc, tmp);
+ }
+ j = CntLeadingZeros(maxSpc) - 1;
+ sfbMaxScaleSpec[i] = fixMin((DFRACT_BITS - 2), j);
+ /* CountLeadingBits() is not necessary here since test value is always > 0
+ */
+ }
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CheckBandEnergyOptim
+ description:
+ input:
+ output:
+*****************************************************************************/
+FIXP_DBL
+FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *const RESTRICT mdctSpectrum,
+ const INT *const RESTRICT sfbMaxScaleSpec,
+ const INT *const RESTRICT bandOffset,
+ const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergy,
+ FIXP_DBL *RESTRICT bandEnergyLdData,
+ const INT minSpecShift) {
+ INT i, j, scale, nr = 0;
+ FIXP_DBL maxNrgLd = FL2FXCONST_DBL(-1.0f);
+ FIXP_DBL maxNrg = 0;
+ FIXP_DBL spec;
+
+ for (i = 0; i < numBands; i++) {
+ scale = fixMax(0, sfbMaxScaleSpec[i] - 4);
+ FIXP_DBL tmp = 0;
+
+ DWORD_ALIGNED(mdctSpectrum);
+
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ spec = mdctSpectrum[j] << scale;
+ tmp = fPow2AddDiv2(tmp, spec);
+ }
+ bandEnergy[i] = tmp << 1;
+
+ /* calculate ld of bandNrg, subtract scaling */
+ bandEnergyLdData[i] = CalcLdData(bandEnergy[i]);
+ if (bandEnergyLdData[i] != FL2FXCONST_DBL(-1.0f)) {
+ bandEnergyLdData[i] -= scale * FL2FXCONST_DBL(2.0 / 64);
+ }
+ /* find index of maxNrg */
+ if (bandEnergyLdData[i] > maxNrgLd) {
+ maxNrgLd = bandEnergyLdData[i];
+ nr = i;
+ }
+ }
+
+ /* return unscaled maxNrg*/
+ scale = fixMax(0, sfbMaxScaleSpec[nr] - 4);
+ scale = fixMax(2 * (minSpecShift - scale), -(DFRACT_BITS - 1));
+
+ maxNrg = scaleValue(bandEnergy[nr], scale);
+
+ return maxNrg;
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CalcBandEnergyOptimLong
+ description:
+ input:
+ output:
+*****************************************************************************/
+INT FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *RESTRICT mdctSpectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ const INT *RESTRICT bandOffset,
+ const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergy,
+ FIXP_DBL *RESTRICT bandEnergyLdData) {
+ INT i, j, shiftBits = 0;
+ FIXP_DBL maxNrgLd = FL2FXCONST_DBL(0.0f);
+
+ FIXP_DBL spec;
+
+ for (i = 0; i < numBands; i++) {
+ INT leadingBits = sfbMaxScaleSpec[i] -
+ 4; /* max sfbWidth = 96 ; 2^7=128 => 7/2 = 4 (spc*spc) */
+ FIXP_DBL tmp = FL2FXCONST_DBL(0.0);
+ /* don't use scaleValue() here, it increases workload quite sufficiently...
+ */
+ if (leadingBits >= 0) {
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ spec = mdctSpectrum[j] << leadingBits;
+ tmp = fPow2AddDiv2(tmp, spec);
+ }
+ } else {
+ INT shift = -leadingBits;
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ spec = mdctSpectrum[j] >> shift;
+ tmp = fPow2AddDiv2(tmp, spec);
+ }
+ }
+ bandEnergy[i] = tmp << 1;
+ }
+
+ /* calculate ld of bandNrg, subtract scaling */
+ LdDataVector(bandEnergy, bandEnergyLdData, numBands);
+ for (i = numBands; i-- != 0;) {
+ FIXP_DBL scaleDiff = (sfbMaxScaleSpec[i] - 4) * FL2FXCONST_DBL(2.0 / 64);
+
+ bandEnergyLdData[i] = (bandEnergyLdData[i] >=
+ ((FL2FXCONST_DBL(-1.f) >> 1) + (scaleDiff >> 1)))
+ ? bandEnergyLdData[i] - scaleDiff
+ : FL2FXCONST_DBL(-1.f);
+ /* find maxNrgLd */
+ maxNrgLd = fixMax(maxNrgLd, bandEnergyLdData[i]);
+ }
+
+ if (maxNrgLd <= (FIXP_DBL)0) {
+ for (i = numBands; i-- != 0;) {
+ INT scale = fixMin((sfbMaxScaleSpec[i] - 4) << 1, (DFRACT_BITS - 1));
+ bandEnergy[i] = scaleValue(bandEnergy[i], -scale);
+ }
+ return 0;
+ } else { /* scale down NRGs */
+ while (maxNrgLd > FL2FXCONST_DBL(0.0f)) {
+ maxNrgLd -= FL2FXCONST_DBL(2.0 / 64);
+ shiftBits++;
+ }
+ for (i = numBands; i-- != 0;) {
+ INT scale = fixMin(((sfbMaxScaleSpec[i] - 4) + shiftBits) << 1,
+ (DFRACT_BITS - 1));
+ bandEnergyLdData[i] -= shiftBits * FL2FXCONST_DBL(2.0 / 64);
+ bandEnergy[i] = scaleValue(bandEnergy[i], -scale);
+ }
+ return shiftBits;
+ }
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CalcBandEnergyOptimShort
+ description:
+ input:
+ output:
+*****************************************************************************/
+void FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *RESTRICT mdctSpectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ const INT *RESTRICT bandOffset,
+ const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergy) {
+ INT i, j;
+
+ for (i = 0; i < numBands; i++) {
+ int leadingBits = sfbMaxScaleSpec[i] -
+ 3; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */
+ FIXP_DBL tmp = FL2FXCONST_DBL(0.0);
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ FIXP_DBL spec = scaleValue(mdctSpectrum[j], leadingBits);
+ tmp = fPow2AddDiv2(tmp, spec);
+ }
+ bandEnergy[i] = tmp;
+ }
+
+ for (i = 0; i < numBands; i++) {
+ INT scale = (2 * (sfbMaxScaleSpec[i] - 3)) -
+ 1; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */
+ scale = fixMax(fixMin(scale, (DFRACT_BITS - 1)), -(DFRACT_BITS - 1));
+ bandEnergy[i] = scaleValueSaturate(bandEnergy[i], -scale);
+ }
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CalcBandNrgMSOpt
+ description:
+ input:
+ output:
+*****************************************************************************/
+void FDKaacEnc_CalcBandNrgMSOpt(
+ const FIXP_DBL *RESTRICT mdctSpectrumLeft,
+ const FIXP_DBL *RESTRICT mdctSpectrumRight,
+ INT *RESTRICT sfbMaxScaleSpecLeft, INT *RESTRICT sfbMaxScaleSpecRight,
+ const INT *RESTRICT bandOffset, const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergyMid, FIXP_DBL *RESTRICT bandEnergySide,
+ INT calcLdData, FIXP_DBL *RESTRICT bandEnergyMidLdData,
+ FIXP_DBL *RESTRICT bandEnergySideLdData) {
+ INT i, j, minScale;
+ FIXP_DBL NrgMid, NrgSide, specm, specs;
+
+ for (i = 0; i < numBands; i++) {
+ NrgMid = NrgSide = FL2FXCONST_DBL(0.0);
+ minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i]) - 4;
+ minScale = fixMax(0, minScale);
+
+ if (minScale > 0) {
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ FIXP_DBL specL = mdctSpectrumLeft[j] << (minScale - 1);
+ FIXP_DBL specR = mdctSpectrumRight[j] << (minScale - 1);
+ specm = specL + specR;
+ specs = specL - specR;
+ NrgMid = fPow2AddDiv2(NrgMid, specm);
+ NrgSide = fPow2AddDiv2(NrgSide, specs);
+ }
+ } else {
+ for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
+ FIXP_DBL specL = mdctSpectrumLeft[j] >> 1;
+ FIXP_DBL specR = mdctSpectrumRight[j] >> 1;
+ specm = specL + specR;
+ specs = specL - specR;
+ NrgMid = fPow2AddDiv2(NrgMid, specm);
+ NrgSide = fPow2AddDiv2(NrgSide, specs);
+ }
+ }
+ bandEnergyMid[i] = fMin(NrgMid, (FIXP_DBL)MAXVAL_DBL >> 1) << 1;
+ bandEnergySide[i] = fMin(NrgSide, (FIXP_DBL)MAXVAL_DBL >> 1) << 1;
+ }
+
+ if (calcLdData) {
+ LdDataVector(bandEnergyMid, bandEnergyMidLdData, numBands);
+ LdDataVector(bandEnergySide, bandEnergySideLdData, numBands);
+ }
+
+ for (i = 0; i < numBands; i++) {
+ minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i]);
+ INT scale = fixMax(0, 2 * (minScale - 4));
+
+ if (calcLdData) {
+ /* using the minimal scaling of left and right channel can cause very
+ small energies; check ldNrg before subtract scaling multiplication:
+ fract*INT we don't need fMult */
+
+ int minus = scale * FL2FXCONST_DBL(1.0 / 64);
+
+ if (bandEnergyMidLdData[i] != FL2FXCONST_DBL(-1.0f))
+ bandEnergyMidLdData[i] -= minus;
+
+ if (bandEnergySideLdData[i] != FL2FXCONST_DBL(-1.0f))
+ bandEnergySideLdData[i] -= minus;
+ }
+ scale = fixMin(scale, (DFRACT_BITS - 1));
+ bandEnergyMid[i] >>= scale;
+ bandEnergySide[i] >>= scale;
+ }
+}
diff --git a/fdk-aac/libAACenc/src/band_nrg.h b/fdk-aac/libAACenc/src/band_nrg.h
new file mode 100644
index 0000000..4137565
--- /dev/null
+++ b/fdk-aac/libAACenc/src/band_nrg.h
@@ -0,0 +1,142 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Band/Line energy calculation
+
+*******************************************************************************/
+
+#ifndef BAND_NRG_H
+#define BAND_NRG_H
+
+#include "common_fix.h"
+
+void FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *mdctSpectrum,
+ const INT *bandOffset, INT *sfbMaxScaleSpec,
+ const INT numBands);
+
+FIXP_DBL
+FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *const RESTRICT mdctSpectrum,
+ const INT *const RESTRICT sfbMaxScaleSpec,
+ const INT *const RESTRICT bandOffset,
+ const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergy,
+ FIXP_DBL *RESTRICT bandEnergyLdData,
+ const INT minSpecShift);
+
+INT FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *mdctSpectrum,
+ INT *sfbMaxScaleSpec,
+ const INT *bandOffset, const INT numBands,
+ FIXP_DBL *bandEnergy,
+ FIXP_DBL *bandEnergyLdData);
+
+void FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *mdctSpectrum,
+ INT *sfbMaxScaleSpec,
+ const INT *bandOffset,
+ const INT numBands,
+ FIXP_DBL *bandEnergy);
+
+void FDKaacEnc_CalcBandNrgMSOpt(
+ const FIXP_DBL *RESTRICT mdctSpectrumLeft,
+ const FIXP_DBL *RESTRICT mdctSpectrumRight,
+ INT *RESTRICT sfbMaxScaleSpecLeft, INT *RESTRICT sfbMaxScaleSpecRight,
+ const INT *RESTRICT bandOffset, const INT numBands,
+ FIXP_DBL *RESTRICT bandEnergyMid, FIXP_DBL *RESTRICT bandEnergySide,
+ INT calcLdData, FIXP_DBL *RESTRICT bandEnergyMidLdData,
+ FIXP_DBL *RESTRICT bandEnergySideLdData);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/bandwidth.cpp b/fdk-aac/libAACenc/src/bandwidth.cpp
new file mode 100644
index 0000000..36cd64d
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bandwidth.cpp
@@ -0,0 +1,360 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Schug / A. Groeschel
+
+ Description: bandwidth expert
+
+*******************************************************************************/
+
+#include "channel_map.h"
+#include "bandwidth.h"
+#include "aacEnc_ram.h"
+
+typedef struct {
+ INT chanBitRate;
+ INT bandWidthMono;
+ INT bandWidth2AndMoreChan;
+
+} BANDWIDTH_TAB;
+
+static const BANDWIDTH_TAB bandWidthTable[] = {
+ {0, 3700, 5000}, {12000, 5000, 6400}, {20000, 6900, 9640},
+ {28000, 9600, 13050}, {40000, 12060, 14260}, {56000, 13950, 15500},
+ {72000, 14200, 16120}, {96000, 17000, 17000}, {576001, 17000, 17000}};
+
+static const BANDWIDTH_TAB bandWidthTable_LD_22050[] = {
+ {8000, 2000, 2400}, {12000, 2500, 2700}, {16000, 3300, 3100},
+ {24000, 6250, 7200}, {32000, 9200, 10500}, {40000, 16000, 16000},
+ {48000, 16000, 16000}, {282241, 16000, 16000}};
+
+static const BANDWIDTH_TAB bandWidthTable_LD_24000[] = {
+ {8000, 2000, 2000}, {12000, 2000, 2300}, {16000, 2200, 2500},
+ {24000, 5650, 7200}, {32000, 11600, 12000}, {40000, 12000, 16000},
+ {48000, 16000, 16000}, {64000, 16000, 16000}, {307201, 16000, 16000}};
+
+static const BANDWIDTH_TAB bandWidthTable_LD_32000[] = {
+ {8000, 2000, 2000}, {12000, 2000, 2000}, {24000, 4250, 7200},
+ {32000, 8400, 9000}, {40000, 9400, 11300}, {48000, 11900, 14700},
+ {64000, 14800, 16000}, {76000, 16000, 16000}, {409601, 16000, 16000}};
+
+static const BANDWIDTH_TAB bandWidthTable_LD_44100[] = {
+ {8000, 2000, 2000}, {24000, 2000, 2000}, {32000, 4400, 5700},
+ {40000, 7400, 8800}, {48000, 9000, 10700}, {56000, 11000, 12900},
+ {64000, 14400, 15500}, {80000, 16000, 16200}, {96000, 16500, 16000},
+ {128000, 16000, 16000}, {564481, 16000, 16000}};
+
+static const BANDWIDTH_TAB bandWidthTable_LD_48000[] = {
+ {8000, 2000, 2000}, {24000, 2000, 2000}, {32000, 4400, 5700},
+ {40000, 7400, 8800}, {48000, 9000, 10700}, {56000, 11000, 12800},
+ {64000, 14300, 15400}, {80000, 16000, 16200}, {96000, 16500, 16000},
+ {128000, 16000, 16000}, {614401, 16000, 16000}};
+
+typedef struct {
+ AACENC_BITRATE_MODE bitrateMode;
+ int bandWidthMono;
+ int bandWidth2AndMoreChan;
+} BANDWIDTH_TAB_VBR;
+
+static const BANDWIDTH_TAB_VBR bandWidthTableVBR[] = {
+ {AACENC_BR_MODE_CBR, 0, 0},
+ {AACENC_BR_MODE_VBR_1, 13050, 13050},
+ {AACENC_BR_MODE_VBR_2, 13050, 13050},
+ {AACENC_BR_MODE_VBR_3, 14260, 14260},
+ {AACENC_BR_MODE_VBR_4, 15500, 15500},
+ {AACENC_BR_MODE_VBR_5, 48000, 48000},
+ {AACENC_BR_MODE_SFR, 0, 0},
+ {AACENC_BR_MODE_FF, 0, 0}
+
+};
+
+static INT GetBandwidthEntry(const INT frameLength, const INT sampleRate,
+ const INT chanBitRate, const INT entryNo) {
+ INT bandwidth = -1;
+ const BANDWIDTH_TAB *pBwTab = NULL;
+ INT bwTabSize = 0;
+
+ switch (frameLength) {
+ case 960:
+ case 1024:
+ pBwTab = bandWidthTable;
+ bwTabSize = sizeof(bandWidthTable) / sizeof(BANDWIDTH_TAB);
+ break;
+ case 120:
+ case 128:
+ case 240:
+ case 256:
+ case 480:
+ case 512:
+ switch (sampleRate) {
+ case 8000:
+ case 11025:
+ case 12000:
+ case 16000:
+ case 22050:
+ pBwTab = bandWidthTable_LD_22050;
+ bwTabSize = sizeof(bandWidthTable_LD_22050) / sizeof(BANDWIDTH_TAB);
+ break;
+ case 24000:
+ pBwTab = bandWidthTable_LD_24000;
+ bwTabSize = sizeof(bandWidthTable_LD_24000) / sizeof(BANDWIDTH_TAB);
+ break;
+ case 32000:
+ pBwTab = bandWidthTable_LD_32000;
+ bwTabSize = sizeof(bandWidthTable_LD_32000) / sizeof(BANDWIDTH_TAB);
+ break;
+ case 44100:
+ pBwTab = bandWidthTable_LD_44100;
+ bwTabSize = sizeof(bandWidthTable_LD_44100) / sizeof(BANDWIDTH_TAB);
+ break;
+ case 48000:
+ case 64000:
+ case 88200:
+ case 96000:
+ pBwTab = bandWidthTable_LD_48000;
+ bwTabSize = sizeof(bandWidthTable_LD_48000) / sizeof(BANDWIDTH_TAB);
+ break;
+ }
+ break;
+ default:
+ pBwTab = NULL;
+ bwTabSize = 0;
+ }
+
+ if (pBwTab != NULL) {
+ int i;
+ for (i = 0; i < bwTabSize - 1; i++) {
+ if (chanBitRate >= pBwTab[i].chanBitRate &&
+ chanBitRate < pBwTab[i + 1].chanBitRate) {
+ switch (frameLength) {
+ case 960:
+ case 1024:
+ bandwidth = (entryNo == 0) ? pBwTab[i].bandWidthMono
+ : pBwTab[i].bandWidth2AndMoreChan;
+ break;
+ case 120:
+ case 128:
+ case 240:
+ case 256:
+ case 480:
+ case 512: {
+ INT q_res = 0;
+ INT startBw = (entryNo == 0) ? pBwTab[i].bandWidthMono
+ : pBwTab[i].bandWidth2AndMoreChan;
+ INT endBw = (entryNo == 0) ? pBwTab[i + 1].bandWidthMono
+ : pBwTab[i + 1].bandWidth2AndMoreChan;
+ INT startBr = pBwTab[i].chanBitRate;
+ INT endBr = pBwTab[i + 1].chanBitRate;
+
+ FIXP_DBL bwFac_fix =
+ fDivNorm(chanBitRate - startBr, endBr - startBr, &q_res);
+ bandwidth =
+ (INT)scaleValue(fMult(bwFac_fix, (FIXP_DBL)(endBw - startBw)),
+ q_res) +
+ startBw;
+ } break;
+ default:
+ bandwidth = -1;
+ }
+ break;
+ } /* within bitrate range */
+ }
+ } /* pBwTab!=NULL */
+
+ return bandwidth;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth(
+ const INT proposedBandWidth, const INT bitrate,
+ const AACENC_BITRATE_MODE bitrateMode, const INT sampleRate,
+ const INT frameLength, const CHANNEL_MAPPING *const cm,
+ const CHANNEL_MODE encoderMode, INT *const bandWidth) {
+ AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
+ INT chanBitRate = bitrate / cm->nChannelsEff;
+
+ switch (bitrateMode) {
+ case AACENC_BR_MODE_VBR_1:
+ case AACENC_BR_MODE_VBR_2:
+ case AACENC_BR_MODE_VBR_3:
+ case AACENC_BR_MODE_VBR_4:
+ case AACENC_BR_MODE_VBR_5:
+ if (proposedBandWidth != 0) {
+ /* use given bw */
+ *bandWidth = proposedBandWidth;
+ } else {
+ /* take bw from table */
+ switch (encoderMode) {
+ case MODE_1:
+ *bandWidth = bandWidthTableVBR[bitrateMode].bandWidthMono;
+ break;
+ case MODE_2:
+ case MODE_1_2:
+ case MODE_1_2_1:
+ case MODE_1_2_2:
+ case MODE_1_2_2_1:
+ case MODE_6_1:
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER:
+ case MODE_7_1_BACK:
+ case MODE_7_1_TOP_FRONT:
+ *bandWidth = bandWidthTableVBR[bitrateMode].bandWidth2AndMoreChan;
+ break;
+ default:
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ }
+ }
+ break;
+ case AACENC_BR_MODE_CBR:
+ case AACENC_BR_MODE_SFR:
+ case AACENC_BR_MODE_FF:
+
+ /* bandwidth limiting */
+ if (proposedBandWidth != 0) {
+ *bandWidth = fMin(proposedBandWidth, fMin(20000, sampleRate >> 1));
+ } else { /* search reasonable bandwidth */
+
+ int entryNo = 0;
+
+ switch (encoderMode) {
+ case MODE_1: /* mono */
+ entryNo = 0; /* use mono bandwidth settings */
+ break;
+
+ case MODE_2: /* stereo */
+ case MODE_1_2: /* sce + cpe */
+ case MODE_1_2_1: /* sce + cpe + sce */
+ case MODE_1_2_2: /* sce + cpe + cpe */
+ case MODE_1_2_2_1: /* (5.1) sce + cpe + cpe + lfe */
+ case MODE_6_1:
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER:
+ case MODE_7_1_BACK:
+ case MODE_7_1_TOP_FRONT:
+ entryNo = 1; /* use stereo bandwidth settings */
+ break;
+
+ default:
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ *bandWidth =
+ GetBandwidthEntry(frameLength, sampleRate, chanBitRate, entryNo);
+
+ if (*bandWidth == -1) {
+ switch (frameLength) {
+ case 120:
+ case 128:
+ case 240:
+ case 256:
+ *bandWidth = 16000;
+ break;
+ default:
+ ErrorStatus = AAC_ENC_INVALID_CHANNEL_BITRATE;
+ }
+ }
+ }
+ break;
+ default:
+ *bandWidth = 0;
+ return AAC_ENC_UNSUPPORTED_BITRATE_MODE;
+ }
+
+ *bandWidth = fMin(*bandWidth, sampleRate / 2);
+
+ return ErrorStatus;
+}
diff --git a/fdk-aac/libAACenc/src/bandwidth.h b/fdk-aac/libAACenc/src/bandwidth.h
new file mode 100644
index 0000000..088e829
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bandwidth.h
@@ -0,0 +1,114 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Schug / A. Groeschel
+
+ Description: bandwidth expert
+
+*******************************************************************************/
+
+#ifndef BANDWIDTH_H
+#define BANDWIDTH_H
+
+#include "qc_data.h"
+
+AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth(
+ const INT proposedBandWidth, const INT bitrate,
+ const AACENC_BITRATE_MODE bitrateMode, const INT sampleRate,
+ const INT frameLength, const CHANNEL_MAPPING *const cm,
+ const CHANNEL_MODE encoderMode, INT *const bandWidth);
+
+#endif /* BANDWIDTH_H */
diff --git a/fdk-aac/libAACenc/src/bit_cnt.cpp b/fdk-aac/libAACenc/src/bit_cnt.cpp
new file mode 100644
index 0000000..579df8c
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bit_cnt.cpp
@@ -0,0 +1,950 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Huffman Bitcounter & coder
+
+*******************************************************************************/
+
+#include "bit_cnt.h"
+
+#include "aacEnc_ram.h"
+
+#define HI_LTAB(a) (a >> 16)
+#define LO_LTAB(a) (a & 0xffff)
+
+/*****************************************************************************
+
+
+ functionname: FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11
+ description: counts tables 1-11
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 1-11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11(const SHORT *const values,
+ const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc1_2, bc3_4, bc5_6, bc7_8, bc9_10, bc11, sc;
+ INT t0, t1, t2, t3;
+ bc1_2 = 0;
+ bc3_4 = 0;
+ bc5_6 = 0;
+ bc7_8 = 0;
+ bc9_10 = 0;
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ bc1_2 += (INT)FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1];
+ bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] +
+ (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc3_4 += (INT)FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3];
+ bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab7_8[t2][t3];
+ bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab9_10[t2][t3];
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+ bitCount[1] = HI_LTAB(bc1_2);
+ bitCount[2] = LO_LTAB(bc1_2);
+ bitCount[3] = HI_LTAB(bc3_4) + sc;
+ bitCount[4] = LO_LTAB(bc3_4) + sc;
+ bitCount[5] = HI_LTAB(bc5_6);
+ bitCount[6] = LO_LTAB(bc5_6);
+ bitCount[7] = HI_LTAB(bc7_8) + sc;
+ bitCount[8] = LO_LTAB(bc7_8) + sc;
+ bitCount[9] = HI_LTAB(bc9_10) + sc;
+ bitCount[10] = LO_LTAB(bc9_10) + sc;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_count3_4_5_6_7_8_9_10_11
+ description: counts tables 3-11
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 3-11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count3_4_5_6_7_8_9_10_11(const SHORT *const values,
+ const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc3_4, bc5_6, bc7_8, bc9_10, bc11, sc;
+ INT t0, t1, t2, t3;
+
+ bc3_4 = 0;
+ bc5_6 = 0;
+ bc7_8 = 0;
+ bc9_10 = 0;
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] +
+ (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc3_4 += (INT)FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3];
+ bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab7_8[t2][t3];
+ bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab9_10[t2][t3];
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+
+ bitCount[1] = INVALID_BITCOUNT;
+ bitCount[2] = INVALID_BITCOUNT;
+ bitCount[3] = HI_LTAB(bc3_4) + sc;
+ bitCount[4] = LO_LTAB(bc3_4) + sc;
+ bitCount[5] = HI_LTAB(bc5_6);
+ bitCount[6] = LO_LTAB(bc5_6);
+ bitCount[7] = HI_LTAB(bc7_8) + sc;
+ bitCount[8] = LO_LTAB(bc7_8) + sc;
+ bitCount[9] = HI_LTAB(bc9_10) + sc;
+ bitCount[10] = LO_LTAB(bc9_10) + sc;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_count5_6_7_8_9_10_11
+ description: counts tables 5-11
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 5-11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count5_6_7_8_9_10_11(const SHORT *const values,
+ const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc5_6, bc7_8, bc9_10, bc11, sc;
+ INT t0, t1, t2, t3;
+ bc5_6 = 0;
+ bc7_8 = 0;
+ bc9_10 = 0;
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] +
+ (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab7_8[t2][t3];
+ bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab9_10[t2][t3];
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+ bitCount[1] = INVALID_BITCOUNT;
+ bitCount[2] = INVALID_BITCOUNT;
+ bitCount[3] = INVALID_BITCOUNT;
+ bitCount[4] = INVALID_BITCOUNT;
+ bitCount[5] = HI_LTAB(bc5_6);
+ bitCount[6] = LO_LTAB(bc5_6);
+ bitCount[7] = HI_LTAB(bc7_8) + sc;
+ bitCount[8] = LO_LTAB(bc7_8) + sc;
+ bitCount[9] = HI_LTAB(bc9_10) + sc;
+ bitCount[10] = LO_LTAB(bc9_10) + sc;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_count7_8_9_10_11
+ description: counts tables 7-11
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 7-11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count7_8_9_10_11(const SHORT *const values,
+ const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc7_8, bc9_10, bc11, sc;
+ INT t0, t1, t2, t3;
+
+ bc7_8 = 0;
+ bc9_10 = 0;
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab7_8[t2][t3];
+ bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab9_10[t2][t3];
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+
+ bitCount[1] = INVALID_BITCOUNT;
+ bitCount[2] = INVALID_BITCOUNT;
+ bitCount[3] = INVALID_BITCOUNT;
+ bitCount[4] = INVALID_BITCOUNT;
+ bitCount[5] = INVALID_BITCOUNT;
+ bitCount[6] = INVALID_BITCOUNT;
+ bitCount[7] = HI_LTAB(bc7_8) + sc;
+ bitCount[8] = LO_LTAB(bc7_8) + sc;
+ bitCount[9] = HI_LTAB(bc9_10) + sc;
+ bitCount[10] = LO_LTAB(bc9_10) + sc;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_count9_10_11
+ description: counts tables 9-11
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 9-11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count9_10_11(const SHORT *const values, const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc9_10, bc11, sc;
+ INT t0, t1, t2, t3;
+
+ bc9_10 = 0;
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] +
+ (INT)FDKaacEnc_huff_ltab9_10[t2][t3];
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+
+ bitCount[1] = INVALID_BITCOUNT;
+ bitCount[2] = INVALID_BITCOUNT;
+ bitCount[3] = INVALID_BITCOUNT;
+ bitCount[4] = INVALID_BITCOUNT;
+ bitCount[5] = INVALID_BITCOUNT;
+ bitCount[6] = INVALID_BITCOUNT;
+ bitCount[7] = INVALID_BITCOUNT;
+ bitCount[8] = INVALID_BITCOUNT;
+ bitCount[9] = HI_LTAB(bc9_10) + sc;
+ bitCount[10] = LO_LTAB(bc9_10) + sc;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_count11
+ description: counts table 11
+ returns:
+ input: quantized spectrum
+ output: bitCount for table 11
+
+*****************************************************************************/
+
+static void FDKaacEnc_count11(const SHORT *const values, const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc11, sc;
+ INT t0, t1, t2, t3;
+
+ bc11 = 0;
+ sc = 0;
+
+ DWORD_ALIGNED(values);
+
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+
+ t0 = fixp_abs(t0);
+ sc += (t0 > 0);
+ t1 = fixp_abs(t1);
+ sc += (t1 > 0);
+ t2 = fixp_abs(t2);
+ sc += (t2 > 0);
+ t3 = fixp_abs(t3);
+ sc += (t3 > 0);
+
+ bc11 +=
+ (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3];
+ }
+
+ bitCount[1] = INVALID_BITCOUNT;
+ bitCount[2] = INVALID_BITCOUNT;
+ bitCount[3] = INVALID_BITCOUNT;
+ bitCount[4] = INVALID_BITCOUNT;
+ bitCount[5] = INVALID_BITCOUNT;
+ bitCount[6] = INVALID_BITCOUNT;
+ bitCount[7] = INVALID_BITCOUNT;
+ bitCount[8] = INVALID_BITCOUNT;
+ bitCount[9] = INVALID_BITCOUNT;
+ bitCount[10] = INVALID_BITCOUNT;
+ bitCount[11] = bc11 + sc;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_countEsc
+ description: counts table 11 (with Esc)
+ returns:
+ input: quantized spectrum
+ output: bitCount for tables 11 (with Esc)
+
+*****************************************************************************/
+
+static void FDKaacEnc_countEsc(const SHORT *const values, const INT width,
+ INT *RESTRICT bitCount) {
+ INT i;
+ INT bc11, ec, sc;
+ INT t0, t1, t00, t01;
+
+ bc11 = 0;
+ sc = 0;
+ ec = 0;
+ for (i = 0; i < width; i += 2) {
+ t0 = fixp_abs(values[i + 0]);
+ t1 = fixp_abs(values[i + 1]);
+
+ sc += (t0 > 0) + (t1 > 0);
+
+ t00 = fixMin(t0, 16);
+ t01 = fixMin(t1, 16);
+ bc11 += (INT)FDKaacEnc_huff_ltab11[t00][t01];
+
+ if (t0 >= 16) {
+ ec += 5;
+ while ((t0 >>= 1) >= 16) ec += 2;
+ }
+
+ if (t1 >= 16) {
+ ec += 5;
+ while ((t1 >>= 1) >= 16) ec += 2;
+ }
+ }
+
+ for (i = 0; i < 11; i++) bitCount[i] = INVALID_BITCOUNT;
+
+ bitCount[11] = bc11 + sc + ec;
+}
+
+typedef void (*COUNT_FUNCTION)(const SHORT *const values, const INT width,
+ INT *RESTRICT bitCount);
+
+static const COUNT_FUNCTION countFuncTable[CODE_BOOK_ESC_LAV + 1] = {
+
+ FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 0 */
+ FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 1 */
+ FDKaacEnc_count3_4_5_6_7_8_9_10_11, /* 2 */
+ FDKaacEnc_count5_6_7_8_9_10_11, /* 3 */
+ FDKaacEnc_count5_6_7_8_9_10_11, /* 4 */
+ FDKaacEnc_count7_8_9_10_11, /* 5 */
+ FDKaacEnc_count7_8_9_10_11, /* 6 */
+ FDKaacEnc_count7_8_9_10_11, /* 7 */
+ FDKaacEnc_count9_10_11, /* 8 */
+ FDKaacEnc_count9_10_11, /* 9 */
+ FDKaacEnc_count9_10_11, /* 10 */
+ FDKaacEnc_count9_10_11, /* 11 */
+ FDKaacEnc_count9_10_11, /* 12 */
+ FDKaacEnc_count11, /* 13 */
+ FDKaacEnc_count11, /* 14 */
+ FDKaacEnc_count11, /* 15 */
+ FDKaacEnc_countEsc /* 16 */
+};
+
+INT FDKaacEnc_bitCount(const SHORT *const values, const INT width,
+ const INT maxVal, INT *const RESTRICT bitCount) {
+ /*
+ check if we can use codebook 0
+ */
+
+ bitCount[0] = (maxVal == 0) ? 0 : INVALID_BITCOUNT;
+
+ countFuncTable[fixMin(maxVal, (INT)CODE_BOOK_ESC_LAV)](values, width,
+ bitCount);
+
+ return (0);
+}
+
+/*
+ count difference between actual and zeroed lines
+*/
+INT FDKaacEnc_countValues(SHORT *RESTRICT values, INT width, INT codeBook) {
+ INT i, t0, t1, t2, t3;
+ INT bitCnt = 0;
+
+ switch (codeBook) {
+ case CODE_BOOK_ZERO_NO:
+ break;
+
+ case CODE_BOOK_1_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+ bitCnt +=
+ HI_LTAB(FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1]);
+ }
+ break;
+
+ case CODE_BOOK_2_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+ bitCnt +=
+ LO_LTAB(FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1]);
+ }
+ break;
+
+ case CODE_BOOK_3_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += HI_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_4_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += LO_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_5_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+ bitCnt += HI_LTAB(FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4]) +
+ HI_LTAB(FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]);
+ }
+ break;
+
+ case CODE_BOOK_6_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0];
+ t1 = values[i + 1];
+ t2 = values[i + 2];
+ t3 = values[i + 3];
+ bitCnt += LO_LTAB(FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4]) +
+ LO_LTAB(FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]);
+ }
+ break;
+
+ case CODE_BOOK_7_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += HI_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]) +
+ HI_LTAB(FDKaacEnc_huff_ltab7_8[t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_8_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += LO_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]) +
+ LO_LTAB(FDKaacEnc_huff_ltab7_8[t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_9_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += HI_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]) +
+ HI_LTAB(FDKaacEnc_huff_ltab9_10[t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_10_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ t2 = fixp_abs(values[i + 2]);
+ bitCnt += (t2 > 0);
+ t3 = fixp_abs(values[i + 3]);
+ bitCnt += (t3 > 0);
+ bitCnt += LO_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]) +
+ LO_LTAB(FDKaacEnc_huff_ltab9_10[t2][t3]);
+ }
+ break;
+
+ case CODE_BOOK_ESC_NO:
+ for (i = 0; i < width; i += 2) {
+ t0 = fixp_abs(values[i + 0]);
+ bitCnt += (t0 > 0);
+ t1 = fixp_abs(values[i + 1]);
+ bitCnt += (t1 > 0);
+ bitCnt += (INT)FDKaacEnc_huff_ltab11[fixMin(t0, 16)][fixMin(t1, 16)];
+ if (t0 >= 16) {
+ bitCnt += 5;
+ while ((t0 >>= 1) >= 16) bitCnt += 2;
+ }
+ if (t1 >= 16) {
+ bitCnt += 5;
+ while ((t1 >>= 1) >= 16) bitCnt += 2;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return (bitCnt);
+}
+
+INT FDKaacEnc_codeValues(SHORT *RESTRICT values, INT width, INT codeBook,
+ HANDLE_FDK_BITSTREAM hBitstream) {
+ INT i, t0, t1, t2, t3, t00, t01;
+ INT codeWord, codeLength;
+ INT sign, signLength;
+
+ DWORD_ALIGNED(values);
+
+ switch (codeBook) {
+ case CODE_BOOK_ZERO_NO:
+ break;
+
+ case CODE_BOOK_1_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0] + 1;
+ t1 = values[i + 1] + 1;
+ t2 = values[i + 2] + 1;
+ t3 = values[i + 3] + 1;
+ codeWord = FDKaacEnc_huff_ctab1[t0][t1][t2][t3];
+ codeLength = HI_LTAB(FDKaacEnc_huff_ltab1_2[t0][t1][t2][t3]);
+ FDKwriteBits(hBitstream, codeWord, codeLength);
+ }
+ break;
+
+ case CODE_BOOK_2_NO:
+ for (i = 0; i < width; i += 4) {
+ t0 = values[i + 0] + 1;
+ t1 = values[i + 1] + 1;
+ t2 = values[i + 2] + 1;
+ t3 = values[i + 3] + 1;
+ codeWord = FDKaacEnc_huff_ctab2[t0][t1][t2][t3];
+ codeLength = LO_LTAB(FDKaacEnc_huff_ltab1_2[t0][t1][t2][t3]);
+ FDKwriteBits(hBitstream, codeWord, codeLength);
+ }
+ break;
+
+ case CODE_BOOK_3_NO:
+ for (i = 0; i < (width >> 2); i++) {
+ sign = 0;
+ signLength = 0;
+ int index[4];
+ for (int j = 0; j < 4; j++) {
+ int ti = *values++;
+ int zero = (ti == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)ti >> 31);
+ index[j] = fixp_abs(ti);
+ }
+ codeWord = FDKaacEnc_huff_ctab3[index[0]][index[1]][index[2]][index[3]];
+ codeLength = HI_LTAB(
+ FDKaacEnc_huff_ltab3_4[index[0]][index[1]][index[2]][index[3]]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_4_NO:
+ for (i = 0; i < width; i += 4) {
+ sign = 0;
+ signLength = 0;
+ int index[4];
+ for (int j = 0; j < 4; j++) {
+ int ti = *values++;
+ int zero = (ti == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)ti >> 31);
+ index[j] = fixp_abs(ti);
+ }
+ codeWord = FDKaacEnc_huff_ctab4[index[0]][index[1]][index[2]][index[3]];
+ codeLength = LO_LTAB(
+ FDKaacEnc_huff_ltab3_4[index[0]][index[1]][index[2]][index[3]]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_5_NO:
+ for (i = 0; i < (width >> 2); i++) {
+ t0 = *values++ + 4;
+ t1 = *values++ + 4;
+ t2 = *values++ + 4;
+ t3 = *values++ + 4;
+ codeWord = FDKaacEnc_huff_ctab5[t0][t1];
+ codeLength =
+ HI_LTAB(FDKaacEnc_huff_ltab5_6[t2][t3]); /* length of 2nd cw */
+ codeWord = (codeWord << codeLength) + FDKaacEnc_huff_ctab5[t2][t3];
+ codeLength += HI_LTAB(FDKaacEnc_huff_ltab5_6[t0][t1]);
+ FDKwriteBits(hBitstream, codeWord, codeLength);
+ }
+ break;
+
+ case CODE_BOOK_6_NO:
+ for (i = 0; i < (width >> 2); i++) {
+ t0 = *values++ + 4;
+ t1 = *values++ + 4;
+ t2 = *values++ + 4;
+ t3 = *values++ + 4;
+ codeWord = FDKaacEnc_huff_ctab6[t0][t1];
+ codeLength =
+ LO_LTAB(FDKaacEnc_huff_ltab5_6[t2][t3]); /* length of 2nd cw */
+ codeWord = (codeWord << codeLength) + FDKaacEnc_huff_ctab6[t2][t3];
+ codeLength += LO_LTAB(FDKaacEnc_huff_ltab5_6[t0][t1]);
+ FDKwriteBits(hBitstream, codeWord, codeLength);
+ }
+ break;
+
+ case CODE_BOOK_7_NO:
+ for (i = 0; i < (width >> 1); i++) {
+ t0 = *values++;
+ sign = ((UINT)t0 >> 31);
+ t0 = fixp_abs(t0);
+ signLength = (t0 == 0) ? 0 : 1;
+ t1 = *values++;
+ INT zero = (t1 == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)t1 >> 31);
+ t1 = fixp_abs(t1);
+ codeWord = FDKaacEnc_huff_ctab7[t0][t1];
+ codeLength = HI_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_8_NO:
+ for (i = 0; i < (width >> 1); i++) {
+ t0 = *values++;
+ sign = ((UINT)t0 >> 31);
+ t0 = fixp_abs(t0);
+ signLength = (t0 == 0) ? 0 : 1;
+ t1 = *values++;
+ INT zero = (t1 == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)t1 >> 31);
+ t1 = fixp_abs(t1);
+ codeWord = FDKaacEnc_huff_ctab8[t0][t1];
+ codeLength = LO_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_9_NO:
+ for (i = 0; i < (width >> 1); i++) {
+ t0 = *values++;
+ sign = ((UINT)t0 >> 31);
+ t0 = fixp_abs(t0);
+ signLength = (t0 == 0) ? 0 : 1;
+ t1 = *values++;
+ INT zero = (t1 == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)t1 >> 31);
+ t1 = fixp_abs(t1);
+ codeWord = FDKaacEnc_huff_ctab9[t0][t1];
+ codeLength = HI_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_10_NO:
+ for (i = 0; i < (width >> 1); i++) {
+ t0 = *values++;
+ sign = ((UINT)t0 >> 31);
+ t0 = fixp_abs(t0);
+ signLength = (t0 == 0) ? 0 : 1;
+ t1 = *values++;
+ INT zero = (t1 == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)t1 >> 31);
+ t1 = fixp_abs(t1);
+ codeWord = FDKaacEnc_huff_ctab10[t0][t1];
+ codeLength = LO_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]);
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ }
+ break;
+
+ case CODE_BOOK_ESC_NO:
+ for (i = 0; i < (width >> 1); i++) {
+ t0 = *values++;
+ sign = ((UINT)t0 >> 31);
+ t0 = fixp_abs(t0);
+ signLength = (t0 == 0) ? 0 : 1;
+ t1 = *values++;
+ INT zero = (t1 == 0) ? 0 : 1;
+ signLength += zero;
+ sign = (sign << zero) + ((UINT)t1 >> 31);
+ t1 = fixp_abs(t1);
+
+ t00 = fixMin(t0, 16);
+ t01 = fixMin(t1, 16);
+
+ codeWord = FDKaacEnc_huff_ctab11[t00][t01];
+ codeLength = (INT)FDKaacEnc_huff_ltab11[t00][t01];
+ FDKwriteBits(hBitstream, (codeWord << signLength) | sign,
+ codeLength + signLength);
+ for (int j = 0; j < 2; j++) {
+ if (t0 >= 16) {
+ INT n = 4, p = t0;
+ for (; (p >>= 1) >= 16;) n++;
+ FDKwriteBits(hBitstream,
+ (((1 << (n - 3)) - 2) << n) | (t0 - (1 << n)),
+ n + n - 3);
+ }
+ t0 = t1;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return (0);
+}
+
+INT FDKaacEnc_codeScalefactorDelta(INT delta, HANDLE_FDK_BITSTREAM hBitstream) {
+ INT codeWord, codeLength;
+
+ if (fixp_abs(delta) > CODE_BOOK_SCF_LAV) return (1);
+
+ codeWord = FDKaacEnc_huff_ctabscf[delta + CODE_BOOK_SCF_LAV];
+ codeLength = (INT)FDKaacEnc_huff_ltabscf[delta + CODE_BOOK_SCF_LAV];
+ FDKwriteBits(hBitstream, codeWord, codeLength);
+ return (0);
+}
diff --git a/fdk-aac/libAACenc/src/bit_cnt.h b/fdk-aac/libAACenc/src/bit_cnt.h
new file mode 100644
index 0000000..7f4c450
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bit_cnt.h
@@ -0,0 +1,200 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Huffman Bitcounter & coder
+
+*******************************************************************************/
+
+#ifndef BIT_CNT_H
+#define BIT_CNT_H
+
+#include "common_fix.h"
+#include "FDK_bitstream.h"
+#include "aacEnc_rom.h"
+
+#define INVALID_BITCOUNT (FDK_INT_MAX / 4)
+
+/*
+ code book number table
+*/
+
+enum codeBookNo {
+ CODE_BOOK_ZERO_NO = 0,
+ CODE_BOOK_1_NO = 1,
+ CODE_BOOK_2_NO = 2,
+ CODE_BOOK_3_NO = 3,
+ CODE_BOOK_4_NO = 4,
+ CODE_BOOK_5_NO = 5,
+ CODE_BOOK_6_NO = 6,
+ CODE_BOOK_7_NO = 7,
+ CODE_BOOK_8_NO = 8,
+ CODE_BOOK_9_NO = 9,
+ CODE_BOOK_10_NO = 10,
+ CODE_BOOK_ESC_NO = 11,
+ CODE_BOOK_RES_NO = 12,
+ CODE_BOOK_PNS_NO = 13,
+ CODE_BOOK_IS_OUT_OF_PHASE_NO = 14,
+ CODE_BOOK_IS_IN_PHASE_NO = 15
+
+};
+
+/*
+ code book index table
+*/
+
+enum codeBookNdx {
+ CODE_BOOK_ZERO_NDX,
+ CODE_BOOK_1_NDX,
+ CODE_BOOK_2_NDX,
+ CODE_BOOK_3_NDX,
+ CODE_BOOK_4_NDX,
+ CODE_BOOK_5_NDX,
+ CODE_BOOK_6_NDX,
+ CODE_BOOK_7_NDX,
+ CODE_BOOK_8_NDX,
+ CODE_BOOK_9_NDX,
+ CODE_BOOK_10_NDX,
+ CODE_BOOK_ESC_NDX,
+ CODE_BOOK_RES_NDX,
+ CODE_BOOK_PNS_NDX,
+ CODE_BOOK_IS_OUT_OF_PHASE_NDX,
+ CODE_BOOK_IS_IN_PHASE_NDX,
+ NUMBER_OF_CODE_BOOKS
+};
+
+/*
+ code book lav table
+*/
+
+enum codeBookLav {
+ CODE_BOOK_ZERO_LAV = 0,
+ CODE_BOOK_1_LAV = 1,
+ CODE_BOOK_2_LAV = 1,
+ CODE_BOOK_3_LAV = 2,
+ CODE_BOOK_4_LAV = 2,
+ CODE_BOOK_5_LAV = 4,
+ CODE_BOOK_6_LAV = 4,
+ CODE_BOOK_7_LAV = 7,
+ CODE_BOOK_8_LAV = 7,
+ CODE_BOOK_9_LAV = 12,
+ CODE_BOOK_10_LAV = 12,
+ CODE_BOOK_ESC_LAV = 16,
+ CODE_BOOK_SCF_LAV = 60,
+ CODE_BOOK_PNS_LAV = 60
+};
+
+INT FDKaacEnc_bitCount(const SHORT *aQuantSpectrum, const INT noOfSpecLines,
+ INT maxVal, INT *bitCountLut);
+
+INT FDKaacEnc_countValues(SHORT *values, INT width, INT codeBook);
+
+INT FDKaacEnc_codeValues(SHORT *values, INT width, INT codeBook,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+INT FDKaacEnc_codeScalefactorDelta(INT scalefactor,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+inline INT FDKaacEnc_bitCountScalefactorDelta(const INT delta) {
+ FDK_ASSERT((0 <= (delta + CODE_BOOK_SCF_LAV)) &&
+ ((delta + CODE_BOOK_SCF_LAV) <
+ (int)(sizeof(FDKaacEnc_huff_ltabscf) /
+ sizeof((FDKaacEnc_huff_ltabscf[0])))));
+ return ((INT)FDKaacEnc_huff_ltabscf[delta + CODE_BOOK_SCF_LAV]);
+}
+
+#endif
diff --git a/fdk-aac/libAACenc/src/bitenc.cpp b/fdk-aac/libAACenc/src/bitenc.cpp
new file mode 100644
index 0000000..512d596
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bitenc.cpp
@@ -0,0 +1,1362 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Bitstream encoder
+
+*******************************************************************************/
+
+#include <stdio.h>
+#include "bitenc.h"
+#include "bit_cnt.h"
+#include "dyn_bits.h"
+#include "qc_data.h"
+#include "interface.h"
+#include "aacEnc_ram.h"
+
+#include "tpenc_lib.h"
+
+#include "FDK_tools_rom.h" /* needed for the bitstream syntax tables */
+
+static const int globalGainOffset = 100;
+static const int icsReservedBit = 0;
+static const int noiseOffset = 90;
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeSpectralData
+ description: encode spectral data
+ returns: the number of written bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeSpectralData(INT *sfbOffset,
+ SECTION_DATA *sectionData,
+ SHORT *quantSpectrum,
+ HANDLE_FDK_BITSTREAM hBitStream) {
+ INT i, sfb;
+ INT dbgVal = FDKgetValidBits(hBitStream);
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ if (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO) {
+ /* huffencode spectral data for this huffsection */
+ INT tmp = sectionData->huffsection[i].sfbStart +
+ sectionData->huffsection[i].sfbCnt;
+ for (sfb = sectionData->huffsection[i].sfbStart; sfb < tmp; sfb++) {
+ FDKaacEnc_codeValues(quantSpectrum + sfbOffset[sfb],
+ sfbOffset[sfb + 1] - sfbOffset[sfb],
+ sectionData->huffsection[i].codeBook, hBitStream);
+ }
+ }
+ }
+ return (FDKgetValidBits(hBitStream) - dbgVal);
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_encodeGlobalGain
+ description: encodes Global Gain (common scale factor)
+ returns: the number of static bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeGlobalGain(INT globalGain, INT scalefac,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ INT mdctScale) {
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream,
+ globalGain - scalefac + globalGainOffset -
+ 4 * (LOG_NORM_PCM - mdctScale),
+ 8);
+ }
+ return (8);
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_encodeIcsInfo
+ description: encodes Ics Info
+ returns: the number of static bits
+ input:
+ output:
+
+*****************************************************************************/
+
+static INT FDKaacEnc_encodeIcsInfo(INT blockType, INT windowShape,
+ INT groupingMask, INT maxSfbPerGroup,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ UINT syntaxFlags) {
+ INT statBits;
+
+ if (blockType == SHORT_WINDOW) {
+ statBits = 8 + TRANS_FAC - 1;
+ } else {
+ if (syntaxFlags & AC_ELD) {
+ statBits = 6;
+ } else {
+ statBits = (!(syntaxFlags & AC_SCALABLE)) ? 11 : 10;
+ }
+ }
+
+ if (hBitStream != NULL) {
+ if (!(syntaxFlags & AC_ELD)) {
+ FDKwriteBits(hBitStream, icsReservedBit, 1);
+ FDKwriteBits(hBitStream, blockType, 2);
+ FDKwriteBits(hBitStream,
+ (windowShape == LOL_WINDOW) ? KBD_WINDOW : windowShape, 1);
+ }
+
+ switch (blockType) {
+ case LONG_WINDOW:
+ case START_WINDOW:
+ case STOP_WINDOW:
+ FDKwriteBits(hBitStream, maxSfbPerGroup, 6);
+
+ if (!(syntaxFlags &
+ (AC_SCALABLE | AC_ELD))) { /* If not scalable syntax then ... */
+ /* No predictor data present */
+ FDKwriteBits(hBitStream, 0, 1);
+ }
+ break;
+
+ case SHORT_WINDOW:
+ FDKwriteBits(hBitStream, maxSfbPerGroup, 4);
+
+ /* Write grouping bits */
+ FDKwriteBits(hBitStream, groupingMask, TRANS_FAC - 1);
+ break;
+ }
+ }
+
+ return (statBits);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeSectionData
+ description: encode section data (common Huffman codebooks for adjacent
+ SFB's)
+ returns: none
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ UINT useVCB11) {
+ if (hBitStream != NULL) {
+ INT sectEscapeVal = 0, sectLenBits = 0;
+ INT sectLen;
+ INT i;
+ INT dbgVal = FDKgetValidBits(hBitStream);
+ INT sectCbBits = 4;
+
+ switch (sectionData->blockType) {
+ case LONG_WINDOW:
+ case START_WINDOW:
+ case STOP_WINDOW:
+ sectEscapeVal = SECT_ESC_VAL_LONG;
+ sectLenBits = SECT_BITS_LONG;
+ break;
+
+ case SHORT_WINDOW:
+ sectEscapeVal = SECT_ESC_VAL_SHORT;
+ sectLenBits = SECT_BITS_SHORT;
+ break;
+ }
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ INT codeBook = sectionData->huffsection[i].codeBook;
+
+ FDKwriteBits(hBitStream, codeBook, sectCbBits);
+
+ {
+ sectLen = sectionData->huffsection[i].sfbCnt;
+
+ while (sectLen >= sectEscapeVal) {
+ FDKwriteBits(hBitStream, sectEscapeVal, sectLenBits);
+ sectLen -= sectEscapeVal;
+ }
+ FDKwriteBits(hBitStream, sectLen, sectLenBits);
+ }
+ }
+ return (FDKgetValidBits(hBitStream) - dbgVal);
+ }
+ return (0);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeScaleFactorData
+ description: encode DPCM coded scale factors
+ returns: none
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb,
+ SECTION_DATA *sectionData,
+ INT *scalefac,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ INT *RESTRICT noiseNrg,
+ const INT *isScale, INT globalGain) {
+ if (hBitStream != NULL) {
+ INT i, j, lastValScf, deltaScf;
+ INT deltaPns;
+ INT lastValPns = 0;
+ INT noisePCMFlag = TRUE;
+ INT lastValIs;
+
+ INT dbgVal = FDKgetValidBits(hBitStream);
+
+ lastValScf = scalefac[sectionData->firstScf];
+ lastValPns = globalGain - scalefac[sectionData->firstScf] +
+ globalGainOffset - 4 * LOG_NORM_PCM - noiseOffset;
+ lastValIs = 0;
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) {
+ if ((sectionData->huffsection[i].codeBook ==
+ CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (sectionData->huffsection[i].codeBook ==
+ CODE_BOOK_IS_IN_PHASE_NO)) {
+ INT sfbStart = sectionData->huffsection[i].sfbStart;
+ INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
+ for (j = sfbStart; j < tmp; j++) {
+ INT deltaIs = isScale[j] - lastValIs;
+ lastValIs = isScale[j];
+ if (FDKaacEnc_codeScalefactorDelta(deltaIs, hBitStream)) {
+ return (1);
+ }
+ } /* sfb */
+ } else if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) {
+ INT sfbStart = sectionData->huffsection[i].sfbStart;
+ INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
+ for (j = sfbStart; j < tmp; j++) {
+ deltaPns = noiseNrg[j] - lastValPns;
+ lastValPns = noiseNrg[j];
+
+ if (noisePCMFlag) {
+ FDKwriteBits(hBitStream, deltaPns + (1 << (PNS_PCM_BITS - 1)),
+ PNS_PCM_BITS);
+ noisePCMFlag = FALSE;
+ } else {
+ if (FDKaacEnc_codeScalefactorDelta(deltaPns, hBitStream)) {
+ return (1);
+ }
+ }
+ } /* sfb */
+ } else {
+ INT tmp = sectionData->huffsection[i].sfbStart +
+ sectionData->huffsection[i].sfbCnt;
+ for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) {
+ /*
+ check if we can repeat the last value to save bits
+ */
+ if (maxValueInSfb[j] == 0)
+ deltaScf = 0;
+ else {
+ deltaScf = -(scalefac[j] - lastValScf);
+ lastValScf = scalefac[j];
+ }
+ if (FDKaacEnc_codeScalefactorDelta(deltaScf, hBitStream)) {
+ return (1);
+ }
+ } /* sfb */
+ } /* code scalefactor */
+ } /* sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO */
+ } /* section loop */
+
+ return (FDKgetValidBits(hBitStream) - dbgVal);
+ } /* if (hBitStream != NULL) */
+
+ return (0);
+}
+
+/*****************************************************************************
+
+ functionname:encodeMsInfo
+ description: encodes MS-Stereo Info
+ returns: the number of static bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeMSInfo(INT sfbCnt, INT grpSfb, INT maxSfb,
+ INT msDigest, INT *jsFlags,
+ HANDLE_FDK_BITSTREAM hBitStream) {
+ INT sfb, sfbOff, msBits = 0;
+
+ if (hBitStream != NULL) {
+ switch (msDigest) {
+ case MS_NONE:
+ FDKwriteBits(hBitStream, SI_MS_MASK_NONE, 2);
+ msBits += 2;
+ break;
+
+ case MS_ALL:
+ FDKwriteBits(hBitStream, SI_MS_MASK_ALL, 2);
+ msBits += 2;
+ break;
+
+ case MS_SOME:
+ FDKwriteBits(hBitStream, SI_MS_MASK_SOME, 2);
+ msBits += 2;
+ for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
+ for (sfb = 0; sfb < maxSfb; sfb++) {
+ if (jsFlags[sfbOff + sfb] & MS_ON) {
+ FDKwriteBits(hBitStream, 1, 1);
+ } else {
+ FDKwriteBits(hBitStream, 0, 1);
+ }
+ msBits += 1;
+ }
+ }
+ break;
+ }
+ } else {
+ msBits += 2;
+ if (msDigest == MS_SOME) {
+ for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
+ for (sfb = 0; sfb < maxSfb; sfb++) {
+ msBits += 1;
+ }
+ }
+ }
+ }
+ return (msBits);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeTnsDataPresent
+ description: encode TNS data (filter order, coeffs, ..)
+ returns: the number of static bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeTnsDataPresent(TNS_INFO *tnsInfo, INT blockType,
+ HANDLE_FDK_BITSTREAM hBitStream) {
+ if ((hBitStream != NULL) && (tnsInfo != NULL)) {
+ INT i, tnsPresent = 0;
+ INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1);
+
+ for (i = 0; i < numOfWindows; i++) {
+ if (tnsInfo->numOfFilters[i] != 0) {
+ tnsPresent = 1;
+ break;
+ }
+ }
+
+ if (tnsPresent == 0) {
+ FDKwriteBits(hBitStream, 0, 1);
+ } else {
+ FDKwriteBits(hBitStream, 1, 1);
+ }
+ }
+ return (1);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeTnsData
+ description: encode TNS data (filter order, coeffs, ..)
+ returns: the number of static bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo, INT blockType,
+ HANDLE_FDK_BITSTREAM hBitStream) {
+ INT tnsBits = 0;
+
+ if (tnsInfo != NULL) {
+ INT i, j, k;
+ INT tnsPresent = 0;
+ INT coefBits;
+ INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1);
+
+ for (i = 0; i < numOfWindows; i++) {
+ if (tnsInfo->numOfFilters[i] != 0) {
+ tnsPresent = 1;
+ }
+ }
+
+ if (hBitStream != NULL) {
+ if (tnsPresent == 1) { /* there is data to be written*/
+ for (i = 0; i < numOfWindows; i++) {
+ FDKwriteBits(hBitStream, tnsInfo->numOfFilters[i],
+ (blockType == SHORT_WINDOW ? 1 : 2));
+ tnsBits += (blockType == SHORT_WINDOW ? 1 : 2);
+ if (tnsInfo->numOfFilters[i]) {
+ FDKwriteBits(hBitStream, (tnsInfo->coefRes[i] == 4 ? 1 : 0), 1);
+ tnsBits += 1;
+ }
+ for (j = 0; j < tnsInfo->numOfFilters[i]; j++) {
+ FDKwriteBits(hBitStream, tnsInfo->length[i][j],
+ (blockType == SHORT_WINDOW ? 4 : 6));
+ tnsBits += (blockType == SHORT_WINDOW ? 4 : 6);
+ FDK_ASSERT(tnsInfo->order[i][j] <= 12);
+ FDKwriteBits(hBitStream, tnsInfo->order[i][j],
+ (blockType == SHORT_WINDOW ? 3 : 5));
+ tnsBits += (blockType == SHORT_WINDOW ? 3 : 5);
+ if (tnsInfo->order[i][j]) {
+ FDKwriteBits(hBitStream, tnsInfo->direction[i][j], 1);
+ tnsBits += 1; /*direction*/
+ if (tnsInfo->coefRes[i] == 4) {
+ coefBits = 3;
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ if (tnsInfo->coef[i][j][k] > 3 ||
+ tnsInfo->coef[i][j][k] < -4) {
+ coefBits = 4;
+ break;
+ }
+ }
+ } else {
+ coefBits = 2;
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ if (tnsInfo->coef[i][j][k] > 1 ||
+ tnsInfo->coef[i][j][k] < -2) {
+ coefBits = 3;
+ break;
+ }
+ }
+ }
+ FDKwriteBits(hBitStream, -(coefBits - tnsInfo->coefRes[i]),
+ 1); /*coef_compres*/
+ tnsBits += 1; /*coef_compression */
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ static const INT rmask[] = {0, 1, 3, 7, 15};
+ FDKwriteBits(hBitStream,
+ tnsInfo->coef[i][j][k] & rmask[coefBits],
+ coefBits);
+ tnsBits += coefBits;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if (tnsPresent != 0) {
+ for (i = 0; i < numOfWindows; i++) {
+ tnsBits += (blockType == SHORT_WINDOW ? 1 : 2);
+ if (tnsInfo->numOfFilters[i]) {
+ tnsBits += 1;
+ for (j = 0; j < tnsInfo->numOfFilters[i]; j++) {
+ tnsBits += (blockType == SHORT_WINDOW ? 4 : 6);
+ tnsBits += (blockType == SHORT_WINDOW ? 3 : 5);
+ if (tnsInfo->order[i][j]) {
+ tnsBits += 1; /*direction*/
+ tnsBits += 1; /*coef_compression */
+ if (tnsInfo->coefRes[i] == 4) {
+ coefBits = 3;
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ if (tnsInfo->coef[i][j][k] > 3 ||
+ tnsInfo->coef[i][j][k] < -4) {
+ coefBits = 4;
+ break;
+ }
+ }
+ } else {
+ coefBits = 2;
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ if (tnsInfo->coef[i][j][k] > 1 ||
+ tnsInfo->coef[i][j][k] < -2) {
+ coefBits = 3;
+ break;
+ }
+ }
+ }
+ for (k = 0; k < tnsInfo->order[i][j]; k++) {
+ tnsBits += coefBits;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } /* (tnsInfo!=NULL) */
+
+ return (tnsBits);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodeGainControlData
+ description: unsupported
+ returns: none
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream) {
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, 0, 1);
+ }
+ return (1);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_encodePulseData
+ description: not supported yet (dummy)
+ returns: none
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream) {
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, 0, 1);
+ }
+ return (1);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_writeExtensionPayload
+ description: write extension payload to bitstream
+ returns: number of written bits
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_writeExtensionPayload(HANDLE_FDK_BITSTREAM hBitStream,
+ EXT_PAYLOAD_TYPE extPayloadType,
+ const UCHAR *extPayloadData,
+ INT extPayloadBits) {
+#define EXT_TYPE_BITS (4)
+#define DATA_EL_VERSION_BITS (4)
+#define FILL_NIBBLE_BITS (4)
+
+ INT extBitsUsed = 0;
+
+ if (extPayloadBits >= EXT_TYPE_BITS) {
+ UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */
+
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS);
+ }
+ extBitsUsed += EXT_TYPE_BITS;
+
+ switch (extPayloadType) {
+ /* case EXT_SAC_DATA: */
+ case EXT_LDSAC_DATA:
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, *extPayloadData++, 4); /* nibble */
+ }
+ extBitsUsed += 4;
+ FDK_FALLTHROUGH;
+ case EXT_DYNAMIC_RANGE:
+ case EXT_SBR_DATA:
+ case EXT_SBR_DATA_CRC:
+ if (hBitStream != NULL) {
+ int i, writeBits = extPayloadBits;
+ for (i = 0; writeBits >= 8; i++) {
+ FDKwriteBits(hBitStream, *extPayloadData++, 8);
+ writeBits -= 8;
+ }
+ if (writeBits > 0) {
+ FDKwriteBits(hBitStream, (*extPayloadData) >> (8 - writeBits),
+ writeBits);
+ }
+ }
+ extBitsUsed += extPayloadBits;
+ break;
+
+ case EXT_DATA_ELEMENT: {
+ INT dataElementLength = (extPayloadBits + 7) >> 3;
+ INT cnt = dataElementLength;
+ int loopCounter = 1;
+
+ while (dataElementLength >= 255) {
+ loopCounter++;
+ dataElementLength -= 255;
+ }
+
+ if (hBitStream != NULL) {
+ int i;
+ FDKwriteBits(
+ hBitStream, 0x00,
+ DATA_EL_VERSION_BITS); /* data_element_version = ANC_DATA */
+
+ for (i = 1; i < loopCounter; i++) {
+ FDKwriteBits(hBitStream, 255, 8);
+ }
+ FDKwriteBits(hBitStream, dataElementLength, 8);
+
+ for (i = 0; i < cnt; i++) {
+ FDKwriteBits(hBitStream, extPayloadData[i], 8);
+ }
+ }
+ extBitsUsed += DATA_EL_VERSION_BITS + (loopCounter * 8) + (cnt * 8);
+ } break;
+
+ case EXT_FILL_DATA:
+ fillByte = 0xA5;
+ FDK_FALLTHROUGH;
+ case EXT_FIL:
+ default:
+ if (hBitStream != NULL) {
+ int writeBits = extPayloadBits;
+ FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS);
+ writeBits -=
+ 8; /* acount for the extension type and the fill nibble */
+ while (writeBits >= 8) {
+ FDKwriteBits(hBitStream, fillByte, 8);
+ writeBits -= 8;
+ }
+ }
+ extBitsUsed += FILL_NIBBLE_BITS + (extPayloadBits & ~0x7) - 8;
+ break;
+ }
+ }
+
+ return (extBitsUsed);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_writeDataStreamElement
+ description: write data stream elements like ancillary data ...
+ returns: the amount of used bits
+ input:
+ output:
+
+******************************************************************************/
+static INT FDKaacEnc_writeDataStreamElement(HANDLE_TRANSPORTENC hTpEnc,
+ INT elementInstanceTag,
+ INT dataPayloadBytes,
+ UCHAR *dataBuffer,
+ UINT alignAnchor) {
+#define DATA_BYTE_ALIGN_FLAG (0)
+
+#define EL_INSTANCE_TAG_BITS (4)
+#define DATA_BYTE_ALIGN_FLAG_BITS (1)
+#define DATA_LEN_COUNT_BITS (8)
+#define DATA_LEN_ESC_COUNT_BITS (8)
+
+#define MAX_DATA_ALIGN_BITS (7)
+#define MAX_DSE_DATA_BYTES (510)
+
+ INT dseBitsUsed = 0;
+
+ while (dataPayloadBytes > 0) {
+ int esc_count = -1;
+ int cnt = 0;
+ INT crcReg = -1;
+
+ dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS +
+ DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS;
+
+ if (DATA_BYTE_ALIGN_FLAG) {
+ dseBitsUsed += MAX_DATA_ALIGN_BITS;
+ }
+
+ cnt = fixMin(MAX_DSE_DATA_BYTES, dataPayloadBytes);
+ if (cnt >= 255) {
+ esc_count = cnt - 255;
+ dseBitsUsed += DATA_LEN_ESC_COUNT_BITS;
+ }
+
+ dataPayloadBytes -= cnt;
+ dseBitsUsed += cnt * 8;
+
+ if (hTpEnc != NULL) {
+ HANDLE_FDK_BITSTREAM hBitStream = transportEnc_GetBitstream(hTpEnc);
+ int i;
+
+ FDKwriteBits(hBitStream, ID_DSE, EL_ID_BITS);
+
+ crcReg = transportEnc_CrcStartReg(hTpEnc, 0);
+
+ FDKwriteBits(hBitStream, elementInstanceTag, EL_INSTANCE_TAG_BITS);
+ FDKwriteBits(hBitStream, DATA_BYTE_ALIGN_FLAG, DATA_BYTE_ALIGN_FLAG_BITS);
+
+ /* write length field(s) */
+ if (esc_count >= 0) {
+ FDKwriteBits(hBitStream, 255, DATA_LEN_COUNT_BITS);
+ FDKwriteBits(hBitStream, esc_count, DATA_LEN_ESC_COUNT_BITS);
+ } else {
+ FDKwriteBits(hBitStream, cnt, DATA_LEN_COUNT_BITS);
+ }
+
+ if (DATA_BYTE_ALIGN_FLAG) {
+ INT tmp = (INT)FDKgetValidBits(hBitStream);
+ FDKbyteAlign(hBitStream, alignAnchor);
+ /* count actual bits */
+ dseBitsUsed +=
+ (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS;
+ }
+
+ /* write payload */
+ for (i = 0; i < cnt; i++) {
+ FDKwriteBits(hBitStream, dataBuffer[i], 8);
+ }
+ transportEnc_CrcEndReg(hTpEnc, crcReg);
+ }
+ }
+
+ return (dseBitsUsed);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_writeExtensionData
+ description: write extension payload to bitstream
+ returns: number of written bits
+ input:
+ output:
+
+*****************************************************************************/
+INT FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc,
+ QC_OUT_EXTENSION *pExtension,
+ INT elInstanceTag, /* for DSE only */
+ UINT alignAnchor, /* for DSE only */
+ UINT syntaxFlags, AUDIO_OBJECT_TYPE aot,
+ SCHAR epConfig) {
+#define FILL_EL_COUNT_BITS (4)
+#define FILL_EL_ESC_COUNT_BITS (8)
+#define MAX_FILL_DATA_BYTES (269)
+
+ HANDLE_FDK_BITSTREAM hBitStream = NULL;
+ INT payloadBits = pExtension->nPayloadBits;
+ INT extBitsUsed = 0;
+
+ if (hTpEnc != NULL) {
+ hBitStream = transportEnc_GetBitstream(hTpEnc);
+ }
+
+ if (syntaxFlags & (AC_SCALABLE | AC_ER)) {
+ {
+ if ((syntaxFlags & AC_ELD) && ((pExtension->type == EXT_SBR_DATA) ||
+ (pExtension->type == EXT_SBR_DATA_CRC))) {
+ if (hBitStream != NULL) {
+ int i, writeBits = payloadBits;
+ UCHAR *extPayloadData = pExtension->pPayload;
+
+ for (i = 0; writeBits >= 8; i++) {
+ FDKwriteBits(hBitStream, extPayloadData[i], 8);
+ writeBits -= 8;
+ }
+ if (writeBits > 0) {
+ FDKwriteBits(hBitStream, extPayloadData[i] >> (8 - writeBits),
+ writeBits);
+ }
+ }
+ extBitsUsed += payloadBits;
+ } else {
+ /* ER or scalable syntax -> write extension en bloc */
+ extBitsUsed += FDKaacEnc_writeExtensionPayload(
+ hBitStream, pExtension->type, pExtension->pPayload, payloadBits);
+ }
+ }
+ } else {
+ /* We have normal GA bitstream payload (AOT 2,5,29) so pack
+ the data into a fill elements or DSEs */
+
+ if (pExtension->type == EXT_DATA_ELEMENT) {
+ extBitsUsed += FDKaacEnc_writeDataStreamElement(
+ hTpEnc, elInstanceTag, pExtension->nPayloadBits >> 3,
+ pExtension->pPayload, alignAnchor);
+ } else {
+ while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) {
+ INT cnt, esc_count = -1, alignBits = 7;
+
+ if ((pExtension->type == EXT_FILL_DATA) ||
+ (pExtension->type == EXT_FIL)) {
+ payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS;
+ if (payloadBits >= 15 * 8) {
+ payloadBits -= FILL_EL_ESC_COUNT_BITS;
+ esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */
+ }
+ alignBits = 0;
+ }
+
+ cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits + alignBits) >> 3);
+
+ if (cnt >= 15) {
+ esc_count = cnt - 15 + 1;
+ }
+
+ if (hBitStream != NULL) {
+ /* write bitstream */
+ FDKwriteBits(hBitStream, ID_FIL, EL_ID_BITS);
+ if (esc_count >= 0) {
+ FDKwriteBits(hBitStream, 15, FILL_EL_COUNT_BITS);
+ FDKwriteBits(hBitStream, esc_count, FILL_EL_ESC_COUNT_BITS);
+ } else {
+ FDKwriteBits(hBitStream, cnt, FILL_EL_COUNT_BITS);
+ }
+ }
+
+ extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS +
+ ((esc_count >= 0) ? FILL_EL_ESC_COUNT_BITS : 0);
+
+ cnt = fixMin(cnt * 8, payloadBits); /* convert back to bits */
+ extBitsUsed += FDKaacEnc_writeExtensionPayload(
+ hBitStream, pExtension->type, pExtension->pPayload, cnt);
+ payloadBits -= cnt;
+ }
+ }
+ }
+
+ return (extBitsUsed);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_ByteAlignment
+ description:
+ returns:
+ input:
+ output:
+
+*****************************************************************************/
+static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream,
+ int alignBits) {
+ FDKwriteBits(hBitStream, 0, alignBits);
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite(
+ HANDLE_TRANSPORTENC hTpEnc, ELEMENT_INFO *pElInfo,
+ QC_OUT_CHANNEL *qcOutChannel[(2)], PSY_OUT_ELEMENT *psyOutElement,
+ PSY_OUT_CHANNEL *psyOutChannel[(2)], UINT syntaxFlags,
+ AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt) {
+ AAC_ENCODER_ERROR error = AAC_ENC_OK;
+ HANDLE_FDK_BITSTREAM hBitStream = NULL;
+ INT bitDemand = 0;
+ const element_list_t *list;
+ int i, ch, decision_bit;
+ INT crcReg1 = -1, crcReg2 = -1;
+ UCHAR numberOfChannels;
+
+ if (hTpEnc != NULL) {
+ /* Get bitstream handle */
+ hBitStream = transportEnc_GetBitstream(hTpEnc);
+ }
+
+ if ((pElInfo->elType == ID_SCE) || (pElInfo->elType == ID_LFE)) {
+ numberOfChannels = 1;
+ } else {
+ numberOfChannels = 2;
+ }
+
+ /* Get channel element sequence table */
+ list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, 0);
+ if (list == NULL) {
+ error = AAC_ENC_UNSUPPORTED_AOT;
+ goto bail;
+ }
+
+ if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) {
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, pElInfo->elType, EL_ID_BITS);
+ }
+ bitDemand += EL_ID_BITS;
+ }
+
+ /* Iterate through sequence table */
+ i = 0;
+ ch = 0;
+ decision_bit = 0;
+ do {
+ /* some tmp values */
+ SECTION_DATA *pChSectionData = NULL;
+ INT *pChScf = NULL;
+ UINT *pChMaxValueInSfb = NULL;
+ TNS_INFO *pTnsInfo = NULL;
+ INT chGlobalGain = 0;
+ INT chBlockType = 0;
+ INT chMaxSfbPerGrp = 0;
+ INT chSfbPerGrp = 0;
+ INT chSfbCnt = 0;
+ INT chFirstScf = 0;
+
+ if (minCnt == 0) {
+ if (qcOutChannel != NULL) {
+ pChSectionData = &(qcOutChannel[ch]->sectionData);
+ pChScf = qcOutChannel[ch]->scf;
+ chGlobalGain = qcOutChannel[ch]->globalGain;
+ pChMaxValueInSfb = qcOutChannel[ch]->maxValueInSfb;
+ chBlockType = pChSectionData->blockType;
+ chMaxSfbPerGrp = pChSectionData->maxSfbPerGroup;
+ chSfbPerGrp = pChSectionData->sfbPerGroup;
+ chSfbCnt = pChSectionData->sfbCnt;
+ chFirstScf = pChScf[pChSectionData->firstScf];
+ } else {
+ /* get values from PSY */
+ chSfbCnt = psyOutChannel[ch]->sfbCnt;
+ chSfbPerGrp = psyOutChannel[ch]->sfbPerGroup;
+ chMaxSfbPerGrp = psyOutChannel[ch]->maxSfbPerGroup;
+ }
+ pTnsInfo = &psyOutChannel[ch]->tnsInfo;
+ } /* minCnt==0 */
+
+ if (qcOutChannel == NULL) {
+ chBlockType = psyOutChannel[ch]->lastWindowSequence;
+ }
+
+ switch (list->id[i]) {
+ case element_instance_tag:
+ /* Write element instance tag */
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, pElInfo->instanceTag, 4);
+ }
+ bitDemand += 4;
+ break;
+
+ case common_window:
+ /* Write common window flag */
+ decision_bit = psyOutElement->commonWindow;
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1);
+ }
+ bitDemand += 1;
+ break;
+
+ case ics_info:
+ /* Write individual channel info */
+ bitDemand +=
+ FDKaacEnc_encodeIcsInfo(chBlockType, psyOutChannel[ch]->windowShape,
+ psyOutChannel[ch]->groupingMask,
+ chMaxSfbPerGrp, hBitStream, syntaxFlags);
+ break;
+
+ case ltp_data_present:
+ /* Write LTP data present flag */
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, 0, 1);
+ }
+ bitDemand += 1;
+ break;
+
+ case ltp_data:
+ /* Predictor data not supported.
+ Nothing to do here. */
+ break;
+
+ case ms:
+ /* Write MS info */
+ bitDemand += FDKaacEnc_encodeMSInfo(
+ chSfbCnt, chSfbPerGrp, chMaxSfbPerGrp,
+ (minCnt == 0) ? psyOutElement->toolsInfo.msDigest : MS_NONE,
+ psyOutElement->toolsInfo.msMask, hBitStream);
+ break;
+
+ case global_gain:
+ bitDemand += FDKaacEnc_encodeGlobalGain(
+ chGlobalGain, chFirstScf, hBitStream, psyOutChannel[ch]->mdctScale);
+ break;
+
+ case section_data: {
+ INT siBits = FDKaacEnc_encodeSectionData(
+ pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11) ? 1 : 0);
+ if (hBitStream != NULL) {
+ if (siBits != qcOutChannel[ch]->sectionData.sideInfoBits) {
+ error = AAC_ENC_WRITE_SEC_ERROR;
+ }
+ }
+ bitDemand += siBits;
+ } break;
+
+ case scale_factor_data: {
+ INT sfDataBits = FDKaacEnc_encodeScaleFactorData(
+ pChMaxValueInSfb, pChSectionData, pChScf, hBitStream,
+ psyOutChannel[ch]->noiseNrg, psyOutChannel[ch]->isScale,
+ chGlobalGain);
+ if ((hBitStream != NULL) &&
+ (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits +
+ qcOutChannel[ch]->sectionData.noiseNrgBits))) {
+ error = AAC_ENC_WRITE_SCAL_ERROR;
+ }
+ bitDemand += sfDataBits;
+ } break;
+
+ case esc2_rvlc:
+ if (syntaxFlags & AC_ER_RVLC) {
+ /* write RVLC data into bitstream (error sens. cat. 2) */
+ error = AAC_ENC_UNSUPPORTED_AOT;
+ }
+ break;
+
+ case pulse:
+ /* Write pulse data */
+ bitDemand += FDKaacEnc_encodePulseData(hBitStream);
+ break;
+
+ case tns_data_present:
+ /* Write TNS data present flag */
+ bitDemand +=
+ FDKaacEnc_encodeTnsDataPresent(pTnsInfo, chBlockType, hBitStream);
+ break;
+ case tns_data:
+ /* Write TNS data */
+ bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo, chBlockType, hBitStream);
+ break;
+
+ case gain_control_data:
+ /* Nothing to do here */
+ break;
+
+ case gain_control_data_present:
+ bitDemand += FDKaacEnc_encodeGainControlData(hBitStream);
+ break;
+
+ case esc1_hcr:
+ if (syntaxFlags & AC_ER_HCR) {
+ error = AAC_ENC_UNKNOWN;
+ }
+ break;
+
+ case spectral_data:
+ if (hBitStream != NULL) {
+ INT spectralBits = 0;
+
+ spectralBits = FDKaacEnc_encodeSpectralData(
+ psyOutChannel[ch]->sfbOffsets, pChSectionData,
+ qcOutChannel[ch]->quantSpec, hBitStream);
+
+ if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) {
+ return AAC_ENC_WRITE_SPEC_ERROR;
+ }
+ bitDemand += spectralBits;
+ }
+ break;
+
+ /* Non data cases */
+ case adtscrc_start_reg1:
+ if (hTpEnc != NULL) {
+ crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192);
+ }
+ break;
+ case adtscrc_start_reg2:
+ if (hTpEnc != NULL) {
+ crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128);
+ }
+ break;
+ case adtscrc_end_reg1:
+ case drmcrc_end_reg:
+ if (hTpEnc != NULL) {
+ transportEnc_CrcEndReg(hTpEnc, crcReg1);
+ }
+ break;
+ case adtscrc_end_reg2:
+ if (hTpEnc != NULL) {
+ transportEnc_CrcEndReg(hTpEnc, crcReg2);
+ }
+ break;
+ case drmcrc_start_reg:
+ if (hTpEnc != NULL) {
+ crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0);
+ }
+ break;
+ case next_channel:
+ ch = (ch + 1) % numberOfChannels;
+ break;
+ case link_sequence:
+ list = list->next[decision_bit];
+ i = -1;
+ break;
+
+ default:
+ error = AAC_ENC_UNKNOWN;
+ break;
+ }
+
+ if (error != AAC_ENC_OK) {
+ return error;
+ }
+
+ i++;
+
+ } while (list->id[i] != end_of_sequence);
+
+bail:
+ if (pBitDemand != NULL) {
+ *pBitDemand = bitDemand;
+ }
+
+ return error;
+}
+
+//-----------------------------------------------------------------------------------------------
+
+AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
+ CHANNEL_MAPPING *channelMapping,
+ QC_OUT *qcOut, PSY_OUT *psyOut,
+ QC_STATE *qcKernel,
+ AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig) {
+ HANDLE_FDK_BITSTREAM hBs = transportEnc_GetBitstream(hTpEnc);
+ AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
+ int i, n, doByteAlign = 1;
+ INT bitMarkUp;
+ INT frameBits;
+ /* Get first bit of raw data block.
+ In case of ADTS+PCE, AU would start at PCE.
+ This is okay because PCE assures alignment. */
+ UINT alignAnchor = FDKgetValidBits(hBs);
+
+ frameBits = bitMarkUp = alignAnchor;
+
+
+ /* Write DSEs first in case of DAB */
+ for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++) {
+ if ( (syntaxFlags & AC_DAB) &&
+ (qcOut->extension[n].type == EXT_DATA_ELEMENT) ) {
+ FDKaacEnc_writeExtensionData( hTpEnc,
+ &qcOut->extension[n],
+ 0,
+ alignAnchor,
+ syntaxFlags,
+ aot,
+ epConfig );
+ }
+
+ /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here */
+ }
+
+ /* Channel element loop */
+ for (i = 0; i < channelMapping->nElements; i++) {
+ ELEMENT_INFO elInfo = channelMapping->elInfo[i];
+ INT elementUsedBits = 0;
+
+ switch (elInfo.elType) {
+ case ID_SCE: /* single channel */
+ case ID_CPE: /* channel pair */
+ case ID_LFE: /* low freq effects channel */
+ {
+ if (AAC_ENC_OK !=
+ (ErrorStatus = FDKaacEnc_ChannelElementWrite(
+ hTpEnc, &elInfo, qcOut->qcElement[i]->qcOutChannel,
+ psyOut->psyOutElement[i],
+ psyOut->psyOutElement[i]->psyOutChannel,
+ syntaxFlags, /* syntaxFlags (ER tools ...) */
+ aot, /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */
+ epConfig, /* epConfig -1, 0, 1 */
+ NULL, 0))) {
+ return ErrorStatus;
+ }
+
+ if (!(syntaxFlags & AC_ER)) {
+ /* Write associated extension payload */
+ for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
+ FDKaacEnc_writeExtensionData(
+ hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
+ syntaxFlags, aot, epConfig);
+ }
+ }
+ } break;
+
+ /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */
+ default:
+ return AAC_ENC_INVALID_ELEMENTINFO_TYPE;
+
+ } /* switch */
+
+ if (elInfo.elType != ID_DSE) {
+ elementUsedBits -= bitMarkUp;
+ bitMarkUp = FDKgetValidBits(hBs);
+ elementUsedBits += bitMarkUp;
+ frameBits += elementUsedBits;
+ }
+
+ } /* for (i=0; i<channelMapping.nElements; i++) */
+
+ if ((syntaxFlags & AC_ER) && !(syntaxFlags & AC_DRM)) {
+ UCHAR channelElementExtensionWritten[((8))][(
+ 1)]; /* 0: extension not touched, 1: extension already written */
+
+ FDKmemclear(channelElementExtensionWritten,
+ sizeof(channelElementExtensionWritten));
+
+ if (syntaxFlags & AC_ELD) {
+ for (i = 0; i < channelMapping->nElements; i++) {
+ for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
+ if ((qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA) ||
+ (qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA_CRC)) {
+ /* Write sbr extension payload */
+ FDKaacEnc_writeExtensionData(
+ hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
+ syntaxFlags, aot, epConfig);
+
+ channelElementExtensionWritten[i][n] = 1;
+ } /* SBR */
+ } /* n */
+ } /* i */
+ } /* AC_ELD */
+
+ for (i = 0; i < channelMapping->nElements; i++) {
+ for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
+ if (channelElementExtensionWritten[i][n] == 0) {
+ /* Write all ramaining extension payloads in element */
+ FDKaacEnc_writeExtensionData(hTpEnc,
+ &qcOut->qcElement[i]->extension[n], 0,
+ alignAnchor, syntaxFlags, aot, epConfig);
+ }
+ } /* n */
+ } /* i */
+ } /* if AC_ER */
+
+ /* Extend global extension payload table with fill bits */
+ n = qcOut->nExtensions;
+
+ /* Add fill data / stuffing bits */
+ n = qcOut->nExtensions;
+
+// if (!(syntaxFlags & AC_DAB)) {
+ qcOut->extension[n].type = EXT_FILL_DATA;
+ qcOut->extension[n].nPayloadBits = qcOut->totFillBits;
+ qcOut->nExtensions++;
+// } else {
+// doByteAlign = 0;
+// }
+ if (syntaxFlags & AC_DAB)
+ doByteAlign = 0;
+
+ /* Write global extension payload and fill data */
+ for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++)
+ {
+ if ( !(syntaxFlags & AC_DAB) ||
+ ( (syntaxFlags & AC_DAB) &&
+ (qcOut->extension[n].type != EXT_DATA_ELEMENT)
+ )
+ ) {
+ FDKaacEnc_writeExtensionData( hTpEnc,
+ &qcOut->extension[n],
+ 0,
+ alignAnchor,
+ syntaxFlags,
+ aot,
+ epConfig );
+ }
+
+ /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here
+ */
+ }
+
+ if (!(syntaxFlags & (AC_SCALABLE | AC_ER | AC_DAB))) {
+ FDKwriteBits(hBs, ID_END, EL_ID_BITS);
+ }
+
+ if (doByteAlign) {
+ /* Assure byte alignment*/
+ if (((FDKgetValidBits(hBs) - alignAnchor + qcOut->alignBits) & 0x7) != 0) {
+ return AAC_ENC_WRITTEN_BITS_ERROR;
+ }
+
+ FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits);
+ }
+
+ frameBits -= bitMarkUp;
+ frameBits += FDKgetValidBits(hBs);
+
+ transportEnc_EndAccessUnit(hTpEnc, &frameBits);
+
+ if (frameBits != qcOut->totalBits + qcKernel->globHdrBits){
+ fprintf(stderr, "frameBits != qcOut->totalBits + qcKernel->globHdrBits: %d != %d + %d", frameBits, qcOut->totalBits, qcKernel->globHdrBits);
+ return AAC_ENC_WRITTEN_BITS_ERROR;
+ }
+
+ //fprintf(stderr, "ErrorStatus=%d", ErrorStatus);
+ return ErrorStatus;
+}
diff --git a/fdk-aac/libAACenc/src/bitenc.h b/fdk-aac/libAACenc/src/bitenc.h
new file mode 100644
index 0000000..75dc068
--- /dev/null
+++ b/fdk-aac/libAACenc/src/bitenc.h
@@ -0,0 +1,184 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Bitstream encoder
+
+*******************************************************************************/
+
+#ifndef BITENC_H
+#define BITENC_H
+
+#include "qc_data.h"
+#include "aacenc_tns.h"
+#include "channel_map.h"
+#include "interface.h" /* obsolete, when PSY_OUT is thrown out of the WritBS-call! */
+#include "FDK_audio.h"
+#include "aacenc.h"
+
+#include "tpenc_lib.h"
+
+typedef enum {
+ MAX_ENCODER_CHANNELS = 9,
+ MAX_BLOCK_TYPES = 4,
+ MAX_AAC_LAYERS = 9,
+ MAX_LAYERS = MAX_AAC_LAYERS, /* only one core layer if present */
+ FIRST_LAY = 1 /* default layer number for AAC nonscalable */
+} _MAX_CONST;
+
+#define BUFFER_MX_HUFFCB_SIZE \
+ (32 * sizeof(INT)) /* our FDK_bitbuffer needs size of power 2 */
+
+#define EL_ID_BITS (3)
+
+/**
+ * \brief Arbitrary order bitstream writer. This function can either assemble a
+ * bit stream and write into the bit buffer of hTpEnc or calculate the number of
+ * static bits (signal independent) TpEnc handle must be NULL in this
+ * case. Or also Calculate the minimum possible number of static bits
+ * which by disabling all tools e.g. MS, TNS and sbfCnt=0. The minCnt
+ * parameter has to be 1 in this latter case.
+ * \param hTpEnc Transport encoder handle. If NULL, the number of static bits
+ * will be returned into *pBitDemand.
+ * \param pElInfo
+ * \param qcOutChannel
+ * \param hReorderInfo
+ * \param psyOutElement
+ * \param psyOutChannel
+ * \param syntaxFlags Bit stream syntax flags as defined in FDK_audio.h (Audio
+ * Codec flags).
+ * \param aot
+ * \param epConfig
+ * \param pBitDemand Pointer to an int where the amount of bits is returned
+ * into. The returned value depends on if hTpEnc is NULL and minCnt.
+ * \param minCnt If non-zero the value returned into *pBitDemand is the absolute
+ * minimum required amount of static bits in order to write a valid bit stream.
+ * \return AAC_ENCODER_ERROR error code
+ */
+AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite(
+ HANDLE_TRANSPORTENC hTpEnc, ELEMENT_INFO *pElInfo,
+ QC_OUT_CHANNEL *qcOutChannel[(2)], PSY_OUT_ELEMENT *psyOutElement,
+ PSY_OUT_CHANNEL *psyOutChannel[(2)], UINT syntaxFlags,
+ AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt);
+/**
+ * \brief Write bit stream or account static bits
+ * \param hTpEnc transport encoder handle. If NULL, the function will
+ * not write any bit stream data but only count the amount
+ * of static (signal independent) bits
+ * \param channelMapping Channel mapping info
+ * \param qcOut
+ * \param psyOut
+ * \param qcKernel
+ * \param hBSE
+ * \param aot Audio Object Type being encoded
+ * \param syntaxFlags Flags indicating format specific detail
+ * \param epConfig Error protection config
+ */
+AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
+ CHANNEL_MAPPING *channelMapping,
+ QC_OUT *qcOut, PSY_OUT *psyOut,
+ QC_STATE *qcKernel,
+ AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig);
+
+INT FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc,
+ QC_OUT_EXTENSION *pExtension,
+ INT elInstanceTag, UINT alignAnchor,
+ UINT syntaxFlags, AUDIO_OBJECT_TYPE aot,
+ SCHAR epConfig);
+
+#endif /* BITENC_H */
diff --git a/fdk-aac/libAACenc/src/block_switch.cpp b/fdk-aac/libAACenc/src/block_switch.cpp
new file mode 100644
index 0000000..c132253
--- /dev/null
+++ b/fdk-aac/libAACenc/src/block_switch.cpp
@@ -0,0 +1,582 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner, Tobias Chalupka
+
+ Description: Block switching
+
+*******************************************************************************/
+
+/****************** Includes *****************************/
+
+#include "block_switch.h"
+#include "genericStds.h"
+
+#define LOWOV_WINDOW _LOWOV_WINDOW
+
+/**************** internal function prototypes ***********/
+
+static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[],
+ const INT blSwWndIdx);
+
+static void FDKaacEnc_CalcWindowEnergy(
+ BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, INT windowLen,
+ const INT_PCM *pTimeSignal);
+
+/****************** Constants *****************************/
+/* LONG START
+ * SHORT STOP LOWOV */
+static const INT blockType2windowShape[2][5] = {
+ {SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW, SINE_WINDOW, KBD_WINDOW}, /* LD */
+ {KBD_WINDOW, SINE_WINDOW, SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW}}; /* LC */
+
+/* IIR high pass coeffs */
+
+#ifndef SINETABLE_16BIT
+
+static const FIXP_DBL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = {
+ FL2FXCONST_DBL(-0.5095), FL2FXCONST_DBL(0.7548)};
+
+static const FIXP_DBL accWindowNrgFac =
+ FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */
+static const FIXP_DBL oneMinusAccWindowNrgFac = FL2FXCONST_DBL(0.7f);
+/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */
+static const FIXP_DBL invAttackRatio =
+ FL2FXCONST_DBL(0.1f); /* inverted lower ratio limit for attacks */
+
+/* The next constants are scaled, because they are used for comparison with
+ * scaled values*/
+/* minimum energy for attacks */
+static const FIXP_DBL minAttackNrg =
+ (FL2FXCONST_DBL(1e+6f * NORM_PCM_ENERGY) >>
+ BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */
+
+#else
+
+static const FIXP_SGL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = {
+ FL2FXCONST_SGL(-0.5095), FL2FXCONST_SGL(0.7548)};
+
+static const FIXP_DBL accWindowNrgFac =
+ FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */
+static const FIXP_SGL oneMinusAccWindowNrgFac = FL2FXCONST_SGL(0.7f);
+/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */
+static const FIXP_SGL invAttackRatio =
+ FL2FXCONST_SGL(0.1f); /* inverted lower ratio limit for attacks */
+/* minimum energy for attacks */
+static const FIXP_DBL minAttackNrg =
+ (FL2FXCONST_DBL(1e+6f * NORM_PCM_ENERGY) >>
+ BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */
+
+#endif
+
+/**************** internal function prototypes ***********/
+
+/****************** Routines ****************************/
+void FDKaacEnc_InitBlockSwitching(
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay) {
+ FDKmemclear(blockSwitchingControl, sizeof(BLOCK_SWITCHING_CONTROL));
+
+ if (isLowDelay) {
+ blockSwitchingControl->nBlockSwitchWindows = 4;
+ blockSwitchingControl->allowShortFrames = 0;
+ blockSwitchingControl->allowLookAhead = 0;
+ } else {
+ blockSwitchingControl->nBlockSwitchWindows = 8;
+ blockSwitchingControl->allowShortFrames = 1;
+ blockSwitchingControl->allowLookAhead = 1;
+ }
+
+ blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS;
+
+ /* Initialize startvalue for blocktype */
+ blockSwitchingControl->lastWindowSequence = LONG_WINDOW;
+ blockSwitchingControl->windowShape =
+ blockType2windowShape[blockSwitchingControl->allowShortFrames]
+ [blockSwitchingControl->lastWindowSequence];
+}
+
+static const INT suggestedGroupingTable[TRANS_FAC][MAX_NO_OF_GROUPS] = {
+ /* Attack in Window 0 */ {1, 3, 3, 1},
+ /* Attack in Window 1 */ {1, 1, 3, 3},
+ /* Attack in Window 2 */ {2, 1, 3, 2},
+ /* Attack in Window 3 */ {3, 1, 3, 1},
+ /* Attack in Window 4 */ {3, 1, 1, 3},
+ /* Attack in Window 5 */ {3, 2, 1, 2},
+ /* Attack in Window 6 */ {3, 3, 1, 1},
+ /* Attack in Window 7 */ {3, 3, 1, 1}};
+
+/* change block type depending on current blocktype and whether there's an
+ * attack */
+/* assume no look-ahead */
+static const INT chgWndSq[2][N_BLOCKTYPES] = {
+ /* LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW,
+ LOWOV_WINDOW, WRONG_WINDOW */
+ /*no attack*/ {LONG_WINDOW, STOP_WINDOW, WRONG_WINDOW, LONG_WINDOW,
+ STOP_WINDOW, WRONG_WINDOW},
+ /*attack */ {START_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, START_WINDOW,
+ LOWOV_WINDOW, WRONG_WINDOW}};
+
+/* change block type depending on current blocktype and whether there's an
+ * attack */
+/* assume look-ahead */
+static const INT chgWndSqLkAhd[2][2][N_BLOCKTYPES] = {
+ /*attack LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW LOWOV_WINDOW, WRONG_WINDOW */ /* last attack */
+ /*no attack*/ {
+ {LONG_WINDOW, SHORT_WINDOW, STOP_WINDOW, LONG_WINDOW, WRONG_WINDOW,
+ WRONG_WINDOW}, /* no attack */
+ /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, START_WINDOW,
+ WRONG_WINDOW, WRONG_WINDOW}}, /* no attack */
+ /*no attack*/ {{LONG_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LONG_WINDOW,
+ WRONG_WINDOW, WRONG_WINDOW}, /* attack */
+ /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW,
+ START_WINDOW, WRONG_WINDOW,
+ WRONG_WINDOW}} /* attack */
+};
+
+int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
+ const INT granuleLength, const int isLFE,
+ const INT_PCM *pTimeSignal) {
+ UINT i;
+ FIXP_DBL enM1, enMax;
+
+ UINT nBlockSwitchWindows = blockSwitchingControl->nBlockSwitchWindows;
+
+ /* for LFE : only LONG window allowed */
+ if (isLFE) {
+ /* case LFE: */
+ /* only long blocks, always use sine windows (MPEG2 AAC, MPEG4 AAC) */
+ blockSwitchingControl->lastWindowSequence = LONG_WINDOW;
+ blockSwitchingControl->windowShape = SINE_WINDOW;
+ blockSwitchingControl->noOfGroups = 1;
+ blockSwitchingControl->groupLen[0] = 1;
+
+ return (0);
+ };
+
+ /* Save current attack index as last attack index */
+ blockSwitchingControl->lastattack = blockSwitchingControl->attack;
+ blockSwitchingControl->lastAttackIndex = blockSwitchingControl->attackIndex;
+
+ /* Save current window energy as last window energy */
+ FDKmemcpy(blockSwitchingControl->windowNrg[0],
+ blockSwitchingControl->windowNrg[1],
+ sizeof(blockSwitchingControl->windowNrg[0]));
+ FDKmemcpy(blockSwitchingControl->windowNrgF[0],
+ blockSwitchingControl->windowNrgF[1],
+ sizeof(blockSwitchingControl->windowNrgF[0]));
+
+ if (blockSwitchingControl->allowShortFrames) {
+ /* Calculate suggested grouping info for the last frame */
+
+ /* Reset grouping info */
+ FDKmemclear(blockSwitchingControl->groupLen,
+ sizeof(blockSwitchingControl->groupLen));
+
+ /* Set grouping info */
+ blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS;
+
+ FDKmemcpy(blockSwitchingControl->groupLen,
+ suggestedGroupingTable[blockSwitchingControl->lastAttackIndex],
+ sizeof(blockSwitchingControl->groupLen));
+
+ if (blockSwitchingControl->attack == TRUE)
+ blockSwitchingControl->maxWindowNrg =
+ FDKaacEnc_GetWindowEnergy(blockSwitchingControl->windowNrg[0],
+ blockSwitchingControl->lastAttackIndex);
+ else
+ blockSwitchingControl->maxWindowNrg = FL2FXCONST_DBL(0.0);
+ }
+
+ /* Calculate unfiltered and filtered energies in subwindows and combine to
+ * segments */
+ FDKaacEnc_CalcWindowEnergy(
+ blockSwitchingControl,
+ granuleLength >> (nBlockSwitchWindows == 4 ? 2 : 3), pTimeSignal);
+
+ /* now calculate if there is an attack */
+
+ /* reset attack */
+ blockSwitchingControl->attack = FALSE;
+
+ /* look for attack */
+ enMax = FL2FXCONST_DBL(0.0f);
+ enM1 = blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows - 1];
+
+ for (i = 0; i < nBlockSwitchWindows; i++) {
+ FIXP_DBL tmp =
+ fMultDiv2(oneMinusAccWindowNrgFac, blockSwitchingControl->accWindowNrg);
+ blockSwitchingControl->accWindowNrg = fMultAdd(tmp, accWindowNrgFac, enM1);
+
+ if (fMult(blockSwitchingControl->windowNrgF[1][i], invAttackRatio) >
+ blockSwitchingControl->accWindowNrg) {
+ blockSwitchingControl->attack = TRUE;
+ blockSwitchingControl->attackIndex = i;
+ }
+ enM1 = blockSwitchingControl->windowNrgF[1][i];
+ enMax = fixMax(enMax, enM1);
+ }
+
+ if (enMax < minAttackNrg) blockSwitchingControl->attack = FALSE;
+
+ /* Check if attack spreads over frame border */
+ if ((blockSwitchingControl->attack == FALSE) &&
+ (blockSwitchingControl->lastattack == TRUE)) {
+ /* if attack is in last window repeat SHORT_WINDOW */
+ if (((blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows - 1] >> 4) >
+ fMult((FIXP_DBL)(10 << (DFRACT_BITS - 1 - 4)),
+ blockSwitchingControl->windowNrgF[1][1])) &&
+ (blockSwitchingControl->lastAttackIndex ==
+ (INT)nBlockSwitchWindows - 1)) {
+ blockSwitchingControl->attack = TRUE;
+ blockSwitchingControl->attackIndex = 0;
+ }
+ }
+
+ if (blockSwitchingControl->allowLookAhead) {
+ blockSwitchingControl->lastWindowSequence =
+ chgWndSqLkAhd[blockSwitchingControl->lastattack]
+ [blockSwitchingControl->attack]
+ [blockSwitchingControl->lastWindowSequence];
+ } else {
+ /* Low Delay */
+ blockSwitchingControl->lastWindowSequence =
+ chgWndSq[blockSwitchingControl->attack]
+ [blockSwitchingControl->lastWindowSequence];
+ }
+
+ /* update window shape */
+ blockSwitchingControl->windowShape =
+ blockType2windowShape[blockSwitchingControl->allowShortFrames]
+ [blockSwitchingControl->lastWindowSequence];
+
+ return (0);
+}
+
+static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[],
+ const INT blSwWndIdx) {
+ /* For coherency, change FDKaacEnc_GetWindowEnergy() to calcluate the energy
+ for a block switching analysis windows, not for a short block. The same is
+ done FDKaacEnc_CalcWindowEnergy(). The result of
+ FDKaacEnc_GetWindowEnergy() is used for a comparision of the max energy of
+ left/right channel. */
+
+ return in[blSwWndIdx];
+}
+
+static void FDKaacEnc_CalcWindowEnergy(
+ BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, INT windowLen,
+ const INT_PCM *pTimeSignal) {
+ INT i;
+ UINT w;
+
+#ifndef SINETABLE_16BIT
+ const FIXP_DBL hiPassCoeff0 = hiPassCoeff[0];
+ const FIXP_DBL hiPassCoeff1 = hiPassCoeff[1];
+#else
+ const FIXP_SGL hiPassCoeff0 = hiPassCoeff[0];
+ const FIXP_SGL hiPassCoeff1 = hiPassCoeff[1];
+#endif
+
+ FIXP_DBL temp_iirState0 = blockSwitchingControl->iirStates[0];
+ FIXP_DBL temp_iirState1 = blockSwitchingControl->iirStates[1];
+
+ /* sum up scalarproduct of timesignal as windowed Energies */
+ for (w = 0; w < blockSwitchingControl->nBlockSwitchWindows; w++) {
+ ULONG temp_windowNrg = 0x0;
+ ULONG temp_windowNrgF = 0x0;
+
+ /* windowNrg = sum(timesample^2) */
+ for (i = 0; i < windowLen; i++) {
+ FIXP_DBL tempUnfiltered, t1, t2;
+ /* tempUnfiltered is scaled with 1 to prevent overflows during calculation
+ * of tempFiltred */
+#if SAMPLE_BITS == DFRACT_BITS
+ tempUnfiltered = (FIXP_DBL)*pTimeSignal++ >> 1;
+#else
+ tempUnfiltered = (FIXP_DBL)*pTimeSignal++
+ << (DFRACT_BITS - SAMPLE_BITS - 1);
+#endif
+ t1 = fMultDiv2(hiPassCoeff1, tempUnfiltered - temp_iirState0);
+ t2 = fMultDiv2(hiPassCoeff0, temp_iirState1);
+ temp_iirState0 = tempUnfiltered;
+ temp_iirState1 = (t1 - t2) << 1;
+
+ temp_windowNrg += (LONG)fPow2Div2(temp_iirState0) >>
+ (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2);
+ temp_windowNrgF += (LONG)fPow2Div2(temp_iirState1) >>
+ (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2);
+ }
+ blockSwitchingControl->windowNrg[1][w] =
+ (LONG)fMin(temp_windowNrg, (UINT)MAXVAL_DBL);
+ blockSwitchingControl->windowNrgF[1][w] =
+ (LONG)fMin(temp_windowNrgF, (UINT)MAXVAL_DBL);
+ }
+ blockSwitchingControl->iirStates[0] = temp_iirState0;
+ blockSwitchingControl->iirStates[1] = temp_iirState1;
+}
+
+static const UCHAR synchronizedBlockTypeTable[5][5] = {
+ /* LONG_WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW
+ LOWOV_WINDOW*/
+ /* LONG_WINDOW */ {LONG_WINDOW, START_WINDOW, SHORT_WINDOW, STOP_WINDOW,
+ LOWOV_WINDOW},
+ /* START_WINDOW */
+ {START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LOWOV_WINDOW},
+ /* SHORT_WINDOW */
+ {SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, WRONG_WINDOW},
+ /* STOP_WINDOW */
+ {STOP_WINDOW, SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW, LOWOV_WINDOW},
+ /* LOWOV_WINDOW */
+ {LOWOV_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, LOWOV_WINDOW, LOWOV_WINDOW},
+};
+
+int FDKaacEnc_SyncBlockSwitching(
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft,
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, const INT nChannels,
+ const INT commonWindow) {
+ UCHAR patchType = LONG_WINDOW;
+
+ if (nChannels == 2 && commonWindow == TRUE) {
+ /* could be better with a channel loop (need a handle to psy_data) */
+ /* get suggested Block Types and synchronize */
+ patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft
+ ->lastWindowSequence];
+ patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight
+ ->lastWindowSequence];
+
+ /* sanity check (no change from low overlap window to short winow and vice
+ * versa) */
+ if (patchType == WRONG_WINDOW) return -1; /* mixed up AAC-LC and AAC-LD */
+
+ /* Set synchronized Blocktype */
+ blockSwitchingControlLeft->lastWindowSequence = patchType;
+ blockSwitchingControlRight->lastWindowSequence = patchType;
+
+ /* update window shape */
+ blockSwitchingControlLeft->windowShape =
+ blockType2windowShape[blockSwitchingControlLeft->allowShortFrames]
+ [blockSwitchingControlLeft->lastWindowSequence];
+ blockSwitchingControlRight->windowShape =
+ blockType2windowShape[blockSwitchingControlLeft->allowShortFrames]
+ [blockSwitchingControlRight->lastWindowSequence];
+ }
+
+ if (blockSwitchingControlLeft->allowShortFrames) {
+ int i;
+
+ if (nChannels == 2) {
+ if (commonWindow == TRUE) {
+ /* Synchronize grouping info */
+ int windowSequenceLeftOld =
+ blockSwitchingControlLeft->lastWindowSequence;
+ int windowSequenceRightOld =
+ blockSwitchingControlRight->lastWindowSequence;
+
+ /* Long Blocks */
+ if (patchType != SHORT_WINDOW) {
+ /* Set grouping info */
+ blockSwitchingControlLeft->noOfGroups = 1;
+ blockSwitchingControlRight->noOfGroups = 1;
+ blockSwitchingControlLeft->groupLen[0] = 1;
+ blockSwitchingControlRight->groupLen[0] = 1;
+
+ for (i = 1; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlLeft->groupLen[i] = 0;
+ blockSwitchingControlRight->groupLen[i] = 0;
+ }
+ }
+
+ /* Short Blocks */
+ else {
+ /* in case all two channels were detected as short-blocks before
+ * syncing, use the grouping of channel with higher maxWindowNrg */
+ if ((windowSequenceLeftOld == SHORT_WINDOW) &&
+ (windowSequenceRightOld == SHORT_WINDOW)) {
+ if (blockSwitchingControlLeft->maxWindowNrg >
+ blockSwitchingControlRight->maxWindowNrg) {
+ /* Left Channel wins */
+ blockSwitchingControlRight->noOfGroups =
+ blockSwitchingControlLeft->noOfGroups;
+ for (i = 0; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlRight->groupLen[i] =
+ blockSwitchingControlLeft->groupLen[i];
+ }
+ } else {
+ /* Right Channel wins */
+ blockSwitchingControlLeft->noOfGroups =
+ blockSwitchingControlRight->noOfGroups;
+ for (i = 0; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlLeft->groupLen[i] =
+ blockSwitchingControlRight->groupLen[i];
+ }
+ }
+ } else if ((windowSequenceLeftOld == SHORT_WINDOW) &&
+ (windowSequenceRightOld != SHORT_WINDOW)) {
+ /* else use grouping of short-block channel */
+ blockSwitchingControlRight->noOfGroups =
+ blockSwitchingControlLeft->noOfGroups;
+ for (i = 0; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlRight->groupLen[i] =
+ blockSwitchingControlLeft->groupLen[i];
+ }
+ } else if ((windowSequenceRightOld == SHORT_WINDOW) &&
+ (windowSequenceLeftOld != SHORT_WINDOW)) {
+ blockSwitchingControlLeft->noOfGroups =
+ blockSwitchingControlRight->noOfGroups;
+ for (i = 0; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlLeft->groupLen[i] =
+ blockSwitchingControlRight->groupLen[i];
+ }
+ } else {
+ /* syncing a start and stop window ... */
+ blockSwitchingControlLeft->noOfGroups =
+ blockSwitchingControlRight->noOfGroups = 2;
+ blockSwitchingControlLeft->groupLen[0] =
+ blockSwitchingControlRight->groupLen[0] = 4;
+ blockSwitchingControlLeft->groupLen[1] =
+ blockSwitchingControlRight->groupLen[1] = 4;
+ }
+ } /* Short Blocks */
+ } else {
+ /* stereo, no common window */
+ if (blockSwitchingControlLeft->lastWindowSequence != SHORT_WINDOW) {
+ blockSwitchingControlLeft->noOfGroups = 1;
+ blockSwitchingControlLeft->groupLen[0] = 1;
+ for (i = 1; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlLeft->groupLen[i] = 0;
+ }
+ }
+ if (blockSwitchingControlRight->lastWindowSequence != SHORT_WINDOW) {
+ blockSwitchingControlRight->noOfGroups = 1;
+ blockSwitchingControlRight->groupLen[0] = 1;
+ for (i = 1; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlRight->groupLen[i] = 0;
+ }
+ }
+ } /* common window */
+ } else {
+ /* Mono */
+ if (blockSwitchingControlLeft->lastWindowSequence != SHORT_WINDOW) {
+ blockSwitchingControlLeft->noOfGroups = 1;
+ blockSwitchingControlLeft->groupLen[0] = 1;
+
+ for (i = 1; i < MAX_NO_OF_GROUPS; i++) {
+ blockSwitchingControlLeft->groupLen[i] = 0;
+ }
+ }
+ }
+ } /* allowShortFrames */
+
+ /* Translate LOWOV_WINDOW block type to a meaningful window shape. */
+ if (!blockSwitchingControlLeft->allowShortFrames) {
+ if (blockSwitchingControlLeft->lastWindowSequence != LONG_WINDOW &&
+ blockSwitchingControlLeft->lastWindowSequence != STOP_WINDOW) {
+ blockSwitchingControlLeft->lastWindowSequence = LONG_WINDOW;
+ blockSwitchingControlLeft->windowShape = LOL_WINDOW;
+ }
+ }
+ if (nChannels == 2) {
+ if (!blockSwitchingControlRight->allowShortFrames) {
+ if (blockSwitchingControlRight->lastWindowSequence != LONG_WINDOW &&
+ blockSwitchingControlRight->lastWindowSequence != STOP_WINDOW) {
+ blockSwitchingControlRight->lastWindowSequence = LONG_WINDOW;
+ blockSwitchingControlRight->windowShape = LOL_WINDOW;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/fdk-aac/libAACenc/src/block_switch.h b/fdk-aac/libAACenc/src/block_switch.h
new file mode 100644
index 0000000..ff20f84
--- /dev/null
+++ b/fdk-aac/libAACenc/src/block_switch.h
@@ -0,0 +1,162 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Block switching
+
+*******************************************************************************/
+
+#ifndef BLOCK_SWITCH_H
+#define BLOCK_SWITCH_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+
+/****************** Defines ******************************/
+#define BLOCK_SWITCH_WINDOWS 8 /* number of windows for energy calculation */
+
+#define BLOCK_SWITCHING_IIR_LEN \
+ 2 /* Length of HighPass-IIR-Filter for Attack-Detection */
+#define BLOCK_SWITCH_ENERGY_SHIFT \
+ 7 /* should be logDualis(BLOCK_SWITCH_WINDOW_LEN) to avoid overflow in \
+ windowNrgs. */
+
+#define LAST_WINDOW 0
+#define THIS_WINDOW 1
+
+/****************** Structures ***************************/
+typedef struct {
+ INT lastWindowSequence;
+ INT windowShape;
+ INT lastWindowShape;
+ UINT nBlockSwitchWindows; /* number of windows for energy calculation */
+ INT attack;
+ INT lastattack;
+ INT attackIndex;
+ INT lastAttackIndex;
+ INT allowShortFrames; /* for Low Delay, don't allow short frames */
+ INT allowLookAhead; /* for Low Delay, don't do look-ahead */
+ INT noOfGroups;
+ INT groupLen[MAX_NO_OF_GROUPS];
+ FIXP_DBL maxWindowNrg; /* max energy in subwindows */
+
+ FIXP_DBL
+ windowNrg[2][BLOCK_SWITCH_WINDOWS]; /* time signal energy in Subwindows
+ (last and current) */
+ FIXP_DBL windowNrgF[2][BLOCK_SWITCH_WINDOWS]; /* filtered time signal energy
+ in segments (last and
+ current) */
+ FIXP_DBL accWindowNrg; /* recursively accumulated windowNrgF */
+
+ FIXP_DBL iirStates[BLOCK_SWITCHING_IIR_LEN]; /* filter delay-line */
+
+} BLOCK_SWITCHING_CONTROL;
+
+void FDKaacEnc_InitBlockSwitching(
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay);
+
+int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
+ const INT granuleLength, const int isLFE,
+ const INT_PCM *pTimeSignal);
+
+int FDKaacEnc_SyncBlockSwitching(
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft,
+ BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, const INT noOfChannels,
+ const INT commonWindow);
+
+#endif /* #ifndef BLOCK_SWITCH_H */
diff --git a/fdk-aac/libAACenc/src/channel_map.cpp b/fdk-aac/libAACenc/src/channel_map.cpp
new file mode 100644
index 0000000..6ee91d5
--- /dev/null
+++ b/fdk-aac/libAACenc/src/channel_map.cpp
@@ -0,0 +1,664 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): A. Groeschel
+
+ Description: channel mapping functionality
+
+*******************************************************************************/
+
+#include "channel_map.h"
+#include "bitenc.h"
+#include "psy_const.h"
+#include "qc_data.h"
+#include "aacEnc_ram.h"
+#include "FDK_tools_rom.h"
+
+/* channel_assignment treats the relationship of Input file channels
+ to the encoder channels.
+ This is necessary because the usual order in RIFF files (.wav)
+ is different from the elements order in the coder given
+ by Table 8.1 (implicit speaker mapping) of the AAC standard.
+
+ In mono and stereo case, this is trivial.
+ In mc case, it looks like this:
+
+ Channel Input file coder chan
+5ch:
+ front center 2 0 (SCE channel)
+ left center 0 1 (1st of 1st CPE)
+ right center 1 2 (2nd of 1st CPE)
+ left surround 3 3 (1st of 2nd CPE)
+ right surround 4 4 (2nd of 2nd CPE)
+
+5.1ch:
+ front center 2 0 (SCE channel)
+ left center 0 1 (1st of 1st CPE)
+ right center 1 2 (2nd of 1st CPE)
+ left surround 4 3 (1st of 2nd CPE)
+ right surround 5 4 (2nd of 2nd CPE)
+ LFE 3 5 (LFE)
+*/
+
+/* Channel mode configuration tab provides,
+ corresponding number of channels and elements
+*/
+static const CHANNEL_MODE_CONFIG_TAB channelModeConfig[] = {
+ {MODE_1, 1, 1, 1}, /* chCfg 1, SCE */
+ {MODE_2, 2, 2, 1}, /* chCfg 2, CPE */
+ {MODE_1_2, 3, 3, 2}, /* chCfg 3, SCE,CPE */
+ {MODE_1_2_1, 4, 4, 3}, /* chCfg 4, SCE,CPE,SCE */
+ {MODE_1_2_2, 5, 5, 3}, /* chCfg 5, SCE,CPE,CPE */
+ {MODE_1_2_2_1, 6, 5, 4}, /* chCfg 6, SCE,CPE,CPE,LFE */
+ {MODE_1_2_2_2_1, 8, 7, 5}, /* chCfg 7, SCE,CPE,CPE,CPE,LFE */
+ {MODE_6_1, 7, 6, 5}, /* chCfg 11, SCE,CPE,CPE,SCE,LFE */
+ {MODE_7_1_BACK, 8, 7, 5}, /* chCfg 12, SCE,CPE,CPE,CPE,LFE */
+ {MODE_7_1_TOP_FRONT, 8, 7, 5}, /* chCfg 14, SCE,CPE,CPE,LFE,CPE */
+ {MODE_7_1_REAR_SURROUND, 8, 7,
+ 5}, /* same as MODE_7_1_BACK, SCE,CPE,CPE,CPE,LFE */
+ {MODE_7_1_FRONT_CENTER, 8, 7,
+ 5}, /* same as MODE_1_2_2_2_1, SCE,CPE,CPE,CPE,LFE */
+
+};
+
+AAC_ENCODER_ERROR FDKaacEnc_DetermineEncoderMode(CHANNEL_MODE* mode,
+ INT nChannels) {
+ INT i;
+ CHANNEL_MODE encMode = MODE_INVALID;
+
+ if (*mode == MODE_UNKNOWN) {
+ for (i = 0; i < (INT)sizeof(channelModeConfig) /
+ (INT)sizeof(CHANNEL_MODE_CONFIG_TAB);
+ i++) {
+ if (channelModeConfig[i].nChannels == nChannels) {
+ encMode = channelModeConfig[i].encMode;
+ break;
+ }
+ }
+ *mode = encMode;
+ } else {
+ /* check if valid channel configuration */
+ if (FDKaacEnc_GetChannelModeConfiguration(*mode)->nChannels == nChannels) {
+ encMode = *mode;
+ }
+ }
+
+ if (encMode == MODE_INVALID) {
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ return AAC_ENC_OK;
+}
+
+static INT FDKaacEnc_initElement(ELEMENT_INFO* elInfo, MP4_ELEMENT_ID elType,
+ INT* cnt, FDK_channelMapDescr* mapDescr,
+ UINT mapIdx, INT* it_cnt,
+ const FIXP_DBL relBits) {
+ INT error = 0;
+ INT counter = *cnt;
+
+ elInfo->elType = elType;
+ elInfo->relativeBits = relBits;
+
+ switch (elInfo->elType) {
+ case ID_SCE:
+ case ID_LFE:
+ case ID_CCE:
+ elInfo->nChannelsInEl = 1;
+ elInfo->ChannelIndex[0] =
+ FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx);
+ elInfo->instanceTag = it_cnt[elType]++;
+ break;
+ case ID_CPE:
+ elInfo->nChannelsInEl = 2;
+ elInfo->ChannelIndex[0] =
+ FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx);
+ elInfo->ChannelIndex[1] =
+ FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx);
+ elInfo->instanceTag = it_cnt[elType]++;
+ break;
+ case ID_DSE:
+ elInfo->nChannelsInEl = 0;
+ elInfo->ChannelIndex[0] = 0;
+ elInfo->ChannelIndex[1] = 0;
+ elInfo->instanceTag = it_cnt[elType]++;
+ break;
+ default:
+ error = 1;
+ };
+ *cnt = counter;
+ return error;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_InitChannelMapping(CHANNEL_MODE mode,
+ CHANNEL_ORDER co,
+ CHANNEL_MAPPING* cm) {
+ INT count = 0; /* count through coder channels */
+ INT it_cnt[ID_END + 1];
+ INT i;
+ UINT mapIdx;
+ FDK_channelMapDescr mapDescr;
+
+ for (i = 0; i < ID_END; i++) it_cnt[i] = 0;
+
+ FDKmemclear(cm, sizeof(CHANNEL_MAPPING));
+
+ /* init channel mapping*/
+ for (i = 0; i < (INT)sizeof(channelModeConfig) /
+ (INT)sizeof(CHANNEL_MODE_CONFIG_TAB);
+ i++) {
+ if (channelModeConfig[i].encMode == mode) {
+ cm->encMode = channelModeConfig[i].encMode;
+ cm->nChannels = channelModeConfig[i].nChannels;
+ cm->nChannelsEff = channelModeConfig[i].nChannelsEff;
+ cm->nElements = channelModeConfig[i].nElements;
+
+ break;
+ }
+ }
+
+ /* init map descriptor */
+ FDK_chMapDescr_init(&mapDescr, NULL, 0, (co == CH_ORDER_MPEG) ? 1 : 0);
+ switch (mode) {
+ case MODE_7_1_REAR_SURROUND: /* MODE_7_1_REAR_SURROUND is equivalent to
+ MODE_7_1_BACK */
+ mapIdx = (INT)MODE_7_1_BACK;
+ break;
+ case MODE_7_1_FRONT_CENTER: /* MODE_7_1_FRONT_CENTER is equivalent to
+ MODE_1_2_2_2_1 */
+ mapIdx = (INT)MODE_1_2_2_2_1;
+ break;
+ default:
+ mapIdx =
+ (INT)mode > 14
+ ? 0
+ : (INT)
+ mode; /* if channel config > 14 MPEG mapping will be used */
+ }
+
+ /* init element info struct */
+ switch (mode) {
+ case MODE_1:
+ /* (mono) sce */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, (FIXP_DBL)MAXVAL_DBL);
+ break;
+ case MODE_2:
+ /* (stereo) cpe */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, (FIXP_DBL)MAXVAL_DBL);
+ break;
+
+ case MODE_1_2:
+ /* sce + cpe */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.4f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.6f));
+ break;
+
+ case MODE_1_2_1:
+ /* sce + cpe + sce */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.3f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.4f));
+ FDKaacEnc_initElement(&cm->elInfo[2], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.3f));
+ break;
+
+ case MODE_1_2_2:
+ /* sce + cpe + cpe */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.26f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.37f));
+ FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.37f));
+ break;
+
+ case MODE_1_2_2_1:
+ /* (5.1) sce + cpe + cpe + lfe */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.24f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.35f));
+ FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.35f));
+ FDKaacEnc_initElement(&cm->elInfo[3], ID_LFE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.06f));
+ break;
+
+ case MODE_6_1:
+ /* (6.1) sce + cpe + cpe + sce + lfe */
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.2f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.275f));
+ FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.275f));
+ FDKaacEnc_initElement(&cm->elInfo[3], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.2f));
+ FDKaacEnc_initElement(&cm->elInfo[4], ID_LFE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.05f));
+ break;
+
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_BACK:
+ case MODE_7_1_TOP_FRONT:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER: {
+ /* (7.1) sce + cpe + cpe + cpe + lfe */
+ /* (7.1 top) sce + cpe + cpe + lfe + cpe */
+
+ FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.18f));
+ FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.26f));
+ FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.26f));
+ if (mode != MODE_7_1_TOP_FRONT) {
+ FDKaacEnc_initElement(&cm->elInfo[3], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.26f));
+ FDKaacEnc_initElement(&cm->elInfo[4], ID_LFE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.04f));
+ } else {
+ FDKaacEnc_initElement(&cm->elInfo[3], ID_LFE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.04f));
+ FDKaacEnc_initElement(&cm->elInfo[4], ID_CPE, &count, &mapDescr, mapIdx,
+ it_cnt, FL2FXCONST_DBL(0.26f));
+ }
+ break;
+ }
+
+ default:
+ //*chMap=0;
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ };
+
+ FDK_ASSERT(cm->nElements <= ((8)));
+
+ return AAC_ENC_OK;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE* hQC, CHANNEL_MAPPING* cm,
+ INT bitrateTot, INT averageBitsTot,
+ INT maxChannelBits) {
+ int sc_brTot = CountLeadingBits(bitrateTot);
+
+ switch (cm->encMode) {
+ case MODE_1:
+ hQC->elementBits[0]->chBitrateEl = bitrateTot;
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ break;
+
+ case MODE_2:
+ hQC->elementBits[0]->chBitrateEl = bitrateTot >> 1;
+
+ hQC->elementBits[0]->maxBitsEl = 2 * maxChannelBits;
+
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ break;
+ case MODE_1_2: {
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits;
+ FIXP_DBL sceRate = cm->elInfo[0].relativeBits;
+ FIXP_DBL cpeRate = cm->elInfo[1].relativeBits;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ break;
+ }
+ case MODE_1_2_1: {
+ /* sce + cpe + sce */
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits;
+ hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits;
+ FIXP_DBL sce1Rate = cm->elInfo[0].relativeBits;
+ FIXP_DBL cpeRate = cm->elInfo[1].relativeBits;
+ FIXP_DBL sce2Rate = cm->elInfo[2].relativeBits;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sce1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[2]->chBitrateEl =
+ fMult(sce2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[2]->maxBitsEl = maxChannelBits;
+ break;
+ }
+ case MODE_1_2_2: {
+ /* sce + cpe + cpe */
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits;
+ hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits;
+ FIXP_DBL sceRate = cm->elInfo[0].relativeBits;
+ FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits;
+ FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[2]->chBitrateEl =
+ fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits;
+ break;
+ }
+ case MODE_1_2_2_1: {
+ /* (5.1) sce + cpe + cpe + lfe */
+ hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits;
+ hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits;
+ hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits;
+ hQC->elementBits[3]->relativeBitsEl = cm->elInfo[3].relativeBits;
+ FIXP_DBL sceRate = cm->elInfo[0].relativeBits;
+ FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits;
+ FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits;
+ FIXP_DBL lfeRate = cm->elInfo[3].relativeBits;
+
+ int maxBitsTot =
+ maxChannelBits * 5; /* LFE does not add to bit reservoir */
+ int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot));
+ int maxLfeBits = (int)fMax(
+ (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1),
+ (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f),
+ fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc)))
+ << 1) >>
+ sc));
+
+ maxChannelBits = (maxBitsTot - maxLfeBits);
+ sc = CountLeadingBits(maxChannelBits);
+
+ maxChannelBits =
+ fMult((FIXP_DBL)maxChannelBits << sc, GetInvInt(5)) >> sc;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[2]->chBitrateEl =
+ fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[3]->chBitrateEl =
+ fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[3]->maxBitsEl = maxLfeBits;
+
+ break;
+ }
+ case MODE_6_1: {
+ /* (6.1) sce + cpe + cpe + sce + lfe */
+ FIXP_DBL sceRate = hQC->elementBits[0]->relativeBitsEl =
+ cm->elInfo[0].relativeBits;
+ FIXP_DBL cpe1Rate = hQC->elementBits[1]->relativeBitsEl =
+ cm->elInfo[1].relativeBits;
+ FIXP_DBL cpe2Rate = hQC->elementBits[2]->relativeBitsEl =
+ cm->elInfo[2].relativeBits;
+ FIXP_DBL sce2Rate = hQC->elementBits[3]->relativeBitsEl =
+ cm->elInfo[3].relativeBits;
+ FIXP_DBL lfeRate = hQC->elementBits[4]->relativeBitsEl =
+ cm->elInfo[4].relativeBits;
+
+ int maxBitsTot =
+ maxChannelBits * 6; /* LFE does not add to bit reservoir */
+ int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot));
+ int maxLfeBits = (int)fMax(
+ (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1),
+ (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f),
+ fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc)))
+ << 1) >>
+ sc));
+
+ maxChannelBits = (maxBitsTot - maxLfeBits) / 6;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[2]->chBitrateEl =
+ fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[3]->chBitrateEl =
+ fMult(sce2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[4]->chBitrateEl =
+ fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[3]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[4]->maxBitsEl = maxLfeBits;
+ break;
+ }
+ case MODE_7_1_TOP_FRONT:
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER:
+ case MODE_1_2_2_2_1: {
+ int cpe3Idx = (cm->encMode != MODE_7_1_TOP_FRONT) ? 3 : 4;
+ int lfeIdx = (cm->encMode != MODE_7_1_TOP_FRONT) ? 4 : 3;
+
+ /* (7.1) sce + cpe + cpe + cpe + lfe */
+ FIXP_DBL sceRate = hQC->elementBits[0]->relativeBitsEl =
+ cm->elInfo[0].relativeBits;
+ FIXP_DBL cpe1Rate = hQC->elementBits[1]->relativeBitsEl =
+ cm->elInfo[1].relativeBits;
+ FIXP_DBL cpe2Rate = hQC->elementBits[2]->relativeBitsEl =
+ cm->elInfo[2].relativeBits;
+ FIXP_DBL cpe3Rate = hQC->elementBits[cpe3Idx]->relativeBitsEl =
+ cm->elInfo[cpe3Idx].relativeBits;
+ FIXP_DBL lfeRate = hQC->elementBits[lfeIdx]->relativeBitsEl =
+ cm->elInfo[lfeIdx].relativeBits;
+
+ int maxBitsTot =
+ maxChannelBits * 7; /* LFE does not add to bit reservoir */
+ int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot));
+ int maxLfeBits = (int)fMax(
+ (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1),
+ (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f),
+ fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc)))
+ << 1) >>
+ sc));
+
+ maxChannelBits = (maxBitsTot - maxLfeBits) / 7;
+
+ hQC->elementBits[0]->chBitrateEl =
+ fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+ hQC->elementBits[1]->chBitrateEl =
+ fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[2]->chBitrateEl =
+ fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[cpe3Idx]->chBitrateEl =
+ fMult(cpe3Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1);
+ hQC->elementBits[lfeIdx]->chBitrateEl =
+ fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot;
+
+ hQC->elementBits[0]->maxBitsEl = maxChannelBits;
+ hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[cpe3Idx]->maxBitsEl = 2 * maxChannelBits;
+ hQC->elementBits[lfeIdx]->maxBitsEl = maxLfeBits;
+ break;
+ }
+
+ default:
+ return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ return AAC_ENC_OK;
+}
+
+/********************************************************************************/
+/* */
+/* function: GetMonoStereoMODE(const CHANNEL_MODE mode) */
+/* */
+/* description: Determines encoder setting from channel mode. */
+/* Multichannel modes are mapped to mono or stereo modes */
+/* returns MODE_MONO in case of mono, */
+/* MODE_STEREO in case of stereo */
+/* MODE_INVALID in case of error */
+/* */
+/* input: CHANNEL_MODE mode: Encoder mode (see qc_data.h). */
+/* output: return: CM_STEREO_MODE monoStereoSetting */
+/* (MODE_INVALID: error, */
+/* MODE_MONO: mono */
+/* MODE_STEREO: stereo). */
+/* */
+/* misc: No memory is allocated. */
+/* */
+/********************************************************************************/
+
+ELEMENT_MODE FDKaacEnc_GetMonoStereoMode(const CHANNEL_MODE mode) {
+ ELEMENT_MODE monoStereoSetting = EL_MODE_INVALID;
+
+ switch (mode) {
+ case MODE_1: /* mono setups */
+ monoStereoSetting = EL_MODE_MONO;
+ break;
+
+ case MODE_2: /* stereo setups */
+ case MODE_1_2:
+ case MODE_1_2_1:
+ case MODE_1_2_2:
+ case MODE_1_2_2_1:
+ case MODE_6_1:
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_REAR_SURROUND:
+ case MODE_7_1_FRONT_CENTER:
+ case MODE_7_1_BACK:
+ case MODE_7_1_TOP_FRONT:
+ monoStereoSetting = EL_MODE_STEREO;
+ break;
+
+ default: /* error */
+ monoStereoSetting = EL_MODE_INVALID;
+ break;
+ }
+
+ return monoStereoSetting;
+}
+
+const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration(
+ const CHANNEL_MODE mode) {
+ INT i;
+ const CHANNEL_MODE_CONFIG_TAB* cm_config = NULL;
+
+ /* get channel mode config */
+ for (i = 0; i < (INT)sizeof(channelModeConfig) /
+ (INT)sizeof(CHANNEL_MODE_CONFIG_TAB);
+ i++) {
+ if (channelModeConfig[i].encMode == mode) {
+ cm_config = &channelModeConfig[i];
+ break;
+ }
+ }
+ return cm_config;
+}
diff --git a/fdk-aac/libAACenc/src/channel_map.h b/fdk-aac/libAACenc/src/channel_map.h
new file mode 100644
index 0000000..f9154cd
--- /dev/null
+++ b/fdk-aac/libAACenc/src/channel_map.h
@@ -0,0 +1,136 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): A. Groeschel
+
+ Description: channel mapping functionality
+
+*******************************************************************************/
+
+#ifndef CHANNEL_MAP_H
+#define CHANNEL_MAP_H
+
+#include "aacenc.h"
+#include "psy_const.h"
+#include "qc_data.h"
+
+typedef struct {
+ CHANNEL_MODE encMode;
+ INT nChannels;
+ INT nChannelsEff;
+ INT nElements;
+} CHANNEL_MODE_CONFIG_TAB;
+
+/* Element mode */
+typedef enum { EL_MODE_INVALID = 0, EL_MODE_MONO, EL_MODE_STEREO } ELEMENT_MODE;
+
+AAC_ENCODER_ERROR FDKaacEnc_DetermineEncoderMode(CHANNEL_MODE* mode,
+ INT nChannels);
+
+AAC_ENCODER_ERROR FDKaacEnc_InitChannelMapping(CHANNEL_MODE mode,
+ CHANNEL_ORDER co,
+ CHANNEL_MAPPING* chMap);
+
+AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE* hQC, CHANNEL_MAPPING* cm,
+ INT bitrateTot, INT averageBitsTot,
+ INT maxChannelBits);
+
+ELEMENT_MODE FDKaacEnc_GetMonoStereoMode(const CHANNEL_MODE mode);
+
+const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration(
+ const CHANNEL_MODE mode);
+
+#endif /* CHANNEL_MAP_H */
diff --git a/fdk-aac/libAACenc/src/chaosmeasure.cpp b/fdk-aac/libAACenc/src/chaosmeasure.cpp
new file mode 100644
index 0000000..664284b
--- /dev/null
+++ b/fdk-aac/libAACenc/src/chaosmeasure.cpp
@@ -0,0 +1,191 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Chaos measure calculation
+
+*******************************************************************************/
+
+#include "chaosmeasure.h"
+
+/*****************************************************************************
+ functionname: FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast
+ description: Eberlein method of chaos measure calculation by high-pass
+ filtering amplitude spectrum
+ A special case of FDKaacEnc_CalculateChaosMeasureTonalGeneric
+-- highly optimized
+*****************************************************************************/
+static void FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast(
+ FIXP_DBL *RESTRICT paMDCTDataNM0, INT numberOfLines,
+ FIXP_DBL *RESTRICT chaosMeasure) {
+ INT i, j;
+
+ /* calculate chaos measure by "peak filter" */
+ /* make even and odd pass through data */
+ FIXP_DBL left_0_div2,
+ center_0; /* left, center tap of filter, even numbered */
+ FIXP_DBL left_1_div2, center_1; /* left, center tap of filter, odd numbered */
+
+ left_0_div2 = (FIXP_DBL)(((LONG)paMDCTDataNM0[0] ^
+ ((LONG)paMDCTDataNM0[0] >> (DFRACT_BITS - 1))) >>
+ 1);
+ left_1_div2 = (FIXP_DBL)(((LONG)paMDCTDataNM0[1] ^
+ ((LONG)paMDCTDataNM0[1] >> (DFRACT_BITS - 1))) >>
+ 1);
+ center_0 = (FIXP_DBL)((LONG)paMDCTDataNM0[2] ^
+ ((LONG)paMDCTDataNM0[2] >> (DFRACT_BITS - 1)));
+ center_1 = (FIXP_DBL)((LONG)paMDCTDataNM0[3] ^
+ ((LONG)paMDCTDataNM0[3] >> (DFRACT_BITS - 1)));
+
+ for (j = 2; j < numberOfLines - 2; j += 2) {
+ FIXP_DBL right_0 =
+ (FIXP_DBL)((LONG)paMDCTDataNM0[j + 2] ^
+ ((LONG)paMDCTDataNM0[j + 2] >> (DFRACT_BITS - 1)));
+ FIXP_DBL tmp_0 = left_0_div2 + (right_0 >> 1);
+ FIXP_DBL right_1 =
+ (FIXP_DBL)((LONG)paMDCTDataNM0[j + 3] ^
+ ((LONG)paMDCTDataNM0[j + 3] >> (DFRACT_BITS - 1)));
+ FIXP_DBL tmp_1 = left_1_div2 + (right_1 >> 1);
+
+ if (tmp_0 < center_0) {
+ INT leadingBits = CntLeadingZeros(center_0) - 1;
+ tmp_0 = schur_div(tmp_0 << leadingBits, center_0 << leadingBits, 8);
+ tmp_0 = fMult(tmp_0, tmp_0);
+ } else {
+ tmp_0 = (FIXP_DBL)MAXVAL_DBL;
+ }
+ chaosMeasure[j + 0] = tmp_0;
+ left_0_div2 = center_0 >> 1;
+ center_0 = right_0;
+
+ if (tmp_1 < center_1) {
+ INT leadingBits = CntLeadingZeros(center_1) - 1;
+ tmp_1 = schur_div(tmp_1 << leadingBits, center_1 << leadingBits, 8);
+ tmp_1 = fMult(tmp_1, tmp_1);
+ } else {
+ tmp_1 = (FIXP_DBL)MAXVAL_DBL;
+ }
+
+ left_1_div2 = center_1 >> 1;
+ center_1 = right_1;
+ chaosMeasure[j + 1] = tmp_1;
+ }
+
+ /* provide chaos measure for first few lines */
+ chaosMeasure[0] = chaosMeasure[2];
+ chaosMeasure[1] = chaosMeasure[2];
+
+ /* provide chaos measure for last few lines */
+ for (i = (numberOfLines - 3); i < numberOfLines; i++)
+ chaosMeasure[i] = FL2FXCONST_DBL(0.5);
+}
+
+/*****************************************************************************
+ functionname: FDKaacEnc_CalculateChaosMeasure
+ description: calculates a chaosmeasure for every line, different methods
+ are available. 0 means tonal, 1 means noiselike
+ returns:
+ input: MDCT data, number of lines
+ output: chaosMeasure
+*****************************************************************************/
+void FDKaacEnc_CalculateChaosMeasure(FIXP_DBL *paMDCTDataNM0, INT numberOfLines,
+ FIXP_DBL *chaosMeasure)
+
+{
+ FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast(
+ paMDCTDataNM0, numberOfLines, chaosMeasure);
+}
diff --git a/fdk-aac/libAACenc/src/chaosmeasure.h b/fdk-aac/libAACenc/src/chaosmeasure.h
new file mode 100644
index 0000000..60d4137
--- /dev/null
+++ b/fdk-aac/libAACenc/src/chaosmeasure.h
@@ -0,0 +1,112 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Chaos measure calculation
+
+*******************************************************************************/
+
+#ifndef CHAOSMEASURE_H
+#define CHAOSMEASURE_H
+
+#include "common_fix.h"
+#include "psy_const.h"
+
+void FDKaacEnc_CalculateChaosMeasure(FIXP_DBL *paMDCTDataNM0, INT numberOfLines,
+ FIXP_DBL *chaosMeasure);
+
+#endif /* CHAOSMEASURE_H */
diff --git a/fdk-aac/libAACenc/src/dyn_bits.cpp b/fdk-aac/libAACenc/src/dyn_bits.cpp
new file mode 100644
index 0000000..b52dc2e
--- /dev/null
+++ b/fdk-aac/libAACenc/src/dyn_bits.cpp
@@ -0,0 +1,665 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Noiseless coder module
+
+*******************************************************************************/
+
+#include "dyn_bits.h"
+#include "bit_cnt.h"
+#include "psy_const.h"
+#include "aacenc_pns.h"
+#include "aacEnc_ram.h"
+#include "aacEnc_rom.h"
+
+typedef INT (*lookUpTable)[CODE_BOOK_ESC_NDX + 1];
+
+static INT FDKaacEnc_getSideInfoBits(const SECTION_INFO* const huffsection,
+ const SHORT* const sideInfoTab,
+ const INT useHCR) {
+ INT sideInfoBits;
+
+ if (useHCR &&
+ ((huffsection->codeBook == 11) || (huffsection->codeBook >= 16))) {
+ sideInfoBits = 5;
+ } else {
+ sideInfoBits = sideInfoTab[huffsection->sfbCnt];
+ }
+
+ return (sideInfoBits);
+}
+
+/* count bits using all possible tables */
+static void FDKaacEnc_buildBitLookUp(
+ const SHORT* const quantSpectrum, const INT maxSfb,
+ const INT* const sfbOffset, const UINT* const sfbMax,
+ INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
+ SECTION_INFO* const huffsection) {
+ INT i, sfbWidth;
+
+ for (i = 0; i < maxSfb; i++) {
+ huffsection[i].sfbCnt = 1;
+ huffsection[i].sfbStart = i;
+ huffsection[i].sectionBits = INVALID_BITCOUNT;
+ huffsection[i].codeBook = -1;
+ sfbWidth = sfbOffset[i + 1] - sfbOffset[i];
+ FDKaacEnc_bitCount(quantSpectrum + sfbOffset[i], sfbWidth, sfbMax[i],
+ bitLookUp[i]);
+ }
+}
+
+/* essential helper functions */
+static inline INT FDKaacEnc_findBestBook(const INT* const bc, INT* const book,
+ const INT useVCB11) {
+ INT minBits = INVALID_BITCOUNT, j;
+
+ int end = CODE_BOOK_ESC_NDX;
+
+ for (j = 0; j <= end; j++) {
+ if (bc[j] < minBits) {
+ minBits = bc[j];
+ *book = j;
+ }
+ }
+ return (minBits);
+}
+
+static inline INT FDKaacEnc_findMinMergeBits(const INT* const bc1,
+ const INT* const bc2,
+ const INT useVCB11) {
+ INT minBits = INVALID_BITCOUNT, j;
+
+ DWORD_ALIGNED(bc1);
+ DWORD_ALIGNED(bc2);
+
+ for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) {
+ minBits = fixMin(minBits, bc1[j] + bc2[j]);
+ }
+ return (minBits);
+}
+
+static inline void FDKaacEnc_mergeBitLookUp(INT* const RESTRICT bc1,
+ const INT* const RESTRICT bc2) {
+ int j;
+
+ for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) {
+ FDK_ASSERT(INVALID_BITCOUNT == 0x1FFFFFFF);
+ bc1[j] = fixMin(bc1[j] + bc2[j], INVALID_BITCOUNT);
+ }
+}
+
+static inline INT FDKaacEnc_findMaxMerge(const INT* const mergeGainLookUp,
+ const SECTION_INFO* const huffsection,
+ const INT maxSfb, INT* const maxNdx) {
+ INT i, maxMergeGain = 0;
+ int lastMaxNdx = 0;
+
+ for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) {
+ if (mergeGainLookUp[i] > maxMergeGain) {
+ maxMergeGain = mergeGainLookUp[i];
+ lastMaxNdx = i;
+ }
+ }
+ *maxNdx = lastMaxNdx;
+ return (maxMergeGain);
+}
+
+static inline INT FDKaacEnc_CalcMergeGain(
+ const SECTION_INFO* const huffsection,
+ const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
+ const SHORT* const sideInfoTab, const INT ndx1, const INT ndx2,
+ const INT useVCB11) {
+ INT MergeGain, MergeBits, SplitBits;
+
+ MergeBits =
+ sideInfoTab[huffsection[ndx1].sfbCnt + huffsection[ndx2].sfbCnt] +
+ FDKaacEnc_findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2], useVCB11);
+ SplitBits =
+ huffsection[ndx1].sectionBits +
+ huffsection[ndx2].sectionBits; /* Bit amount for splitted huffsections */
+ MergeGain = SplitBits - MergeBits;
+
+ if ((huffsection[ndx1].codeBook == CODE_BOOK_PNS_NO) ||
+ (huffsection[ndx2].codeBook == CODE_BOOK_PNS_NO) ||
+ (huffsection[ndx1].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (huffsection[ndx2].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (huffsection[ndx1].codeBook == CODE_BOOK_IS_IN_PHASE_NO) ||
+ (huffsection[ndx2].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) {
+ MergeGain = -1;
+ }
+
+ return (MergeGain);
+}
+
+/* sectioning Stage 0:find minimum codbooks */
+static void FDKaacEnc_gmStage0(
+ SECTION_INFO* const RESTRICT huffsection,
+ const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb,
+ const INT* const noiseNrg, const INT* const isBook) {
+ INT i;
+
+ for (i = 0; i < maxSfb; i++) {
+ /* Side-Info bits will be calculated in Stage 1! */
+ if (huffsection[i].sectionBits == INVALID_BITCOUNT) {
+ /* intensity and pns codebooks are already allocated in bitcount.c */
+ if (noiseNrg[i] != NO_NOISE_PNS) {
+ huffsection[i].codeBook = CODE_BOOK_PNS_NO;
+ huffsection[i].sectionBits = 0;
+ } else if (isBook[i]) {
+ huffsection[i].codeBook = isBook[i];
+ huffsection[i].sectionBits = 0;
+ } else {
+ huffsection[i].sectionBits =
+ FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook),
+ 0); /* useVCB11 must be 0!!! */
+ }
+ }
+ }
+}
+
+/*
+ sectioning Stage 1:merge all connected regions with the same code book and
+ calculate side info
+ */
+static void FDKaacEnc_gmStage1(
+ SECTION_INFO* const RESTRICT huffsection,
+ INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb,
+ const SHORT* const sideInfoTab, const INT useVCB11) {
+ INT mergeStart = 0, mergeEnd;
+
+ do {
+ for (mergeEnd = mergeStart + 1; mergeEnd < maxSfb; mergeEnd++) {
+ if (huffsection[mergeStart].codeBook != huffsection[mergeEnd].codeBook)
+ break;
+
+ /* we can merge. update tables, side info bits will be updated outside of
+ * this loop */
+ huffsection[mergeStart].sfbCnt++;
+ huffsection[mergeStart].sectionBits += huffsection[mergeEnd].sectionBits;
+
+ /* update bit look up for all code books */
+ FDKaacEnc_mergeBitLookUp(bitLookUp[mergeStart], bitLookUp[mergeEnd]);
+ }
+
+ /* add side info info bits */
+ huffsection[mergeStart].sectionBits += FDKaacEnc_getSideInfoBits(
+ &huffsection[mergeStart], sideInfoTab, useVCB11);
+ huffsection[mergeEnd - 1].sfbStart =
+ huffsection[mergeStart].sfbStart; /* speed up prev search */
+
+ mergeStart = mergeEnd;
+
+ } while (mergeStart < maxSfb);
+}
+
+/*
+ sectioning Stage 2:greedy merge algorithm, merge connected sections with
+ maximum bit gain until no more gain is possible
+ */
+static inline void FDKaacEnc_gmStage2(
+ SECTION_INFO* const RESTRICT huffsection,
+ INT* const RESTRICT mergeGainLookUp,
+ INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb,
+ const SHORT* const sideInfoTab, const INT useVCB11) {
+ INT i;
+
+ for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) {
+ mergeGainLookUp[i] =
+ FDKaacEnc_CalcMergeGain(huffsection, bitLookUp, sideInfoTab, i,
+ i + huffsection[i].sfbCnt, useVCB11);
+ }
+
+ while (TRUE) {
+ INT maxMergeGain, maxNdx, maxNdxNext, maxNdxLast;
+
+ maxMergeGain =
+ FDKaacEnc_findMaxMerge(mergeGainLookUp, huffsection, maxSfb, &maxNdx);
+
+ /* exit while loop if no more gain is possible */
+ if (maxMergeGain <= 0) break;
+
+ maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt;
+
+ /* merge sections with maximum bit gain */
+ huffsection[maxNdx].sfbCnt += huffsection[maxNdxNext].sfbCnt;
+ huffsection[maxNdx].sectionBits +=
+ huffsection[maxNdxNext].sectionBits - maxMergeGain;
+
+ /* update bit look up table for merged huffsection */
+ FDKaacEnc_mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]);
+
+ /* update mergeLookUpTable */
+ if (maxNdx != 0) {
+ maxNdxLast = huffsection[maxNdx - 1].sfbStart;
+ mergeGainLookUp[maxNdxLast] = FDKaacEnc_CalcMergeGain(
+ huffsection, bitLookUp, sideInfoTab, maxNdxLast, maxNdx, useVCB11);
+ }
+ maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt;
+
+ huffsection[maxNdxNext - 1].sfbStart = huffsection[maxNdx].sfbStart;
+
+ if (maxNdxNext < maxSfb)
+ mergeGainLookUp[maxNdx] = FDKaacEnc_CalcMergeGain(
+ huffsection, bitLookUp, sideInfoTab, maxNdx, maxNdxNext, useVCB11);
+ }
+}
+
+/* count bits used by the noiseless coder */
+static void FDKaacEnc_noiselessCounter(
+ SECTION_DATA* const RESTRICT sectionData, INT mergeGainLookUp[MAX_SFB_LONG],
+ INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1],
+ const SHORT* const quantSpectrum, const UINT* const maxValueInSfb,
+ const INT* const sfbOffset, const INT blockType, const INT* const noiseNrg,
+ const INT* const isBook, const INT useVCB11) {
+ INT grpNdx, i;
+ const SHORT* sideInfoTab = NULL;
+ SECTION_INFO* huffsection;
+
+ /* use appropriate side info table */
+ switch (blockType) {
+ case LONG_WINDOW:
+ case START_WINDOW:
+ case STOP_WINDOW:
+ default:
+ sideInfoTab = FDKaacEnc_sideInfoTabLong;
+ break;
+ case SHORT_WINDOW:
+ sideInfoTab = FDKaacEnc_sideInfoTabShort;
+ break;
+ }
+
+ FDK_ASSERT(sideInfoTab != NULL);
+
+ sectionData->noOfSections = 0;
+ sectionData->huffmanBits = 0;
+ sectionData->sideInfoBits = 0;
+
+ if (sectionData->maxSfbPerGroup == 0) return;
+
+ /* loop trough groups */
+ for (grpNdx = 0; grpNdx < sectionData->sfbCnt;
+ grpNdx += sectionData->sfbPerGroup) {
+ huffsection = sectionData->huffsection + sectionData->noOfSections;
+
+ /* count bits in this group */
+ FDKaacEnc_buildBitLookUp(quantSpectrum, sectionData->maxSfbPerGroup,
+ sfbOffset + grpNdx, maxValueInSfb + grpNdx,
+ bitLookUp, huffsection);
+
+ /* 0.Stage :Find minimum Codebooks */
+ FDKaacEnc_gmStage0(huffsection, bitLookUp, sectionData->maxSfbPerGroup,
+ noiseNrg + grpNdx, isBook + grpNdx);
+
+ /* 1.Stage :Merge all connected regions with the same code book */
+ FDKaacEnc_gmStage1(huffsection, bitLookUp, sectionData->maxSfbPerGroup,
+ sideInfoTab, useVCB11);
+
+ /*
+ 2.Stage
+ greedy merge algorithm, merge connected huffsections with maximum bit
+ gain until no more gain is possible
+ */
+
+ FDKaacEnc_gmStage2(huffsection, mergeGainLookUp, bitLookUp,
+ sectionData->maxSfbPerGroup, sideInfoTab, useVCB11);
+
+ /*
+ compress output, calculate total huff and side bits
+ since we did not update the actual codebook in stage 2
+ to save time, we must set it here for later use in bitenc
+ */
+
+ for (i = 0; i < sectionData->maxSfbPerGroup; i += huffsection[i].sfbCnt) {
+ if ((huffsection[i].codeBook == CODE_BOOK_PNS_NO) ||
+ (huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) {
+ huffsection[i].sectionBits = 0;
+ } else {
+ /* the sections in the sectionData are now marked with the optimal code
+ * book */
+
+ FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook),
+ useVCB11);
+
+ sectionData->huffmanBits +=
+ huffsection[i].sectionBits -
+ FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11);
+ }
+
+ huffsection[i].sfbStart += grpNdx;
+
+ /* sum up side info bits (section data bits) */
+ sectionData->sideInfoBits +=
+ FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11);
+ sectionData->huffsection[sectionData->noOfSections++] = huffsection[i];
+ }
+ }
+}
+
+/*******************************************************************************
+
+ functionname: FDKaacEnc_scfCount
+ returns : ---
+ description : count bits used by scalefactors.
+
+ not in all cases if maxValueInSfb[] == 0 we set deltaScf
+ to zero. only if the difference of the last and future
+ scalefacGain is not greater then CODE_BOOK_SCF_LAV (60).
+
+ example:
+ ^
+ scalefacGain |
+ |
+ | last 75
+ | |
+ | |
+ | |
+ | | current 50
+ | | |
+ | | |
+ | | |
+ | | |
+ | | | future 5
+ | | | |
+ --- ... ---------------------------- ... --------->
+ sfb
+
+
+ if maxValueInSfb[] of current is zero because of a
+ notfallstrategie, we do not save bits and transmit a
+ deltaScf of 25. otherwise the deltaScf between the last
+ scalfacGain (75) and the future scalefacGain (5) is 70.
+
+********************************************************************************/
+static void FDKaacEnc_scfCount(const INT* const scalefacGain,
+ const UINT* const maxValueInSfb,
+ SECTION_DATA* const RESTRICT sectionData,
+ const INT* const isScale) {
+ INT i, j, k, m, n;
+
+ INT lastValScf = 0;
+ INT deltaScf = 0;
+ INT found = 0;
+ INT scfSkipCounter = 0;
+ INT lastValIs = 0;
+
+ sectionData->scalefacBits = 0;
+
+ if (scalefacGain == NULL) return;
+
+ sectionData->firstScf = 0;
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) {
+ sectionData->firstScf = sectionData->huffsection[i].sfbStart;
+ lastValScf = scalefacGain[sectionData->firstScf];
+ break;
+ }
+ }
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ if ((sectionData->huffsection[i].codeBook ==
+ CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
+ (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) {
+ for (j = sectionData->huffsection[i].sfbStart;
+ j < sectionData->huffsection[i].sfbStart +
+ sectionData->huffsection[i].sfbCnt;
+ j++) {
+ INT deltaIs = isScale[j] - lastValIs;
+ lastValIs = isScale[j];
+ sectionData->scalefacBits +=
+ FDKaacEnc_bitCountScalefactorDelta(deltaIs);
+ }
+ } /* Intensity */
+ else if ((sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) &&
+ (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO)) {
+ INT tmp = sectionData->huffsection[i].sfbStart +
+ sectionData->huffsection[i].sfbCnt;
+ for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) {
+ /* check if we can repeat the last value to save bits */
+ if (maxValueInSfb[j] == 0) {
+ found = 0;
+ /* are scalefactors skipped? */
+ if (scfSkipCounter == 0) {
+ /* end of section */
+ if (j == (tmp - 1))
+ found = 0; /* search in other sections for maxValueInSfb != 0 */
+ else {
+ /* search in this section for the next maxValueInSfb[] != 0 */
+ for (k = (j + 1); k < tmp; k++) {
+ if (maxValueInSfb[k] != 0) {
+ found = 1;
+ if ((fixp_abs(scalefacGain[k] - lastValScf)) <=
+ CODE_BOOK_SCF_LAV)
+ deltaScf = 0; /* save bits */
+ else {
+ /* do not save bits */
+ deltaScf = lastValScf - scalefacGain[j];
+ lastValScf = scalefacGain[j];
+ scfSkipCounter = 0;
+ }
+ break;
+ }
+ /* count scalefactor skip */
+ scfSkipCounter++;
+ }
+ }
+
+ /* search for the next maxValueInSfb[] != 0 in all other sections */
+ for (m = (i + 1); (m < sectionData->noOfSections) && (found == 0);
+ m++) {
+ if ((sectionData->huffsection[m].codeBook != CODE_BOOK_ZERO_NO) &&
+ (sectionData->huffsection[m].codeBook != CODE_BOOK_PNS_NO)) {
+ INT end = sectionData->huffsection[m].sfbStart +
+ sectionData->huffsection[m].sfbCnt;
+ for (n = sectionData->huffsection[m].sfbStart; n < end; n++) {
+ if (maxValueInSfb[n] != 0) {
+ found = 1;
+ if (fixp_abs(scalefacGain[n] - lastValScf) <=
+ CODE_BOOK_SCF_LAV)
+ deltaScf = 0; /* save bits */
+ else {
+ /* do not save bits */
+ deltaScf = lastValScf - scalefacGain[j];
+ lastValScf = scalefacGain[j];
+ scfSkipCounter = 0;
+ }
+ break;
+ }
+ /* count scalefactor skip */
+ scfSkipCounter++;
+ }
+ }
+ }
+ /* no maxValueInSfb[] != 0 found */
+ if (found == 0) {
+ deltaScf = 0;
+ scfSkipCounter = 0;
+ }
+ } else {
+ /* consider skipped scalefactors */
+ deltaScf = 0;
+ scfSkipCounter--;
+ }
+ } else {
+ deltaScf = lastValScf - scalefacGain[j];
+ lastValScf = scalefacGain[j];
+ }
+ sectionData->scalefacBits +=
+ FDKaacEnc_bitCountScalefactorDelta(deltaScf);
+ }
+ }
+ } /* for (i=0; i<sectionData->noOfSections; i++) */
+}
+
+/* count bits used by pns */
+static void FDKaacEnc_noiseCount(SECTION_DATA* const RESTRICT sectionData,
+ const INT* const noiseNrg) {
+ INT noisePCMFlag = TRUE;
+ INT lastValPns = 0, deltaPns;
+ int i, j;
+
+ sectionData->noiseNrgBits = 0;
+
+ for (i = 0; i < sectionData->noOfSections; i++) {
+ if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) {
+ int sfbStart = sectionData->huffsection[i].sfbStart;
+ int sfbEnd = sfbStart + sectionData->huffsection[i].sfbCnt;
+ for (j = sfbStart; j < sfbEnd; j++) {
+ if (noisePCMFlag) {
+ sectionData->noiseNrgBits += PNS_PCM_BITS;
+ lastValPns = noiseNrg[j];
+ noisePCMFlag = FALSE;
+ } else {
+ deltaPns = noiseNrg[j] - lastValPns;
+ lastValPns = noiseNrg[j];
+ sectionData->noiseNrgBits +=
+ FDKaacEnc_bitCountScalefactorDelta(deltaPns);
+ }
+ }
+ }
+ }
+}
+
+INT FDKaacEnc_dynBitCount(BITCNTR_STATE* const hBC,
+ const SHORT* const quantSpectrum,
+ const UINT* const maxValueInSfb,
+ const INT* const scalefac, const INT blockType,
+ const INT sfbCnt, const INT maxSfbPerGroup,
+ const INT sfbPerGroup, const INT* const sfbOffset,
+ SECTION_DATA* const RESTRICT sectionData,
+ const INT* const noiseNrg, const INT* const isBook,
+ const INT* const isScale, const UINT syntaxFlags) {
+ sectionData->blockType = blockType;
+ sectionData->sfbCnt = sfbCnt;
+ sectionData->sfbPerGroup = sfbPerGroup;
+ sectionData->noOfGroups = sfbCnt / sfbPerGroup;
+ sectionData->maxSfbPerGroup = maxSfbPerGroup;
+
+ FDKaacEnc_noiselessCounter(sectionData, hBC->mergeGainLookUp,
+ (lookUpTable)hBC->bitLookUp, quantSpectrum,
+ maxValueInSfb, sfbOffset, blockType, noiseNrg,
+ isBook, (syntaxFlags & AC_ER_VCB11) ? 1 : 0);
+
+ FDKaacEnc_scfCount(scalefac, maxValueInSfb, sectionData, isScale);
+
+ FDKaacEnc_noiseCount(sectionData, noiseNrg);
+
+ return (sectionData->huffmanBits + sectionData->sideInfoBits +
+ sectionData->scalefacBits + sectionData->noiseNrgBits);
+}
+
+INT FDKaacEnc_BCNew(BITCNTR_STATE** phBC, UCHAR* dynamic_RAM) {
+ BITCNTR_STATE* hBC = GetRam_aacEnc_BitCntrState();
+
+ if (hBC) {
+ *phBC = hBC;
+ hBC->bitLookUp = GetRam_aacEnc_BitLookUp(0, dynamic_RAM);
+ hBC->mergeGainLookUp = GetRam_aacEnc_MergeGainLookUp(0, dynamic_RAM);
+ if (hBC->bitLookUp == 0 || hBC->mergeGainLookUp == 0) {
+ return 1;
+ }
+ }
+ return (hBC == 0) ? 1 : 0;
+}
+
+void FDKaacEnc_BCClose(BITCNTR_STATE** phBC) {
+ if (*phBC != NULL) {
+ FreeRam_aacEnc_BitCntrState(phBC);
+ }
+}
diff --git a/fdk-aac/libAACenc/src/dyn_bits.h b/fdk-aac/libAACenc/src/dyn_bits.h
new file mode 100644
index 0000000..a727a30
--- /dev/null
+++ b/fdk-aac/libAACenc/src/dyn_bits.h
@@ -0,0 +1,160 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Noiseless coder module
+
+*******************************************************************************/
+
+#ifndef DYN_BITS_H
+#define DYN_BITS_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+#include "aacenc_tns.h"
+
+#define MAX_SECTIONS MAX_GROUPED_SFB
+#define SECT_ESC_VAL_LONG 31
+#define SECT_ESC_VAL_SHORT 7
+#define CODE_BOOK_BITS 4
+#define SECT_BITS_LONG 5
+#define SECT_BITS_SHORT 3
+#define PNS_PCM_BITS 9
+
+typedef struct {
+ INT codeBook;
+ INT sfbStart;
+ INT sfbCnt;
+ INT sectionBits; /* huff + si ! */
+} SECTION_INFO;
+
+typedef struct {
+ INT blockType;
+ INT noOfGroups;
+ INT sfbCnt;
+ INT maxSfbPerGroup;
+ INT sfbPerGroup;
+ INT noOfSections;
+ SECTION_INFO huffsection[MAX_SECTIONS];
+ INT sideInfoBits; /* sectioning bits */
+ INT huffmanBits; /* huffman coded bits */
+ INT scalefacBits; /* scalefac coded bits */
+ INT noiseNrgBits; /* noiseEnergy coded bits */
+ INT firstScf; /* first scf to be coded */
+} SECTION_DATA;
+
+struct BITCNTR_STATE {
+ INT* bitLookUp;
+ INT* mergeGainLookUp;
+};
+
+INT FDKaacEnc_BCNew(BITCNTR_STATE** phBC, UCHAR* dynamic_RAM);
+
+void FDKaacEnc_BCClose(BITCNTR_STATE** phBC);
+
+INT FDKaacEnc_dynBitCount(BITCNTR_STATE* const hBC,
+ const SHORT* const quantSpectrum,
+ const UINT* const maxValueInSfb,
+ const INT* const scalefac, const INT blockType,
+ const INT sfbCnt, const INT maxSfbPerGroup,
+ const INT sfbPerGroup, const INT* const sfbOffset,
+ SECTION_DATA* const RESTRICT sectionData,
+ const INT* const noiseNrg, const INT* const isBook,
+ const INT* const isScale, const UINT syntaxFlags);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/grp_data.cpp b/fdk-aac/libAACenc/src/grp_data.cpp
new file mode 100644
index 0000000..bc9d85f
--- /dev/null
+++ b/fdk-aac/libAACenc/src/grp_data.cpp
@@ -0,0 +1,264 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Short block grouping
+
+*******************************************************************************/
+
+#include "psy_const.h"
+#include "interface.h"
+
+/*
+ * this routine does not work in-place
+ */
+
+/*
+ * Don't use fAddSaturate2() because it looses one bit accuracy which is
+ * usefull for quality.
+ */
+static inline FIXP_DBL nrgAddSaturate(const FIXP_DBL a, const FIXP_DBL b) {
+ return ((a >= (FIXP_DBL)MAXVAL_DBL - b) ? (FIXP_DBL)MAXVAL_DBL : (a + b));
+}
+
+void FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */
+ SFB_THRESHOLD *sfbThreshold, /* in-out */
+ SFB_ENERGY *sfbEnergy, /* in-out */
+ SFB_ENERGY *sfbEnergyMS, /* in-out */
+ SFB_ENERGY *sfbSpreadEnergy, const INT sfbCnt,
+ const INT sfbActive, const INT *sfbOffset,
+ const FIXP_DBL *sfbMinSnrLdData,
+ INT *groupedSfbOffset, /* out */
+ INT *maxSfbPerGroup, /* out */
+ FIXP_DBL *groupedSfbMinSnrLdData,
+ const INT noOfGroups, const INT *groupLen,
+ const INT granuleLength) {
+ INT i, j;
+ INT line; /* counts through lines */
+ INT sfb; /* counts through scalefactor bands */
+ INT grp; /* counts through groups */
+ INT wnd; /* counts through windows in a group */
+ INT offset; /* needed in sfbOffset grouping */
+ INT highestSfb;
+ INT granuleLength_short = granuleLength / TRANS_FAC;
+
+ C_ALLOC_SCRATCH_START(tmpSpectrum, FIXP_DBL, (1024))
+
+ /* for short blocks: regroup spectrum and */
+ /* group energies and thresholds according to grouping */
+
+ /* calculate maxSfbPerGroup */
+ highestSfb = 0;
+ for (wnd = 0; wnd < TRANS_FAC; wnd++) {
+ for (sfb = sfbActive - 1; sfb >= highestSfb; sfb--) {
+ for (line = sfbOffset[sfb + 1] - 1; line >= sfbOffset[sfb]; line--) {
+ if (mdctSpectrum[wnd * granuleLength_short + line] !=
+ FL2FXCONST_SPC(0.0))
+ break; /* this band is not completely zero */
+ }
+ if (line >= sfbOffset[sfb]) break; /* this band was not completely zero */
+ }
+ highestSfb = fixMax(highestSfb, sfb);
+ }
+ highestSfb = highestSfb > 0 ? highestSfb : 0;
+ *maxSfbPerGroup = highestSfb + 1;
+
+ /* calculate groupedSfbOffset */
+ i = 0;
+ offset = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive + 1; sfb++) {
+ groupedSfbOffset[i++] = offset + sfbOffset[sfb] * groupLen[grp];
+ }
+ i += sfbCnt - sfb;
+ offset += groupLen[grp] * granuleLength_short;
+ }
+ groupedSfbOffset[i++] = granuleLength;
+
+ /* calculate groupedSfbMinSnr */
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ groupedSfbMinSnrLdData[i++] = sfbMinSnrLdData[sfb];
+ }
+ i += sfbCnt - sfb;
+ }
+
+ /* sum up sfbThresholds */
+ wnd = 0;
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ FIXP_DBL thresh = sfbThreshold->Short[wnd][sfb];
+ for (j = 1; j < groupLen[grp]; j++) {
+ thresh = nrgAddSaturate(thresh, sfbThreshold->Short[wnd + j][sfb]);
+ }
+ sfbThreshold->Long[i++] = thresh;
+ }
+ i += sfbCnt - sfb;
+ wnd += groupLen[grp];
+ }
+
+ /* sum up sfbEnergies left/right */
+ wnd = 0;
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ FIXP_DBL energy = sfbEnergy->Short[wnd][sfb];
+ for (j = 1; j < groupLen[grp]; j++) {
+ energy = nrgAddSaturate(energy, sfbEnergy->Short[wnd + j][sfb]);
+ }
+ sfbEnergy->Long[i++] = energy;
+ }
+ i += sfbCnt - sfb;
+ wnd += groupLen[grp];
+ }
+
+ /* sum up sfbEnergies mid/side */
+ wnd = 0;
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ FIXP_DBL energy = sfbEnergyMS->Short[wnd][sfb];
+ for (j = 1; j < groupLen[grp]; j++) {
+ energy = nrgAddSaturate(energy, sfbEnergyMS->Short[wnd + j][sfb]);
+ }
+ sfbEnergyMS->Long[i++] = energy;
+ }
+ i += sfbCnt - sfb;
+ wnd += groupLen[grp];
+ }
+
+ /* sum up sfbSpreadEnergies */
+ wnd = 0;
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ FIXP_DBL energy = sfbSpreadEnergy->Short[wnd][sfb];
+ for (j = 1; j < groupLen[grp]; j++) {
+ energy = nrgAddSaturate(energy, sfbSpreadEnergy->Short[wnd + j][sfb]);
+ }
+ sfbSpreadEnergy->Long[i++] = energy;
+ }
+ i += sfbCnt - sfb;
+ wnd += groupLen[grp];
+ }
+
+ /* re-group spectrum */
+ wnd = 0;
+ i = 0;
+ for (grp = 0; grp < noOfGroups; grp++) {
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ int width = sfbOffset[sfb + 1] - sfbOffset[sfb];
+ FIXP_DBL *pMdctSpectrum =
+ &mdctSpectrum[sfbOffset[sfb]] + wnd * granuleLength_short;
+ for (j = 0; j < groupLen[grp]; j++) {
+ FIXP_DBL *pTmp = pMdctSpectrum;
+ for (line = width; line > 0; line--) {
+ tmpSpectrum[i++] = *pTmp++;
+ }
+ pMdctSpectrum += granuleLength_short;
+ }
+ }
+ i += (groupLen[grp] * (sfbOffset[sfbCnt] - sfbOffset[sfb]));
+ wnd += groupLen[grp];
+ }
+
+ FDKmemcpy(mdctSpectrum, tmpSpectrum, granuleLength * sizeof(FIXP_DBL));
+
+ C_ALLOC_SCRATCH_END(tmpSpectrum, FIXP_DBL, (1024))
+}
diff --git a/fdk-aac/libAACenc/src/grp_data.h b/fdk-aac/libAACenc/src/grp_data.h
new file mode 100644
index 0000000..3e1a708
--- /dev/null
+++ b/fdk-aac/libAACenc/src/grp_data.h
@@ -0,0 +1,123 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Short block grouping
+
+*******************************************************************************/
+
+#ifndef GRP_DATA_H
+#define GRP_DATA_H
+
+#include "common_fix.h"
+
+#include "psy_data.h"
+
+void FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */
+ SFB_THRESHOLD *sfbThreshold, /* in-out */
+ SFB_ENERGY *sfbEnergy, /* in-out */
+ SFB_ENERGY *sfbEnergyMS, /* in-out */
+ SFB_ENERGY *sfbSpreadEnergy, const INT sfbCnt,
+ const INT sfbActive, const INT *sfbOffset,
+ const FIXP_DBL *sfbMinSnrLdData,
+ INT *groupedSfbOffset, /* out */
+ INT *maxSfbPerGroup,
+ FIXP_DBL *groupedSfbMinSnrLdData,
+ const INT noOfGroups, const INT *groupLen,
+ const INT granuleLength);
+
+#endif /* _INTERFACE_H */
diff --git a/fdk-aac/libAACenc/src/intensity.cpp b/fdk-aac/libAACenc/src/intensity.cpp
new file mode 100644
index 0000000..8cb1b45
--- /dev/null
+++ b/fdk-aac/libAACenc/src/intensity.cpp
@@ -0,0 +1,810 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): A. Horndasch (code originally from lwr) / Josef Hoepfl (FDK)
+
+ Description: intensity stereo processing
+
+*******************************************************************************/
+
+#include "intensity.h"
+
+#include "interface.h"
+#include "psy_configuration.h"
+#include "psy_const.h"
+#include "qc_main.h"
+#include "bit_cnt.h"
+
+/* only set an IS seed it left/right channel correlation is above IS_CORR_THRESH
+ */
+#define IS_CORR_THRESH FL2FXCONST_DBL(0.95f)
+
+/* when expanding the IS region to more SFBs only accept an error that is
+ * not more than IS_TOTAL_ERROR_THRESH overall and
+ * not more than IS_LOCAL_ERROR_THRESH for the current SFB */
+#define IS_TOTAL_ERROR_THRESH FL2FXCONST_DBL(0.04f)
+#define IS_LOCAL_ERROR_THRESH FL2FXCONST_DBL(0.01f)
+
+/* the maximum allowed change of the intensity direction (unit: IS scale) -
+ * scaled with factor 0.25 - */
+#define IS_DIRECTION_DEVIATION_THRESH_SF 2
+#define IS_DIRECTION_DEVIATION_THRESH \
+ FL2FXCONST_DBL(2.0f / (1 << IS_DIRECTION_DEVIATION_THRESH_SF))
+
+/* IS regions need to have a minimal percentage of the overall loudness, e.g.
+ * 0.06 == 6% */
+#define IS_REGION_MIN_LOUDNESS FL2FXCONST_DBL(0.1f)
+
+/* only perform IS if IS_MIN_SFBS neighboring SFBs can be processed */
+#define IS_MIN_SFBS 6
+
+/* only do IS if
+ * if IS_LEFT_RIGHT_RATIO_THRESH < sfbEnergyLeft[sfb]/sfbEnergyRight[sfb] < 1 /
+ * IS_LEFT_RIGHT_RATIO_THRESH
+ * -> no IS if the panning angle is not far from the middle, MS will do */
+/* this is equivalent to a scale of +/-1.02914634566 */
+#define IS_LEFT_RIGHT_RATIO_THRESH FL2FXCONST_DBL(0.7f)
+
+/* scalefactor of realScale */
+#define REAL_SCALE_SF 1
+
+/* scalefactor overallLoudness */
+#define OVERALL_LOUDNESS_SF 6
+
+/* scalefactor for sum over max samples per goup */
+#define MAX_SFB_PER_GROUP_SF 6
+
+/* scalefactor for sum of mdct spectrum */
+#define MDCT_SPEC_SF 6
+
+typedef struct {
+ FIXP_DBL corr_thresh; /*!< Only set an IS seed it left/right channel
+ correlation is above corr_thresh */
+
+ FIXP_DBL total_error_thresh; /*!< When expanding the IS region to more SFBs
+ only accept an error that is not more than
+ 'total_error_thresh' overall. */
+
+ FIXP_DBL local_error_thresh; /*!< When expanding the IS region to more SFBs
+ only accept an error that is not more than
+ 'local_error_thresh' for the current SFB. */
+
+ FIXP_DBL direction_deviation_thresh; /*!< The maximum allowed change of the
+ intensity direction (unit: IS scale)
+ */
+
+ FIXP_DBL is_region_min_loudness; /*!< IS regions need to have a minimal
+ percentage of the overall loudness, e.g.
+ 0.06 == 6% */
+
+ INT min_is_sfbs; /*!< Only perform IS if 'min_is_sfbs' neighboring SFBs can be
+ processed */
+
+ FIXP_DBL left_right_ratio_threshold; /*!< No IS if the panning angle is not
+ far from the middle, MS will do */
+
+} INTENSITY_PARAMETERS;
+
+/*****************************************************************************
+
+ functionname: calcSfbMaxScale
+
+ description: Calc max value in scalefactor band
+
+ input: *mdctSpectrum
+ l1
+ l2
+
+ output: none
+
+ returns: scalefactor
+
+*****************************************************************************/
+static INT calcSfbMaxScale(const FIXP_DBL *mdctSpectrum, const INT l1,
+ const INT l2) {
+ INT i;
+ INT sfbMaxScale;
+ FIXP_DBL maxSpc;
+
+ maxSpc = FL2FXCONST_DBL(0.0);
+ for (i = l1; i < l2; i++) {
+ FIXP_DBL tmp = fixp_abs((FIXP_DBL)mdctSpectrum[i]);
+ maxSpc = fixMax(maxSpc, tmp);
+ }
+ sfbMaxScale = (maxSpc == FL2FXCONST_DBL(0.0)) ? (DFRACT_BITS - 2)
+ : CntLeadingZeros(maxSpc) - 1;
+
+ return sfbMaxScale;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_initIsParams
+
+ description: Initialization of intensity parameters
+
+ input: isParams
+
+ output: isParams
+
+ returns: none
+
+*****************************************************************************/
+static void FDKaacEnc_initIsParams(INTENSITY_PARAMETERS *isParams) {
+ isParams->corr_thresh = IS_CORR_THRESH;
+ isParams->total_error_thresh = IS_TOTAL_ERROR_THRESH;
+ isParams->local_error_thresh = IS_LOCAL_ERROR_THRESH;
+ isParams->direction_deviation_thresh = IS_DIRECTION_DEVIATION_THRESH;
+ isParams->is_region_min_loudness = IS_REGION_MIN_LOUDNESS;
+ isParams->min_is_sfbs = IS_MIN_SFBS;
+ isParams->left_right_ratio_threshold = IS_LEFT_RIGHT_RATIO_THRESH;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_prepareIntensityDecision
+
+ description: Prepares intensity decision
+
+ input: sfbEnergyLeft
+ sfbEnergyRight
+ sfbEnergyLdDataLeft
+ sfbEnergyLdDataRight
+ mdctSpectrumLeft
+ sfbEnergyLdDataRight
+ isParams
+
+ output: hrrErr scale: none
+ isMask scale: none
+ realScale scale: LD_DATA_SHIFT + REAL_SCALE_SF
+ normSfbLoudness scale: none
+
+ returns: none
+
+*****************************************************************************/
+static void FDKaacEnc_prepareIntensityDecision(
+ const FIXP_DBL *sfbEnergyLeft, const FIXP_DBL *sfbEnergyRight,
+ const FIXP_DBL *sfbEnergyLdDataLeft, const FIXP_DBL *sfbEnergyLdDataRight,
+ const FIXP_DBL *mdctSpectrumLeft, const FIXP_DBL *mdctSpectrumRight,
+ const INTENSITY_PARAMETERS *isParams, FIXP_DBL *hrrErr, INT *isMask,
+ FIXP_DBL *realScale, FIXP_DBL *normSfbLoudness, const INT sfbCnt,
+ const INT sfbPerGroup, const INT maxSfbPerGroup, const INT *sfbOffset) {
+ INT j, sfb, sfboffs;
+ INT grpCounter;
+
+ /* temporary variables to compute loudness */
+ FIXP_DBL overallLoudness[MAX_NO_OF_GROUPS];
+
+ /* temporary variables to compute correlation */
+ FIXP_DBL channelCorr[MAX_GROUPED_SFB];
+ FIXP_DBL ml, mr;
+ FIXP_DBL prod_lr;
+ FIXP_DBL square_l, square_r;
+ FIXP_DBL tmp_l, tmp_r;
+ FIXP_DBL inv_n;
+
+ FDKmemclear(channelCorr, MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+ FDKmemclear(normSfbLoudness, MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+ FDKmemclear(overallLoudness, MAX_NO_OF_GROUPS * sizeof(FIXP_DBL));
+ FDKmemclear(realScale, MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+
+ for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt;
+ sfboffs += sfbPerGroup, grpCounter++) {
+ overallLoudness[grpCounter] = FL2FXCONST_DBL(0.0f);
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ INT sL, sR, s;
+ FIXP_DBL isValue = sfbEnergyLdDataLeft[sfb + sfboffs] -
+ sfbEnergyLdDataRight[sfb + sfboffs];
+
+ /* delimitate intensity scale value to representable range */
+ realScale[sfb + sfboffs] = fixMin(
+ FL2FXCONST_DBL(60.f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT))),
+ fixMax(FL2FXCONST_DBL(-60.f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT))),
+ isValue));
+
+ sL = fixMax(0, (CntLeadingZeros(sfbEnergyLeft[sfb + sfboffs]) - 1));
+ sR = fixMax(0, (CntLeadingZeros(sfbEnergyRight[sfb + sfboffs]) - 1));
+ s = (fixMin(sL, sR) >> 2) << 2;
+ normSfbLoudness[sfb + sfboffs] =
+ sqrtFixp(sqrtFixp(((sfbEnergyLeft[sfb + sfboffs] << s) >> 1) +
+ ((sfbEnergyRight[sfb + sfboffs] << s) >> 1))) >>
+ (s >> 2);
+
+ overallLoudness[grpCounter] +=
+ normSfbLoudness[sfb + sfboffs] >> OVERALL_LOUDNESS_SF;
+ /* don't do intensity if
+ * - panning angle is too close to the middle or
+ * - one channel is non-existent or
+ * - if it is dual mono */
+ if ((sfbEnergyLeft[sfb + sfboffs] >=
+ fMult(isParams->left_right_ratio_threshold,
+ sfbEnergyRight[sfb + sfboffs])) &&
+ (fMult(isParams->left_right_ratio_threshold,
+ sfbEnergyLeft[sfb + sfboffs]) <=
+ sfbEnergyRight[sfb + sfboffs])) {
+ /* this will prevent post processing from considering this SFB for
+ * merging */
+ hrrErr[sfb + sfboffs] = FL2FXCONST_DBL(1.0 / 8.0);
+ }
+ }
+ }
+
+ for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt;
+ sfboffs += sfbPerGroup, grpCounter++) {
+ INT invOverallLoudnessSF;
+ FIXP_DBL invOverallLoudness;
+
+ if (overallLoudness[grpCounter] == FL2FXCONST_DBL(0.0)) {
+ invOverallLoudness = FL2FXCONST_DBL(0.0);
+ invOverallLoudnessSF = 0;
+ } else {
+ invOverallLoudness =
+ fDivNorm((FIXP_DBL)MAXVAL_DBL, overallLoudness[grpCounter],
+ &invOverallLoudnessSF);
+ invOverallLoudnessSF =
+ invOverallLoudnessSF - OVERALL_LOUDNESS_SF +
+ 1; /* +1: compensate fMultDiv2() in subsequent loop */
+ }
+ invOverallLoudnessSF = fixMin(
+ fixMax(invOverallLoudnessSF, -(DFRACT_BITS - 1)), DFRACT_BITS - 1);
+
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ FIXP_DBL tmp;
+
+ tmp = fMultDiv2((normSfbLoudness[sfb + sfboffs] >> OVERALL_LOUDNESS_SF)
+ << OVERALL_LOUDNESS_SF,
+ invOverallLoudness);
+
+ normSfbLoudness[sfb + sfboffs] = scaleValue(tmp, invOverallLoudnessSF);
+
+ channelCorr[sfb + sfboffs] = FL2FXCONST_DBL(0.0f);
+
+ /* max width of scalefactorband is 96; width's are always even */
+ /* inv_n is scaled with factor 2 to compensate fMultDiv2() in subsequent
+ * loops */
+ inv_n = GetInvInt(
+ (sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs]) >> 1);
+
+ if (inv_n > FL2FXCONST_DBL(0.0f)) {
+ INT s, sL, sR;
+
+ /* correlation := Pearson's product-moment coefficient */
+ /* compute correlation between channels and check if it is over
+ * threshold */
+ ml = FL2FXCONST_DBL(0.0f);
+ mr = FL2FXCONST_DBL(0.0f);
+ prod_lr = FL2FXCONST_DBL(0.0f);
+ square_l = FL2FXCONST_DBL(0.0f);
+ square_r = FL2FXCONST_DBL(0.0f);
+
+ sL = calcSfbMaxScale(mdctSpectrumLeft, sfbOffset[sfb + sfboffs],
+ sfbOffset[sfb + sfboffs + 1]);
+ sR = calcSfbMaxScale(mdctSpectrumRight, sfbOffset[sfb + sfboffs],
+ sfbOffset[sfb + sfboffs + 1]);
+ s = fixMin(sL, sR);
+
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ ml += fMultDiv2((mdctSpectrumLeft[j] << s),
+ inv_n); // scaled with mdctScale - s + inv_n
+ mr += fMultDiv2((mdctSpectrumRight[j] << s),
+ inv_n); // scaled with mdctScale - s + inv_n
+ }
+ ml = fMultDiv2(ml, inv_n); // scaled with mdctScale - s + inv_n
+ mr = fMultDiv2(mr, inv_n); // scaled with mdctScale - s + inv_n
+
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ tmp_l = fMultDiv2((mdctSpectrumLeft[j] << s), inv_n) -
+ ml; // scaled with mdctScale - s + inv_n
+ tmp_r = fMultDiv2((mdctSpectrumRight[j] << s), inv_n) -
+ mr; // scaled with mdctScale - s + inv_n
+
+ prod_lr += fMultDiv2(
+ tmp_l, tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1
+ square_l +=
+ fPow2Div2(tmp_l); // scaled with 2*(mdctScale - s + inv_n) + 1
+ square_r +=
+ fPow2Div2(tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1
+ }
+ prod_lr = prod_lr << 1; // scaled with 2*(mdctScale - s + inv_n)
+ square_l = square_l << 1; // scaled with 2*(mdctScale - s + inv_n)
+ square_r = square_r << 1; // scaled with 2*(mdctScale - s + inv_n)
+
+ if (square_l > FL2FXCONST_DBL(0.0f) &&
+ square_r > FL2FXCONST_DBL(0.0f)) {
+ INT channelCorrSF = 0;
+
+ /* local scaling of square_l and square_r is compensated after sqrt
+ * calculation */
+ sL = fixMax(0, (CntLeadingZeros(square_l) - 1));
+ sR = fixMax(0, (CntLeadingZeros(square_r) - 1));
+ s = ((sL + sR) >> 1) << 1;
+ sL = fixMin(sL, s);
+ sR = s - sL;
+ tmp = fMult(square_l << sL, square_r << sR);
+ tmp = sqrtFixp(tmp);
+
+ FDK_ASSERT(tmp > FL2FXCONST_DBL(0.0f));
+
+ /* numerator and denominator have the same scaling */
+ if (prod_lr < FL2FXCONST_DBL(0.0f)) {
+ channelCorr[sfb + sfboffs] =
+ -(fDivNorm(-prod_lr, tmp, &channelCorrSF));
+
+ } else {
+ channelCorr[sfb + sfboffs] =
+ (fDivNorm(prod_lr, tmp, &channelCorrSF));
+ }
+ channelCorrSF = fixMin(
+ fixMax((channelCorrSF + ((sL + sR) >> 1)), -(DFRACT_BITS - 1)),
+ DFRACT_BITS - 1);
+
+ if (channelCorrSF < 0) {
+ channelCorr[sfb + sfboffs] =
+ channelCorr[sfb + sfboffs] >> (-channelCorrSF);
+ } else {
+ /* avoid overflows due to limited computational accuracy */
+ if (fAbs(channelCorr[sfb + sfboffs]) >
+ (((FIXP_DBL)MAXVAL_DBL) >> channelCorrSF)) {
+ if (channelCorr[sfb + sfboffs] < FL2FXCONST_DBL(0.0f))
+ channelCorr[sfb + sfboffs] = -(FIXP_DBL)MAXVAL_DBL;
+ else
+ channelCorr[sfb + sfboffs] = (FIXP_DBL)MAXVAL_DBL;
+ } else {
+ channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs]
+ << channelCorrSF;
+ }
+ }
+ }
+ }
+
+ /* for post processing: hrrErr is the error in terms of (too little)
+ * correlation weighted with the loudness of the SFB; SFBs with small
+ * hrrErr can be merged */
+ if (hrrErr[sfb + sfboffs] == FL2FXCONST_DBL(1.0 / 8.0)) {
+ continue;
+ }
+
+ hrrErr[sfb + sfboffs] =
+ fMultDiv2((FL2FXCONST_DBL(0.25f) - (channelCorr[sfb + sfboffs] >> 2)),
+ normSfbLoudness[sfb + sfboffs]);
+
+ /* set IS mask/vector to 1, if correlation is high enough */
+ if (fAbs(channelCorr[sfb + sfboffs]) >= isParams->corr_thresh) {
+ isMask[sfb + sfboffs] = 1;
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_finalizeIntensityDecision
+
+ description: Finalizes intensity decision
+
+ input: isParams scale: none
+ hrrErr scale: none
+ realIsScale scale: LD_DATA_SHIFT + REAL_SCALE_SF
+ normSfbLoudness scale: none
+
+ output: isMask scale: none
+
+ returns: none
+
+*****************************************************************************/
+static void FDKaacEnc_finalizeIntensityDecision(
+ const FIXP_DBL *hrrErr, INT *isMask, const FIXP_DBL *realIsScale,
+ const FIXP_DBL *normSfbLoudness, const INTENSITY_PARAMETERS *isParams,
+ const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup) {
+ INT sfb, sfboffs, j;
+ FIXP_DBL isScaleLast = FL2FXCONST_DBL(0.0f);
+ INT isStartValueFound = 0;
+
+ for (sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup) {
+ INT startIsSfb = 0;
+ INT inIsBlock = 0;
+ INT currentIsSfbCount = 0;
+ FIXP_DBL overallHrrError = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL isRegionLoudness = FL2FXCONST_DBL(0.0f);
+
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ if (isMask[sfboffs + sfb] == 1) {
+ if (currentIsSfbCount == 0) {
+ startIsSfb = sfboffs + sfb;
+ }
+ if (isStartValueFound == 0) {
+ isScaleLast = realIsScale[sfboffs + sfb];
+ isStartValueFound = 1;
+ }
+ inIsBlock = 1;
+ currentIsSfbCount++;
+ overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF - 3);
+ isRegionLoudness +=
+ normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF;
+ } else {
+ /* based on correlation, IS should not be used
+ * -> use it anyway, if overall error is below threshold
+ * and if local error does not exceed threshold
+ * otherwise: check if there are enough IS SFBs
+ */
+ if (inIsBlock) {
+ overallHrrError +=
+ hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF - 3);
+ isRegionLoudness +=
+ normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF;
+
+ if ((hrrErr[sfboffs + sfb] < (isParams->local_error_thresh >> 3)) &&
+ (overallHrrError <
+ (isParams->total_error_thresh >> MAX_SFB_PER_GROUP_SF))) {
+ currentIsSfbCount++;
+ /* overwrite correlation based decision */
+ isMask[sfboffs + sfb] = 1;
+ } else {
+ inIsBlock = 0;
+ }
+ }
+ }
+ /* check for large direction deviation */
+ if (inIsBlock) {
+ if (fAbs(isScaleLast - realIsScale[sfboffs + sfb]) <
+ (isParams->direction_deviation_thresh >>
+ (REAL_SCALE_SF + LD_DATA_SHIFT -
+ IS_DIRECTION_DEVIATION_THRESH_SF))) {
+ isScaleLast = realIsScale[sfboffs + sfb];
+ } else {
+ isMask[sfboffs + sfb] = 0;
+ inIsBlock = 0;
+ currentIsSfbCount--;
+ }
+ }
+
+ if (currentIsSfbCount > 0 && (!inIsBlock || sfb == maxSfbPerGroup - 1)) {
+ /* not enough SFBs -> do not use IS */
+ if (currentIsSfbCount < isParams->min_is_sfbs ||
+ (isRegionLoudness<isParams->is_region_min_loudness>>
+ MAX_SFB_PER_GROUP_SF)) {
+ for (j = startIsSfb; j <= sfboffs + sfb; j++) {
+ isMask[j] = 0;
+ }
+ isScaleLast = FL2FXCONST_DBL(0.0f);
+ isStartValueFound = 0;
+ for (j = 0; j < startIsSfb; j++) {
+ if (isMask[j] != 0) {
+ isScaleLast = realIsScale[j];
+ isStartValueFound = 1;
+ }
+ }
+ }
+ currentIsSfbCount = 0;
+ overallHrrError = FL2FXCONST_DBL(0.0f);
+ isRegionLoudness = FL2FXCONST_DBL(0.0f);
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_IntensityStereoProcessing
+
+ description: Intensity stereo processing tool
+
+ input: sfbEnergyLeft
+ sfbEnergyRight
+ mdctSpectrumLeft
+ mdctSpectrumRight
+ sfbThresholdLeft
+ sfbThresholdRight
+ sfbSpreadEnLeft
+ sfbSpreadEnRight
+ sfbEnergyLdDataLeft
+ sfbEnergyLdDataRight
+
+ output: isBook
+ isScale
+ pnsData->pnsFlag
+ msDigest zeroed from start to sfbCnt
+ msMask zeroed from start to sfbCnt
+ mdctSpectrumRight zeroed where isBook!=0
+ sfbEnergyRight zeroed where isBook!=0
+ sfbSpreadEnRight zeroed where isBook!=0
+ sfbThresholdRight zeroed where isBook!=0
+ sfbEnergyLdDataRight FL2FXCONST_DBL(-1.0) where isBook!=0
+ sfbThresholdLdDataRight FL2FXCONST_DBL(-0.515625f) where
+isBook!=0
+
+ returns: none
+
+*****************************************************************************/
+void FDKaacEnc_IntensityStereoProcessing(
+ FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight,
+ FIXP_DBL *mdctSpectrumLeft, FIXP_DBL *mdctSpectrumRight,
+ FIXP_DBL *sfbThresholdLeft, FIXP_DBL *sfbThresholdRight,
+ FIXP_DBL *sfbThresholdLdDataRight, FIXP_DBL *sfbSpreadEnLeft,
+ FIXP_DBL *sfbSpreadEnRight, FIXP_DBL *sfbEnergyLdDataLeft,
+ FIXP_DBL *sfbEnergyLdDataRight, INT *msDigest, INT *msMask,
+ const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup,
+ const INT *sfbOffset, const INT allowIS, INT *isBook, INT *isScale,
+ PNS_DATA *RESTRICT pnsData[2]) {
+ INT sfb, sfboffs, j;
+ FIXP_DBL scale;
+ FIXP_DBL lr;
+ FIXP_DBL hrrErr[MAX_GROUPED_SFB];
+ FIXP_DBL normSfbLoudness[MAX_GROUPED_SFB];
+ FIXP_DBL realIsScale[MAX_GROUPED_SFB];
+ INTENSITY_PARAMETERS isParams;
+ INT isMask[MAX_GROUPED_SFB];
+
+ FDKmemclear((void *)isBook, sfbCnt * sizeof(INT));
+ FDKmemclear((void *)isMask, sfbCnt * sizeof(INT));
+ FDKmemclear((void *)realIsScale, sfbCnt * sizeof(FIXP_DBL));
+ FDKmemclear((void *)isScale, sfbCnt * sizeof(INT));
+ FDKmemclear((void *)hrrErr, sfbCnt * sizeof(FIXP_DBL));
+
+ if (!allowIS) return;
+
+ FDKaacEnc_initIsParams(&isParams);
+
+ /* compute / set the following values per SFB:
+ * - left/right ratio between channels
+ * - normalized loudness
+ * + loudness == average of energy in channels to 0.25
+ * + normalization: division by sum of all SFB loudnesses
+ * - isMask (is set to 0 if channels are the same or one is 0)
+ */
+ FDKaacEnc_prepareIntensityDecision(
+ sfbEnergyLeft, sfbEnergyRight, sfbEnergyLdDataLeft, sfbEnergyLdDataRight,
+ mdctSpectrumLeft, mdctSpectrumRight, &isParams, hrrErr, isMask,
+ realIsScale, normSfbLoudness, sfbCnt, sfbPerGroup, maxSfbPerGroup,
+ sfbOffset);
+
+ FDKaacEnc_finalizeIntensityDecision(hrrErr, isMask, realIsScale,
+ normSfbLoudness, &isParams, sfbCnt,
+ sfbPerGroup, maxSfbPerGroup);
+
+ for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) {
+ for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) {
+ INT sL, sR;
+ FIXP_DBL inv_n;
+
+ msMask[sfb + sfboffs] = 0;
+ if (isMask[sfb + sfboffs] == 0) {
+ continue;
+ }
+
+ if ((sfbEnergyLeft[sfb + sfboffs] < sfbThresholdLeft[sfb + sfboffs]) &&
+ (fMult(FL2FXCONST_DBL(1.0f / 1.5f), sfbEnergyRight[sfb + sfboffs]) >
+ sfbThresholdRight[sfb + sfboffs])) {
+ continue;
+ }
+ /* NEW: if there is a big-enough IS region, switch off PNS */
+ if (pnsData[0]) {
+ if (pnsData[0]->pnsFlag[sfb + sfboffs]) {
+ pnsData[0]->pnsFlag[sfb + sfboffs] = 0;
+ }
+ if (pnsData[1]->pnsFlag[sfb + sfboffs]) {
+ pnsData[1]->pnsFlag[sfb + sfboffs] = 0;
+ }
+ }
+
+ inv_n = GetInvInt(
+ (sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs]) >>
+ 1); // scaled with 2 to compensate fMultDiv2() in subsequent loop
+ sL = calcSfbMaxScale(mdctSpectrumLeft, sfbOffset[sfb + sfboffs],
+ sfbOffset[sfb + sfboffs + 1]);
+ sR = calcSfbMaxScale(mdctSpectrumRight, sfbOffset[sfb + sfboffs],
+ sfbOffset[sfb + sfboffs + 1]);
+
+ lr = FL2FXCONST_DBL(0.0f);
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; j++)
+ lr += fMultDiv2(
+ fMultDiv2(mdctSpectrumLeft[j] << sL, mdctSpectrumRight[j] << sR),
+ inv_n);
+ lr = lr << 1;
+
+ if (lr < FL2FXCONST_DBL(0.0f)) {
+ /* This means OUT OF phase intensity stereo, cf. standard */
+ INT s0, s1, s2;
+ FIXP_DBL tmp, d, ed = FL2FXCONST_DBL(0.0f);
+
+ s0 = fixMin(sL, sR);
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ d = ((mdctSpectrumLeft[j] << s0) >> 1) -
+ ((mdctSpectrumRight[j] << s0) >> 1);
+ ed += fMultDiv2(d, d) >> (MDCT_SPEC_SF - 1);
+ }
+ msMask[sfb + sfboffs] = 1;
+ tmp = fDivNorm(sfbEnergyLeft[sfb + sfboffs], ed, &s1);
+ s2 = (s1) + (2 * s0) - 2 - MDCT_SPEC_SF;
+ if (s2 & 1) {
+ tmp = tmp >> 1;
+ s2 = s2 + 1;
+ }
+ s2 = (s2 >> 1) + 1; // +1 compensate fMultDiv2() in subsequent loop
+ s2 = fixMin(fixMax(s2, -(DFRACT_BITS - 1)), (DFRACT_BITS - 1));
+ scale = sqrtFixp(tmp);
+ if (s2 < 0) {
+ s2 = -s2;
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) -
+ fMultDiv2(mdctSpectrumRight[j], scale)) >>
+ s2;
+ mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f);
+ }
+ } else {
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) -
+ fMultDiv2(mdctSpectrumRight[j], scale))
+ << s2;
+ mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f);
+ }
+ }
+ } else {
+ /* This means IN phase intensity stereo, cf. standard */
+ INT s0, s1, s2;
+ FIXP_DBL tmp, s, es = FL2FXCONST_DBL(0.0f);
+
+ s0 = fixMin(sL, sR);
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ s = ((mdctSpectrumLeft[j] << s0) >> 1) +
+ ((mdctSpectrumRight[j] << s0) >> 1);
+ es = fAddSaturate(es, fMultDiv2(s, s) >>
+ (MDCT_SPEC_SF -
+ 1)); // scaled 2*(mdctScale - s0 + 1) + MDCT_SPEC_SF
+ }
+ msMask[sfb + sfboffs] = 0;
+ tmp = fDivNorm(sfbEnergyLeft[sfb + sfboffs], es, &s1);
+ s2 = (s1) + (2 * s0) - 2 - MDCT_SPEC_SF;
+ if (s2 & 1) {
+ tmp = tmp >> 1;
+ s2 = s2 + 1;
+ }
+ s2 = (s2 >> 1) + 1; // +1 compensate fMultDiv2() in subsequent loop
+ s2 = fixMin(fixMax(s2, -(DFRACT_BITS - 1)), (DFRACT_BITS - 1));
+ scale = sqrtFixp(tmp);
+ if (s2 < 0) {
+ s2 = -s2;
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) +
+ fMultDiv2(mdctSpectrumRight[j], scale)) >>
+ s2;
+ mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f);
+ }
+ } else {
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) +
+ fMultDiv2(mdctSpectrumRight[j], scale))
+ << s2;
+ mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f);
+ }
+ }
+ }
+
+ isBook[sfb + sfboffs] = CODE_BOOK_IS_IN_PHASE_NO;
+
+ if (realIsScale[sfb + sfboffs] < FL2FXCONST_DBL(0.0f)) {
+ isScale[sfb + sfboffs] =
+ (INT)(((realIsScale[sfb + sfboffs] >> 1) -
+ FL2FXCONST_DBL(
+ 0.5f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT + 1)))) >>
+ (DFRACT_BITS - 1 - REAL_SCALE_SF - LD_DATA_SHIFT - 1)) +
+ 1;
+ } else {
+ isScale[sfb + sfboffs] =
+ (INT)(((realIsScale[sfb + sfboffs] >> 1) +
+ FL2FXCONST_DBL(
+ 0.5f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT + 1)))) >>
+ (DFRACT_BITS - 1 - REAL_SCALE_SF - LD_DATA_SHIFT - 1));
+ }
+
+ sfbEnergyRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f);
+ sfbEnergyLdDataRight[sfb + sfboffs] = FL2FXCONST_DBL(-1.0f);
+ sfbThresholdRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f);
+ sfbThresholdLdDataRight[sfb + sfboffs] = FL2FXCONST_DBL(-0.515625f);
+ sfbSpreadEnRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f);
+
+ *msDigest = MS_SOME;
+ }
+ }
+}
diff --git a/fdk-aac/libAACenc/src/intensity.h b/fdk-aac/libAACenc/src/intensity.h
new file mode 100644
index 0000000..70f23d5
--- /dev/null
+++ b/fdk-aac/libAACenc/src/intensity.h
@@ -0,0 +1,121 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): A. Horndasch (code originally from lwr and rtb) / Josef Hoepfl
+(FDK)
+
+ Description: intensity stereo prototype
+
+*******************************************************************************/
+
+#ifndef INTENSITY_H
+#define INTENSITY_H
+
+#include "aacenc_pns.h"
+#include "common_fix.h"
+
+void FDKaacEnc_IntensityStereoProcessing(
+ FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight,
+ FIXP_DBL *mdctSpectrumLeft, FIXP_DBL *mdctSpectrumRight,
+ FIXP_DBL *sfbThresholdLeft, FIXP_DBL *sfbThresholdRight,
+ FIXP_DBL *sfbThresholdLdDataRight, FIXP_DBL *sfbSpreadEnLeft,
+ FIXP_DBL *sfbSpreadEnRight, FIXP_DBL *sfbEnergyLdDataLeft,
+ FIXP_DBL *sfbEnergyLdDataRight, INT *msDigest, INT *msMask,
+ const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup,
+ const INT *sfbOffset, const INT allowIS, INT *isBook, INT *isScale,
+ PNS_DATA *RESTRICT pnsData[2]);
+
+#endif /* INTENSITY_H */
diff --git a/fdk-aac/libAACenc/src/interface.h b/fdk-aac/libAACenc/src/interface.h
new file mode 100644
index 0000000..b1a31ef
--- /dev/null
+++ b/fdk-aac/libAACenc/src/interface.h
@@ -0,0 +1,168 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Interface psychoaccoustic/quantizer
+
+*******************************************************************************/
+
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#include "common_fix.h"
+#include "FDK_audio.h"
+
+#include "psy_data.h"
+#include "aacenc_tns.h"
+
+enum { MS_NONE = 0, MS_SOME = 1, MS_ALL = 2 };
+
+enum { MS_ON = 1 };
+
+struct TOOLSINFO {
+ INT msDigest; /* 0 = no MS; 1 = some MS, 2 = all MS */
+ INT msMask[MAX_GROUPED_SFB];
+};
+
+typedef struct {
+ INT sfbCnt;
+ INT sfbPerGroup;
+ INT maxSfbPerGroup;
+ INT lastWindowSequence;
+ INT windowShape;
+ INT groupingMask;
+ INT sfbOffsets[MAX_GROUPED_SFB + 1];
+
+ INT mdctScale; /* number of transform shifts */
+ INT groupLen[MAX_NO_OF_GROUPS];
+
+ TNS_INFO tnsInfo;
+ INT noiseNrg[MAX_GROUPED_SFB];
+ INT isBook[MAX_GROUPED_SFB];
+ INT isScale[MAX_GROUPED_SFB];
+
+ /* memory located in QC_OUT_CHANNEL */
+ FIXP_DBL *mdctSpectrum;
+ FIXP_DBL *sfbEnergy;
+ FIXP_DBL *sfbSpreadEnergy;
+ FIXP_DBL *sfbThresholdLdData;
+ FIXP_DBL *sfbMinSnrLdData;
+ FIXP_DBL *sfbEnergyLdData;
+
+} PSY_OUT_CHANNEL;
+
+typedef struct {
+ /* information specific to each channel */
+ PSY_OUT_CHANNEL *psyOutChannel[(2)];
+
+ /* information shared by both channels */
+ INT commonWindow;
+ struct TOOLSINFO toolsInfo;
+
+} PSY_OUT_ELEMENT;
+
+typedef struct {
+ PSY_OUT_ELEMENT *psyOutElement[((8))];
+ PSY_OUT_CHANNEL *pPsyOutChannels[(8)];
+
+} PSY_OUT;
+
+inline int isLowDelay(AUDIO_OBJECT_TYPE aot) {
+ return (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD);
+}
+
+#endif /* INTERFACE_H */
diff --git a/fdk-aac/libAACenc/src/line_pe.cpp b/fdk-aac/libAACenc/src/line_pe.cpp
new file mode 100644
index 0000000..47734e5
--- /dev/null
+++ b/fdk-aac/libAACenc/src/line_pe.cpp
@@ -0,0 +1,234 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Perceptual entropie module
+
+*******************************************************************************/
+
+#include "line_pe.h"
+#include "sf_estim.h"
+#include "bit_cnt.h"
+
+#include "genericStds.h"
+
+static const FIXP_DBL C1LdData =
+ FL2FXCONST_DBL(3.0 / LD_DATA_SCALING); /* C1 = 3.0 = log(8.0)/log(2) */
+static const FIXP_DBL C2LdData = FL2FXCONST_DBL(
+ 1.3219281 / LD_DATA_SCALING); /* C2 = 1.3219281 = log(2.5)/log(2) */
+static const FIXP_DBL C3LdData = FL2FXCONST_DBL(0.5593573); /* 1-C2/C1 */
+
+/* constants that do not change during successive pe calculations */
+void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData,
+ const FIXP_DBL *RESTRICT const sfbEnergyLdData,
+ const FIXP_DBL *RESTRICT const sfbThresholdLdData,
+ const FIXP_DBL *RESTRICT const sfbFormFactorLdData,
+ const INT *RESTRICT const sfbOffset,
+ const INT sfbCnt, const INT sfbPerGroup,
+ const INT maxSfbPerGroup) {
+ INT sfbGrp, sfb;
+ INT sfbWidth;
+ FIXP_DBL avgFormFactorLdData;
+ const FIXP_DBL formFacScaling =
+ FL2FXCONST_DBL((float)FORM_FAC_SHIFT / LD_DATA_SCALING);
+
+ for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) {
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ if ((FIXP_DBL)sfbEnergyLdData[sfbGrp + sfb] >
+ (FIXP_DBL)sfbThresholdLdData[sfbGrp + sfb]) {
+ sfbWidth = sfbOffset[sfbGrp + sfb + 1] - sfbOffset[sfbGrp + sfb];
+ /* estimate number of active lines */
+ avgFormFactorLdData = ((-sfbEnergyLdData[sfbGrp + sfb] >> 1) +
+ (CalcLdInt(sfbWidth) >> 1)) >>
+ 1;
+ peChanData->sfbNLines[sfbGrp + sfb] = (INT)CalcInvLdData(
+ (sfbFormFactorLdData[sfbGrp + sfb] + formFacScaling) +
+ avgFormFactorLdData);
+ /* Make sure sfbNLines is never greater than sfbWidth due to
+ * unaccuracies (e.g. sfbEnergyLdData[sfbGrp+sfb] = 0x80000000) */
+ peChanData->sfbNLines[sfbGrp + sfb] =
+ fMin(sfbWidth, peChanData->sfbNLines[sfbGrp + sfb]);
+ } else {
+ peChanData->sfbNLines[sfbGrp + sfb] = 0;
+ }
+ }
+ }
+}
+
+/*
+ formula for one sfb:
+ pe = n * ld(en/thr), if ld(en/thr) >= C1
+ pe = n * (C2 + C3 * ld(en/thr)), if ld(en/thr) < C1
+ n: estimated number of lines in sfb,
+ ld(x) = log(x)/log(2)
+
+ constPart is sfbPe without the threshold part n*ld(thr) or n*C3*ld(thr)
+*/
+void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData,
+ const FIXP_DBL *RESTRICT const sfbEnergyLdData,
+ const FIXP_DBL *RESTRICT const sfbThresholdLdData,
+ const INT sfbCnt, const INT sfbPerGroup,
+ const INT maxSfbPerGroup,
+ const INT *RESTRICT const isBook,
+ const INT *RESTRICT const isScale) {
+ INT sfbGrp, sfb, thisSfb;
+ INT nLines;
+ FIXP_DBL logDataRatio;
+ FIXP_DBL scaleLd = (FIXP_DBL)0;
+ INT lastValIs = 0;
+
+ FIXP_DBL pe = 0;
+ FIXP_DBL constPart = 0;
+ FIXP_DBL nActiveLines = 0;
+
+ FIXP_DBL tmpPe, tmpConstPart, tmpNActiveLines;
+
+ for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) {
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ tmpPe = (FIXP_DBL)0;
+ tmpConstPart = (FIXP_DBL)0;
+ tmpNActiveLines = (FIXP_DBL)0;
+
+ thisSfb = sfbGrp + sfb;
+
+ if (sfbEnergyLdData[thisSfb] > sfbThresholdLdData[thisSfb]) {
+ logDataRatio = sfbEnergyLdData[thisSfb] - sfbThresholdLdData[thisSfb];
+ nLines = peChanData->sfbNLines[thisSfb];
+
+ FIXP_DBL factor = nLines << (LD_DATA_SHIFT + PE_CONSTPART_SHIFT + 1);
+ if (logDataRatio >= C1LdData) {
+ /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */
+ tmpPe = fMultDiv2(logDataRatio, factor);
+ tmpConstPart = fMultDiv2(sfbEnergyLdData[thisSfb] + scaleLd, factor);
+ } else {
+ /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */
+ tmpPe = fMultDiv2(
+ ((FIXP_DBL)C2LdData + fMult(C3LdData, logDataRatio)), factor);
+ tmpConstPart =
+ fMultDiv2(((FIXP_DBL)C2LdData +
+ fMult(C3LdData, sfbEnergyLdData[thisSfb] + scaleLd)),
+ factor);
+
+ nLines = fMultI(C3LdData, nLines);
+ }
+ tmpNActiveLines = (FIXP_DBL)nLines;
+ } else if (isBook[thisSfb]) {
+ /* provide for cost of scale factor for Intensity */
+ INT delta = isScale[thisSfb] - lastValIs;
+ lastValIs = isScale[thisSfb];
+ peChanData->sfbPe[thisSfb] = FDKaacEnc_bitCountScalefactorDelta(delta)
+ << PE_CONSTPART_SHIFT;
+ peChanData->sfbConstPart[thisSfb] = 0;
+ peChanData->sfbNActiveLines[thisSfb] = 0;
+ }
+ peChanData->sfbPe[thisSfb] = tmpPe;
+ peChanData->sfbConstPart[thisSfb] = tmpConstPart;
+ peChanData->sfbNActiveLines[thisSfb] = tmpNActiveLines;
+
+ /* sum up peChanData values */
+ pe += tmpPe;
+ constPart += tmpConstPart;
+ nActiveLines += tmpNActiveLines;
+ }
+ }
+
+ /* correct scaled pe and constPart values */
+ peChanData->pe = pe >> PE_CONSTPART_SHIFT;
+ peChanData->constPart = constPart >> PE_CONSTPART_SHIFT;
+
+ peChanData->nActiveLines = nActiveLines;
+}
diff --git a/fdk-aac/libAACenc/src/line_pe.h b/fdk-aac/libAACenc/src/line_pe.h
new file mode 100644
index 0000000..ecc2388
--- /dev/null
+++ b/fdk-aac/libAACenc/src/line_pe.h
@@ -0,0 +1,148 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Perceptual entropie module
+
+*******************************************************************************/
+
+#ifndef LINE_PE_H
+#define LINE_PE_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+
+#define PE_CONSTPART_SHIFT FRACT_BITS
+
+typedef struct {
+ /* calculated by FDKaacEnc_prepareSfbPe */
+ INT sfbNLines[MAX_GROUPED_SFB]; /* number of relevant lines in sfb */
+ /* the rest is calculated by FDKaacEnc_calcSfbPe */
+ INT sfbPe[MAX_GROUPED_SFB]; /* pe for each sfb */
+ INT sfbConstPart[MAX_GROUPED_SFB]; /* constant part for each sfb */
+ INT sfbNActiveLines[MAX_GROUPED_SFB]; /* number of active lines in sfb */
+ INT pe; /* sum of sfbPe */
+ INT constPart; /* sum of sfbConstPart */
+ INT nActiveLines; /* sum of sfbNActiveLines */
+} PE_CHANNEL_DATA;
+
+typedef struct {
+ PE_CHANNEL_DATA peChannelData[(2)];
+ INT pe;
+ INT constPart;
+ INT nActiveLines;
+ INT offset;
+} PE_DATA;
+
+void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData,
+ const FIXP_DBL *RESTRICT const sfbEnergyLdData,
+ const FIXP_DBL *RESTRICT const sfbThresholdLdData,
+ const FIXP_DBL *RESTRICT const sfbFormFactorLdData,
+ const INT *RESTRICT const sfbOffset,
+ const INT sfbCnt, const INT sfbPerGroup,
+ const INT maxSfbPerGroup);
+
+void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData,
+ const FIXP_DBL *RESTRICT const sfbEnergyLdData,
+ const FIXP_DBL *RESTRICT const sfbThresholdLdData,
+ const INT sfbCnt, const INT sfbPerGroup,
+ const INT maxSfbPerGroup,
+ const INT *RESTRICT const isBook,
+ const INT *RESTRICT const isScale);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/metadata_compressor.cpp b/fdk-aac/libAACenc/src/metadata_compressor.cpp
new file mode 100644
index 0000000..bdac80a
--- /dev/null
+++ b/fdk-aac/libAACenc/src/metadata_compressor.cpp
@@ -0,0 +1,1579 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Neusinger
+
+ Description: Compressor for AAC Metadata Generator
+
+*******************************************************************************/
+
+#include "metadata_compressor.h"
+#include "channel_map.h"
+
+#define LOG2 0.69314718056f /* natural logarithm of 2 */
+#define ILOG2 1.442695041f /* 1/LOG2 */
+#define FIXP_ILOG2_DIV2 (FL2FXCONST_DBL(ILOG2 / 2))
+
+/*----------------- defines ----------------------*/
+
+#define MAX_DRC_CHANNELS (8) /*!< Max number of audio input channels. */
+#define DOWNMIX_SHIFT (3) /*!< Max 8 channel. */
+#define WEIGHTING_FILTER_SHIFT (2) /*!< Scaling used in weighting filter. */
+
+#define METADATA_INT_BITS 10
+#define METADATA_LINT_BITS 20
+#define METADATA_INT_SCALE (INT64(1) << (METADATA_INT_BITS))
+#define METADATA_FRACT_BITS (DFRACT_BITS - 1 - METADATA_INT_BITS)
+#define METADATA_FRACT_SCALE (INT64(1) << (METADATA_FRACT_BITS))
+
+/**
+ * Enum for channel assignment.
+ */
+enum { L = 0, R = 1, C = 2, LFE = 3, LS = 4, RS = 5, S = 6, LS2 = 7, RS2 = 8 };
+
+/*--------------- structure definitions --------------------*/
+
+/**
+ * Structure holds weighting filter filter states.
+ */
+struct WEIGHTING_STATES {
+ FIXP_DBL x1;
+ FIXP_DBL x2;
+ FIXP_DBL y1;
+ FIXP_DBL y2;
+};
+
+/**
+ * Dynamic Range Control compressor structure.
+ */
+struct DRC_COMP {
+ FIXP_DBL maxBoostThr[2]; /*!< Max boost threshold. */
+ FIXP_DBL boostThr[2]; /*!< Boost threshold. */
+ FIXP_DBL earlyCutThr[2]; /*!< Early cut threshold. */
+ FIXP_DBL cutThr[2]; /*!< Cut threshold. */
+ FIXP_DBL maxCutThr[2]; /*!< Max cut threshold. */
+
+ FIXP_DBL boostFac[2]; /*!< Precalculated factor for boost compression. */
+ FIXP_DBL
+ earlyCutFac[2]; /*!< Precalculated factor for early cut compression. */
+ FIXP_DBL cutFac[2]; /*!< Precalculated factor for cut compression. */
+
+ FIXP_DBL maxBoost[2]; /*!< Maximum boost. */
+ FIXP_DBL maxCut[2]; /*!< Maximum cut. */
+ FIXP_DBL maxEarlyCut[2]; /*!< Maximum early cut. */
+
+ FIXP_DBL fastAttack[2]; /*!< Fast attack coefficient. */
+ FIXP_DBL fastDecay[2]; /*!< Fast release coefficient. */
+ FIXP_DBL slowAttack[2]; /*!< Slow attack coefficient. */
+ FIXP_DBL slowDecay[2]; /*!< Slow release coefficient. */
+ UINT holdOff[2]; /*!< Hold time in blocks. */
+
+ FIXP_DBL attackThr[2]; /*!< Slow/fast attack threshold. */
+ FIXP_DBL decayThr[2]; /*!< Slow/fast release threshold. */
+
+ DRC_PROFILE profile[2]; /*!< DRC profile. */
+ INT blockLength; /*!< Block length in samples. */
+ UINT sampleRate; /*!< Sample rate. */
+ CHANNEL_MODE chanConfig; /*!< Channel configuration. */
+
+ UCHAR useWeighting; /*!< Use weighting filter. */
+
+ UINT channels; /*!< Number of channels. */
+ UINT fullChannels; /*!< Number of full range channels. */
+ INT channelIdx[9]; /*!< Offsets of interleaved channel samples (L, R, C, LFE,
+ Ls, Rs, S, Ls2, Rs2). */
+
+ FIXP_DBL smoothLevel[2]; /*!< level smoothing states */
+ FIXP_DBL smoothGain[2]; /*!< gain smoothing states */
+ UINT holdCnt[2]; /*!< hold counter */
+
+ FIXP_DBL limGain[2]; /*!< limiter gain */
+ FIXP_DBL limDecay; /*!< limiter decay (linear) */
+ FIXP_DBL prevPeak[2]; /*!< max peak of previous block (stereo/mono)*/
+
+ WEIGHTING_STATES
+ filter[MAX_DRC_CHANNELS]; /*!< array holds weighting filter states */
+};
+
+/*---------------- constants -----------------------*/
+
+/**
+ * Profile tables.
+ */
+static const FIXP_DBL tabMaxBoostThr[] = {
+ (FIXP_DBL)(-(43 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(53 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(55 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(65 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(50 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(40 << METADATA_FRACT_BITS))};
+static const FIXP_DBL tabBoostThr[] = {
+ (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(41 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(41 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(31 << METADATA_FRACT_BITS))};
+static const FIXP_DBL tabEarlyCutThr[] = {
+ (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(20 << METADATA_FRACT_BITS))};
+static const FIXP_DBL tabCutThr[] = {(FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(11 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
+ (FIXP_DBL)(-(10 << METADATA_FRACT_BITS))};
+static const FIXP_DBL tabMaxCutThr[] = {
+ (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(9 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(9 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(4 << METADATA_FRACT_BITS)};
+static const FIXP_DBL tabBoostRatio[] = {
+ FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 5.f) - 1.f)), FL2FXCONST_DBL(((1.f / 5.f) - 1.f))};
+static const FIXP_DBL tabEarlyCutRatio[] = {
+ FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 1.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f))};
+static const FIXP_DBL tabCutRatio[] = {
+ FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 20.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
+ FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 20.f) - 1.f))};
+static const FIXP_DBL tabMaxBoost[] = {(FIXP_DBL)(6 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(6 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(12 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(12 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS)};
+static const FIXP_DBL tabMaxCut[] = {(FIXP_DBL)(24 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(24 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(24 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(24 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(24 << METADATA_FRACT_BITS)};
+static const FIXP_DBL tabFastAttack[] = {
+ FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
+static const FIXP_DBL tabFastDecay[] = {
+ FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((200.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
+static const FIXP_DBL tabSlowAttack[] = {
+ FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
+static const FIXP_DBL tabSlowDecay[] = {
+ FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((10000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
+ FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
+
+static const INT tabHoldOff[] = {10, 10, 10, 10, 10, 0};
+
+static const FIXP_DBL tabAttackThr[] = {(FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(15 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(10 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(0 << METADATA_FRACT_BITS)};
+static const FIXP_DBL tabDecayThr[] = {(FIXP_DBL)(20 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(20 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(20 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(20 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(10 << METADATA_FRACT_BITS),
+ (FIXP_DBL)(0 << METADATA_FRACT_BITS)};
+
+/**
+ * Weighting filter coefficients (biquad bandpass).
+ */
+static const FIXP_DBL b0 = FL2FXCONST_DBL(0.53050662f); /* b1 = 0, b2 = -b0 */
+static const FIXP_DBL a1 = FL2FXCONST_DBL(-0.95237983f),
+ a2 = FL2FXCONST_DBL(-0.02248836f); /* a0 = 1 */
+
+/*------------- function definitions ----------------*/
+
+/**
+ * \brief Calculate scaling factor for denoted processing block.
+ *
+ * \param blockLength Length of processing block.
+ *
+ * \return shiftFactor
+ */
+static UINT getShiftFactor(const UINT length) {
+ UINT ldN;
+ for (ldN = 1; (((UINT)1) << ldN) < length; ldN++)
+ ;
+
+ return ldN;
+}
+
+/**
+ * \brief Sum up fixpoint values with best possible accuracy.
+ *
+ * \param value1 First input value.
+ * \param q1 Scaling factor of first input value.
+ * \param pValue2 Pointer to second input value, will be modified on
+ * return.
+ * \param pQ2 Pointer to second scaling factor, will be modified on
+ * return.
+ *
+ * \return void
+ */
+static void fixpAdd(const FIXP_DBL value1, const int q1,
+ FIXP_DBL* const pValue2, int* const pQ2) {
+ const int headroom1 = fNormz(fixp_abs(value1)) - 1;
+ const int headroom2 = fNormz(fixp_abs(*pValue2)) - 1;
+ int resultScale = fixMax(q1 - headroom1, (*pQ2) - headroom2);
+
+ if ((value1 != FL2FXCONST_DBL(0.f)) && (*pValue2 != FL2FXCONST_DBL(0.f))) {
+ resultScale++;
+ }
+
+ *pValue2 = scaleValue(value1, q1 - resultScale) +
+ scaleValue(*pValue2, (*pQ2) - resultScale);
+ *pQ2 = (*pValue2 != (FIXP_DBL)0) ? resultScale : DFRACT_BITS - 1;
+}
+
+/**
+ * \brief Function for converting time constant to filter coefficient.
+ *
+ * \param t Time constant.
+ * \param sampleRate Sampling rate in Hz.
+ * \param blockLength Length of processing block in samples per channel.
+ *
+ * \return result = 1.0 - exp(-1.0/((t) * (f)))
+ */
+static FIXP_DBL tc2Coeff(const FIXP_DBL t, const INT sampleRate,
+ const INT blockLength) {
+ FIXP_DBL sampleRateFract;
+ FIXP_DBL blockLengthFract;
+ FIXP_DBL f, product;
+ FIXP_DBL exponent, result;
+ INT e_res;
+
+ /* f = sampleRate/blockLength */
+ sampleRateFract =
+ (FIXP_DBL)(sampleRate << (DFRACT_BITS - 1 - METADATA_LINT_BITS));
+ blockLengthFract =
+ (FIXP_DBL)(blockLength << (DFRACT_BITS - 1 - METADATA_LINT_BITS));
+ f = fDivNorm(sampleRateFract, blockLengthFract, &e_res);
+ f = scaleValue(f, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */
+
+ /* product = t*f */
+ product = fMultNorm(t, f, &e_res);
+ product = scaleValue(
+ product, e_res + METADATA_INT_BITS); /* convert to METADATA_FRACT */
+
+ /* exponent = (-1.0/((t) * (f))) */
+ exponent = fDivNorm(METADATA_FRACT_SCALE, product, &e_res);
+ exponent = scaleValue(
+ exponent, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */
+
+ /* exponent * ld(e) */
+ exponent = fMult(exponent, FIXP_ILOG2_DIV2) << 1; /* e^(x) = 2^(x*ld(e)) */
+
+ /* exp(-1.0/((t) * (f))) */
+ result = f2Pow(-exponent, DFRACT_BITS - 1 - METADATA_FRACT_BITS, &e_res);
+
+ /* result = 1.0 - exp(-1.0/((t) * (f))) */
+ result = (FIXP_DBL)MAXVAL_DBL - scaleValue(result, e_res);
+
+ return result;
+}
+
+static void findPeakLevels(HDRC_COMP drcComp, const INT_PCM* const inSamples,
+ const FIXP_DBL clev, const FIXP_DBL slev,
+ const FIXP_DBL ext_leva, const FIXP_DBL ext_levb,
+ const FIXP_DBL lfe_lev, const FIXP_DBL dmxGain5,
+ const FIXP_DBL dmxGain2, FIXP_DBL peak[2]) {
+ int i, c;
+ FIXP_DBL tmp = FL2FXCONST_DBL(0.f);
+ INT_PCM maxSample = 0;
+
+ /* find peak level */
+ peak[0] = peak[1] = FL2FXCONST_DBL(0.f);
+ for (i = 0; i < drcComp->blockLength; i++) {
+ const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
+
+ /* single channels */
+ for (c = 0; c < (int)drcComp->channels; c++) {
+ maxSample = fMax(maxSample, (INT_PCM)fAbs(pSamples[c]));
+ }
+ }
+ peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample) >> DOWNMIX_SHIFT);
+
+ /* 7.1/6.1 to 5.1 downmixes */
+ if (drcComp->fullChannels > 5) {
+ for (i = 0; i < drcComp->blockLength; i++) {
+ const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
+
+ /* channel 1 (L, Ls,...) */
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_6_1:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
+ (DOWNMIX_SHIFT - 1); /* Cs */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lrs / Lss */
+ break;
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ (DOWNMIX_SHIFT - 1); /* L */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lvh */
+ break;
+ default:
+ break;
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+
+ /* channel 2 (R, Rs,...) */
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_6_1:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
+ (DOWNMIX_SHIFT - 1); /* Cs */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rrs / Rss */
+ break;
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ (DOWNMIX_SHIFT - 1); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rvh */
+ break;
+ default:
+ break;
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+
+ /* channel 3 (C) */
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ DOWNMIX_SHIFT); /* C */
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc */
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc */
+ break;
+ default:
+ break;
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+
+ } /* for (blocklength) */
+
+ /* take downmix gain into accout */
+ peak[0] = fMult(dmxGain5, peak[0])
+ << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+
+ /* 7.1 / 5.1 to stereo downmixes */
+ if (drcComp->fullChannels > 2) {
+ /* Lt/Rt downmix */
+ for (i = 0; i < drcComp->blockLength; i++) {
+ const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
+
+ /* Lt */
+ tmp = FL2FXCONST_DBL(0.f);
+ if (drcComp->channelIdx[LS] >= 0)
+ tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ if (drcComp->channelIdx[LS2] >= 0)
+ tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls2 */
+ if (drcComp->channelIdx[RS] >= 0)
+ tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ if (drcComp->channelIdx[RS2] >= 0)
+ tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs2 */
+ if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
+ tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
+ if (drcComp->channelIdx[S] >= 0)
+ tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >>
+ (DOWNMIX_SHIFT - 1); /* S */
+ if (drcComp->channelIdx[C] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
+ DOWNMIX_SHIFT); /* L */
+
+ /* apply scaling of downmix gains */
+ /* only for positive values only, as legacy decoders might not know this
+ * parameter */
+ if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
+ if (drcComp->fullChannels > 5) {
+ tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+
+ /* Rt */
+ tmp = FL2FXCONST_DBL(0.f);
+ if (drcComp->channelIdx[LS] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ if (drcComp->channelIdx[LS2] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls2 */
+ if (drcComp->channelIdx[RS] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ if (drcComp->channelIdx[RS2] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs2 */
+ if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0))
+ tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
+ if (drcComp->channelIdx[S] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >>
+ (DOWNMIX_SHIFT - 1); /* S */
+ if (drcComp->channelIdx[C] >= 0)
+ tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
+ DOWNMIX_SHIFT); /* R */
+
+ /* apply scaling of downmix gains */
+ /* only for positive values only, as legacy decoders might not know this
+ * parameter */
+ if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
+ if (drcComp->fullChannels > 5) {
+ tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+ }
+
+ /* Lo/Ro downmix */
+ for (i = 0; i < drcComp->blockLength; i++) {
+ const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
+
+ /* Lo */
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_6_1:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
+ (DOWNMIX_SHIFT - 1); /* Cs */
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc */
+ tmp += fMultDiv2(fMult(ext_leva, clev),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc - second path*/
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ (DOWNMIX_SHIFT - 1); /* L */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lvh */
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ default:
+ if (drcComp->channelIdx[LS] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ if (drcComp->channelIdx[LS2] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls2 */
+ if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
+ tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
+ if (drcComp->channelIdx[S] >= 0)
+ tmp +=
+ fMultDiv2(slev,
+ fMult(FL2FXCONST_DBL(0.7f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
+ (DOWNMIX_SHIFT - 1); /* S */
+ if (drcComp->channelIdx[C] >= 0)
+ tmp +=
+ fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ if (drcComp->channelIdx[3] >= 0)
+ tmp += fMultDiv2(lfe_lev,
+ (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
+ DOWNMIX_SHIFT); /* L */
+ break;
+ }
+
+ /* apply scaling of downmix gains */
+ /* only for positive values only, as legacy decoders might not know this
+ * parameter */
+ if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
+ if (drcComp->fullChannels > 5) {
+ tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+
+ /* Ro */
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_6_1:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
+ (DOWNMIX_SHIFT - 1); /* Cs */
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc */
+ tmp += fMultDiv2(fMult(ext_leva, clev),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc - second path*/
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ (DOWNMIX_SHIFT - 1); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rvh */
+ tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp +=
+ fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ default:
+ if (drcComp->channelIdx[RS] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ if (drcComp->channelIdx[RS2] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs2 */
+ if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0))
+ tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
+ if (drcComp->channelIdx[S] >= 0)
+ tmp +=
+ fMultDiv2(slev,
+ fMult(FL2FXCONST_DBL(0.7f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
+ (DOWNMIX_SHIFT - 1); /* S */
+ if (drcComp->channelIdx[C] >= 0)
+ tmp +=
+ fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ if (drcComp->channelIdx[3] >= 0)
+ tmp += fMultDiv2(lfe_lev,
+ (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
+ DOWNMIX_SHIFT); /* R */
+ }
+
+ /* apply scaling of downmix gains */
+ /* only for positive values only, as legacy decoders might not know this
+ * parameter */
+ if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
+ if (drcComp->fullChannels > 5) {
+ tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ peak[0] = fixMax(peak[0], fixp_abs(tmp));
+ }
+ }
+
+ peak[1] = fixMax(peak[0], peak[1]);
+
+ /* Mono Downmix - for comp_val only */
+ if (drcComp->fullChannels > 1) {
+ for (i = 0; i < drcComp->blockLength; i++) {
+ const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
+
+ tmp = FL2FXCONST_DBL(0.f);
+ switch (drcComp->chanConfig) {
+ case MODE_6_1:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMult(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
+ (DOWNMIX_SHIFT - 1); /* Cs */
+ tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(fMult(slev, ext_leva),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/
+ tmp += fMultDiv2(fMult(slev, ext_levb),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/
+ tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_1_2_2_2_1:
+ case MODE_7_1_FRONT_CENTER:
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ DOWNMIX_SHIFT); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc */
+ tmp += fMultDiv2(fMult(ext_leva, clev),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lc - second path*/
+ tmp += fMultDiv2(fMult(ext_leva, clev),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rc - second path*/
+ tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
+ (DOWNMIX_SHIFT - 1); /* L */
+ tmp +=
+ fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
+ (DOWNMIX_SHIFT - 1); /* R */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
+ (DOWNMIX_SHIFT - 1); /* Lvh */
+ tmp +=
+ fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rvh */
+ tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
+ (DOWNMIX_SHIFT - 1); /* C */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ break;
+ default:
+ if (drcComp->channelIdx[LS] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls */
+ if (drcComp->channelIdx[LS2] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Ls2 */
+ if (drcComp->channelIdx[RS] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs */
+ if (drcComp->channelIdx[RS2] >= 0)
+ tmp +=
+ fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
+ (DOWNMIX_SHIFT - 1); /* Rs2 */
+ if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
+ tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
+ /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */
+ if (drcComp->channelIdx[S] >= 0)
+ tmp +=
+ fMultDiv2(slev,
+ fMult(FL2FXCONST_DBL(0.7f),
+ (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
+ (DOWNMIX_SHIFT - 1); /* S */
+ if (drcComp->channelIdx[C] >= 0)
+ tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
+ (DOWNMIX_SHIFT - 1); /* C (2*clev) */
+ if (drcComp->channelIdx[3] >= 0)
+ tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
+ (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
+ DOWNMIX_SHIFT); /* L */
+ tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
+ DOWNMIX_SHIFT); /* R */
+ }
+
+ /* apply scaling of downmix gains */
+ /* only for positive values only, as legacy decoders might not know this
+ * parameter */
+ if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
+ if (drcComp->fullChannels > 5) {
+ tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
+ }
+ peak[1] = fixMax(peak[1], fixp_abs(tmp));
+ }
+ }
+}
+
+INT FDK_DRC_Generator_Open(HDRC_COMP* phDrcComp) {
+ INT err = 0;
+ HDRC_COMP hDcComp = NULL;
+
+ if (phDrcComp == NULL) {
+ err = -1;
+ goto bail;
+ }
+
+ /* allocate memory */
+ hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP));
+
+ if (hDcComp == NULL) {
+ err = -1;
+ goto bail;
+ }
+
+ FDKmemclear(hDcComp, sizeof(DRC_COMP));
+
+ /* Return drc compressor instance */
+ *phDrcComp = hDcComp;
+ return err;
+bail:
+ FDK_DRC_Generator_Close(&hDcComp);
+ return err;
+}
+
+INT FDK_DRC_Generator_Close(HDRC_COMP* phDrcComp) {
+ if (phDrcComp == NULL) {
+ return -1;
+ }
+ if (*phDrcComp != NULL) {
+ FDKfree(*phDrcComp);
+ *phDrcComp = NULL;
+ }
+ return 0;
+}
+
+INT FDK_DRC_Generator_Initialize(HDRC_COMP drcComp,
+ const DRC_PROFILE profileLine,
+ const DRC_PROFILE profileRF,
+ const INT blockLength, const UINT sampleRate,
+ const CHANNEL_MODE channelMode,
+ const CHANNEL_ORDER channelOrder,
+ const UCHAR useWeighting) {
+ int i;
+ CHANNEL_MAPPING channelMapping;
+
+ drcComp->limDecay =
+ FL2FXCONST_DBL(((0.006f / 256) * blockLength) / METADATA_INT_SCALE);
+
+ /* Save parameters. */
+ drcComp->blockLength = blockLength;
+ drcComp->sampleRate = sampleRate;
+ drcComp->chanConfig = channelMode;
+ drcComp->useWeighting = useWeighting;
+
+ if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF) !=
+ 0) { /* expects initialized blockLength and sampleRate */
+ return (-1);
+ }
+
+ /* Set number of channels and channel offsets. */
+ if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder,
+ &channelMapping) != AAC_ENC_OK) {
+ return (-2);
+ }
+
+ for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1;
+
+ switch (channelMode) {
+ case MODE_1: /* mono */
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
+ break;
+ case MODE_2: /* stereo */
+ drcComp->channelIdx[L] = channelMapping.elInfo[0].ChannelIndex[0];
+ drcComp->channelIdx[R] = channelMapping.elInfo[0].ChannelIndex[1];
+ break;
+ case MODE_1_2: /* 3ch */
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
+ break;
+ case MODE_1_2_1: /* 4ch */
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
+ drcComp->channelIdx[S] = channelMapping.elInfo[2].ChannelIndex[0];
+ break;
+ case MODE_1_2_2: /* 5ch */
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
+ drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0];
+ drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1];
+ break;
+ case MODE_1_2_2_1: /* 5.1 ch */
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
+ drcComp->channelIdx[LFE] = channelMapping.elInfo[3].ChannelIndex[0];
+ drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0];
+ drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1];
+ break;
+ case MODE_1_2_2_2_1: /* 7.1 ch */
+ case MODE_7_1_FRONT_CENTER:
+ drcComp->channelIdx[L] = channelMapping.elInfo[2].ChannelIndex[0]; /* l */
+ drcComp->channelIdx[R] = channelMapping.elInfo[2].ChannelIndex[1]; /* r */
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
+ drcComp->channelIdx[LFE] =
+ channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
+ drcComp->channelIdx[LS] =
+ channelMapping.elInfo[3].ChannelIndex[0]; /* ls */
+ drcComp->channelIdx[RS] =
+ channelMapping.elInfo[3].ChannelIndex[1]; /* rs */
+ drcComp->channelIdx[LS2] =
+ channelMapping.elInfo[1].ChannelIndex[0]; /* lc */
+ drcComp->channelIdx[RS2] =
+ channelMapping.elInfo[1].ChannelIndex[1]; /* rc */
+ break;
+ case MODE_7_1_BACK:
+ case MODE_7_1_REAR_SURROUND:
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
+ drcComp->channelIdx[LFE] =
+ channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
+ drcComp->channelIdx[LS] =
+ channelMapping.elInfo[3].ChannelIndex[0]; /* lrear */
+ drcComp->channelIdx[RS] =
+ channelMapping.elInfo[3].ChannelIndex[1]; /* rrear */
+ drcComp->channelIdx[LS2] =
+ channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
+ drcComp->channelIdx[RS2] =
+ channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
+ break;
+ case MODE_6_1:
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
+ drcComp->channelIdx[LFE] =
+ channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
+ drcComp->channelIdx[LS] =
+ channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
+ drcComp->channelIdx[RS] =
+ channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
+ drcComp->channelIdx[S] = channelMapping.elInfo[3].ChannelIndex[0]; /* s */
+ break;
+ case MODE_7_1_TOP_FRONT:
+ drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
+ drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
+ drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
+ drcComp->channelIdx[LFE] =
+ channelMapping.elInfo[3].ChannelIndex[0]; /* lfe */
+ drcComp->channelIdx[LS] =
+ channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
+ drcComp->channelIdx[RS] =
+ channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
+ drcComp->channelIdx[LS2] =
+ channelMapping.elInfo[4].ChannelIndex[0]; /* lvh2 */
+ drcComp->channelIdx[RS2] =
+ channelMapping.elInfo[4].ChannelIndex[1]; /* rvh2 */
+ break;
+ default:
+ return (-1);
+ }
+
+ drcComp->fullChannels = channelMapping.nChannelsEff;
+ drcComp->channels = channelMapping.nChannels;
+
+ /* Init states. */
+ drcComp->smoothLevel[0] = drcComp->smoothLevel[1] =
+ (FIXP_DBL)(-(135 << METADATA_FRACT_BITS));
+
+ FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain));
+ FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt));
+ FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain));
+ FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak));
+ FDKmemclear(drcComp->filter, sizeof(drcComp->filter));
+
+ return (0);
+}
+
+INT FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp,
+ const DRC_PROFILE profileLine,
+ const DRC_PROFILE profileRF) {
+ int profileIdx, i;
+
+ drcComp->profile[0] = profileLine;
+ drcComp->profile[1] = profileRF;
+
+ for (i = 0; i < 2; i++) {
+ /* get profile index */
+ switch (drcComp->profile[i]) {
+ case DRC_NONE:
+ case DRC_NOT_PRESENT:
+ case DRC_FILMSTANDARD:
+ profileIdx = 0;
+ break;
+ case DRC_FILMLIGHT:
+ profileIdx = 1;
+ break;
+ case DRC_MUSICSTANDARD:
+ profileIdx = 2;
+ break;
+ case DRC_MUSICLIGHT:
+ profileIdx = 3;
+ break;
+ case DRC_SPEECH:
+ profileIdx = 4;
+ break;
+ case DRC_DELAY_TEST:
+ profileIdx = 5;
+ break;
+ default:
+ return (-1);
+ }
+
+ /* get parameters for selected profile */
+ if (profileIdx >= 0) {
+ drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx];
+ drcComp->boostThr[i] = tabBoostThr[profileIdx];
+ drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx];
+ drcComp->cutThr[i] = tabCutThr[profileIdx];
+ drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx];
+
+ drcComp->boostFac[i] = tabBoostRatio[profileIdx];
+ drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx];
+ drcComp->cutFac[i] = tabCutRatio[profileIdx];
+
+ drcComp->maxBoost[i] = tabMaxBoost[profileIdx];
+ drcComp->maxCut[i] = tabMaxCut[profileIdx];
+ drcComp->maxEarlyCut[i] =
+ -fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]),
+ drcComp->earlyCutFac[i]); /* no scaling after mult needed,
+ earlyCutFac is in FIXP_DBL */
+
+ drcComp->fastAttack[i] = tc2Coeff(
+ tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
+ drcComp->fastDecay[i] = tc2Coeff(
+ tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
+ drcComp->slowAttack[i] = tc2Coeff(
+ tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
+ drcComp->slowDecay[i] = tc2Coeff(
+ tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
+ drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength;
+
+ drcComp->attackThr[i] = tabAttackThr[profileIdx];
+ drcComp->decayThr[i] = tabDecayThr[profileIdx];
+ }
+
+ drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
+ }
+ return (0);
+}
+
+INT FDK_DRC_Generator_Calc(HDRC_COMP drcComp, const INT_PCM* const inSamples,
+ const UINT inSamplesBufSize, const INT dialnorm,
+ const INT drc_TargetRefLevel,
+ const INT comp_TargetRefLevel, const FIXP_DBL clev,
+ const FIXP_DBL slev, const FIXP_DBL ext_leva,
+ const FIXP_DBL ext_levb, const FIXP_DBL lfe_lev,
+ const INT dmxGain5, const INT dmxGain2,
+ INT* const pDynrng, INT* const pCompr) {
+ int i, c;
+ FIXP_DBL peak[2];
+
+ /**************************************************************************
+ * compressor
+ **************************************************************************/
+ if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) {
+ /* Calc loudness level */
+ FIXP_DBL level_b = FL2FXCONST_DBL(0.f);
+ int level_e = DFRACT_BITS - 1;
+
+ /* Increase energy time resolution with shorter processing blocks. 16 is an
+ * empiric value. */
+ const int granuleLength = fixMin(16, drcComp->blockLength);
+
+ if (drcComp->useWeighting) {
+ FIXP_DBL x1, x2, y, y1, y2;
+ /* sum of filter coefficients about 2.5 -> squared value is 6.25
+ WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce
+ granuleShift by 1.
+ */
+ const int granuleShift = getShiftFactor(granuleLength) - 1;
+
+ for (c = 0; c < (int)drcComp->channels; c++) {
+ const INT_PCM* pSamples = inSamples + c * inSamplesBufSize;
+
+ if (c == drcComp->channelIdx[LFE]) {
+ continue; /* skip LFE */
+ }
+
+ /* get filter states */
+ x1 = drcComp->filter[c].x1;
+ x2 = drcComp->filter[c].x2;
+ y1 = drcComp->filter[c].y1;
+ y2 = drcComp->filter[c].y2;
+
+ i = 0;
+
+ do {
+ int offset = i;
+ FIXP_DBL accu = FL2FXCONST_DBL(0.f);
+
+ for (i = offset;
+ i < fixMin(offset + granuleLength, drcComp->blockLength); i++) {
+ /* apply weighting filter */
+ FIXP_DBL x =
+ FX_PCM2FX_DBL((FIXP_PCM)pSamples[i]) >> WEIGHTING_FILTER_SHIFT;
+
+ /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */
+ y = fMult(b0, x - x2) - fMult(a1, y1) - fMult(a2, y2);
+
+ x2 = x1;
+ x1 = x;
+ y2 = y1;
+ y1 = y;
+
+ accu += fPow2Div2(y) >> (granuleShift - 1); /* partial energy */
+ } /* i */
+
+ fixpAdd(accu, granuleShift + 2 * WEIGHTING_FILTER_SHIFT, &level_b,
+ &level_e); /* sup up partial energies */
+
+ } while (i < drcComp->blockLength);
+
+ /* save filter states */
+ drcComp->filter[c].x1 = x1;
+ drcComp->filter[c].x2 = x2;
+ drcComp->filter[c].y1 = y1;
+ drcComp->filter[c].y2 = y2;
+ } /* c */
+ } /* weighting */
+ else {
+ const int granuleShift = getShiftFactor(granuleLength);
+
+ for (c = 0; c < (int)drcComp->channels; c++) {
+ const INT_PCM* pSamples = inSamples + c * inSamplesBufSize;
+
+ if ((int)c == drcComp->channelIdx[LFE]) {
+ continue; /* skip LFE */
+ }
+
+ i = 0;
+
+ do {
+ int offset = i;
+ FIXP_DBL accu = FL2FXCONST_DBL(0.f);
+
+ for (i = offset;
+ i < fixMin(offset + granuleLength, drcComp->blockLength); i++) {
+ /* partial energy */
+ accu += fPow2Div2((FIXP_PCM)pSamples[i]) >> (granuleShift - 1);
+ } /* i */
+
+ fixpAdd(accu, granuleShift, &level_b,
+ &level_e); /* sup up partial energies */
+
+ } while (i < drcComp->blockLength);
+ }
+ } /* weighting */
+
+ /*
+ * Convert to dBFS, apply dialnorm
+ */
+ /* level scaling */
+
+ /* descaled level in ld64 representation */
+ FIXP_DBL ldLevel =
+ CalcLdData(level_b) +
+ (FIXP_DBL)((level_e - 12) << (DFRACT_BITS - 1 - LD_DATA_SHIFT)) -
+ CalcLdData((FIXP_DBL)(drcComp->blockLength << (DFRACT_BITS - 1 - 12)));
+
+ /* if (level < 1e-10) level = 1e-10f; */
+ ldLevel =
+ fMax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f));
+
+ /* level = 10 * log(level)/log(10) + 3;
+ * = 10*log(2)/log(10) * ld(level) + 3;
+ * = 10 * 0.30102999566398119521373889472449 * ld(level) + 3
+ * = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3)
+ * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64)
+ * * 64
+ *
+ * additional scaling with METADATA_FRACT_BITS:
+ * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64)
+ * * 64 * 2^(METADATA_FRACT_BITS) = 10 * (0.30102999566398119521373889472449
+ * * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) =
+ * 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * (
+ * 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 )
+ * */
+ FIXP_DBL level = fMult(
+ (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)),
+ fMult(FL2FXCONST_DBL(0.30102999566398119521373889472449f), ldLevel) +
+ (FIXP_DBL)(FL2FXCONST_DBL(0.3f) >> LD_DATA_SHIFT));
+
+ /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as
+ compressor profiles are defined relative to
+ this */
+ level -= ((FIXP_DBL)(dialnorm << (METADATA_FRACT_BITS - 16)) +
+ (FIXP_DBL)(31 << METADATA_FRACT_BITS));
+
+ for (i = 0; i < 2; i++) {
+ if (drcComp->profile[i] == DRC_NONE) {
+ /* no compression */
+ drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
+ } else {
+ FIXP_DBL gain, alpha, lvl2smthlvl;
+
+ /* calc static gain */
+ if (level <= drcComp->maxBoostThr[i]) {
+ /* max boost */
+ gain = drcComp->maxBoost[i];
+ } else if (level < drcComp->boostThr[i]) {
+ /* boost range */
+ gain = fMult((level - drcComp->boostThr[i]), drcComp->boostFac[i]);
+ } else if (level <= drcComp->earlyCutThr[i]) {
+ /* null band */
+ gain = FL2FXCONST_DBL(0.f);
+ } else if (level <= drcComp->cutThr[i]) {
+ /* early cut range */
+ gain =
+ fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]);
+ } else if (level < drcComp->maxCutThr[i]) {
+ /* cut range */
+ gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) -
+ drcComp->maxEarlyCut[i];
+ } else {
+ /* max cut */
+ gain = -drcComp->maxCut[i];
+ }
+
+ /* choose time constant */
+ lvl2smthlvl = level - drcComp->smoothLevel[i];
+ if (gain < drcComp->smoothGain[i]) {
+ /* attack */
+ if (lvl2smthlvl > drcComp->attackThr[i]) {
+ /* fast attack */
+ alpha = drcComp->fastAttack[i];
+ } else {
+ /* slow attack */
+ alpha = drcComp->slowAttack[i];
+ }
+ } else {
+ /* release */
+ if (lvl2smthlvl < -drcComp->decayThr[i]) {
+ /* fast release */
+ alpha = drcComp->fastDecay[i];
+ } else {
+ /* slow release */
+ alpha = drcComp->slowDecay[i];
+ }
+ }
+
+ /* smooth gain & level */
+ if ((gain < drcComp->smoothGain[i]) ||
+ (drcComp->holdCnt[i] ==
+ 0)) { /* hold gain unless we have an attack or hold
+ period is over */
+ FIXP_DBL accu;
+
+ /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] +
+ * alpha * level; */
+ accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothLevel[i]);
+ accu += fMult(alpha, level);
+ drcComp->smoothLevel[i] = accu;
+
+ /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] +
+ * alpha * gain; */
+ accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothGain[i]);
+ accu += fMult(alpha, gain);
+ drcComp->smoothGain[i] = accu;
+ }
+
+ /* hold counter */
+ if (drcComp->holdCnt[i]) {
+ drcComp->holdCnt[i]--;
+ }
+ if (gain < drcComp->smoothGain[i]) {
+ drcComp->holdCnt[i] = drcComp->holdOff[i];
+ }
+ } /* profile != DRC_NONE */
+ } /* for i=1..2 */
+ } else {
+ /* no compression */
+ drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f);
+ drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f);
+ }
+
+ /**************************************************************************
+ * limiter
+ **************************************************************************/
+
+ findPeakLevels(drcComp, inSamples, clev, slev, ext_leva, ext_levb, lfe_lev,
+ (FIXP_DBL)((LONG)(dmxGain5) << (METADATA_FRACT_BITS - 16)),
+ (FIXP_DBL)((LONG)(dmxGain2) << (METADATA_FRACT_BITS - 16)),
+ peak);
+
+ for (i = 0; i < 2; i++) {
+ FIXP_DBL tmp = drcComp->prevPeak[i];
+ drcComp->prevPeak[i] = peak[i];
+ peak[i] = fixMax(peak[i], tmp);
+
+ /*
+ * Convert to dBFS, apply dialnorm
+ */
+ /* descaled peak in ld64 representation */
+ FIXP_DBL ld_peak =
+ CalcLdData(peak[i]) +
+ (FIXP_DBL)((LONG)DOWNMIX_SHIFT << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
+
+ /* if (peak < 1e-6) level = 1e-6f; */
+ ld_peak =
+ fMax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f));
+
+ /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f +
+ * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 20 *
+ * log(2)/log(10) * ld(peak[i]) + 0.2f +
+ * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 10 *
+ * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f +
+ * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
+ *
+ * additional scaling with METADATA_FRACT_BITS:
+ * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64
+ * + 0.2f +
+ * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS)
+ * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) *
+ * 2*0.30102999566398119521373889472449 * ld64(peak[i])
+ * + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i]
+ */
+ peak[i] = fMult(
+ (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)),
+ fMult(FL2FX_DBL(2 * 0.30102999566398119521373889472449f), ld_peak));
+ peak[i] +=
+ (FL2FX_DBL(0.5f) >> METADATA_INT_BITS); /* add a little bit headroom */
+ peak[i] += drcComp->smoothGain[i];
+ }
+
+ /* peak -= dialnorm + 31; */ /* this is Dolby style only */
+ peak[0] -= (FIXP_DBL)((dialnorm - drc_TargetRefLevel)
+ << (METADATA_FRACT_BITS -
+ 16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */
+
+ /* peak += 11; */
+ /* this is Dolby style only */ /* RF mode output is 11dB higher */
+ /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/
+ peak[1] -=
+ (FIXP_DBL)((dialnorm - comp_TargetRefLevel)
+ << (METADATA_FRACT_BITS -
+ 16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */
+
+ /* limiter gain */
+ drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */
+ drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]);
+
+ drcComp->limGain[1] += 2 * drcComp->limDecay; /* linear limiter release */
+ drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]);
+
+ /*************************************************************************/
+
+ /* apply limiting, return DRC gains*/
+ {
+ FIXP_DBL tmp;
+
+ tmp = drcComp->smoothGain[0];
+ if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) {
+ tmp += drcComp->limGain[0];
+ }
+ *pDynrng = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16));
+
+ tmp = drcComp->smoothGain[1];
+ if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) {
+ tmp += drcComp->limGain[1];
+ }
+ *pCompr = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16));
+ }
+
+ return 0;
+}
+
+DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp) {
+ return drcComp->profile[0];
+}
+
+DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp) {
+ return drcComp->profile[1];
+}
diff --git a/fdk-aac/libAACenc/src/metadata_compressor.h b/fdk-aac/libAACenc/src/metadata_compressor.h
new file mode 100644
index 0000000..1d0aa42
--- /dev/null
+++ b/fdk-aac/libAACenc/src/metadata_compressor.h
@@ -0,0 +1,255 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Neusinger
+
+ Description: Compressor for AAC Metadata Generator
+
+*******************************************************************************/
+
+#ifndef METADATA_COMPRESSOR_H
+#define METADATA_COMPRESSOR_H
+
+#include "FDK_audio.h"
+#include "common_fix.h"
+
+#include "aacenc.h"
+
+#define LFE_LEV_SCALE 2
+
+/**
+ * DRC compression profiles.
+ */
+typedef enum DRC_PROFILE {
+ DRC_NONE = 0,
+ DRC_FILMSTANDARD = 1,
+ DRC_FILMLIGHT = 2,
+ DRC_MUSICSTANDARD = 3,
+ DRC_MUSICLIGHT = 4,
+ DRC_SPEECH = 5,
+ DRC_DELAY_TEST = 6,
+ DRC_NOT_PRESENT = -2
+
+} DRC_PROFILE;
+
+/**
+ * DRC Compressor handle.
+ */
+typedef struct DRC_COMP DRC_COMP, *HDRC_COMP;
+
+/**
+ * \brief Open a DRC Compressor instance.
+ *
+ * Allocate memory for a compressor instance.
+ *
+ * \param phDrcComp A pointer to a compressor handle. Initialized on
+ * return.
+ *
+ * \return
+ * - 0, on succes.
+ * - unequal 0, on failure.
+ */
+INT FDK_DRC_Generator_Open(HDRC_COMP *phDrcComp);
+
+/**
+ * \brief Close the DRC Compressor instance.
+ *
+ * Deallocate instance and free whole memory.
+ *
+ * \param phDrcComp Pointer to the compressor handle to be
+ * deallocated.
+ *
+ * \return
+ * - 0, on succes.
+ * - unequal 0, on failure.
+ */
+INT FDK_DRC_Generator_Close(HDRC_COMP *phDrcComp);
+
+/**
+ * \brief Configure DRC Compressor.
+ *
+ * \param drcComp Compressor handle.
+ * \param profileLine DRC profile for line mode.
+ * \param profileRF DRC profile for RF mode.
+ * \param blockLength Length of processing block in samples per
+ * channel.
+ * \param sampleRate Sampling rate in Hz.
+ * \param channelMode Channel configuration.
+ * \param channelOrder Channel order, MPEG or WAV.
+ * \param useWeighting Use weighting filter for loudness calculation
+ *
+ * \return
+ * - 0, on success,
+ * - unequal 0, on failure
+ */
+INT FDK_DRC_Generator_Initialize(HDRC_COMP drcComp,
+ const DRC_PROFILE profileLine,
+ const DRC_PROFILE profileRF,
+ const INT blockLength, const UINT sampleRate,
+ const CHANNEL_MODE channelMode,
+ const CHANNEL_ORDER channelOrder,
+ const UCHAR useWeighting);
+
+/**
+ * \brief Calculate DRC Compressor Gain.
+ *
+ * \param drcComp Compressor handle.
+ * \param inSamples Pointer to interleaved input audio samples.
+ * \param inSamplesBufSize Size of inSamples for one channel.
+ * \param dialnorm Dialog Level in dB (typically -31...-1).
+ * \param drc_TargetRefLevel
+ * \param comp_TargetRefLevel
+ * \param clev Downmix center mix factor (typically 0.707,
+ * 0.595 or 0.5)
+ * \param slev Downmix surround mix factor (typically 0.707,
+ * 0.5, or 0)
+ * \param ext_leva Downmix gain factor A
+ * \param ext_levb Downmix gain factor B
+ * \param lfe_lev LFE gain factor
+ * \param dmxGain5 Gain factor for downmix to 5 channels
+ * \param dmxGain2 Gain factor for downmix to 2 channels
+ * \param dynrng Pointer to variable receiving line mode DRC gain
+ * in dB
+ * \param compr Pointer to variable receiving RF mode DRC gain
+ * in dB
+ *
+ * \return
+ * - 0, on success,
+ * - unequal 0, on failure
+ */
+INT FDK_DRC_Generator_Calc(HDRC_COMP drcComp, const INT_PCM *const inSamples,
+ const UINT inSamplesBufSize, const INT dialnorm,
+ const INT drc_TargetRefLevel,
+ const INT comp_TargetRefLevel, const FIXP_DBL clev,
+ const FIXP_DBL slev, const FIXP_DBL ext_leva,
+ const FIXP_DBL ext_levb, const FIXP_DBL lfe_lev,
+ const INT dmxGain5, const INT dmxGain2,
+ INT *const dynrng, INT *const compr);
+
+/**
+ * \brief Configure DRC Compressor Profile.
+ *
+ * \param drcComp Compressor handle.
+ * \param profileLine DRC profile for line mode.
+ * \param profileRF DRC profile for RF mode.
+ *
+ * \return
+ * - 0, on success,
+ * - unequal 0, on failure
+ */
+INT FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp,
+ const DRC_PROFILE profileLine,
+ const DRC_PROFILE profileRF);
+
+/**
+ * \brief Get DRC profile for line mode.
+ *
+ * \param drcComp Compressor handle.
+ *
+ * \return Current Profile.
+ */
+DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp);
+
+/**
+ * \brief Get DRC profile for RF mode.
+ *
+ * \param drcComp Compressor handle.
+ *
+ * \return Current Profile.
+ */
+DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp);
+
+#endif /* METADATA_COMPRESSOR_H */
diff --git a/fdk-aac/libAACenc/src/metadata_main.cpp b/fdk-aac/libAACenc/src/metadata_main.cpp
new file mode 100644
index 0000000..ada4502
--- /dev/null
+++ b/fdk-aac/libAACenc/src/metadata_main.cpp
@@ -0,0 +1,1191 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): V. Bacigalupo
+
+ Description: Metadata Encoder library interface functions
+
+*******************************************************************************/
+
+#include "metadata_main.h"
+#include "metadata_compressor.h"
+#include "FDK_bitstream.h"
+#include "FDK_audio.h"
+#include "genericStds.h"
+
+/*----------------- defines ----------------------*/
+#define MAX_DRC_BANDS (1 << 4)
+#define MAX_DRC_FRAMELEN (2 * 1024)
+#define MAX_DELAY_FRAMES (3)
+
+/*--------------- structure definitions --------------------*/
+
+typedef struct AAC_METADATA {
+ /* MPEG: Dynamic Range Control */
+ struct {
+ UCHAR prog_ref_level_present;
+ SCHAR prog_ref_level;
+
+ UCHAR dyn_rng_sgn[MAX_DRC_BANDS];
+ UCHAR dyn_rng_ctl[MAX_DRC_BANDS];
+
+ UCHAR drc_bands_present;
+ UCHAR drc_band_incr;
+ UCHAR drc_band_top[MAX_DRC_BANDS];
+ UCHAR drc_interpolation_scheme;
+ AACENC_METADATA_DRC_PROFILE drc_profile;
+ INT drc_TargetRefLevel; /* used for Limiter */
+
+ /* excluded channels */
+ UCHAR excluded_chns_present;
+ UCHAR exclude_mask[2]; /* MAX_NUMBER_CHANNELS/8 */
+ } mpegDrc;
+
+ /* ETSI: addtl ancillary data */
+ struct {
+ /* Heavy Compression */
+ UCHAR compression_on; /* flag, if compression value should be written */
+ UCHAR compression_value; /* compression value */
+ AACENC_METADATA_DRC_PROFILE comp_profile;
+ INT comp_TargetRefLevel; /* used for Limiter */
+ INT timecode_coarse_status;
+ INT timecode_fine_status;
+
+ UCHAR extAncDataStatus;
+
+ struct {
+ UCHAR ext_downmix_lvl_status;
+ UCHAR ext_downmix_gain_status;
+ UCHAR ext_lfe_downmix_status;
+ UCHAR
+ ext_dmix_a_idx; /* extended downmix level (0..7, according to table)
+ */
+ UCHAR
+ ext_dmix_b_idx; /* extended downmix level (0..7, according to table)
+ */
+ UCHAR dmx_gain_5_sgn;
+ UCHAR dmx_gain_5_idx;
+ UCHAR dmx_gain_2_sgn;
+ UCHAR dmx_gain_2_idx;
+ UCHAR ext_dmix_lfe_idx; /* extended downmix level for lfe (0..15,
+ according to table) */
+
+ } extAncData;
+
+ } etsiAncData;
+
+ SCHAR centerMixLevel; /* center downmix level (0...7, according to table) */
+ SCHAR
+ surroundMixLevel; /* surround downmix level (0...7, according to table) */
+ UCHAR WritePCEMixDwnIdx; /* flag */
+ UCHAR DmxLvl_On; /* flag */
+
+ UCHAR dolbySurroundMode;
+ UCHAR drcPresentationMode;
+
+ UCHAR
+ metadataMode; /* indicate meta data mode in current frame (delay line) */
+
+} AAC_METADATA;
+
+typedef struct FDK_METADATA_ENCODER {
+ INT metadataMode;
+ HDRC_COMP hDrcComp;
+ AACENC_MetaData submittedMetaData;
+
+ INT nAudioDataDelay; /* Additional delay to round up to next frame border (in
+ samples) */
+ INT nMetaDataDelay; /* Meta data delay (in frames) */
+ INT nChannels;
+ CHANNEL_MODE channelMode;
+
+ INT_PCM* pAudioDelayBuffer;
+
+ AAC_METADATA metaDataBuffer[MAX_DELAY_FRAMES];
+ INT metaDataDelayIdx;
+
+ UCHAR drcInfoPayload[12];
+ UCHAR drcDsePayload[8];
+
+ INT matrix_mixdown_idx;
+
+ AACENC_EXT_PAYLOAD exPayload[2];
+ INT nExtensions;
+
+ UINT maxChannels; /* Maximum number of audio channels to be supported. */
+
+ INT finalizeMetaData; /* Delay switch off by one frame and write default
+ configuration to finalize the metadata setup. */
+ INT initializeMetaData; /* Fill up delay line with first meta data info. This
+ is required to have meta data already in first
+ frame. */
+} FDK_METADATA_ENCODER;
+
+/*---------------- constants -----------------------*/
+static const AACENC_MetaData defaultMetaDataSetup = {
+ AACENC_METADATA_DRC_NONE, /* drc_profile */
+ AACENC_METADATA_DRC_NOT_PRESENT, /* comp_profile */
+ -(31 << 16), /* drc_TargetRefLevel */
+ -(23 << 16), /* comp_TargetRefLevel */
+ 0, /* prog_ref_level_present */
+ -(23 << 16), /* prog_ref_level */
+ 0, /* PCE_mixdown_idx_present */
+ 0, /* ETSI_DmxLvl_present */
+ 0, /* centerMixLevel */
+ 0, /* surroundMixLevel */
+ 0, /* dolbySurroundMode */
+ 0, /* drcPresentationMode */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0} /* ExtMetaData */
+};
+
+static const FIXP_DBL dmxTable[8] = {
+ ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f),
+ FL2FXCONST_DBL(0.596f), FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f),
+ FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f)};
+
+#define FL2DMXLFE(a) FL2FXCONST_DBL((a) / (1 << LFE_LEV_SCALE))
+static const FIXP_DBL dmxLfeTable[16] = {
+ FL2DMXLFE(3.162f), FL2DMXLFE(2.000f), FL2DMXLFE(1.679f), FL2DMXLFE(1.413f),
+ FL2DMXLFE(1.189f), FL2DMXLFE(1.000f), FL2DMXLFE(0.841f), FL2DMXLFE(0.707f),
+ FL2DMXLFE(0.596f), FL2DMXLFE(0.500f), FL2DMXLFE(0.316f), FL2DMXLFE(0.178f),
+ FL2DMXLFE(0.100f), FL2DMXLFE(0.032f), FL2DMXLFE(0.010f), FL2DMXLFE(0.000f)};
+
+static const UCHAR surmix2matrix_mixdown_idx[8] = {0, 0, 0, 1, 1, 2, 2, 3};
+
+/*--------------- function declarations --------------------*/
+static FDK_METADATA_ERROR WriteMetadataPayload(
+ const HANDLE_FDK_METADATA_ENCODER hMetaData,
+ const AAC_METADATA* const pMetadata);
+
+static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata,
+ UCHAR* const pExtensionPayload);
+
+static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata,
+ UCHAR* const pExtensionPayload);
+
+static FDK_METADATA_ERROR CompensateAudioDelay(
+ HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
+ const UINT audioSamplesBufSize, const INT nAudioSamples);
+
+static FDK_METADATA_ERROR LoadSubmittedMetadata(
+ const AACENC_MetaData* const hMetadata, const INT nChannels,
+ const INT metadataMode, AAC_METADATA* const pAacMetaData);
+
+static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata,
+ HDRC_COMP hDrcComp,
+ const INT_PCM* const pSamples,
+ const UINT samplesBufSize,
+ const INT nSamples);
+
+/*------------- function definitions ----------------*/
+
+static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile) {
+ DRC_PROFILE drcProfile = DRC_NONE;
+
+ switch (aacProfile) {
+ case AACENC_METADATA_DRC_NONE:
+ drcProfile = DRC_NONE;
+ break;
+ case AACENC_METADATA_DRC_FILMSTANDARD:
+ drcProfile = DRC_FILMSTANDARD;
+ break;
+ case AACENC_METADATA_DRC_FILMLIGHT:
+ drcProfile = DRC_FILMLIGHT;
+ break;
+ case AACENC_METADATA_DRC_MUSICSTANDARD:
+ drcProfile = DRC_MUSICSTANDARD;
+ break;
+ case AACENC_METADATA_DRC_MUSICLIGHT:
+ drcProfile = DRC_MUSICLIGHT;
+ break;
+ case AACENC_METADATA_DRC_SPEECH:
+ drcProfile = DRC_SPEECH;
+ break;
+ case AACENC_METADATA_DRC_NOT_PRESENT:
+ drcProfile = DRC_NOT_PRESENT;
+ break;
+ default:
+ drcProfile = DRC_NONE;
+ break;
+ }
+ return drcProfile;
+}
+
+/* convert dialog normalization to program reference level */
+/* NOTE: this only is correct, if the decoder target level is set to -31dB for
+ * line mode / -20dB for RF mode */
+static UCHAR dialnorm2progreflvl(const INT d) {
+ return ((UCHAR)fMax(0, fMin((-d + (1 << 13)) >> 14, 127)));
+}
+
+/* convert program reference level to dialog normalization */
+static INT progreflvl2dialnorm(const UCHAR p) {
+ return -((INT)(p << (16 - 2)));
+}
+
+/* encode downmix levels to Downmixing_levels_MPEG4 */
+static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev) {
+ SCHAR dmxLvls = 0;
+ dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */
+ dmxLvls |= 0x08 | surmixlev; /* surround_mix_level_on */
+
+ return dmxLvls;
+}
+
+/* encode AAC DRC gain (ISO/IEC 14496-3:2005 4.5.2.7) */
+static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl,
+ UCHAR* const dyn_rng_sgn) {
+ if (gain < 0) {
+ *dyn_rng_sgn = 1;
+ gain = -gain;
+ } else {
+ *dyn_rng_sgn = 0;
+ }
+ gain = fMin(gain, (127 << 14));
+
+ *dyn_rng_ctl = (UCHAR)((gain + (1 << 13)) >> 14);
+}
+
+/* decode AAC DRC gain (ISO/IEC 14496-3:2005 4.5.2.7) */
+static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn) {
+ INT tmp = ((INT)dyn_rng_ctl << (16 - 2));
+ if (dyn_rng_sgn) tmp = -tmp;
+
+ return tmp;
+}
+
+/* encode AAC compression value (ETSI TS 101 154 page 99) */
+static UCHAR encodeCompr(INT gain) {
+ UCHAR x, y;
+ INT tmp;
+
+ /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */
+ tmp = ((3156476 - gain) * 15 + 197283) / 394566;
+
+ if (tmp >= 240) {
+ return 0xFF;
+ } else if (tmp < 0) {
+ return 0;
+ } else {
+ x = tmp / 15;
+ y = tmp % 15;
+ }
+
+ return (x << 4) | y;
+}
+
+/* decode AAC compression value (ETSI TS 101 154 page 99) */
+static INT decodeCompr(const UCHAR compr) {
+ INT gain;
+ SCHAR x = compr >> 4; /* 4 MSB of compr */
+ UCHAR y = (compr & 0x0F); /* 4 LSB of compr */
+
+ /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */
+ gain = (INT)(
+ scaleValue((FIXP_DBL)(((LONG)FL2FXCONST_DBL(6.0206f / 128.f) * (8 - x) -
+ (LONG)FL2FXCONST_DBL(0.4014f / 128.f) * y)),
+ -(DFRACT_BITS - 1 - 7 - 16)));
+
+ return gain;
+}
+
+FDK_METADATA_ERROR FDK_MetadataEnc_Open(HANDLE_FDK_METADATA_ENCODER* phMetaData,
+ const UINT maxChannels) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+ HANDLE_FDK_METADATA_ENCODER hMetaData = NULL;
+
+ if (phMetaData == NULL) {
+ err = METADATA_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* allocate memory */
+ if (NULL == (hMetaData = (HANDLE_FDK_METADATA_ENCODER)FDKcalloc(
+ 1, sizeof(FDK_METADATA_ENCODER)))) {
+ err = METADATA_MEMORY_ERROR;
+ goto bail;
+ }
+ FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER));
+
+ if (NULL == (hMetaData->pAudioDelayBuffer = (INT_PCM*)FDKcalloc(
+ maxChannels * MAX_DRC_FRAMELEN, sizeof(INT_PCM)))) {
+ err = METADATA_MEMORY_ERROR;
+ goto bail;
+ }
+ FDKmemclear(hMetaData->pAudioDelayBuffer,
+ maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM));
+ hMetaData->maxChannels = maxChannels;
+
+ /* Allocate DRC Compressor. */
+ if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp) != 0) {
+ err = METADATA_MEMORY_ERROR;
+ goto bail;
+ }
+ hMetaData->channelMode = MODE_UNKNOWN;
+
+ /* Return metadata instance */
+ *phMetaData = hMetaData;
+
+ return err;
+
+bail:
+ FDK_MetadataEnc_Close(&hMetaData);
+ return err;
+}
+
+FDK_METADATA_ERROR FDK_MetadataEnc_Close(
+ HANDLE_FDK_METADATA_ENCODER* phMetaData) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+
+ if (phMetaData == NULL) {
+ err = METADATA_INVALID_HANDLE;
+ goto bail;
+ }
+
+ if (*phMetaData != NULL) {
+ FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp);
+ FDKfree((*phMetaData)->pAudioDelayBuffer);
+ FDKfree(*phMetaData);
+ *phMetaData = NULL;
+ }
+bail:
+ return err;
+}
+
+FDK_METADATA_ERROR FDK_MetadataEnc_Init(
+ HANDLE_FDK_METADATA_ENCODER hMetaData, const INT resetStates,
+ const INT metadataMode, const INT audioDelay, const UINT frameLength,
+ const UINT sampleRate, const UINT nChannels, const CHANNEL_MODE channelMode,
+ const CHANNEL_ORDER channelOrder) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+ int i, nFrames, delay;
+
+ if (hMetaData == NULL) {
+ err = METADATA_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* Determine values for delay compensation. */
+ for (nFrames = 0, delay = audioDelay - (INT)frameLength; delay > 0;
+ delay -= (INT)frameLength, nFrames++)
+ ;
+
+ if ((nChannels > (8)) || (nChannels > hMetaData->maxChannels) ||
+ ((-delay) > MAX_DRC_FRAMELEN) || nFrames >= MAX_DELAY_FRAMES) {
+ err = METADATA_INIT_ERROR;
+ goto bail;
+ }
+
+ /* Initialize with default setup. */
+ FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup,
+ sizeof(AACENC_MetaData));
+
+ hMetaData->finalizeMetaData =
+ 0; /* finalize meta data only while on/off switching, else disabled */
+ hMetaData->initializeMetaData =
+ 0; /* fill up meta data delay line only at a reset otherwise disabled */
+
+ /* Reset delay lines. */
+ if (resetStates || (hMetaData->nAudioDataDelay != -delay) ||
+ (hMetaData->channelMode != channelMode)) {
+ if (resetStates || (hMetaData->channelMode == MODE_UNKNOWN)) {
+ /* clear delay buffer */
+ FDKmemclear(hMetaData->pAudioDelayBuffer,
+ hMetaData->maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM));
+ } else {
+ /* if possible, keep static audio channels for seamless channel
+ * reconfiguration */
+ FDK_channelMapDescr mapDescrPrev, mapDescr;
+ int c, src[2] = {-1, -1}, dst[2] = {-1, -1};
+
+ if (channelOrder == CH_ORDER_WG4) {
+ FDK_chMapDescr_init(&mapDescrPrev, FDK_mapInfoTabWg4,
+ FDK_mapInfoTabLenWg4, 0);
+ FDK_chMapDescr_init(&mapDescr, FDK_mapInfoTabWg4,
+ FDK_mapInfoTabLenWg4, 0);
+ } else {
+ FDK_chMapDescr_init(&mapDescrPrev, NULL, 0,
+ (channelOrder == CH_ORDER_MPEG) ? 1 : 0);
+ FDK_chMapDescr_init(&mapDescr, NULL, 0,
+ (channelOrder == CH_ORDER_MPEG) ? 1 : 0);
+ }
+
+ switch (channelMode) {
+ case MODE_1:
+ if ((INT)nChannels != 2) {
+ /* preserve center channel */
+ src[0] = FDK_chMapDescr_getMapValue(&mapDescrPrev, 0,
+ hMetaData->channelMode);
+ dst[0] = FDK_chMapDescr_getMapValue(&mapDescr, 0, channelMode);
+ }
+ break;
+ case MODE_2:
+ case MODE_1_2:
+ case MODE_1_2_1:
+ case MODE_1_2_2:
+ case MODE_1_2_2_1:
+ if (hMetaData->nChannels >= 2) {
+ /* preserve left/right channel */
+ src[0] = FDK_chMapDescr_getMapValue(
+ &mapDescrPrev, ((hMetaData->channelMode == 2) ? 0 : 1),
+ hMetaData->channelMode);
+ src[1] = FDK_chMapDescr_getMapValue(
+ &mapDescrPrev, ((hMetaData->channelMode == 2) ? 1 : 2),
+ hMetaData->channelMode);
+ dst[0] = FDK_chMapDescr_getMapValue(
+ &mapDescr, ((channelMode == 2) ? 0 : 1), channelMode);
+ dst[1] = FDK_chMapDescr_getMapValue(
+ &mapDescr, ((channelMode == 2) ? 1 : 2), channelMode);
+ }
+ break;
+ default:;
+ }
+ C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, (8));
+ FDKmemclear(scratch_audioDelayBuffer, (8) * sizeof(INT_PCM));
+
+ i = (hMetaData->nChannels > (INT)nChannels)
+ ? 0
+ : hMetaData->nAudioDataDelay - 1;
+ do {
+ for (c = 0; c < 2; c++) {
+ if (src[c] != -1 && dst[c] != -1) {
+ scratch_audioDelayBuffer[dst[c]] =
+ hMetaData->pAudioDelayBuffer[i * hMetaData->nChannels + src[c]];
+ }
+ }
+ FDKmemcpy(&hMetaData->pAudioDelayBuffer[i * nChannels],
+ scratch_audioDelayBuffer, nChannels * sizeof(INT_PCM));
+ i += (hMetaData->nChannels > (INT)nChannels) ? 1 : -1;
+ } while ((i < hMetaData->nAudioDataDelay) && (i >= 0));
+
+ C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, (8));
+ }
+ FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer));
+ hMetaData->metaDataDelayIdx = 0;
+ hMetaData->initializeMetaData =
+ 1; /* fill up delay line with first meta data info */
+ } else {
+ /* Enable meta data. */
+ if ((hMetaData->metadataMode == 0) && (metadataMode != 0)) {
+ /* disable meta data in all delay lines */
+ for (i = 0;
+ i < (int)(sizeof(hMetaData->metaDataBuffer) / sizeof(AAC_METADATA));
+ i++) {
+ LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0,
+ &hMetaData->metaDataBuffer[i]);
+ }
+ }
+
+ /* Disable meta data.*/
+ if ((hMetaData->metadataMode != 0) && (metadataMode == 0)) {
+ hMetaData->finalizeMetaData = hMetaData->metadataMode;
+ }
+ }
+
+ /* Initialize delay. */
+ hMetaData->nAudioDataDelay = -delay;
+ hMetaData->nMetaDataDelay = nFrames;
+ hMetaData->nChannels = nChannels;
+ hMetaData->channelMode = channelMode;
+ hMetaData->metadataMode = metadataMode;
+
+ /* Initialize compressor. */
+ if ((metadataMode == 1) || (metadataMode == 2)) {
+ if (FDK_DRC_Generator_Initialize(hMetaData->hDrcComp, DRC_NONE, DRC_NONE,
+ frameLength, sampleRate, channelMode,
+ channelOrder, 1) != 0) {
+ err = METADATA_INIT_ERROR;
+ }
+ }
+bail:
+ return err;
+}
+
+static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata,
+ HDRC_COMP hDrcComp,
+ const INT_PCM* const pSamples,
+ const UINT samplesBufSize,
+ const INT nSamples) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+
+ INT dynrng, compr;
+ INT dmxGain5, dmxGain2;
+ DRC_PROFILE profileDrc;
+ DRC_PROFILE profileComp;
+
+ if ((pMetadata == NULL) || (hDrcComp == NULL)) {
+ err = METADATA_INVALID_HANDLE;
+ return err;
+ }
+
+ profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile);
+ profileComp = convertProfile(pMetadata->etsiAncData.comp_profile);
+
+ /* first, check if profile is same as last frame
+ * otherwise, update setup */
+ if ((profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp)) ||
+ (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp))) {
+ FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp);
+ }
+
+ /* Sanity check */
+ if (profileComp == DRC_NONE) {
+ pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external
+ values will be written
+ if not configured */
+ }
+
+ /* in case of embedding external values, copy this now (limiter may overwrite
+ * them) */
+ dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0],
+ pMetadata->mpegDrc.dyn_rng_sgn[0]);
+ compr = decodeCompr(pMetadata->etsiAncData.compression_value);
+
+ dmxGain5 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
+ pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn);
+ dmxGain2 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
+ pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn);
+
+ /* Call compressor */
+ if (FDK_DRC_Generator_Calc(
+ hDrcComp, pSamples, samplesBufSize,
+ progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level),
+ pMetadata->mpegDrc.drc_TargetRefLevel,
+ pMetadata->etsiAncData.comp_TargetRefLevel,
+ dmxTable[pMetadata->centerMixLevel],
+ dmxTable[pMetadata->surroundMixLevel],
+ dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_a_idx],
+ dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_b_idx],
+ pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status
+ ? dmxLfeTable[pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx]
+ : (FIXP_DBL)0,
+ dmxGain5, dmxGain2, &dynrng, &compr) != 0) {
+ err = METADATA_ENCODE_ERROR;
+ goto bail;
+ }
+
+ /* Write DRC values */
+ pMetadata->mpegDrc.drc_band_incr = 0;
+ encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl,
+ pMetadata->mpegDrc.dyn_rng_sgn);
+ pMetadata->etsiAncData.compression_value = encodeCompr(compr);
+
+bail:
+ return err;
+}
+
+FDK_METADATA_ERROR FDK_MetadataEnc_Process(
+ HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
+ const UINT audioSamplesBufSize, const INT nAudioSamples,
+ const AACENC_MetaData* const pMetadata,
+ AACENC_EXT_PAYLOAD** ppMetaDataExtPayload, UINT* nMetaDataExtensions,
+ INT* matrix_mixdown_idx) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+ int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode;
+
+ /* Where to write new meta data info */
+ metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx;
+
+ /* How to write the data */
+ metadataMode = hMetaDataEnc->metadataMode;
+
+ /* Compensate meta data delay. */
+ hMetaDataEnc->metaDataDelayIdx++;
+ if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay)
+ hMetaDataEnc->metaDataDelayIdx = 0;
+
+ /* Where to read pending meta data info from. */
+ metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx;
+
+ /* Submit new data if available. */
+ if (pMetadata != NULL) {
+ FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata,
+ sizeof(AACENC_MetaData));
+ }
+
+ /* Write one additional frame with default configuration of meta data. Ensure
+ * defined behaviour on decoder side. */
+ if ((hMetaDataEnc->finalizeMetaData != 0) &&
+ (hMetaDataEnc->metadataMode == 0)) {
+ FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup,
+ sizeof(AACENC_MetaData));
+ metadataMode = hMetaDataEnc->finalizeMetaData;
+ hMetaDataEnc->finalizeMetaData = 0;
+ }
+
+ /* Get last submitted data. */
+ if ((err = LoadSubmittedMetadata(
+ &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
+ metadataMode,
+ &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) !=
+ METADATA_OK) {
+ goto bail;
+ }
+
+ /* Calculate compressor if necessary and updata meta data info */
+ if ((hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 1) ||
+ (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 2)) {
+ if ((err = ProcessCompressor(
+ &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
+ hMetaDataEnc->hDrcComp, pAudioSamples, audioSamplesBufSize,
+ nAudioSamples)) != METADATA_OK) {
+ /* Get last submitted data again. */
+ LoadSubmittedMetadata(
+ &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
+ metadataMode, &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]);
+ }
+ }
+
+ /* Fill up delay line with initial meta data info.*/
+ if ((hMetaDataEnc->initializeMetaData != 0) &&
+ (hMetaDataEnc->metadataMode != 0)) {
+ int i;
+ for (i = 0;
+ i < (int)(sizeof(hMetaDataEnc->metaDataBuffer) / sizeof(AAC_METADATA));
+ i++) {
+ if (i != metaDataDelayWriteIdx) {
+ FDKmemcpy(&hMetaDataEnc->metaDataBuffer[i],
+ &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
+ sizeof(hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]));
+ }
+ }
+ hMetaDataEnc->initializeMetaData = 0;
+ }
+
+ /* Convert Meta Data side info to bitstream data. */
+ FDK_ASSERT(metaDataDelayReadIdx < MAX_DELAY_FRAMES);
+ if ((err = WriteMetadataPayload(
+ hMetaDataEnc,
+ &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) !=
+ METADATA_OK) {
+ goto bail;
+ }
+
+ /* Assign meta data to output */
+ *ppMetaDataExtPayload = hMetaDataEnc->exPayload;
+ *nMetaDataExtensions = hMetaDataEnc->nExtensions;
+ *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx;
+
+bail:
+ /* Compensate audio delay, reset err status. */
+ err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, audioSamplesBufSize,
+ nAudioSamples / hMetaDataEnc->nChannels);
+
+ return err;
+}
+
+static FDK_METADATA_ERROR CompensateAudioDelay(
+ HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
+ const UINT audioSamplesBufSize, const INT nAudioSamples) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+
+ if (hMetaDataEnc->nAudioDataDelay) {
+ C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, 1024);
+
+ for (int c = 0; c < hMetaDataEnc->nChannels; c++) {
+ int M = 1024;
+ INT_PCM* pAudioSamples2 = pAudioSamples + c * audioSamplesBufSize;
+ int delayIdx = hMetaDataEnc->nAudioDataDelay;
+
+ do {
+ M = fMin(M, delayIdx);
+ delayIdx -= M;
+
+ FDKmemcpy(&scratch_audioDelayBuffer[0],
+ &pAudioSamples2[(nAudioSamples - M)], sizeof(INT_PCM) * M);
+ FDKmemmove(&pAudioSamples2[M], &pAudioSamples2[0],
+ sizeof(INT_PCM) * (nAudioSamples - M));
+ FDKmemcpy(
+ &pAudioSamples2[0],
+ &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
+ c * hMetaDataEnc->nAudioDataDelay],
+ sizeof(INT_PCM) * M);
+ FDKmemcpy(
+ &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
+ c * hMetaDataEnc->nAudioDataDelay],
+ &scratch_audioDelayBuffer[0], sizeof(INT_PCM) * M);
+
+ } while (delayIdx > 0);
+ }
+
+ C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, 1024);
+ }
+
+ return err;
+}
+
+/*-----------------------------------------------------------------------------
+
+ functionname: WriteMetadataPayload
+ description: fills anc data and extension payload
+ returns: Error status
+
+ ------------------------------------------------------------------------------*/
+static FDK_METADATA_ERROR WriteMetadataPayload(
+ const HANDLE_FDK_METADATA_ENCODER hMetaData,
+ const AAC_METADATA* const pMetadata) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+
+ if ((hMetaData == NULL) || (pMetadata == NULL)) {
+ err = METADATA_INVALID_HANDLE;
+ goto bail;
+ }
+
+ hMetaData->nExtensions = 0;
+ hMetaData->matrix_mixdown_idx = -1;
+
+ if (pMetadata->metadataMode != 0) {
+ /* AAC-DRC */
+ if ((pMetadata->metadataMode == 1) || (pMetadata->metadataMode == 2)) {
+ hMetaData->exPayload[hMetaData->nExtensions].pData =
+ hMetaData->drcInfoPayload;
+ hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE;
+ hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
+
+ hMetaData->exPayload[hMetaData->nExtensions].dataSize =
+ WriteDynamicRangeInfoPayload(
+ pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
+
+ hMetaData->nExtensions++;
+ } /* pMetadata->metadataMode==1 || pMetadata->metadataMode==2 */
+
+ /* Matrix Mixdown Coefficient in PCE */
+ if (pMetadata->WritePCEMixDwnIdx) {
+ hMetaData->matrix_mixdown_idx =
+ surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel];
+ }
+
+ /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */
+ if ((pMetadata->metadataMode == 2) ||
+ (pMetadata->metadataMode == 3)) /* MP4_METADATA_MPEG_ETSI */
+ {
+ hMetaData->exPayload[hMetaData->nExtensions].pData =
+ hMetaData->drcDsePayload;
+ hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT;
+ hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
+
+ hMetaData->exPayload[hMetaData->nExtensions].dataSize =
+ WriteEtsiAncillaryDataPayload(
+ pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
+
+ hMetaData->nExtensions++;
+ } /* metadataMode==2 || metadataMode==3 */
+
+ } /* metadataMode != 0 */
+
+bail:
+ return err;
+}
+
+static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata,
+ UCHAR* const pExtensionPayload) {
+ const INT pce_tag_present = 0; /* yet fixed setting! */
+ const INT prog_ref_lev_res_bits = 0;
+ INT i, drc_num_bands = 1;
+
+ FDK_BITSTREAM bsWriter;
+ FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
+
+ /* dynamic_range_info() */
+ FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */
+ if (pce_tag_present) {
+ FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */
+ FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */
+ }
+
+ /* Exclude channels */
+ FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0,
+ 1); /* excluded_chns_present*/
+
+ /* Multiband DRC */
+ FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0,
+ 1); /* drc_bands_present */
+ if (pMetadata->mpegDrc.drc_bands_present) {
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr,
+ 4); /* drc_band_incr */
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme,
+ 4); /* drc_interpolation_scheme */
+ drc_num_bands += pMetadata->mpegDrc.drc_band_incr;
+ for (i = 0; i < drc_num_bands; i++) {
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i],
+ 8); /* drc_band_top */
+ }
+ }
+
+ /* Program Reference Level */
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present,
+ 1); /* prog_ref_level_present */
+ if (pMetadata->mpegDrc.prog_ref_level_present) {
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level,
+ 7); /* prog_ref_level */
+ FDKwriteBits(&bsWriter, prog_ref_lev_res_bits,
+ 1); /* prog_ref_level_reserved_bits */
+ }
+
+ /* DRC Values */
+ for (i = 0; i < drc_num_bands; i++) {
+ FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0,
+ 1); /* dyn_rng_sgn[ */
+ FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i],
+ 7); /* dyn_rng_ctl */
+ }
+
+ /* return number of valid bits in extension payload. */
+ return FDKgetValidBits(&bsWriter);
+}
+
+static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata,
+ UCHAR* const pExtensionPayload) {
+ FDK_BITSTREAM bsWriter;
+ FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
+
+ /* ancillary_data_sync */
+ FDKwriteBits(&bsWriter, 0xBC, 8);
+
+ /* bs_info */
+ FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */
+ FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode,
+ 2); /* dolby_surround_mode */
+ FDKwriteBits(&bsWriter, pMetadata->drcPresentationMode,
+ 2); /* DRC presentation mode */
+ FDKwriteBits(&bsWriter, 0x0, 1); /* stereo_downmix_mode */
+ FDKwriteBits(&bsWriter, 0x0, 1); /* reserved */
+
+ /* ancillary_data_status */
+ FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */
+ FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0,
+ 1); /* downmixing_levels_MPEG4_status */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncDataStatus,
+ 1); /* ext_anc_data_status */
+ FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0,
+ 1); /* audio_coding_mode_and_compression status */
+ FDKwriteBits(&bsWriter,
+ (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0,
+ 1); /* coarse_grain_timecode_status */
+ FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0,
+ 1); /* fine_grain_timecode_status */
+
+ /* downmixing_levels_MPEG4_status */
+ if (pMetadata->DmxLvl_On) {
+ FDKwriteBits(
+ &bsWriter,
+ encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel),
+ 8);
+ }
+
+ /* audio_coding_mode_and_compression_status */
+ if (pMetadata->etsiAncData.compression_on) {
+ FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value,
+ 8); /* compression value */
+ }
+
+ /* grain-timecode coarse/fine */
+ if (pMetadata->etsiAncData.timecode_coarse_status) {
+ FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
+ }
+
+ if (pMetadata->etsiAncData.timecode_fine_status) {
+ FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
+ }
+
+ /* extended ancillary data structure */
+ if (pMetadata->etsiAncData.extAncDataStatus) {
+ /* ext_ancillary_data_status */
+ FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
+ FDKwriteBits(&bsWriter,
+ pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status,
+ 1); /* ext_downmixing_levels_status */
+ FDKwriteBits(&bsWriter,
+ pMetadata->etsiAncData.extAncData.ext_downmix_gain_status,
+ 1); /* ext_downmixing_global_gains_status */
+ FDKwriteBits(&bsWriter,
+ pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status,
+ 1); /* ext_downmixing_lfe_level_status" */
+ FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */
+
+ /* ext_downmixing_levels */
+ if (pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status) {
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_a_idx,
+ 3); /* dmix_a_idx */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_b_idx,
+ 3); /* dmix_b_idx */
+ FDKwriteBits(&bsWriter, 0, 2); /* Reserved, set to "0" */
+ }
+
+ /* ext_downmixing_gains */
+ if (pMetadata->etsiAncData.extAncData.ext_downmix_gain_status) {
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn,
+ 1); /* dmx_gain_5_sign */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
+ 6); /* dmx_gain_5_idx */
+ FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn,
+ 1); /* dmx_gain_2_sign */
+ FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
+ 6); /* dmx_gain_2_idx */
+ FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
+ }
+
+ if (pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status) {
+ FDKwriteBits(&bsWriter,
+ pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx,
+ 4); /* dmix_lfe_idx */
+ FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */
+ }
+ }
+
+ return FDKgetValidBits(&bsWriter);
+}
+
+static FDK_METADATA_ERROR LoadSubmittedMetadata(
+ const AACENC_MetaData* const hMetadata, const INT nChannels,
+ const INT metadataMode, AAC_METADATA* const pAacMetaData) {
+ FDK_METADATA_ERROR err = METADATA_OK;
+
+ if (pAacMetaData == NULL) {
+ err = METADATA_INVALID_HANDLE;
+ } else {
+ /* init struct */
+ FDKmemclear(pAacMetaData, sizeof(AAC_METADATA));
+
+ if (hMetadata != NULL) {
+ /* convert data */
+ pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile;
+ pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile;
+ pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel;
+ pAacMetaData->etsiAncData.comp_TargetRefLevel =
+ hMetadata->comp_TargetRefLevel;
+ pAacMetaData->mpegDrc.prog_ref_level_present =
+ hMetadata->prog_ref_level_present;
+ pAacMetaData->mpegDrc.prog_ref_level =
+ dialnorm2progreflvl(hMetadata->prog_ref_level);
+
+ pAacMetaData->centerMixLevel = hMetadata->centerMixLevel;
+ pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel;
+ pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present;
+ pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present;
+
+ pAacMetaData->etsiAncData.compression_on =
+ (hMetadata->comp_profile == AACENC_METADATA_DRC_NOT_PRESENT ? 0 : 1);
+
+ if (pAacMetaData->mpegDrc.drc_profile ==
+ AACENC_METADATA_DRC_NOT_PRESENT) {
+ pAacMetaData->mpegDrc.drc_profile =
+ AACENC_METADATA_DRC_NONE; /* MPEG DRC gains are
+ always present in BS
+ syntax */
+ /* we should give a warning, but ErrorHandler does not support this */
+ }
+
+ if (nChannels == 2) {
+ pAacMetaData->dolbySurroundMode =
+ hMetadata->dolbySurroundMode; /* dolby_surround_mode */
+ } else {
+ pAacMetaData->dolbySurroundMode = 0;
+ }
+
+ pAacMetaData->drcPresentationMode = hMetadata->drcPresentationMode;
+ /* override external values if DVB DRC presentation mode is given */
+ if (pAacMetaData->drcPresentationMode == 1) {
+ pAacMetaData->mpegDrc.drc_TargetRefLevel =
+ fMax(-(31 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
+ pAacMetaData->etsiAncData.comp_TargetRefLevel = fMax(
+ -(20 << 16),
+ pAacMetaData->etsiAncData.comp_TargetRefLevel); /* implies -23dB */
+ }
+ if (pAacMetaData->drcPresentationMode == 2) {
+ pAacMetaData->mpegDrc.drc_TargetRefLevel =
+ fMax(-(23 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
+ pAacMetaData->etsiAncData.comp_TargetRefLevel =
+ fMax(-(23 << 16), pAacMetaData->etsiAncData.comp_TargetRefLevel);
+ }
+ if (pAacMetaData->etsiAncData.comp_profile ==
+ AACENC_METADATA_DRC_NOT_PRESENT) {
+ /* DVB defines to revert to Light DRC if heavy is not present */
+ if (pAacMetaData->drcPresentationMode != 0) {
+ /* we exclude the "not indicated" mode as this requires the user to
+ * define desired levels anyway */
+ pAacMetaData->mpegDrc.drc_TargetRefLevel =
+ fMax(pAacMetaData->etsiAncData.comp_TargetRefLevel,
+ pAacMetaData->mpegDrc.drc_TargetRefLevel);
+ }
+ }
+
+ pAacMetaData->etsiAncData.timecode_coarse_status =
+ 0; /* not yet supported - attention: Update
+ GetEstMetadataBytesPerFrame() if enable this! */
+ pAacMetaData->etsiAncData.timecode_fine_status =
+ 0; /* not yet supported - attention: Update
+ GetEstMetadataBytesPerFrame() if enable this! */
+
+ /* extended ancillary data */
+ pAacMetaData->etsiAncData.extAncDataStatus =
+ ((hMetadata->ExtMetaData.extAncDataEnable == 1) ? 1 : 0);
+
+ if (pAacMetaData->etsiAncData.extAncDataStatus) {
+ pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status =
+ (hMetadata->ExtMetaData.extDownmixLevelEnable ? 1 : 0);
+ pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status =
+ (hMetadata->ExtMetaData.dmxGainEnable ? 1 : 0);
+ pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status =
+ (hMetadata->ExtMetaData.lfeDmxEnable ? 1 : 0);
+
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx =
+ hMetadata->ExtMetaData.extDownmixLevel_A;
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx =
+ hMetadata->ExtMetaData.extDownmixLevel_B;
+
+ if (pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status) {
+ encodeDynrng(hMetadata->ExtMetaData.dmxGain5,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
+ encodeDynrng(hMetadata->ExtMetaData.dmxGain2,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
+ } else {
+ encodeDynrng(1 << 16,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
+ encodeDynrng(1 << 16,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
+ }
+
+ if (pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status) {
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
+ hMetadata->ExtMetaData.lfeDmxLevel;
+ } else {
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
+ 15; /* -inf dB */
+ }
+ } else {
+ pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status = 0;
+ pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status = 0;
+ pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status = 0;
+
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx = 7; /* -inf dB */
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx = 7; /* -inf dB */
+
+ encodeDynrng(1 << 16,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
+ encodeDynrng(1 << 16,
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
+ &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
+
+ pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
+ 15; /* -inf dB */
+ }
+
+ pAacMetaData->metadataMode = metadataMode;
+ } else {
+ pAacMetaData->metadataMode = 0; /* there is no configuration available */
+ }
+ }
+
+ return err;
+}
+
+INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc) {
+ INT delay = 0;
+
+ if (hMetadataEnc != NULL) {
+ delay = hMetadataEnc->nAudioDataDelay;
+ }
+
+ return delay;
+}
diff --git a/fdk-aac/libAACenc/src/metadata_main.h b/fdk-aac/libAACenc/src/metadata_main.h
new file mode 100644
index 0000000..d872c77
--- /dev/null
+++ b/fdk-aac/libAACenc/src/metadata_main.h
@@ -0,0 +1,226 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): V. Bacigalupo
+
+ Description: Metadata Encoder library interface functions
+
+*******************************************************************************/
+
+#ifndef METADATA_MAIN_H
+#define METADATA_MAIN_H
+
+/* Includes ******************************************************************/
+#include "aacenc_lib.h"
+#include "aacenc.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+
+typedef enum {
+ METADATA_OK = 0x0000, /*!< No error happened. All fine. */
+ METADATA_INVALID_HANDLE =
+ 0x0020, /*!< Handle passed to function call was invalid. */
+ METADATA_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */
+ METADATA_INIT_ERROR = 0x0040, /*!< General initialization error. */
+ METADATA_ENCODE_ERROR =
+ 0x0060 /*!< The encoding process was interrupted by an unexpected error.
+ */
+
+} FDK_METADATA_ERROR;
+
+/**
+ * Meta Data handle.
+ */
+typedef struct FDK_METADATA_ENCODER *HANDLE_FDK_METADATA_ENCODER;
+
+/**
+ * \brief Open a Meta Data instance.
+ *
+ * \param phMetadataEnc A pointer to a Meta Data handle to be allocated.
+ * Initialized on return.
+ * \param maxChannels Maximum number of supported audio channels.
+ *
+ * \return
+ * - METADATA_OK, on succes.
+ * - METADATA_INVALID_HANDLE, METADATA_MEMORY_ERROR, on failure.
+ */
+FDK_METADATA_ERROR FDK_MetadataEnc_Open(
+ HANDLE_FDK_METADATA_ENCODER *phMetadataEnc, const UINT maxChannels);
+
+/**
+ * \brief Initialize a Meta Data instance.
+ *
+ * \param hMetadataEnc Meta Data handle.
+ * \param resetStates Indication for full reset of all states.
+ * \param metadataMode Configures meta data output format (0,1,2,3).
+ * \param audioDelay Delay cause by the audio encoder.
+ * \param frameLength Number of samples to be processes within one
+ * frame.
+ * \param sampleRate Sampling rat in Hz of audio input signal.
+ * \param nChannels Number of audio input channels.
+ * \param channelMode Channel configuration which is used by the
+ * encoder.
+ * \param channelOrder Channel order of the input data. (WAV, MPEG)
+ *
+ * \return
+ * - METADATA_OK, on succes.
+ * - METADATA_INVALID_HANDLE, METADATA_INIT_ERROR, on failure.
+ */
+FDK_METADATA_ERROR FDK_MetadataEnc_Init(
+ HANDLE_FDK_METADATA_ENCODER hMetadataEnc, const INT resetStates,
+ const INT metadataMode, const INT audioDelay, const UINT frameLength,
+ const UINT sampleRate, const UINT nChannels, const CHANNEL_MODE channelMode,
+ const CHANNEL_ORDER channelOrder);
+
+/**
+ * \brief Calculate Meta Data processing.
+ *
+ * This function treats all step necessary for meta data processing.
+ * - Receive new meta data and make usable.
+ * - Calculate DRC compressor and extract meta data info.
+ * - Make meta data available for extern use.
+ * - Apply audio data and meta data delay compensation.
+ *
+ * \param hMetadataEnc Meta Data handle.
+ * \param pAudioSamples Pointer to audio input data. Existing function
+ * overwrites audio data with delayed audio samples.
+ * \param nAudioSamples Number of input audio samples to be prcessed.
+ * \param pMetadata Pointer to Metat Data input.
+ * \param ppMetaDataExtPayload Pointer to extension payload array. Filled on
+ * return.
+ * \param nMetaDataExtensions Pointer to variable to describe number of
+ * available extension payloads. Filled on return.
+ * \param matrix_mixdown_idx Pointer to variable for matrix mixdown
+ * coefficient. Filled on return.
+ *
+ * \return
+ * - METADATA_OK, on succes.
+ * - METADATA_INVALID_HANDLE, METADATA_ENCODE_ERROR, on failure.
+ */
+FDK_METADATA_ERROR FDK_MetadataEnc_Process(
+ HANDLE_FDK_METADATA_ENCODER hMetadataEnc, INT_PCM *const pAudioSamples,
+ const UINT audioSamplesBufSize, const INT nAudioSamples,
+ const AACENC_MetaData *const pMetadata,
+ AACENC_EXT_PAYLOAD **ppMetaDataExtPayload, UINT *nMetaDataExtensions,
+ INT *matrix_mixdown_idx);
+
+/**
+ * \brief Close the Meta Data instance.
+ *
+ * Deallocate instance and free whole memory.
+ *
+ * \param phMetaData Pointer to the Meta Data handle to be
+ * deallocated.
+ *
+ * \return
+ * - METADATA_OK, on succes.
+ * - METADATA_INVALID_HANDLE, on failure.
+ */
+FDK_METADATA_ERROR FDK_MetadataEnc_Close(
+ HANDLE_FDK_METADATA_ENCODER *phMetaData);
+
+/**
+ * \brief Get Meta Data Encoder delay.
+ *
+ * \param hMetadataEnc Meta Data Encoder handle.
+ *
+ * \return Delay caused by Meta Data module.
+ */
+INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc);
+
+#endif /* METADATA_MAIN_H */
diff --git a/fdk-aac/libAACenc/src/mps_main.cpp b/fdk-aac/libAACenc/src/mps_main.cpp
new file mode 100644
index 0000000..1048228
--- /dev/null
+++ b/fdk-aac/libAACenc/src/mps_main.cpp
@@ -0,0 +1,529 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Markus Lohwasser
+
+ Description: Mpeg Surround library interface functions
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "mps_main.h"
+#include "sacenc_lib.h"
+
+/* Data Types ****************************************************************/
+struct MPS_ENCODER {
+ HANDLE_MP4SPACE_ENCODER hSacEncoder;
+
+ AUDIO_OBJECT_TYPE audioObjectType;
+
+ FDK_bufDescr inBufDesc;
+ FDK_bufDescr outBufDesc;
+ SACENC_InArgs inargs;
+ SACENC_OutArgs outargs;
+
+ void *pInBuffer[1];
+ UINT pInBufferSize[1];
+ UINT pInBufferElSize[1];
+ UINT pInBufferType[1];
+
+ void *pOutBuffer[2];
+ UINT pOutBufferSize[2];
+ UINT pOutBufferElSize[2];
+ UINT pOutBufferType[2];
+
+ UCHAR sacOutBuffer[1024]; /* Worst case memory consumption for ELDv2: 768
+ bytes => 6144 bits (Core + SBR + MPS) */
+};
+
+struct MPS_CONFIG_TAB {
+ AUDIO_OBJECT_TYPE audio_object_type;
+ CHANNEL_MODE channel_mode;
+ ULONG sbr_ratio;
+ ULONG sampling_rate;
+ ULONG bitrate_min;
+ ULONG bitrate_max;
+};
+
+/* Constants *****************************************************************/
+static const MPS_CONFIG_TAB mpsConfigTab[] = {
+ {AOT_ER_AAC_ELD, MODE_212, 0, 16000, 16000, 39999},
+ {AOT_ER_AAC_ELD, MODE_212, 0, 22050, 16000, 49999},
+ {AOT_ER_AAC_ELD, MODE_212, 0, 24000, 16000, 61999},
+ {AOT_ER_AAC_ELD, MODE_212, 0, 32000, 20000, 84999},
+ {AOT_ER_AAC_ELD, MODE_212, 0, 44100, 50000, 192000},
+ {AOT_ER_AAC_ELD, MODE_212, 0, 48000, 62000, 192000},
+
+ {AOT_ER_AAC_ELD, MODE_212, 1, 16000, 18000, 31999},
+ {AOT_ER_AAC_ELD, MODE_212, 1, 22050, 18000, 31999},
+ {AOT_ER_AAC_ELD, MODE_212, 1, 24000, 20000, 64000},
+
+ {AOT_ER_AAC_ELD, MODE_212, 2, 32000, 18000, 64000},
+ {AOT_ER_AAC_ELD, MODE_212, 2, 44100, 21000, 64000},
+ {AOT_ER_AAC_ELD, MODE_212, 2, 48000, 26000, 64000}
+
+};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static INT FDK_MpegsEnc_WriteFrameHeader(HANDLE_MPS_ENCODER hMpsEnc,
+ UCHAR *const pOutputBuffer,
+ const int outputBufferSize);
+
+MPS_ENCODER_ERROR FDK_MpegsEnc_Open(HANDLE_MPS_ENCODER *phMpsEnc) {
+ MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
+ HANDLE_MPS_ENCODER hMpsEnc = NULL;
+
+ if (phMpsEnc == NULL) {
+ error = MPS_ENCODER_INVALID_HANDLE;
+ goto bail;
+ }
+
+ if (NULL ==
+ (hMpsEnc = (HANDLE_MPS_ENCODER)FDKcalloc(1, sizeof(MPS_ENCODER)))) {
+ error = MPS_ENCODER_MEMORY_ERROR;
+ goto bail;
+ }
+ FDKmemclear(hMpsEnc, sizeof(MPS_ENCODER));
+
+ if (SACENC_OK != FDK_sacenc_open(&hMpsEnc->hSacEncoder)) {
+ error = MPS_ENCODER_MEMORY_ERROR;
+ goto bail;
+ }
+
+ /* Return mps encoder instance */
+ *phMpsEnc = hMpsEnc;
+
+bail:
+ if (error != MPS_ENCODER_OK) {
+ FDK_MpegsEnc_Close(&hMpsEnc);
+ }
+ return error;
+}
+
+MPS_ENCODER_ERROR FDK_MpegsEnc_Close(HANDLE_MPS_ENCODER *phMpsEnc) {
+ MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
+
+ if (phMpsEnc == NULL) {
+ error = MPS_ENCODER_INVALID_HANDLE;
+ goto bail;
+ }
+
+ if (*phMpsEnc != NULL) {
+ FDK_sacenc_close(&(*phMpsEnc)->hSacEncoder);
+ FDKfree(*phMpsEnc);
+ *phMpsEnc = NULL;
+ }
+bail:
+ return error;
+}
+
+MPS_ENCODER_ERROR FDK_MpegsEnc_Init(HANDLE_MPS_ENCODER hMpsEnc,
+ const AUDIO_OBJECT_TYPE audioObjectType,
+ const UINT samplingrate, const UINT bitrate,
+ const UINT sbrRatio, const UINT framelength,
+ const UINT inputBufferSizePerChannel,
+ const UINT coreCoderDelay) {
+ MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
+ const UINT fs_low = 27713; /* low MPS sampling frequencies */
+ const UINT fs_high = 55426; /* high MPS sampling frequencies */
+ UINT nTimeSlots = 0, nQmfBandsLd = 0;
+
+ if (hMpsEnc == NULL) {
+ error = MPS_ENCODER_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* Combine MPS with SBR only if the number of QMF band fits together.*/
+ switch (sbrRatio) {
+ case 1: /* downsampled sbr - 32 QMF bands required */
+ if (!(samplingrate < fs_low)) {
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+ break;
+ case 2: /* dualrate - 64 QMF bands required */
+ if (!((samplingrate >= fs_low) && (samplingrate < fs_high))) {
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+ break;
+ case 0:
+ default:; /* time interface - no samplingrate restriction */
+ }
+
+ /* 32 QMF-Bands ( fs < 27713 )
+ * 64 QMF-Bands ( 27713 >= fs <= 55426 )
+ * 128 QMF-Bands ( fs > 55426 )
+ */
+ nQmfBandsLd =
+ (samplingrate < fs_low) ? 5 : ((samplingrate > fs_high) ? 7 : 6);
+ nTimeSlots = framelength >> nQmfBandsLd;
+
+ /* check if number of qmf bands is usable for given framelength */
+ if (framelength != (nTimeSlots << nQmfBandsLd)) {
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+
+ /* is given bitrate intended to be supported */
+ if ((INT)bitrate != FDK_MpegsEnc_GetClosestBitRate(audioObjectType, MODE_212,
+ samplingrate, sbrRatio,
+ bitrate)) {
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+
+ /* init SAC library */
+ switch (audioObjectType) {
+ case AOT_ER_AAC_ELD: {
+ const UINT noInterFrameCoding = 0;
+
+ if ((SACENC_OK !=
+ FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_LOWDELAY,
+ (noInterFrameCoding == 1) ? 1 : 2)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_ENC_MODE, SACENC_212)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_SAMPLERATE, samplingrate)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_FRAME_TIME_SLOTS,
+ nTimeSlots)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_PARAM_BANDS,
+ SACENC_BANDS_15)) ||
+ (SACENC_OK !=
+ FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_TIME_DOM_DMX, 2)) ||
+ (SACENC_OK !=
+ FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_COARSE_QUANT, 0)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_QUANT_MODE,
+ SACENC_QUANTMODE_FINE)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_TIME_ALIGNMENT, 0)) ||
+ (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder,
+ SACENC_INDEPENDENCY_FACTOR, 20))) {
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+ break;
+ }
+ default:
+ error = MPS_ENCODER_INIT_ERROR;
+ goto bail;
+ }
+
+ if (SACENC_OK != FDK_sacenc_init(hMpsEnc->hSacEncoder, coreCoderDelay)) {
+ error = MPS_ENCODER_INIT_ERROR;
+ }
+
+ hMpsEnc->audioObjectType = audioObjectType;
+
+ hMpsEnc->inBufDesc.ppBase = (void **)&hMpsEnc->pInBuffer;
+ hMpsEnc->inBufDesc.pBufSize = hMpsEnc->pInBufferSize;
+ hMpsEnc->inBufDesc.pEleSize = hMpsEnc->pInBufferElSize;
+ hMpsEnc->inBufDesc.pBufType = hMpsEnc->pInBufferType;
+ hMpsEnc->inBufDesc.numBufs = 1;
+
+ hMpsEnc->outBufDesc.ppBase = (void **)&hMpsEnc->pOutBuffer;
+ hMpsEnc->outBufDesc.pBufSize = hMpsEnc->pOutBufferSize;
+ hMpsEnc->outBufDesc.pEleSize = hMpsEnc->pOutBufferElSize;
+ hMpsEnc->outBufDesc.pBufType = hMpsEnc->pOutBufferType;
+ hMpsEnc->outBufDesc.numBufs = 2;
+
+ hMpsEnc->pInBuffer[0] = NULL;
+ hMpsEnc->pInBufferSize[0] = 0;
+ hMpsEnc->pInBufferElSize[0] = sizeof(INT_PCM);
+ hMpsEnc->pInBufferType[0] = (FDK_BUF_TYPE_INPUT | FDK_BUF_TYPE_PCM_DATA);
+
+ hMpsEnc->pOutBuffer[0] = NULL;
+ hMpsEnc->pOutBufferSize[0] = 0;
+ hMpsEnc->pOutBufferElSize[0] = sizeof(INT_PCM);
+ hMpsEnc->pOutBufferType[0] = (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA);
+
+ hMpsEnc->pOutBuffer[1] = NULL;
+ hMpsEnc->pOutBufferSize[1] = 0;
+ hMpsEnc->pOutBufferElSize[1] = sizeof(UCHAR);
+ hMpsEnc->pOutBufferType[1] = (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_BS_DATA);
+
+ hMpsEnc->inargs.isInputInterleaved = 0;
+ hMpsEnc->inargs.inputBufferSizePerChannel = inputBufferSizePerChannel;
+
+bail:
+ return error;
+}
+
+MPS_ENCODER_ERROR FDK_MpegsEnc_Process(HANDLE_MPS_ENCODER hMpsEnc,
+ INT_PCM *const pAudioSamples,
+ const INT nAudioSamples,
+ AACENC_EXT_PAYLOAD *pMpsExtPayload) {
+ MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
+
+ if (hMpsEnc == NULL) {
+ error = MPS_ENCODER_INVALID_HANDLE;
+ } else {
+ int sacHeaderFlag = 1;
+ int sacOutBufferOffset = 0;
+
+ /* In case of eld the ssc is explicit and doesn't need to be inband */
+ if (hMpsEnc->audioObjectType == AOT_ER_AAC_ELD) {
+ sacHeaderFlag = 0;
+ }
+
+ /* 4 bits nibble after extension type */
+ hMpsEnc->sacOutBuffer[0] = (sacHeaderFlag == 0) ? 0x3 : 0x7;
+ sacOutBufferOffset += 1;
+
+ if (sacHeaderFlag) {
+ sacOutBufferOffset += FDK_MpegsEnc_WriteFrameHeader(
+ hMpsEnc, &hMpsEnc->sacOutBuffer[sacOutBufferOffset],
+ sizeof(hMpsEnc->sacOutBuffer) - sacOutBufferOffset);
+ }
+
+ /* Register input and output buffer. */
+ hMpsEnc->pInBuffer[0] = (void *)pAudioSamples;
+ hMpsEnc->inargs.nInputSamples = nAudioSamples;
+
+ hMpsEnc->pOutBuffer[0] = (void *)pAudioSamples;
+ hMpsEnc->pOutBufferSize[0] = sizeof(INT_PCM) * nAudioSamples / 2;
+
+ hMpsEnc->pOutBuffer[1] = (void *)&hMpsEnc->sacOutBuffer[sacOutBufferOffset];
+ hMpsEnc->pOutBufferSize[1] =
+ sizeof(hMpsEnc->sacOutBuffer) - sacOutBufferOffset;
+
+ /* encode SAC frame */
+ if (SACENC_OK != FDK_sacenc_encode(hMpsEnc->hSacEncoder,
+ &hMpsEnc->inBufDesc,
+ &hMpsEnc->outBufDesc, &hMpsEnc->inargs,
+ &hMpsEnc->outargs)) {
+ error = MPS_ENCODER_ENCODE_ERROR;
+ goto bail;
+ }
+
+ /* export MPS payload */
+ pMpsExtPayload->pData = (UCHAR *)hMpsEnc->sacOutBuffer;
+ pMpsExtPayload->dataSize =
+ hMpsEnc->outargs.nOutputBits + 8 * (sacOutBufferOffset - 1);
+ pMpsExtPayload->dataType = EXT_LDSAC_DATA;
+ pMpsExtPayload->associatedChElement = -1;
+ }
+
+bail:
+ return error;
+}
+
+INT FDK_MpegsEnc_WriteSpatialSpecificConfig(HANDLE_MPS_ENCODER hMpsEnc,
+ HANDLE_FDK_BITSTREAM hBs) {
+ INT sscBits = 0;
+
+ if (NULL != hMpsEnc) {
+ MP4SPACEENC_INFO mp4SpaceEncoderInfo;
+ FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo);
+
+ if (hBs != NULL) {
+ int i;
+ int writtenBits = 0;
+ for (i = 0; i<mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits>> 3; i++) {
+ FDKwriteBits(hBs, mp4SpaceEncoderInfo.pSscBuf->pSsc[i], 8);
+ writtenBits += 8;
+ }
+ FDKwriteBits(hBs, mp4SpaceEncoderInfo.pSscBuf->pSsc[i],
+ mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits - writtenBits);
+ } /* hBS */
+
+ sscBits = mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits;
+
+ } /* valid hMpsEnc */
+
+ return sscBits;
+}
+
+static INT FDK_MpegsEnc_WriteFrameHeader(HANDLE_MPS_ENCODER hMpsEnc,
+ UCHAR *const pOutputBuffer,
+ const int outputBufferSize) {
+ const int sacTimeAlignFlag = 0;
+
+ /* Initialize variables */
+ int numBits = 0;
+
+ if ((NULL != hMpsEnc) && (NULL != pOutputBuffer)) {
+ UINT alignAnchor, cnt;
+ FDK_BITSTREAM Bs;
+ FDKinitBitStream(&Bs, pOutputBuffer, outputBufferSize, 0, BS_WRITER);
+
+ /* Calculate SSC length information */
+ cnt = (FDK_MpegsEnc_WriteSpatialSpecificConfig(hMpsEnc, NULL) + 7) >> 3;
+
+ /* Write SSC */
+ FDKwriteBits(&Bs, sacTimeAlignFlag, 1);
+
+ if (cnt < 127) {
+ FDKwriteBits(&Bs, cnt, 7);
+ } else {
+ FDKwriteBits(&Bs, 127, 7);
+ FDKwriteBits(&Bs, cnt - 127, 16);
+ }
+
+ alignAnchor = FDKgetValidBits(&Bs);
+ FDK_MpegsEnc_WriteSpatialSpecificConfig(hMpsEnc, &Bs);
+ FDKbyteAlign(&Bs, alignAnchor); /* bsFillBits */
+
+ if (sacTimeAlignFlag) {
+ FDK_ASSERT(1); /* time alignment not supported */
+ }
+
+ numBits = FDKgetValidBits(&Bs);
+ } /* valid handle */
+
+ return ((numBits + 7) >> 3);
+}
+
+INT FDK_MpegsEnc_GetClosestBitRate(const AUDIO_OBJECT_TYPE audioObjectType,
+ const CHANNEL_MODE channelMode,
+ const UINT samplingrate, const UINT sbrRatio,
+ const UINT bitrate) {
+ unsigned int i;
+ int targetBitrate = -1;
+
+ for (i = 0; i < sizeof(mpsConfigTab) / sizeof(MPS_CONFIG_TAB); i++) {
+ if ((mpsConfigTab[i].audio_object_type == audioObjectType) &&
+ (mpsConfigTab[i].channel_mode == channelMode) &&
+ (mpsConfigTab[i].sbr_ratio == sbrRatio) &&
+ (mpsConfigTab[i].sampling_rate == samplingrate)) {
+ targetBitrate = fMin(fMax(bitrate, mpsConfigTab[i].bitrate_min),
+ mpsConfigTab[i].bitrate_max);
+ }
+ }
+
+ return targetBitrate;
+}
+
+INT FDK_MpegsEnc_GetDelay(HANDLE_MPS_ENCODER hMpsEnc) {
+ INT delay = 0;
+
+ if (NULL != hMpsEnc) {
+ MP4SPACEENC_INFO mp4SpaceEncoderInfo;
+ FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo);
+ delay = mp4SpaceEncoderInfo.nCodecDelay;
+ }
+
+ return delay;
+}
+
+INT FDK_MpegsEnc_GetDecDelay(HANDLE_MPS_ENCODER hMpsEnc) {
+ INT delay = 0;
+
+ if (NULL != hMpsEnc) {
+ MP4SPACEENC_INFO mp4SpaceEncoderInfo;
+ FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo);
+ delay = mp4SpaceEncoderInfo.nDecoderDelay;
+ }
+
+ return delay;
+}
+
+MPS_ENCODER_ERROR FDK_MpegsEnc_GetLibInfo(LIB_INFO *info) {
+ MPS_ENCODER_ERROR error = MPS_ENCODER_OK;
+
+ if (NULL == info) {
+ error = MPS_ENCODER_INVALID_HANDLE;
+ } else if (SACENC_OK != FDK_sacenc_getLibInfo(info)) {
+ error = MPS_ENCODER_INIT_ERROR;
+ }
+
+ return error;
+}
diff --git a/fdk-aac/libAACenc/src/mps_main.h b/fdk-aac/libAACenc/src/mps_main.h
new file mode 100644
index 0000000..f56678a
--- /dev/null
+++ b/fdk-aac/libAACenc/src/mps_main.h
@@ -0,0 +1,270 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Markus Lohwasser
+
+ Description: Mpeg Surround library interface functions
+
+*******************************************************************************/
+
+#ifndef MPS_MAIN_H
+#define MPS_MAIN_H
+
+/* Includes ******************************************************************/
+#include "aacenc.h"
+#include "FDK_audio.h"
+#include "machine_type.h"
+
+/* Defines *******************************************************************/
+typedef enum {
+ MPS_ENCODER_OK = 0x0000, /*!< No error happened. All fine. */
+ MPS_ENCODER_INVALID_HANDLE =
+ 0x0020, /*!< Handle passed to function call was invalid. */
+ MPS_ENCODER_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */
+ MPS_ENCODER_INIT_ERROR = 0x0040, /*!< General initialization error. */
+ MPS_ENCODER_ENCODE_ERROR =
+ 0x0060 /*!< The encoding process was interrupted by an unexpected error.
+ */
+
+} MPS_ENCODER_ERROR;
+
+/* Data Types ****************************************************************/
+
+/**
+ * MPEG Surround Encoder interface handle.
+ */
+typedef struct MPS_ENCODER MPS_ENCODER, *HANDLE_MPS_ENCODER;
+
+/* Function / Class Declarations *********************************************/
+
+/**
+ * \brief Open a Mpeg Surround Encoder instance.
+ *
+ * \phMpsEnc A pointer to a MPS handle to be allocated.
+ * Initialized on return.
+ *
+ * \return
+ * - MPS_ENCODER_OK, on succes.
+ * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_MEMORY_ERROR, on failure.
+ */
+MPS_ENCODER_ERROR FDK_MpegsEnc_Open(HANDLE_MPS_ENCODER *phMpsEnc);
+
+/**
+ * \brief Close the Mpeg Surround Encoder instance.
+ *
+ * Deallocate instance and free whole memory.
+ *
+ * \param phMpsEnc Pointer to the MPS handle to be deallocated.
+ *
+ * \return
+ * - MPS_ENCODER_OK, on succes.
+ * - MPS_ENCODER_INVALID_HANDLE, on failure.
+ */
+MPS_ENCODER_ERROR FDK_MpegsEnc_Close(HANDLE_MPS_ENCODER *phMpsEnc);
+
+/**
+ * \brief Initialize a Mpeg Surround Encoder instance.
+ *
+ * \param hMpsEnc MPS Encoder handle.
+ * \param audioObjectType Audio object type.
+ * \param samplingrate Sampling rate in Hz of audio input signal.
+ * \param bitrate Encder target bitrate.
+ * \param sbrRatio SBR sampling rate ratio.
+ * \param framelength Number of samples to be processes within one
+ * frame.
+ * \param inputBufferSizePerChannel Size of input buffer per channel.
+ * \param coreCoderDelay Core coder delay.
+ *
+ * \return
+ * - MPS_ENCODER_OK, on succes.
+ * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_ENCODE_ERROR, on failure.
+ */
+MPS_ENCODER_ERROR FDK_MpegsEnc_Init(HANDLE_MPS_ENCODER hMpsEnc,
+ const AUDIO_OBJECT_TYPE audioObjectType,
+ const UINT samplingrate, const UINT bitrate,
+ const UINT sbrRatio, const UINT framelength,
+ const UINT inputBufferSizePerChannel,
+ const UINT coreCoderDelay);
+
+/**
+ * \brief Calculate Mpeg Surround processing.
+ *
+ * This fuction applies the MPS processing. The MPS side info will be written to
+ * extension payload. The input audio data will be overwritten by the calculated
+ * downmix.
+ *
+ * \param hMpsEnc MPS Encoder handle.
+ * \param pAudioSamples Pointer to audio input/output data.
+ * \param nAudioSamples Number of input audio samples to be prcessed.
+ * \param pMpsExtPayload Pointer to extension payload to be filled on
+ * return.
+ *
+ * \return
+ * - MPS_ENCODER_OK, on succes.
+ * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_ENCODE_ERROR, on failure.
+ */
+MPS_ENCODER_ERROR FDK_MpegsEnc_Process(HANDLE_MPS_ENCODER hMpsEnc,
+ INT_PCM *const pAudioSamples,
+ const INT nAudioSamples,
+ AACENC_EXT_PAYLOAD *pMpsExtPayload);
+
+/**
+ * \brief Write Spatial Specific Config.
+ *
+ * This function can be called via call back from the transport library to write
+ * the Spatial Specific Config to given bitstream buffer.
+ *
+ * \param hMpsEnc MPS Encoder handle.
+ * \param hBs Bitstream buffer handle.
+ *
+ * \return Number of written bits.
+ */
+INT FDK_MpegsEnc_WriteSpatialSpecificConfig(HANDLE_MPS_ENCODER hMpsEnc,
+ HANDLE_FDK_BITSTREAM hBs);
+
+/**
+ * \brief Get closest valid bitrate supported by given config.
+ *
+ * \param audioObjectType Audio object type.
+ * \param channelMode Encoder channel mode.
+ * \param samplingrate Sampling rate in Hz of audio input signal.
+ * \param sbrRatio SBR sampling rate ratio.
+ * \param bitrate The desired target bitrate.
+ *
+ * \return Closest valid bitrate to given bitrate..
+ */
+INT FDK_MpegsEnc_GetClosestBitRate(const AUDIO_OBJECT_TYPE audioObjectType,
+ const CHANNEL_MODE channelMode,
+ const UINT samplingrate, const UINT sbrRatio,
+ const UINT bitrate);
+
+/**
+ * \brief Get codec delay.
+ *
+ * This function returns delay of the whole en-/decoded signal, including
+ * corecoder delay.
+ *
+ * \param hMpsEnc MPS Encoder handle.
+ *
+ * \return Codec delay in samples.
+ */
+INT FDK_MpegsEnc_GetDelay(HANDLE_MPS_ENCODER hMpsEnc);
+
+/**
+ * \brief Get Mpeg Surround Decoder delay.
+ *
+ * This function returns delay of the Mpeg Surround decoder.
+ *
+ * \param hMpsEnc MPS Encoder handle.
+ *
+ * \return Mpeg Surround Decoder delay in samples.
+ */
+INT FDK_MpegsEnc_GetDecDelay(HANDLE_MPS_ENCODER hMpsEnc);
+
+/**
+ * \brief Get information about encoder library build.
+ *
+ * Fill a given LIB_INFO structure with library version information.
+ *
+ * \param info Pointer to an allocated LIB_INFO struct.
+ *
+ * \return
+ * - MPS_ENCODER_OK, on succes.
+ * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_INIT_ERROR, on failure.
+ */
+MPS_ENCODER_ERROR FDK_MpegsEnc_GetLibInfo(LIB_INFO *info);
+
+#endif /* MPS_MAIN_H */
diff --git a/fdk-aac/libAACenc/src/ms_stereo.cpp b/fdk-aac/libAACenc/src/ms_stereo.cpp
new file mode 100644
index 0000000..6a121b2
--- /dev/null
+++ b/fdk-aac/libAACenc/src/ms_stereo.cpp
@@ -0,0 +1,295 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: MS stereo processing
+
+*******************************************************************************/
+
+#include "ms_stereo.h"
+
+#include "psy_const.h"
+
+/* static const float scaleMinThres = 1.0f; */ /* 0.75f for 3db boost */
+
+void FDKaacEnc_MsStereoProcessing(PSY_DATA *RESTRICT psyData[(2)],
+ PSY_OUT_CHANNEL *psyOutChannel[2],
+ const INT *isBook, INT *msDigest, /* output */
+ INT *msMask, /* output */
+ const INT allowMS, const INT sfbCnt,
+ const INT sfbPerGroup,
+ const INT maxSfbPerGroup,
+ const INT *sfbOffset) {
+ FIXP_DBL *sfbEnergyLeft =
+ psyData[0]->sfbEnergy.Long; /* modified where msMask==1 */
+ FIXP_DBL *sfbEnergyRight =
+ psyData[1]->sfbEnergy.Long; /* modified where msMask==1 */
+ const FIXP_DBL *sfbEnergyMid = psyData[0]->sfbEnergyMS.Long;
+ const FIXP_DBL *sfbEnergySide = psyData[1]->sfbEnergyMS.Long;
+ FIXP_DBL *sfbThresholdLeft =
+ psyData[0]->sfbThreshold.Long; /* modified where msMask==1 */
+ FIXP_DBL *sfbThresholdRight =
+ psyData[1]->sfbThreshold.Long; /* modified where msMask==1 */
+
+ FIXP_DBL *sfbSpreadEnLeft = psyData[0]->sfbSpreadEnergy.Long;
+ FIXP_DBL *sfbSpreadEnRight = psyData[1]->sfbSpreadEnergy.Long;
+
+ FIXP_DBL *sfbEnergyLeftLdData =
+ psyOutChannel[0]->sfbEnergyLdData; /* modified where msMask==1 */
+ FIXP_DBL *sfbEnergyRightLdData =
+ psyOutChannel[1]->sfbEnergyLdData; /* modified where msMask==1 */
+ FIXP_DBL *sfbEnergyMidLdData = psyData[0]->sfbEnergyMSLdData;
+ FIXP_DBL *sfbEnergySideLdData = psyData[1]->sfbEnergyMSLdData;
+ FIXP_DBL *sfbThresholdLeftLdData =
+ psyOutChannel[0]->sfbThresholdLdData; /* modified where msMask==1 */
+ FIXP_DBL *sfbThresholdRightLdData =
+ psyOutChannel[1]->sfbThresholdLdData; /* modified where msMask==1 */
+
+ FIXP_DBL *mdctSpectrumLeft =
+ psyData[0]->mdctSpectrum; /* modified where msMask==1 */
+ FIXP_DBL *mdctSpectrumRight =
+ psyData[1]->mdctSpectrum; /* modified where msMask==1 */
+
+ INT sfb, sfboffs, j; /* loop counters */
+ FIXP_DBL pnlrLdData, pnmsLdData;
+ FIXP_DBL minThresholdLdData;
+ FIXP_DBL minThreshold;
+ INT useMS;
+
+ INT msMaskTrueSomewhere = 0; /* to determine msDigest */
+ INT numMsMaskFalse =
+ 0; /* number of non-intensity bands where L/R coding is used */
+
+ for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) {
+ for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) {
+ if ((isBook == NULL) ? 1 : (isBook[sfb + sfboffs] == 0)) {
+ FIXP_DBL tmp;
+
+ /*
+ minThreshold=min(sfbThresholdLeft[sfb+sfboffs],
+ sfbThresholdRight[sfb+sfboffs])*scaleMinThres; pnlr =
+ (sfbThresholdLeft[sfb+sfboffs]/
+ max(sfbEnergyLeft[sfb+sfboffs],sfbThresholdLeft[sfb+sfboffs]))*
+ (sfbThresholdRight[sfb+sfboffs]/
+ max(sfbEnergyRight[sfb+sfboffs],sfbThresholdRight[sfb+sfboffs]));
+ pnms =
+ (minThreshold/max(sfbEnergyMid[sfb+sfboffs],minThreshold))*
+ (minThreshold/max(sfbEnergySide[sfb+sfboffs],minThreshold));
+ useMS = (pnms > pnlr);
+ */
+
+ /* we assume that scaleMinThres == 1.0f and we can drop it */
+ minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb + sfboffs],
+ sfbThresholdRightLdData[sfb + sfboffs]);
+
+ /* pnlrLdData = sfbThresholdLeftLdData[sfb+sfboffs] -
+ max(sfbEnergyLeftLdData[sfb+sfboffs],
+ sfbThresholdLeftLdData[sfb+sfboffs]) +
+ sfbThresholdRightLdData[sfb+sfboffs] -
+ max(sfbEnergyRightLdData[sfb+sfboffs],
+ sfbThresholdRightLdData[sfb+sfboffs]); */
+ tmp = fixMax(sfbEnergyLeftLdData[sfb + sfboffs],
+ sfbThresholdLeftLdData[sfb + sfboffs]);
+ pnlrLdData = (sfbThresholdLeftLdData[sfb + sfboffs] >> 1) - (tmp >> 1);
+ pnlrLdData = pnlrLdData + (sfbThresholdRightLdData[sfb + sfboffs] >> 1);
+ tmp = fixMax(sfbEnergyRightLdData[sfb + sfboffs],
+ sfbThresholdRightLdData[sfb + sfboffs]);
+ pnlrLdData = pnlrLdData - (tmp >> 1);
+
+ /* pnmsLdData = minThresholdLdData -
+ max(sfbEnergyMidLdData[sfb+sfboffs], minThresholdLdData) +
+ minThresholdLdData - max(sfbEnergySideLdData[sfb+sfboffs],
+ minThresholdLdData); */
+ tmp = fixMax(sfbEnergyMidLdData[sfb + sfboffs], minThresholdLdData);
+ pnmsLdData = minThresholdLdData - (tmp >> 1);
+ tmp = fixMax(sfbEnergySideLdData[sfb + sfboffs], minThresholdLdData);
+ pnmsLdData = pnmsLdData - (tmp >> 1);
+ useMS = ((allowMS != 0) && (pnmsLdData > pnlrLdData)) ? 1 : 0;
+
+ if (useMS) {
+ msMask[sfb + sfboffs] = 1;
+ msMaskTrueSomewhere = 1;
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ FIXP_DBL specL, specR;
+ specL = mdctSpectrumLeft[j] >> 1;
+ specR = mdctSpectrumRight[j] >> 1;
+ mdctSpectrumLeft[j] = specL + specR;
+ mdctSpectrumRight[j] = specL - specR;
+ }
+ minThreshold = fixMin(sfbThresholdLeft[sfb + sfboffs],
+ sfbThresholdRight[sfb + sfboffs]);
+ sfbThresholdLeft[sfb + sfboffs] = sfbThresholdRight[sfb + sfboffs] =
+ minThreshold;
+ sfbThresholdLeftLdData[sfb + sfboffs] =
+ sfbThresholdRightLdData[sfb + sfboffs] = minThresholdLdData;
+ sfbEnergyLeft[sfb + sfboffs] = sfbEnergyMid[sfb + sfboffs];
+ sfbEnergyRight[sfb + sfboffs] = sfbEnergySide[sfb + sfboffs];
+ sfbEnergyLeftLdData[sfb + sfboffs] =
+ sfbEnergyMidLdData[sfb + sfboffs];
+ sfbEnergyRightLdData[sfb + sfboffs] =
+ sfbEnergySideLdData[sfb + sfboffs];
+
+ sfbSpreadEnLeft[sfb + sfboffs] = sfbSpreadEnRight[sfb + sfboffs] =
+ fixMin(sfbSpreadEnLeft[sfb + sfboffs],
+ sfbSpreadEnRight[sfb + sfboffs]) >>
+ 1;
+
+ } else {
+ msMask[sfb + sfboffs] = 0;
+ numMsMaskFalse++;
+ } /* useMS */
+ } /* isBook */
+ else {
+ /* keep mDigest from IS module */
+ if (msMask[sfb + sfboffs]) {
+ msMaskTrueSomewhere = 1;
+ }
+ /* prohibit MS_MASK_ALL in combination with IS */
+ numMsMaskFalse = 9;
+ } /* isBook */
+ } /* sfboffs */
+ } /* sfb */
+
+ if (msMaskTrueSomewhere == 1) {
+ if ((numMsMaskFalse == 0) ||
+ ((numMsMaskFalse < maxSfbPerGroup) && (numMsMaskFalse < 9))) {
+ *msDigest = SI_MS_MASK_ALL;
+ /* loop through M/S bands; if msMask==0, set it to 1 and apply M/S */
+ for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) {
+ for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) {
+ if (((isBook == NULL) ? 1 : (isBook[sfb + sfboffs] == 0)) &&
+ (msMask[sfb + sfboffs] == 0)) {
+ msMask[sfb + sfboffs] = 1;
+ /* apply M/S coding */
+ for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1];
+ j++) {
+ FIXP_DBL specL, specR;
+ specL = mdctSpectrumLeft[j] >> 1;
+ specR = mdctSpectrumRight[j] >> 1;
+ mdctSpectrumLeft[j] = specL + specR;
+ mdctSpectrumRight[j] = specL - specR;
+ }
+ minThreshold = fixMin(sfbThresholdLeft[sfb + sfboffs],
+ sfbThresholdRight[sfb + sfboffs]);
+ sfbThresholdLeft[sfb + sfboffs] = sfbThresholdRight[sfb + sfboffs] =
+ minThreshold;
+ minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb + sfboffs],
+ sfbThresholdRightLdData[sfb + sfboffs]);
+ sfbThresholdLeftLdData[sfb + sfboffs] =
+ sfbThresholdRightLdData[sfb + sfboffs] = minThresholdLdData;
+ sfbEnergyLeft[sfb + sfboffs] = sfbEnergyMid[sfb + sfboffs];
+ sfbEnergyRight[sfb + sfboffs] = sfbEnergySide[sfb + sfboffs];
+ sfbEnergyLeftLdData[sfb + sfboffs] =
+ sfbEnergyMidLdData[sfb + sfboffs];
+ sfbEnergyRightLdData[sfb + sfboffs] =
+ sfbEnergySideLdData[sfb + sfboffs];
+
+ sfbSpreadEnLeft[sfb + sfboffs] = sfbSpreadEnRight[sfb + sfboffs] =
+ fixMin(sfbSpreadEnLeft[sfb + sfboffs],
+ sfbSpreadEnRight[sfb + sfboffs]) >>
+ 1;
+ }
+ }
+ }
+ } else {
+ *msDigest = SI_MS_MASK_SOME;
+ }
+ } else {
+ *msDigest = SI_MS_MASK_NONE;
+ }
+}
diff --git a/fdk-aac/libAACenc/src/ms_stereo.h b/fdk-aac/libAACenc/src/ms_stereo.h
new file mode 100644
index 0000000..a202307
--- /dev/null
+++ b/fdk-aac/libAACenc/src/ms_stereo.h
@@ -0,0 +1,117 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: MS stereo processing
+
+*******************************************************************************/
+
+#ifndef MS_STEREO_H
+#define MS_STEREO_H
+
+#include "interface.h"
+
+void FDKaacEnc_MsStereoProcessing(PSY_DATA *RESTRICT psyData[(2)],
+ PSY_OUT_CHANNEL *psyOutChannel[2],
+ const INT *isBook, INT *msDigest, /* output */
+ INT *msMask, /* output */
+ const INT allowMS, const INT sfbCnt,
+ const INT sfbPerGroup,
+ const INT maxSfbPerGroup,
+ const INT *sfbOffset);
+
+#endif /* MS_STEREO_H */
diff --git a/fdk-aac/libAACenc/src/noisedet.cpp b/fdk-aac/libAACenc/src/noisedet.cpp
new file mode 100644
index 0000000..c984304
--- /dev/null
+++ b/fdk-aac/libAACenc/src/noisedet.cpp
@@ -0,0 +1,235 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: noisedet.c
+ Routines for Noise Detection
+
+*******************************************************************************/
+
+#include "noisedet.h"
+
+#include "aacenc_pns.h"
+#include "pnsparam.h"
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_fuzzyIsSmaller
+ description: Fuzzy value calculation for "testVal is smaller than refVal"
+ returns: fuzzy value
+ input: test and ref Value,
+ low and high Lim
+ output: return fuzzy value
+
+*****************************************************************************/
+static FIXP_SGL FDKaacEnc_fuzzyIsSmaller(FIXP_DBL testVal, FIXP_DBL refVal,
+ FIXP_DBL loLim, FIXP_DBL hiLim) {
+ if (refVal <= FL2FXCONST_DBL(0.0))
+ return (FL2FXCONST_SGL(0.0f));
+ else if (testVal >= fMult((hiLim >> 1) + (loLim >> 1), refVal))
+ return (FL2FXCONST_SGL(0.0f));
+ else
+ return ((FIXP_SGL)MAXVAL_SGL);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_noiseDetect
+ description: detect tonal sfb's; two tests
+ Powerdistribution:
+ sfb splittet in four regions,
+ compare the energy in all sections
+ PsychTonality:
+ compare tonality from chaosmeasure with reftonality
+ returns:
+ input: spectrum of one large mdct
+ number of sfb's
+ pointer to offset of sfb's
+ pointer to noiseFuzzyMeasure (modified)
+ noiseparams struct
+ pointer to sfb energies
+ pointer to tonality calculated in chaosmeasure
+ output: noiseFuzzy Measure
+
+*****************************************************************************/
+
+void FDKaacEnc_noiseDetect(FIXP_DBL *RESTRICT mdctSpectrum,
+ INT *RESTRICT sfbMaxScaleSpec, INT sfbActive,
+ const INT *RESTRICT sfbOffset,
+ FIXP_SGL *RESTRICT noiseFuzzyMeasure,
+ NOISEPARAMS *np, FIXP_SGL *RESTRICT sfbtonality)
+
+{
+ int i, k, sfb, sfbWidth;
+ FIXP_SGL fuzzy, fuzzyTotal;
+ FIXP_DBL refVal, testVal;
+
+ /***** Start detection phase *****/
+ /* Start noise detection for each band based on a number of checks */
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ fuzzyTotal = (FIXP_SGL)MAXVAL_SGL;
+ sfbWidth = sfbOffset[sfb + 1] - sfbOffset[sfb];
+
+ /* Reset output for lower bands or too small bands */
+ if (sfb < np->startSfb || sfbWidth < np->minSfbWidth) {
+ noiseFuzzyMeasure[sfb] = FL2FXCONST_SGL(0.0f);
+ continue;
+ }
+
+ if ((np->detectionAlgorithmFlags & USE_POWER_DISTRIBUTION) &&
+ (fuzzyTotal > FL2FXCONST_SGL(0.5f))) {
+ FIXP_DBL fhelp1, fhelp2, fhelp3, fhelp4, maxVal, minVal;
+ INT leadingBits = fixMax(
+ 0, (sfbMaxScaleSpec[sfb] -
+ 3)); /* max sfbWidth = 96/4 ; 2^5=32 => 5/2 = 3 (spc*spc) */
+
+ /* check power distribution in four regions */
+ fhelp1 = fhelp2 = fhelp3 = fhelp4 = FL2FXCONST_DBL(0.0f);
+ k = sfbWidth >> 2; /* Width of a quarter band */
+
+ for (i = sfbOffset[sfb]; i < sfbOffset[sfb] + k; i++) {
+ fhelp1 = fPow2AddDiv2(fhelp1, mdctSpectrum[i] << leadingBits);
+ fhelp2 = fPow2AddDiv2(fhelp2, mdctSpectrum[i + k] << leadingBits);
+ fhelp3 = fPow2AddDiv2(fhelp3, mdctSpectrum[i + 2 * k] << leadingBits);
+ fhelp4 = fPow2AddDiv2(fhelp4, mdctSpectrum[i + 3 * k] << leadingBits);
+ }
+
+ /* get max into fhelp: */
+ maxVal = fixMax(fhelp1, fhelp2);
+ maxVal = fixMax(maxVal, fhelp3);
+ maxVal = fixMax(maxVal, fhelp4);
+
+ /* get min into fhelp1: */
+ minVal = fixMin(fhelp1, fhelp2);
+ minVal = fixMin(minVal, fhelp3);
+ minVal = fixMin(minVal, fhelp4);
+
+ /* Normalize min and max Val */
+ leadingBits = CountLeadingBits(maxVal);
+ testVal = maxVal << leadingBits;
+ refVal = minVal << leadingBits;
+
+ /* calculate fuzzy value for power distribution */
+ testVal = fMultDiv2(testVal, np->powDistPSDcurve[sfb]);
+
+ fuzzy = FDKaacEnc_fuzzyIsSmaller(
+ testVal, /* 1/2 * maxValue * PSDcurve */
+ refVal, /* 1 * minValue */
+ FL2FXCONST_DBL(0.495), /* 1/2 * loLim (0.99f/2) */
+ FL2FXCONST_DBL(0.505)); /* 1/2 * hiLim (1.01f/2) */
+
+ fuzzyTotal = fixMin(fuzzyTotal, fuzzy);
+ }
+
+ if ((np->detectionAlgorithmFlags & USE_PSYCH_TONALITY) &&
+ (fuzzyTotal > FL2FXCONST_SGL(0.5f))) {
+ /* Detection with tonality-value of psych. acoustic (here: 1 is tonal!)*/
+
+ testVal = FX_SGL2FX_DBL(sfbtonality[sfb]) >> 1; /* 1/2 * sfbTonality */
+ refVal = np->refTonality;
+
+ fuzzy = FDKaacEnc_fuzzyIsSmaller(
+ testVal, refVal, FL2FXCONST_DBL(0.45f), /* 1/2 * loLim (0.9f/2) */
+ FL2FXCONST_DBL(0.55f)); /* 1/2 * hiLim (1.1f/2) */
+
+ fuzzyTotal = fixMin(fuzzyTotal, fuzzy);
+ }
+
+ /* Output of final result */
+ noiseFuzzyMeasure[sfb] = fuzzyTotal;
+ }
+}
diff --git a/fdk-aac/libAACenc/src/noisedet.h b/fdk-aac/libAACenc/src/noisedet.h
new file mode 100644
index 0000000..478701f
--- /dev/null
+++ b/fdk-aac/libAACenc/src/noisedet.h
@@ -0,0 +1,116 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: noisedet.h
+
+*******************************************************************************/
+
+#ifndef NOISEDET_H
+#define NOISEDET_H
+
+#include "common_fix.h"
+
+#include "pnsparam.h"
+#include "psy_data.h"
+
+void FDKaacEnc_noiseDetect(FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec,
+ INT sfbActive, const INT *sfbOffset,
+ FIXP_SGL noiseFuzzyMeasure[], NOISEPARAMS *np,
+ FIXP_SGL *sfbtonality);
+
+#endif /* NOISEDET_H */
diff --git a/fdk-aac/libAACenc/src/pns_func.h b/fdk-aac/libAACenc/src/pns_func.h
new file mode 100644
index 0000000..88f4586
--- /dev/null
+++ b/fdk-aac/libAACenc/src/pns_func.h
@@ -0,0 +1,138 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: pns_func.h
+
+*******************************************************************************/
+
+#ifndef PNS_FUNC_H
+#define PNS_FUNC_H
+
+#include "common_fix.h"
+#include "aacenc_pns.h"
+#include "psy_data.h"
+
+AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(
+ PNS_CONFIG *pnsConf, INT bitRate, INT sampleRate, INT usePns, INT sfbCnt,
+ const INT *sfbOffset, const INT numChan, const INT isLC);
+
+void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, PNS_DATA *pnsData,
+ const INT lastWindowSequence, const INT sfbActive,
+ const INT maxSfbPerGroup, FIXP_DBL *sfbThresholdLdData,
+ const INT *sfbOffset, FIXP_DBL *mdctSpectrum,
+ INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality,
+ int tnsOrder, INT tnsPredictionGain, INT tnsActive,
+ FIXP_DBL *sfbEnergyLdData, INT *noiseNrg);
+
+void FDKaacEnc_CodePnsChannel(const INT sfbActive, PNS_CONFIG *pnsConf,
+ INT *pnsFlag, FIXP_DBL *sfbEnergy, INT *noiseNrg,
+ FIXP_DBL *sfbThreshold);
+
+void FDKaacEnc_PreProcessPnsChannelPair(
+ const INT sfbActive, FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight,
+ FIXP_DBL *sfbEnergyLeftLD, FIXP_DBL *sfbEnergyRightLD,
+ FIXP_DBL *sfbEnergyMid, PNS_CONFIG *pnsConfLeft, PNS_DATA *pnsDataLeft,
+ PNS_DATA *pnsDataRight);
+
+void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive,
+ PNS_CONFIG *pnsConf,
+ PNS_DATA *pnsDataLeft,
+ PNS_DATA *pnsDataRight, INT *msMask,
+ INT *msDigest);
+
+#endif /* PNS_FUNC_H */
diff --git a/fdk-aac/libAACenc/src/pnsparam.cpp b/fdk-aac/libAACenc/src/pnsparam.cpp
new file mode 100644
index 0000000..a6aab06
--- /dev/null
+++ b/fdk-aac/libAACenc/src/pnsparam.cpp
@@ -0,0 +1,574 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Lohwasser
+
+ Description: PNS parameters depending on bitrate and bandwidth
+
+*******************************************************************************/
+
+#include "pnsparam.h"
+
+#include "psy_configuration.h"
+
+typedef struct {
+ SHORT startFreq;
+ /* Parameters for detection */
+ FIXP_SGL refPower;
+ FIXP_SGL refTonality;
+ SHORT tnsGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */
+ SHORT tnsPNSGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */
+ FIXP_SGL gapFillThr;
+ SHORT minSfbWidth;
+ USHORT detectionAlgorithmFlags;
+} PNS_INFO_TAB;
+
+typedef struct {
+ ULONG brFrom;
+ ULONG brTo;
+ UCHAR S16000;
+ UCHAR S22050;
+ UCHAR S24000;
+ UCHAR S32000;
+ UCHAR S44100;
+ UCHAR S48000;
+} AUTO_PNS_TAB;
+
+static const AUTO_PNS_TAB levelTable_mono[] = {
+ {
+ 0,
+ 11999,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ },
+ {
+ 12000,
+ 19999,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ },
+ {
+ 20000,
+ 28999,
+ 0,
+ 2,
+ 1,
+ 1,
+ 1,
+ 1,
+ },
+ {
+ 29000,
+ 40999,
+ 0,
+ 4,
+ 4,
+ 4,
+ 2,
+ 2,
+ },
+ {
+ 41000,
+ 55999,
+ 0,
+ 9,
+ 9,
+ 7,
+ 7,
+ 7,
+ },
+ {
+ 56000,
+ 61999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 9,
+ 9,
+ },
+ {
+ 62000,
+ 75999,
+ 0,
+ 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[] = {
+ {
+ 0,
+ 11999,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ },
+ {
+ 12000,
+ 19999,
+ 0,
+ 3,
+ 1,
+ 1,
+ 1,
+ 1,
+ },
+ {
+ 20000,
+ 28999,
+ 0,
+ 3,
+ 3,
+ 3,
+ 2,
+ 2,
+ },
+ {
+ 29000,
+ 40999,
+ 0,
+ 7,
+ 6,
+ 6,
+ 5,
+ 5,
+ },
+ {
+ 41000,
+ 55999,
+ 0,
+ 9,
+ 9,
+ 7,
+ 7,
+ 7,
+ },
+ {
+ 56000,
+ 79999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+ {
+ 80000,
+ 99999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+ {
+ 100000,
+ 999999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+};
+
+static const PNS_INFO_TAB pnsInfoTab[] = {
+ /*0 pns off */
+ /*1*/ {4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.06), 1150, 1200,
+ FL2FXCONST_SGL(0.02), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS /*| JUST_LONG_WINDOW*/},
+ /*2*/
+ {4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1130, 1300,
+ FL2FXCONST_SGL(0.05), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS /*| JUST_LONG_WINDOW*/},
+ /*3*/
+ {4100, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1100, 1400,
+ FL2FXCONST_SGL(0.10), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS /*| JUST_LONG_WINDOW*/},
+ /*4*/
+ {4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400,
+ FL2FXCONST_SGL(0.15), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS /*| JUST_LONG_WINDOW*/},
+ /*5*/
+ {4300, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400,
+ FL2FXCONST_SGL(0.15), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*6*/
+ {5000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400,
+ FL2FXCONST_SGL(0.25), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*7*/
+ {5500, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1100, 1400,
+ FL2FXCONST_SGL(0.35), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*8*/
+ {6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1080, 1400,
+ FL2FXCONST_SGL(0.40), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*9*/
+ {6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.14), 1070, 1400,
+ FL2FXCONST_SGL(0.45), 8,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+};
+
+static const AUTO_PNS_TAB levelTable_lowComplexity[] = {
+ {
+ 0,
+ 27999,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ },
+ {
+ 28000,
+ 31999,
+ 0,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ },
+ {
+ 32000,
+ 47999,
+ 0,
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ },
+ {
+ 48000,
+ 48000,
+ 0,
+ 4,
+ 4,
+ 4,
+ 4,
+ 4,
+ },
+ {
+ 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) */
+static const PNS_INFO_TAB pnsInfoTab_lowComplexity[] = {
+ /*0 pns off */
+ /* DEFAULT parameter set */
+ /*1*/ {4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.16), 1100, 1400,
+ FL2FXCONST_SGL(0.5), 16,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*2*/
+ {4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1410, 1400,
+ FL2FXCONST_SGL(0.5), 16,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /*3*/
+ {4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1100, 1400,
+ FL2FXCONST_SGL(0.5), 16,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+ /* LOWSUBST -> PNS is used less often than with DEFAULT parameter set (for
+ br: 48000 - 79999) */
+ /*4*/
+ {4100, FL2FXCONST_SGL(0.20), FL2FXCONST_SGL(0.10), 1410, 1400,
+ FL2FXCONST_SGL(0.5), 16,
+ USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR |
+ USE_TNS_PNS | JUST_LONG_WINDOW},
+};
+
+/****************************************************************************
+ function to look up used pns level
+****************************************************************************/
+int FDKaacEnc_lookUpPnsUse(int bitRate, int sampleRate, int numChan,
+ const int isLC) {
+ int hUsePns = 0, size, i;
+ const AUTO_PNS_TAB *levelTable;
+
+ if (isLC) {
+ levelTable = &levelTable_lowComplexity[0];
+ size = sizeof(levelTable_lowComplexity);
+ } else { /* (E)LD */
+ levelTable = (numChan > 1) ? &levelTable_stereo[0] : &levelTable_mono[0];
+ size = (numChan > 1) ? sizeof(levelTable_stereo) : sizeof(levelTable_mono);
+ }
+
+ for (i = 0; i < (int)(size / sizeof(AUTO_PNS_TAB)); i++) {
+ if (((ULONG)bitRate >= levelTable[i].brFrom) &&
+ ((ULONG)bitRate <= levelTable[i].brTo))
+ break;
+ }
+
+ /* sanity check */
+ if ((int)(sizeof(pnsInfoTab) / sizeof(PNS_INFO_TAB)) < i) {
+ return (PNS_TABLE_ERROR);
+ }
+
+ switch (sampleRate) {
+ case 16000:
+ hUsePns = levelTable[i].S16000;
+ break;
+ case 22050:
+ hUsePns = levelTable[i].S22050;
+ break;
+ case 24000:
+ hUsePns = levelTable[i].S24000;
+ break;
+ case 32000:
+ hUsePns = levelTable[i].S32000;
+ break;
+ case 44100:
+ hUsePns = levelTable[i].S44100;
+ break;
+ case 48000:
+ hUsePns = levelTable[i].S48000;
+ break;
+ default:
+ if (isLC) {
+ hUsePns = levelTable[i].S48000;
+ }
+ break;
+ }
+
+ return (hUsePns);
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_GetPnsParam
+ description: Gets PNS parameters depending on bitrate and bandwidth or
+ bitsPerLine
+ returns: error status
+ input: Noiseparams struct, bitrate, sampling rate,
+ number of sfb's, pointer to sfb offset
+ output: PNS parameters
+
+*****************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, INT bitRate,
+ INT sampleRate, INT sfbCnt,
+ const INT *sfbOffset, INT *usePns,
+ INT numChan, const INT isLC) {
+ int i, hUsePns;
+ const PNS_INFO_TAB *pnsInfo;
+
+ if (*usePns <= 0) return AAC_ENC_OK;
+
+ if (isLC) {
+ np->detectionAlgorithmFlags = IS_LOW_COMPLEXITY;
+
+ pnsInfo = pnsInfoTab_lowComplexity;
+
+ /* new pns params */
+ hUsePns = FDKaacEnc_lookUpPnsUse(bitRate, sampleRate, numChan, isLC);
+ if (hUsePns == 0) {
+ *usePns = 0;
+ return AAC_ENC_OK;
+ }
+
+ if (hUsePns == PNS_TABLE_ERROR) {
+ return AAC_ENC_PNS_TABLE_ERROR;
+ }
+
+ /* select correct row of tuning table */
+ pnsInfo += hUsePns - 1;
+
+ } else {
+ np->detectionAlgorithmFlags = 0;
+ pnsInfo = pnsInfoTab;
+
+ /* new pns params */
+ hUsePns = FDKaacEnc_lookUpPnsUse(bitRate, sampleRate, numChan, isLC);
+ if (hUsePns == 0) {
+ *usePns = 0;
+ return AAC_ENC_OK;
+ }
+ if (hUsePns == PNS_TABLE_ERROR) return AAC_ENC_PNS_TABLE_ERROR;
+
+ /* select correct row of tuning table */
+ pnsInfo += hUsePns - 1;
+ }
+
+ np->startSfb = FDKaacEnc_FreqToBandWidthRounding(
+ pnsInfo->startFreq, sampleRate, sfbCnt, sfbOffset);
+
+ np->detectionAlgorithmFlags |= pnsInfo->detectionAlgorithmFlags;
+
+ np->refPower = FX_SGL2FX_DBL(pnsInfo->refPower);
+ np->refTonality = FX_SGL2FX_DBL(pnsInfo->refTonality);
+ np->tnsGainThreshold = pnsInfo->tnsGainThreshold;
+ np->tnsPNSGainThreshold = pnsInfo->tnsPNSGainThreshold;
+ np->minSfbWidth = pnsInfo->minSfbWidth;
+
+ np->gapFillThr =
+ pnsInfo->gapFillThr; /* for LC it is always FL2FXCONST_SGL(0.5) */
+
+ /* assuming a constant dB/Hz slope in the signal's PSD curve,
+ the detection threshold needs to be corrected for the width of the band */
+
+ for (i = 0; i < (sfbCnt - 1); i++) {
+ INT qtmp, sfbWidth;
+ FIXP_DBL tmp;
+
+ sfbWidth = sfbOffset[i + 1] - sfbOffset[i];
+
+ tmp = fPow(np->refPower, 0, sfbWidth, DFRACT_BITS - 1 - 5, &qtmp);
+ np->powDistPSDcurve[i] = (FIXP_SGL)((LONG)(scaleValue(tmp, qtmp) >> 16));
+ }
+ np->powDistPSDcurve[sfbCnt] = np->powDistPSDcurve[sfbCnt - 1];
+
+ return AAC_ENC_OK;
+}
diff --git a/fdk-aac/libAACenc/src/pnsparam.h b/fdk-aac/libAACenc/src/pnsparam.h
new file mode 100644
index 0000000..c37738a
--- /dev/null
+++ b/fdk-aac/libAACenc/src/pnsparam.h
@@ -0,0 +1,149 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: PNS parameters depending on bitrate and bandwidth
+
+*******************************************************************************/
+
+#ifndef PNSPARAM_H
+#define PNSPARAM_H
+
+#include "aacenc.h"
+#include "common_fix.h"
+#include "psy_const.h"
+
+#define NUM_PNSINFOTAB 4
+#define PNS_TABLE_ERROR -1
+
+/* detection algorithm flags */
+#define USE_POWER_DISTRIBUTION (1 << 0)
+#define USE_PSYCH_TONALITY (1 << 1)
+#define USE_TNS_GAIN_THR (1 << 2)
+#define USE_TNS_PNS (1 << 3)
+#define JUST_LONG_WINDOW (1 << 4)
+/* additional algorithm flags */
+#define IS_LOW_COMPLEXITY (1 << 5)
+
+typedef struct {
+ /* PNS start band */
+ short startSfb;
+
+ /* detection algorithm flags */
+ USHORT detectionAlgorithmFlags;
+
+ /* Parameters for detection */
+ FIXP_DBL refPower;
+ FIXP_DBL refTonality;
+ INT tnsGainThreshold;
+ INT tnsPNSGainThreshold;
+ INT minSfbWidth;
+ FIXP_SGL powDistPSDcurve[MAX_GROUPED_SFB];
+ FIXP_SGL gapFillThr;
+} NOISEPARAMS;
+
+int FDKaacEnc_lookUpPnsUse(int bitRate, int sampleRate, int numChan,
+ const int isLC);
+
+/****** Definition of prototypes ******/
+
+AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, INT bitRate,
+ INT sampleRate, INT sfbCnt,
+ const INT *sfbOffset, INT *usePns,
+ INT numChan, const INT isLC);
+
+#endif /* PNSPARAM_H */
diff --git a/fdk-aac/libAACenc/src/pre_echo_control.cpp b/fdk-aac/libAACenc/src/pre_echo_control.cpp
new file mode 100644
index 0000000..3d5d153
--- /dev/null
+++ b/fdk-aac/libAACenc/src/pre_echo_control.cpp
@@ -0,0 +1,176 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Pre echo control
+
+*******************************************************************************/
+
+#include "pre_echo_control.h"
+#include "psy_configuration.h"
+
+void FDKaacEnc_InitPreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1,
+ INT *calcPreEcho, INT numPb,
+ FIXP_DBL *RESTRICT sfbPcmQuantThreshold,
+ INT *mdctScalenm1) {
+ *mdctScalenm1 = PCM_QUANT_THR_SCALE >> 1;
+
+ FDKmemcpy(pbThresholdNm1, sfbPcmQuantThreshold, numPb * sizeof(FIXP_DBL));
+
+ *calcPreEcho = 1;
+}
+
+void FDKaacEnc_PreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1,
+ INT calcPreEcho, INT numPb,
+ INT maxAllowedIncreaseFactor,
+ FIXP_SGL minRemainingThresholdFactor,
+ FIXP_DBL *RESTRICT pbThreshold, INT mdctScale,
+ INT *mdctScalenm1) {
+ int i;
+ FIXP_DBL tmpThreshold1, tmpThreshold2;
+ int scaling;
+
+ /* If lastWindowSequence in previous frame was start- or stop-window,
+ skip preechocontrol calculation */
+ if (calcPreEcho == 0) {
+ /* copy thresholds to internal memory */
+ FDKmemcpy(pbThresholdNm1, pbThreshold, numPb * sizeof(FIXP_DBL));
+ *mdctScalenm1 = mdctScale;
+ return;
+ }
+
+ if (mdctScale > *mdctScalenm1) {
+ /* if current thresholds are downscaled more than the ones from the last
+ * block */
+ scaling = 2 * (mdctScale - *mdctScalenm1);
+ for (i = 0; i < numPb; i++) {
+ /* multiplication with return data type fract ist equivalent to int
+ * multiplication */
+ FDK_ASSERT(scaling >= 0);
+ tmpThreshold1 = maxAllowedIncreaseFactor * (pbThresholdNm1[i] >> scaling);
+ tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]);
+
+ FIXP_DBL tmp = pbThreshold[i];
+
+ /* copy thresholds to internal memory */
+ pbThresholdNm1[i] = tmp;
+
+ tmp = fixMin(tmp, tmpThreshold1);
+ pbThreshold[i] = fixMax(tmp, tmpThreshold2);
+ }
+ } else {
+ /* if thresholds of last block are more downscaled than the current ones */
+ scaling = 2 * (*mdctScalenm1 - mdctScale);
+ for (i = 0; i < numPb; i++) {
+ /* multiplication with return data type fract ist equivalent to int
+ * multiplication */
+ tmpThreshold1 = (maxAllowedIncreaseFactor >> 1) * pbThresholdNm1[i];
+ tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]);
+
+ /* copy thresholds to internal memory */
+ pbThresholdNm1[i] = pbThreshold[i];
+
+ FDK_ASSERT(scaling >= 0);
+ if ((pbThreshold[i] >> (scaling + 1)) > tmpThreshold1) {
+ pbThreshold[i] = tmpThreshold1 << (scaling + 1);
+ }
+ pbThreshold[i] = fixMax(pbThreshold[i], tmpThreshold2);
+ }
+ }
+
+ *mdctScalenm1 = mdctScale;
+}
diff --git a/fdk-aac/libAACenc/src/pre_echo_control.h b/fdk-aac/libAACenc/src/pre_echo_control.h
new file mode 100644
index 0000000..688efdb
--- /dev/null
+++ b/fdk-aac/libAACenc/src/pre_echo_control.h
@@ -0,0 +1,118 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Pre echo control
+
+*******************************************************************************/
+
+#ifndef PRE_ECHO_CONTROL_H
+#define PRE_ECHO_CONTROL_H
+
+#include "common_fix.h"
+
+void FDKaacEnc_InitPreEchoControl(FIXP_DBL *pbThresholdnm1, INT *calcPreEcho,
+ INT numPb, FIXP_DBL *sfbPcmQuantThreshold,
+ INT *mdctScalenm1);
+
+void FDKaacEnc_PreEchoControl(FIXP_DBL *pbThresholdNm1, INT calcPreEcho,
+ INT numPb, INT maxAllowedIncreaseFactor,
+ FIXP_SGL minRemainingThresholdFactor,
+ FIXP_DBL *pbThreshold, INT mdctScale,
+ INT *mdctScalenm1);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/psy_configuration.cpp b/fdk-aac/libAACenc/src/psy_configuration.cpp
new file mode 100644
index 0000000..b444b58
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_configuration.cpp
@@ -0,0 +1,801 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Psychoaccoustic configuration
+
+*******************************************************************************/
+
+#include "psy_configuration.h"
+#include "adj_thr.h"
+#include "aacEnc_rom.h"
+
+#include "genericStds.h"
+
+#include "FDK_trigFcts.h"
+
+typedef struct {
+ LONG sampleRate;
+ const SFB_PARAM_LONG *paramLong;
+ const SFB_PARAM_SHORT *paramShort;
+} SFB_INFO_TAB;
+
+static const SFB_INFO_TAB sfbInfoTab[] = {
+ {8000, &p_FDKaacEnc_8000_long_1024, &p_FDKaacEnc_8000_short_128},
+ {11025, &p_FDKaacEnc_11025_long_1024, &p_FDKaacEnc_11025_short_128},
+ {12000, &p_FDKaacEnc_12000_long_1024, &p_FDKaacEnc_12000_short_128},
+ {16000, &p_FDKaacEnc_16000_long_1024, &p_FDKaacEnc_16000_short_128},
+ {22050, &p_FDKaacEnc_22050_long_1024, &p_FDKaacEnc_22050_short_128},
+ {24000, &p_FDKaacEnc_24000_long_1024, &p_FDKaacEnc_24000_short_128},
+ {32000, &p_FDKaacEnc_32000_long_1024, &p_FDKaacEnc_32000_short_128},
+ {44100, &p_FDKaacEnc_44100_long_1024, &p_FDKaacEnc_44100_short_128},
+ {48000, &p_FDKaacEnc_48000_long_1024, &p_FDKaacEnc_48000_short_128},
+ {64000, &p_FDKaacEnc_64000_long_1024, &p_FDKaacEnc_64000_short_128},
+ {88200, &p_FDKaacEnc_88200_long_1024, &p_FDKaacEnc_88200_short_128},
+ {96000, &p_FDKaacEnc_96000_long_1024, &p_FDKaacEnc_96000_short_128}
+
+};
+
+
+
+const SFB_PARAM_LONG p_FDKaacEnc_8000_long_960 = {
+ 40,
+ { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16,
+ 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28,
+ 28, 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 16 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_8000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_11025_long_960 = {
+ 42,
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24,
+ 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_11025_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_12000_long_960 = {
+ 42,
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24,
+ 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_12000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_16000_long_960 = {
+ 42,
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24,
+ 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_16000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_22050_long_960 = {
+ 46,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16,
+ 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, 52, 52,
+ 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_22050_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_24000_long_960 = {
+ 46,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16,
+ 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, 52, 52,
+ 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_24000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_32000_long_960 = {
+ 49,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32 }
+};
+
+const SFB_PARAM_SHORT p_FDKaacEnc_32000_short_120 = {
+ 14,
+ { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 8 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_44100_long_960 = {
+ 49,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
+ 8, 8, 8, 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28,
+ 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32 }
+};
+
+const SFB_PARAM_SHORT p_FDKaacEnc_44100_short_120 = {
+ 14,
+ { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 8 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_48000_long_960 = {
+ 49,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
+ 8, 8, 8, 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28,
+ 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_48000_short_120 = {
+ 14,
+ { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 8 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_64000_long_960 = {
+ 46,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12,
+ 12, 16, 16, 16, 20, 24, 24, 28, 36, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 16 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_64000_short_120 = {
+ 12,
+ { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 28 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_88200_long_960 = {
+ 40,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12,
+ 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_88200_short_120 = {
+ 12,
+ { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 28 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_96000_long_960 = {
+ 40,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12,
+ 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_120 = {
+ 12,
+ { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 28 }
+};
+
+
+static const SFB_INFO_TAB sfbInfoTab960[] = {
+ { 8000, &p_FDKaacEnc_8000_long_960, &p_FDKaacEnc_8000_short_120},
+ {11025, &p_FDKaacEnc_11025_long_960, &p_FDKaacEnc_11025_short_120},
+ {12000, &p_FDKaacEnc_12000_long_960, &p_FDKaacEnc_12000_short_120},
+ {16000, &p_FDKaacEnc_16000_long_960, &p_FDKaacEnc_16000_short_120},
+ {22050, &p_FDKaacEnc_22050_long_960, &p_FDKaacEnc_22050_short_120},
+ {24000, &p_FDKaacEnc_24000_long_960, &p_FDKaacEnc_24000_short_120},
+ {32000, &p_FDKaacEnc_32000_long_960, &p_FDKaacEnc_32000_short_120},
+ {44100, &p_FDKaacEnc_44100_long_960, &p_FDKaacEnc_44100_short_120},
+ {48000, &p_FDKaacEnc_48000_long_960, &p_FDKaacEnc_48000_short_120},
+ {64000, &p_FDKaacEnc_64000_long_960, &p_FDKaacEnc_64000_short_120},
+ {88200, &p_FDKaacEnc_88200_long_960, &p_FDKaacEnc_88200_short_120},
+ {96000, &p_FDKaacEnc_96000_long_960, &p_FDKaacEnc_96000_short_120},
+};
+
+
+/* 22050 and 24000 Hz */
+static const SFB_PARAM_LONG p_22050_long_512 = {
+ 31, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12,
+ 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}};
+
+/* 32000 Hz */
+static const SFB_PARAM_LONG p_32000_long_512 = {
+ 37,
+ {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 32, 32, 32, 32, 32, 32, 32}};
+
+/* 44100 Hz */
+static const SFB_PARAM_LONG p_44100_long_512 = {
+ 36, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8,
+ 8, 8, 12, 12, 12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 52}};
+
+static const SFB_INFO_TAB sfbInfoTabLD512[] = {
+ {8000, &p_22050_long_512, NULL}, {11025, &p_22050_long_512, NULL},
+ {12000, &p_22050_long_512, NULL}, {16000, &p_22050_long_512, NULL},
+ {22050, &p_22050_long_512, NULL}, {24000, &p_22050_long_512, NULL},
+ {32000, &p_32000_long_512, NULL}, {44100, &p_44100_long_512, NULL},
+ {48000, &p_44100_long_512, NULL}, {64000, &p_44100_long_512, NULL},
+ {88200, &p_44100_long_512, NULL}, {96000, &p_44100_long_512, NULL},
+ {128000, &p_44100_long_512, NULL}, {176400, &p_44100_long_512, NULL},
+ {192000, &p_44100_long_512, NULL}, {256000, &p_44100_long_512, NULL},
+ {352800, &p_44100_long_512, NULL}, {384000, &p_44100_long_512, NULL},
+};
+
+/* 22050 and 24000 Hz */
+static const SFB_PARAM_LONG p_22050_long_480 = {
+ 30, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12,
+ 12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32}};
+
+/* 32000 Hz */
+static const SFB_PARAM_LONG p_32000_long_480 = {
+ 37, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8,
+ 8, 8, 8, 12, 12, 12, 16, 16, 20, 24, 32, 32, 32, 32, 32, 32, 32, 32}};
+
+/* 44100 Hz */
+static const SFB_PARAM_LONG p_44100_long_480 = {
+ 35, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
+ 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, 32, 32, 32, 32, 32, 32, 48}};
+
+static const SFB_INFO_TAB sfbInfoTabLD480[] = {
+ {8000, &p_22050_long_480, NULL}, {11025, &p_22050_long_480, NULL},
+ {12000, &p_22050_long_480, NULL}, {16000, &p_22050_long_480, NULL},
+ {22050, &p_22050_long_480, NULL}, {24000, &p_22050_long_480, NULL},
+ {32000, &p_32000_long_480, NULL}, {44100, &p_44100_long_480, NULL},
+ {48000, &p_44100_long_480, NULL}, {64000, &p_44100_long_480, NULL},
+ {88200, &p_44100_long_480, NULL}, {96000, &p_44100_long_480, NULL},
+ {128000, &p_44100_long_480, NULL}, {176400, &p_44100_long_480, NULL},
+ {192000, &p_44100_long_480, NULL}, {256000, &p_44100_long_480, NULL},
+ {352800, &p_44100_long_480, NULL}, {384000, &p_44100_long_480, NULL},
+};
+
+/* Fixed point precision definitions */
+#define Q_BARCVAL (25)
+
+AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(const LONG sampleRate,
+ const INT blockType,
+ const INT granuleLength,
+ INT *const sfbOffset,
+ INT *const sfbCnt) {
+ INT i, specStartOffset = 0;
+ INT granuleLengthWindow = granuleLength;
+ const UCHAR *sfbWidth = NULL;
+ const SFB_INFO_TAB *sfbInfo = NULL;
+ int size;
+
+ /*
+ select table
+ */
+ switch (granuleLength) {
+ case 1024:
+ sfbInfo = sfbInfoTab;
+ size = (INT)(sizeof(sfbInfoTab) / sizeof(SFB_INFO_TAB));
+ break;
+ case 960:
+ sfbInfo = sfbInfoTab960;
+ size = (INT)(sizeof(sfbInfoTab960)/sizeof(SFB_INFO_TAB));
+ break;
+ case 512:
+ sfbInfo = sfbInfoTabLD512;
+ size = sizeof(sfbInfoTabLD512);
+ break;
+ case 480:
+ sfbInfo = sfbInfoTabLD480;
+ size = sizeof(sfbInfoTabLD480);
+ break;
+ default:
+ return AAC_ENC_INVALID_FRAME_LENGTH;
+ }
+
+ for (i = 0; i < size; i++) {
+ if (sfbInfo[i].sampleRate == sampleRate) {
+ switch (blockType) {
+ case LONG_WINDOW:
+ case START_WINDOW:
+ case STOP_WINDOW:
+ sfbWidth = sfbInfo[i].paramLong->sfbWidth;
+ *sfbCnt = sfbInfo[i].paramLong->sfbCnt;
+ break;
+ case SHORT_WINDOW:
+ sfbWidth = sfbInfo[i].paramShort->sfbWidth;
+ *sfbCnt = sfbInfo[i].paramShort->sfbCnt;
+ granuleLengthWindow /= TRANS_FAC;
+ break;
+ }
+ break;
+ }
+ }
+ if (i == size) {
+ return AAC_ENC_UNSUPPORTED_SAMPLINGRATE;
+ }
+
+ /*
+ calc sfb offsets
+ */
+ for (i = 0; i < *sfbCnt; i++) {
+ sfbOffset[i] = specStartOffset;
+ specStartOffset += sfbWidth[i];
+ if (specStartOffset >= granuleLengthWindow) {
+ i++;
+ break;
+ }
+ }
+ *sfbCnt = fixMin(i, *sfbCnt);
+ sfbOffset[*sfbCnt] = fixMin(specStartOffset, granuleLengthWindow);
+ return AAC_ENC_OK;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_BarcLineValue
+ description: Calculates barc value for one frequency line
+ returns: barc value of line
+ input: number of lines in transform, index of line to check, Fs
+ output:
+
+*****************************************************************************/
+static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine,
+ LONG samplingFreq) {
+ FIXP_DBL FOURBY3EM4 = (FIXP_DBL)0x45e7b273; /* 4.0/3 * 0.0001 in q43 */
+ FIXP_DBL PZZZ76 = (FIXP_DBL)0x639d5e4a; /* 0.00076 in q41 */
+ FIXP_DBL ONE3P3 = (FIXP_DBL)0x35333333; /* 13.3 in q26 */
+ FIXP_DBL THREEP5 = (FIXP_DBL)0x1c000000; /* 3.5 in q27 */
+ FIXP_DBL INV480 = (FIXP_DBL)0x44444444; // 1/480 in q39
+
+ FIXP_DBL center_freq, x1, x2;
+ FIXP_DBL bvalFFTLine, atan1, atan2;
+
+ /* Theoritical maximum of center_freq (samp_freq*0.5) is 96khz * 0.5 = 48000
+ */
+ /* Theoritical maximum of x1 is 1.3333333e-4f * center_freq = 6.4, can keep in
+ * q28 */
+ /* Theoritical maximum of x2 is 0.00076f * center_freq = 36.48, can keep in
+ * q25 */
+
+ center_freq = fftLine * samplingFreq; /* q11 or q8 */
+
+
+ switch (noOfLines) {
+ case 1024:
+ center_freq = center_freq << 2; /* q13 */
+ break;
+ case 960:
+ center_freq = fMult(center_freq, INV480) << 3;
+ break;
+ case 128:
+ center_freq = center_freq << 5; /* q13 */
+ break;
+ case 120:
+ center_freq = fMult(center_freq, INV480) << 6;
+ break;
+ case 512:
+ center_freq = (fftLine * samplingFreq) << 3; // q13
+ break;
+ case 480:
+ center_freq = fMult(center_freq, INV480) << 4; // q13
+ break;
+ default:
+ center_freq = (FIXP_DBL)0;
+ }
+
+
+ x1 = fMult(center_freq, FOURBY3EM4); /* q13 * q43 - (DFRACT_BITS-1) = q25 */
+ x2 = fMult(center_freq, PZZZ76)
+ << 2; /* q13 * q41 - (DFRACT_BITS-1) + 2 = q25 */
+
+ atan1 = fixp_atan(x1);
+ atan2 = fixp_atan(x2);
+
+ /* q25 (q26 * q30 - (DFRACT_BITS-1)) + q25 (q27 * q30 * q30) */
+ bvalFFTLine = fMult(ONE3P3, atan2) + fMult(THREEP5, fMult(atan1, atan1));
+ return (bvalFFTLine);
+}
+
+/*
+ do not consider energies below a certain input signal level,
+ i.e. of -96dB or 1 bit at 16 bit PCM resolution,
+ might need to be configurable to e.g. 24 bit PCM Input or a lower
+ resolution for low bit rates
+*/
+static void FDKaacEnc_InitMinPCMResolution(int numPb, int *pbOffset,
+ FIXP_DBL *sfbPCMquantThreshold) {
+/* PCM_QUANT_NOISE = FDKpow(10.0f, - 20.f / 10.0f) * ABS_LOW * NORM_PCM_ENERGY *
+ * FDKpow(2,PCM_QUANT_THR_SCALE) */
+#define PCM_QUANT_NOISE ((FIXP_DBL)0x00547062)
+
+ for (int i = 0; i < numPb; i++) {
+ sfbPCMquantThreshold[i] = (pbOffset[i + 1] - pbOffset[i]) * PCM_QUANT_NOISE;
+ }
+}
+
+static FIXP_DBL getMaskFactor(const FIXP_DBL dbVal_fix, const INT dbVal_e,
+ const FIXP_DBL ten_fix, const INT ten_e) {
+ INT q_msk;
+ FIXP_DBL mask_factor;
+
+ mask_factor = fPow(ten_fix, DFRACT_BITS - 1 - ten_e, -dbVal_fix,
+ DFRACT_BITS - 1 - dbVal_e, &q_msk);
+ q_msk = fixMin(DFRACT_BITS - 1, fixMax(-(DFRACT_BITS - 1), q_msk));
+
+ if ((q_msk > 0) && (mask_factor > (FIXP_DBL)MAXVAL_DBL >> q_msk)) {
+ mask_factor = (FIXP_DBL)MAXVAL_DBL;
+ } else {
+ mask_factor = scaleValue(mask_factor, q_msk);
+ }
+
+ return (mask_factor);
+}
+
+static void FDKaacEnc_initSpreading(INT numPb, FIXP_DBL *pbBarcValue,
+ FIXP_DBL *pbMaskLoFactor,
+ FIXP_DBL *pbMaskHiFactor,
+ FIXP_DBL *pbMaskLoFactorSprEn,
+ FIXP_DBL *pbMaskHiFactorSprEn,
+ const LONG bitrate, const INT blockType)
+
+{
+ INT i;
+ FIXP_DBL MASKLOWSPREN, MASKHIGHSPREN;
+
+ FIXP_DBL MASKHIGH = (FIXP_DBL)0x30000000; /* 1.5 in q29 */
+ FIXP_DBL MASKLOW = (FIXP_DBL)0x60000000; /* 3.0 in q29 */
+ FIXP_DBL MASKLOWSPRENLONG = (FIXP_DBL)0x60000000; /* 3.0 in q29 */
+ FIXP_DBL MASKHIGHSPRENLONG = (FIXP_DBL)0x40000000; /* 2.0 in q29 */
+ FIXP_DBL MASKHIGHSPRENLONGLOWBR = (FIXP_DBL)0x30000000; /* 1.5 in q29 */
+ FIXP_DBL MASKLOWSPRENSHORT = (FIXP_DBL)0x40000000; /* 2.0 in q29 */
+ FIXP_DBL MASKHIGHSPRENSHORT = (FIXP_DBL)0x30000000; /* 1.5 in q29 */
+ FIXP_DBL TEN = (FIXP_DBL)0x50000000; /* 10.0 in q27 */
+
+ if (blockType != SHORT_WINDOW) {
+ MASKLOWSPREN = MASKLOWSPRENLONG;
+ MASKHIGHSPREN =
+ (bitrate > 20000) ? MASKHIGHSPRENLONG : MASKHIGHSPRENLONGLOWBR;
+ } else {
+ MASKLOWSPREN = MASKLOWSPRENSHORT;
+ MASKHIGHSPREN = MASKHIGHSPRENSHORT;
+ }
+
+ for (i = 0; i < numPb; i++) {
+ if (i > 0) {
+ pbMaskHiFactor[i] = getMaskFactor(
+ fMult(MASKHIGH, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27);
+
+ pbMaskLoFactor[i - 1] = getMaskFactor(
+ fMult(MASKLOW, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27);
+
+ pbMaskHiFactorSprEn[i] = getMaskFactor(
+ fMult(MASKHIGHSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN,
+ 27);
+
+ pbMaskLoFactorSprEn[i - 1] = getMaskFactor(
+ fMult(MASKLOWSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN,
+ 27);
+ } else {
+ pbMaskHiFactor[i] = (FIXP_DBL)0;
+ pbMaskLoFactor[numPb - 1] = (FIXP_DBL)0;
+ pbMaskHiFactorSprEn[i] = (FIXP_DBL)0;
+ pbMaskLoFactorSprEn[numPb - 1] = (FIXP_DBL)0;
+ }
+ }
+}
+
+static void FDKaacEnc_initBarcValues(INT numPb, INT *pbOffset, INT numLines,
+ INT samplingFrequency, FIXP_DBL *pbBval) {
+ INT i;
+ FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */
+
+ for (i = 0; i < numPb; i++) {
+ FIXP_DBL v1, v2, cur_bark;
+ v1 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i], samplingFrequency);
+ v2 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i + 1], samplingFrequency);
+ cur_bark = (v1 >> 1) + (v2 >> 1);
+ pbBval[i] = fixMin(cur_bark, MAX_BARC);
+ }
+}
+
+static void FDKaacEnc_initMinSnr(const LONG bitrate, const LONG samplerate,
+ const INT numLines, const INT *sfbOffset,
+ const INT sfbActive, const INT blockType,
+ FIXP_DBL *sfbMinSnrLdData) {
+ INT sfb;
+
+ /* Fix conversion variables */
+ INT qbfac, qperwin, qdiv, qpeprt_const, qpeprt;
+ INT qtmp, qsnr, sfbWidth;
+
+ FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */
+ FIXP_DBL MAX_BARCP1 = (FIXP_DBL)0x32000000; /* 25.0 in q25 */
+ FIXP_DBL BITS2PEFAC = (FIXP_DBL)0x4b851eb8; /* 1.18 in q30 */
+ FIXP_DBL PERS2P4 = (FIXP_DBL)0x624dd2f2; /* 0.024 in q36 */
+ FIXP_DBL ONEP5 = (FIXP_DBL)0x60000000; /* 1.5 in q30 */
+ FIXP_DBL MAX_SNR = (FIXP_DBL)0x33333333; /* 0.8 in q30 */
+ FIXP_DBL MIN_SNR = (FIXP_DBL)0x003126e9; /* 0.003 in q30 */
+
+ FIXP_DBL barcFactor, pePerWindow, pePart, barcWidth;
+ FIXP_DBL pePart_const, tmp, snr, one_qsnr, one_point5;
+
+ /* relative number of active barks */
+ barcFactor = fDivNorm(fixMin(FDKaacEnc_BarcLineValue(
+ numLines, sfbOffset[sfbActive], samplerate),
+ MAX_BARC),
+ MAX_BARCP1, &qbfac);
+
+ qbfac = DFRACT_BITS - 1 - qbfac;
+
+ pePerWindow = fDivNorm(bitrate, samplerate, &qperwin);
+ qperwin = DFRACT_BITS - 1 - qperwin;
+ pePerWindow = fMult(pePerWindow, BITS2PEFAC);
+ qperwin = qperwin + 30 - (DFRACT_BITS - 1);
+ pePerWindow = fMult(pePerWindow, PERS2P4);
+ qperwin = qperwin + 36 - (DFRACT_BITS - 1);
+
+ switch (numLines) {
+ case 1024:
+ qperwin = qperwin - 10;
+ break;
+ case 128:
+ qperwin = qperwin - 7;
+ break;
+ case 512:
+ qperwin = qperwin - 9;
+ break;
+ case 480:
+ qperwin = qperwin - 9;
+ pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(480.f / 512.f));
+ break;
+ case 960:
+ pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(960.f/1024.f));
+ qperwin = qperwin - 10;
+ break;
+ case 120:
+ pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(120.f/128.f));
+ qperwin = qperwin - 7;
+ break;
+ }
+
+ /* for short blocks it is assumed that more bits are available */
+ if (blockType == SHORT_WINDOW) {
+ pePerWindow = fMult(pePerWindow, ONEP5);
+ qperwin = qperwin + 30 - (DFRACT_BITS - 1);
+ }
+ pePart_const = fDivNorm(pePerWindow, barcFactor, &qdiv);
+ qpeprt_const = qperwin - qbfac + DFRACT_BITS - 1 - qdiv;
+
+ for (sfb = 0; sfb < sfbActive; sfb++) {
+ barcWidth =
+ FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb + 1], samplerate) -
+ FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb], samplerate);
+
+ /* adapt to sfb bands */
+ pePart = fMult(pePart_const, barcWidth);
+ qpeprt = qpeprt_const + 25 - (DFRACT_BITS - 1);
+
+ /* pe -> snr calculation */
+ sfbWidth = (sfbOffset[sfb + 1] - sfbOffset[sfb]);
+ pePart = fDivNorm(pePart, sfbWidth, &qdiv);
+ qpeprt += DFRACT_BITS - 1 - qdiv;
+
+ tmp = f2Pow(pePart, DFRACT_BITS - 1 - qpeprt, &qtmp);
+ qtmp = DFRACT_BITS - 1 - qtmp;
+
+ /* Subtract 1.5 */
+ qsnr = fixMin(qtmp, 30);
+ tmp = tmp >> (qtmp - qsnr);
+
+ if ((30 + 1 - qsnr) > (DFRACT_BITS - 1))
+ one_point5 = (FIXP_DBL)0;
+ else
+ one_point5 = (FIXP_DBL)(ONEP5 >> (30 + 1 - qsnr));
+
+ snr = (tmp >> 1) - (one_point5);
+ qsnr -= 1;
+
+ /* max(snr, 1.0) */
+ if (qsnr > 0)
+ one_qsnr = (FIXP_DBL)(1 << qsnr);
+ else
+ one_qsnr = (FIXP_DBL)0;
+
+ snr = fixMax(one_qsnr, snr);
+
+ /* 1/snr */
+ snr = fDivNorm(one_qsnr, snr, &qsnr);
+ qsnr = DFRACT_BITS - 1 - qsnr;
+ snr = (qsnr > 30) ? (snr >> (qsnr - 30)) : snr;
+
+ /* upper limit is -1 dB */
+ snr = (snr > MAX_SNR) ? MAX_SNR : snr;
+
+ /* lower limit is -25 dB */
+ snr = (snr < MIN_SNR) ? MIN_SNR : snr;
+ snr = snr << 1;
+
+ sfbMinSnrLdData[sfb] = CalcLdData(snr);
+ }
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, INT samplerate,
+ INT bandwidth, INT blocktype,
+ INT granuleLength, INT useIS,
+ INT useMS,
+ PSY_CONFIGURATION *psyConf,
+ FB_TYPE filterbank) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ INT sfb;
+ FIXP_DBL sfbBarcVal[MAX_SFB];
+ const INT frameLengthLong = granuleLength;
+ const INT frameLengthShort = granuleLength / TRANS_FAC;
+ INT downscaleFactor = 1;
+
+ switch (granuleLength) {
+ case 256:
+ case 240:
+ downscaleFactor = 2;
+ break;
+ case 128:
+ case 120:
+ downscaleFactor = 4;
+ break;
+ default:
+ downscaleFactor = 1;
+ break;
+ }
+
+ FDKmemclear(psyConf, sizeof(PSY_CONFIGURATION));
+ psyConf->granuleLength = granuleLength;
+ psyConf->filterbank = filterbank;
+
+ psyConf->allowIS = (useIS) && ((bitrate / bandwidth) < 5);
+ psyConf->allowMS = useMS;
+
+ /* init sfb table */
+ ErrorStatus = FDKaacEnc_initSfbTable(samplerate * downscaleFactor, blocktype,
+ granuleLength * downscaleFactor,
+ psyConf->sfbOffset, &psyConf->sfbCnt);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ /* calculate barc values for each pb */
+ FDKaacEnc_initBarcValues(psyConf->sfbCnt, psyConf->sfbOffset,
+ psyConf->sfbOffset[psyConf->sfbCnt], samplerate,
+ sfbBarcVal);
+
+ FDKaacEnc_InitMinPCMResolution(psyConf->sfbCnt, psyConf->sfbOffset,
+ psyConf->sfbPcmQuantThreshold);
+
+ /* calculate spreading function */
+ FDKaacEnc_initSpreading(psyConf->sfbCnt, sfbBarcVal,
+ psyConf->sfbMaskLowFactor, psyConf->sfbMaskHighFactor,
+ psyConf->sfbMaskLowFactorSprEn,
+ psyConf->sfbMaskHighFactorSprEn, bitrate, blocktype);
+
+ /* init ratio */
+
+ psyConf->maxAllowedIncreaseFactor = 2; /* integer */
+ psyConf->minRemainingThresholdFactor = (FIXP_SGL)0x0148;
+ /* FL2FXCONST_SGL(0.01f); */ /* fract */
+
+ psyConf->clipEnergy =
+ (FIXP_DBL)0x773593ff; /* FL2FXCONST_DBL(1.0e9*NORM_PCM_ENERGY); */
+
+ if (blocktype != SHORT_WINDOW) {
+ psyConf->lowpassLine =
+ (INT)((2 * bandwidth * frameLengthLong) / samplerate);
+ psyConf->lowpassLineLFE = LFE_LOWPASS_LINE;
+ } else {
+ psyConf->lowpassLine =
+ (INT)((2 * bandwidth * frameLengthShort) / samplerate);
+ psyConf->lowpassLineLFE = 0; /* LFE only in lonf blocks */
+ /* psyConf->clipEnergy /= (TRANS_FAC * TRANS_FAC); */
+ psyConf->clipEnergy >>= 6;
+ }
+
+ for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
+ if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine) break;
+ }
+ psyConf->sfbActive = fMax(sfb, 1);
+
+ for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
+ if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE) break;
+ }
+ psyConf->sfbActiveLFE = sfb;
+ psyConf->sfbActive = fMax(psyConf->sfbActive, psyConf->sfbActiveLFE);
+
+ /* calculate minSnr */
+ FDKaacEnc_initMinSnr(bitrate, samplerate * downscaleFactor,
+ psyConf->sfbOffset[psyConf->sfbCnt], psyConf->sfbOffset,
+ psyConf->sfbActive, blocktype, psyConf->sfbMinSnrLdData);
+
+ return AAC_ENC_OK;
+}
diff --git a/fdk-aac/libAACenc/src/psy_configuration.h b/fdk-aac/libAACenc/src/psy_configuration.h
new file mode 100644
index 0000000..52b2887
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_configuration.h
@@ -0,0 +1,171 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Psychoaccoustic configuration
+
+*******************************************************************************/
+
+#ifndef PSY_CONFIGURATION_H
+#define PSY_CONFIGURATION_H
+
+#include "aacenc.h"
+#include "common_fix.h"
+
+#include "psy_const.h"
+#include "aacenc_tns.h"
+#include "aacenc_pns.h"
+
+#define THR_SHIFTBITS 4
+#define PCM_QUANT_THR_SCALE 16
+#define BITS_PER_LINE_SHIFT 3
+
+#define C_RATIO \
+ (FIXP_DBL)0x02940a10 /* FL2FXCONST_DBL(0.001258925f) << THR_SHIFTBITS; */ /* pow(10.0f, -(29.0f/10.0f)) */
+
+typedef struct {
+ INT sfbCnt; /* number of existing sf bands */
+ INT sfbActive; /* number of sf bands containing energy after lowpass */
+ INT sfbActiveLFE;
+ INT sfbOffset[MAX_SFB + 1];
+
+ INT filterbank; /* LC, LD or ELD */
+
+ FIXP_DBL sfbPcmQuantThreshold[MAX_SFB];
+
+ INT maxAllowedIncreaseFactor; /* preecho control */
+ FIXP_SGL minRemainingThresholdFactor;
+
+ INT lowpassLine;
+ INT lowpassLineLFE;
+ FIXP_DBL clipEnergy; /* for level dependend tmn */
+
+ FIXP_DBL sfbMaskLowFactor[MAX_SFB];
+ FIXP_DBL sfbMaskHighFactor[MAX_SFB];
+
+ FIXP_DBL sfbMaskLowFactorSprEn[MAX_SFB];
+ FIXP_DBL sfbMaskHighFactorSprEn[MAX_SFB];
+
+ FIXP_DBL sfbMinSnrLdData[MAX_SFB]; /* minimum snr (formerly known as bmax) */
+
+ TNS_CONFIG tnsConf;
+ PNS_CONFIG pnsConf;
+
+ INT granuleLength;
+ INT allowIS;
+ INT allowMS;
+} PSY_CONFIGURATION;
+
+typedef struct {
+ UCHAR sfbCnt; /* Number of scalefactor bands */
+ UCHAR sfbWidth[MAX_SFB_LONG]; /* Width of scalefactor bands for long blocks */
+} SFB_PARAM_LONG;
+
+typedef struct {
+ UCHAR sfbCnt; /* Number of scalefactor bands */
+ UCHAR
+ sfbWidth[MAX_SFB_SHORT]; /* Width of scalefactor bands for short blocks */
+} SFB_PARAM_SHORT;
+
+AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, INT samplerate,
+ INT bandwidth, INT blocktype,
+ INT granuleLength, INT useIS,
+ INT useMS,
+ PSY_CONFIGURATION *psyConf,
+ FB_TYPE filterbank);
+
+#endif /* PSY_CONFIGURATION_H */
diff --git a/fdk-aac/libAACenc/src/psy_const.h b/fdk-aac/libAACenc/src/psy_const.h
new file mode 100644
index 0000000..c3f3f64
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_const.h
@@ -0,0 +1,169 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Global psychoaccoustic constants
+
+*******************************************************************************/
+
+#ifndef PSY_CONST_H
+#define PSY_CONST_H
+
+#define TRUE 1
+#define FALSE 0
+
+#define TRANS_FAC 8 /* encoder short long ratio */
+
+#define FRAME_LEN_LONG_960 (960)
+#define FRAME_MAXLEN_SHORT ((1024) / TRANS_FAC)
+#define FRAME_LEN_SHORT_128 ((1024) / TRANS_FAC)
+#define FRAME_LEN_SHORT_120 (FRAME_LEN_LONG_960 / TRANS_FAC)
+
+/* Filterbank type*/
+enum FB_TYPE { FB_LC = 0, FB_LD = 1, FB_ELD = 2 };
+
+/* Block types */
+#define N_BLOCKTYPES 6
+enum {
+ LONG_WINDOW = 0,
+ START_WINDOW,
+ SHORT_WINDOW,
+ STOP_WINDOW,
+ _LOWOV_WINDOW, /* Do not use this block type out side of block_switch.cpp */
+ WRONG_WINDOW
+};
+
+/* Window shapes */
+enum {
+ SINE_WINDOW = 0,
+ KBD_WINDOW = 1,
+ LOL_WINDOW = 2 /* Low OverLap window shape for AAC-LD */
+};
+
+/*
+ MS stuff
+*/
+enum { SI_MS_MASK_NONE = 0, SI_MS_MASK_SOME = 1, SI_MS_MASK_ALL = 2 };
+
+#define MAX_NO_OF_GROUPS 4
+#define MAX_SFB_LONG \
+ 51 /* 51 for a memory optimized implementation, maybe 64 for convenient \
+ debugging */
+#define MAX_SFB_SHORT \
+ 15 /* 15 for a memory optimized implementation, maybe 16 for convenient \
+ debugging */
+
+#define MAX_SFB \
+ (MAX_SFB_SHORT > MAX_SFB_LONG ? MAX_SFB_SHORT : MAX_SFB_LONG) /* = 51 */
+#define MAX_GROUPED_SFB \
+ (MAX_NO_OF_GROUPS * MAX_SFB_SHORT > MAX_SFB_LONG \
+ ? MAX_NO_OF_GROUPS * MAX_SFB_SHORT \
+ : MAX_SFB_LONG) /* = 60 */
+
+#define MAX_INPUT_BUFFER_SIZE (2 * (1024)) /* 2048 */
+
+#define PCM_LEVEL 1.0f
+#define NORM_PCM (PCM_LEVEL / 32768.0f)
+#define NORM_PCM_ENERGY (NORM_PCM * NORM_PCM)
+#define LOG_NORM_PCM -15
+
+#define TNS_PREDGAIN_SCALE (1000)
+
+#define LFE_LOWPASS_LINE 12
+#define LFE_LOWPASS_LINE_MIN 4
+
+#endif /* PSY_CONST_H */
diff --git a/fdk-aac/libAACenc/src/psy_data.h b/fdk-aac/libAACenc/src/psy_data.h
new file mode 100644
index 0000000..fc04734
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_data.h
@@ -0,0 +1,169 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Psychoaccoustic data
+
+*******************************************************************************/
+
+#ifndef PSY_DATA_H
+#define PSY_DATA_H
+
+#include "block_switch.h"
+#include "mdct.h"
+
+/* Be careful with MAX_SFB_LONG as length of the .Long arrays.
+ * sfbEnergy.Long and sfbEnergyMS.Long and sfbThreshold.Long are used as a
+ * temporary storage for the regrouped short energies and thresholds between
+ * FDKaacEnc_groupShortData() and BuildInterface() in FDKaacEnc_psyMain(). The
+ * space required for this is MAX_GROUPED_SFB ( = MAX_NO_OF_GROUPS*MAX_SFB_SHORT
+ * ). However, this is not important if unions are used (which is not possible
+ * with pfloat). */
+
+typedef shouldBeUnion {
+ FIXP_DBL Long[MAX_GROUPED_SFB];
+ FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT];
+}
+SFB_THRESHOLD;
+
+typedef shouldBeUnion {
+ FIXP_DBL Long[MAX_GROUPED_SFB];
+ FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT];
+}
+SFB_ENERGY;
+
+typedef shouldBeUnion {
+ FIXP_DBL Long[MAX_GROUPED_SFB];
+ FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT];
+}
+SFB_LD_ENERGY;
+
+typedef shouldBeUnion {
+ INT Long[MAX_GROUPED_SFB];
+ INT Short[TRANS_FAC][MAX_SFB_SHORT];
+}
+SFB_MAX_SCALE;
+
+typedef struct {
+ INT_PCM* psyInputBuffer;
+ FIXP_DBL overlapAddBuffer[3 * 512 / 2];
+
+ mdct_t mdctPers; /* MDCT persistent data */
+ BLOCK_SWITCHING_CONTROL blockSwitchingControl; /* block switching */
+ FIXP_DBL sfbThresholdnm1[MAX_SFB]; /* FDKaacEnc_PreEchoControl */
+ INT mdctScalenm1; /* scale of last block's mdct (FDKaacEnc_PreEchoControl) */
+ INT calcPreEcho;
+ INT isLFE;
+} PSY_STATIC;
+
+typedef struct {
+ FIXP_DBL* mdctSpectrum;
+ SFB_THRESHOLD sfbThreshold; /* adapt */
+ SFB_ENERGY sfbEnergy; /* sfb energies */
+ SFB_LD_ENERGY sfbEnergyLdData; /* sfb energies in ldData format */
+ SFB_MAX_SCALE sfbMaxScaleSpec;
+ SFB_ENERGY sfbEnergyMS; /* mid/side sfb energies */
+ FIXP_DBL sfbEnergyMSLdData[MAX_GROUPED_SFB]; /* mid/side sfb energies in
+ ldData format */
+ SFB_ENERGY sfbSpreadEnergy;
+ INT mdctScale; /* exponent of data in mdctSpectrum */
+ INT groupedSfbOffset[MAX_GROUPED_SFB + 1];
+ INT sfbActive;
+ INT lowpassLine;
+} PSY_DATA;
+
+#endif /* PSY_DATA_H */
diff --git a/fdk-aac/libAACenc/src/psy_main.cpp b/fdk-aac/libAACenc/src/psy_main.cpp
new file mode 100644
index 0000000..f6345e4
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_main.cpp
@@ -0,0 +1,1348 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Psychoaccoustic major function block
+
+*******************************************************************************/
+
+#include "psy_const.h"
+
+#include "block_switch.h"
+#include "transform.h"
+#include "spreading.h"
+#include "pre_echo_control.h"
+#include "band_nrg.h"
+#include "psy_configuration.h"
+#include "psy_data.h"
+#include "ms_stereo.h"
+#include "interface.h"
+#include "psy_main.h"
+#include "grp_data.h"
+#include "tns_func.h"
+#include "pns_func.h"
+#include "tonality.h"
+#include "aacEnc_ram.h"
+#include "intensity.h"
+
+/* blending to reduce gibbs artifacts */
+#define FADE_OUT_LEN 6
+static const FIXP_DBL fadeOutFactor[FADE_OUT_LEN] = {
+ 1840644096, 1533870080, 1227096064, 920322048, 613548032, 306774016};
+
+/* forward definitions */
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_PsyNew
+ description: allocates memory for psychoacoustic
+ returns: an error code
+ input: pointer to a psych handle
+
+*****************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, const INT nElements,
+ const INT nChannels, UCHAR *dynamic_RAM) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ PSY_INTERNAL *hPsy;
+ INT i;
+
+ hPsy = GetRam_aacEnc_PsyInternal();
+ *phpsy = hPsy;
+ if (hPsy == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+
+ for (i = 0; i < nElements; i++) {
+ /* PSY_ELEMENT */
+ hPsy->psyElement[i] = GetRam_aacEnc_PsyElement(i);
+ if (hPsy->psyElement[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ }
+
+ for (i = 0; i < nChannels; i++) {
+ /* PSY_STATIC */
+ hPsy->pStaticChannels[i] = GetRam_aacEnc_PsyStatic(i);
+ if (hPsy->pStaticChannels[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ /* AUDIO INPUT BUFFER */
+ hPsy->pStaticChannels[i]->psyInputBuffer = GetRam_aacEnc_PsyInputBuffer(i);
+ if (hPsy->pStaticChannels[i]->psyInputBuffer == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ }
+
+ /* reusable psych memory */
+ hPsy->psyDynamic = GetRam_aacEnc_PsyDynamic(0, dynamic_RAM);
+
+ return AAC_ENC_OK;
+
+bail:
+ FDKaacEnc_PsyClose(phpsy, NULL);
+
+ return ErrorStatus;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_PsyOutNew
+ description: allocates memory for psyOut struc
+ returns: an error code
+ input: pointer to a psych handle
+
+*****************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, const INT nElements,
+ const INT nChannels, const INT nSubFrames,
+ UCHAR *dynamic_RAM) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ int n, i;
+ int elInc = 0, chInc = 0;
+
+ for (n = 0; n < nSubFrames; n++) {
+ phpsyOut[n] = GetRam_aacEnc_PsyOut(n);
+
+ if (phpsyOut[n] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+
+ for (i = 0; i < nChannels; i++) {
+ phpsyOut[n]->pPsyOutChannels[i] = GetRam_aacEnc_PsyOutChannel(chInc++);
+ if (NULL == phpsyOut[n]->pPsyOutChannels[i]) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ }
+
+ for (i = 0; i < nElements; i++) {
+ phpsyOut[n]->psyOutElement[i] = GetRam_aacEnc_PsyOutElements(elInc++);
+ if (phpsyOut[n]->psyOutElement[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto bail;
+ }
+ }
+ } /* nSubFrames */
+
+ return AAC_ENC_OK;
+
+bail:
+ FDKaacEnc_PsyClose(NULL, phpsyOut);
+ return ErrorStatus;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_psyInitStates(PSY_INTERNAL *hPsy,
+ PSY_STATIC *psyStatic,
+ AUDIO_OBJECT_TYPE audioObjectType) {
+ /* init input buffer */
+ FDKmemclear(psyStatic->psyInputBuffer,
+ MAX_INPUT_BUFFER_SIZE * sizeof(INT_PCM));
+
+ FDKaacEnc_InitBlockSwitching(&psyStatic->blockSwitchingControl,
+ isLowDelay(audioObjectType));
+
+ return AAC_ENC_OK;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, PSY_OUT **phpsyOut,
+ const INT nSubFrames,
+ const INT nMaxChannels,
+ const AUDIO_OBJECT_TYPE audioObjectType,
+ CHANNEL_MAPPING *cm) {
+ AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
+ int i, ch, n, chInc = 0, resetChannels = 3;
+
+ if ((nMaxChannels > 2) && (cm->nChannels == 2)) {
+ chInc = 1;
+ FDKaacEnc_psyInitStates(hPsy, hPsy->pStaticChannels[0], audioObjectType);
+ }
+
+ if ((nMaxChannels == 2)) {
+ resetChannels = 0;
+ }
+
+ for (i = 0; i < cm->nElements; i++) {
+ for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
+ hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[chInc];
+ if (cm->elInfo[i].elType != ID_LFE) {
+ if (chInc >= resetChannels) {
+ FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch],
+ audioObjectType);
+ }
+ mdct_init(&(hPsy->psyElement[i]->psyStatic[ch]->mdctPers), NULL, 0);
+ hPsy->psyElement[i]->psyStatic[ch]->isLFE = 0;
+ } else {
+ hPsy->psyElement[i]->psyStatic[ch]->isLFE = 1;
+ }
+ chInc++;
+ }
+ }
+
+ for (n = 0; n < nSubFrames; n++) {
+ chInc = 0;
+ for (i = 0; i < cm->nElements; i++) {
+ for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
+ phpsyOut[n]->psyOutElement[i]->psyOutChannel[ch] =
+ phpsyOut[n]->pPsyOutChannels[chInc++];
+ }
+ }
+ }
+
+ return ErrorStatus;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_psyMainInit
+ description: initializes psychoacoustic
+ returns: an error code
+
+*****************************************************************************/
+
+AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(
+ PSY_INTERNAL *hPsy, AUDIO_OBJECT_TYPE audioObjectType, CHANNEL_MAPPING *cm,
+ INT sampleRate, INT granuleLength, INT bitRate, INT tnsMask, INT bandwidth,
+ INT usePns, INT useIS, INT useMS, UINT syntaxFlags, ULONG initFlags) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ int i, ch;
+ int channelsEff = cm->nChannelsEff;
+ int tnsChannels = 0;
+ FB_TYPE filterBank;
+
+ switch (FDKaacEnc_GetMonoStereoMode(cm->encMode)) {
+ /* ... and map to tnsChannels */
+ case EL_MODE_MONO:
+ tnsChannels = 1;
+ break;
+ case EL_MODE_STEREO:
+ tnsChannels = 2;
+ break;
+ default:
+ tnsChannels = 0;
+ }
+
+ switch (audioObjectType) {
+ default:
+ filterBank = FB_LC;
+ break;
+ case AOT_ER_AAC_LD:
+ filterBank = FB_LD;
+ break;
+ case AOT_ER_AAC_ELD:
+ filterBank = FB_ELD;
+ break;
+ }
+
+ hPsy->granuleLength = granuleLength;
+
+ ErrorStatus = FDKaacEnc_InitPsyConfiguration(
+ bitRate / channelsEff, sampleRate, bandwidth, LONG_WINDOW,
+ hPsy->granuleLength, useIS, useMS, &(hPsy->psyConf[0]), filterBank);
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ ErrorStatus = FDKaacEnc_InitTnsConfiguration(
+ (bitRate * tnsChannels) / channelsEff, sampleRate, tnsChannels,
+ LONG_WINDOW, hPsy->granuleLength, isLowDelay(audioObjectType),
+ (syntaxFlags & AC_SBR_PRESENT) ? 1 : 0, &(hPsy->psyConf[0].tnsConf),
+ &hPsy->psyConf[0], (INT)(tnsMask & 2), (INT)(tnsMask & 8));
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ if (granuleLength > 512) {
+ ErrorStatus = FDKaacEnc_InitPsyConfiguration(
+ bitRate / channelsEff, sampleRate, bandwidth, SHORT_WINDOW,
+ hPsy->granuleLength, useIS, useMS, &hPsy->psyConf[1], filterBank);
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ ErrorStatus = FDKaacEnc_InitTnsConfiguration(
+ (bitRate * tnsChannels) / channelsEff, sampleRate, tnsChannels,
+ SHORT_WINDOW, hPsy->granuleLength, isLowDelay(audioObjectType),
+ (syntaxFlags & AC_SBR_PRESENT) ? 1 : 0, &hPsy->psyConf[1].tnsConf,
+ &hPsy->psyConf[1], (INT)(tnsMask & 1), (INT)(tnsMask & 4));
+
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+ }
+
+ for (i = 0; i < cm->nElements; i++) {
+ for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
+ if (initFlags) {
+ /* reset states */
+ FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch],
+ audioObjectType);
+ }
+
+ FDKaacEnc_InitPreEchoControl(
+ hPsy->psyElement[i]->psyStatic[ch]->sfbThresholdnm1,
+ &hPsy->psyElement[i]->psyStatic[ch]->calcPreEcho,
+ hPsy->psyConf[0].sfbCnt, hPsy->psyConf[0].sfbPcmQuantThreshold,
+ &hPsy->psyElement[i]->psyStatic[ch]->mdctScalenm1);
+ }
+ }
+
+ ErrorStatus = FDKaacEnc_InitPnsConfiguration(
+ &hPsy->psyConf[0].pnsConf, bitRate / channelsEff, sampleRate, usePns,
+ hPsy->psyConf[0].sfbCnt, hPsy->psyConf[0].sfbOffset,
+ cm->elInfo[0].nChannelsInEl, (hPsy->psyConf[0].filterbank == FB_LC));
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+
+ if (granuleLength > 512) {
+ ErrorStatus = FDKaacEnc_InitPnsConfiguration(
+ &hPsy->psyConf[1].pnsConf, bitRate / channelsEff, sampleRate, usePns,
+ hPsy->psyConf[1].sfbCnt, hPsy->psyConf[1].sfbOffset,
+ cm->elInfo[1].nChannelsInEl, (hPsy->psyConf[1].filterbank == FB_LC));
+ if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
+ }
+
+ return ErrorStatus;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_psyMain
+ description: psychoacoustic
+ returns: an error code
+
+ This function assumes that enough input data is in the modulo buffer.
+
+*****************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, PSY_ELEMENT *psyElement,
+ PSY_DYNAMIC *psyDynamic,
+ PSY_CONFIGURATION *psyConf,
+ PSY_OUT_ELEMENT *RESTRICT psyOutElement,
+ INT_PCM *pInput, const UINT inputBufSize,
+ INT *chIdx, INT totalChannels) {
+ const INT commonWindow = 1;
+ INT maxSfbPerGroup[(2)];
+ INT mdctSpectrum_e;
+ INT ch; /* counts through channels */
+ INT w; /* counts through windows */
+ INT sfb; /* counts through scalefactor bands */
+ INT line; /* counts through lines */
+
+ PSY_CONFIGURATION *RESTRICT hPsyConfLong = &psyConf[0];
+ PSY_CONFIGURATION *RESTRICT hPsyConfShort = &psyConf[1];
+ PSY_OUT_CHANNEL **RESTRICT psyOutChannel = psyOutElement->psyOutChannel;
+ FIXP_SGL sfbTonality[(2)][MAX_SFB_LONG];
+
+ PSY_STATIC **RESTRICT psyStatic = psyElement->psyStatic;
+
+ PSY_DATA *RESTRICT psyData[(2)];
+ TNS_DATA *RESTRICT tnsData[(2)];
+ PNS_DATA *RESTRICT pnsData[(2)];
+
+ INT zeroSpec = TRUE; /* means all spectral lines are zero */
+
+ INT blockSwitchingOffset;
+
+ PSY_CONFIGURATION *RESTRICT hThisPsyConf[(2)];
+ INT windowLength[(2)];
+ INT nWindows[(2)];
+ INT wOffset;
+
+ INT maxSfb[(2)];
+ INT *pSfbMaxScaleSpec[(2)];
+ FIXP_DBL *pSfbEnergy[(2)];
+ FIXP_DBL *pSfbSpreadEnergy[(2)];
+ FIXP_DBL *pSfbEnergyLdData[(2)];
+ FIXP_DBL *pSfbEnergyMS[(2)];
+ FIXP_DBL *pSfbThreshold[(2)];
+
+ INT isShortWindow[(2)];
+
+ /* number of incoming time samples to be processed */
+ const INT nTimeSamples = psyConf->granuleLength;
+
+ switch (hPsyConfLong->filterbank) {
+ case FB_LC:
+ blockSwitchingOffset =
+ nTimeSamples + (9 * nTimeSamples / (2 * TRANS_FAC));
+ break;
+ case FB_LD:
+ case FB_ELD:
+ blockSwitchingOffset = nTimeSamples;
+ break;
+ default:
+ return AAC_ENC_UNSUPPORTED_FILTERBANK;
+ }
+
+ for (ch = 0; ch < channels; ch++) {
+ psyData[ch] = &psyDynamic->psyData[ch];
+ tnsData[ch] = &psyDynamic->tnsData[ch];
+ pnsData[ch] = &psyDynamic->pnsData[ch];
+
+ psyData[ch]->mdctSpectrum = psyOutChannel[ch]->mdctSpectrum;
+ }
+
+ /* block switching */
+ if (hPsyConfLong->filterbank != FB_ELD) {
+ int err;
+
+ for (ch = 0; ch < channels; ch++) {
+ C_ALLOC_SCRATCH_START(pTimeSignal, INT_PCM, (1024))
+
+ /* copy input data and use for block switching */
+ FDKmemcpy(pTimeSignal, pInput + chIdx[ch] * inputBufSize,
+ nTimeSamples * sizeof(INT_PCM));
+
+ FDKaacEnc_BlockSwitching(&psyStatic[ch]->blockSwitchingControl,
+ nTimeSamples, psyStatic[ch]->isLFE, pTimeSignal);
+
+ /* fill up internal input buffer, to 2xframelength samples */
+ FDKmemcpy(psyStatic[ch]->psyInputBuffer + blockSwitchingOffset,
+ pTimeSignal,
+ (2 * nTimeSamples - blockSwitchingOffset) * sizeof(INT_PCM));
+
+ C_ALLOC_SCRATCH_END(pTimeSignal, INT_PCM, (1024))
+ }
+
+ /* synch left and right block type */
+ err = FDKaacEnc_SyncBlockSwitching(
+ &psyStatic[0]->blockSwitchingControl,
+ (channels > 1) ? &psyStatic[1]->blockSwitchingControl : NULL, channels,
+ commonWindow);
+
+ if (err) {
+ return AAC_ENC_UNSUPPORTED_AOT; /* mixed up LC and LD */
+ }
+
+ } else {
+ for (ch = 0; ch < channels; ch++) {
+ /* copy input data and use for block switching */
+ FDKmemcpy(psyStatic[ch]->psyInputBuffer + blockSwitchingOffset,
+ pInput + chIdx[ch] * inputBufSize,
+ nTimeSamples * sizeof(INT_PCM));
+ }
+ }
+
+ for (ch = 0; ch < channels; ch++)
+ isShortWindow[ch] =
+ (psyStatic[ch]->blockSwitchingControl.lastWindowSequence ==
+ SHORT_WINDOW);
+
+ /* set parameters according to window length */
+ for (ch = 0; ch < channels; ch++) {
+ if (isShortWindow[ch]) {
+ hThisPsyConf[ch] = hPsyConfShort;
+ windowLength[ch] = psyConf->granuleLength / TRANS_FAC;
+ nWindows[ch] = TRANS_FAC;
+ maxSfb[ch] = MAX_SFB_SHORT;
+
+ pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Short[0];
+ pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Short[0];
+ pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Short[0];
+ pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Short[0];
+ pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Short[0];
+ pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Short[0];
+
+ } else {
+ hThisPsyConf[ch] = hPsyConfLong;
+ windowLength[ch] = psyConf->granuleLength;
+ nWindows[ch] = 1;
+ maxSfb[ch] = MAX_GROUPED_SFB;
+
+ pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Long;
+ pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Long;
+ pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Long;
+ pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Long;
+ pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Long;
+ pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Long;
+ }
+ }
+
+ /* Transform and get mdctScaling for all channels and windows. */
+ for (ch = 0; ch < channels; ch++) {
+ /* update number of active bands */
+ if (psyStatic[ch]->isLFE) {
+ psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActiveLFE;
+ psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLineLFE;
+ } else {
+ psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActive;
+ psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLine;
+ }
+
+ if (hThisPsyConf[ch]->filterbank == FB_ELD) {
+ if (FDKaacEnc_Transform_Real_Eld(
+ psyStatic[ch]->psyInputBuffer, psyData[ch]->mdctSpectrum,
+ psyStatic[ch]->blockSwitchingControl.lastWindowSequence,
+ psyStatic[ch]->blockSwitchingControl.windowShape,
+ &psyStatic[ch]->blockSwitchingControl.lastWindowShape,
+ nTimeSamples, &mdctSpectrum_e, hThisPsyConf[ch]->filterbank,
+ psyStatic[ch]->overlapAddBuffer) != 0) {
+ return AAC_ENC_UNSUPPORTED_FILTERBANK;
+ }
+ } else {
+ if (FDKaacEnc_Transform_Real(
+ psyStatic[ch]->psyInputBuffer, psyData[ch]->mdctSpectrum,
+ psyStatic[ch]->blockSwitchingControl.lastWindowSequence,
+ psyStatic[ch]->blockSwitchingControl.windowShape,
+ &psyStatic[ch]->blockSwitchingControl.lastWindowShape,
+ &psyStatic[ch]->mdctPers, nTimeSamples, &mdctSpectrum_e,
+ hThisPsyConf[ch]->filterbank) != 0) {
+ return AAC_ENC_UNSUPPORTED_FILTERBANK;
+ }
+ }
+
+ for (w = 0; w < nWindows[ch]; w++) {
+ wOffset = w * windowLength[ch];
+
+ /* Low pass / highest sfb */
+ FDKmemclear(
+ &psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine + wOffset],
+ (windowLength[ch] - psyData[ch]->lowpassLine) * sizeof(FIXP_DBL));
+
+ if ((hPsyConfLong->filterbank != FB_LC) &&
+ (psyData[ch]->lowpassLine >= FADE_OUT_LEN)) {
+ /* Do blending to reduce gibbs artifacts */
+ 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]);
+ }
+ }
+
+ /* Check for zero spectrum. These loops will usually terminate very, very
+ * early. */
+ for (line = 0; (line < psyData[ch]->lowpassLine) && (zeroSpec == TRUE);
+ line++) {
+ if (psyData[ch]->mdctSpectrum[line + wOffset] != (FIXP_DBL)0) {
+ zeroSpec = FALSE;
+ break;
+ }
+ }
+
+ } /* w loop */
+
+ psyData[ch]->mdctScale = mdctSpectrum_e;
+
+ /* rotate internal time samples */
+ FDKmemmove(psyStatic[ch]->psyInputBuffer,
+ psyStatic[ch]->psyInputBuffer + nTimeSamples,
+ nTimeSamples * sizeof(INT_PCM));
+
+ /* ... and get remaining samples from input buffer */
+ FDKmemcpy(psyStatic[ch]->psyInputBuffer + nTimeSamples,
+ pInput + (2 * nTimeSamples - blockSwitchingOffset) +
+ chIdx[ch] * inputBufSize,
+ (blockSwitchingOffset - nTimeSamples) * sizeof(INT_PCM));
+
+ } /* ch */
+
+ /* Do some rescaling to get maximum possible accuracy for energies */
+ if (zeroSpec == FALSE) {
+ /* Calc possible spectrum leftshift for each sfb (1 means: 1 bit left shift
+ * is possible without overflow) */
+ INT minSpecShift = MAX_SHIFT_DBL;
+ INT nrgShift = MAX_SHIFT_DBL;
+ INT finalShift = MAX_SHIFT_DBL;
+ FIXP_DBL currNrg = 0;
+ FIXP_DBL maxNrg = 0;
+
+ for (ch = 0; ch < channels; ch++) {
+ for (w = 0; w < nWindows[ch]; w++) {
+ wOffset = w * windowLength[ch];
+ FDKaacEnc_CalcSfbMaxScaleSpec(
+ psyData[ch]->mdctSpectrum + wOffset, hThisPsyConf[ch]->sfbOffset,
+ pSfbMaxScaleSpec[ch] + w * maxSfb[ch], psyData[ch]->sfbActive);
+
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++)
+ minSpecShift = fixMin(minSpecShift,
+ (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb]);
+ }
+ }
+
+ /* Calc possible energy leftshift for each sfb (1 means: 1 bit left shift is
+ * possible without overflow) */
+ for (ch = 0; ch < channels; ch++) {
+ for (w = 0; w < nWindows[ch]; w++) {
+ wOffset = w * windowLength[ch];
+ currNrg = FDKaacEnc_CheckBandEnergyOptim(
+ psyData[ch]->mdctSpectrum + wOffset,
+ pSfbMaxScaleSpec[ch] + w * maxSfb[ch], hThisPsyConf[ch]->sfbOffset,
+ psyData[ch]->sfbActive, pSfbEnergy[ch] + w * maxSfb[ch],
+ pSfbEnergyLdData[ch] + w * maxSfb[ch], minSpecShift - 4);
+
+ maxNrg = fixMax(maxNrg, currNrg);
+ }
+ }
+
+ if (maxNrg != (FIXP_DBL)0) {
+ nrgShift = (CountLeadingBits(maxNrg) >> 1) + (minSpecShift - 4);
+ }
+
+ /* 2check: Hasn't this decision to be made for both channels? */
+ /* For short windows 1 additional bit headroom is necessary to prevent
+ * overflows when summing up energies in FDKaacEnc_groupShortData() */
+ if (isShortWindow[0]) nrgShift--;
+
+ /* both spectrum and energies mustn't overflow */
+ finalShift = fixMin(minSpecShift, nrgShift);
+
+ /* do not shift more than 3 bits more to the left than signal without
+ * blockfloating point would be to avoid overflow of scaled PCM quantization
+ * thresholds */
+ if (finalShift > psyData[0]->mdctScale + 3)
+ finalShift = psyData[0]->mdctScale + 3;
+
+ FDK_ASSERT(finalShift >= 0); /* right shift is not allowed */
+
+ /* correct sfbEnergy and sfbEnergyLdData with new finalShift */
+ FIXP_DBL ldShift = finalShift * FL2FXCONST_DBL(2.0 / 64);
+ for (ch = 0; ch < channels; ch++) {
+ INT maxSfb_ch = maxSfb[ch];
+ INT w_maxSfb_ch = 0;
+ for (w = 0; w < nWindows[ch]; w++) {
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ INT scale = fixMax(0, (pSfbMaxScaleSpec[ch] + w_maxSfb_ch)[sfb] - 4);
+ scale = fixMin((scale - finalShift) << 1, DFRACT_BITS - 1);
+ if (scale >= 0)
+ (pSfbEnergy[ch] + w_maxSfb_ch)[sfb] >>= (scale);
+ else
+ (pSfbEnergy[ch] + w_maxSfb_ch)[sfb] <<= (-scale);
+ (pSfbThreshold[ch] + w_maxSfb_ch)[sfb] =
+ fMult((pSfbEnergy[ch] + w_maxSfb_ch)[sfb], C_RATIO);
+ (pSfbEnergyLdData[ch] + w_maxSfb_ch)[sfb] += ldShift;
+ }
+ w_maxSfb_ch += maxSfb_ch;
+ }
+ }
+
+ if (finalShift != 0) {
+ for (ch = 0; ch < channels; ch++) {
+ INT wLen = windowLength[ch];
+ INT lowpassLine = psyData[ch]->lowpassLine;
+ wOffset = 0;
+ FIXP_DBL *mdctSpectrum = &psyData[ch]->mdctSpectrum[0];
+ for (w = 0; w < nWindows[ch]; w++) {
+ FIXP_DBL *spectrum = &mdctSpectrum[wOffset];
+ for (line = 0; line < lowpassLine; line++) {
+ spectrum[line] <<= finalShift;
+ }
+ wOffset += wLen;
+
+ /* update sfbMaxScaleSpec */
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++)
+ (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb] -= finalShift;
+ }
+ /* update mdctScale */
+ psyData[ch]->mdctScale -= finalShift;
+ }
+ }
+
+ } else {
+ /* all spectral lines are zero */
+ for (ch = 0; ch < channels; ch++) {
+ psyData[ch]->mdctScale =
+ 0; /* otherwise mdctScale would be for example 7 and PCM quantization
+ * thresholds would be shifted 14 bits to the right causing some of
+ * them to become 0 (which causes problems later) */
+ /* clear sfbMaxScaleSpec */
+ for (w = 0; w < nWindows[ch]; w++) {
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb] = 0;
+ (pSfbEnergy[ch] + w * maxSfb[ch])[sfb] = (FIXP_DBL)0;
+ (pSfbEnergyLdData[ch] + w * maxSfb[ch])[sfb] = FL2FXCONST_DBL(-1.0f);
+ (pSfbThreshold[ch] + w * maxSfb[ch])[sfb] = (FIXP_DBL)0;
+ }
+ }
+ }
+ }
+
+ /* Advance psychoacoustics: Tonality and TNS */
+ if ((channels >= 1) && (psyStatic[0]->isLFE)) {
+ tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] = 0;
+ tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] = 0;
+ } else {
+ for (ch = 0; ch < channels; ch++) {
+ if (!isShortWindow[ch]) {
+ /* tonality */
+ FDKaacEnc_CalculateFullTonality(
+ psyData[ch]->mdctSpectrum, pSfbMaxScaleSpec[ch],
+ pSfbEnergyLdData[ch], sfbTonality[ch], psyData[ch]->sfbActive,
+ hThisPsyConf[ch]->sfbOffset, hThisPsyConf[ch]->pnsConf.usePns);
+ }
+ } /* ch */
+
+ if (hPsyConfLong->tnsConf.tnsActive || hPsyConfShort->tnsConf.tnsActive) {
+ INT tnsActive[TRANS_FAC] = {0};
+ INT nrgScaling[2] = {0, 0};
+ INT tnsSpecShift = 0;
+
+ for (ch = 0; ch < channels; ch++) {
+ for (w = 0; w < nWindows[ch]; w++) {
+ wOffset = w * windowLength[ch];
+ /* TNS */
+ FDKaacEnc_TnsDetect(
+ tnsData[ch], &hThisPsyConf[ch]->tnsConf,
+ &psyOutChannel[ch]->tnsInfo, hThisPsyConf[ch]->sfbCnt,
+ psyData[ch]->mdctSpectrum + wOffset, w,
+ psyStatic[ch]->blockSwitchingControl.lastWindowSequence);
+ }
+ }
+
+ if (channels == 2) {
+ FDKaacEnc_TnsSync(
+ tnsData[1], tnsData[0], &psyOutChannel[1]->tnsInfo,
+ &psyOutChannel[0]->tnsInfo,
+
+ psyStatic[1]->blockSwitchingControl.lastWindowSequence,
+ psyStatic[0]->blockSwitchingControl.lastWindowSequence,
+ &hThisPsyConf[1]->tnsConf);
+ }
+
+ if (channels >= 1) {
+ 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++) {
+ if (isShortWindow[0])
+ tnsActive[w] =
+ tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] ||
+ 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
+ tnsActive[w] =
+ tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] ||
+ 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++) {
+ if (tnsActive[0] && !isShortWindow[ch]) {
+ /* Scale down spectrum if tns is active in one of the two channels
+ * with same lastWindowSequence */
+ /* first part of threshold calculation; it's not necessary to update
+ * sfbMaxScaleSpec */
+ INT shift = 1;
+ for (sfb = 0; sfb < hThisPsyConf[ch]->lowpassLine; sfb++) {
+ psyData[ch]->mdctSpectrum[sfb] =
+ psyData[ch]->mdctSpectrum[sfb] >> shift;
+ }
+
+ /* update thresholds */
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ pSfbThreshold[ch][sfb] >>= (2 * shift);
+ }
+
+ psyData[ch]->mdctScale += shift; /* update mdctScale */
+
+ /* calc sfbEnergies after tnsEncode again ! */
+ }
+ }
+
+ for (ch = 0; ch < channels; ch++) {
+ for (w = 0; w < nWindows[ch]; w++) {
+ wOffset = w * windowLength[ch];
+ FDKaacEnc_TnsEncode(
+ &psyOutChannel[ch]->tnsInfo, tnsData[ch],
+ hThisPsyConf[ch]->sfbCnt, &hThisPsyConf[ch]->tnsConf,
+ hThisPsyConf[ch]->sfbOffset[psyData[ch]->sfbActive],
+ /*hThisPsyConf[ch]->lowpassLine*/ /* filter stops
+ before that
+ line ! */
+ psyData[ch]->mdctSpectrum +
+ wOffset,
+ w, psyStatic[ch]->blockSwitchingControl.lastWindowSequence);
+
+ if (tnsActive[w]) {
+ /* Calc sfb-bandwise mdct-energies for left and right channel again,
+ */
+ /* if tns active in current channel or in one channel with same
+ * lastWindowSequence left and right */
+ FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum + wOffset,
+ hThisPsyConf[ch]->sfbOffset,
+ pSfbMaxScaleSpec[ch] + w * maxSfb[ch],
+ psyData[ch]->sfbActive);
+ }
+ }
+ }
+
+ for (ch = 0; ch < channels; ch++) {
+ for (w = 0; w < nWindows[ch]; w++) {
+ if (tnsActive[w]) {
+ if (isShortWindow[ch]) {
+ FDKaacEnc_CalcBandEnergyOptimShort(
+ psyData[ch]->mdctSpectrum + w * windowLength[ch],
+ pSfbMaxScaleSpec[ch] + w * maxSfb[ch],
+ hThisPsyConf[ch]->sfbOffset, psyData[ch]->sfbActive,
+ pSfbEnergy[ch] + w * maxSfb[ch]);
+ } else {
+ nrgScaling[ch] = /* with tns, energy calculation can overflow; ->
+ scaling */
+ FDKaacEnc_CalcBandEnergyOptimLong(
+ psyData[ch]->mdctSpectrum, pSfbMaxScaleSpec[ch],
+ hThisPsyConf[ch]->sfbOffset, psyData[ch]->sfbActive,
+ pSfbEnergy[ch], pSfbEnergyLdData[ch]);
+ tnsSpecShift =
+ fixMax(tnsSpecShift, nrgScaling[ch]); /* nrgScaling is set
+ only if nrg would
+ have an overflow */
+ }
+ } /* if tnsActive */
+ }
+ } /* end channel loop */
+
+ /* adapt scaling to prevent nrg overflow, only for long blocks */
+ for (ch = 0; ch < channels; ch++) {
+ if ((tnsSpecShift != 0) && !isShortWindow[ch]) {
+ /* scale down spectrum, nrg's and thresholds, if there was an overflow
+ * in sfbNrg calculation after tns */
+ for (line = 0; line < hThisPsyConf[ch]->lowpassLine; line++) {
+ psyData[ch]->mdctSpectrum[line] >>= tnsSpecShift;
+ }
+ INT scale = (tnsSpecShift - nrgScaling[ch]) << 1;
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ pSfbEnergyLdData[ch][sfb] -=
+ scale * FL2FXCONST_DBL(1.0 / LD_DATA_SCALING);
+ pSfbEnergy[ch][sfb] >>= scale;
+ pSfbThreshold[ch][sfb] >>= (tnsSpecShift << 1);
+ }
+ psyData[ch]->mdctScale += tnsSpecShift; /* update mdctScale; not
+ necessary to update
+ sfbMaxScaleSpec */
+ }
+ } /* end channel loop */
+
+ } /* TNS active */
+ else {
+ /* In case of disable TNS, reset its dynamic data. Some of its elements is
+ * required in PNS detection below. */
+ FDKmemclear(psyDynamic->tnsData, sizeof(psyDynamic->tnsData));
+ }
+ } /* !isLFE */
+
+ /* Advance thresholds */
+ for (ch = 0; ch < channels; ch++) {
+ INT headroom;
+
+ FIXP_DBL clipEnergy;
+ INT energyShift = psyData[ch]->mdctScale * 2;
+ INT clipNrgShift = energyShift - THR_SHIFTBITS;
+ if (isShortWindow[ch])
+ headroom = 6;
+ else
+ headroom = 0;
+
+ if (clipNrgShift >= 0)
+ clipEnergy = hThisPsyConf[ch]->clipEnergy >> clipNrgShift;
+ else if (clipNrgShift >= -headroom)
+ clipEnergy = hThisPsyConf[ch]->clipEnergy << -clipNrgShift;
+ else
+ clipEnergy = (FIXP_DBL)MAXVAL_DBL;
+
+ for (w = 0; w < nWindows[ch]; w++) {
+ INT i;
+ /* limit threshold to avoid clipping */
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ *(pSfbThreshold[ch] + w * maxSfb[ch] + i) =
+ fixMin(*(pSfbThreshold[ch] + w * maxSfb[ch] + i), clipEnergy);
+ }
+
+ /* spreading */
+ FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive,
+ hThisPsyConf[ch]->sfbMaskLowFactor,
+ hThisPsyConf[ch]->sfbMaskHighFactor,
+ pSfbThreshold[ch] + w * maxSfb[ch]);
+
+ /* PCM quantization threshold */
+ energyShift += PCM_QUANT_THR_SCALE;
+ if (energyShift >= 0) {
+ energyShift = fixMin(DFRACT_BITS - 1, energyShift);
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ *(pSfbThreshold[ch] + w * maxSfb[ch] + i) = fixMax(
+ *(pSfbThreshold[ch] + w * maxSfb[ch] + i) >> THR_SHIFTBITS,
+ (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] >> energyShift));
+ }
+ } else {
+ energyShift = fixMin(DFRACT_BITS - 1, -energyShift);
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ *(pSfbThreshold[ch] + w * maxSfb[ch] + i) = fixMax(
+ *(pSfbThreshold[ch] + w * maxSfb[ch] + i) >> THR_SHIFTBITS,
+ (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] << energyShift));
+ }
+ }
+
+ if (!psyStatic[ch]->isLFE) {
+ /* preecho control */
+ if (psyStatic[ch]->blockSwitchingControl.lastWindowSequence ==
+ STOP_WINDOW) {
+ /* prevent FDKaacEnc_PreEchoControl from comparing stop
+ thresholds with short thresholds */
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL;
+ }
+
+ psyStatic[ch]->mdctScalenm1 = 0;
+ psyStatic[ch]->calcPreEcho = 0;
+ }
+
+ FDKaacEnc_PreEchoControl(
+ psyStatic[ch]->sfbThresholdnm1, psyStatic[ch]->calcPreEcho,
+ psyData[ch]->sfbActive, hThisPsyConf[ch]->maxAllowedIncreaseFactor,
+ hThisPsyConf[ch]->minRemainingThresholdFactor,
+ pSfbThreshold[ch] + w * maxSfb[ch], psyData[ch]->mdctScale,
+ &psyStatic[ch]->mdctScalenm1);
+
+ psyStatic[ch]->calcPreEcho = 1;
+
+ if (psyStatic[ch]->blockSwitchingControl.lastWindowSequence ==
+ START_WINDOW) {
+ /* prevent FDKaacEnc_PreEchoControl in next frame to compare start
+ thresholds with short thresholds */
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL;
+ }
+
+ psyStatic[ch]->mdctScalenm1 = 0;
+ psyStatic[ch]->calcPreEcho = 0;
+ }
+ }
+
+ /* spread energy to avoid hole detection */
+ FDKmemcpy(pSfbSpreadEnergy[ch] + w * maxSfb[ch],
+ pSfbEnergy[ch] + w * maxSfb[ch],
+ psyData[ch]->sfbActive * sizeof(FIXP_DBL));
+
+ FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive,
+ hThisPsyConf[ch]->sfbMaskLowFactorSprEn,
+ hThisPsyConf[ch]->sfbMaskHighFactorSprEn,
+ pSfbSpreadEnergy[ch] + w * maxSfb[ch]);
+ }
+ }
+
+ /* Calc bandwise energies for mid and side channel. Do it only if 2 channels
+ * exist */
+ if (channels == 2) {
+ for (w = 0; w < nWindows[1]; w++) {
+ wOffset = w * windowLength[1];
+ FDKaacEnc_CalcBandNrgMSOpt(
+ psyData[0]->mdctSpectrum + wOffset,
+ psyData[1]->mdctSpectrum + wOffset,
+ pSfbMaxScaleSpec[0] + w * maxSfb[0],
+ pSfbMaxScaleSpec[1] + w * maxSfb[1], hThisPsyConf[1]->sfbOffset,
+ psyData[0]->sfbActive, pSfbEnergyMS[0] + w * maxSfb[0],
+ pSfbEnergyMS[1] + w * maxSfb[1],
+ (psyStatic[1]->blockSwitchingControl.lastWindowSequence !=
+ SHORT_WINDOW),
+ psyData[0]->sfbEnergyMSLdData, psyData[1]->sfbEnergyMSLdData);
+ }
+ }
+
+ /* group short data (maxSfb[ch] for short blocks is determined here) */
+ for (ch = 0; ch < channels; ch++) {
+ if (isShortWindow[ch]) {
+ int sfbGrp;
+ int noSfb = psyStatic[ch]->blockSwitchingControl.noOfGroups *
+ hPsyConfShort->sfbCnt;
+ /* At this point, energies and thresholds are copied/regrouped from the
+ * ".Short" to the ".Long" arrays */
+ FDKaacEnc_groupShortData(
+ psyData[ch]->mdctSpectrum, &psyData[ch]->sfbThreshold,
+ &psyData[ch]->sfbEnergy, &psyData[ch]->sfbEnergyMS,
+ &psyData[ch]->sfbSpreadEnergy, hPsyConfShort->sfbCnt,
+ psyData[ch]->sfbActive, hPsyConfShort->sfbOffset,
+ hPsyConfShort->sfbMinSnrLdData, psyData[ch]->groupedSfbOffset,
+ &maxSfbPerGroup[ch], psyOutChannel[ch]->sfbMinSnrLdData,
+ psyStatic[ch]->blockSwitchingControl.noOfGroups,
+ psyStatic[ch]->blockSwitchingControl.groupLen,
+ psyConf[1].granuleLength);
+
+ /* calculate ldData arrays (short values are in .Long-arrays after
+ * FDKaacEnc_groupShortData) */
+ for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) {
+ LdDataVector(&psyData[ch]->sfbEnergy.Long[sfbGrp],
+ &psyOutChannel[ch]->sfbEnergyLdData[sfbGrp],
+ psyData[ch]->sfbActive);
+ }
+
+ /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/
+ for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) {
+ LdDataVector(&psyData[ch]->sfbThreshold.Long[sfbGrp],
+ &psyOutChannel[ch]->sfbThresholdLdData[sfbGrp],
+ psyData[ch]->sfbActive);
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb] =
+ fixMax(psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb],
+ FL2FXCONST_DBL(-0.515625f));
+ }
+ }
+
+ if (channels == 2) {
+ for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) {
+ LdDataVector(&psyData[ch]->sfbEnergyMS.Long[sfbGrp],
+ &psyData[ch]->sfbEnergyMSLdData[sfbGrp],
+ psyData[ch]->sfbActive);
+ }
+ }
+
+ FDKmemcpy(psyOutChannel[ch]->sfbOffsets, psyData[ch]->groupedSfbOffset,
+ (MAX_GROUPED_SFB + 1) * sizeof(INT));
+
+ } else {
+ int i;
+ /* maxSfb[ch] for long blocks */
+ for (sfb = psyData[ch]->sfbActive - 1; sfb >= 0; sfb--) {
+ for (line = hPsyConfLong->sfbOffset[sfb + 1] - 1;
+ line >= hPsyConfLong->sfbOffset[sfb]; line--) {
+ if (psyData[ch]->mdctSpectrum[line] != FL2FXCONST_SGL(0.0f)) break;
+ }
+ if (line > hPsyConfLong->sfbOffset[sfb]) break;
+ }
+ maxSfbPerGroup[ch] = sfb + 1;
+ maxSfbPerGroup[ch] =
+ fixMax(fixMin(5, psyData[ch]->sfbActive), maxSfbPerGroup[ch]);
+
+ /* sfbNrgLdData is calculated in FDKaacEnc_advancePsychLong, copy in
+ * psyOut structure */
+ FDKmemcpy(psyOutChannel[ch]->sfbEnergyLdData,
+ psyData[ch]->sfbEnergyLdData.Long,
+ psyData[ch]->sfbActive * sizeof(FIXP_DBL));
+
+ FDKmemcpy(psyOutChannel[ch]->sfbOffsets, hPsyConfLong->sfbOffset,
+ (MAX_GROUPED_SFB + 1) * sizeof(INT));
+
+ /* sfbMinSnrLdData modified in adjust threshold, copy necessary */
+ FDKmemcpy(psyOutChannel[ch]->sfbMinSnrLdData,
+ hPsyConfLong->sfbMinSnrLdData,
+ psyData[ch]->sfbActive * sizeof(FIXP_DBL));
+
+ /* sfbEnergyMSLdData ist already calculated in FDKaacEnc_CalcBandNrgMSOpt;
+ * only in long case */
+
+ /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/
+ LdDataVector(psyData[ch]->sfbThreshold.Long,
+ psyOutChannel[ch]->sfbThresholdLdData,
+ psyData[ch]->sfbActive);
+ for (i = 0; i < psyData[ch]->sfbActive; i++) {
+ psyOutChannel[ch]->sfbThresholdLdData[i] =
+ fixMax(psyOutChannel[ch]->sfbThresholdLdData[i],
+ FL2FXCONST_DBL(-0.515625f));
+ }
+ }
+ }
+
+ /*
+ Intensity parameter intialization.
+ */
+ for (ch = 0; ch < channels; ch++) {
+ FDKmemclear(psyOutChannel[ch]->isBook, MAX_GROUPED_SFB * sizeof(INT));
+ FDKmemclear(psyOutChannel[ch]->isScale, MAX_GROUPED_SFB * sizeof(INT));
+ }
+
+ for (ch = 0; ch < channels; ch++) {
+ INT win = (isShortWindow[ch] ? 1 : 0);
+ if (!psyStatic[ch]->isLFE) {
+ /* PNS Decision */
+ FDKaacEnc_PnsDetect(
+ &(psyConf[0].pnsConf), pnsData[ch],
+ psyStatic[ch]->blockSwitchingControl.lastWindowSequence,
+ psyData[ch]->sfbActive,
+ maxSfbPerGroup[ch], /* count of Sfb which are not zero. */
+ psyOutChannel[ch]->sfbThresholdLdData, psyConf[win].sfbOffset,
+ psyData[ch]->mdctSpectrum, psyData[ch]->sfbMaxScaleSpec.Long,
+ sfbTonality[ch], psyOutChannel[ch]->tnsInfo.order[0][0],
+ tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain[HIFILT],
+ tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT],
+ psyOutChannel[ch]->sfbEnergyLdData, psyOutChannel[ch]->noiseNrg);
+ } /* !isLFE */
+ } /* ch */
+
+ /*
+ stereo Processing
+ */
+ if (channels == 2) {
+ psyOutElement->toolsInfo.msDigest = MS_NONE;
+ psyOutElement->commonWindow = commonWindow;
+ if (psyOutElement->commonWindow)
+ maxSfbPerGroup[0] = maxSfbPerGroup[1] =
+ fixMax(maxSfbPerGroup[0], maxSfbPerGroup[1]);
+ if (psyStatic[0]->blockSwitchingControl.lastWindowSequence !=
+ SHORT_WINDOW) {
+ /* PNS preprocessing depending on ms processing: PNS not in Short Window!
+ */
+ FDKaacEnc_PreProcessPnsChannelPair(
+ psyData[0]->sfbActive, (&psyData[0]->sfbEnergy)->Long,
+ (&psyData[1]->sfbEnergy)->Long, psyOutChannel[0]->sfbEnergyLdData,
+ psyOutChannel[1]->sfbEnergyLdData, psyData[0]->sfbEnergyMS.Long,
+ &(psyConf[0].pnsConf), pnsData[0], pnsData[1]);
+
+ FDKaacEnc_IntensityStereoProcessing(
+ psyData[0]->sfbEnergy.Long, psyData[1]->sfbEnergy.Long,
+ psyData[0]->mdctSpectrum, psyData[1]->mdctSpectrum,
+ psyData[0]->sfbThreshold.Long, psyData[1]->sfbThreshold.Long,
+ psyOutChannel[1]->sfbThresholdLdData,
+ psyData[0]->sfbSpreadEnergy.Long, psyData[1]->sfbSpreadEnergy.Long,
+ psyOutChannel[0]->sfbEnergyLdData, psyOutChannel[1]->sfbEnergyLdData,
+ &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask,
+ psyConf[0].sfbCnt, psyConf[0].sfbCnt, maxSfbPerGroup[0],
+ psyConf[0].sfbOffset,
+ psyConf[0].allowIS && psyOutElement->commonWindow,
+ psyOutChannel[1]->isBook, psyOutChannel[1]->isScale, pnsData);
+
+ FDKaacEnc_MsStereoProcessing(
+ psyData, psyOutChannel, psyOutChannel[1]->isBook,
+ &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask,
+ psyConf[0].allowMS, psyData[0]->sfbActive, psyData[0]->sfbActive,
+ maxSfbPerGroup[0], psyOutChannel[0]->sfbOffsets);
+
+ /* PNS postprocessing */
+ FDKaacEnc_PostProcessPnsChannelPair(
+ psyData[0]->sfbActive, &(psyConf[0].pnsConf), pnsData[0], pnsData[1],
+ psyOutElement->toolsInfo.msMask, &psyOutElement->toolsInfo.msDigest);
+
+ } else {
+ FDKaacEnc_IntensityStereoProcessing(
+ psyData[0]->sfbEnergy.Long, psyData[1]->sfbEnergy.Long,
+ psyData[0]->mdctSpectrum, psyData[1]->mdctSpectrum,
+ psyData[0]->sfbThreshold.Long, psyData[1]->sfbThreshold.Long,
+ psyOutChannel[1]->sfbThresholdLdData,
+ psyData[0]->sfbSpreadEnergy.Long, psyData[1]->sfbSpreadEnergy.Long,
+ psyOutChannel[0]->sfbEnergyLdData, psyOutChannel[1]->sfbEnergyLdData,
+ &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask,
+ psyStatic[0]->blockSwitchingControl.noOfGroups *
+ hPsyConfShort->sfbCnt,
+ psyConf[1].sfbCnt, maxSfbPerGroup[0], psyData[0]->groupedSfbOffset,
+ psyConf[0].allowIS && psyOutElement->commonWindow,
+ psyOutChannel[1]->isBook, psyOutChannel[1]->isScale, pnsData);
+
+ /* it's OK to pass the ".Long" arrays here. They contain grouped short
+ * data since FDKaacEnc_groupShortData() */
+ FDKaacEnc_MsStereoProcessing(
+ psyData, psyOutChannel, psyOutChannel[1]->isBook,
+ &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask,
+ psyConf[1].allowMS,
+ psyStatic[0]->blockSwitchingControl.noOfGroups *
+ hPsyConfShort->sfbCnt,
+ hPsyConfShort->sfbCnt, maxSfbPerGroup[0],
+ psyOutChannel[0]->sfbOffsets);
+ }
+ } /* (channels == 2) */
+
+ /*
+ PNS Coding
+ */
+ for (ch = 0; ch < channels; ch++) {
+ if (psyStatic[ch]->isLFE) {
+ /* no PNS coding */
+ for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
+ psyOutChannel[ch]->noiseNrg[sfb] = NO_NOISE_PNS;
+ }
+ } else {
+ FDKaacEnc_CodePnsChannel(
+ psyData[ch]->sfbActive, &(hThisPsyConf[ch]->pnsConf),
+ pnsData[ch]->pnsFlag, psyData[ch]->sfbEnergyLdData.Long,
+ psyOutChannel[ch]->noiseNrg, /* this is the energy that will be
+ written to the bitstream */
+ psyOutChannel[ch]->sfbThresholdLdData);
+ }
+ }
+
+ /*
+ build output
+ */
+ for (ch = 0; ch < channels; ch++) {
+ INT mask;
+ int grp;
+ psyOutChannel[ch]->maxSfbPerGroup = maxSfbPerGroup[ch];
+ psyOutChannel[ch]->mdctScale = psyData[ch]->mdctScale;
+ if (isShortWindow[ch] == 0) {
+ psyOutChannel[ch]->sfbCnt = hPsyConfLong->sfbActive;
+ psyOutChannel[ch]->sfbPerGroup = hPsyConfLong->sfbActive;
+ psyOutChannel[ch]->lastWindowSequence =
+ psyStatic[ch]->blockSwitchingControl.lastWindowSequence;
+ psyOutChannel[ch]->windowShape =
+ psyStatic[ch]->blockSwitchingControl.windowShape;
+ } else {
+ INT sfbCnt = psyStatic[ch]->blockSwitchingControl.noOfGroups *
+ hPsyConfShort->sfbCnt;
+
+ psyOutChannel[ch]->sfbCnt = sfbCnt;
+ psyOutChannel[ch]->sfbPerGroup = hPsyConfShort->sfbCnt;
+ psyOutChannel[ch]->lastWindowSequence = SHORT_WINDOW;
+ psyOutChannel[ch]->windowShape = SINE_WINDOW;
+ }
+ /* generate grouping mask */
+ mask = 0;
+ for (grp = 0; grp < psyStatic[ch]->blockSwitchingControl.noOfGroups;
+ grp++) {
+ int j;
+ mask <<= 1;
+ for (j = 1; j < psyStatic[ch]->blockSwitchingControl.groupLen[grp]; j++) {
+ mask = (mask << 1) | 1;
+ }
+ }
+ psyOutChannel[ch]->groupingMask = mask;
+
+ /* build interface */
+ FDKmemcpy(psyOutChannel[ch]->groupLen,
+ psyStatic[ch]->blockSwitchingControl.groupLen,
+ MAX_NO_OF_GROUPS * sizeof(INT));
+ FDKmemcpy(psyOutChannel[ch]->sfbEnergy, (&psyData[ch]->sfbEnergy)->Long,
+ MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+ FDKmemcpy(psyOutChannel[ch]->sfbSpreadEnergy,
+ (&psyData[ch]->sfbSpreadEnergy)->Long,
+ MAX_GROUPED_SFB * sizeof(FIXP_DBL));
+ // FDKmemcpy(psyOutChannel[ch]->mdctSpectrum,
+ // psyData[ch]->mdctSpectrum, (1024)*sizeof(FIXP_DBL));
+ }
+
+ return AAC_ENC_OK;
+}
+
+void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, PSY_OUT **phPsyOut) {
+ int n, i;
+
+ if (phPsyInternal != NULL) {
+ PSY_INTERNAL *hPsyInternal = *phPsyInternal;
+
+ if (hPsyInternal) {
+ for (i = 0; i < (8); i++) {
+ if (hPsyInternal->pStaticChannels[i]) {
+ if (hPsyInternal->pStaticChannels[i]->psyInputBuffer)
+ FreeRam_aacEnc_PsyInputBuffer(
+ &hPsyInternal->pStaticChannels[i]
+ ->psyInputBuffer); /* AUDIO INPUT BUFFER */
+
+ FreeRam_aacEnc_PsyStatic(
+ &hPsyInternal->pStaticChannels[i]); /* PSY_STATIC */
+ }
+ }
+
+ for (i = 0; i < ((8)); i++) {
+ if (hPsyInternal->psyElement[i])
+ FreeRam_aacEnc_PsyElement(
+ &hPsyInternal->psyElement[i]); /* PSY_ELEMENT */
+ }
+
+ FreeRam_aacEnc_PsyInternal(phPsyInternal);
+ }
+ }
+
+ if (phPsyOut != NULL) {
+ for (n = 0; n < (1); n++) {
+ if (phPsyOut[n]) {
+ for (i = 0; i < (8); i++) {
+ if (phPsyOut[n]->pPsyOutChannels[i])
+ FreeRam_aacEnc_PsyOutChannel(
+ &phPsyOut[n]->pPsyOutChannels[i]); /* PSY_OUT_CHANNEL */
+ }
+
+ for (i = 0; i < ((8)); i++) {
+ if (phPsyOut[n]->psyOutElement[i])
+ FreeRam_aacEnc_PsyOutElements(
+ &phPsyOut[n]->psyOutElement[i]); /* PSY_OUT_ELEMENTS */
+ }
+
+ FreeRam_aacEnc_PsyOut(&phPsyOut[n]);
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACenc/src/psy_main.h b/fdk-aac/libAACenc/src/psy_main.h
new file mode 100644
index 0000000..7cc01a3
--- /dev/null
+++ b/fdk-aac/libAACenc/src/psy_main.h
@@ -0,0 +1,161 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Psychoaccoustic major function block
+
+*******************************************************************************/
+
+#ifndef PSY_MAIN_H
+#define PSY_MAIN_H
+
+#include "psy_configuration.h"
+#include "qc_data.h"
+#include "aacenc_pns.h"
+
+/*
+ psych internal
+*/
+typedef struct {
+ PSY_STATIC *psyStatic[(2)];
+
+} PSY_ELEMENT;
+
+typedef struct {
+ PSY_DATA psyData[(2)];
+ TNS_DATA tnsData[(2)];
+ PNS_DATA pnsData[(2)];
+
+} PSY_DYNAMIC;
+
+typedef struct {
+ PSY_CONFIGURATION psyConf[2]; /* LONG / SHORT */
+ PSY_ELEMENT *psyElement[((8))];
+ PSY_STATIC *pStaticChannels[(8)];
+ PSY_DYNAMIC *psyDynamic;
+ INT granuleLength;
+
+} PSY_INTERNAL;
+
+AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, const INT nElements,
+ const INT nChannels, UCHAR *dynamic_RAM);
+
+AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, const INT nElements,
+ const INT nChannels, const INT nSubFrames,
+ UCHAR *dynamic_RAM);
+
+AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, PSY_OUT **phpsyOut,
+ const INT nSubFrames,
+ const INT nMaxChannels,
+ const AUDIO_OBJECT_TYPE audioObjectType,
+ CHANNEL_MAPPING *cm);
+
+AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(
+ PSY_INTERNAL *hPsy, AUDIO_OBJECT_TYPE audioObjectType, CHANNEL_MAPPING *cm,
+ INT sampleRate, INT granuleLength, INT bitRate, INT tnsMask, INT bandwidth,
+ INT usePns, INT useIS, INT useMS, UINT syntaxFlags, ULONG initFlags);
+
+AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, PSY_ELEMENT *psyElement,
+ PSY_DYNAMIC *psyDynamic,
+ PSY_CONFIGURATION *psyConf,
+ PSY_OUT_ELEMENT *psyOutElement,
+ INT_PCM *pInput, const UINT inputBufSize,
+ INT *chIdx, INT totalChannels);
+
+void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, PSY_OUT **phPsyOut);
+
+#endif /* PSY_MAIN_H */
diff --git a/fdk-aac/libAACenc/src/qc_data.h b/fdk-aac/libAACenc/src/qc_data.h
new file mode 100644
index 0000000..6e671ed
--- /dev/null
+++ b/fdk-aac/libAACenc/src/qc_data.h
@@ -0,0 +1,299 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Quantizing & coding data
+
+*******************************************************************************/
+
+#ifndef QC_DATA_H
+#define QC_DATA_H
+
+#include "aacenc.h"
+#include "psy_const.h"
+#include "dyn_bits.h"
+#include "adj_thr_data.h"
+#include "line_pe.h"
+#include "FDK_audio.h"
+#include "interface.h"
+
+typedef enum {
+ QCDATA_BR_MODE_INVALID = -1,
+ QCDATA_BR_MODE_CBR = 0, /* Constant bit rate, given average bitrate */
+ QCDATA_BR_MODE_VBR_1 = 1, /* Variable bit rate, very low */
+ QCDATA_BR_MODE_VBR_2 = 2, /* Variable bit rate, low */
+ QCDATA_BR_MODE_VBR_3 = 3, /* Variable bit rate, medium */
+ QCDATA_BR_MODE_VBR_4 = 4, /* Variable bit rate, high */
+ QCDATA_BR_MODE_VBR_5 = 5, /* Variable bit rate, very high */
+ QCDATA_BR_MODE_FF = 6, /* Fixed frame mode. */
+ QCDATA_BR_MODE_SFR = 7 /* Superframe mode. */
+
+} QCDATA_BR_MODE;
+
+typedef struct {
+ MP4_ELEMENT_ID elType;
+ INT instanceTag;
+ INT nChannelsInEl;
+ INT ChannelIndex[2];
+ FIXP_DBL relativeBits;
+} ELEMENT_INFO;
+
+typedef struct {
+ CHANNEL_MODE encMode;
+ INT nChannels;
+ INT nChannelsEff;
+ INT nElements;
+ ELEMENT_INFO elInfo[((8))];
+} CHANNEL_MAPPING;
+
+typedef struct {
+ INT paddingRest;
+} PADDING;
+
+/* Quantizing & coding stage */
+
+struct QC_INIT {
+ CHANNEL_MAPPING *channelMapping;
+ INT sceCpe; /* not used yet */
+ INT maxBits; /* maximum number of bits in reservoir */
+ INT averageBits; /* average number of bits we should use */
+ INT bitRes;
+ INT sampleRate; /* output sample rate */
+ INT isLowDelay; /* if set, calc bits2PE factor depending on samplerate */
+ INT staticBits; /* Bits per frame consumed by transport layers. */
+ QCDATA_BR_MODE bitrateMode;
+ INT meanPe;
+ INT chBitrate; /* Bitrate/channel */
+ INT invQuant;
+ INT maxIterations; /* Maximum number of allowed iterations before
+ FDKaacEnc_crashRecovery() is applied. */
+ FIXP_DBL maxBitFac;
+ INT bitrate;
+ INT nSubFrames; /* helper variable */
+ INT minBits; /* minimal number of bits in one frame*/
+ AACENC_BITRES_MODE bitResMode; /* 0: full bitreservoir, 1: reduced
+ bitreservoir, 2: disabled bitreservoir */
+ INT bitDistributionMode; /* Configure element-wise execution or execution over
+ all elements for the pe-dependent
+ threshold-adaption */
+
+ PADDING padding;
+};
+
+typedef struct {
+ FIXP_DBL mdctSpectrum[(1024)];
+
+ SHORT quantSpec[(1024)];
+
+ UINT maxValueInSfb[MAX_GROUPED_SFB];
+ INT scf[MAX_GROUPED_SFB];
+ INT globalGain;
+ SECTION_DATA sectionData;
+
+ FIXP_DBL sfbFormFactorLdData[MAX_GROUPED_SFB];
+
+ FIXP_DBL sfbThresholdLdData[MAX_GROUPED_SFB];
+ FIXP_DBL sfbMinSnrLdData[MAX_GROUPED_SFB];
+ FIXP_DBL sfbEnergyLdData[MAX_GROUPED_SFB];
+ FIXP_DBL sfbEnergy[MAX_GROUPED_SFB];
+ FIXP_DBL sfbWeightedEnergyLdData[MAX_GROUPED_SFB];
+
+ FIXP_DBL sfbEnFacLd[MAX_GROUPED_SFB];
+
+ FIXP_DBL sfbSpreadEnergy[MAX_GROUPED_SFB];
+
+} QC_OUT_CHANNEL;
+
+typedef struct {
+ EXT_PAYLOAD_TYPE type; /* type of the extension payload */
+ INT nPayloadBits; /* size of the payload */
+ UCHAR *pPayload; /* pointer to payload */
+
+} QC_OUT_EXTENSION;
+
+typedef struct {
+ INT staticBitsUsed; /* for verification purposes */
+ INT dynBitsUsed; /* for verification purposes */
+
+ INT extBitsUsed; /* bit consumption of extended fill elements */
+ INT nExtensions; /* number of extension payloads for this element */
+ QC_OUT_EXTENSION extension[(1)]; /* reffering extension payload */
+
+ INT grantedDynBits;
+
+ INT grantedPe;
+ INT grantedPeCorr;
+
+ PE_DATA peData;
+
+ QC_OUT_CHANNEL *qcOutChannel[(2)];
+
+ UCHAR
+ *dynMem_Ah_Flag; /* pointer to dynamic buffer used by AhFlag in function
+ FDKaacEnc_adaptThresholdsToPe() */
+ UCHAR
+ *dynMem_Thr_Exp; /* pointer to dynamic buffer used by ThrExp in function
+ FDKaacEnc_adaptThresholdsToPe() */
+ UCHAR *dynMem_SfbNActiveLinesLdData; /* pointer to dynamic buffer used by
+ sfbNActiveLinesLdData in function
+ FDKaacEnc_correctThresh() */
+
+} QC_OUT_ELEMENT;
+
+typedef struct {
+ QC_OUT_ELEMENT *qcElement[((8))];
+ QC_OUT_CHANNEL *pQcOutChannels[(8)];
+ QC_OUT_EXTENSION extension[(2 + 2)]; /* global extension payload */
+ INT nExtensions; /* number of extension payloads for this AU */
+ INT maxDynBits; /* maximal allowed dynamic bits in frame */
+ INT grantedDynBits; /* granted dynamic bits in frame */
+ INT totFillBits; /* fill bits */
+ INT elementExtBits; /* element associated extension payload bits, e.g. sbr,
+ drc ... */
+ INT globalExtBits; /* frame/au associated extension payload bits (anc data
+ ...) */
+ INT staticBits; /* aac side info bits */
+
+ INT totalNoRedPe;
+ INT totalGrantedPeCorr;
+
+ INT usedDynBits; /* number of dynamic bits in use */
+ INT alignBits; /* AU alignment bits */
+ INT totalBits; /* sum of static, dyn, sbr, fill, align and dse bits */
+
+} QC_OUT;
+
+typedef struct {
+ INT chBitrateEl; /* channel bitrate in element
+ (totalbitrate*el_relativeBits/el_channels) */
+ INT maxBitsEl; /* used in crash recovery */
+ INT bitResLevelEl; /* update bitreservoir level in each call of
+ FDKaacEnc_QCMain */
+ INT maxBitResBitsEl; /* nEffChannels*6144 - averageBitsInFrame */
+ FIXP_DBL relativeBitsEl; /* Bits relative to total Bits*/
+} ELEMENT_BITS;
+
+typedef struct {
+ /* this is basically struct QC_INIT */
+
+ INT globHdrBits;
+ INT maxBitsPerFrame; /* maximal allowed bits per frame, 6144*nChannelsEff */
+ INT minBitsPerFrame; /* minimal allowd bits per fram, superframing - DRM */
+ INT nElements;
+ QCDATA_BR_MODE bitrateMode;
+ AACENC_BITRES_MODE bitResMode; /* 0: full bitreservoir, 1: reduced
+ bitreservoir, 2: disabled bitreservoir */
+ INT bitResTot;
+ INT bitResTotMax;
+ INT maxIterations; /* Maximum number of allowed iterations before
+ FDKaacEnc_crashRecovery() is applied. */
+ INT invQuant;
+
+ FIXP_DBL vbrQualFactor;
+ FIXP_DBL maxBitFac;
+
+ PADDING padding;
+
+ ELEMENT_BITS *elementBits[((8))];
+ BITCNTR_STATE *hBitCounter;
+ ADJ_THR_STATE *hAdjThr;
+
+ INT dZoneQuantEnable; /* enable dead zone quantizer */
+
+} QC_STATE;
+
+#endif /* QC_DATA_H */
diff --git a/fdk-aac/libAACenc/src/qc_main.cpp b/fdk-aac/libAACenc/src/qc_main.cpp
new file mode 100644
index 0000000..0bf234c
--- /dev/null
+++ b/fdk-aac/libAACenc/src/qc_main.cpp
@@ -0,0 +1,1555 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Quantizing & coding
+
+*******************************************************************************/
+
+#include "qc_main.h"
+#include "quantize.h"
+#include "interface.h"
+#include "adj_thr.h"
+#include "sf_estim.h"
+#include "bit_cnt.h"
+#include "dyn_bits.h"
+#include "channel_map.h"
+#include "aacEnc_ram.h"
+
+#include "genericStds.h"
+
+#define AACENC_DZQ_BR_THR 32000 /* Dead zone quantizer bitrate threshold */
+
+typedef struct {
+ QCDATA_BR_MODE bitrateMode;
+ LONG vbrQualFactor;
+} TAB_VBR_QUAL_FACTOR;
+
+static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = {
+ {QCDATA_BR_MODE_VBR_1,
+ FL2FXCONST_DBL(0.160f)}, /* Approx. 32 - 48 (AC-LC), 32 - 56
+ (AAC-LD/ELD) kbps/channel */
+ {QCDATA_BR_MODE_VBR_2,
+ FL2FXCONST_DBL(0.148f)}, /* Approx. 40 - 56 (AC-LC), 40 - 64
+ (AAC-LD/ELD) kbps/channel */
+ {QCDATA_BR_MODE_VBR_3,
+ FL2FXCONST_DBL(0.135f)}, /* Approx. 48 - 64 (AC-LC), 48 - 72
+ (AAC-LD/ELD) kbps/channel */
+ {QCDATA_BR_MODE_VBR_4,
+ FL2FXCONST_DBL(0.111f)}, /* Approx. 64 - 80 (AC-LC), 64 - 88
+ (AAC-LD/ELD) kbps/channel */
+ {QCDATA_BR_MODE_VBR_5,
+ FL2FXCONST_DBL(0.070f)} /* Approx. 96 - 120 (AC-LC), 112 - 144
+ (AAC-LD/ELD) kbps/channel */
+};
+
+static INT isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode) {
+ return (((bitrateMode == QCDATA_BR_MODE_CBR) ||
+ (bitrateMode == QCDATA_BR_MODE_SFR) ||
+ (bitrateMode == QCDATA_BR_MODE_FF))
+ ? 1
+ : 0);
+}
+
+typedef enum {
+ FRAME_LEN_BYTES_MODULO = 1,
+ FRAME_LEN_BYTES_INT = 2
+} FRAME_LEN_RESULT_MODE;
+
+/* forward declarations */
+
+static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup,
+ INT sfbPerGroup, INT* RESTRICT sfbOffset,
+ SHORT* RESTRICT quantSpectrum,
+ UINT* RESTRICT maxValue);
+
+static void FDKaacEnc_crashRecovery(INT nChannels,
+ PSY_OUT_ELEMENT* psyOutElement,
+ QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement,
+ INT bitsToSave, AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig);
+
+static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(
+ int* iterations, const int maxIterations, int gainAdjustment,
+ int* chConstraintsFulfilled, int* calculateQuant, int nChannels,
+ PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement,
+ ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags,
+ SCHAR epConfig);
+
+void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC);
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_calcFrameLen
+ description:
+ returns:
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_calcFrameLen(INT bitRate, INT sampleRate,
+ INT granuleLength,
+ FRAME_LEN_RESULT_MODE mode) {
+ INT result;
+
+ result = ((granuleLength) >> 3) * (bitRate);
+
+ switch (mode) {
+ case FRAME_LEN_BYTES_MODULO:
+ result %= sampleRate;
+ break;
+ case FRAME_LEN_BYTES_INT:
+ result /= sampleRate;
+ break;
+ }
+ return (result);
+}
+
+/*****************************************************************************
+
+ functionname:FDKaacEnc_framePadding
+ description: Calculates if padding is needed for actual frame
+ returns:
+ input:
+ output:
+
+*****************************************************************************/
+static INT FDKaacEnc_framePadding(INT bitRate, INT sampleRate,
+ INT granuleLength, INT* paddingRest) {
+ INT paddingOn;
+ INT difference;
+
+ paddingOn = 0;
+
+ difference = FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength,
+ FRAME_LEN_BYTES_MODULO);
+ *paddingRest -= difference;
+
+ if (*paddingRest <= 0) {
+ paddingOn = 1;
+ *paddingRest += sampleRate;
+ }
+
+ return (paddingOn);
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_QCOutNew
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT** phQC, const INT nElements,
+ const INT nChannels, const INT nSubFrames,
+ UCHAR* dynamic_RAM) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ int n, i;
+ int elInc = 0, chInc = 0;
+
+ for (n = 0; n < nSubFrames; n++) {
+ phQC[n] = GetRam_aacEnc_QCout(n);
+ if (phQC[n] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCOutNew_bail;
+ }
+
+ for (i = 0; i < nChannels; i++) {
+ phQC[n]->pQcOutChannels[i] = GetRam_aacEnc_QCchannel(chInc, dynamic_RAM);
+ if (phQC[n]->pQcOutChannels[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCOutNew_bail;
+ }
+
+ chInc++;
+ } /* nChannels */
+
+ for (i = 0; i < nElements; i++) {
+ phQC[n]->qcElement[i] = GetRam_aacEnc_QCelement(elInc);
+ if (phQC[n]->qcElement[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCOutNew_bail;
+ }
+ elInc++;
+
+ /* initialize pointer to dynamic buffer which are used in adjust
+ * thresholds */
+ phQC[n]->qcElement[i]->dynMem_Ah_Flag = dynamic_RAM + (P_BUF_1);
+ phQC[n]->qcElement[i]->dynMem_Thr_Exp =
+ dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE;
+ phQC[n]->qcElement[i]->dynMem_SfbNActiveLinesLdData =
+ dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE + ADJ_THR_THR_EXP_SIZE;
+
+ } /* nElements */
+
+ } /* nSubFrames */
+
+ return AAC_ENC_OK;
+
+QCOutNew_bail:
+ return ErrorStatus;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_QCOutInit
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT* phQC[(1)], const INT nSubFrames,
+ const CHANNEL_MAPPING* cm) {
+ INT n, i, ch;
+
+ for (n = 0; n < nSubFrames; n++) {
+ INT chInc = 0;
+ for (i = 0; i < cm->nElements; i++) {
+ for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
+ phQC[n]->qcElement[i]->qcOutChannel[ch] =
+ phQC[n]->pQcOutChannels[chInc];
+ chInc++;
+ } /* chInEl */
+ } /* nElements */
+ } /* nSubFrames */
+
+ return AAC_ENC_OK;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_QCNew
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE** phQC, INT nElements,
+ UCHAR* dynamic_RAM) {
+ AAC_ENCODER_ERROR ErrorStatus;
+ int i;
+
+ QC_STATE* hQC = GetRam_aacEnc_QCstate();
+ *phQC = hQC;
+ if (hQC == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCNew_bail;
+ }
+
+ if (FDKaacEnc_AdjThrNew(&hQC->hAdjThr, nElements)) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCNew_bail;
+ }
+
+ if (FDKaacEnc_BCNew(&(hQC->hBitCounter), dynamic_RAM)) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCNew_bail;
+ }
+
+ for (i = 0; i < nElements; i++) {
+ hQC->elementBits[i] = GetRam_aacEnc_ElementBits(i);
+ if (hQC->elementBits[i] == NULL) {
+ ErrorStatus = AAC_ENC_NO_MEMORY;
+ goto QCNew_bail;
+ }
+ }
+
+ return AAC_ENC_OK;
+
+QCNew_bail:
+ FDKaacEnc_QCClose(phQC, NULL);
+ return ErrorStatus;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_QCInit
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE* hQC, struct QC_INIT* init,
+ const ULONG initFlags) {
+ AAC_ENCODER_ERROR err = AAC_ENC_OK;
+
+ int i;
+ hQC->maxBitsPerFrame = init->maxBits;
+ hQC->minBitsPerFrame = init->minBits;
+ hQC->nElements = init->channelMapping->nElements;
+ if ((initFlags != 0) || ((init->bitrateMode != QCDATA_BR_MODE_FF) &&
+ (hQC->bitResTotMax != init->bitRes))) {
+ hQC->bitResTot = init->bitRes;
+ }
+ hQC->bitResTotMax = init->bitRes;
+ hQC->maxBitFac = init->maxBitFac;
+ hQC->bitrateMode = init->bitrateMode;
+ hQC->invQuant = init->invQuant;
+ hQC->maxIterations = init->maxIterations;
+
+ if (isConstantBitrateMode(hQC->bitrateMode)) {
+ /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir
+ */
+ hQC->bitResMode = init->bitResMode;
+ } else {
+ hQC->bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
+ }
+
+ hQC->padding.paddingRest = init->padding.paddingRest;
+
+ hQC->globHdrBits = init->staticBits; /* Bit overhead due to transport */
+
+ err = FDKaacEnc_InitElementBits(
+ hQC, init->channelMapping, init->bitrate,
+ (init->averageBits / init->nSubFrames) - hQC->globHdrBits,
+ hQC->maxBitsPerFrame / init->channelMapping->nChannelsEff);
+ if (err != AAC_ENC_OK) goto bail;
+
+ hQC->vbrQualFactor = FL2FXCONST_DBL(0.f);
+ for (i = 0;
+ i < (int)(sizeof(tableVbrQualFactor) / sizeof(TAB_VBR_QUAL_FACTOR));
+ i++) {
+ if (hQC->bitrateMode == tableVbrQualFactor[i].bitrateMode) {
+ hQC->vbrQualFactor = (FIXP_DBL)tableVbrQualFactor[i].vbrQualFactor;
+ break;
+ }
+ }
+
+ if (init->channelMapping->nChannelsEff == 1 &&
+ (init->bitrate / init->channelMapping->nChannelsEff) <
+ AACENC_DZQ_BR_THR &&
+ init->isLowDelay !=
+ 0) /* watch out here: init->bitrate is the bitrate "minus" the
+ standard SBR bitrate (=2500kbps) --> for the FDK the OFFSTE
+ tuning should start somewhere below 32000kbps-2500kbps ... so
+ everything is fine here */
+ {
+ hQC->dZoneQuantEnable = 1;
+ } else {
+ hQC->dZoneQuantEnable = 0;
+ }
+
+ FDKaacEnc_AdjThrInit(
+ hQC->hAdjThr, init->meanPe, hQC->invQuant, init->channelMapping,
+ init->sampleRate, /* output sample rate */
+ init->bitrate, /* total bitrate */
+ init->isLowDelay, /* if set, calc bits2PE factor
+ depending on samplerate */
+ init->bitResMode /* for a small bitreservoir, the pe
+ correction is calc'd differently */
+ ,
+ hQC->dZoneQuantEnable, init->bitDistributionMode, hQC->vbrQualFactor);
+
+bail:
+ return err;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_QCMainPrepare
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare(
+ ELEMENT_INFO* elInfo, ATS_ELEMENT* RESTRICT adjThrStateElement,
+ PSY_OUT_ELEMENT* RESTRICT psyOutElement,
+ QC_OUT_ELEMENT* RESTRICT qcOutElement, AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig) {
+ AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
+ INT nChannels = elInfo->nChannelsInEl;
+
+ PSY_OUT_CHANNEL** RESTRICT psyOutChannel =
+ psyOutElement->psyOutChannel; /* may be modified in-place */
+
+ FDKaacEnc_CalcFormFactor(qcOutElement->qcOutChannel, psyOutChannel,
+ nChannels);
+
+ /* prepare and calculate PE without reduction */
+ FDKaacEnc_peCalculation(&qcOutElement->peData, psyOutChannel,
+ qcOutElement->qcOutChannel, &psyOutElement->toolsInfo,
+ adjThrStateElement, nChannels);
+
+ ErrorStatus = FDKaacEnc_ChannelElementWrite(
+ NULL, elInfo, NULL, psyOutElement, psyOutElement->psyOutChannel,
+ syntaxFlags, aot, epConfig, &qcOutElement->staticBitsUsed, 0);
+
+ return ErrorStatus;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_AdjustBitrate
+ description: adjusts framelength via padding on a frame to frame
+basis, to achieve a bitrate that demands a non byte aligned framelength return:
+errorcode
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(
+ QC_STATE* RESTRICT hQC, CHANNEL_MAPPING* RESTRICT cm, INT* avgTotalBits,
+ INT bitRate, /* total bitrate */
+ INT sampleRate, /* output sampling rate */
+ INT granuleLength) /* frame length */
+{
+ INT paddingOn;
+ INT frameLen;
+ //fprintf(stderr, "hQC->padding.paddingRest=%d bytes! (before)\n", hQC->padding.paddingRest);
+
+ /* Do we need an extra padding byte? */
+ paddingOn = FDKaacEnc_framePadding(bitRate, sampleRate, granuleLength,
+ &hQC->padding.paddingRest);
+
+ frameLen =
+ paddingOn + FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength,
+ FRAME_LEN_BYTES_INT);
+
+ *avgTotalBits = frameLen << 3;
+
+ return AAC_ENC_OK;
+}
+
+#define isAudioElement(elType) \
+ ((elType == ID_SCE) || (elType == ID_CPE) || (elType == ID_LFE))
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_distributeElementDynBits
+ description: distributes all bits over all elements. The relative bit
+ distibution is described in the ELEMENT_INFO of the
+ appropriate element. The bit distribution table is
+ initialized in FDKaacEnc_InitChannelMapping().
+ return: errorcode
+
+**********************************************************************************/
+static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits(
+ QC_STATE* hQC, QC_OUT_ELEMENT* qcElement[((8))], CHANNEL_MAPPING* cm,
+ INT codeBits) {
+ INT i; /* counter variable */
+ INT totalBits = 0; /* sum of bits over all elements */
+
+ for (i = (cm->nElements - 1); i >= 0; i--) {
+ if (isAudioElement(cm->elInfo[i].elType)) {
+ qcElement[i]->grantedDynBits =
+ fMax(0, fMultI(hQC->elementBits[i]->relativeBitsEl, codeBits));
+ totalBits += qcElement[i]->grantedDynBits;
+ }
+ }
+
+ /* Due to inaccuracies with the multiplication, codeBits may differ from
+ totalBits. For that case, the difference must be added/substracted again
+ to/from one element, i.e:
+ Negative differences are substracted from the element with the most bits.
+ Positive differences are added to the element with the least bits.
+ */
+ if (codeBits != totalBits) {
+ INT elMaxBits = cm->nElements - 1; /* element with the most bits */
+ INT elMinBits = cm->nElements - 1; /* element with the least bits */
+
+ /* Search for biggest and smallest audio element */
+ for (i = (cm->nElements - 1); i >= 0; i--) {
+ if (isAudioElement(cm->elInfo[i].elType)) {
+ if (qcElement[i]->grantedDynBits >
+ qcElement[elMaxBits]->grantedDynBits) {
+ elMaxBits = i;
+ }
+ if (qcElement[i]->grantedDynBits <
+ qcElement[elMinBits]->grantedDynBits) {
+ elMinBits = i;
+ }
+ }
+ }
+ /* Compensate for bit distibution difference */
+ if (codeBits - totalBits > 0) {
+ qcElement[elMinBits]->grantedDynBits += codeBits - totalBits;
+ } else {
+ qcElement[elMaxBits]->grantedDynBits += codeBits - totalBits;
+ }
+ }
+
+ return AAC_ENC_OK;
+}
+
+/**
+ * \brief Verify whether minBitsPerFrame criterion can be satisfied.
+ *
+ * This function evaluates the bit consumption only if minBitsPerFrame parameter
+ * is not 0. In hyperframing mode the difference between grantedDynBits and
+ * usedDynBits of all sub frames results the number of fillbits to be written.
+ * This bits can be distrubitued in superframe to reach minBitsPerFrame bit
+ * consumption in single AU's. The return value denotes if enough desired fill
+ * bits are available to achieve minBitsPerFrame in all frames. This check can
+ * only be used within superframes.
+ *
+ * \param qcOut Pointer to coding data struct.
+ * \param minBitsPerFrame Minimal number of bits to be consumed in each frame.
+ * \param nSubFrames Number of frames in superframe
+ *
+ * \return
+ * - 1: all fine
+ * - 0: criterion not fulfilled
+ */
+static int checkMinFrameBitsDemand(QC_OUT** qcOut, const INT minBitsPerFrame,
+ const INT nSubFrames) {
+ int result = 1; /* all fine*/
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/*********************************************************************************
+
+ functionname: FDKaacEnc_getMinimalStaticBitdemand
+ description: calculate minmal size of static bits by reduction ,
+ to zero spectrum and deactivating tns and MS
+ return: number of static bits
+
+**********************************************************************************/
+static int FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING* cm,
+ PSY_OUT** psyOut) {
+ AUDIO_OBJECT_TYPE aot = AOT_AAC_LC;
+ UINT syntaxFlags = 0;
+ SCHAR epConfig = -1;
+ int i, bitcount = 0;
+
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ INT minElBits = 0;
+
+ FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL,
+ psyOut[0]->psyOutElement[i],
+ psyOut[0]->psyOutElement[i]->psyOutChannel,
+ syntaxFlags, aot, epConfig, &minElBits, 1);
+ bitcount += minElBits;
+ }
+ }
+
+ return bitcount;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static AAC_ENCODER_ERROR FDKaacEnc_prepareBitDistribution(
+ QC_STATE* hQC, PSY_OUT** psyOut, QC_OUT** qcOut, CHANNEL_MAPPING* cm,
+ QC_OUT_ELEMENT* qcElement[(1)][((8))], INT avgTotalBits,
+ INT* totalAvailableBits, INT* avgTotalDynBits) {
+ int i;
+ /* get maximal allowed dynamic bits */
+ qcOut[0]->grantedDynBits =
+ (fixMin(hQC->maxBitsPerFrame, avgTotalBits) - hQC->globHdrBits) & ~7;
+ qcOut[0]->grantedDynBits -= (qcOut[0]->globalExtBits + qcOut[0]->staticBits +
+ qcOut[0]->elementExtBits);
+ qcOut[0]->maxDynBits = ((hQC->maxBitsPerFrame) & ~7) -
+ (qcOut[0]->globalExtBits + qcOut[0]->staticBits +
+ qcOut[0]->elementExtBits);
+ /* assure that enough bits are available */
+ if ((qcOut[0]->grantedDynBits + hQC->bitResTot) < 0) {
+ /* crash recovery allows to reduce static bits to a minimum */
+ if ((qcOut[0]->grantedDynBits + hQC->bitResTot) <
+ (FDKaacEnc_getMinimalStaticBitdemand(cm, psyOut) -
+ qcOut[0]->staticBits))
+ return AAC_ENC_BITRES_TOO_LOW;
+ }
+
+ /* distribute dynamic bits to each element */
+ FDKaacEnc_distributeElementDynBits(hQC, qcElement[0], cm,
+ qcOut[0]->grantedDynBits);
+
+ *avgTotalDynBits = 0; /*frameDynBits;*/
+
+ *totalAvailableBits = avgTotalBits;
+
+ /* sum up corrected granted PE */
+ qcOut[0]->totalGrantedPeCorr = 0;
+
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+ int nChannels = elInfo.nChannelsInEl;
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* for ( all sub frames ) ... */
+ FDKaacEnc_DistributeBits(
+ hQC->hAdjThr, hQC->hAdjThr->adjThrStateElem[i],
+ psyOut[0]->psyOutElement[i]->psyOutChannel, &qcElement[0][i]->peData,
+ &qcElement[0][i]->grantedPe, &qcElement[0][i]->grantedPeCorr,
+ nChannels, psyOut[0]->psyOutElement[i]->commonWindow,
+ qcElement[0][i]->grantedDynBits, hQC->elementBits[i]->bitResLevelEl,
+ hQC->elementBits[i]->maxBitResBitsEl, hQC->maxBitFac,
+ hQC->bitResMode);
+
+ *totalAvailableBits += hQC->elementBits[i]->bitResLevelEl;
+ /* get total corrected granted PE */
+ qcOut[0]->totalGrantedPeCorr += qcElement[0][i]->grantedPeCorr;
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+
+ } /* -end- element loop */
+
+ *totalAvailableBits = fMin(hQC->maxBitsPerFrame, (*totalAvailableBits));
+
+ return AAC_ENC_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static AAC_ENCODER_ERROR FDKaacEnc_updateUsedDynBits(
+ INT* sumDynBitsConsumed, QC_OUT_ELEMENT* qcElement[((8))],
+ CHANNEL_MAPPING* cm) {
+ INT i;
+
+ *sumDynBitsConsumed = 0;
+
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* sum up bits consumed */
+ *sumDynBitsConsumed += qcElement[i]->dynBitsUsed;
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+
+ } /* -end- element loop */
+
+ return AAC_ENC_OK;
+}
+
+static INT FDKaacEnc_getTotalConsumedDynBits(QC_OUT** qcOut, INT nSubFrames) {
+ INT c, totalBits = 0;
+
+ /* sum up bit consumption for all sub frames */
+ for (c = 0; c < nSubFrames; c++) {
+ /* bit consumption not valid if dynamic bits
+ not available in one sub frame */
+ if (qcOut[c]->usedDynBits == -1) return -1;
+ totalBits += qcOut[c]->usedDynBits;
+ }
+
+ return totalBits;
+}
+
+static INT FDKaacEnc_getTotalConsumedBits(QC_OUT** qcOut,
+ QC_OUT_ELEMENT* qcElement[(1)][((8))],
+ CHANNEL_MAPPING* cm, INT globHdrBits,
+ INT nSubFrames) {
+ int c, i;
+ int totalUsedBits = 0;
+
+ for (c = 0; c < nSubFrames; c++) {
+ int dataBits = 0;
+ for (i = 0; i < cm->nElements; i++) {
+ if ((cm->elInfo[i].elType == ID_SCE) ||
+ (cm->elInfo[i].elType == ID_CPE) ||
+ (cm->elInfo[i].elType == ID_LFE)) {
+ dataBits += qcElement[c][i]->dynBitsUsed +
+ qcElement[c][i]->staticBitsUsed +
+ qcElement[c][i]->extBitsUsed;
+ }
+ }
+ dataBits += qcOut[c]->globalExtBits;
+
+ totalUsedBits += (8 - (dataBits) % 8) % 8;
+ totalUsedBits += dataBits + globHdrBits; /* header bits for every frame */
+ }
+ return totalUsedBits;
+}
+
+static AAC_ENCODER_ERROR FDKaacEnc_BitResRedistribution(
+ QC_STATE* const hQC, const CHANNEL_MAPPING* const cm,
+ const INT avgTotalBits) {
+ /* check bitreservoir fill level */
+ if (hQC->bitResTot < 0) {
+ return AAC_ENC_BITRES_TOO_LOW;
+ } else if (hQC->bitResTot > hQC->bitResTotMax) {
+ return AAC_ENC_BITRES_TOO_HIGH;
+ } else {
+ INT i;
+ INT totalBits = 0, totalBits_max = 0;
+
+ const int totalBitreservoir =
+ fMin(hQC->bitResTot, (hQC->maxBitsPerFrame - avgTotalBits));
+ const int totalBitreservoirMax =
+ fMin(hQC->bitResTotMax, (hQC->maxBitsPerFrame - avgTotalBits));
+
+ for (i = (cm->nElements - 1); i >= 0; i--) {
+ if ((cm->elInfo[i].elType == ID_SCE) ||
+ (cm->elInfo[i].elType == ID_CPE) ||
+ (cm->elInfo[i].elType == ID_LFE)) {
+ hQC->elementBits[i]->bitResLevelEl =
+ fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoir);
+ totalBits += hQC->elementBits[i]->bitResLevelEl;
+
+ hQC->elementBits[i]->maxBitResBitsEl =
+ fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoirMax);
+ totalBits_max += hQC->elementBits[i]->maxBitResBitsEl;
+ }
+ }
+ for (i = 0; i < cm->nElements; i++) {
+ if ((cm->elInfo[i].elType == ID_SCE) ||
+ (cm->elInfo[i].elType == ID_CPE) ||
+ (cm->elInfo[i].elType == ID_LFE)) {
+ int deltaBits = fMax(totalBitreservoir - totalBits,
+ -hQC->elementBits[i]->bitResLevelEl);
+ hQC->elementBits[i]->bitResLevelEl += deltaBits;
+ totalBits += deltaBits;
+
+ deltaBits = fMax(totalBitreservoirMax - totalBits_max,
+ -hQC->elementBits[i]->maxBitResBitsEl);
+ hQC->elementBits[i]->maxBitResBitsEl += deltaBits;
+ totalBits_max += deltaBits;
+ }
+ }
+ }
+
+ return AAC_ENC_OK;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, PSY_OUT** psyOut,
+ QC_OUT** qcOut, INT avgTotalBits,
+ CHANNEL_MAPPING* cm,
+ const AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig) {
+ int i, c;
+ AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
+ INT avgTotalDynBits = 0; /* maximal allowed dynamic bits for all frames */
+ INT totalAvailableBits = 0;
+ INT nSubFrames = 1;
+
+ /*-------------------------------------------- */
+ /* redistribute total bitreservoir to elements */
+ ErrorStatus = FDKaacEnc_BitResRedistribution(hQC, cm, avgTotalBits);
+ if (ErrorStatus != AAC_ENC_OK) {
+ return ErrorStatus;
+ }
+
+ /*-------------------------------------------- */
+ /* fastenc needs one time threshold simulation,
+ in case of multiple frames, one more guess has to be calculated */
+
+ /*-------------------------------------------- */
+ /* helper pointer */
+ QC_OUT_ELEMENT* qcElement[(1)][((8))];
+
+ /* work on a copy of qcChannel and qcElement */
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* for ( all sub frames ) ... */
+ for (c = 0; c < nSubFrames; c++) {
+ { qcElement[c][i] = qcOut[c]->qcElement[i]; }
+ }
+ }
+ }
+
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+ if (isConstantBitrateMode(hQC->bitrateMode)) {
+ /* calc granted dynamic bits for sub frame and
+ distribute it to each element */
+ ErrorStatus = FDKaacEnc_prepareBitDistribution(
+ hQC, psyOut, qcOut, cm, qcElement, avgTotalBits, &totalAvailableBits,
+ &avgTotalDynBits);
+
+ if (ErrorStatus != AAC_ENC_OK) {
+ return ErrorStatus;
+ }
+ } else {
+ qcOut[0]->grantedDynBits =
+ ((hQC->maxBitsPerFrame - (hQC->globHdrBits)) & ~7) -
+ (qcOut[0]->globalExtBits + qcOut[0]->staticBits +
+ qcOut[0]->elementExtBits);
+ qcOut[0]->maxDynBits = qcOut[0]->grantedDynBits;
+
+ totalAvailableBits = hQC->maxBitsPerFrame;
+ avgTotalDynBits = 0;
+ }
+
+ /* for ( all sub frames ) ... */
+ for (c = 0; c < nSubFrames; c++) {
+ /* for CBR and VBR mode */
+ FDKaacEnc_AdjustThresholds(hQC->hAdjThr, qcElement[c], qcOut[c],
+ psyOut[c]->psyOutElement,
+ isConstantBitrateMode(hQC->bitrateMode), cm);
+
+ } /* -end- sub frame counter */
+
+ /*-------------------------------------------- */
+ INT iterations[(1)][((8))];
+ INT chConstraintsFulfilled[(1)][((8))][(2)];
+ INT calculateQuant[(1)][((8))][(2)];
+ INT constraintsFulfilled[(1)][((8))];
+ /*-------------------------------------------- */
+
+ /* for ( all sub frames ) ... */
+ for (c = 0; c < nSubFrames; c++) {
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+ INT ch, nChannels = elInfo.nChannelsInEl;
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* Turn thresholds into scalefactors, optimize bit consumption and
+ * verify conformance */
+ FDKaacEnc_EstimateScaleFactors(
+ psyOut[c]->psyOutElement[i]->psyOutChannel,
+ qcElement[c][i]->qcOutChannel, hQC->invQuant, hQC->dZoneQuantEnable,
+ cm->elInfo[i].nChannelsInEl);
+
+ /*-------------------------------------------- */
+ constraintsFulfilled[c][i] = 1;
+ iterations[c][i] = 0;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ chConstraintsFulfilled[c][i][ch] = 1;
+ calculateQuant[c][i][ch] = 1;
+ }
+
+ /*-------------------------------------------- */
+
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+
+ } /* -end- element loop */
+
+ qcOut[c]->usedDynBits = -1;
+
+ } /* -end- sub frame counter */
+
+ INT quantizationDone = 0;
+ INT sumDynBitsConsumedTotal = 0;
+ INT decreaseBitConsumption = -1; /* no direction yet! */
+
+ /*-------------------------------------------- */
+ /* -start- Quantization loop ... */
+ /*-------------------------------------------- */
+ do /* until max allowed bits per frame and maxDynBits!=-1*/
+ {
+ quantizationDone = 0;
+
+ c = 0; /* get frame to process */
+
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+ INT ch, nChannels = elInfo.nChannelsInEl;
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ do /* until element bits < nChannels*MIN_BUFSIZE_PER_EFF_CHAN */
+ {
+ do /* until spectral values < MAX_QUANT */
+ {
+ /*-------------------------------------------- */
+ if (!constraintsFulfilled[c][i]) {
+ if ((ErrorStatus = FDKaacEnc_reduceBitConsumption(
+ &iterations[c][i], hQC->maxIterations,
+ (decreaseBitConsumption) ? 1 : -1,
+ chConstraintsFulfilled[c][i], calculateQuant[c][i],
+ nChannels, psyOut[c]->psyOutElement[i], qcOut[c],
+ qcElement[c][i], hQC->elementBits[i], aot, syntaxFlags,
+ epConfig)) != AAC_ENC_OK) {
+ return ErrorStatus;
+ }
+ }
+
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+ constraintsFulfilled[c][i] = 1;
+
+ /*-------------------------------------------- */
+ /* quantize spectrum (per each channel) */
+ for (ch = 0; ch < nChannels; ch++) {
+ /*-------------------------------------------- */
+ chConstraintsFulfilled[c][i][ch] = 1;
+
+ /*-------------------------------------------- */
+
+ if (calculateQuant[c][i][ch]) {
+ QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch];
+ PSY_OUT_CHANNEL* psyOutCh =
+ psyOut[c]->psyOutElement[i]->psyOutChannel[ch];
+
+ calculateQuant[c][i][ch] =
+ 0; /* calculate quantization only if necessary */
+
+ /*-------------------------------------------- */
+ FDKaacEnc_QuantizeSpectrum(
+ psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup,
+ psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets,
+ qcOutCh->mdctSpectrum, qcOutCh->globalGain, qcOutCh->scf,
+ qcOutCh->quantSpec, hQC->dZoneQuantEnable);
+
+ /*-------------------------------------------- */
+ if (FDKaacEnc_calcMaxValueInSfb(
+ psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup,
+ psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets,
+ qcOutCh->quantSpec,
+ qcOutCh->maxValueInSfb) > MAX_QUANT) {
+ chConstraintsFulfilled[c][i][ch] = 0;
+ constraintsFulfilled[c][i] = 0;
+ /* if quanizted value out of range; increase global gain! */
+ decreaseBitConsumption = 1;
+ }
+
+ /*-------------------------------------------- */
+
+ } /* if calculateQuant[c][i][ch] */
+
+ } /* channel loop */
+
+ /*-------------------------------------------- */
+ /* quantize spectrum (per each channel) */
+
+ /*-------------------------------------------- */
+
+ } while (!constraintsFulfilled[c][i]); /* does not regard bit
+ consumption */
+
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+ qcElement[c][i]->dynBitsUsed = 0; /* reset dynamic bits */
+
+ /* quantization valid in current channel! */
+ for (ch = 0; ch < nChannels; ch++) {
+ QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch];
+ PSY_OUT_CHANNEL* psyOutCh =
+ psyOut[c]->psyOutElement[i]->psyOutChannel[ch];
+
+ /* count dynamic bits */
+ INT chDynBits = FDKaacEnc_dynBitCount(
+ hQC->hBitCounter, qcOutCh->quantSpec, qcOutCh->maxValueInSfb,
+ qcOutCh->scf, psyOutCh->lastWindowSequence, psyOutCh->sfbCnt,
+ psyOutCh->maxSfbPerGroup, psyOutCh->sfbPerGroup,
+ psyOutCh->sfbOffsets, &qcOutCh->sectionData, psyOutCh->noiseNrg,
+ psyOutCh->isBook, psyOutCh->isScale, syntaxFlags);
+
+ /* sum up dynamic channel bits */
+ qcElement[c][i]->dynBitsUsed += chDynBits;
+ }
+
+ /* save dynBitsUsed for correction of bits2pe relation */
+ if (hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast == -1) {
+ hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast =
+ qcElement[c][i]->dynBitsUsed;
+ }
+
+ /* hold total bit consumption in present element below maximum allowed
+ */
+ if (qcElement[c][i]->dynBitsUsed >
+ ((nChannels * MIN_BUFSIZE_PER_EFF_CHAN) -
+ qcElement[c][i]->staticBitsUsed -
+ qcElement[c][i]->extBitsUsed)) {
+ constraintsFulfilled[c][i] = 0;
+ }
+
+ } while (!constraintsFulfilled[c][i]);
+
+ } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */
+
+ } /* -end- element loop */
+
+ /* update dynBits of current subFrame */
+ FDKaacEnc_updateUsedDynBits(&qcOut[c]->usedDynBits, qcElement[c], cm);
+
+ /* get total consumed bits, dyn bits in all sub frames have to be valid */
+ sumDynBitsConsumedTotal =
+ FDKaacEnc_getTotalConsumedDynBits(qcOut, nSubFrames);
+
+ if (sumDynBitsConsumedTotal == -1) {
+ quantizationDone = 0; /* bit consumption not valid in all sub frames */
+ } else {
+ int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(
+ qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames);
+
+ /* in all frames are valid dynamic bits */
+ if (((sumBitsConsumedTotal < totalAvailableBits) ||
+ sumDynBitsConsumedTotal == 0) &&
+ (decreaseBitConsumption == 1) &&
+ checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)
+ /*()*/) {
+ quantizationDone = 1; /* exit bit adjustment */
+ }
+ if (sumBitsConsumedTotal > totalAvailableBits &&
+ (decreaseBitConsumption == 0)) {
+ quantizationDone = 0; /* reset! */
+ }
+ }
+
+ /*-------------------------------------------- */
+
+ int emergencyIterations = 1;
+ int dynBitsOvershoot = 0;
+
+ for (c = 0; c < nSubFrames; c++) {
+ for (i = 0; i < cm->nElements; i++) {
+ ELEMENT_INFO elInfo = cm->elInfo[i];
+
+ if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
+ (elInfo.elType == ID_LFE)) {
+ /* iteration limitation */
+ emergencyIterations &=
+ ((iterations[c][i] < hQC->maxIterations) ? 0 : 1);
+ }
+ }
+ /* detection if used dyn bits exceeds the maximal allowed criterion */
+ dynBitsOvershoot |=
+ ((qcOut[c]->usedDynBits > qcOut[c]->maxDynBits) ? 1 : 0);
+ }
+
+ if (quantizationDone == 0 || dynBitsOvershoot) {
+ int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(
+ qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames);
+
+ if ((sumDynBitsConsumedTotal >= avgTotalDynBits) ||
+ (sumDynBitsConsumedTotal == 0)) {
+ quantizationDone = 1;
+ }
+ if (emergencyIterations && (sumBitsConsumedTotal < totalAvailableBits)) {
+ quantizationDone = 1;
+ }
+ if ((sumBitsConsumedTotal > totalAvailableBits) ||
+ !checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) {
+ quantizationDone = 0;
+ }
+ if ((sumBitsConsumedTotal < totalAvailableBits) &&
+ checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) {
+ decreaseBitConsumption = 0;
+ } else {
+ decreaseBitConsumption = 1;
+ }
+
+ if (dynBitsOvershoot) {
+ quantizationDone = 0;
+ decreaseBitConsumption = 1;
+ }
+
+ /* reset constraints fullfilled flags */
+ FDKmemclear(constraintsFulfilled, sizeof(constraintsFulfilled));
+ FDKmemclear(chConstraintsFulfilled, sizeof(chConstraintsFulfilled));
+
+ } /* quantizationDone */
+
+ } while (!quantizationDone);
+
+ /*-------------------------------------------- */
+ /* ... -end- Quantization loop */
+ /*-------------------------------------------- */
+
+ /*-------------------------------------------- */
+ /*-------------------------------------------- */
+
+ return AAC_ENC_OK;
+}
+
+static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(
+ int* iterations, const int maxIterations, int gainAdjustment,
+ int* chConstraintsFulfilled, int* calculateQuant, int nChannels,
+ PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement,
+ ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags,
+ SCHAR epConfig) {
+ int ch;
+
+ /** SOLVING PROBLEM **/
+ if ((*iterations) < maxIterations) {
+ /* increase gain (+ next iteration) */
+ for (ch = 0; ch < nChannels; ch++) {
+ if (!chConstraintsFulfilled[ch]) {
+ qcOutElement->qcOutChannel[ch]->globalGain += gainAdjustment;
+ calculateQuant[ch] = 1; /* global gain has changed, recalculate
+ quantization in next iteration! */
+ }
+ }
+ } else if ((*iterations) == maxIterations) {
+ if (qcOutElement->dynBitsUsed == 0) {
+ return AAC_ENC_QUANT_ERROR;
+ } else {
+ /* crash recovery */
+ INT bitsToSave = 0;
+ if ((bitsToSave = fixMax(
+ (qcOutElement->dynBitsUsed + 8) -
+ (elBits->bitResLevelEl + qcOutElement->grantedDynBits),
+ (qcOutElement->dynBitsUsed + qcOutElement->staticBitsUsed + 8) -
+ (elBits->maxBitsEl))) > 0) {
+ FDKaacEnc_crashRecovery(nChannels, psyOutElement, qcOut, qcOutElement,
+ bitsToSave, aot, syntaxFlags, epConfig);
+ } else {
+ for (ch = 0; ch < nChannels; ch++) {
+ qcOutElement->qcOutChannel[ch]->globalGain += 1;
+ }
+ }
+ for (ch = 0; ch < nChannels; ch++) {
+ calculateQuant[ch] = 1;
+ }
+ }
+ } else {
+ /* (*iterations) > maxIterations */
+ return AAC_ENC_QUANT_ERROR;
+ }
+ (*iterations)++;
+
+ return AAC_ENC_OK;
+}
+
+AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm,
+ QC_STATE* qcKernel,
+ ELEMENT_BITS* RESTRICT elBits[((8))],
+ QC_OUT** qcOut) {
+ switch (qcKernel->bitrateMode) {
+ case QCDATA_BR_MODE_SFR:
+ break;
+
+ case QCDATA_BR_MODE_FF:
+ break;
+ case QCDATA_BR_MODE_VBR_1:
+ case QCDATA_BR_MODE_VBR_2:
+ case QCDATA_BR_MODE_VBR_3:
+ case QCDATA_BR_MODE_VBR_4:
+ case QCDATA_BR_MODE_VBR_5:
+ 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;
+ case QCDATA_BR_MODE_CBR:
+ case QCDATA_BR_MODE_INVALID:
+ default:
+ INT bitResSpace = qcKernel->bitResTotMax - qcKernel->bitResTot;
+ /* processing fill-bits */
+ INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits;
+ 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;
+ } /* switch (qcKernel->bitrateMode) */
+
+ return AAC_ENC_OK;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_calcMaxValueInSfb
+ description:
+ return:
+
+**********************************************************************************/
+
+static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup,
+ INT sfbPerGroup, INT* RESTRICT sfbOffset,
+ SHORT* RESTRICT quantSpectrum,
+ UINT* RESTRICT maxValue) {
+ INT sfbOffs, sfb;
+ INT maxValueAll = 0;
+
+ for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup)
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ INT line;
+ INT maxThisSfb = 0;
+ for (line = sfbOffset[sfbOffs + sfb]; line < sfbOffset[sfbOffs + sfb + 1];
+ line++) {
+ INT tmp = fixp_abs(quantSpectrum[line]);
+ maxThisSfb = fixMax(tmp, maxThisSfb);
+ }
+
+ maxValue[sfbOffs + sfb] = maxThisSfb;
+ maxValueAll = fixMax(maxThisSfb, maxValueAll);
+ }
+ return maxValueAll;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_updateBitres
+ description:
+ return:
+
+**********************************************************************************/
+void FDKaacEnc_updateBitres(CHANNEL_MAPPING* cm, QC_STATE* qcKernel,
+ QC_OUT** qcOut) {
+ switch (qcKernel->bitrateMode) {
+ case QCDATA_BR_MODE_VBR_1:
+ case QCDATA_BR_MODE_VBR_2:
+ case QCDATA_BR_MODE_VBR_3:
+ case QCDATA_BR_MODE_VBR_4:
+ case QCDATA_BR_MODE_VBR_5:
+ /* variable bitrate */
+ qcKernel->bitResTot =
+ fMin(qcKernel->maxBitsPerFrame, qcKernel->bitResTotMax);
+ break;
+ case QCDATA_BR_MODE_CBR:
+ case QCDATA_BR_MODE_SFR:
+ case QCDATA_BR_MODE_INVALID:
+ default:
+ int c = 0;
+ /* constant bitrate */
+ {
+ qcKernel->bitResTot += qcOut[c]->grantedDynBits -
+ (qcOut[c]->usedDynBits + qcOut[c]->totFillBits +
+ qcOut[c]->alignBits);
+ }
+ break;
+ }
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_FinalizeBitConsumption
+ description:
+ return:
+
+**********************************************************************************/
+AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(
+ CHANNEL_MAPPING* cm, QC_STATE* qcKernel, QC_OUT* qcOut,
+ QC_OUT_ELEMENT** qcElement, HANDLE_TRANSPORTENC hTpEnc,
+ AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig) {
+ QC_OUT_EXTENSION fillExtPayload;
+ INT totFillBits, alignBits;
+
+ /* Get total consumed bits in AU */
+ qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits +
+ qcOut->totFillBits + qcOut->elementExtBits +
+ qcOut->globalExtBits;
+
+ if (qcKernel->bitrateMode == QCDATA_BR_MODE_CBR) {
+ /* Now we can get the exact transport bit amount, and hopefully it is equal
+ * to the estimated value */
+ INT exactTpBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
+
+ if (exactTpBits != qcKernel->globHdrBits) {
+ INT diffFillBits = 0;
+
+ /* How many bits can be take by bitreservoir */
+ const INT bitresSpace =
+ qcKernel->bitResTotMax -
+ (qcKernel->bitResTot +
+ (qcOut->grantedDynBits - (qcOut->usedDynBits + qcOut->totFillBits)));
+
+ /* Number of bits which can be moved to bitreservoir. */
+ const INT bitsToBitres = qcKernel->globHdrBits - exactTpBits;
+ FDK_ASSERT(bitsToBitres >= 0); /* is always positive */
+
+ /* If bitreservoir can not take all bits, move ramaining bits to fillbits
+ */
+ diffFillBits = fMax(0, bitsToBitres - bitresSpace);
+
+ /* Assure previous alignment */
+ diffFillBits = (diffFillBits + 7) & ~7;
+
+ /* Move as many bits as possible to bitreservoir */
+ qcKernel->bitResTot += (bitsToBitres - diffFillBits);
+
+ /* Write remaing bits as fill bits */
+ qcOut->totFillBits += diffFillBits;
+ qcOut->totalBits += diffFillBits;
+ qcOut->grantedDynBits += diffFillBits;
+
+ /* Get new header bits */
+ qcKernel->globHdrBits =
+ transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
+
+ if (qcKernel->globHdrBits != exactTpBits) {
+ /* In previous step, fill bits and corresponding total bits were changed
+ when bitreservoir was completely filled. Now we can take the too much
+ taken bits caused by header overhead from bitreservoir.
+ */
+ qcKernel->bitResTot -= (qcKernel->globHdrBits - exactTpBits);
+ }
+ }
+
+ } /* MODE_CBR */
+
+ /* Update exact number of consumed header bits. */
+ qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
+
+ /* Save total fill bits and distribut to alignment and fill bits */
+ totFillBits = qcOut->totFillBits;
+
+ /* fake a fill extension payload */
+ FDKmemclear(&fillExtPayload, sizeof(QC_OUT_EXTENSION));
+
+ fillExtPayload.type = EXT_FILL_DATA;
+ fillExtPayload.nPayloadBits = totFillBits;
+
+ /* ask bitstream encoder how many of that bits can be written in a fill
+ * extension data entity */
+ qcOut->totFillBits = FDKaacEnc_writeExtensionData(NULL, &fillExtPayload, 0, 0,
+ syntaxFlags, aot, epConfig);
+
+ //fprintf(stderr, "FinalizeBitConsumption(): totFillBits=%d, qcOut->totFillBits=%d \n", totFillBits, qcOut->totFillBits);
+
+ /* now distribute extra fillbits and alignbits */
+ alignBits =
+ 7 - (qcOut->staticBits + qcOut->usedDynBits + qcOut->elementExtBits +
+ qcOut->totFillBits + qcOut->globalExtBits - 1) %
+ 8;
+
+ /* Maybe we could remove this */
+ if (((alignBits + qcOut->totFillBits - totFillBits) == 8) &&
+ (qcOut->totFillBits > 8))
+ qcOut->totFillBits -= 8;
+
+ qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits +
+ qcOut->totFillBits + alignBits + qcOut->elementExtBits +
+ qcOut->globalExtBits;
+
+ if ((qcOut->totalBits > qcKernel->maxBitsPerFrame) ||
+ (qcOut->totalBits < qcKernel->minBitsPerFrame)) {
+ return AAC_ENC_QUANT_ERROR;
+ }
+
+ qcOut->alignBits = alignBits;
+
+ return AAC_ENC_OK;
+}
+
+/*********************************************************************************
+
+ functionname: FDKaacEnc_crashRecovery
+ description: fulfills constraints by means of brute force...
+ => bits are saved by cancelling out spectral lines!!
+ (beginning at the highest frequencies)
+ return: errorcode
+
+**********************************************************************************/
+
+static void FDKaacEnc_crashRecovery(INT nChannels,
+ PSY_OUT_ELEMENT* psyOutElement,
+ QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement,
+ INT bitsToSave, AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig) {
+ INT ch;
+ INT savedBits = 0;
+ INT sfb, sfbGrp;
+ INT bitsPerScf[(2)][MAX_GROUPED_SFB];
+ INT sectionToScf[(2)][MAX_GROUPED_SFB];
+ INT* sfbOffset;
+ INT sect, statBitsNew;
+ QC_OUT_CHANNEL** qcChannel = qcElement->qcOutChannel;
+ PSY_OUT_CHANNEL** psyChannel = psyOutElement->psyOutChannel;
+
+ /* create a table which converts frq-bins to bit-demand... [bitsPerScf] */
+ /* ...and another one which holds the corresponding sections [sectionToScf] */
+ for (ch = 0; ch < nChannels; ch++) {
+ sfbOffset = psyChannel[ch]->sfbOffsets;
+
+ for (sect = 0; sect < qcChannel[ch]->sectionData.noOfSections; sect++) {
+ INT codeBook = qcChannel[ch]->sectionData.huffsection[sect].codeBook;
+
+ for (sfb = qcChannel[ch]->sectionData.huffsection[sect].sfbStart;
+ sfb < qcChannel[ch]->sectionData.huffsection[sect].sfbStart +
+ qcChannel[ch]->sectionData.huffsection[sect].sfbCnt;
+ sfb++) {
+ bitsPerScf[ch][sfb] = 0;
+ if ((codeBook != CODE_BOOK_PNS_NO) /*&&
+ (sfb < (qcChannel[ch]->sectionData.noOfGroups*qcChannel[ch]->sectionData.maxSfbPerGroup))*/) {
+ INT sfbStartLine = sfbOffset[sfb];
+ INT noOfLines = sfbOffset[sfb + 1] - sfbStartLine;
+ bitsPerScf[ch][sfb] = FDKaacEnc_countValues(
+ &(qcChannel[ch]->quantSpec[sfbStartLine]), noOfLines, codeBook);
+ }
+ sectionToScf[ch][sfb] = sect;
+ }
+ }
+ }
+
+ /* LOWER [maxSfb] IN BOTH CHANNELS!! */
+ /* Attention: in case of stereo: maxSfbL == maxSfbR, GroupingL == GroupingR ;
+ */
+
+ for (sfb = qcChannel[0]->sectionData.maxSfbPerGroup - 1; sfb >= 0; sfb--) {
+ for (sfbGrp = 0; sfbGrp < psyChannel[0]->sfbCnt;
+ sfbGrp += psyChannel[0]->sfbPerGroup) {
+ for (ch = 0; ch < nChannels; ch++) {
+ sect = sectionToScf[ch][sfbGrp + sfb];
+ qcChannel[ch]->sectionData.huffsection[sect].sfbCnt--;
+ savedBits += bitsPerScf[ch][sfbGrp + sfb];
+
+ if (qcChannel[ch]->sectionData.huffsection[sect].sfbCnt == 0) {
+ savedBits += (psyChannel[ch]->lastWindowSequence != SHORT_WINDOW)
+ ? FDKaacEnc_sideInfoTabLong[0]
+ : FDKaacEnc_sideInfoTabShort[0];
+ }
+ }
+ }
+
+ /* ...have enough bits been saved? */
+ if (savedBits >= bitsToSave) break;
+
+ } /* sfb loop */
+
+ /* if not enough bits saved,
+ clean whole spectrum and remove side info overhead */
+ if (sfb == -1) {
+ sfb = 0;
+ }
+
+ for (ch = 0; ch < nChannels; ch++) {
+ qcChannel[ch]->sectionData.maxSfbPerGroup = sfb;
+ psyChannel[ch]->maxSfbPerGroup = sfb;
+ /* when no spectrum is coded save tools info in bitstream */
+ if (sfb == 0) {
+ FDKmemclear(&psyChannel[ch]->tnsInfo, sizeof(TNS_INFO));
+ FDKmemclear(&psyOutElement->toolsInfo, sizeof(TOOLSINFO));
+ }
+ }
+ /* dynamic bits will be updated in iteration loop */
+
+ { /* if stop sfb has changed save bits in side info, e.g. MS or TNS coding */
+ ELEMENT_INFO elInfo;
+
+ FDKmemclear(&elInfo, sizeof(ELEMENT_INFO));
+ elInfo.nChannelsInEl = nChannels;
+ elInfo.elType = (nChannels == 2) ? ID_CPE : ID_SCE;
+
+ FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL, psyOutElement,
+ psyChannel, syntaxFlags, aot, epConfig,
+ &statBitsNew, 0);
+ }
+
+ savedBits = qcElement->staticBitsUsed - statBitsNew;
+
+ /* update static and dynamic bits */
+ qcElement->staticBitsUsed -= savedBits;
+ qcElement->grantedDynBits += savedBits;
+
+ qcOut->staticBits -= savedBits;
+ qcOut->grantedDynBits += savedBits;
+ qcOut->maxDynBits += savedBits;
+}
+
+void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC) {
+ int n, i;
+
+ if (phQC != NULL) {
+ for (n = 0; n < (1); n++) {
+ if (phQC[n] != NULL) {
+ QC_OUT* hQC = phQC[n];
+ for (i = 0; i < (8); i++) {
+ }
+
+ for (i = 0; i < ((8)); i++) {
+ if (hQC->qcElement[i]) FreeRam_aacEnc_QCelement(&hQC->qcElement[i]);
+ }
+
+ FreeRam_aacEnc_QCout(&phQC[n]);
+ }
+ }
+ }
+
+ if (phQCstate != NULL) {
+ if (*phQCstate != NULL) {
+ QC_STATE* hQCstate = *phQCstate;
+
+ if (hQCstate->hAdjThr != NULL) FDKaacEnc_AdjThrClose(&hQCstate->hAdjThr);
+
+ if (hQCstate->hBitCounter != NULL)
+ FDKaacEnc_BCClose(&hQCstate->hBitCounter);
+
+ for (i = 0; i < ((8)); i++) {
+ if (hQCstate->elementBits[i] != NULL) {
+ FreeRam_aacEnc_ElementBits(&hQCstate->elementBits[i]);
+ }
+ }
+ FreeRam_aacEnc_QCstate(phQCstate);
+ }
+ }
+}
diff --git a/fdk-aac/libAACenc/src/qc_main.h b/fdk-aac/libAACenc/src/qc_main.h
new file mode 100644
index 0000000..b9e8e2d
--- /dev/null
+++ b/fdk-aac/libAACenc/src/qc_main.h
@@ -0,0 +1,158 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Quantizing & coding
+
+*******************************************************************************/
+
+#ifndef QC_MAIN_H
+#define QC_MAIN_H
+
+#include "aacenc.h"
+#include "qc_data.h"
+#include "interface.h"
+#include "psy_main.h"
+#include "tpenc_lib.h"
+
+/* Quantizing & coding stage */
+
+AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT **phQC, const INT nElements,
+ const INT nChannels, const INT nSubFrames,
+ UCHAR *dynamic_RAM);
+
+AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT *phQC[(1)], const INT nSubFrames,
+ const CHANNEL_MAPPING *cm);
+
+AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE **phQC, INT nElements,
+ UCHAR *dynamic_RAM);
+
+AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, struct QC_INIT *init,
+ const ULONG initFlags);
+
+AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare(
+ ELEMENT_INFO *elInfo, ATS_ELEMENT *RESTRICT adjThrStateElement,
+ PSY_OUT_ELEMENT *RESTRICT psyOutElement,
+ QC_OUT_ELEMENT *RESTRICT qcOutElement, /* returns error code */
+ AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig);
+
+AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE *RESTRICT hQC, PSY_OUT **psyOut,
+ QC_OUT **qcOut, INT avgTotalBits,
+ CHANNEL_MAPPING *cm, AUDIO_OBJECT_TYPE aot,
+ UINT syntaxFlags, SCHAR epConfig);
+
+AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING *cm,
+ QC_STATE *qcKernel,
+ ELEMENT_BITS *RESTRICT elBits[((8))],
+ QC_OUT **qcOut);
+
+void FDKaacEnc_updateBitres(CHANNEL_MAPPING *cm, QC_STATE *qcKernel,
+ QC_OUT **qcOut);
+
+AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(
+ CHANNEL_MAPPING *cm, QC_STATE *hQC, QC_OUT *qcOut,
+ QC_OUT_ELEMENT **qcElement, HANDLE_TRANSPORTENC hTpEnc,
+ AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig);
+
+AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(QC_STATE *RESTRICT hQC,
+ CHANNEL_MAPPING *RESTRICT cm,
+ INT *avgTotalBits, INT bitRate,
+ INT sampleRate, INT granuleLength);
+
+void FDKaacEnc_QCClose(QC_STATE **phQCstate, QC_OUT **phQC);
+
+#endif /* QC_MAIN_H */
diff --git a/fdk-aac/libAACenc/src/quantize.cpp b/fdk-aac/libAACenc/src/quantize.cpp
new file mode 100644
index 0000000..4d25263
--- /dev/null
+++ b/fdk-aac/libAACenc/src/quantize.cpp
@@ -0,0 +1,401 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Quantization
+
+*******************************************************************************/
+
+#include "quantize.h"
+
+#include "aacEnc_rom.h"
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_quantizeLines
+ description: quantizes spectrum lines
+ returns:
+ input: global gain, number of lines to process, spectral data
+ output: quantized spectrum
+
+*****************************************************************************/
+static void FDKaacEnc_quantizeLines(INT gain, INT noOfLines,
+ const FIXP_DBL *mdctSpectrum,
+ SHORT *quaSpectrum, INT dZoneQuantEnable) {
+ int line;
+ FIXP_DBL k = FL2FXCONST_DBL(0.0f);
+ FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain) & 3];
+ 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++) {
+ FIXP_DBL accu = fMultDiv2(mdctSpectrum[line], quantizer);
+
+ if (accu < FL2FXCONST_DBL(0.0f)) {
+ accu = -accu;
+ /* normalize */
+ INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not
+ necessary here since test
+ value is always > 0 */
+ accu <<= accuShift;
+ INT tabIndex =
+ (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE);
+ INT totalShift = quantizershift - accuShift + 1;
+ accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],
+ FDKaacEnc_quantTableE[totalShift & 3]);
+ totalShift = (16 - 4) - (3 * (totalShift >> 2));
+ FDK_ASSERT(totalShift >= 0); /* MAX_QUANT_VIOLATION */
+ accu >>= fixMin(totalShift, DFRACT_BITS - 1);
+ quaSpectrum[line] =
+ (SHORT)(-((LONG)(k + accu) >> (DFRACT_BITS - 1 - 16)));
+ } else if (accu > FL2FXCONST_DBL(0.0f)) {
+ /* normalize */
+ INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not
+ necessary here since test
+ value is always > 0 */
+ accu <<= accuShift;
+ INT tabIndex =
+ (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE);
+ INT totalShift = quantizershift - accuShift + 1;
+ accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],
+ FDKaacEnc_quantTableE[totalShift & 3]);
+ totalShift = (16 - 4) - (3 * (totalShift >> 2));
+ FDK_ASSERT(totalShift >= 0); /* MAX_QUANT_VIOLATION */
+ accu >>= fixMin(totalShift, DFRACT_BITS - 1);
+ quaSpectrum[line] = (SHORT)((LONG)(k + accu) >> (DFRACT_BITS - 1 - 16));
+ } else {
+ quaSpectrum[line] = 0;
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname:iFDKaacEnc_quantizeLines
+ description: iquantizes spectrum lines
+ mdctSpectrum = iquaSpectrum^4/3 *2^(0.25*gain)
+ input: global gain, number of lines to process,quantized spectrum
+ output: spectral data
+
+*****************************************************************************/
+static void FDKaacEnc_invQuantizeLines(INT gain, INT noOfLines,
+ SHORT *quantSpectrum,
+ FIXP_DBL *mdctSpectrum)
+
+{
+ INT iquantizermod;
+ INT iquantizershift;
+ INT line;
+
+ iquantizermod = gain & 3;
+ iquantizershift = gain >> 2;
+
+ for (line = 0; line < noOfLines; line++) {
+ if (quantSpectrum[line] < 0) {
+ FIXP_DBL accu;
+ INT ex, specExp, tabIndex;
+ FIXP_DBL s, t;
+
+ accu = (FIXP_DBL)-quantSpectrum[line];
+
+ ex = CountLeadingBits(accu);
+ accu <<= ex;
+ specExp = (DFRACT_BITS - 1) - ex;
+
+ FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */
+
+ tabIndex = (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE);
+
+ /* calculate "mantissa" ^4/3 */
+ s = FDKaacEnc_mTab_4_3Elc[tabIndex];
+
+ /* get approperiate exponent multiplier for specExp^3/4 combined with
+ * scfMod */
+ t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp];
+
+ /* multiply "mantissa" ^4/3 with exponent multiplier */
+ accu = fMult(s, t);
+
+ /* get approperiate exponent shifter */
+ specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp] -
+ 1; /* -1 to avoid overflows in accu */
+
+ if ((-iquantizershift - specExp) < 0)
+ accu <<= -(-iquantizershift - specExp);
+ else
+ accu >>= -iquantizershift - specExp;
+
+ mdctSpectrum[line] = -accu;
+ } else if (quantSpectrum[line] > 0) {
+ FIXP_DBL accu;
+ INT ex, specExp, tabIndex;
+ FIXP_DBL s, t;
+
+ accu = (FIXP_DBL)(INT)quantSpectrum[line];
+
+ ex = CountLeadingBits(accu);
+ accu <<= ex;
+ specExp = (DFRACT_BITS - 1) - ex;
+
+ FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */
+
+ tabIndex = (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE);
+
+ /* calculate "mantissa" ^4/3 */
+ s = FDKaacEnc_mTab_4_3Elc[tabIndex];
+
+ /* get approperiate exponent multiplier for specExp^3/4 combined with
+ * scfMod */
+ t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp];
+
+ /* multiply "mantissa" ^4/3 with exponent multiplier */
+ accu = fMult(s, t);
+
+ /* get approperiate exponent shifter */
+ specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp] -
+ 1; /* -1 to avoid overflows in accu */
+
+ if ((-iquantizershift - specExp) < 0)
+ accu <<= -(-iquantizershift - specExp);
+ else
+ accu >>= -iquantizershift - specExp;
+
+ mdctSpectrum[line] = accu;
+ } else {
+ mdctSpectrum[line] = FL2FXCONST_DBL(0.0f);
+ }
+ }
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_QuantizeSpectrum
+ description: quantizes the entire spectrum
+ returns:
+ input: number of scalefactor bands to be quantized, ...
+ output: quantized spectrum
+
+*****************************************************************************/
+void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, INT maxSfbPerGroup, INT sfbPerGroup,
+ const INT *sfbOffset,
+ const FIXP_DBL *mdctSpectrum, INT globalGain,
+ const INT *scalefactors,
+ SHORT *quantizedSpectrum,
+ INT dZoneQuantEnable) {
+ INT sfbOffs, sfb;
+
+ /* in FDKaacEnc_quantizeLines quaSpectrum is calculated with:
+ spec^(3/4) * 2^(-3/16*QSS) * 2^(3/4*scale) + k
+ simplify scaling calculation and reduce QSS before:
+ spec^(3/4) * 2^(-3/16*(QSS - 4*scale)) */
+
+ for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup)
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ INT scalefactor = scalefactors[sfbOffs + sfb];
+
+ FDKaacEnc_quantizeLines(
+ globalGain - scalefactor, /* QSS */
+ sfbOffset[sfbOffs + sfb + 1] - sfbOffset[sfbOffs + sfb],
+ mdctSpectrum + sfbOffset[sfbOffs + sfb],
+ quantizedSpectrum + sfbOffset[sfbOffs + sfb], dZoneQuantEnable);
+ }
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_calcSfbDist
+ description: calculates distortion of quantized values
+ returns: distortion
+ input: gain, number of lines to process, spectral data
+ output:
+
+*****************************************************************************/
+FIXP_DBL FDKaacEnc_calcSfbDist(const FIXP_DBL *mdctSpectrum,
+ SHORT *quantSpectrum, INT noOfLines, INT gain,
+ INT dZoneQuantEnable) {
+ INT i, scale;
+ FIXP_DBL xfsf;
+ FIXP_DBL diff;
+ FIXP_DBL invQuantSpec;
+
+ xfsf = FL2FXCONST_DBL(0.0f);
+
+ for (i = 0; i < noOfLines; i++) {
+ /* quantization */
+ FDKaacEnc_quantizeLines(gain, 1, &mdctSpectrum[i], &quantSpectrum[i],
+ dZoneQuantEnable);
+
+ if (fAbs(quantSpectrum[i]) > MAX_QUANT) {
+ return FL2FXCONST_DBL(0.0f);
+ }
+ /* inverse quantization */
+ FDKaacEnc_invQuantizeLines(gain, 1, &quantSpectrum[i], &invQuantSpec);
+
+ /* dist */
+ diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i] >> 1));
+
+ scale = CountLeadingBits(diff);
+ diff = scaleValue(diff, scale);
+ diff = fPow2(diff);
+ scale = fixMin(2 * (scale - 1), DFRACT_BITS - 1);
+
+ diff = scaleValue(diff, -scale);
+
+ xfsf = xfsf + diff;
+ }
+
+ xfsf = CalcLdData(xfsf);
+
+ return xfsf;
+}
+
+/*****************************************************************************
+
+ functionname: FDKaacEnc_calcSfbQuantEnergyAndDist
+ description: calculates energy and distortion of quantized values
+ returns:
+ input: gain, number of lines to process, quantized spectral data,
+ spectral data
+ output: energy, distortion
+
+*****************************************************************************/
+void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum,
+ SHORT *quantSpectrum, INT noOfLines,
+ INT gain, FIXP_DBL *en,
+ FIXP_DBL *dist) {
+ INT i, scale;
+ FIXP_DBL invQuantSpec;
+ FIXP_DBL diff;
+
+ FIXP_DBL energy = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL distortion = FL2FXCONST_DBL(0.0f);
+
+ for (i = 0; i < noOfLines; i++) {
+ if (fAbs(quantSpectrum[i]) > MAX_QUANT) {
+ *en = FL2FXCONST_DBL(0.0f);
+ *dist = FL2FXCONST_DBL(0.0f);
+ return;
+ }
+
+ /* inverse quantization */
+ FDKaacEnc_invQuantizeLines(gain, 1, &quantSpectrum[i], &invQuantSpec);
+
+ /* energy */
+ energy += fPow2(invQuantSpec);
+
+ /* dist */
+ diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i] >> 1));
+
+ scale = CountLeadingBits(diff);
+ diff = scaleValue(diff, scale);
+ diff = fPow2(diff);
+
+ scale = fixMin(2 * (scale - 1), DFRACT_BITS - 1);
+
+ diff = scaleValue(diff, -scale);
+
+ distortion += diff;
+ }
+
+ *en = CalcLdData(energy) + FL2FXCONST_DBL(0.03125f);
+ *dist = CalcLdData(distortion);
+}
diff --git a/fdk-aac/libAACenc/src/quantize.h b/fdk-aac/libAACenc/src/quantize.h
new file mode 100644
index 0000000..dfc2206
--- /dev/null
+++ b/fdk-aac/libAACenc/src/quantize.h
@@ -0,0 +1,127 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Quantization
+
+*******************************************************************************/
+
+#ifndef QUANTIZE_H
+#define QUANTIZE_H
+
+#include "common_fix.h"
+
+/* quantizing */
+
+#define MAX_QUANT 8191
+
+void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, INT maxSfbPerGroup, INT sfbPerGroup,
+ const INT *sfbOffset,
+ const FIXP_DBL *mdctSpectrum, INT globalGain,
+ const INT *scalefactors,
+ SHORT *quantizedSpectrum, INT dZoneQuantEnable);
+
+FIXP_DBL FDKaacEnc_calcSfbDist(const FIXP_DBL *mdctSpectrum,
+ SHORT *quantSpectrum, INT noOfLines, INT gain,
+ INT dZoneQuantEnable);
+
+void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum,
+ SHORT *quantSpectrum, INT noOfLines,
+ INT gain, FIXP_DBL *en,
+ FIXP_DBL *dist);
+
+#endif /* QUANTIZE_H */
diff --git a/fdk-aac/libAACenc/src/sf_estim.cpp b/fdk-aac/libAACenc/src/sf_estim.cpp
new file mode 100644
index 0000000..17a8ae2
--- /dev/null
+++ b/fdk-aac/libAACenc/src/sf_estim.cpp
@@ -0,0 +1,1292 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Scale factor estimation
+
+*******************************************************************************/
+
+#include "sf_estim.h"
+#include "aacEnc_rom.h"
+#include "quantize.h"
+#include "bit_cnt.h"
+
+#ifdef __arm__
+#endif
+
+#define UPCOUNT_LIMIT 1
+#define AS_PE_FAC_SHIFT 7
+#define DIST_FAC_SHIFT 3
+#define AS_PE_FAC_FLOAT (float)(1 << AS_PE_FAC_SHIFT)
+static const INT MAX_SCF_DELTA = 60;
+
+static const FIXP_DBL PE_C1 = FL2FXCONST_DBL(
+ 3.0f / AS_PE_FAC_FLOAT); /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */
+static const FIXP_DBL PE_C2 = FL2FXCONST_DBL(
+ 1.3219281f / AS_PE_FAC_FLOAT); /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */
+static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f); /* 1-C2/C1 */
+
+/*
+ Function; FDKaacEnc_FDKaacEnc_CalcFormFactorChannel
+
+ Description: Calculates the formfactor
+
+ sf: scale factor of the mdct spectrum
+ sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) *
+ (2^FORM_FAC_SHIFT))
+*/
+static void FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(
+ FIXP_DBL *RESTRICT sfbFormFactorLdData,
+ PSY_OUT_CHANNEL *RESTRICT psyOutChan) {
+ INT j, sfb, sfbGrp;
+ FIXP_DBL formFactor;
+
+ int tmp0 = psyOutChan->sfbCnt;
+ int tmp1 = psyOutChan->maxSfbPerGroup;
+ int step = psyOutChan->sfbPerGroup;
+ for (sfbGrp = 0; sfbGrp < tmp0; sfbGrp += step) {
+ for (sfb = 0; sfb < tmp1; sfb++) {
+ formFactor = FL2FXCONST_DBL(0.0f);
+ /* calc sum of sqrt(spec) */
+ for (j = psyOutChan->sfbOffsets[sfbGrp + sfb];
+ j < psyOutChan->sfbOffsets[sfbGrp + sfb + 1]; j++) {
+ formFactor +=
+ sqrtFixp(fixp_abs(psyOutChan->mdctSpectrum[j])) >> FORM_FAC_SHIFT;
+ }
+ sfbFormFactorLdData[sfbGrp + sfb] = CalcLdData(formFactor);
+ }
+ /* set sfbFormFactor for sfbs with zero spec to zero. Just for debugging. */
+ for (; sfb < psyOutChan->sfbPerGroup; sfb++) {
+ sfbFormFactorLdData[sfbGrp + sfb] = FL2FXCONST_DBL(-1.0f);
+ }
+ }
+}
+
+/*
+ Function: FDKaacEnc_CalcFormFactor
+
+ Description: Calls FDKaacEnc_FDKaacEnc_CalcFormFactorChannel() for each
+ channel
+*/
+
+void FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)],
+ PSY_OUT_CHANNEL *psyOutChannel[(2)],
+ const INT nChannels) {
+ INT j;
+ for (j = 0; j < nChannels; j++) {
+ FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(
+ qcOutChannel[j]->sfbFormFactorLdData, psyOutChannel[j]);
+ }
+}
+
+/*
+ Function: FDKaacEnc_calcSfbRelevantLines
+
+ Description: Calculates sfbNRelevantLines
+
+ sfbNRelevantLines is scaled with the factor 1/((2^FORM_FAC_SHIFT) * 2.0)
+*/
+static void FDKaacEnc_calcSfbRelevantLines(
+ const FIXP_DBL *const sfbFormFactorLdData,
+ const FIXP_DBL *const sfbEnergyLdData,
+ const FIXP_DBL *const sfbThresholdLdData, const INT *const sfbOffsets,
+ const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup,
+ FIXP_DBL *sfbNRelevantLines) {
+ INT sfbOffs, sfb;
+ FIXP_DBL sfbWidthLdData;
+ FIXP_DBL asPeFacLdData =
+ FL2FXCONST_DBL(0.109375); /* AS_PE_FAC_SHIFT*ld64(2) */
+ FIXP_DBL accu;
+
+ /* sfbNRelevantLines[i] = 2^( (sfbFormFactorLdData[i] - 0.25 *
+ * (sfbEnergyLdData[i] - ld64(sfbWidth[i]/(2^7)) - AS_PE_FAC_SHIFT*ld64(2)) *
+ * 64); */
+
+ FDKmemclear(sfbNRelevantLines, sfbCnt * sizeof(FIXP_DBL));
+
+ for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup) {
+ for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
+ /* calc sum of sqrt(spec) */
+ if ((FIXP_DBL)sfbEnergyLdData[sfbOffs + sfb] >
+ (FIXP_DBL)sfbThresholdLdData[sfbOffs + sfb]) {
+ INT sfbWidth =
+ sfbOffsets[sfbOffs + sfb + 1] - sfbOffsets[sfbOffs + sfb];
+
+ /* avgFormFactorLdData =
+ * sqrtFixp(sqrtFixp(sfbEnergyLdData[sfbOffs+sfb]/sfbWidth)); */
+ /* sfbNRelevantLines[sfbOffs+sfb] = sfbFormFactor[sfbOffs+sfb] /
+ * avgFormFactorLdData; */
+ sfbWidthLdData =
+ (FIXP_DBL)(sfbWidth << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
+ sfbWidthLdData = CalcLdData(sfbWidthLdData);
+
+ accu = sfbEnergyLdData[sfbOffs + sfb] - sfbWidthLdData - asPeFacLdData;
+ accu = sfbFormFactorLdData[sfbOffs + sfb] - (accu >> 2);
+
+ sfbNRelevantLines[sfbOffs + sfb] = CalcInvLdData(accu) >> 1;
+ }
+ }
+ }
+}
+
+/*
+ Function: FDKaacEnc_countSingleScfBits
+
+ Description:
+
+ scfBitsFract is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
+*/
+static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft,
+ INT scfRight) {
+ FIXP_DBL scfBitsFract;
+
+ scfBitsFract = (FIXP_DBL)(FDKaacEnc_bitCountScalefactorDelta(scfLeft - scf) +
+ FDKaacEnc_bitCountScalefactorDelta(scf - scfRight));
+
+ scfBitsFract = scfBitsFract << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT));
+
+ return scfBitsFract; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
+}
+
+/*
+ Function: FDKaacEnc_calcSingleSpecPe
+
+ specPe is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
+*/
+static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart,
+ FIXP_DBL nLines) {
+ FIXP_DBL specPe = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL ldRatio;
+ FIXP_DBL scfFract;
+
+ scfFract = (FIXP_DBL)(scf << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
+
+ ldRatio = sfbConstPePart - fMult(FL2FXCONST_DBL(0.375f), scfFract);
+
+ if (ldRatio >= PE_C1) {
+ specPe = fMult(FL2FXCONST_DBL(0.7f), fMult(nLines, ldRatio));
+ } else {
+ specPe = fMult(FL2FXCONST_DBL(0.7f),
+ fMult(nLines, (PE_C2 + fMult(PE_C3, ldRatio))));
+ }
+
+ return specPe; /* output scaled by 1/(2^(2*AS_PE_FAC)) */
+}
+
+/*
+ Function: FDKaacEnc_countScfBitsDiff
+
+ scfBitsDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
+*/
+static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, INT *scfNew, INT sfbCnt,
+ INT startSfb, INT stopSfb) {
+ FIXP_DBL scfBitsFract;
+ INT scfBitsDiff = 0;
+ INT sfb = 0, sfbLast;
+ INT sfbPrev, sfbNext;
+
+ /* search for first relevant sfb */
+ sfbLast = startSfb;
+ while ((sfbLast < stopSfb) && (scfOld[sfbLast] == FDK_INT_MIN)) sfbLast++;
+ /* search for previous relevant sfb and count diff */
+ sfbPrev = startSfb - 1;
+ while ((sfbPrev >= 0) && (scfOld[sfbPrev] == FDK_INT_MIN)) sfbPrev--;
+ if (sfbPrev >= 0)
+ scfBitsDiff +=
+ FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) -
+ FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]);
+ /* now loop through all sfbs and count diffs of relevant sfbs */
+ for (sfb = sfbLast + 1; sfb < stopSfb; sfb++) {
+ if (scfOld[sfb] != FDK_INT_MIN) {
+ scfBitsDiff +=
+ FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfb]) -
+ FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfb]);
+ sfbLast = sfb;
+ }
+ }
+ /* search for next relevant sfb and count diff */
+ sfbNext = stopSfb;
+ while ((sfbNext < sfbCnt) && (scfOld[sfbNext] == FDK_INT_MIN)) sfbNext++;
+ if (sfbNext < sfbCnt)
+ scfBitsDiff +=
+ FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfbNext]) -
+ FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfbNext]);
+
+ scfBitsFract =
+ (FIXP_DBL)(scfBitsDiff << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT)));
+
+ return scfBitsFract;
+}
+
+/*
+ Function: FDKaacEnc_calcSpecPeDiff
+
+ specPeDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT))
+*/
+static FIXP_DBL FDKaacEnc_calcSpecPeDiff(
+ PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, INT *scfOld,
+ INT *scfNew, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
+ FIXP_DBL *sfbNRelevantLines, INT startSfb, INT stopSfb) {
+ FIXP_DBL specPeDiff = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL scfFract = FL2FXCONST_DBL(0.0f);
+ INT sfb;
+
+ /* loop through all sfbs and count pe difference */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfOld[sfb] != FDK_INT_MIN) {
+ FIXP_DBL ldRatioOld, ldRatioNew, pOld, pNew;
+
+ /* sfbConstPePart[sfb] = (float)log(psyOutChan->sfbEnergy[sfb] * 6.75f /
+ * sfbFormFactor[sfb]) * LOG2_1; */
+ /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for
+ * log2 */
+ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
+ if (sfbConstPePart[sfb] == (FIXP_DBL)FDK_INT_MIN)
+ sfbConstPePart[sfb] =
+ ((psyOutChan->sfbEnergyLdData[sfb] - sfbFormFactorLdData[sfb] -
+ FL2FXCONST_DBL(0.09375f)) >>
+ 1) +
+ FL2FXCONST_DBL(0.02152255861f);
+
+ scfFract = (FIXP_DBL)(scfOld[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
+ ldRatioOld =
+ sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract);
+
+ scfFract = (FIXP_DBL)(scfNew[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT));
+ ldRatioNew =
+ sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract);
+
+ if (ldRatioOld >= PE_C1)
+ pOld = ldRatioOld;
+ else
+ pOld = PE_C2 + fMult(PE_C3, ldRatioOld);
+
+ if (ldRatioNew >= PE_C1)
+ pNew = ldRatioNew;
+ else
+ pNew = PE_C2 + fMult(PE_C3, ldRatioNew);
+
+ specPeDiff += fMult(FL2FXCONST_DBL(0.7f),
+ fMult(sfbNRelevantLines[sfb], (pNew - pOld)));
+ }
+ }
+
+ return specPeDiff;
+}
+
+/*
+ Function: FDKaacEnc_improveScf
+
+ Description: Calculate the distortion by quantization and inverse quantization
+ of the spectrum with various scalefactors. The scalefactor which provides the
+ best results will be used.
+*/
+static INT FDKaacEnc_improveScf(const FIXP_DBL *spec, SHORT *quantSpec,
+ SHORT *quantSpecTmp, INT sfbWidth,
+ FIXP_DBL threshLdData, INT scf, INT minScf,
+ FIXP_DBL *distLdData, INT *minScfCalculated,
+ INT dZoneQuantEnable) {
+ FIXP_DBL sfbDistLdData;
+ INT scfBest = scf;
+ INT k;
+ FIXP_DBL distFactorLdData = FL2FXCONST_DBL(-0.0050301265); /* ld64(1/1.25) */
+
+ /* calc real distortion */
+ sfbDistLdData =
+ FDKaacEnc_calcSfbDist(spec, quantSpec, sfbWidth, scf, dZoneQuantEnable);
+ *minScfCalculated = scf;
+ /* nmr > 1.25 -> try to improve nmr */
+ if (sfbDistLdData > (threshLdData - distFactorLdData)) {
+ INT scfEstimated = scf;
+ FIXP_DBL sfbDistBestLdData = sfbDistLdData;
+ INT cnt;
+ /* improve by bigger scf ? */
+ cnt = 0;
+
+ while ((sfbDistLdData > (threshLdData - distFactorLdData)) &&
+ (cnt++ < UPCOUNT_LIMIT)) {
+ scf++;
+ sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
+ dZoneQuantEnable);
+
+ if (sfbDistLdData < sfbDistBestLdData) {
+ scfBest = scf;
+ sfbDistBestLdData = sfbDistLdData;
+ for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
+ }
+ }
+ /* improve by smaller scf ? */
+ cnt = 0;
+ scf = scfEstimated;
+ sfbDistLdData = sfbDistBestLdData;
+ while ((sfbDistLdData > (threshLdData - distFactorLdData)) && (cnt++ < 1) &&
+ (scf > minScf)) {
+ scf--;
+ sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
+ dZoneQuantEnable);
+
+ if (sfbDistLdData < sfbDistBestLdData) {
+ scfBest = scf;
+ sfbDistBestLdData = sfbDistLdData;
+ for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
+ }
+ *minScfCalculated = scf;
+ }
+ *distLdData = sfbDistBestLdData;
+ } else { /* nmr <= 1.25 -> try to find bigger scf to use less bits */
+ FIXP_DBL sfbDistBestLdData = sfbDistLdData;
+ FIXP_DBL sfbDistAllowedLdData =
+ fixMin(sfbDistLdData - distFactorLdData, threshLdData);
+ int cnt;
+ for (cnt = 0; cnt < UPCOUNT_LIMIT; cnt++) {
+ scf++;
+ sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf,
+ dZoneQuantEnable);
+
+ if (sfbDistLdData < sfbDistAllowedLdData) {
+ *minScfCalculated = scfBest + 1;
+ scfBest = scf;
+ sfbDistBestLdData = sfbDistLdData;
+ for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k];
+ }
+ }
+ *distLdData = sfbDistBestLdData;
+ }
+
+ /* return best scalefactor */
+ return scfBest;
+}
+
+/*
+ Function: FDKaacEnc_assimilateSingleScf
+
+*/
+static void FDKaacEnc_assimilateSingleScf(
+ const PSY_OUT_CHANNEL *psyOutChan, const QC_OUT_CHANNEL *qcOutChannel,
+ SHORT *quantSpec, SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf,
+ const INT *minScf, FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart,
+ const FIXP_DBL *sfbFormFactorLdData, const FIXP_DBL *sfbNRelevantLines,
+ INT *minScfCalculated, INT restartOnSuccess) {
+ INT sfbLast, sfbAct, sfbNext;
+ INT scfAct, *scfLast, *scfNext, scfMin, scfMax;
+ INT sfbWidth, sfbOffs;
+ FIXP_DBL enLdData;
+ FIXP_DBL sfbPeOld, sfbPeNew;
+ FIXP_DBL sfbDistNew;
+ INT i, k;
+ INT success = 0;
+ FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL deltaPeNew, deltaPeTmp;
+ INT prevScfLast[MAX_GROUPED_SFB], prevScfNext[MAX_GROUPED_SFB];
+ FIXP_DBL deltaPeLast[MAX_GROUPED_SFB];
+ INT updateMinScfCalculated;
+
+ for (i = 0; i < psyOutChan->sfbCnt; i++) {
+ prevScfLast[i] = FDK_INT_MAX;
+ prevScfNext[i] = FDK_INT_MAX;
+ deltaPeLast[i] = (FIXP_DBL)FDK_INT_MAX;
+ }
+
+ sfbLast = -1;
+ sfbAct = -1;
+ sfbNext = -1;
+ scfLast = 0;
+ scfNext = 0;
+ scfMin = FDK_INT_MAX;
+ scfMax = FDK_INT_MAX;
+ do {
+ /* search for new relevant sfb */
+ sfbNext++;
+ while ((sfbNext < psyOutChan->sfbCnt) && (scf[sfbNext] == FDK_INT_MIN))
+ sfbNext++;
+ if ((sfbLast >= 0) && (sfbAct >= 0) && (sfbNext < psyOutChan->sfbCnt)) {
+ /* relevant scfs to the left and to the right */
+ scfAct = scf[sfbAct];
+ scfLast = scf + sfbLast;
+ scfNext = scf + sfbNext;
+ scfMin = fixMin(*scfLast, *scfNext);
+ scfMax = fixMax(*scfLast, *scfNext);
+ } else if ((sfbLast == -1) && (sfbAct >= 0) &&
+ (sfbNext < psyOutChan->sfbCnt)) {
+ /* first relevant scf */
+ scfAct = scf[sfbAct];
+ scfLast = &scfAct;
+ scfNext = scf + sfbNext;
+ scfMin = *scfNext;
+ scfMax = *scfNext;
+ } else if ((sfbLast >= 0) && (sfbAct >= 0) &&
+ (sfbNext == psyOutChan->sfbCnt)) {
+ /* last relevant scf */
+ scfAct = scf[sfbAct];
+ scfLast = scf + sfbLast;
+ scfNext = &scfAct;
+ scfMin = *scfLast;
+ scfMax = *scfLast;
+ }
+ if (sfbAct >= 0) scfMin = fixMax(scfMin, minScf[sfbAct]);
+
+ if ((sfbAct >= 0) && (sfbLast >= 0 || sfbNext < psyOutChan->sfbCnt) &&
+ (scfAct > scfMin) && (scfAct <= scfMin + MAX_SCF_DELTA) &&
+ (scfAct >= scfMax - MAX_SCF_DELTA) &&
+ (scfAct <=
+ fixMin(scfMin, fixMin(*scfLast, *scfNext)) + MAX_SCF_DELTA) &&
+ (*scfLast != prevScfLast[sfbAct] || *scfNext != prevScfNext[sfbAct] ||
+ deltaPe < deltaPeLast[sfbAct])) {
+ /* bigger than neighbouring scf found, try to use smaller scf */
+ success = 0;
+
+ sfbWidth =
+ psyOutChan->sfbOffsets[sfbAct + 1] - psyOutChan->sfbOffsets[sfbAct];
+ sfbOffs = psyOutChan->sfbOffsets[sfbAct];
+
+ /* estimate required bits for actual scf */
+ enLdData = qcOutChannel->sfbEnergyLdData[sfbAct];
+
+ /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) *
+ * LOG2_1; */
+ /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for
+ * log2 */
+ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
+ if (sfbConstPePart[sfbAct] == (FIXP_DBL)FDK_INT_MIN) {
+ sfbConstPePart[sfbAct] = ((enLdData - sfbFormFactorLdData[sfbAct] -
+ FL2FXCONST_DBL(0.09375f)) >>
+ 1) +
+ FL2FXCONST_DBL(0.02152255861f);
+ }
+
+ sfbPeOld = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct],
+ sfbNRelevantLines[sfbAct]) +
+ FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext);
+
+ deltaPeNew = deltaPe;
+ updateMinScfCalculated = 1;
+
+ do {
+ /* estimate required bits for smaller scf */
+ scfAct--;
+ /* check only if the same check was not done before */
+ if (scfAct < minScfCalculated[sfbAct] &&
+ scfAct >= scfMax - MAX_SCF_DELTA) {
+ /* estimate required bits for new scf */
+ sfbPeNew = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct],
+ sfbNRelevantLines[sfbAct]) +
+ FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext);
+
+ /* use new scf if no increase in pe and
+ quantization error is smaller */
+ deltaPeTmp = deltaPe + sfbPeNew - sfbPeOld;
+ /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
+ if (deltaPeTmp < FL2FXCONST_DBL(0.0006103515625f)) {
+ /* distortion of new scf */
+ sfbDistNew = FDKaacEnc_calcSfbDist(
+ qcOutChannel->mdctSpectrum + sfbOffs, quantSpecTmp + sfbOffs,
+ sfbWidth, scfAct, dZoneQuantEnable);
+
+ if (sfbDistNew < sfbDist[sfbAct]) {
+ /* success, replace scf by new one */
+ scf[sfbAct] = scfAct;
+ sfbDist[sfbAct] = sfbDistNew;
+
+ for (k = 0; k < sfbWidth; k++)
+ quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k];
+
+ deltaPeNew = deltaPeTmp;
+ success = 1;
+ }
+ /* mark as already checked */
+ if (updateMinScfCalculated) minScfCalculated[sfbAct] = scfAct;
+ } else {
+ /* from this scf value on not all new values have been checked */
+ updateMinScfCalculated = 0;
+ }
+ }
+ } while (scfAct > scfMin);
+
+ deltaPe = deltaPeNew;
+
+ /* save parameters to avoid multiple computations of the same sfb */
+ prevScfLast[sfbAct] = *scfLast;
+ prevScfNext[sfbAct] = *scfNext;
+ deltaPeLast[sfbAct] = deltaPe;
+ }
+
+ if (success && restartOnSuccess) {
+ /* start again at first sfb */
+ sfbLast = -1;
+ sfbAct = -1;
+ sfbNext = -1;
+ scfLast = 0;
+ scfNext = 0;
+ scfMin = FDK_INT_MAX;
+ scfMax = FDK_INT_MAX;
+ success = 0;
+ } else {
+ /* shift sfbs for next band */
+ sfbLast = sfbAct;
+ sfbAct = sfbNext;
+ }
+ } while (sfbNext < psyOutChan->sfbCnt);
+}
+
+/*
+ Function: FDKaacEnc_assimilateMultipleScf
+
+*/
+static void FDKaacEnc_assimilateMultipleScf(
+ PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec,
+ SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf,
+ FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
+ FIXP_DBL *sfbNRelevantLines) {
+ INT sfb, startSfb, stopSfb;
+ INT scfTmp[MAX_GROUPED_SFB], scfMin, scfMax, scfAct;
+ INT possibleRegionFound;
+ INT sfbWidth, sfbOffs, i, k;
+ FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], distOldSum, distNewSum;
+ INT deltaScfBits;
+ FIXP_DBL deltaSpecPe;
+ FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL deltaPeNew;
+ INT sfbCnt = psyOutChan->sfbCnt;
+
+ /* calc min and max scalfactors */
+ scfMin = FDK_INT_MAX;
+ scfMax = FDK_INT_MIN;
+ for (sfb = 0; sfb < sfbCnt; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ scfMin = fixMin(scfMin, scf[sfb]);
+ scfMax = fixMax(scfMax, scf[sfb]);
+ }
+ }
+
+ if (scfMax != FDK_INT_MIN && scfMax <= scfMin + MAX_SCF_DELTA) {
+ scfAct = scfMax;
+
+ do {
+ /* try smaller scf */
+ scfAct--;
+ for (i = 0; i < MAX_GROUPED_SFB; i++) scfTmp[i] = scf[i];
+ stopSfb = 0;
+ do {
+ /* search for region where all scfs are bigger than scfAct */
+ sfb = stopSfb;
+ while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] <= scfAct))
+ sfb++;
+ startSfb = sfb;
+ sfb++;
+ while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] > scfAct))
+ sfb++;
+ stopSfb = sfb;
+
+ /* check if in all sfb of a valid region scfAct >= minScf[sfb] */
+ possibleRegionFound = 0;
+ if (startSfb < sfbCnt) {
+ possibleRegionFound = 1;
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN)
+ if (scfAct < minScf[sfb]) {
+ possibleRegionFound = 0;
+ break;
+ }
+ }
+ }
+
+ if (possibleRegionFound) { /* region found */
+
+ /* replace scfs in region by scfAct */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfAct;
+ }
+
+ /* estimate change in bit demand for new scfs */
+ deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
+ startSfb, stopSfb);
+
+ deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
+ psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
+
+ deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
+
+ /* new bit demand small enough ? */
+ /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */
+ if (deltaPeNew < FL2FXCONST_DBL(0.0006103515625f)) {
+ /* quantize and calc sum of new distortion */
+ distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) {
+ distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
+
+ sfbWidth = psyOutChan->sfbOffsets[sfb + 1] -
+ psyOutChan->sfbOffsets[sfb];
+ sfbOffs = psyOutChan->sfbOffsets[sfb];
+
+ sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
+ qcOutChannel->mdctSpectrum + sfbOffs,
+ quantSpecTmp + sfbOffs, sfbWidth, scfAct, dZoneQuantEnable);
+
+ if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
+ /* no improvement, skip further dist. calculations */
+ distNewSum = distOldSum << 1;
+ break;
+ }
+ distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
+ }
+ }
+ /* distortion smaller ? -> use new scalefactors */
+ if (distNewSum < distOldSum) {
+ deltaPe = deltaPeNew;
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ sfbWidth = psyOutChan->sfbOffsets[sfb + 1] -
+ psyOutChan->sfbOffsets[sfb];
+ sfbOffs = psyOutChan->sfbOffsets[sfb];
+ scf[sfb] = scfAct;
+ sfbDist[sfb] = sfbDistNew[sfb];
+
+ for (k = 0; k < sfbWidth; k++)
+ quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k];
+ }
+ }
+ }
+ }
+ }
+
+ } while (stopSfb <= sfbCnt);
+
+ } while (scfAct > scfMin);
+ }
+}
+
+/*
+ Function: FDKaacEnc_FDKaacEnc_assimilateMultipleScf2
+
+*/
+static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(
+ PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec,
+ SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf,
+ FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData,
+ FIXP_DBL *sfbNRelevantLines) {
+ INT sfb, startSfb, stopSfb;
+ INT scfTmp[MAX_GROUPED_SFB], scfAct, scfNew;
+ INT scfPrev, scfNext, scfPrevNextMin, scfPrevNextMax, scfLo, scfHi;
+ INT scfMin, scfMax;
+ INT *sfbOffs = psyOutChan->sfbOffsets;
+ FIXP_DBL sfbDistNew[MAX_GROUPED_SFB], sfbDistMax[MAX_GROUPED_SFB];
+ FIXP_DBL distOldSum, distNewSum;
+ INT deltaScfBits;
+ FIXP_DBL deltaSpecPe;
+ FIXP_DBL deltaPe = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL deltaPeNew = FL2FXCONST_DBL(0.0f);
+ INT sfbCnt = psyOutChan->sfbCnt;
+ INT bSuccess, bCheckScf;
+ INT i, k;
+
+ /* calc min and max scalfactors */
+ scfMin = FDK_INT_MAX;
+ scfMax = FDK_INT_MIN;
+ for (sfb = 0; sfb < sfbCnt; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ scfMin = fixMin(scfMin, scf[sfb]);
+ scfMax = fixMax(scfMax, scf[sfb]);
+ }
+ }
+
+ stopSfb = 0;
+ scfAct = FDK_INT_MIN;
+ do {
+ /* search for region with same scf values scfAct */
+ scfPrev = scfAct;
+
+ sfb = stopSfb;
+ while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN)) sfb++;
+ startSfb = sfb;
+ scfAct = scf[startSfb];
+ sfb++;
+ while (sfb < sfbCnt &&
+ ((scf[sfb] == FDK_INT_MIN) || (scf[sfb] == scf[startSfb])))
+ sfb++;
+ stopSfb = sfb;
+
+ if (stopSfb < sfbCnt)
+ scfNext = scf[stopSfb];
+ else
+ scfNext = scfAct;
+
+ if (scfPrev == FDK_INT_MIN) scfPrev = scfAct;
+
+ scfPrevNextMax = fixMax(scfPrev, scfNext);
+ scfPrevNextMin = fixMin(scfPrev, scfNext);
+
+ /* try to reduce bits by checking scf values in the range
+ scf[startSfb]...scfHi */
+ scfHi = fixMax(scfPrevNextMax, scfAct);
+ /* try to find a better solution by reducing the scf difference to
+ the nearest possible lower scf */
+ if (scfPrevNextMax >= scfAct)
+ scfLo = fixMin(scfAct, scfPrevNextMin);
+ else
+ scfLo = scfPrevNextMax;
+
+ if (startSfb < sfbCnt &&
+ scfHi - scfLo <= MAX_SCF_DELTA) { /* region found */
+ /* 1. try to save bits by coarser quantization */
+ if (scfHi > scf[startSfb]) {
+ /* calculate the allowed distortion */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ /* sfbDistMax[sfb] =
+ * (float)pow(qcOutChannel->sfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f);
+ */
+ /* sfbDistMax[sfb] =
+ * fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f));
+ */
+ /* -0.15571537944 = ld64(1.e-3f)*/
+ sfbDistMax[sfb] = fMult(FL2FXCONST_DBL(1.0f / 3.0f),
+ qcOutChannel->sfbThresholdLdData[sfb]) +
+ fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]) +
+ fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]);
+ sfbDistMax[sfb] =
+ fixMax(sfbDistMax[sfb], qcOutChannel->sfbEnergyLdData[sfb] -
+ FL2FXCONST_DBL(0.15571537944));
+ sfbDistMax[sfb] =
+ fixMin(sfbDistMax[sfb], qcOutChannel->sfbThresholdLdData[sfb]);
+ }
+ }
+
+ /* loop over all possible scf values for this region */
+ bCheckScf = 1;
+ for (scfNew = scf[startSfb] + 1; scfNew <= scfHi; scfNew++) {
+ for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k];
+
+ /* replace scfs in region by scfNew */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew;
+ }
+
+ /* estimate change in bit demand for new scfs */
+ deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
+ startSfb, stopSfb);
+
+ deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
+ psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
+
+ deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
+
+ /* new bit demand small enough ? */
+ if (deltaPeNew < FL2FXCONST_DBL(0.0f)) {
+ bSuccess = 1;
+
+ /* quantize and calc sum of new distortion */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) {
+ sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
+ qcOutChannel->mdctSpectrum + sfbOffs[sfb],
+ quantSpecTmp + sfbOffs[sfb],
+ sfbOffs[sfb + 1] - sfbOffs[sfb], scfNew, dZoneQuantEnable);
+
+ if (sfbDistNew[sfb] > sfbDistMax[sfb]) {
+ /* no improvement, skip further dist. calculations */
+ bSuccess = 0;
+ if (sfbDistNew[sfb] == qcOutChannel->sfbEnergyLdData[sfb]) {
+ /* if whole sfb is already quantized to 0, further
+ checks with even coarser quant. are useless*/
+ bCheckScf = 0;
+ }
+ break;
+ }
+ }
+ }
+ if (bCheckScf == 0) /* further calculations useless ? */
+ break;
+ /* distortion small enough ? -> use new scalefactors */
+ if (bSuccess) {
+ deltaPe = deltaPeNew;
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ scf[sfb] = scfNew;
+ sfbDist[sfb] = sfbDistNew[sfb];
+
+ for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++)
+ quantSpec[sfbOffs[sfb] + k] =
+ quantSpecTmp[sfbOffs[sfb] + k];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* 2. only if coarser quantization was not successful, try to find
+ a better solution by finer quantization and reducing bits for
+ scalefactor coding */
+ if (scfAct == scf[startSfb] && scfLo < scfAct &&
+ scfMax - scfMin <= MAX_SCF_DELTA) {
+ int bminScfViolation = 0;
+
+ for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k];
+
+ scfNew = scfLo;
+
+ /* replace scfs in region by scfNew and
+ check if in all sfb scfNew >= minScf[sfb] */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) {
+ scfTmp[sfb] = scfNew;
+ if (scfNew < minScf[sfb]) bminScfViolation = 1;
+ }
+ }
+
+ if (!bminScfViolation) {
+ /* estimate change in bit demand for new scfs */
+ deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
+ startSfb, stopSfb);
+
+ deltaSpecPe = FDKaacEnc_calcSpecPeDiff(
+ psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb);
+
+ deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe;
+ }
+
+ /* new bit demand small enough ? */
+ if (!bminScfViolation && deltaPeNew < FL2FXCONST_DBL(0.0f)) {
+ /* quantize and calc sum of new distortion */
+ distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) {
+ distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
+
+ sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(
+ qcOutChannel->mdctSpectrum + sfbOffs[sfb],
+ quantSpecTmp + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb],
+ scfNew, dZoneQuantEnable);
+
+ if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
+ /* no improvement, skip further dist. calculations */
+ distNewSum = distOldSum << 1;
+ break;
+ }
+ distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
+ }
+ }
+ /* distortion smaller ? -> use new scalefactors */
+ if (distNewSum < fMult(FL2FXCONST_DBL(0.8f), distOldSum)) {
+ deltaPe = deltaPeNew;
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ scf[sfb] = scfNew;
+ sfbDist[sfb] = sfbDistNew[sfb];
+
+ for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++)
+ quantSpec[sfbOffs[sfb] + k] = quantSpecTmp[sfbOffs[sfb] + k];
+ }
+ }
+ }
+ }
+ }
+
+ /* 3. try to find a better solution (save bits) by only reducing the
+ scalefactor without new quantization */
+ if (scfMax - scfMin <=
+ MAX_SCF_DELTA - 3) { /* 3 bec. scf is reduced 3 times,
+ see for loop below */
+
+ for (k = 0; k < sfbCnt; k++) scfTmp[k] = scf[k];
+
+ for (i = 0; i < 3; i++) {
+ scfNew = scfTmp[startSfb] - 1;
+ /* replace scfs in region by scfNew */
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew;
+ }
+ /* estimate change in bit demand for new scfs */
+ deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt,
+ startSfb, stopSfb);
+ deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits;
+ /* new bit demand small enough ? */
+ if (deltaPeNew <= FL2FXCONST_DBL(0.0f)) {
+ bSuccess = 1;
+ distOldSum = distNewSum = FL2FXCONST_DBL(0.0f);
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scfTmp[sfb] != FDK_INT_MIN) {
+ FIXP_DBL sfbEnQ;
+ /* calc the energy and distortion of the quantized spectrum for
+ a smaller scf */
+ FDKaacEnc_calcSfbQuantEnergyAndDist(
+ qcOutChannel->mdctSpectrum + sfbOffs[sfb],
+ quantSpec + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb],
+ scfNew, &sfbEnQ, &sfbDistNew[sfb]);
+
+ distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT;
+ distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT;
+
+ /* 0.00259488556167 = ld64(1.122f) */
+ /* -0.00778722686652 = ld64(0.7079f) */
+ if ((sfbDistNew[sfb] >
+ (sfbDist[sfb] + FL2FXCONST_DBL(0.00259488556167f))) ||
+ (sfbEnQ < (qcOutChannel->sfbEnergyLdData[sfb] -
+ FL2FXCONST_DBL(0.00778722686652f)))) {
+ bSuccess = 0;
+ break;
+ }
+ }
+ }
+ /* distortion smaller ? -> use new scalefactors */
+ if (distNewSum < distOldSum && bSuccess) {
+ deltaPe = deltaPeNew;
+ for (sfb = startSfb; sfb < stopSfb; sfb++) {
+ if (scf[sfb] != FDK_INT_MIN) {
+ scf[sfb] = scfNew;
+ sfbDist[sfb] = sfbDistNew[sfb];
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } while (stopSfb <= sfbCnt);
+}
+
+static void FDKaacEnc_EstimateScaleFactorsChannel(
+ QC_OUT_CHANNEL *qcOutChannel, PSY_OUT_CHANNEL *psyOutChannel,
+ INT *RESTRICT scf, INT *RESTRICT globalGain,
+ FIXP_DBL *RESTRICT sfbFormFactorLdData, const INT invQuant,
+ SHORT *RESTRICT quantSpec, const INT dZoneQuantEnable) {
+ INT i, j, sfb, sfbOffs;
+ INT scfInt;
+ INT maxSf;
+ INT minSf;
+ FIXP_DBL threshLdData;
+ FIXP_DBL energyLdData;
+ FIXP_DBL energyPartLdData;
+ FIXP_DBL thresholdPartLdData;
+ FIXP_DBL scfFract;
+ FIXP_DBL maxSpec;
+ INT minScfCalculated[MAX_GROUPED_SFB];
+ FIXP_DBL sfbDistLdData[MAX_GROUPED_SFB];
+ C_ALLOC_SCRATCH_START(quantSpecTmp, SHORT, (1024))
+ INT minSfMaxQuant[MAX_GROUPED_SFB];
+
+ FIXP_DBL threshConstLdData =
+ FL2FXCONST_DBL(0.04304511722f); /* log10(6.75)/log10(2.0)/64.0 */
+ FIXP_DBL convConst = FL2FXCONST_DBL(0.30102999566f); /* log10(2.0) */
+ FIXP_DBL c1Const =
+ FL2FXCONST_DBL(-0.27083183594f); /* C1 = -69.33295 => C1/2^8 */
+
+ if (invQuant > 0) {
+ FDKmemclear(quantSpec, (1024) * sizeof(SHORT));
+ }
+
+ /* scfs without energy or with thresh>energy are marked with FDK_INT_MIN */
+ for (i = 0; i < psyOutChannel->sfbCnt; i++) {
+ scf[i] = FDK_INT_MIN;
+ }
+
+ for (i = 0; i < MAX_GROUPED_SFB; i++) {
+ minSfMaxQuant[i] = FDK_INT_MIN;
+ }
+
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ threshLdData = qcOutChannel->sfbThresholdLdData[sfbOffs + sfb];
+ energyLdData = qcOutChannel->sfbEnergyLdData[sfbOffs + sfb];
+
+ sfbDistLdData[sfbOffs + sfb] = energyLdData;
+
+ if (energyLdData > threshLdData) {
+ FIXP_DBL tmp;
+
+ /* energyPart = (float)log10(sfbFormFactor[sfbOffs+sfb]); */
+ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */
+ energyPartLdData =
+ sfbFormFactorLdData[sfbOffs + sfb] + FL2FXCONST_DBL(0.09375f);
+
+ /* influence of allowed distortion */
+ /* thresholdPart = (float)log10(6.75*thresh+FLT_MIN); */
+ thresholdPartLdData = threshConstLdData + threshLdData;
+
+ /* scf calc */
+ /* scfFloat = 8.8585f * (thresholdPart - energyPart); */
+ scfFract = thresholdPartLdData - energyPartLdData;
+ /* conversion from log2 to log10 */
+ scfFract = fMult(convConst, scfFract);
+ /* (8.8585f * scfFract)/8 = 8/8 * scfFract + 0.8585 * scfFract/8 */
+ scfFract = scfFract + fMult(FL2FXCONST_DBL(0.8585f), scfFract >> 3);
+
+ /* integer scalefactor */
+ /* scfInt = (int)floor(scfFloat); */
+ scfInt =
+ (INT)(scfFract >>
+ ((DFRACT_BITS - 1) - 3 -
+ LD_DATA_SHIFT)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */
+
+ /* maximum of spectrum */
+ maxSpec = FL2FXCONST_DBL(0.0f);
+
+ /* Unroll by 4, allow dual memory access */
+ DWORD_ALIGNED(qcOutChannel->mdctSpectrum);
+ for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
+ j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j += 4) {
+ maxSpec = fMax(maxSpec,
+ fMax(fMax(fAbs(qcOutChannel->mdctSpectrum[j + 0]),
+ fAbs(qcOutChannel->mdctSpectrum[j + 1])),
+ fMax(fAbs(qcOutChannel->mdctSpectrum[j + 2]),
+ fAbs(qcOutChannel->mdctSpectrum[j + 3]))));
+ }
+ /* lower scf limit to avoid quantized values bigger than MAX_QUANT */
+ /* C1 = -69.33295f, C2 = 5.77078f = 4/log(2) */
+ /* minSfMaxQuant[sfbOffs+sfb] = (int)ceil(C1 + C2*log(maxSpec)); */
+ /* C1/2^8 + 4/log(2.0)*log(maxSpec)/2^8 => C1/2^8 +
+ * log(maxSpec)/log(2.0)*4/2^8 => C1/2^8 + log(maxSpec)/log(2.0)/64.0 */
+
+ // minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec))
+ // >> ((DFRACT_BITS-1)-8))) + 1;
+ tmp = CalcLdData(maxSpec);
+ if (c1Const > FL2FXCONST_DBL(-1.f) - tmp) {
+ minSfMaxQuant[sfbOffs + sfb] =
+ ((INT)((c1Const + tmp) >> ((DFRACT_BITS - 1) - 8))) + 1;
+ } else {
+ minSfMaxQuant[sfbOffs + sfb] =
+ ((INT)(FL2FXCONST_DBL(-1.f) >> ((DFRACT_BITS - 1) - 8))) + 1;
+ }
+
+ scfInt = fixMax(scfInt, minSfMaxQuant[sfbOffs + sfb]);
+
+ /* find better scalefactor with analysis by synthesis */
+ if (invQuant > 0) {
+ scfInt = FDKaacEnc_improveScf(
+ qcOutChannel->mdctSpectrum +
+ psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ quantSpecTmp + psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] -
+ psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ threshLdData, scfInt, minSfMaxQuant[sfbOffs + sfb],
+ &sfbDistLdData[sfbOffs + sfb], &minScfCalculated[sfbOffs + sfb],
+ dZoneQuantEnable);
+ }
+ scf[sfbOffs + sfb] = scfInt;
+ }
+ }
+ }
+
+ if (invQuant > 0) {
+ /* try to decrease scf differences */
+ FIXP_DBL sfbConstPePart[MAX_GROUPED_SFB];
+ FIXP_DBL sfbNRelevantLines[MAX_GROUPED_SFB];
+
+ for (i = 0; i < psyOutChannel->sfbCnt; i++)
+ sfbConstPePart[i] = (FIXP_DBL)FDK_INT_MIN;
+
+ FDKaacEnc_calcSfbRelevantLines(
+ sfbFormFactorLdData, qcOutChannel->sfbEnergyLdData,
+ qcOutChannel->sfbThresholdLdData, psyOutChannel->sfbOffsets,
+ psyOutChannel->sfbCnt, psyOutChannel->sfbPerGroup,
+ psyOutChannel->maxSfbPerGroup, sfbNRelevantLines);
+
+ FDKaacEnc_assimilateSingleScf(
+ psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, dZoneQuantEnable,
+ scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, sfbFormFactorLdData,
+ sfbNRelevantLines, minScfCalculated, 1);
+
+ if (invQuant > 1) {
+ FDKaacEnc_assimilateMultipleScf(
+ psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
+ dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines);
+
+ FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(
+ psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
+ dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines);
+ }
+ }
+
+ /* get min scalefac */
+ minSf = FDK_INT_MAX;
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ if (scf[sfbOffs + sfb] != FDK_INT_MIN)
+ minSf = fixMin(minSf, scf[sfbOffs + sfb]);
+ }
+ }
+
+ /* limit scf delta */
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ if ((scf[sfbOffs + sfb] != FDK_INT_MIN) &&
+ (minSf + MAX_SCF_DELTA) < scf[sfbOffs + sfb]) {
+ scf[sfbOffs + sfb] = minSf + MAX_SCF_DELTA;
+ if (invQuant > 0) { /* changed bands need to be quantized again */
+ sfbDistLdData[sfbOffs + sfb] = FDKaacEnc_calcSfbDist(
+ qcOutChannel->mdctSpectrum +
+ psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] -
+ psyOutChannel->sfbOffsets[sfbOffs + sfb],
+ scf[sfbOffs + sfb], dZoneQuantEnable);
+ }
+ }
+ }
+ }
+
+ /* get max scalefac for global gain */
+ maxSf = FDK_INT_MIN;
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ maxSf = fixMax(maxSf, scf[sfbOffs + sfb]);
+ }
+ }
+
+ /* calc loop scalefactors, if spec is not all zero (i.e. maxSf == -99) */
+ if (maxSf > FDK_INT_MIN) {
+ *globalGain = maxSf;
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ if (scf[sfbOffs + sfb] == FDK_INT_MIN) {
+ scf[sfbOffs + sfb] = 0;
+ /* set band explicitely to zero */
+ for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
+ j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) {
+ qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
+ }
+ } else {
+ scf[sfbOffs + sfb] = maxSf - scf[sfbOffs + sfb];
+ }
+ }
+ }
+ } else {
+ *globalGain = 0;
+ /* set spectrum explicitely to zero */
+ for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt;
+ sfbOffs += psyOutChannel->sfbPerGroup) {
+ for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) {
+ scf[sfbOffs + sfb] = 0;
+ /* set band explicitely to zero */
+ for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb];
+ j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) {
+ qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f);
+ }
+ }
+ }
+ }
+
+ /* free quantSpecTmp from scratch */
+ C_ALLOC_SCRATCH_END(quantSpecTmp, SHORT, (1024))
+}
+
+void FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
+ QC_OUT_CHANNEL *qcOutChannel[],
+ const INT invQuant,
+ const INT dZoneQuantEnable,
+ const INT nChannels) {
+ int ch;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ FDKaacEnc_EstimateScaleFactorsChannel(
+ qcOutChannel[ch], psyOutChannel[ch], qcOutChannel[ch]->scf,
+ &qcOutChannel[ch]->globalGain, qcOutChannel[ch]->sfbFormFactorLdData,
+ invQuant, qcOutChannel[ch]->quantSpec, dZoneQuantEnable);
+ }
+}
diff --git a/fdk-aac/libAACenc/src/sf_estim.h b/fdk-aac/libAACenc/src/sf_estim.h
new file mode 100644
index 0000000..ab2d3c2
--- /dev/null
+++ b/fdk-aac/libAACenc/src/sf_estim.h
@@ -0,0 +1,124 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Scale factor estimation
+
+*******************************************************************************/
+
+#ifndef SF_ESTIM_H
+#define SF_ESTIM_H
+
+#include "common_fix.h"
+
+#include "psy_const.h"
+#include "qc_data.h"
+#include "interface.h"
+
+#define FORM_FAC_SHIFT 6
+
+void FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)],
+ PSY_OUT_CHANNEL *psyOutChannel[(2)],
+ const INT nChannels);
+
+void FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
+ QC_OUT_CHANNEL *qcOutChannel[],
+ const INT invQuant,
+ const INT dZoneQuantEnable,
+ const INT nChannels);
+
+#endif
diff --git a/fdk-aac/libAACenc/src/spreading.cpp b/fdk-aac/libAACenc/src/spreading.cpp
new file mode 100644
index 0000000..0fb43bb
--- /dev/null
+++ b/fdk-aac/libAACenc/src/spreading.cpp
@@ -0,0 +1,125 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Spreading of energy
+
+*******************************************************************************/
+
+#include "spreading.h"
+
+void FDKaacEnc_SpreadingMax(const INT pbCnt,
+ const FIXP_DBL *RESTRICT maskLowFactor,
+ const FIXP_DBL *RESTRICT maskHighFactor,
+ FIXP_DBL *RESTRICT pbSpreadEnergy) {
+ int i;
+ FIXP_DBL delay;
+
+ /* slope to higher frequencies */
+ delay = pbSpreadEnergy[0];
+ for (i = 1; i < pbCnt; i++) {
+ delay = fixMax(pbSpreadEnergy[i], fMult(maskHighFactor[i], delay));
+ pbSpreadEnergy[i] = delay;
+ }
+
+ /* slope to lower frequencies */
+ delay = pbSpreadEnergy[pbCnt - 1];
+ for (i = pbCnt - 2; i >= 0; i--) {
+ delay = fixMax(pbSpreadEnergy[i], fMult(maskLowFactor[i], delay));
+ pbSpreadEnergy[i] = delay;
+ }
+}
diff --git a/fdk-aac/libAACenc/src/spreading.h b/fdk-aac/libAACenc/src/spreading.h
new file mode 100644
index 0000000..e693031
--- /dev/null
+++ b/fdk-aac/libAACenc/src/spreading.h
@@ -0,0 +1,113 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M.Werner
+
+ Description: Spreading of energy and weighted tonality
+
+*******************************************************************************/
+
+#ifndef SPREADING_H
+#define SPREADING_H
+
+#include "common_fix.h"
+
+void FDKaacEnc_SpreadingMax(const INT pbCnt,
+ const FIXP_DBL *RESTRICT maskLowFactor,
+ const FIXP_DBL *RESTRICT maskHighFactor,
+ FIXP_DBL *RESTRICT pbSpreadEnergy);
+
+#endif /* #ifndef SPREADING_H */
diff --git a/fdk-aac/libAACenc/src/tns_func.h b/fdk-aac/libAACenc/src/tns_func.h
new file mode 100644
index 0000000..6099bc7
--- /dev/null
+++ b/fdk-aac/libAACenc/src/tns_func.h
@@ -0,0 +1,129 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Alex Goeschel
+
+ Description: Temporal noise shaping
+
+*******************************************************************************/
+
+#ifndef TNS_FUNC_H
+#define TNS_FUNC_H
+
+#include "common_fix.h"
+
+#include "psy_configuration.h"
+
+AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(
+ INT bitrate, INT samplerate, INT channels, INT blocktype, INT granuleLength,
+ INT isLowDelay, INT ldSbrPresent, TNS_CONFIG *tnsConfig,
+ PSY_CONFIGURATION *psyConfig, INT active, INT useTnsPeak);
+
+INT FDKaacEnc_TnsDetect(TNS_DATA *tnsData, const TNS_CONFIG *tC,
+ TNS_INFO *tnsInfo, INT sfbCnt, const FIXP_DBL *spectrum,
+ INT subBlockNumber, INT blockType);
+
+void FDKaacEnc_TnsSync(TNS_DATA *tnsDataDest, const TNS_DATA *tnsDataSrc,
+ TNS_INFO *tnsInfoDest, TNS_INFO *tnsInfoSrc,
+ const INT blockTypeDest, const INT blockTypeSrc,
+ const TNS_CONFIG *tC);
+
+INT FDKaacEnc_TnsEncode(TNS_INFO *tnsInfo, TNS_DATA *tnsData,
+ const INT numOfSfb, const TNS_CONFIG *tC,
+ const INT lowPassLine, FIXP_DBL *spectrum,
+ const INT subBlockNumber, const INT blockType);
+
+#endif /* TNS_FUNC_H */
diff --git a/fdk-aac/libAACenc/src/tonality.cpp b/fdk-aac/libAACenc/src/tonality.cpp
new file mode 100644
index 0000000..334e0f1
--- /dev/null
+++ b/fdk-aac/libAACenc/src/tonality.cpp
@@ -0,0 +1,219 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: Convert chaos measure to the tonality index
+
+*******************************************************************************/
+
+#include "tonality.h"
+
+#include "chaosmeasure.h"
+
+#if defined(__arm__)
+#endif
+
+static const FIXP_DBL normlog =
+ (FIXP_DBL)0xd977d949; /*FL2FXCONST_DBL(-0.4342944819f *
+ FDKlog(2.0)/FDKlog(2.7182818)); */
+
+static void FDKaacEnc_CalcSfbTonality(FIXP_DBL *RESTRICT spectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ FIXP_DBL *RESTRICT chaosMeasure,
+ FIXP_SGL *RESTRICT sfbTonality,
+ INT sfbCnt, const INT *RESTRICT sfbOffset,
+ FIXP_DBL *RESTRICT sfbEnergyLD64);
+
+void FDKaacEnc_CalculateFullTonality(FIXP_DBL *RESTRICT spectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ FIXP_DBL *RESTRICT sfbEnergyLD64,
+ FIXP_SGL *RESTRICT sfbTonality, INT sfbCnt,
+ const INT *sfbOffset, INT usePns) {
+ INT j;
+ INT numberOfLines = sfbOffset[sfbCnt];
+
+ if (usePns) {
+ C_ALLOC_SCRATCH_START(chaosMeasurePerLine, FIXP_DBL, (1024))
+
+ /* calculate chaos measure */
+ FDKaacEnc_CalculateChaosMeasure(spectrum, numberOfLines,
+ chaosMeasurePerLine);
+
+ /* smooth ChaosMeasure */
+ FIXP_DBL left = chaosMeasurePerLine[0];
+ FIXP_DBL right;
+ for (j = 1; j < (numberOfLines - 1); j += 2) {
+ right = chaosMeasurePerLine[j];
+ right = right - (right >> 2);
+ left = right + (left >> 2);
+ chaosMeasurePerLine[j] = left; /* 0.25 left + 0.75 right */
+
+ right = chaosMeasurePerLine[j + 1];
+ right = right - (right >> 2);
+ left = right + (left >> 2);
+ chaosMeasurePerLine[j + 1] = left;
+ }
+ if (j == (numberOfLines - 1)) {
+ right = chaosMeasurePerLine[j];
+ right = right - (right >> 2);
+ left = right + (left >> 2);
+ chaosMeasurePerLine[j] = left;
+ }
+
+ FDKaacEnc_CalcSfbTonality(spectrum, sfbMaxScaleSpec, chaosMeasurePerLine,
+ sfbTonality, sfbCnt, sfbOffset, sfbEnergyLD64);
+
+ C_ALLOC_SCRATCH_END(chaosMeasurePerLine, FIXP_DBL, (1024))
+ }
+}
+
+/*****************************************************************************
+
+ functionname: CalculateTonalityIndex
+ description: computes tonality values out of unpredictability values
+ limits range and computes log()
+ returns:
+ input: ptr to energies, ptr to chaos measure values,
+ number of sfb
+ output: sfb wise tonality values
+
+*****************************************************************************/
+static void FDKaacEnc_CalcSfbTonality(FIXP_DBL *RESTRICT spectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ FIXP_DBL *RESTRICT chaosMeasure,
+ FIXP_SGL *RESTRICT sfbTonality,
+ INT sfbCnt, const INT *RESTRICT sfbOffset,
+ FIXP_DBL *RESTRICT sfbEnergyLD64) {
+ INT i;
+
+ for (i = 0; i < sfbCnt; i++) {
+ FIXP_DBL chaosMeasureSfbLD64;
+ INT shiftBits =
+ fixMax(0, sfbMaxScaleSpec[i] -
+ 4); /* max sfbWidth = 96 ; 2^7=128 => 7/2 = 4 (spc*spc) */
+
+ INT j;
+ FIXP_DBL chaosMeasureSfb = FL2FXCONST_DBL(0.0);
+
+ /* calc chaosMeasurePerSfb */
+ for (j = (sfbOffset[i + 1] - sfbOffset[i]) - 1; j >= 0; j--) {
+ FIXP_DBL tmp = (*spectrum++) << shiftBits;
+ FIXP_DBL lineNrg = fMultDiv2(tmp, tmp);
+ chaosMeasureSfb = fMultAddDiv2(chaosMeasureSfb, lineNrg, *chaosMeasure++);
+ }
+
+ /* calc tonalityPerSfb */
+ if (chaosMeasureSfb != FL2FXCONST_DBL(0.0)) {
+ /* add ld(convtone)/64 and 2/64 bec.fMultDiv2 */
+ chaosMeasureSfbLD64 = CalcLdData((chaosMeasureSfb)) - sfbEnergyLD64[i];
+ chaosMeasureSfbLD64 += FL2FXCONST_DBL(3.0f / 64) -
+ ((FIXP_DBL)(shiftBits) << (DFRACT_BITS - 6));
+
+ if (chaosMeasureSfbLD64 >
+ FL2FXCONST_DBL(-0.0519051)) /* > ld(0.05)+ld(2) */
+ {
+ if (chaosMeasureSfbLD64 <= FL2FXCONST_DBL(0.0))
+ sfbTonality[i] =
+ FX_DBL2FX_SGL(fMultDiv2(chaosMeasureSfbLD64, normlog) << 7);
+ else
+ sfbTonality[i] = FL2FXCONST_SGL(0.0);
+ } else
+ sfbTonality[i] = (FIXP_SGL)MAXVAL_SGL;
+ } else
+ sfbTonality[i] = (FIXP_SGL)MAXVAL_SGL;
+ }
+}
diff --git a/fdk-aac/libAACenc/src/tonality.h b/fdk-aac/libAACenc/src/tonality.h
new file mode 100644
index 0000000..c5cf4c5
--- /dev/null
+++ b/fdk-aac/libAACenc/src/tonality.h
@@ -0,0 +1,115 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Lohwasser
+
+ Description: Calculate tonality index
+
+*******************************************************************************/
+
+#ifndef TONALITY_H
+#define TONALITY_H
+
+#include "common_fix.h"
+#include "chaosmeasure.h"
+
+void FDKaacEnc_CalculateFullTonality(FIXP_DBL *RESTRICT spectrum,
+ INT *RESTRICT sfbMaxScaleSpec,
+ FIXP_DBL *RESTRICT sfbEnergyLD64,
+ FIXP_SGL *RESTRICT sfbTonality, INT sfbCnt,
+ const INT *sfbOffset, INT usePns);
+
+#endif /* TONALITY_H */
diff --git a/fdk-aac/libAACenc/src/transform.cpp b/fdk-aac/libAACenc/src/transform.cpp
new file mode 100644
index 0000000..08b1c2f
--- /dev/null
+++ b/fdk-aac/libAACenc/src/transform.cpp
@@ -0,0 +1,294 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): Tobias Chalupka
+
+ Description: FDKaacLdEnc_MdctTransform480:
+ The module FDKaacLdEnc_MdctTransform will perform the MDCT.
+ The MDCT supports the sine window and
+ the zero padded window. The algorithm of the MDCT
+ can be divided in Windowing, PreModulation, Fft and
+ PostModulation.
+
+*******************************************************************************/
+
+#include "transform.h"
+#include "dct.h"
+#include "psy_const.h"
+#include "aacEnc_rom.h"
+#include "FDK_tools_rom.h"
+
+#if defined(__arm__)
+#endif
+
+INT FDKaacEnc_Transform_Real(const INT_PCM *pTimeData,
+ FIXP_DBL *RESTRICT mdctData, const INT blockType,
+ const INT windowShape, INT *prevWindowShape,
+ H_MDCT mdctPers, const INT frameLength,
+ INT *pMdctData_e, INT filterType) {
+ const INT_PCM *RESTRICT timeData;
+
+ UINT numSpec;
+ UINT numMdctLines;
+ UINT offset;
+ int fr; /* fr: right window slope length */
+ SHORT mdctData_e[8];
+
+ timeData = pTimeData;
+
+ if (blockType == SHORT_WINDOW) {
+ numSpec = 8;
+ numMdctLines = frameLength >> 3;
+ } else {
+ numSpec = 1;
+ numMdctLines = frameLength;
+ }
+
+ offset = (windowShape == LOL_WINDOW) ? ((frameLength * 3) >> 2) : 0;
+ switch (blockType) {
+ case LONG_WINDOW:
+ case STOP_WINDOW:
+ fr = frameLength - offset;
+ break;
+ case START_WINDOW: /* or StopStartSequence */
+ case SHORT_WINDOW:
+ fr = frameLength >> 3;
+ break;
+ default:
+ FDK_ASSERT(0);
+ return -1;
+ }
+
+ mdct_block(mdctPers, timeData, frameLength, mdctData, numSpec, numMdctLines,
+ FDKgetWindowSlope(fr, windowShape), fr, mdctData_e);
+
+ if (blockType == SHORT_WINDOW) {
+ if (!(mdctData_e[0] == mdctData_e[1] && mdctData_e[1] == mdctData_e[2] &&
+ mdctData_e[2] == mdctData_e[3] && mdctData_e[3] == mdctData_e[4] &&
+ mdctData_e[4] == mdctData_e[5] && mdctData_e[5] == mdctData_e[6] &&
+ mdctData_e[6] == mdctData_e[7])) {
+ return -1;
+ }
+ }
+ *prevWindowShape = windowShape;
+ *pMdctData_e = mdctData_e[0];
+
+ return 0;
+}
+
+INT FDKaacEnc_Transform_Real_Eld(const INT_PCM *pTimeData,
+ FIXP_DBL *RESTRICT mdctData,
+ const INT blockType, const INT windowShape,
+ INT *prevWindowShape, const INT frameLength,
+ INT *mdctData_e, INT filterType,
+ FIXP_DBL *RESTRICT overlapAddBuffer) {
+ const INT_PCM *RESTRICT timeData;
+
+ INT i;
+
+ /* tl: transform length
+ fl: left window slope length
+ nl: left window slope offset
+ fr: right window slope length
+ nr: right window slope offset */
+ const FIXP_WTB *pWindowELD = NULL;
+ int N = frameLength;
+ int L = frameLength;
+
+ timeData = pTimeData;
+
+ if (blockType != LONG_WINDOW) {
+ return -1;
+ }
+
+ /*
+ * MDCT scale:
+ * + 1: fMultDiv2() in windowing.
+ * + 1: Because of factor 1/2 in Princen-Bradley compliant windowed TDAC.
+ */
+ *mdctData_e = 1 + 1;
+
+ switch (frameLength) {
+ case 512:
+ pWindowELD = ELDAnalysis512;
+ break;
+ case 480:
+ pWindowELD = ELDAnalysis480;
+ break;
+ case 256:
+ pWindowELD = ELDAnalysis256;
+ *mdctData_e += 1;
+ break;
+ case 240:
+ pWindowELD = ELDAnalysis240;
+ *mdctData_e += 1;
+ break;
+ case 128:
+ pWindowELD = ELDAnalysis128;
+ *mdctData_e += 2;
+ break;
+ case 120:
+ pWindowELD = ELDAnalysis120;
+ *mdctData_e += 2;
+ break;
+ default:
+ FDK_ASSERT(0);
+ return -1;
+ }
+
+ for (i = 0; i < N / 4; i++) {
+ FIXP_DBL z0, outval;
+
+ z0 = (fMult((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i],
+ pWindowELD[N / 2 - 1 - i])
+ << (WTS0 - 1)) +
+ (fMult((FIXP_PCM)timeData[L + N * 3 / 4 + i], pWindowELD[N / 2 + i])
+ << (WTS0 - 1));
+
+ outval = (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i],
+ pWindowELD[N + N / 2 - 1 - i]) >>
+ (-WTS1));
+ outval += (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 + i],
+ pWindowELD[N + N / 2 + i]) >>
+ (-WTS1));
+ outval += (fMultDiv2(overlapAddBuffer[N / 2 + i], pWindowELD[2 * N + i]) >>
+ (-WTS2 - 1));
+
+ overlapAddBuffer[N / 2 + i] = overlapAddBuffer[i];
+
+ overlapAddBuffer[i] = z0;
+ mdctData[i] = overlapAddBuffer[N / 2 + i] +
+ (fMultDiv2(overlapAddBuffer[N + N / 2 - 1 - i],
+ pWindowELD[2 * N + N / 2 + i]) >>
+ (-WTS2 - 1));
+
+ mdctData[N - 1 - i] = outval;
+ overlapAddBuffer[N + N / 2 - 1 - i] = outval;
+ }
+
+ for (i = N / 4; i < N / 2; i++) {
+ FIXP_DBL z0, outval;
+
+ z0 = fMult((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i],
+ pWindowELD[N / 2 - 1 - i])
+ << (WTS0 - 1);
+
+ outval = (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i],
+ pWindowELD[N + N / 2 - 1 - i]) >>
+ (-WTS1));
+ outval += (fMultDiv2(overlapAddBuffer[N / 2 + i], pWindowELD[2 * N + i]) >>
+ (-WTS2 - 1));
+
+ overlapAddBuffer[N / 2 + i] =
+ overlapAddBuffer[i] +
+ (fMult((FIXP_PCM)timeData[L - N / 4 + i], pWindowELD[N / 2 + i])
+ << (WTS0 - 1));
+
+ overlapAddBuffer[i] = z0;
+ mdctData[i] = overlapAddBuffer[N / 2 + i] +
+ (fMultDiv2(overlapAddBuffer[N + N / 2 - 1 - i],
+ pWindowELD[2 * N + N / 2 + i]) >>
+ (-WTS2 - 1));
+
+ mdctData[N - 1 - i] = outval;
+ overlapAddBuffer[N + N / 2 - 1 - i] = outval;
+ }
+ dct_IV(mdctData, frameLength, mdctData_e);
+
+ *prevWindowShape = windowShape;
+
+ return 0;
+}
diff --git a/fdk-aac/libAACenc/src/transform.h b/fdk-aac/libAACenc/src/transform.h
new file mode 100644
index 0000000..8f5ff46
--- /dev/null
+++ b/fdk-aac/libAACenc/src/transform.h
@@ -0,0 +1,163 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** AAC encoder library ******************************
+
+ Author(s): M. Werner
+
+ Description: MDCT Transform
+
+*******************************************************************************/
+
+#ifndef TRANSFORM_H
+#define TRANSFORM_H
+
+#include "mdct.h"
+#include "common_fix.h"
+
+#define WTS0 1
+#define WTS1 0
+#define WTS2 -2
+
+/**
+ * \brief: Performe MDCT transform of time domain data.
+ * \param timeData pointer to time domain input signal.
+ * \param mdctData pointer to store frequency domain output data.
+ * \param blockType index indicating the type of block. Either
+ * LONG_WINDOW, START_WINDOW, SHORT_WINDOW or STOP_WINDOW.
+ * \param windowShape index indicating the window slope type to be used.
+ * Values allowed are either SINE_WINDOW or KBD_WINDOW.
+ * \param previndowShape index indicating the window slope type used
+ * in the last frame.
+ * Values allowed are either SINE_WINDOW or KBD_WINDOW.
+ * \param frameLength length of the block. Either 1024 or 960.
+ * \param mdctData_e pointer to an INT where the exponent of the frequency
+ * domain output data is stored into.
+ * \param filterType xxx
+ * \return 0 in case of success, non-zero in case of error (inconsistent
+ * parameters).
+ */
+INT FDKaacEnc_Transform_Real(const INT_PCM* pTimeData,
+ FIXP_DBL* RESTRICT mdctData, const INT blockType,
+ const INT windowShape, INT* prevWindowShape,
+ H_MDCT mdctPers, const INT frameLength,
+ INT* pMdctData_e, INT filterType);
+
+/**
+ * \brief: Performe ELD filterbnank transform of time domain data.
+ * \param timeData pointer to time domain input signal.
+ * \param mdctData pointer to store frequency domain output data.
+ * \param blockType index indicating the type of block. Either
+ * LONG_WINDOW, START_WINDOW, SHORT_WINDOW or STOP_WINDOW.
+ * \param windowShape index indicating the window slope type to be used.
+ * Values allowed are either SINE_WINDOW or KBD_WINDOW.
+ * \param previndowShape index indicating the window slope type used
+ * in the last frame.
+ * Values allowed are either SINE_WINDOW or KBD_WINDOW.
+ * \param frameLength length of the block. Either 1024 or 960.
+ * \param mdctData_e pointer to an INT where the exponent of the frequency
+ * domain output data is stored into.
+ * \param filterType xxx
+ * \param overlapAddBuffer overlap add buffer for overlap of ELD filterbank
+ * \return 0 in case of success, non-zero in case of error (inconsistent
+ * parameters).
+ */
+INT FDKaacEnc_Transform_Real_Eld(const INT_PCM* pTimeData,
+ FIXP_DBL* RESTRICT mdctData,
+ const INT blockType, const INT windowShape,
+ INT* prevWindowShape, const INT frameLength,
+ INT* mdctData_e, INT filterType,
+ FIXP_DBL* RESTRICT overlapAddBuffer);
+
+#endif /* #!defined (TRANSFORM_H) */
diff --git a/fdk-aac/libArithCoding/include/ac_arith_coder.h b/fdk-aac/libArithCoding/include/ac_arith_coder.h
new file mode 100644
index 0000000..130c188
--- /dev/null
+++ b/fdk-aac/libArithCoding/include/ac_arith_coder.h
@@ -0,0 +1,142 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/************************** Arithmetic coder library ***************************
+
+ Author(s): Oliver Weiss
+
+ Description: Interface for Spectral Noiseless Coding Scheme based on an
+ Arithmetic Coder in Conjunction with an Adaptive Context
+
+*******************************************************************************/
+
+#ifndef AC_ARITH_CODER_H
+#define AC_ARITH_CODER_H
+
+#include "common_fix.h"
+#include "FDK_bitstream.h"
+
+#include "FDK_audio.h"
+
+typedef enum { ARITH_CODER_OK = 0, ARITH_CODER_ERROR = 5 } ARITH_CODING_ERROR;
+
+typedef struct {
+ SHORT m_numberLinesPrev;
+ UCHAR c_prev[(1024 / 2) + 4]; /* 2-tuple context of previous frame, 4 bit */
+} CArcoData;
+
+/* prototypes */
+
+CArcoData *CArco_Create(void);
+
+void CArco_Destroy(CArcoData *pArcoData);
+
+/**
+ * \brief decode a spectral data element by using an adaptive context dependent
+ * arithmetic coding scheme
+ * \param hBs bit stream handle
+ * \param spectrum pointer to quantized data output.
+ * \param lg number of quantized spectral coefficients (output by the arithmetic
+ * decoder).
+ * \param lg_max max number of quantized spectral coefficients.
+ * \param arith_reset_flag flag which indicates if the spectral noiseless
+ * context must be reset
+ * \return void
+ */
+ARITH_CODING_ERROR CArco_DecodeArithData(CArcoData *pArcoData,
+ HANDLE_FDK_BITSTREAM hBs,
+ FIXP_DBL *RESTRICT spectrum, int lg,
+ int lg_max, int arith_reset_flag);
+
+#endif /* AC_ARITH_CODER_H */
diff --git a/fdk-aac/libArithCoding/src/ac_arith_coder.cpp b/fdk-aac/libArithCoding/src/ac_arith_coder.cpp
new file mode 100644
index 0000000..a433b08
--- /dev/null
+++ b/fdk-aac/libArithCoding/src/ac_arith_coder.cpp
@@ -0,0 +1,785 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/************************** Arithmetic coder library ***************************
+
+ Author(s): Youliy Ninov, Oliver Weiss
+
+ Description: Definition of Spectral Noiseless Coding Scheme based on an
+ Arithmetic Coder in Conjunction with an Adaptive Context
+
+*******************************************************************************/
+
+#include "ac_arith_coder.h"
+
+#define cbitsnew 16
+#define stat_bitsnew 14
+#define ari_q4new (((long)1 << cbitsnew) - 1) /* 0xFFFF */
+#define ari_q1new (ari_q4new / 4 + 1) /* 0x4000 */
+#define ari_q2new (2 * ari_q1new) /* 0x8000 */
+#define ari_q3new (3 * ari_q1new) /* 0xC000 */
+
+#define VAL_ESC 16
+
+/* Arithmetic coder library info */
+#define AC_LIB_VL0 2
+#define AC_LIB_VL1 0
+#define AC_LIB_VL2 0
+#define AC_LIB_TITLE "Arithmetic Coder Lib"
+#ifdef __ANDROID__
+#define AC_LIB_BUILD_DATE ""
+#define AC_LIB_BUILD_TIME ""
+#else
+#define AC_LIB_BUILD_DATE __DATE__
+#define AC_LIB_BUILD_TIME __TIME__
+#endif
+
+const SHORT ari_lsb2[3][4] = {
+ {12571, 10569, 3696, 0}, {12661, 5700, 3751, 0}, {10827, 6884, 2929, 0}};
+
+H_ALLOC_MEM(ArcoData, CArcoData)
+/*! The structure ArcoData contains 2-tuple context of previous frame. <br>
+ Dimension: 1 */
+C_ALLOC_MEM(ArcoData, CArcoData, 1)
+
+/*
+ This define triggers the use of the pre-known return values of function
+ get_pk_v2() for the cases, where parameter s is in range
+ 0x00000000..0x0000000F. Note: These 16 bytes have been moved into the first 4
+ entries of ari_merged_hash_ps that are no more referenced.
+*/
+
+static const ULONG ari_merged_hash_ps[742] = {
+ 0x00001044UL, 0x00003D0AUL, 0x00005350UL, 0x000074D6UL, 0x0000A49FUL,
+ 0x0000F96EUL, 0x00111000UL, 0x01111E83UL, 0x01113146UL, 0x01114036UL,
+ 0x01116863UL, 0x011194E9UL, 0x0111F7EEUL, 0x0112269BUL, 0x01124775UL,
+ 0x01126DA1UL, 0x0112D912UL, 0x01131AF0UL, 0x011336DDUL, 0x01135CF5UL,
+ 0x01139DF8UL, 0x01141A5BUL, 0x01144773UL, 0x01146CF5UL, 0x0114FDE9UL,
+ 0x01166CF5UL, 0x0116FDE4UL, 0x01174CF3UL, 0x011FFDCFUL, 0x01211CC2UL,
+ 0x01213B2DUL, 0x01214036UL, 0x01216863UL, 0x012194D2UL, 0x0122197FUL,
+ 0x01223AADUL, 0x01224036UL, 0x01226878UL, 0x0122A929UL, 0x0122F4ABUL,
+ 0x01232B2DUL, 0x012347B6UL, 0x01237DF8UL, 0x0123B929UL, 0x012417DDUL,
+ 0x01245D76UL, 0x01249DF8UL, 0x0124F912UL, 0x01255D75UL, 0x0125FDE9UL,
+ 0x01265D75UL, 0x012B8DF7UL, 0x01311E2AUL, 0x01313B5EUL, 0x0131687BUL,
+ 0x01321A6DUL, 0x013237BCUL, 0x01326863UL, 0x0132F4EEUL, 0x01332B5EUL,
+ 0x01335DA1UL, 0x01338E24UL, 0x01341A5EUL, 0x01343DB6UL, 0x01348DF8UL,
+ 0x01351935UL, 0x01355DB7UL, 0x0135FE12UL, 0x01376DF7UL, 0x013FFE29UL,
+ 0x01400024UL, 0x01423821UL, 0x014318F6UL, 0x01433821UL, 0x0143F8E5UL,
+ 0x01443DA1UL, 0x01486E38UL, 0x014FF929UL, 0x01543EE3UL, 0x015FF912UL,
+ 0x016F298CUL, 0x018A5A69UL, 0x021007F1UL, 0x02112C2CUL, 0x02114B48UL,
+ 0x02117353UL, 0x0211F4AEUL, 0x02122FEAUL, 0x02124B48UL, 0x02127850UL,
+ 0x0212F72EUL, 0x02133A9EUL, 0x02134036UL, 0x02138864UL, 0x021414ADUL,
+ 0x0214379EUL, 0x02145DB6UL, 0x0214FE1FUL, 0x02166DB7UL, 0x02200DC4UL,
+ 0x02212FEAUL, 0x022147A0UL, 0x02218369UL, 0x0221F7EEUL, 0x02222AADUL,
+ 0x02224788UL, 0x02226863UL, 0x02229929UL, 0x0222F4ABUL, 0x02232A9EUL,
+ 0x02234F08UL, 0x02237864UL, 0x0223A929UL, 0x022417DEUL, 0x02244F36UL,
+ 0x02248863UL, 0x02251A74UL, 0x02256DA1UL, 0x0225FE12UL, 0x02263DB6UL,
+ 0x02276DF7UL, 0x022FFE29UL, 0x0231186DUL, 0x023137BCUL, 0x02314020UL,
+ 0x02319ED6UL, 0x0232196DUL, 0x023237BCUL, 0x02325809UL, 0x02329429UL,
+ 0x023317EDUL, 0x02333F08UL, 0x02335809UL, 0x023378E4UL, 0x02341A7CUL,
+ 0x02344221UL, 0x0234A8D3UL, 0x023514BCUL, 0x02354221UL, 0x0235F8DFUL,
+ 0x02364861UL, 0x023FFE29UL, 0x02400024UL, 0x0241583BUL, 0x024214C8UL,
+ 0x02424809UL, 0x02427EE6UL, 0x02431708UL, 0x02434809UL, 0x02436ED0UL,
+ 0x02441A76UL, 0x02443821UL, 0x024458E3UL, 0x0244F91FUL, 0x02454863UL,
+ 0x0246190AUL, 0x02464863UL, 0x024FF929UL, 0x02525ED0UL, 0x025314E1UL,
+ 0x025348FBUL, 0x025419A1UL, 0x025458D0UL, 0x0254F4E5UL, 0x02552861UL,
+ 0x025FF912UL, 0x02665993UL, 0x027F5A69UL, 0x029F1481UL, 0x02CF28A4UL,
+ 0x03100AF0UL, 0x031120AAUL, 0x031147A0UL, 0x03118356UL, 0x031217ECUL,
+ 0x03123B5EUL, 0x03124008UL, 0x03127350UL, 0x031314AAUL, 0x0313201EUL,
+ 0x03134F08UL, 0x03136863UL, 0x03141A5EUL, 0x03143F3CUL, 0x03200847UL,
+ 0x03212AADUL, 0x03214F20UL, 0x03218ED6UL, 0x032218ADUL, 0x032237BCUL,
+ 0x03225809UL, 0x03229416UL, 0x032317EDUL, 0x03234F20UL, 0x03237350UL,
+ 0x0323FA6BUL, 0x03243F08UL, 0x03246863UL, 0x0324F925UL, 0x03254221UL,
+ 0x0325F8DFUL, 0x03264821UL, 0x032FFE29UL, 0x03311E47UL, 0x03313F08UL,
+ 0x0331580DUL, 0x033214DEUL, 0x03323F08UL, 0x03324020UL, 0x03326350UL,
+ 0x033294E9UL, 0x033317DEUL, 0x03333F08UL, 0x0333627BUL, 0x0333A9A9UL,
+ 0x033417FCUL, 0x03343220UL, 0x0334627BUL, 0x0334A9A9UL, 0x0335148AUL,
+ 0x03353220UL, 0x033588E4UL, 0x03361A4AUL, 0x03363821UL, 0x0336F8D2UL,
+ 0x03376863UL, 0x03411939UL, 0x0341583BUL, 0x034214C8UL, 0x03424809UL,
+ 0x03426ED0UL, 0x03431588UL, 0x03434809UL, 0x03436ED0UL, 0x03441A48UL,
+ 0x0344480DUL, 0x03446ED0UL, 0x03451A4AUL, 0x03453809UL, 0x03455EFBUL,
+ 0x034614CAUL, 0x03463849UL, 0x034F8924UL, 0x03500A69UL, 0x035252D0UL,
+ 0x035314E0UL, 0x0353324DUL, 0x03535ED0UL, 0x035414E0UL, 0x0354324DUL,
+ 0x03545ED0UL, 0x0354F4E8UL, 0x0355384DUL, 0x03555ED0UL, 0x0355F4DFUL,
+ 0x03564350UL, 0x035969A6UL, 0x035FFA52UL, 0x036649A6UL, 0x036FFA52UL,
+ 0x037F4F66UL, 0x039D7492UL, 0x03BF6892UL, 0x03DF8A1FUL, 0x04100B84UL,
+ 0x04112107UL, 0x0411520DUL, 0x041214EAUL, 0x04124F20UL, 0x04131EDEUL,
+ 0x04133F08UL, 0x04135809UL, 0x0413F42BUL, 0x04142F08UL, 0x04200847UL,
+ 0x042121FCUL, 0x04214209UL, 0x04221407UL, 0x0422203CUL, 0x04224209UL,
+ 0x04226350UL, 0x04231A7CUL, 0x04234209UL, 0x0423637BUL, 0x04241A7CUL,
+ 0x04243220UL, 0x0424627BUL, 0x042514C8UL, 0x04254809UL, 0x042FF8E9UL,
+ 0x04311E47UL, 0x04313220UL, 0x0431527BUL, 0x043214FCUL, 0x04323220UL,
+ 0x04326250UL, 0x043315BCUL, 0x04333220UL, 0x0433527BUL, 0x04338413UL,
+ 0x04341488UL, 0x04344809UL, 0x04346ED0UL, 0x04351F48UL, 0x0435527BUL,
+ 0x0435F9A5UL, 0x04363809UL, 0x04375EFBUL, 0x043FF929UL, 0x04412E79UL,
+ 0x0441427BUL, 0x044219B9UL, 0x04423809UL, 0x0442537BUL, 0x044314C8UL,
+ 0x04432020UL, 0x0443527BUL, 0x044414CAUL, 0x04443809UL, 0x0444537BUL,
+ 0x04448993UL, 0x0445148AUL, 0x04453809UL, 0x04455ED0UL, 0x0445F4E5UL,
+ 0x0446384DUL, 0x045009A6UL, 0x045272D3UL, 0x045314A0UL, 0x0453324DUL,
+ 0x04535ED0UL, 0x045415A0UL, 0x0454324DUL, 0x04545ED0UL, 0x04551F60UL,
+ 0x0455324DUL, 0x04562989UL, 0x04564350UL, 0x045FF4D2UL, 0x04665993UL,
+ 0x047FFF62UL, 0x048FF725UL, 0x049F44BDUL, 0x04BFB7E5UL, 0x04EF8A25UL,
+ 0x04FFFB98UL, 0x051131F9UL, 0x051212C7UL, 0x05134209UL, 0x05200247UL,
+ 0x05211007UL, 0x05213E60UL, 0x052212C7UL, 0x05224209UL, 0x052319BCUL,
+ 0x05233220UL, 0x0523527BUL, 0x052414C8UL, 0x05243820UL, 0x053112F9UL,
+ 0x05313E49UL, 0x05321439UL, 0x05323E49UL, 0x0532537BUL, 0x053314C8UL,
+ 0x0533480DUL, 0x05337413UL, 0x05341488UL, 0x0534527BUL, 0x0534F4EBUL,
+ 0x05353809UL, 0x05356ED0UL, 0x0535F4E5UL, 0x0536427BUL, 0x054119B9UL,
+ 0x054212F9UL, 0x05423249UL, 0x05426ED3UL, 0x05431739UL, 0x05433249UL,
+ 0x05435ED0UL, 0x0543F4EBUL, 0x05443809UL, 0x05445ED0UL, 0x0544F4E8UL,
+ 0x0545324DUL, 0x054FF992UL, 0x055362D3UL, 0x0553F5ABUL, 0x05544350UL,
+ 0x055514CAUL, 0x0555427BUL, 0x0555F4E5UL, 0x0556327BUL, 0x055FF4D2UL,
+ 0x05665993UL, 0x05774F53UL, 0x059FF728UL, 0x05CC37FDUL, 0x05EFBA28UL,
+ 0x05FFFB98UL, 0x061131F9UL, 0x06121407UL, 0x06133E60UL, 0x061A72E4UL,
+ 0x06211E47UL, 0x06214E4BUL, 0x062214C7UL, 0x06223E60UL, 0x062312F9UL,
+ 0x06233E60UL, 0x063112F9UL, 0x06313E4CUL, 0x063219B9UL, 0x06323E49UL,
+ 0x06331439UL, 0x06333809UL, 0x06336EE6UL, 0x0633F5ABUL, 0x06343809UL,
+ 0x0634F42BUL, 0x0635427BUL, 0x063FF992UL, 0x064342FBUL, 0x0643F4EBUL,
+ 0x0644427BUL, 0x064524C9UL, 0x06655993UL, 0x0666170AUL, 0x066652E6UL,
+ 0x067A6F56UL, 0x0698473DUL, 0x06CF67D2UL, 0x06EF3A26UL, 0x06FFFAD8UL,
+ 0x071131CCUL, 0x07211307UL, 0x07222E79UL, 0x072292DCUL, 0x07234E4BUL,
+ 0x073112F9UL, 0x07322339UL, 0x073632CBUL, 0x073FF992UL, 0x074432CBUL,
+ 0x075549A6UL, 0x0776FF68UL, 0x07774350UL, 0x0788473DUL, 0x07CF4516UL,
+ 0x07EF3A26UL, 0x07FFFAD8UL, 0x08222E79UL, 0x083112F9UL, 0x0834330BUL,
+ 0x0845338BUL, 0x08756F5CUL, 0x0887F725UL, 0x08884366UL, 0x08AF649CUL,
+ 0x08F00898UL, 0x08FFFAD8UL, 0x091111C7UL, 0x0932330BUL, 0x0945338BUL,
+ 0x09774F7DUL, 0x0998C725UL, 0x09996416UL, 0x09EF87E5UL, 0x09FFFAD8UL,
+ 0x0A34330BUL, 0x0A45338BUL, 0x0A77467DUL, 0x0AA9F52BUL, 0x0AAA6416UL,
+ 0x0ABD67DFUL, 0x0AFFFA18UL, 0x0B33330BUL, 0x0B4443A6UL, 0x0B76467DUL,
+ 0x0BB9751FUL, 0x0BBB59BDUL, 0x0BEF5892UL, 0x0BFFFAD8UL, 0x0C221339UL,
+ 0x0C53338EUL, 0x0C76367DUL, 0x0CCAF52EUL, 0x0CCC6996UL, 0x0CFFFA18UL,
+ 0x0D44438EUL, 0x0D64264EUL, 0x0DDCF52EUL, 0x0DDD5996UL, 0x0DFFFA18UL,
+ 0x0E43338EUL, 0x0E68465CUL, 0x0EEE651CUL, 0x0EFFFA18UL, 0x0F33238EUL,
+ 0x0F553659UL, 0x0F8F451CUL, 0x0FAFF8AEUL, 0x0FF00A2EUL, 0x0FFF1ACCUL,
+ 0x0FFF33BDUL, 0x0FFF7522UL, 0x0FFFFAD8UL, 0x10002C72UL, 0x1111103EUL,
+ 0x11121E83UL, 0x11131E9AUL, 0x1121115AUL, 0x11221170UL, 0x112316F0UL,
+ 0x1124175DUL, 0x11311CC2UL, 0x11321182UL, 0x11331D42UL, 0x11411D48UL,
+ 0x11421836UL, 0x11431876UL, 0x11441DF5UL, 0x1152287BUL, 0x12111903UL,
+ 0x1212115AUL, 0x121316F0UL, 0x12211B30UL, 0x12221B30UL, 0x12231B02UL,
+ 0x12311184UL, 0x12321D04UL, 0x12331784UL, 0x12411D39UL, 0x12412020UL,
+ 0x12422220UL, 0x12511D89UL, 0x1252227BUL, 0x1258184AUL, 0x12832992UL,
+ 0x1311171AUL, 0x13121B30UL, 0x1312202CUL, 0x131320AAUL, 0x132120AAUL,
+ 0x132220ADUL, 0x13232FEDUL, 0x13312107UL, 0x13322134UL, 0x13332134UL,
+ 0x13411D39UL, 0x13431E74UL, 0x13441834UL, 0x134812B4UL, 0x1352230BUL,
+ 0x13611E4BUL, 0x136522E4UL, 0x141113C2UL, 0x141211C4UL, 0x143121F9UL,
+ 0x143221F9UL, 0x143321CAUL, 0x14351D34UL, 0x14431E47UL, 0x14441E74UL,
+ 0x144612B4UL, 0x1452230EUL, 0x14551E74UL, 0x1471130EUL, 0x151113C2UL,
+ 0x152121F9UL, 0x153121F9UL, 0x153221F9UL, 0x15331007UL, 0x15522E4EUL,
+ 0x15551E74UL, 0x1571130EUL, 0x161113C7UL, 0x162121F9UL, 0x163121F9UL,
+ 0x16611E79UL, 0x16661334UL, 0x171113C7UL, 0x172121F9UL, 0x17451E47UL,
+ 0x1771130CUL, 0x181113C7UL, 0x18211E47UL, 0x18511E4CUL, 0x1882130CUL,
+ 0x191113C7UL, 0x19331E79UL, 0x1A111307UL, 0x1A311E79UL, 0x1F52230EUL,
+ 0x200003C1UL, 0x20001027UL, 0x20004467UL, 0x200079E7UL, 0x2000E5EFUL,
+ 0x21100BC0UL, 0x211129C0UL, 0x21114011UL, 0x211189E7UL, 0x2111F5EFUL,
+ 0x21124011UL, 0x21127455UL, 0x211325C0UL, 0x21134011UL, 0x21137455UL,
+ 0x211425C0UL, 0x21212440UL, 0x21213001UL, 0x2121F9EFUL, 0x21222540UL,
+ 0x21226455UL, 0x2122F5EFUL, 0x21233051UL, 0x2123F56FUL, 0x21244451UL,
+ 0x21312551UL, 0x21323451UL, 0x21332551UL, 0x21844555UL, 0x221125C0UL,
+ 0x22113011UL, 0x2211F9EFUL, 0x22123051UL, 0x2212F9EFUL, 0x221329D1UL,
+ 0x22212541UL, 0x22213011UL, 0x2221F9EFUL, 0x22223451UL, 0x2222F9EFUL,
+ 0x22232551UL, 0x2223F56FUL, 0x22312551UL, 0x223229D1UL, 0x2232F56FUL,
+ 0x22332551UL, 0x2233F56FUL, 0x22875555UL, 0x22DAB5D7UL, 0x23112BD1UL,
+ 0x23115467UL, 0x231225D1UL, 0x232129D1UL, 0x232229D1UL, 0x2322F9EFUL,
+ 0x23233451UL, 0x2323F9EFUL, 0x23312551UL, 0x233229D1UL, 0x2332F9EFUL,
+ 0x2333F56FUL, 0x237FF557UL, 0x238569D5UL, 0x23D955D7UL, 0x24100BE7UL,
+ 0x248789E7UL, 0x24E315D7UL, 0x24FFFBEFUL, 0x259869E7UL, 0x25DFF5EFUL,
+ 0x25FFFBEFUL, 0x268789E7UL, 0x26DFA5D7UL, 0x26FFFBEFUL, 0x279649E7UL,
+ 0x27E425D7UL, 0x27FFFBEFUL, 0x288879E7UL, 0x28EFF5EFUL, 0x28FFFBEFUL,
+ 0x298439E7UL, 0x29F115EFUL, 0x29FFFBEFUL, 0x2A7659E7UL, 0x2AEF75D7UL,
+ 0x2AFFFBEFUL, 0x2B7C89E7UL, 0x2BEF95D7UL, 0x2BFFFBEFUL, 0x2C6659E7UL,
+ 0x2CD555D7UL, 0x2CFFFBEFUL, 0x2D6329E7UL, 0x2DDD55E7UL, 0x2DFFFBEBUL,
+ 0x2E8479D7UL, 0x2EEE35E7UL, 0x2EFFFBEFUL, 0x2F5459E7UL, 0x2FCF85D7UL,
+ 0x2FFEFBEBUL, 0x2FFFA5EFUL, 0x2FFFEBEFUL, 0x30001AE7UL, 0x30002001UL,
+ 0x311129C0UL, 0x31221015UL, 0x31232000UL, 0x31332451UL, 0x32112540UL,
+ 0x32131027UL, 0x32212440UL, 0x33452455UL, 0x4000F9D7UL, 0x4122F9D7UL,
+ 0x43F65555UL, 0x43FFF5D7UL, 0x44F55567UL, 0x44FFF5D7UL, 0x45F00557UL,
+ 0x45FFF5D7UL, 0x46F659D7UL, 0x471005E7UL, 0x47F449E7UL, 0x481005E7UL,
+ 0x48EFA9D5UL, 0x48FFF5EFUL, 0x49F449E7UL, 0x49FFF5EFUL, 0x4AEA79E7UL,
+ 0x4AFFF5EFUL, 0x4BE9C9D5UL, 0x4BFFF5EFUL, 0x4CE549E7UL, 0x4CFFF5EFUL,
+ 0x4DE359E7UL, 0x4DFFF5D7UL, 0x4EE469E7UL, 0x4EFFF5D7UL, 0x4FEF39E7UL,
+ 0x4FFFF5EFUL, 0x6000F9E7UL, 0x69FFF557UL, 0x6FFFF9D7UL, 0x811009D7UL,
+ 0x8EFFF555UL, 0xFFFFF9E7UL};
+
+static const SHORT ari_pk[64][17] = {
+ {708, 706, 579, 569, 568, 567, 479, 469, 297, 138, 97, 91, 72, 52, 38, 34,
+ 0},
+ {7619, 6917, 6519, 6412, 5514, 5003, 4683, 4563, 3907, 3297, 3125, 3060,
+ 2904, 2718, 2631, 2590, 0},
+ {7263, 4888, 4810, 4803, 1889, 415, 335, 327, 195, 72, 52, 49, 36, 20, 15,
+ 14, 0},
+ {3626, 2197, 2188, 2187, 582, 57, 47, 46, 30, 12, 9, 8, 6, 4, 3, 2, 0},
+ {7806, 5541, 5451, 5441, 2720, 834, 691, 674, 487, 243, 179, 167, 139, 98,
+ 77, 70, 0},
+ {6684, 4101, 4058, 4055, 1748, 426, 368, 364, 322, 257, 235, 232, 228, 222,
+ 217, 215, 0},
+ {9162, 5964, 5831, 5819, 3269, 866, 658, 638, 535, 348, 258, 244, 234, 214,
+ 195, 186, 0},
+ {10638, 8491, 8365, 8351, 4418, 2067, 1859, 1834, 1190, 601, 495, 478, 356,
+ 217, 174, 164, 0},
+ {13389, 10514, 10032, 9961, 7166, 3488, 2655, 2524, 2015, 1140, 760, 672,
+ 585, 426, 325, 283, 0},
+ {14861, 12788, 12115, 11952, 9987, 6657, 5323, 4984, 4324, 3001, 2205, 1943,
+ 1764, 1394, 1115, 978, 0},
+ {12876, 10004, 9661, 9610, 7107, 3435, 2711, 2595, 2257, 1508, 1059, 952,
+ 893, 753, 609, 538, 0},
+ {15125, 13591, 13049, 12874, 11192, 8543, 7406, 7023, 6291, 4922, 4104,
+ 3769, 3465, 2890, 2486, 2275, 0},
+ {14574, 13106, 12731, 12638, 10453, 7947, 7233, 7037, 6031, 4618, 4081,
+ 3906, 3465, 2802, 2476, 2349, 0},
+ {15070, 13179, 12517, 12351, 10742, 7657, 6200, 5825, 5264, 3998, 3014,
+ 2662, 2510, 2153, 1799, 1564, 0},
+ {15542, 14466, 14007, 13844, 12489, 10409, 9481, 9132, 8305, 6940, 6193,
+ 5867, 5458, 4743, 4291, 4047, 0},
+ {15165, 14384, 14084, 13934, 12911, 11485, 10844, 10513, 10002, 8993, 8380,
+ 8051, 7711, 7036, 6514, 6233, 0},
+ {15642, 14279, 13625, 13393, 12348, 9971, 8405, 7858, 7335, 6119, 4918,
+ 4376, 4185, 3719, 3231, 2860, 0},
+ {13408, 13407, 11471, 11218, 11217, 11216, 9473, 9216, 6480, 3689, 2857,
+ 2690, 2256, 1732, 1405, 1302, 0},
+ {16098, 15584, 15191, 14931, 14514, 13578, 12703, 12103, 11830, 11172,
+ 10475, 9867, 9695, 9281, 8825, 8389, 0},
+ {15844, 14873, 14277, 13996, 13230, 11535, 10205, 9543, 9107, 8086, 7085,
+ 6419, 6214, 5713, 5195, 4731, 0},
+ {16131, 15720, 15443, 15276, 14848, 13971, 13314, 12910, 12591, 11874,
+ 11225, 10788, 10573, 10077, 9585, 9209, 0},
+ {16331, 16330, 12283, 11435, 11434, 11433, 8725, 8049, 6065, 4138, 3187,
+ 2842, 2529, 2171, 1907, 1745, 0},
+ {16011, 15292, 14782, 14528, 14008, 12767, 11556, 10921, 10591, 9759, 8813,
+ 8043, 7855, 7383, 6863, 6282, 0},
+ {16380, 16379, 15159, 14610, 14609, 14608, 12859, 12111, 11046, 9536, 8348,
+ 7713, 7216, 6533, 5964, 5546, 0},
+ {16367, 16333, 16294, 16253, 16222, 16143, 16048, 15947, 15915, 15832,
+ 15731, 15619, 15589, 15512, 15416, 15310, 0},
+ {15967, 15319, 14937, 14753, 14010, 12638, 11787, 11360, 10805, 9706, 8934,
+ 8515, 8166, 7456, 6911, 6575, 0},
+ {4906, 3005, 2985, 2984, 875, 102, 83, 81, 47, 17, 12, 11, 8, 5, 4, 3, 0},
+ {7217, 4346, 4269, 4264, 1924, 428, 340, 332, 280, 203, 179, 175, 171, 164,
+ 159, 157, 0},
+ {16010, 15415, 15032, 14805, 14228, 13043, 12168, 11634, 11265, 10419, 9645,
+ 9110, 8892, 8378, 7850, 7437, 0},
+ {8573, 5218, 5046, 5032, 2787, 771, 555, 533, 443, 286, 218, 205, 197, 181,
+ 168, 162, 0},
+ {11474, 8095, 7822, 7796, 4632, 1443, 1046, 1004, 748, 351, 218, 194, 167,
+ 121, 93, 83, 0},
+ {16152, 15764, 15463, 15264, 14925, 14189, 13536, 13070, 12846, 12314,
+ 11763, 11277, 11131, 10777, 10383, 10011, 0},
+ {14187, 11654, 11043, 10919, 8498, 4885, 3778, 3552, 2947, 1835, 1283, 1134,
+ 998, 749, 585, 514, 0},
+ {14162, 11527, 10759, 10557, 8601, 5417, 4105, 3753, 3286, 2353, 1708, 1473,
+ 1370, 1148, 959, 840, 0},
+ {16205, 15902, 15669, 15498, 15213, 14601, 14068, 13674, 13463, 12970,
+ 12471, 12061, 11916, 11564, 11183, 10841, 0},
+ {15043, 12972, 12092, 11792, 10265, 7446, 5934, 5379, 4883, 3825, 3036,
+ 2647, 2507, 2185, 1901, 1699, 0},
+ {15320, 13694, 12782, 12352, 11191, 8936, 7433, 6671, 6255, 5366, 4622,
+ 4158, 4020, 3712, 3420, 3198, 0},
+ {16255, 16020, 15768, 15600, 15416, 14963, 14440, 14006, 13875, 13534,
+ 13137, 12697, 12602, 12364, 12084, 11781, 0},
+ {15627, 14503, 13906, 13622, 12557, 10527, 9269, 8661, 8117, 6933, 5994,
+ 5474, 5222, 4664, 4166, 3841, 0},
+ {16366, 16365, 14547, 14160, 14159, 14158, 11969, 11473, 8735, 6147, 4911,
+ 4530, 3865, 3180, 2710, 2473, 0},
+ {16257, 16038, 15871, 15754, 15536, 15071, 14673, 14390, 14230, 13842,
+ 13452, 13136, 13021, 12745, 12434, 12154, 0},
+ {15855, 14971, 14338, 13939, 13239, 11782, 10585, 9805, 9444, 8623, 7846,
+ 7254, 7079, 6673, 6262, 5923, 0},
+ {9492, 6318, 6197, 6189, 3004, 652, 489, 477, 333, 143, 96, 90, 78, 60, 50,
+ 47, 0},
+ {16313, 16191, 16063, 15968, 15851, 15590, 15303, 15082, 14968, 14704,
+ 14427, 14177, 14095, 13899, 13674, 13457, 0},
+ {8485, 5473, 5389, 5383, 2411, 494, 386, 377, 278, 150, 117, 112, 103, 89,
+ 81, 78, 0},
+ {10497, 7154, 6959, 6943, 3788, 1004, 734, 709, 517, 238, 152, 138, 120, 90,
+ 72, 66, 0},
+ {16317, 16226, 16127, 16040, 15955, 15762, 15547, 15345, 15277, 15111,
+ 14922, 14723, 14671, 14546, 14396, 14239, 0},
+ {16382, 16381, 15858, 15540, 15539, 15538, 14704, 14168, 13768, 13092,
+ 12452, 11925, 11683, 11268, 10841, 10460, 0},
+ {5974, 3798, 3758, 3755, 1275, 205, 166, 162, 95, 35, 26, 24, 18, 11, 8, 7,
+ 0},
+ {3532, 2258, 2246, 2244, 731, 135, 118, 115, 87, 45, 36, 34, 29, 21, 17, 16,
+ 0},
+ {7466, 4882, 4821, 4811, 2476, 886, 788, 771, 688, 531, 469, 457, 437, 400,
+ 369, 361, 0},
+ {9580, 5772, 5291, 5216, 3444, 1496, 1025, 928, 806, 578, 433, 384, 366,
+ 331, 296, 273, 0},
+ {10692, 7730, 7543, 7521, 4679, 1746, 1391, 1346, 1128, 692, 495, 458, 424,
+ 353, 291, 268, 0},
+ {11040, 7132, 6549, 6452, 4377, 1875, 1253, 1130, 958, 631, 431, 370, 346,
+ 296, 253, 227, 0},
+ {12687, 9332, 8701, 8585, 6266, 3093, 2182, 2004, 1683, 1072, 712, 608, 559,
+ 458, 373, 323, 0},
+ {13429, 9853, 8860, 8584, 6806, 4039, 2862, 2478, 2239, 1764, 1409, 1224,
+ 1178, 1077, 979, 903, 0},
+ {14685, 12163, 11061, 10668, 9101, 6345, 4871, 4263, 3908, 3200, 2668, 2368,
+ 2285, 2106, 1942, 1819, 0},
+ {13295, 11302, 10999, 10945, 7947, 5036, 4490, 4385, 3391, 2185, 1836, 1757,
+ 1424, 998, 833, 785, 0},
+ {4992, 2993, 2972, 2970, 1269, 575, 552, 549, 530, 505, 497, 495, 493, 489,
+ 486, 485, 0},
+ {15419, 13862, 13104, 12819, 11429, 8753, 7220, 6651, 6020, 4667, 3663,
+ 3220, 2995, 2511, 2107, 1871, 0},
+ {12468, 9263, 8912, 8873, 5758, 2193, 1625, 1556, 1187, 589, 371, 330, 283,
+ 200, 149, 131, 0},
+ {15870, 15076, 14615, 14369, 13586, 12034, 10990, 10423, 9953, 8908, 8031,
+ 7488, 7233, 6648, 6101, 5712, 0},
+ {1693, 978, 976, 975, 194, 18, 16, 15, 11, 7, 6, 5, 4, 3, 2, 1, 0},
+ {7992, 5218, 5147, 5143, 2152, 366, 282, 276, 173, 59, 38, 35, 27, 16, 11,
+ 10, 0}};
+
+typedef struct {
+ int low;
+ int high;
+ int vobf;
+} Tastat;
+
+static inline INT mul_sbc_14bits(INT r, INT c) {
+ return (((INT)r) * ((INT)c)) >> stat_bitsnew;
+}
+
+static inline INT ari_decode_14bits(HANDLE_FDK_BITSTREAM hBs, Tastat *s,
+ const SHORT *RESTRICT c_freq, int cfl) {
+ INT symbol;
+ INT low, high, range, value;
+ INT c;
+ const SHORT *p;
+
+ low = s->low;
+ high = s->high;
+ value = s->vobf;
+
+ range = high - low + 1;
+ c = (((int)(value - low + 1)) << stat_bitsnew) - ((int)1);
+ p = (const SHORT *)(c_freq - 1);
+
+ if (cfl == (VAL_ESC + 1)) {
+ /* In 50% of all cases, the first entry is the right one, so we check it
+ * prior to all others */
+ if ((p[1] * range) > c) {
+ p += 1;
+ if ((p[8] * range) > c) {
+ p += 8;
+ }
+ if ((p[4] * range) > c) {
+ p += 4;
+ }
+ if ((p[2] * range) > c) {
+ p += 2;
+ }
+ if ((p[1] * range) > c) {
+ p += 1;
+ }
+ }
+ } else if (cfl == 4) {
+ if ((p[2] * range) > c) {
+ p += 2;
+ }
+ if ((p[1] * range) > c) {
+ p += 1;
+ }
+ } else if (cfl == 2) {
+ if ((p[1] * range) > c) {
+ p += 1;
+ }
+ } else if (cfl == 27) {
+ const SHORT *p_24 = p + 24;
+
+ if ((p[16] * range) > c) {
+ p += 16;
+ }
+ if ((p[8] * range) > c) {
+ p += 8;
+ }
+ if (p != p_24) {
+ if ((p[4] * range) > c) {
+ p += 4;
+ }
+ }
+ if ((p[2] * range) > c) {
+ p += 2;
+ }
+
+ if (p != &p_24[2]) {
+ if ((p[1] * range) > c) {
+ p += 1;
+ }
+ }
+ }
+
+ symbol = (INT)(p - (const SHORT *)(c_freq - 1));
+
+ if (symbol) {
+ high = low + mul_sbc_14bits(range, c_freq[symbol - 1]) - 1;
+ }
+
+ low += mul_sbc_14bits(range, c_freq[symbol]);
+
+ USHORT us_high = (USHORT)high;
+ USHORT us_low = (USHORT)low;
+ while (1) {
+ if (us_high & 0x8000) {
+ if (!(us_low & 0x8000)) {
+ if (us_low & 0x4000 && !(us_high & 0x4000)) {
+ us_low -= 0x4000;
+ us_high -= 0x4000;
+ value -= 0x4000;
+ } else
+ break;
+ }
+ }
+ us_low = us_low << 1;
+ us_high = (us_high << 1) | 1;
+ value = (value << 1) | FDKreadBit(hBs);
+ }
+ s->low = (int)us_low;
+ s->high = (int)us_high;
+ s->vobf = value & 0xFFFF;
+
+ return symbol;
+}
+
+static inline void copyTableAmrwbArith2(UCHAR tab[], int sizeIn, int sizeOut) {
+ int i;
+ int j;
+ int k = 2;
+
+ tab += 2;
+
+ if (sizeIn < sizeOut) {
+ tab[sizeOut + 0] = tab[sizeIn + 0];
+ tab[sizeOut + 1] = tab[sizeIn + 1];
+ if (sizeIn < (sizeOut >> 2)) {
+ k = 8;
+ } else if (sizeIn == (sizeOut >> 2)) {
+ k = 4;
+ }
+
+ i = sizeOut - 1;
+ j = sizeIn - 1;
+
+ for (; i >= 0; j--) {
+ UCHAR tq_data0 = tab[j];
+
+ for (int l = (k >> 1); l > 0; l--) {
+ tab[i--] = tq_data0;
+ tab[i--] = tq_data0;
+ }
+ }
+ } else {
+ if (sizeOut < (sizeIn >> 2)) {
+ k = 8;
+ } else if (sizeOut == (sizeIn >> 2)) {
+ k = 4;
+ }
+
+ for (i = 0, j = 0; i < sizeOut; j += k) {
+ UCHAR tq_data0 = tab[j];
+
+ tab[i++] = tq_data0;
+ }
+ tab[sizeOut + 0] = tab[sizeIn + 0];
+ tab[sizeOut + 1] = tab[sizeIn + 1];
+ }
+}
+
+static inline ULONG get_pk_v2(ULONG s) {
+ const ULONG *p = ari_merged_hash_ps;
+ ULONG s12 = (fMax((UINT)s, (UINT)1) << 12) - 1;
+ if (s12 > p[485]) {
+ p += 486; /* 742 - 256 = 486 */
+ } else {
+ if (s12 > p[255]) p += 256;
+ }
+
+ if (s12 > p[127]) {
+ p += 128;
+ }
+ if (s12 > p[63]) {
+ p += 64;
+ }
+ if (s12 > p[31]) {
+ p += 32;
+ }
+ if (s12 > p[15]) {
+ p += 16;
+ }
+ if (s12 > p[7]) {
+ p += 8;
+ }
+ if (s12 > p[3]) {
+ p += 4;
+ }
+ if (s12 > p[1]) {
+ p += 2;
+ }
+ ULONG j = p[0];
+ if (s12 > j) j = p[1];
+ if (s != (j >> 12)) j >>= 6;
+ return (j & 0x3F);
+}
+
+static ARITH_CODING_ERROR decode2(HANDLE_FDK_BITSTREAM bbuf,
+ UCHAR *RESTRICT c_prev,
+ FIXP_DBL *RESTRICT pSpectralCoefficient,
+ INT n, INT nt) {
+ Tastat as;
+ int i, l, r;
+ INT lev, esc_nb, pki;
+ USHORT state_inc;
+ UINT s;
+ ARITH_CODING_ERROR ErrorStatus = ARITH_CODER_OK;
+
+ int c_3 = 0; /* context of current frame 3 time steps ago */
+ int c_2 = 0; /* context of current frame 2 time steps ago */
+ int c_1 = 0; /* context of current frame 1 time steps ago */
+ int c_0 = 1; /* context of current frame to be calculated */
+
+ /* ari_start_decoding_14bits */
+ as.low = 0;
+ as.high = ari_q4new;
+ as.vobf = FDKreadBits(bbuf, cbitsnew);
+
+ /* arith_map_context */
+ state_inc = c_prev[0] << 12;
+
+ for (i = 0; i < n; i++) {
+ /* arith_get_context */
+ s = state_inc >> 8;
+ s = s + (c_prev[i + 1] << 8);
+ s = (s << 4) + c_1;
+
+ state_inc = s;
+
+ if (i > 3) {
+ /* Cumulative amplitude below 2 */
+ if ((c_1 + c_2 + c_3) < 5) {
+ s += 0x10000;
+ }
+ }
+
+ /* MSBs decoding */
+ for (lev = esc_nb = 0;;) {
+ pki = get_pk_v2(s + (esc_nb << (VAL_ESC + 1)));
+ r = ari_decode_14bits(bbuf, &as, ari_pk[pki], VAL_ESC + 1);
+ if (r < VAL_ESC) {
+ break;
+ }
+
+ lev++;
+
+ if (lev > 23) return ARITH_CODER_ERROR;
+
+ if (esc_nb < 7) {
+ esc_nb++;
+ }
+ }
+
+ /* Stop symbol */
+ if (r == 0) {
+ if (esc_nb > 0) {
+ break; /* Stop symbol */
+ }
+ c_0 = 1;
+ } else /* if (r==0) */
+ {
+ INT b = r >> 2;
+ INT a = r & 0x3;
+
+ /* LSBs decoding */
+ for (l = 0; l < lev; l++) {
+ {
+ int pidx = (a == 0) ? 1 : ((b == 0) ? 0 : 2);
+ r = ari_decode_14bits(bbuf, &as, ari_lsb2[pidx], 4);
+ }
+ a = (a << 1) | (r & 1);
+ b = (b << 1) | (r >> 1);
+ }
+
+ pSpectralCoefficient[2 * i] = (FIXP_DBL)a;
+ pSpectralCoefficient[2 * i + 1] = (FIXP_DBL)b;
+
+ c_0 = a + b + 1;
+ if (c_0 > 0xF) {
+ c_0 = 0xF;
+ }
+
+ } /* endif (r==0) */
+
+ /* arith_update_context */
+ c_3 = c_2;
+ c_2 = c_1;
+ c_1 = c_0;
+ c_prev[i] = (UCHAR)c_0;
+
+ } /* for (i=0; i<n; i++) */
+
+ FDKpushBack(bbuf, cbitsnew - 2);
+
+ /* We need to run only from 0 to i-1 since all other q[i][1].a,b will be
+ * cleared later */
+ int j = i;
+ for (i = 0; i < j; i++) {
+ int bits = 0;
+ if (pSpectralCoefficient[2 * i] != (FIXP_DBL)0) bits++;
+ if (pSpectralCoefficient[2 * i + 1] != (FIXP_DBL)0) bits++;
+
+ if (bits) {
+ r = FDKreadBits(bbuf, bits);
+ if (pSpectralCoefficient[2 * i] != (FIXP_DBL)0 && !(r >> (bits - 1))) {
+ pSpectralCoefficient[2 * i] = -pSpectralCoefficient[2 * i];
+ }
+ if (pSpectralCoefficient[2 * i + 1] != (FIXP_DBL)0 && !(r & 1)) {
+ pSpectralCoefficient[2 * i + 1] = -pSpectralCoefficient[2 * i + 1];
+ }
+ }
+ }
+
+ FDKmemset(&c_prev[i], 1, sizeof(c_prev[0]) * (nt - i));
+
+ return ErrorStatus;
+}
+
+CArcoData *CArco_Create(void) { return GetArcoData(); }
+
+void CArco_Destroy(CArcoData *pArcoData) { FreeArcoData(&pArcoData); }
+
+ARITH_CODING_ERROR CArco_DecodeArithData(CArcoData *pArcoData,
+ HANDLE_FDK_BITSTREAM hBs,
+ FIXP_DBL *RESTRICT mdctSpectrum,
+ int lg, int lg_max,
+ int arith_reset_flag) {
+ ARITH_CODING_ERROR ErrorStatus = ARITH_CODER_OK;
+
+ /* Check lg and lg_max consistency. */
+ if (lg_max < lg) {
+ return ARITH_CODER_ERROR;
+ }
+
+ FDKmemclear(mdctSpectrum, lg_max * sizeof(FIXP_DBL));
+
+ /* arith_map_context */
+ if (arith_reset_flag) {
+ FDKmemclear(pArcoData->c_prev,
+ sizeof(pArcoData->c_prev[0]) * ((lg_max / 2) + 4));
+ } else {
+ if (lg_max != pArcoData->m_numberLinesPrev) {
+ if (pArcoData->m_numberLinesPrev == 0) {
+ /* Cannot decode without a valid AC context */
+ return ARITH_CODER_ERROR;
+ }
+
+ /* short-to-long or long-to-short block transition */
+ /* Current length differs compared to previous - perform up/downmix of
+ * m_qbuf */
+ copyTableAmrwbArith2(pArcoData->c_prev, pArcoData->m_numberLinesPrev >> 1,
+ lg_max >> 1);
+ }
+ }
+
+ pArcoData->m_numberLinesPrev = lg_max;
+
+ if (lg > 0) {
+ ErrorStatus =
+ decode2(hBs, pArcoData->c_prev + 2, mdctSpectrum, lg >> 1, lg_max >> 1);
+ } else {
+ FDKmemset(&pArcoData->c_prev[2], 1,
+ sizeof(pArcoData->c_prev[2]) * (lg_max >> 1));
+ }
+
+ if ((INT)FDKgetValidBits(hBs) < 0) {
+ return ARITH_CODER_ERROR;
+ }
+
+ return ErrorStatus;
+}
diff --git a/fdk-aac/libDRCdec/include/FDK_drcDecLib.h b/fdk-aac/libDRCdec/include/FDK_drcDecLib.h
new file mode 100644
index 0000000..e187e18
--- /dev/null
+++ b/fdk-aac/libDRCdec/include/FDK_drcDecLib.h
@@ -0,0 +1,313 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s): Bernhard Neugebauer
+
+ Description: MPEG-D DRC Decoder
+
+*******************************************************************************/
+
+#ifndef FDK_DRCDECLIB_H
+#define FDK_DRCDECLIB_H
+
+#include "FDK_bitstream.h"
+#include "FDK_audio.h"
+#include "common_fix.h"
+
+/* DRC decoder according to ISO/IEC 23003-4 (MPEG-D DRC) */
+/* including ISO/IEC 23003-4/AMD1 (Amendment 1) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct s_drc_decoder* HANDLE_DRC_DECODER;
+typedef struct s_uni_drc_interface* HANDLE_UNI_DRC_INTERFACE;
+typedef struct s_selection_process_output* HANDLE_SEL_PROC_OUTPUT;
+
+typedef enum {
+ DRC_DEC_SELECTION = 0x1, /* DRC decoder instance for DRC set selection only */
+ DRC_DEC_GAIN = 0x2, /* DRC decoder instance for applying DRC only */
+ DRC_DEC_ALL = 0x3 /* DRC decoder with full functionality */
+} DRC_DEC_FUNCTIONAL_RANGE;
+
+typedef enum {
+ /* get and set userparams */
+ DRC_DEC_BOOST,
+ DRC_DEC_COMPRESS,
+ /* set only userparams */
+ DRC_DEC_LOUDNESS_NORMALIZATION_ON,
+ DRC_DEC_TARGET_LOUDNESS, /**< target loudness in dB, with exponent e = 7 */
+ DRC_DEC_EFFECT_TYPE,
+ DRC_DEC_EFFECT_TYPE_FALLBACK_CODE,
+ DRC_DEC_LOUDNESS_MEASUREMENT_METHOD,
+ /* set only system (not user) parameters */
+ DRC_DEC_DOWNMIX_ID,
+ DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED, /**< number of output channels
+ notified to FDK_drcDecLib for
+ choosing an appropriate
+ downmixInstruction */
+ DRC_DEC_BASE_CHANNEL_COUNT,
+ /* get only system parameters */
+ DRC_DEC_IS_MULTIBAND_DRC_1,
+ DRC_DEC_IS_MULTIBAND_DRC_2,
+ DRC_DEC_IS_ACTIVE, /**< MPEG-D DRC payload is present and at least one of
+ Dynamic Range Control (DRC) or Loudness Normalization
+ (LN) is activated */
+ DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED /**< number of output channels if
+ appropriate downmixInstruction exists
+ */
+} DRC_DEC_USERPARAM;
+
+typedef enum {
+ DRC_DEC_OK = 0,
+
+ DRC_DEC_NOT_OK = -10000,
+ DRC_DEC_OUT_OF_MEMORY,
+ DRC_DEC_NOT_OPENED,
+ DRC_DEC_NOT_READY,
+ DRC_DEC_PARAM_OUT_OF_RANGE,
+ DRC_DEC_INVALID_PARAM,
+ DRC_DEC_UNSUPPORTED_FUNCTION
+} DRC_DEC_ERROR;
+
+typedef enum {
+ DRC_DEC_TEST_TIME_DOMAIN = -100,
+ DRC_DEC_TEST_QMF_DOMAIN,
+ DRC_DEC_TEST_STFT_DOMAIN,
+ DRC_DEC_CODEC_MODE_UNDEFINED = -1,
+ DRC_DEC_MPEG_4_AAC,
+ DRC_DEC_MPEG_D_USAC,
+ DRC_DEC_MPEG_H_3DA
+} DRC_DEC_CODEC_MODE;
+
+/* Apply only DRC sets dedicated to processing location.
+ DRC1: before downmix
+ DRC2: before or after downmix (AMD1: only after downmix)
+ DRC3: after downmix */
+typedef enum {
+ DRC_DEC_DRC1,
+ DRC_DEC_DRC1_DRC2,
+ DRC_DEC_DRC2,
+ DRC_DEC_DRC3,
+ DRC_DEC_DRC2_DRC3
+} DRC_DEC_LOCATION;
+
+DRC_DEC_ERROR
+FDK_drcDec_Open(HANDLE_DRC_DECODER* phDrcDec,
+ const DRC_DEC_FUNCTIONAL_RANGE functionalRange);
+
+DRC_DEC_ERROR
+FDK_drcDec_SetCodecMode(HANDLE_DRC_DECODER hDrcDec,
+ const DRC_DEC_CODEC_MODE codecMode);
+
+DRC_DEC_ERROR
+FDK_drcDec_Init(HANDLE_DRC_DECODER hDrcDec, const int frameSize,
+ const int sampleRate, const int baseChannelCount);
+
+DRC_DEC_ERROR
+FDK_drcDec_Close(HANDLE_DRC_DECODER* phDrcDec);
+
+/* set single user request */
+DRC_DEC_ERROR
+FDK_drcDec_SetParam(HANDLE_DRC_DECODER hDrcDec,
+ const DRC_DEC_USERPARAM requestType,
+ const FIXP_DBL requestValue);
+
+LONG FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec,
+ const DRC_DEC_USERPARAM requestType);
+
+DRC_DEC_ERROR
+FDK_drcDec_SetInterfaceParameters(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_UNI_DRC_INTERFACE uniDrcInterface);
+
+DRC_DEC_ERROR
+FDK_drcDec_SetSelectionProcessMpeghParameters_simple(
+ HANDLE_DRC_DECODER hDrcDec, const int groupPresetIdRequested,
+ const int numGroupIdsRequested, const int* groupIdsRequested);
+
+DRC_DEC_ERROR
+FDK_drcDec_SetDownmixInstructions(HANDLE_DRC_DECODER hDrcDec,
+ const int numDowmixId, const int* downmixId,
+ const int* targetLayout,
+ const int* targetChannelCount);
+
+void FDK_drcDec_SetSelectionProcessOutput(
+ HANDLE_DRC_DECODER hDrcDec, HANDLE_SEL_PROC_OUTPUT hSelProcOutput);
+
+HANDLE_SEL_PROC_OUTPUT
+FDK_drcDec_GetSelectionProcessOutput(HANDLE_DRC_DECODER hDrcDec);
+
+LONG /* FIXP_DBL, e = 7 */
+FDK_drcDec_GetGroupLoudness(HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
+ const int groupID, int* groupLoudnessAvailable);
+
+void FDK_drcDec_SetChannelGains(HANDLE_DRC_DECODER hDrcDec,
+ const int numChannels, const int frameSize,
+ FIXP_DBL* channelGainDb, FIXP_DBL* audioBuffer,
+ const int audioBufferChannelOffset);
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadUniDrcConfig(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadLoudnessInfoSet(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadLoudnessBox(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadDownmixInstructions_Box(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadUniDrcInstructions_Box(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadUniDrcCoefficients_Box(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadUniDrcGain(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+/* either call FDK_drcDec_ReadUniDrcConfig, FDK_drcDec_ReadLoudnessInfoSet and
+ FDK_drcDec_ReadUniDrcGain separately, or call FDK_drcDec_ReadUniDrc */
+DRC_DEC_ERROR
+FDK_drcDec_ReadUniDrc(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+/* calling sequence:
+ FDK_drcDec_Read...()
+ FDK_drcDec_SetChannelGains()
+ FDK_drcDec_Preprocess()
+ FDK_drcDec_Process...() */
+
+DRC_DEC_ERROR
+FDK_drcDec_Preprocess(HANDLE_DRC_DECODER hDrcDec);
+
+DRC_DEC_ERROR
+FDK_drcDec_ProcessTime(HANDLE_DRC_DECODER hDrcDec, const int delaySamples,
+ const DRC_DEC_LOCATION drcLocation,
+ const int channelOffset, const int drcChannelOffset,
+ const int numChannelsProcessed, FIXP_DBL* realBuffer,
+ const int timeDataChannelOffset);
+
+DRC_DEC_ERROR
+FDK_drcDec_ProcessFreq(HANDLE_DRC_DECODER hDrcDec, const int delaySamples,
+ const DRC_DEC_LOCATION drcLocation,
+ const int channelOffset, const int drcChannelOffset,
+ const int numChannelsProcessed,
+ const int processSingleTimeslot, FIXP_DBL** realBuffer,
+ FIXP_DBL** imagBuffer);
+
+DRC_DEC_ERROR
+FDK_drcDec_ApplyDownmix(HANDLE_DRC_DECODER hDrcDec, int* reverseInChannelMap,
+ int* reverseOutChannelMap, FIXP_DBL* realBuffer,
+ int* pNChannels);
+
+/* Get library info for this module. */
+DRC_DEC_ERROR
+FDK_drcDec_GetLibInfo(LIB_INFO* info);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/fdk-aac/libDRCdec/src/FDK_drcDecLib.cpp b/fdk-aac/libDRCdec/src/FDK_drcDecLib.cpp
new file mode 100644
index 0000000..b29b79d
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/FDK_drcDecLib.cpp
@@ -0,0 +1,891 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s): Bernhard Neugebauer
+
+ Description: MPEG-D DRC Decoder
+
+*******************************************************************************/
+
+#include "drcDec_reader.h"
+#include "drcDec_gainDecoder.h"
+#include "FDK_drcDecLib.h"
+
+#include "drcDec_selectionProcess.h"
+#include "drcDec_tools.h"
+
+/* Decoder library info */
+#define DRCDEC_LIB_VL0 2
+#define DRCDEC_LIB_VL1 1
+#define DRCDEC_LIB_VL2 0
+#define DRCDEC_LIB_TITLE "MPEG-D DRC Decoder Lib"
+#ifdef __ANDROID__
+#define DRCDEC_LIB_BUILD_DATE ""
+#define DRCDEC_LIB_BUILD_TIME ""
+#else
+#define DRCDEC_LIB_BUILD_DATE __DATE__
+#define DRCDEC_LIB_BUILD_TIME __TIME__
+#endif
+
+typedef enum {
+ DRC_DEC_NOT_INITIALIZED = 0,
+ DRC_DEC_INITIALIZED,
+ DRC_DEC_NEW_GAIN_PAYLOAD,
+ DRC_DEC_INTERPOLATION_PREPARED
+} DRC_DEC_STATUS;
+
+struct s_drc_decoder {
+ DRC_DEC_CODEC_MODE codecMode;
+ DRC_DEC_FUNCTIONAL_RANGE functionalRange;
+ DRC_DEC_STATUS status;
+
+ /* handles of submodules */
+ HANDLE_DRC_GAIN_DECODER hGainDec;
+ HANDLE_DRC_SELECTION_PROCESS hSelectionProc;
+ int selProcInputDiff;
+
+ /* data structs */
+ UNI_DRC_CONFIG uniDrcConfig;
+ LOUDNESS_INFO_SET loudnessInfoSet;
+ UNI_DRC_GAIN uniDrcGain;
+
+ SEL_PROC_OUTPUT selProcOutput;
+} DRC_DECODER;
+
+static int isResetNeeded(HANDLE_DRC_DECODER hDrcDec,
+ const SEL_PROC_OUTPUT oldSelProcOutput) {
+ int i, resetNeeded = 0;
+
+ if (hDrcDec->selProcOutput.numSelectedDrcSets !=
+ oldSelProcOutput.numSelectedDrcSets) {
+ resetNeeded = 1;
+ } else {
+ for (i = 0; i < hDrcDec->selProcOutput.numSelectedDrcSets; i++) {
+ if (hDrcDec->selProcOutput.selectedDrcSetIds[i] !=
+ oldSelProcOutput.selectedDrcSetIds[i])
+ resetNeeded = 1;
+ if (hDrcDec->selProcOutput.selectedDownmixIds[i] !=
+ oldSelProcOutput.selectedDownmixIds[i])
+ resetNeeded = 1;
+ }
+ }
+
+ if (hDrcDec->selProcOutput.boost != oldSelProcOutput.boost) resetNeeded = 1;
+ if (hDrcDec->selProcOutput.compress != oldSelProcOutput.compress)
+ resetNeeded = 1;
+
+ /* Note: Changes in downmix matrix are not caught, as they don't affect the
+ * DRC gain decoder */
+
+ return resetNeeded;
+}
+
+static DRC_DEC_ERROR startSelectionProcess(HANDLE_DRC_DECODER hDrcDec) {
+ DRC_ERROR dErr = DE_OK;
+ DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ int uniDrcConfigHasChanged = 0;
+ SEL_PROC_OUTPUT oldSelProcOutput = hDrcDec->selProcOutput;
+
+ if (!hDrcDec->status) return DRC_DEC_NOT_READY;
+
+ if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
+ uniDrcConfigHasChanged = hDrcDec->uniDrcConfig.diff;
+ if (hDrcDec->uniDrcConfig.diff || hDrcDec->loudnessInfoSet.diff ||
+ hDrcDec->selProcInputDiff) {
+ /* in case of an error, signal that selection process was not successful
+ */
+ hDrcDec->selProcOutput.numSelectedDrcSets = 0;
+
+ sErr = drcDec_SelectionProcess_Process(
+ hDrcDec->hSelectionProc, &(hDrcDec->uniDrcConfig),
+ &(hDrcDec->loudnessInfoSet), &(hDrcDec->selProcOutput));
+ if (sErr) return DRC_DEC_OK;
+
+ hDrcDec->selProcInputDiff = 0;
+ hDrcDec->uniDrcConfig.diff = 0;
+ hDrcDec->loudnessInfoSet.diff = 0;
+ }
+ }
+
+ if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
+ if (isResetNeeded(hDrcDec, oldSelProcOutput) || uniDrcConfigHasChanged) {
+ dErr =
+ drcDec_GainDecoder_Config(hDrcDec->hGainDec, &(hDrcDec->uniDrcConfig),
+ hDrcDec->selProcOutput.numSelectedDrcSets,
+ hDrcDec->selProcOutput.selectedDrcSetIds,
+ hDrcDec->selProcOutput.selectedDownmixIds);
+ if (dErr) return DRC_DEC_OK;
+ }
+ }
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_Open(HANDLE_DRC_DECODER* phDrcDec,
+ const DRC_DEC_FUNCTIONAL_RANGE functionalRange) {
+ DRC_ERROR dErr = DE_OK;
+ DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ HANDLE_DRC_DECODER hDrcDec;
+
+ *phDrcDec = (HANDLE_DRC_DECODER)FDKcalloc(1, sizeof(DRC_DECODER));
+ if (!*phDrcDec) return DRC_DEC_OUT_OF_MEMORY;
+ hDrcDec = *phDrcDec;
+
+ hDrcDec->functionalRange = functionalRange;
+
+ hDrcDec->status = DRC_DEC_NOT_INITIALIZED;
+ hDrcDec->codecMode = DRC_DEC_CODEC_MODE_UNDEFINED;
+
+ if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
+ sErr = drcDec_SelectionProcess_Create(&(hDrcDec->hSelectionProc));
+ if (sErr) return DRC_DEC_OUT_OF_MEMORY;
+ sErr = drcDec_SelectionProcess_Init(hDrcDec->hSelectionProc);
+ if (sErr) return DRC_DEC_NOT_OK;
+ hDrcDec->selProcInputDiff = 1;
+ }
+
+ if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
+ dErr = drcDec_GainDecoder_Open(&(hDrcDec->hGainDec));
+ if (dErr) return DRC_DEC_OUT_OF_MEMORY;
+ }
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_SetCodecMode(HANDLE_DRC_DECODER hDrcDec,
+ const DRC_DEC_CODEC_MODE codecMode) {
+ DRC_ERROR dErr = DE_OK;
+ DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+
+ if (hDrcDec->codecMode ==
+ DRC_DEC_CODEC_MODE_UNDEFINED) { /* Set codec mode, if it is set for the
+ first time */
+ hDrcDec->codecMode = codecMode;
+
+ if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
+ sErr = drcDec_SelectionProcess_SetCodecMode(
+ hDrcDec->hSelectionProc, (SEL_PROC_CODEC_MODE)codecMode);
+ if (sErr) return DRC_DEC_NOT_OK;
+ hDrcDec->selProcInputDiff = 1;
+ }
+
+ if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
+ DELAY_MODE delayMode;
+ int timeDomainSupported;
+ SUBBAND_DOMAIN_MODE subbandDomainSupported;
+
+ switch (hDrcDec->codecMode) {
+ case DRC_DEC_MPEG_4_AAC:
+ case DRC_DEC_MPEG_D_USAC:
+ case DRC_DEC_MPEG_H_3DA:
+ default:
+ delayMode = DM_REGULAR_DELAY;
+ }
+
+ switch (hDrcDec->codecMode) {
+ case DRC_DEC_MPEG_4_AAC:
+ case DRC_DEC_MPEG_D_USAC:
+ timeDomainSupported = 1;
+ subbandDomainSupported = SDM_OFF;
+ break;
+ case DRC_DEC_MPEG_H_3DA:
+ timeDomainSupported = 1;
+ subbandDomainSupported = SDM_STFT256;
+ break;
+
+ case DRC_DEC_TEST_TIME_DOMAIN:
+ timeDomainSupported = 1;
+ subbandDomainSupported = SDM_OFF;
+ break;
+ case DRC_DEC_TEST_QMF_DOMAIN:
+ timeDomainSupported = 0;
+ subbandDomainSupported = SDM_QMF64;
+ break;
+ case DRC_DEC_TEST_STFT_DOMAIN:
+ timeDomainSupported = 0;
+ subbandDomainSupported = SDM_STFT256;
+ break;
+
+ default:
+ timeDomainSupported = 0;
+ subbandDomainSupported = SDM_OFF;
+ }
+
+ dErr = drcDec_GainDecoder_SetCodecDependentParameters(
+ hDrcDec->hGainDec, delayMode, timeDomainSupported,
+ subbandDomainSupported);
+ if (dErr) return DRC_DEC_NOT_OK;
+ }
+ }
+
+ /* Don't allow changing codecMode if it has already been set. */
+ if (hDrcDec->codecMode != codecMode) return DRC_DEC_NOT_OK;
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_Init(HANDLE_DRC_DECODER hDrcDec, const int frameSize,
+ const int sampleRate, const int baseChannelCount) {
+ DRC_ERROR dErr = DE_OK;
+ DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+
+ if (hDrcDec == NULL || frameSize == 0 || sampleRate == 0 ||
+ baseChannelCount == 0)
+ return DRC_DEC_OK; /* return without doing anything */
+
+ if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
+ sErr = drcDec_SelectionProcess_SetParam(
+ hDrcDec->hSelectionProc, SEL_PROC_BASE_CHANNEL_COUNT,
+ (FIXP_DBL)baseChannelCount, &(hDrcDec->selProcInputDiff));
+ if (sErr) return DRC_DEC_NOT_OK;
+ sErr = drcDec_SelectionProcess_SetParam(
+ hDrcDec->hSelectionProc, SEL_PROC_SAMPLE_RATE, (FIXP_DBL)sampleRate,
+ &(hDrcDec->selProcInputDiff));
+ if (sErr) return DRC_DEC_NOT_OK;
+ }
+
+ if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
+ dErr = drcDec_GainDecoder_Init(hDrcDec->hGainDec, frameSize, sampleRate);
+ if (dErr) return DRC_DEC_NOT_OK;
+ }
+
+ hDrcDec->status = DRC_DEC_INITIALIZED;
+
+ startSelectionProcess(hDrcDec);
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_Close(HANDLE_DRC_DECODER* phDrcDec) {
+ HANDLE_DRC_DECODER hDrcDec;
+
+ if (phDrcDec == NULL) {
+ return DRC_DEC_OK;
+ }
+
+ hDrcDec = *phDrcDec;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+
+ if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
+ drcDec_GainDecoder_Close(&(hDrcDec->hGainDec));
+ }
+
+ if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
+ drcDec_SelectionProcess_Delete(&(hDrcDec->hSelectionProc));
+ }
+
+ FDKfree(*phDrcDec);
+ *phDrcDec = NULL;
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_SetParam(HANDLE_DRC_DECODER hDrcDec,
+ const DRC_DEC_USERPARAM requestType,
+ const FIXP_DBL requestValue) {
+ DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+
+ if (hDrcDec->functionalRange == DRC_DEC_GAIN)
+ return DRC_DEC_NOT_OK; /* not supported for DRC_DEC_GAIN. All parameters are
+ handed over to selection process lib. */
+
+ switch (requestType) {
+ case DRC_DEC_BOOST:
+ sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
+ SEL_PROC_BOOST, requestValue,
+ &(hDrcDec->selProcInputDiff));
+ if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
+ break;
+ case DRC_DEC_COMPRESS:
+ sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
+ SEL_PROC_COMPRESS, requestValue,
+ &(hDrcDec->selProcInputDiff));
+ if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
+ break;
+ case DRC_DEC_LOUDNESS_NORMALIZATION_ON:
+ sErr = drcDec_SelectionProcess_SetParam(
+ hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_NORMALIZATION_ON,
+ requestValue, &(hDrcDec->selProcInputDiff));
+ if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
+ break;
+ case DRC_DEC_TARGET_LOUDNESS:
+ sErr = drcDec_SelectionProcess_SetParam(
+ hDrcDec->hSelectionProc, SEL_PROC_TARGET_LOUDNESS, requestValue,
+ &(hDrcDec->selProcInputDiff));
+ if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
+ break;
+ case DRC_DEC_EFFECT_TYPE:
+ sErr = drcDec_SelectionProcess_SetParam(
+ hDrcDec->hSelectionProc, SEL_PROC_EFFECT_TYPE, requestValue,
+ &(hDrcDec->selProcInputDiff));
+ if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
+ break;
+ case DRC_DEC_DOWNMIX_ID:
+ sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
+ SEL_PROC_DOWNMIX_ID, requestValue,
+ &(hDrcDec->selProcInputDiff));
+ if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
+ break;
+ case DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED:
+ sErr = drcDec_SelectionProcess_SetParam(
+ hDrcDec->hSelectionProc, SEL_PROC_TARGET_CHANNEL_COUNT, requestValue,
+ &(hDrcDec->selProcInputDiff));
+ if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
+ break;
+ case DRC_DEC_BASE_CHANNEL_COUNT:
+ sErr = drcDec_SelectionProcess_SetParam(
+ hDrcDec->hSelectionProc, SEL_PROC_BASE_CHANNEL_COUNT, requestValue,
+ &(hDrcDec->selProcInputDiff));
+ if (sErr) return DRC_DEC_NOT_OK;
+ break;
+ case DRC_DEC_LOUDNESS_MEASUREMENT_METHOD:
+ sErr = drcDec_SelectionProcess_SetParam(
+ hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_MEASUREMENT_METHOD,
+ requestValue, &(hDrcDec->selProcInputDiff));
+ if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
+ break;
+ default:
+ return DRC_DEC_INVALID_PARAM;
+ }
+
+ /* All parameters need a new start of the selection process */
+ startSelectionProcess(hDrcDec);
+
+ return DRC_DEC_OK;
+}
+
+LONG FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec,
+ const DRC_DEC_USERPARAM requestType) {
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+
+ switch (requestType) {
+ case DRC_DEC_BOOST:
+ return (LONG)hDrcDec->selProcOutput.boost;
+ case DRC_DEC_COMPRESS:
+ return (LONG)hDrcDec->selProcOutput.compress;
+ case DRC_DEC_IS_MULTIBAND_DRC_1:
+ return (LONG)bitstreamContainsMultibandDrc(&hDrcDec->uniDrcConfig, 0);
+ case DRC_DEC_IS_MULTIBAND_DRC_2:
+ return (LONG)bitstreamContainsMultibandDrc(&hDrcDec->uniDrcConfig, 0x7F);
+ case DRC_DEC_IS_ACTIVE: {
+ /* MPEG-D DRC is considered active (and overrides MPEG-4 DRC), if
+ * uniDrc payload is present (loudnessInfoSet and/or uniDrcConfig)
+ * at least one of DRC and Loudness Control is switched on */
+ int drcOn = drcDec_SelectionProcess_GetParam(
+ hDrcDec->hSelectionProc, SEL_PROC_DYNAMIC_RANGE_CONTROL_ON);
+ int lnOn = drcDec_SelectionProcess_GetParam(
+ hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_NORMALIZATION_ON);
+ int uniDrcPayloadPresent =
+ (hDrcDec->loudnessInfoSet.loudnessInfoCount > 0);
+ uniDrcPayloadPresent |=
+ (hDrcDec->loudnessInfoSet.loudnessInfoAlbumCount > 0);
+ uniDrcPayloadPresent |=
+ (hDrcDec->uniDrcConfig.drcInstructionsUniDrcCount > 0);
+ uniDrcPayloadPresent |=
+ (hDrcDec->uniDrcConfig.downmixInstructionsCount > 0);
+ return (LONG)(uniDrcPayloadPresent && (drcOn || lnOn));
+ }
+ case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED:
+ return (LONG)hDrcDec->selProcOutput.targetChannelCount;
+ default:
+ return 0;
+ }
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_SetInterfaceParameters(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_UNI_DRC_INTERFACE hUniDrcInterface) {
+ return DRC_DEC_UNSUPPORTED_FUNCTION;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_SetSelectionProcessMpeghParameters_simple(
+ HANDLE_DRC_DECODER hDrcDec, const int groupPresetIdRequested,
+ const int numGroupIdsRequested, const int* groupIdsRequested) {
+ return DRC_DEC_UNSUPPORTED_FUNCTION;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_SetDownmixInstructions(HANDLE_DRC_DECODER hDrcDec,
+ const int numDownmixId, const int* downmixId,
+ const int* targetLayout,
+ const int* targetChannelCount) {
+ return DRC_DEC_UNSUPPORTED_FUNCTION;
+}
+
+void FDK_drcDec_SetSelectionProcessOutput(
+ HANDLE_DRC_DECODER hDrcDec, HANDLE_SEL_PROC_OUTPUT hSelProcOutput) {}
+
+HANDLE_SEL_PROC_OUTPUT
+FDK_drcDec_GetSelectionProcessOutput(HANDLE_DRC_DECODER hDrcDec) {
+ if (hDrcDec == NULL) return NULL;
+
+ return &(hDrcDec->selProcOutput);
+}
+
+LONG /* FIXP_DBL, e = 7 */
+FDK_drcDec_GetGroupLoudness(HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
+ const int groupID, int* groupLoudnessAvailable) {
+ return (LONG)0;
+}
+
+void FDK_drcDec_SetChannelGains(HANDLE_DRC_DECODER hDrcDec,
+ const int numChannels, const int frameSize,
+ FIXP_DBL* channelGainDb, FIXP_DBL* audioBuffer,
+ const int audioBufferChannelOffset) {
+ int err;
+
+ if (hDrcDec == NULL) return;
+
+ err = drcDec_GainDecoder_SetLoudnessNormalizationGainDb(
+ hDrcDec->hGainDec, hDrcDec->selProcOutput.loudnessNormalizationGainDb);
+ if (err) return;
+
+ drcDec_GainDecoder_SetChannelGains(hDrcDec->hGainDec, numChannels, frameSize,
+ channelGainDb, audioBufferChannelOffset,
+ audioBuffer);
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadUniDrcConfig(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream) {
+ DRC_ERROR dErr = DE_OK;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+
+ if (hDrcDec->codecMode == DRC_DEC_MPEG_D_USAC) {
+ dErr = drcDec_readUniDrcConfig(hBitstream, &(hDrcDec->uniDrcConfig));
+ } else
+ return DRC_DEC_NOT_OK;
+
+ if (dErr) {
+ /* clear config, if parsing error occured */
+ FDKmemclear(&hDrcDec->uniDrcConfig, sizeof(hDrcDec->uniDrcConfig));
+ hDrcDec->uniDrcConfig.diff = 1;
+ }
+
+ startSelectionProcess(hDrcDec);
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadDownmixInstructions_Box(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream) {
+ DRC_ERROR dErr = DE_OK;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+
+ return DRC_DEC_NOT_OK;
+
+ if (dErr) {
+ /* clear config, if parsing error occurred */
+ FDKmemclear(&hDrcDec->uniDrcConfig.downmixInstructions,
+ sizeof(hDrcDec->uniDrcConfig.downmixInstructions));
+ hDrcDec->uniDrcConfig.downmixInstructionsCount = 0;
+ hDrcDec->uniDrcConfig.downmixInstructionsCountV0 = 0;
+ hDrcDec->uniDrcConfig.downmixInstructionsCountV1 = 0;
+ hDrcDec->uniDrcConfig.diff = 1;
+ }
+
+ startSelectionProcess(hDrcDec);
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadUniDrcInstructions_Box(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream) {
+ DRC_ERROR dErr = DE_OK;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+
+ return DRC_DEC_NOT_OK;
+
+ if (dErr) {
+ /* clear config, if parsing error occurred */
+ FDKmemclear(&hDrcDec->uniDrcConfig.drcInstructionsUniDrc,
+ sizeof(hDrcDec->uniDrcConfig.drcInstructionsUniDrc));
+ hDrcDec->uniDrcConfig.drcInstructionsUniDrcCount = 0;
+ hDrcDec->uniDrcConfig.drcInstructionsUniDrcCountV0 = 0;
+ hDrcDec->uniDrcConfig.drcInstructionsUniDrcCountV1 = 0;
+ hDrcDec->uniDrcConfig.diff = 1;
+ }
+
+ startSelectionProcess(hDrcDec);
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadUniDrcCoefficients_Box(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream) {
+ DRC_ERROR dErr = DE_OK;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+
+ return DRC_DEC_NOT_OK;
+
+ if (dErr) {
+ /* clear config, if parsing error occurred */
+ FDKmemclear(&hDrcDec->uniDrcConfig.drcCoefficientsUniDrc,
+ sizeof(hDrcDec->uniDrcConfig.drcCoefficientsUniDrc));
+ hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCount = 0;
+ hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCountV0 = 0;
+ hDrcDec->uniDrcConfig.drcCoefficientsUniDrcCountV1 = 0;
+ hDrcDec->uniDrcConfig.diff = 1;
+ }
+
+ startSelectionProcess(hDrcDec);
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadLoudnessInfoSet(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream) {
+ DRC_ERROR dErr = DE_OK;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+
+ if (hDrcDec->codecMode == DRC_DEC_MPEG_D_USAC) {
+ dErr = drcDec_readLoudnessInfoSet(hBitstream, &(hDrcDec->loudnessInfoSet));
+ } else
+ return DRC_DEC_NOT_OK;
+
+ if (dErr) {
+ /* clear config, if parsing error occurred */
+ FDKmemclear(&hDrcDec->loudnessInfoSet, sizeof(hDrcDec->loudnessInfoSet));
+ hDrcDec->loudnessInfoSet.diff = 1;
+ }
+
+ startSelectionProcess(hDrcDec);
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadLoudnessBox(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream) {
+ DRC_ERROR dErr = DE_OK;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+
+ return DRC_DEC_NOT_OK;
+
+ if (dErr) {
+ /* clear config, if parsing error occurred */
+ FDKmemclear(&hDrcDec->loudnessInfoSet, sizeof(hDrcDec->loudnessInfoSet));
+ hDrcDec->loudnessInfoSet.diff = 1;
+ }
+
+ startSelectionProcess(hDrcDec);
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadUniDrcGain(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream) {
+ DRC_ERROR dErr = DE_OK;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+ if (!hDrcDec->status) {
+ return DRC_DEC_OK;
+ }
+
+ dErr = drcDec_readUniDrcGain(
+ hBitstream, &(hDrcDec->uniDrcConfig),
+ drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec),
+ drcDec_GainDecoder_GetDeltaTminDefault(hDrcDec->hGainDec),
+ &(hDrcDec->uniDrcGain));
+ if (dErr) return DRC_DEC_NOT_OK;
+
+ hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_ReadUniDrc(HANDLE_DRC_DECODER hDrcDec,
+ HANDLE_FDK_BITSTREAM hBitstream) {
+ DRC_ERROR dErr = DE_OK;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+ if (!hDrcDec->status) return DRC_DEC_NOT_READY;
+
+ dErr = drcDec_readUniDrc(
+ hBitstream, &(hDrcDec->uniDrcConfig), &(hDrcDec->loudnessInfoSet),
+ drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec),
+ drcDec_GainDecoder_GetDeltaTminDefault(hDrcDec->hGainDec),
+ &(hDrcDec->uniDrcGain));
+ if (dErr) return DRC_DEC_NOT_OK;
+
+ startSelectionProcess(hDrcDec);
+
+ hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD;
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_Preprocess(HANDLE_DRC_DECODER hDrcDec) {
+ DRC_ERROR dErr = DE_OK;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+ if (!hDrcDec->status) return DRC_DEC_NOT_READY;
+ if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
+
+ if (hDrcDec->status != DRC_DEC_NEW_GAIN_PAYLOAD) {
+ /* no new gain payload was read, e.g. during concalment or flushing.
+ Generate DRC gains based on the stored DRC gains of last frames */
+ drcDec_GainDecoder_Conceal(hDrcDec->hGainDec, &(hDrcDec->uniDrcConfig),
+ &(hDrcDec->uniDrcGain));
+ }
+
+ dErr = drcDec_GainDecoder_Preprocess(
+ hDrcDec->hGainDec, &(hDrcDec->uniDrcGain),
+ hDrcDec->selProcOutput.loudnessNormalizationGainDb,
+ hDrcDec->selProcOutput.boost, hDrcDec->selProcOutput.compress);
+ if (dErr) return DRC_DEC_NOT_OK;
+ hDrcDec->status = DRC_DEC_INTERPOLATION_PREPARED;
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_ProcessTime(HANDLE_DRC_DECODER hDrcDec, const int delaySamples,
+ const DRC_DEC_LOCATION drcLocation,
+ const int channelOffset, const int drcChannelOffset,
+ const int numChannelsProcessed, FIXP_DBL* realBuffer,
+ const int timeDataChannelOffset) {
+ DRC_ERROR dErr = DE_OK;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+ if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
+ if (hDrcDec->status != DRC_DEC_INTERPOLATION_PREPARED)
+ return DRC_DEC_NOT_READY;
+
+ dErr = drcDec_GainDecoder_ProcessTimeDomain(
+ hDrcDec->hGainDec, delaySamples, (GAIN_DEC_LOCATION)drcLocation,
+ channelOffset, drcChannelOffset, numChannelsProcessed,
+ timeDataChannelOffset, realBuffer);
+ if (dErr) return DRC_DEC_NOT_OK;
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_ProcessFreq(HANDLE_DRC_DECODER hDrcDec, const int delaySamples,
+ const DRC_DEC_LOCATION drcLocation,
+ const int channelOffset, const int drcChannelOffset,
+ const int numChannelsProcessed,
+ const int processSingleTimeslot, FIXP_DBL** realBuffer,
+ FIXP_DBL** imagBuffer) {
+ DRC_ERROR dErr = DE_OK;
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+ if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
+ if (hDrcDec->status != DRC_DEC_INTERPOLATION_PREPARED)
+ return DRC_DEC_NOT_READY;
+
+ dErr = drcDec_GainDecoder_ProcessSubbandDomain(
+ hDrcDec->hGainDec, delaySamples, (GAIN_DEC_LOCATION)drcLocation,
+ channelOffset, drcChannelOffset, numChannelsProcessed,
+ processSingleTimeslot, realBuffer, imagBuffer);
+ if (dErr) return DRC_DEC_NOT_OK;
+
+ return DRC_DEC_OK;
+}
+
+DRC_DEC_ERROR
+FDK_drcDec_ApplyDownmix(HANDLE_DRC_DECODER hDrcDec, int* reverseInChannelMap,
+ int* reverseOutChannelMap, FIXP_DBL* realBuffer,
+ int* pNChannels) {
+ SEL_PROC_OUTPUT* pSelProcOutput = &(hDrcDec->selProcOutput);
+ int baseChCnt = pSelProcOutput->baseChannelCount;
+ int targetChCnt = pSelProcOutput->targetChannelCount;
+ int frameSize, n, ic, oc;
+ FIXP_DBL tmp_out[8];
+ FIXP_DBL* audioChannels[8];
+
+ if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
+ if (!(hDrcDec->functionalRange & DRC_DEC_GAIN)) return DRC_DEC_NOT_OK;
+
+ /* only downmix is performed here, no upmix.
+ Downmix is only performed if downmix coefficients are provided.
+ All other cases of downmix and upmix are treated by pcmDmx library. */
+ if (pSelProcOutput->downmixMatrixPresent == 0)
+ return DRC_DEC_OK; /* no downmix */
+ if (targetChCnt >= baseChCnt) return DRC_DEC_OK; /* downmix only */
+
+ /* sanity checks */
+ if (realBuffer == NULL) return DRC_DEC_NOT_OK;
+ if (reverseInChannelMap == NULL) return DRC_DEC_NOT_OK;
+ if (reverseOutChannelMap == NULL) return DRC_DEC_NOT_OK;
+ if (baseChCnt > 8) return DRC_DEC_NOT_OK;
+ if (baseChCnt != *pNChannels) return DRC_DEC_NOT_OK;
+ if (targetChCnt > 8) return DRC_DEC_NOT_OK;
+
+ frameSize = drcDec_GainDecoder_GetFrameSize(hDrcDec->hGainDec);
+
+ for (ic = 0; ic < baseChCnt; ic++) {
+ audioChannels[ic] = &(realBuffer[ic * frameSize]);
+ }
+
+ /* in-place downmix */
+ for (n = 0; n < frameSize; n++) {
+ for (oc = 0; oc < targetChCnt; oc++) {
+ tmp_out[oc] = (FIXP_DBL)0;
+ for (ic = 0; ic < baseChCnt; ic++) {
+ tmp_out[oc] +=
+ fMultDiv2(audioChannels[ic][n],
+ pSelProcOutput->downmixMatrix[reverseInChannelMap[ic]]
+ [reverseOutChannelMap[oc]])
+ << 3;
+ }
+ }
+ for (oc = 0; oc < targetChCnt; oc++) {
+ if (oc >= baseChCnt) break;
+ audioChannels[oc][n] = tmp_out[oc];
+ }
+ }
+
+ for (oc = targetChCnt; oc < baseChCnt; oc++) {
+ FDKmemset(audioChannels[oc], 0, frameSize * sizeof(FIXP_DBL));
+ }
+
+ *pNChannels = targetChCnt;
+
+ return DRC_DEC_OK;
+}
+
+/* Get library info for this module. */
+DRC_DEC_ERROR
+FDK_drcDec_GetLibInfo(LIB_INFO* info) {
+ int i;
+
+ if (info == NULL) {
+ return DRC_DEC_INVALID_PARAM;
+ }
+
+ /* Search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) {
+ return DRC_DEC_NOT_OK;
+ }
+
+ /* Add the library info */
+ info[i].module_id = FDK_UNIDRCDEC;
+ info[i].version = LIB_VERSION(DRCDEC_LIB_VL0, DRCDEC_LIB_VL1, DRCDEC_LIB_VL2);
+ LIB_VERSION_STRING(info + i);
+ info[i].build_date = DRCDEC_LIB_BUILD_DATE;
+ info[i].build_time = DRCDEC_LIB_BUILD_TIME;
+ info[i].title = DRCDEC_LIB_TITLE;
+
+ return DRC_DEC_OK;
+}
diff --git a/fdk-aac/libDRCdec/src/drcDec_gainDecoder.cpp b/fdk-aac/libDRCdec/src/drcDec_gainDecoder.cpp
new file mode 100644
index 0000000..ca81fad
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDec_gainDecoder.cpp
@@ -0,0 +1,445 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "drcDec_types.h"
+#include "drcDec_gainDecoder.h"
+#include "drcGainDec_preprocess.h"
+#include "drcGainDec_init.h"
+#include "drcGainDec_process.h"
+#include "drcDec_tools.h"
+
+/*******************************************/
+/* static functions */
+/*******************************************/
+
+static int _fitsLocation(DRC_INSTRUCTIONS_UNI_DRC* pInst,
+ const GAIN_DEC_LOCATION drcLocation) {
+ int downmixId = pInst->drcApplyToDownmix ? pInst->downmixId[0] : 0;
+ switch (drcLocation) {
+ case GAIN_DEC_DRC1:
+ return (downmixId == 0);
+ case GAIN_DEC_DRC1_DRC2:
+ return ((downmixId == 0) || (downmixId == DOWNMIX_ID_ANY_DOWNMIX));
+ case GAIN_DEC_DRC2:
+ return (downmixId == DOWNMIX_ID_ANY_DOWNMIX);
+ case GAIN_DEC_DRC3:
+ return ((downmixId != 0) && (downmixId != DOWNMIX_ID_ANY_DOWNMIX));
+ case GAIN_DEC_DRC2_DRC3:
+ return (downmixId != 0);
+ }
+ return 0;
+}
+
+static void _setChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,
+ const int numChannelGains,
+ const FIXP_DBL* channelGainDb) {
+ int i, channelGain_e;
+ FIXP_DBL channelGain;
+ FDK_ASSERT(numChannelGains <= 8);
+ for (i = 0; i < numChannelGains; i++) {
+ if (channelGainDb[i] == (FIXP_DBL)MINVAL_DBL) {
+ hGainDec->channelGain[i] = (FIXP_DBL)0;
+ } else {
+ /* add loudness normalisation gain (dB) to channel gain (dB) */
+ FIXP_DBL tmp_channelGainDb = (channelGainDb[i] >> 1) +
+ (hGainDec->loudnessNormalisationGainDb >> 2);
+ tmp_channelGainDb =
+ SATURATE_LEFT_SHIFT(tmp_channelGainDb, 1, DFRACT_BITS);
+ channelGain = dB2lin(tmp_channelGainDb, 8, &channelGain_e);
+ hGainDec->channelGain[i] = scaleValue(channelGain, channelGain_e - 8);
+ }
+ }
+}
+
+/*******************************************/
+/* public functions */
+/*******************************************/
+
+DRC_ERROR
+drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER* phGainDec) {
+ DRC_GAIN_DECODER* hGainDec = NULL;
+
+ hGainDec = (DRC_GAIN_DECODER*)FDKcalloc(1, sizeof(DRC_GAIN_DECODER));
+ if (hGainDec == NULL) return DE_MEMORY_ERROR;
+
+ hGainDec->multiBandActiveDrcIndex = -1;
+ hGainDec->channelGainActiveDrcIndex = -1;
+
+ *phGainDec = hGainDec;
+
+ return DE_OK;
+}
+
+DRC_ERROR
+drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
+ const int sampleRate) {
+ DRC_ERROR err = DE_OK;
+
+ err = initGainDec(hGainDec, frameSize, sampleRate);
+ if (err) return err;
+
+ initDrcGainBuffers(hGainDec->frameSize, &hGainDec->drcGainBuffers);
+
+ return err;
+}
+
+DRC_ERROR
+drcDec_GainDecoder_SetCodecDependentParameters(
+ HANDLE_DRC_GAIN_DECODER hGainDec, const DELAY_MODE delayMode,
+ const int timeDomainSupported,
+ const SUBBAND_DOMAIN_MODE subbandDomainSupported) {
+ if ((delayMode != DM_REGULAR_DELAY) && (delayMode != DM_LOW_DELAY)) {
+ return DE_NOT_OK;
+ }
+ hGainDec->delayMode = delayMode;
+ hGainDec->timeDomainSupported = timeDomainSupported;
+ hGainDec->subbandDomainSupported = subbandDomainSupported;
+
+ return DE_OK;
+}
+
+DRC_ERROR
+drcDec_GainDecoder_Config(HANDLE_DRC_GAIN_DECODER hGainDec,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ const UCHAR numSelectedDrcSets,
+ const SCHAR* selectedDrcSetIds,
+ const UCHAR* selectedDownmixIds) {
+ DRC_ERROR err = DE_OK;
+ int a;
+
+ hGainDec->nActiveDrcs = 0;
+ hGainDec->multiBandActiveDrcIndex = -1;
+ hGainDec->channelGainActiveDrcIndex = -1;
+ for (a = 0; a < numSelectedDrcSets; a++) {
+ err = initActiveDrc(hGainDec, hUniDrcConfig, selectedDrcSetIds[a],
+ selectedDownmixIds[a]);
+ if (err) return err;
+ }
+
+ err = initActiveDrcOffset(hGainDec);
+ if (err) return err;
+
+ return err;
+}
+
+DRC_ERROR
+drcDec_GainDecoder_Close(HANDLE_DRC_GAIN_DECODER* phGainDec) {
+ if (*phGainDec != NULL) {
+ FDKfree(*phGainDec);
+ *phGainDec = NULL;
+ }
+
+ return DE_OK;
+}
+
+DRC_ERROR
+drcDec_GainDecoder_Preprocess(HANDLE_DRC_GAIN_DECODER hGainDec,
+ HANDLE_UNI_DRC_GAIN hUniDrcGain,
+ const FIXP_DBL loudnessNormalizationGainDb,
+ const FIXP_SGL boost, const FIXP_SGL compress) {
+ DRC_ERROR err = DE_OK;
+ int a, c;
+
+ /* lnbPointer is the index on the most recent node buffer */
+ hGainDec->drcGainBuffers.lnbPointer++;
+ if (hGainDec->drcGainBuffers.lnbPointer >= NUM_LNB_FRAMES)
+ hGainDec->drcGainBuffers.lnbPointer = 0;
+
+ for (a = 0; a < hGainDec->nActiveDrcs; a++) {
+ /* prepare gain interpolation of sequences used by copying and modifying
+ * nodes in node buffers */
+ err = prepareDrcGain(hGainDec, hUniDrcGain, compress, boost,
+ loudnessNormalizationGainDb, a);
+ if (err) return err;
+ }
+
+ for (a = 0; a < MAX_ACTIVE_DRCS; a++) {
+ for (c = 0; c < 8; c++) {
+ hGainDec->activeDrc[a]
+ .lnbIndexForChannel[c][hGainDec->drcGainBuffers.lnbPointer] =
+ -1; /* "no DRC processing" */
+ }
+ hGainDec->activeDrc[a].subbandGainsReady = 0;
+ }
+
+ for (c = 0; c < 8; c++) {
+ hGainDec->drcGainBuffers
+ .channelGain[c][hGainDec->drcGainBuffers.lnbPointer] =
+ FL2FXCONST_DBL(1.0f / (float)(1 << 8));
+ }
+
+ return err;
+}
+
+/* create gain sequence out of gain sequences of last frame for concealment and
+ * flushing */
+DRC_ERROR
+drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_UNI_DRC_GAIN hUniDrcGain) {
+ int seq, gainSequenceCount;
+ DRC_COEFFICIENTS_UNI_DRC* pCoef =
+ selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
+ if (pCoef == NULL) return DE_OK;
+
+ gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
+
+ for (seq = 0; seq < gainSequenceCount; seq++) {
+ int lastNodeIndex = 0;
+ FIXP_SGL lastGainDb = (FIXP_SGL)0;
+
+ lastNodeIndex = hUniDrcGain->nNodes[seq] - 1;
+ if ((lastNodeIndex >= 0) && (lastNodeIndex < 16)) {
+ lastGainDb = hUniDrcGain->gainNode[seq][lastNodeIndex].gainDb;
+ }
+
+ hUniDrcGain->nNodes[seq] = 1;
+ if (lastGainDb > (FIXP_SGL)0) {
+ hUniDrcGain->gainNode[seq][0].gainDb =
+ FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.9f), lastGainDb));
+ } else {
+ hUniDrcGain->gainNode[seq][0].gainDb =
+ FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.98f), lastGainDb));
+ }
+ hUniDrcGain->gainNode[seq][0].time = hGainDec->frameSize - 1;
+ }
+ return DE_OK;
+}
+
+void drcDec_GainDecoder_SetChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,
+ const int numChannels,
+ const int frameSize,
+ const FIXP_DBL* channelGainDb,
+ const int audioBufferChannelOffset,
+ FIXP_DBL* audioBuffer) {
+ int c, i;
+
+ if (hGainDec->channelGainActiveDrcIndex >= 0) {
+ /* channel gains will be applied in drcDec_GainDecoder_ProcessTimeDomain or
+ * drcDec_GainDecoder_ProcessSubbandDomain, respectively. */
+ _setChannelGains(hGainDec, numChannels, channelGainDb);
+
+ if (!hGainDec->status) { /* overwrite previous channel gains at startup */
+ DRC_GAIN_BUFFERS* pDrcGainBuffers = &hGainDec->drcGainBuffers;
+ for (c = 0; c < numChannels; c++) {
+ for (i = 0; i < NUM_LNB_FRAMES; i++) {
+ pDrcGainBuffers->channelGain[c][i] = hGainDec->channelGain[c];
+ }
+ }
+ hGainDec->status = 1;
+ }
+ } else {
+ /* smooth and apply channel gains */
+ FIXP_DBL prevChannelGain[8];
+ for (c = 0; c < numChannels; c++) {
+ prevChannelGain[c] = hGainDec->channelGain[c];
+ }
+
+ _setChannelGains(hGainDec, numChannels, channelGainDb);
+
+ if (!hGainDec->status) { /* overwrite previous channel gains at startup */
+ for (c = 0; c < numChannels; c++)
+ prevChannelGain[c] = hGainDec->channelGain[c];
+ hGainDec->status = 1;
+ }
+
+ for (c = 0; c < numChannels; c++) {
+ INT n_min = fMin(fMin(CntLeadingZeros(prevChannelGain[c]),
+ CntLeadingZeros(hGainDec->channelGain[c])) -
+ 1,
+ 9);
+ FIXP_DBL gain = prevChannelGain[c] << n_min;
+ FIXP_DBL stepsize = ((hGainDec->channelGain[c] << n_min) - gain);
+ if (stepsize != (FIXP_DBL)0) {
+ if (frameSize == 1024)
+ stepsize = stepsize >> 10;
+ else
+ stepsize = (LONG)stepsize / frameSize;
+ }
+ n_min = 9 - n_min;
+#ifdef FUNCTION_drcDec_GainDecoder_SetChannelGains_func1
+ drcDec_GainDecoder_SetChannelGains_func1(audioBuffer, gain, stepsize,
+ n_min, frameSize);
+#else
+ for (i = 0; i < frameSize; i++) {
+ audioBuffer[i] = fMultDiv2(audioBuffer[i], gain) << n_min;
+ gain += stepsize;
+ }
+#endif
+ audioBuffer += audioBufferChannelOffset;
+ }
+ }
+}
+
+DRC_ERROR
+drcDec_GainDecoder_ProcessTimeDomain(
+ HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
+ const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
+ const int drcChannelOffset, const int numChannelsProcessed,
+ const int timeDataChannelOffset, FIXP_DBL* audioIOBuffer) {
+ DRC_ERROR err = DE_OK;
+ int a;
+
+ if (!hGainDec->timeDomainSupported) {
+ return DE_NOT_OK;
+ }
+
+ for (a = 0; a < hGainDec->nActiveDrcs; a++) {
+ if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
+
+ /* Apply DRC */
+ err = processDrcTime(hGainDec, a, delaySamples, channelOffset,
+ drcChannelOffset, numChannelsProcessed,
+ timeDataChannelOffset, audioIOBuffer);
+ if (err) return err;
+ }
+
+ return err;
+}
+
+DRC_ERROR
+drcDec_GainDecoder_ProcessSubbandDomain(
+ HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
+ const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
+ const int drcChannelOffset, const int numChannelsProcessed,
+ const int processSingleTimeslot, FIXP_DBL* audioIOBufferReal[],
+ FIXP_DBL* audioIOBufferImag[]) {
+ DRC_ERROR err = DE_OK;
+ int a;
+
+ if (hGainDec->subbandDomainSupported == SDM_OFF) {
+ return DE_NOT_OK;
+ }
+
+ for (a = 0; a < hGainDec->nActiveDrcs; a++) {
+ if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
+
+ /* Apply DRC */
+ err = processDrcSubband(hGainDec, a, delaySamples, channelOffset,
+ drcChannelOffset, numChannelsProcessed,
+ processSingleTimeslot, audioIOBufferReal,
+ audioIOBufferImag);
+ if (err) return err;
+ }
+
+ return err;
+}
+
+DRC_ERROR
+drcDec_GainDecoder_SetLoudnessNormalizationGainDb(
+ HANDLE_DRC_GAIN_DECODER hGainDec, FIXP_DBL loudnessNormalizationGainDb) {
+ hGainDec->loudnessNormalisationGainDb = loudnessNormalizationGainDb;
+
+ return DE_OK;
+}
+
+int drcDec_GainDecoder_GetFrameSize(HANDLE_DRC_GAIN_DECODER hGainDec) {
+ if (hGainDec == NULL) return -1;
+
+ return hGainDec->frameSize;
+}
+
+int drcDec_GainDecoder_GetDeltaTminDefault(HANDLE_DRC_GAIN_DECODER hGainDec) {
+ if (hGainDec == NULL) return -1;
+
+ return hGainDec->deltaTminDefault;
+}
diff --git a/fdk-aac/libDRCdec/src/drcDec_gainDecoder.h b/fdk-aac/libDRCdec/src/drcDec_gainDecoder.h
new file mode 100644
index 0000000..2f4df4c
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDec_gainDecoder.h
@@ -0,0 +1,264 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef DRCDEC_GAINDECODER_H
+#define DRCDEC_GAINDECODER_H
+
+#include "drcDecoder.h"
+
+/* Definitions common to gainDecoder submodule */
+
+#define NUM_LNB_FRAMES \
+ 5 /* previous frame + this frame + one frame for DM_REGULAR_DELAY + (maximum \
+ delaySamples)/frameSize */
+
+/* QMF64 */
+#define SUBBAND_NUM_BANDS_QMF64 64
+#define SUBBAND_DOWNSAMPLING_FACTOR_QMF64 64
+#define SUBBAND_ANALYSIS_DELAY_QMF64 320
+
+/* QMF71 (according to ISO/IEC 23003-1:2007) */
+#define SUBBAND_NUM_BANDS_QMF71 71
+#define SUBBAND_DOWNSAMPLING_FACTOR_QMF71 64
+#define SUBBAND_ANALYSIS_DELAY_QMF71 320 + 384
+
+/* STFT256 (according to ISO/IEC 23008-3:2015/AMD3) */
+#define SUBBAND_NUM_BANDS_STFT256 256
+#define SUBBAND_DOWNSAMPLING_FACTOR_STFT256 256
+#define SUBBAND_ANALYSIS_DELAY_STFT256 256
+
+typedef enum {
+ GAIN_DEC_DRC1,
+ GAIN_DEC_DRC1_DRC2,
+ GAIN_DEC_DRC2,
+ GAIN_DEC_DRC3,
+ GAIN_DEC_DRC2_DRC3
+} GAIN_DEC_LOCATION;
+
+typedef struct {
+ FIXP_DBL gainLin; /* e = 7 */
+ SHORT time;
+} NODE_LIN;
+
+typedef struct {
+ GAIN_INTERPOLATION_TYPE gainInterpolationType;
+ int nNodes[NUM_LNB_FRAMES]; /* number of nodes, saturated to 16 */
+ NODE_LIN linearNode[NUM_LNB_FRAMES][16];
+} LINEAR_NODE_BUFFER;
+
+typedef struct {
+ int lnbPointer;
+ LINEAR_NODE_BUFFER linearNodeBuffer[12];
+ LINEAR_NODE_BUFFER dummyLnb;
+ FIXP_DBL channelGain[8][NUM_LNB_FRAMES]; /* e = 8 */
+} DRC_GAIN_BUFFERS;
+
+typedef struct {
+ int activeDrcOffset;
+ DRC_INSTRUCTIONS_UNI_DRC* pInst;
+ DRC_COEFFICIENTS_UNI_DRC* pCoef;
+
+ DUCKING_MODIFICATION duckingModificationForChannelGroup[8];
+ SCHAR channelGroupForChannel[8];
+
+ UCHAR bandCountForChannelGroup[8];
+ UCHAR gainElementForGroup[8];
+ UCHAR channelGroupIsParametricDrc[8];
+ UCHAR gainElementCount; /* number of different DRC gains inluding all DRC
+ bands */
+ int lnbIndexForChannel[8][NUM_LNB_FRAMES];
+ int subbandGainsReady;
+} ACTIVE_DRC;
+
+typedef struct {
+ int deltaTminDefault;
+ INT frameSize;
+ FIXP_DBL loudnessNormalisationGainDb;
+ DELAY_MODE delayMode;
+
+ int nActiveDrcs;
+ ACTIVE_DRC activeDrc[MAX_ACTIVE_DRCS];
+ int multiBandActiveDrcIndex;
+ int channelGainActiveDrcIndex;
+ FIXP_DBL channelGain[8]; /* e = 8 */
+
+ DRC_GAIN_BUFFERS drcGainBuffers;
+ FIXP_DBL subbandGains[12][4 * 1024 / 256];
+ FIXP_DBL dummySubbandGains[4 * 1024 / 256];
+
+ int status;
+ int timeDomainSupported;
+ SUBBAND_DOMAIN_MODE subbandDomainSupported;
+} DRC_GAIN_DECODER, *HANDLE_DRC_GAIN_DECODER;
+
+/* init functions */
+DRC_ERROR
+drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER* phGainDec);
+
+DRC_ERROR
+drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
+ const int sampleRate);
+
+DRC_ERROR
+drcDec_GainDecoder_SetCodecDependentParameters(
+ HANDLE_DRC_GAIN_DECODER hGainDec, const DELAY_MODE delayMode,
+ const int timeDomainSupported,
+ const SUBBAND_DOMAIN_MODE subbandDomainSupported);
+
+DRC_ERROR
+drcDec_GainDecoder_Config(HANDLE_DRC_GAIN_DECODER hGainDec,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ const UCHAR numSelectedDrcSets,
+ const SCHAR* selectedDrcSetIds,
+ const UCHAR* selectedDownmixIds);
+
+/* close functions */
+DRC_ERROR
+drcDec_GainDecoder_Close(HANDLE_DRC_GAIN_DECODER* phGainDec);
+
+/* process functions */
+
+/* call drcDec_GainDecoder_Preprocess first */
+DRC_ERROR
+drcDec_GainDecoder_Preprocess(HANDLE_DRC_GAIN_DECODER hGainDec,
+ HANDLE_UNI_DRC_GAIN hUniDrcGain,
+ const FIXP_DBL loudnessNormalizationGainDb,
+ const FIXP_SGL boost, const FIXP_SGL compress);
+
+/* Then call one of drcDec_GainDecoder_ProcessTimeDomain or
+ * drcDec_GainDecoder_ProcessSubbandDomain */
+DRC_ERROR
+drcDec_GainDecoder_ProcessTimeDomain(
+ HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
+ const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
+ const int drcChannelOffset, const int numChannelsProcessed,
+ const int timeDataChannelOffset, FIXP_DBL* audioIOBuffer);
+
+DRC_ERROR
+drcDec_GainDecoder_ProcessSubbandDomain(
+ HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
+ GAIN_DEC_LOCATION drcLocation, const int channelOffset,
+ const int drcChannelOffset, const int numChannelsProcessed,
+ const int processSingleTimeslot, FIXP_DBL* audioIOBufferReal[],
+ FIXP_DBL* audioIOBufferImag[]);
+
+DRC_ERROR
+drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_UNI_DRC_GAIN hUniDrcGain);
+
+DRC_ERROR
+drcDec_GainDecoder_SetLoudnessNormalizationGainDb(
+ HANDLE_DRC_GAIN_DECODER hGainDec, FIXP_DBL loudnessNormalizationGainDb);
+
+int drcDec_GainDecoder_GetFrameSize(HANDLE_DRC_GAIN_DECODER hGainDec);
+
+int drcDec_GainDecoder_GetDeltaTminDefault(HANDLE_DRC_GAIN_DECODER hGainDec);
+
+void drcDec_GainDecoder_SetChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,
+ const int numChannels,
+ const int frameSize,
+ const FIXP_DBL* channelGainDb,
+ const int audioBufferChannelOffset,
+ FIXP_DBL* audioBuffer);
+
+#endif
diff --git a/fdk-aac/libDRCdec/src/drcDec_reader.cpp b/fdk-aac/libDRCdec/src/drcDec_reader.cpp
new file mode 100644
index 0000000..6fe7a04
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDec_reader.cpp
@@ -0,0 +1,2029 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "fixpoint_math.h"
+#include "drcDec_reader.h"
+#include "drcDec_tools.h"
+#include "drcDec_rom.h"
+#include "drcDecoder.h"
+
+/* MPEG-D DRC AMD 1 */
+
+#define UNIDRCCONFEXT_PARAM_DRC 0x1
+#define UNIDRCCONFEXT_V1 0x2
+#define UNIDRCLOUDEXT_EQ 0x1
+
+#define UNIDRCGAINEXT_TERM 0x0
+#define UNIDRCLOUDEXT_TERM 0x0
+#define UNIDRCCONFEXT_TERM 0x0
+
+static int _getZ(const int nNodesMax) {
+ /* Z is the minimum codeword length that is needed to encode all possible
+ * timeDelta values */
+ /* Z = ceil(log2(2*nNodesMax)) */
+ int Z = 1;
+ while ((1 << Z) < (2 * nNodesMax)) {
+ Z++;
+ }
+ return Z;
+}
+
+static int _getTimeDeltaMin(const GAIN_SET* pGset, const int deltaTminDefault) {
+ if (pGset->timeDeltaMinPresent) {
+ return pGset->timeDeltaMin;
+ } else {
+ return deltaTminDefault;
+ }
+}
+
+/* compare and assign */
+static inline int _compAssign(UCHAR* dest, const UCHAR src) {
+ int diff = 0;
+ if (*dest != src) diff = 1;
+ *dest = src;
+ return diff;
+}
+
+static inline int _compAssign(ULONG* dest, const ULONG src) {
+ int diff = 0;
+ if (*dest != src) diff = 1;
+ *dest = src;
+ return diff;
+}
+
+typedef const SCHAR (*Huffman)[2];
+
+int _decodeHuffmanCW(Huffman h, /*!< pointer to huffman codebook table */
+ HANDLE_FDK_BITSTREAM hBs) /*!< Handle to bitbuffer */
+{
+ SCHAR index = 0;
+ int value, bit;
+
+ while (index >= 0) {
+ bit = FDKreadBits(hBs, 1);
+ index = h[index][bit];
+ }
+
+ value = index + 64; /* Add offset */
+
+ return value;
+}
+
+/**********/
+/* uniDrc */
+/**********/
+
+DRC_ERROR
+drcDec_readUniDrc(HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ const int frameSize, const int deltaTminDefault,
+ HANDLE_UNI_DRC_GAIN hUniDrcGain) {
+ DRC_ERROR err = DE_OK;
+ int loudnessInfoSetPresent, uniDrcConfigPresent;
+
+ loudnessInfoSetPresent = FDKreadBits(hBs, 1);
+ if (loudnessInfoSetPresent) {
+ uniDrcConfigPresent = FDKreadBits(hBs, 1);
+ if (uniDrcConfigPresent) {
+ err = drcDec_readUniDrcConfig(hBs, hUniDrcConfig);
+ if (err) return err;
+ }
+ err = drcDec_readLoudnessInfoSet(hBs, hLoudnessInfoSet);
+ if (err) return err;
+ }
+
+ if (hUniDrcGain != NULL) {
+ err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault,
+ hUniDrcGain);
+ if (err) return err;
+ }
+
+ return err;
+}
+
+/**************/
+/* uniDrcGain */
+/**************/
+
+static FIXP_SGL _decodeGainInitial(
+ HANDLE_FDK_BITSTREAM hBs, const GAIN_CODING_PROFILE gainCodingProfile) {
+ int sign, magn;
+ FIXP_SGL gainInitial = (FIXP_SGL)0;
+ switch (gainCodingProfile) {
+ case GCP_REGULAR:
+ sign = FDKreadBits(hBs, 1);
+ magn = FDKreadBits(hBs, 8);
+
+ gainInitial =
+ (FIXP_SGL)(magn << (FRACT_BITS - 1 - 3 - 7)); /* magn * 0.125; */
+ if (sign) gainInitial = -gainInitial;
+ break;
+ case GCP_FADING:
+ sign = FDKreadBits(hBs, 1);
+ if (sign == 0)
+ gainInitial = (FIXP_SGL)0;
+ else {
+ magn = FDKreadBits(hBs, 10);
+ gainInitial = -(FIXP_SGL)(
+ (magn + 1) << (FRACT_BITS - 1 - 3 - 7)); /* - (magn + 1) * 0.125; */
+ }
+ break;
+ case GCP_CLIPPING_DUCKING:
+ sign = FDKreadBits(hBs, 1);
+ if (sign == 0)
+ gainInitial = (FIXP_SGL)0;
+ else {
+ magn = FDKreadBits(hBs, 8);
+ gainInitial = -(FIXP_SGL)(
+ (magn + 1) << (FRACT_BITS - 1 - 3 - 7)); /* - (magn + 1) * 0.125; */
+ }
+ break;
+ case GCP_CONSTANT:
+ break;
+ }
+ return gainInitial;
+}
+
+static int _decodeNNodes(HANDLE_FDK_BITSTREAM hBs) {
+ int nNodes = 0, endMarker = 0;
+
+ /* decode number of nodes */
+ while (endMarker != 1) {
+ nNodes++;
+ if (nNodes >= 128) break;
+ endMarker = FDKreadBits(hBs, 1);
+ }
+ return nNodes;
+}
+
+static void _decodeGains(HANDLE_FDK_BITSTREAM hBs,
+ const GAIN_CODING_PROFILE gainCodingProfile,
+ const int nNodes, GAIN_NODE* pNodes) {
+ int k, deltaGain;
+ Huffman deltaGainCodebook;
+
+ pNodes[0].gainDb = _decodeGainInitial(hBs, gainCodingProfile);
+
+ if (gainCodingProfile == GCP_CLIPPING_DUCKING) {
+ deltaGainCodebook = (Huffman)&deltaGain_codingProfile_2_huffman;
+ } else {
+ deltaGainCodebook = (Huffman)&deltaGain_codingProfile_0_1_huffman;
+ }
+
+ for (k = 1; k < nNodes; k++) {
+ deltaGain = _decodeHuffmanCW(deltaGainCodebook, hBs);
+ if (k >= 16) continue;
+ /* gain_dB_e = 7 */
+ pNodes[k].gainDb =
+ pNodes[k - 1].gainDb +
+ (FIXP_SGL)(deltaGain << (FRACT_BITS - 1 - 7 -
+ 3)); /* pNodes[k-1].gainDb + 0.125*deltaGain */
+ }
+}
+
+static void _decodeSlopes(HANDLE_FDK_BITSTREAM hBs,
+ const GAIN_INTERPOLATION_TYPE gainInterpolationType,
+ const int nNodes, GAIN_NODE* pNodes) {
+ int k = 0;
+
+ if (gainInterpolationType == GIT_SPLINE) {
+ /* decode slope steepness */
+ for (k = 0; k < nNodes; k++) {
+ _decodeHuffmanCW((Huffman)&slopeSteepness_huffman, hBs);
+ }
+ }
+}
+
+static int _decodeTimeDelta(HANDLE_FDK_BITSTREAM hBs, const int Z) {
+ int prefix, mu;
+
+ prefix = FDKreadBits(hBs, 2);
+ switch (prefix) {
+ case 0x0:
+ return 1;
+ case 0x1:
+ mu = FDKreadBits(hBs, 2);
+ return mu + 2;
+ case 0x2:
+ mu = FDKreadBits(hBs, 3);
+ return mu + 6;
+ case 0x3:
+ mu = FDKreadBits(hBs, Z);
+ return mu + 14;
+ default:
+ return 0;
+ }
+}
+
+static void _decodeTimes(HANDLE_FDK_BITSTREAM hBs, const int deltaTmin,
+ const int frameSize, const int fullFrame,
+ const int timeOffset, const int Z, const int nNodes,
+ GAIN_NODE* pNodes) {
+ int timeDelta, k;
+ int timeOffs = timeOffset;
+ int frameEndFlag, nodeTimeTmp, nodeResFlag;
+
+ if (fullFrame == 0) {
+ frameEndFlag = FDKreadBits(hBs, 1);
+ } else {
+ frameEndFlag = 1;
+ }
+
+ if (frameEndFlag ==
+ 1) { /* frameEndFlag == 1 signals that the last node is at the end of the
+ DRC frame */
+ nodeResFlag = 0;
+ for (k = 0; k < nNodes - 1; k++) {
+ /* decode a delta time value */
+ timeDelta = _decodeTimeDelta(hBs, Z);
+ if (k >= (16 - 1)) continue;
+ /* frameEndFlag == 1 needs special handling for last node with node
+ * reservoir */
+ nodeTimeTmp = timeOffs + timeDelta * deltaTmin;
+ if (nodeTimeTmp > frameSize + timeOffset) {
+ if (nodeResFlag == 0) {
+ pNodes[k].time = frameSize + timeOffset;
+ nodeResFlag = 1;
+ }
+ pNodes[k + 1].time = nodeTimeTmp;
+ } else {
+ pNodes[k].time = nodeTimeTmp;
+ }
+ timeOffs = nodeTimeTmp;
+ }
+ if (nodeResFlag == 0) {
+ k = fMin(k, 16 - 1);
+ pNodes[k].time = frameSize + timeOffset;
+ }
+ } else {
+ for (k = 0; k < nNodes; k++) {
+ /* decode a delta time value */
+ timeDelta = _decodeTimeDelta(hBs, Z);
+ if (k >= 16) continue;
+ pNodes[k].time = timeOffs + timeDelta * deltaTmin;
+ timeOffs = pNodes[k].time;
+ }
+ }
+}
+
+static void _readNodes(HANDLE_FDK_BITSTREAM hBs, GAIN_SET* gainSet,
+ const int frameSize, const int timeDeltaMin,
+ UCHAR* pNNodes, GAIN_NODE* pNodes) {
+ int timeOffset, drcGainCodingMode, nNodes;
+ int Z = _getZ(frameSize / timeDeltaMin);
+ if (gainSet->timeAlignment == 0) {
+ timeOffset = -1;
+ } else {
+ timeOffset = -timeDeltaMin +
+ (timeDeltaMin - 1) /
+ 2; /* timeOffset = - deltaTmin + floor((deltaTmin-1)/2); */
+ }
+
+ drcGainCodingMode = FDKreadBits(hBs, 1);
+ if (drcGainCodingMode == 0) {
+ /* "simple" mode: only one node at the end of the frame with slope = 0 */
+ nNodes = 1;
+ pNodes[0].gainDb = _decodeGainInitial(
+ hBs, (GAIN_CODING_PROFILE)gainSet->gainCodingProfile);
+ pNodes[0].time = frameSize + timeOffset;
+ } else {
+ nNodes = _decodeNNodes(hBs);
+
+ _decodeSlopes(hBs, (GAIN_INTERPOLATION_TYPE)gainSet->gainInterpolationType,
+ nNodes, pNodes);
+
+ _decodeTimes(hBs, timeDeltaMin, frameSize, gainSet->fullFrame, timeOffset,
+ Z, nNodes, pNodes);
+
+ _decodeGains(hBs, (GAIN_CODING_PROFILE)gainSet->gainCodingProfile, nNodes,
+ pNodes);
+ }
+ *pNNodes = (UCHAR)nNodes;
+}
+
+static void _readDrcGainSequence(HANDLE_FDK_BITSTREAM hBs, GAIN_SET* gainSet,
+ const int frameSize, const int timeDeltaMin,
+ UCHAR* pNNodes, GAIN_NODE pNodes[16]) {
+ SHORT timeBufPrevFrame[16], timeBufCurFrame[16];
+ int nNodesNodeRes, nNodesCur, k, m;
+
+ if (gainSet->gainCodingProfile == GCP_CONSTANT) {
+ *pNNodes = 1;
+ pNodes[0].time = frameSize - 1;
+ pNodes[0].gainDb = (FIXP_SGL)0;
+ } else {
+ _readNodes(hBs, gainSet, frameSize, timeDeltaMin, pNNodes, pNodes);
+
+ /* count number of nodes in node reservoir */
+ nNodesNodeRes = 0;
+ nNodesCur = 0;
+ /* count and buffer nodes from node reservoir */
+ for (k = 0; k < *pNNodes; k++) {
+ if (k >= 16) continue;
+ if (pNodes[k].time >= frameSize) {
+ /* write node reservoir times into buffer */
+ timeBufPrevFrame[nNodesNodeRes] = pNodes[k].time;
+ nNodesNodeRes++;
+ } else { /* times from current frame */
+ timeBufCurFrame[nNodesCur] = pNodes[k].time;
+ nNodesCur++;
+ }
+ }
+ /* compose right time order (bit reservoir first) */
+ for (k = 0; k < nNodesNodeRes; k++) {
+ /* subtract two time frameSize: one to remove node reservoir offset and
+ * one to get the negative index relative to the current frame
+ */
+ pNodes[k].time = timeBufPrevFrame[k] - 2 * frameSize;
+ }
+ /* ...and times from current frame */
+ for (m = 0; m < nNodesCur; m++, k++) {
+ pNodes[k].time = timeBufCurFrame[m];
+ }
+ }
+}
+
+static DRC_ERROR _readUniDrcGainExtension(HANDLE_FDK_BITSTREAM hBs,
+ UNI_DRC_GAIN_EXTENSION* pExt) {
+ DRC_ERROR err = DE_OK;
+ int k, bitSizeLen, extSizeBits, bitSize;
+
+ k = 0;
+ pExt->uniDrcGainExtType[k] = FDKreadBits(hBs, 4);
+ while (pExt->uniDrcGainExtType[k] != UNIDRCGAINEXT_TERM) {
+ if (k >= (8 - 1)) return DE_MEMORY_ERROR;
+ bitSizeLen = FDKreadBits(hBs, 3);
+ extSizeBits = bitSizeLen + 4;
+
+ bitSize = FDKreadBits(hBs, extSizeBits);
+ pExt->extBitSize[k] = bitSize + 1;
+
+ switch (pExt->uniDrcGainExtType[k]) {
+ /* add future extensions here */
+ default:
+ FDKpushFor(hBs, pExt->extBitSize[k]);
+ break;
+ }
+ k++;
+ pExt->uniDrcGainExtType[k] = FDKreadBits(hBs, 4);
+ }
+
+ return err;
+}
+
+DRC_ERROR
+drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int frameSize,
+ const int deltaTminDefault,
+ HANDLE_UNI_DRC_GAIN hUniDrcGain) {
+ DRC_ERROR err = DE_OK;
+ int seq, gainSequenceCount;
+ DRC_COEFFICIENTS_UNI_DRC* pCoef =
+ selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
+ if (pCoef == NULL) return DE_OK;
+ if (hUniDrcGain == NULL) return DE_OK; /* hUniDrcGain not initialized yet */
+
+ gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
+
+ for (seq = 0; seq < gainSequenceCount; seq++) {
+ UCHAR index = pCoef->gainSetIndexForGainSequence[seq];
+ GAIN_SET* gainSet;
+ int timeDeltaMin;
+ UCHAR tmpNNodes = 0;
+ GAIN_NODE tmpNodes[16];
+
+ if ((index >= pCoef->gainSetCount) || (index >= 12)) return DE_NOT_OK;
+ gainSet = &(pCoef->gainSet[index]);
+
+ timeDeltaMin = _getTimeDeltaMin(gainSet, deltaTminDefault);
+
+ _readDrcGainSequence(hBs, gainSet, frameSize, timeDeltaMin, &tmpNNodes,
+ tmpNodes);
+
+ hUniDrcGain->nNodes[seq] = tmpNNodes;
+ FDKmemcpy(hUniDrcGain->gainNode[seq], tmpNodes,
+ fMin(tmpNNodes, (UCHAR)16) * sizeof(GAIN_NODE));
+ }
+
+ hUniDrcGain->uniDrcGainExtPresent = FDKreadBits(hBs, 1);
+ if (hUniDrcGain->uniDrcGainExtPresent == 1) {
+ err = _readUniDrcGainExtension(hBs, &(hUniDrcGain->uniDrcGainExtension));
+ if (err) return err;
+ }
+
+ return err;
+}
+
+/****************/
+/* uniDrcConfig */
+/****************/
+
+static void _decodeDuckingModification(HANDLE_FDK_BITSTREAM hBs,
+ DUCKING_MODIFICATION* pDMod, int isBox) {
+ int bsDuckingScaling, sigma, mu;
+
+ if (isBox) FDKpushFor(hBs, 7); /* reserved */
+ pDMod->duckingScalingPresent = FDKreadBits(hBs, 1);
+
+ if (pDMod->duckingScalingPresent) {
+ if (isBox) FDKpushFor(hBs, 4); /* reserved */
+ bsDuckingScaling = FDKreadBits(hBs, 4);
+ sigma = bsDuckingScaling >> 3;
+ mu = bsDuckingScaling & 0x7;
+
+ if (sigma) {
+ pDMod->duckingScaling = (FIXP_SGL)(
+ (7 - mu) << (FRACT_BITS - 1 - 3 - 2)); /* 1.0 - 0.125 * (1 + mu); */
+ } else {
+ pDMod->duckingScaling = (FIXP_SGL)(
+ (9 + mu) << (FRACT_BITS - 1 - 3 - 2)); /* 1.0 + 0.125 * (1 + mu); */
+ }
+ } else {
+ pDMod->duckingScaling = (FIXP_SGL)(1 << (FRACT_BITS - 1 - 2)); /* 1.0 */
+ }
+}
+
+static void _decodeGainModification(HANDLE_FDK_BITSTREAM hBs, const int version,
+ int bandCount, GAIN_MODIFICATION* pGMod,
+ int isBox) {
+ int sign, bsGainOffset, bsAttenuationScaling, bsAmplificationScaling;
+
+ if (version > 0) {
+ int b, shapeFilterPresent;
+
+ if (isBox) {
+ FDKpushFor(hBs, 4); /* reserved */
+ bandCount = FDKreadBits(hBs, 4);
+ }
+
+ for (b = 0; b < bandCount; b++) {
+ if (isBox) {
+ FDKpushFor(hBs, 4); /* reserved */
+ pGMod[b].targetCharacteristicLeftPresent = FDKreadBits(hBs, 1);
+ pGMod[b].targetCharacteristicRightPresent = FDKreadBits(hBs, 1);
+ pGMod[b].gainScalingPresent = FDKreadBits(hBs, 1);
+ pGMod[b].gainOffsetPresent = FDKreadBits(hBs, 1);
+ }
+
+ if (!isBox)
+ pGMod[b].targetCharacteristicLeftPresent = FDKreadBits(hBs, 1);
+ if (pGMod[b].targetCharacteristicLeftPresent) {
+ if (isBox) FDKpushFor(hBs, 4); /* reserved */
+ pGMod[b].targetCharacteristicLeftIndex = FDKreadBits(hBs, 4);
+ }
+ if (!isBox)
+ pGMod[b].targetCharacteristicRightPresent = FDKreadBits(hBs, 1);
+ if (pGMod[b].targetCharacteristicRightPresent) {
+ if (isBox) FDKpushFor(hBs, 4); /* reserved */
+ pGMod[b].targetCharacteristicRightIndex = FDKreadBits(hBs, 4);
+ }
+ if (!isBox) pGMod[b].gainScalingPresent = FDKreadBits(hBs, 1);
+ if (pGMod[b].gainScalingPresent) {
+ bsAttenuationScaling = FDKreadBits(hBs, 4);
+ pGMod[b].attenuationScaling = (FIXP_SGL)(
+ bsAttenuationScaling
+ << (FRACT_BITS - 1 - 3 - 2)); /* bsAttenuationScaling * 0.125; */
+ bsAmplificationScaling = FDKreadBits(hBs, 4);
+ pGMod[b].amplificationScaling = (FIXP_SGL)(
+ bsAmplificationScaling
+ << (FRACT_BITS - 1 - 3 - 2)); /* bsAmplificationScaling * 0.125; */
+ }
+ if (!isBox) pGMod[b].gainOffsetPresent = FDKreadBits(hBs, 1);
+ if (pGMod[b].gainOffsetPresent) {
+ if (isBox) FDKpushFor(hBs, 2); /* reserved */
+ sign = FDKreadBits(hBs, 1);
+ bsGainOffset = FDKreadBits(hBs, 5);
+ pGMod[b].gainOffset = (FIXP_SGL)(
+ (1 + bsGainOffset)
+ << (FRACT_BITS - 1 - 2 - 4)); /* (1+bsGainOffset) * 0.25; */
+ if (sign) {
+ pGMod[b].gainOffset = -pGMod[b].gainOffset;
+ }
+ }
+ }
+ if (bandCount == 1) {
+ shapeFilterPresent = FDKreadBits(hBs, 1);
+ if (shapeFilterPresent) {
+ if (isBox) FDKpushFor(hBs, 3); /* reserved */
+ FDKpushFor(hBs, 4); /* pGMod->shapeFilterIndex */
+ } else {
+ if (isBox) FDKpushFor(hBs, 7); /* reserved */
+ }
+ }
+ } else {
+ int b, gainScalingPresent, gainOffsetPresent;
+ FIXP_SGL attenuationScaling = FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
+ amplificationScaling = FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
+ gainOffset = (FIXP_SGL)0;
+ if (isBox) FDKpushFor(hBs, 7); /* reserved */
+ gainScalingPresent = FDKreadBits(hBs, 1);
+ if (gainScalingPresent) {
+ bsAttenuationScaling = FDKreadBits(hBs, 4);
+ attenuationScaling = (FIXP_SGL)(
+ bsAttenuationScaling
+ << (FRACT_BITS - 1 - 3 - 2)); /* bsAttenuationScaling * 0.125; */
+ bsAmplificationScaling = FDKreadBits(hBs, 4);
+ amplificationScaling = (FIXP_SGL)(
+ bsAmplificationScaling
+ << (FRACT_BITS - 1 - 3 - 2)); /* bsAmplificationScaling * 0.125; */
+ }
+ if (isBox) FDKpushFor(hBs, 7); /* reserved */
+ gainOffsetPresent = FDKreadBits(hBs, 1);
+ if (gainOffsetPresent) {
+ if (isBox) FDKpushFor(hBs, 2); /* reserved */
+ sign = FDKreadBits(hBs, 1);
+ bsGainOffset = FDKreadBits(hBs, 5);
+ gainOffset =
+ (FIXP_SGL)((1 + bsGainOffset) << (FRACT_BITS - 1 - 2 -
+ 4)); /* (1+bsGainOffset) * 0.25; */
+ if (sign) {
+ gainOffset = -gainOffset;
+ }
+ }
+ for (b = 0; b < 4; b++) {
+ pGMod[b].targetCharacteristicLeftPresent = 0;
+ pGMod[b].targetCharacteristicRightPresent = 0;
+ pGMod[b].gainScalingPresent = gainScalingPresent;
+ pGMod[b].attenuationScaling = attenuationScaling;
+ pGMod[b].amplificationScaling = amplificationScaling;
+ pGMod[b].gainOffsetPresent = gainOffsetPresent;
+ pGMod[b].gainOffset = gainOffset;
+ }
+ }
+}
+
+static void _readDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs, const int version,
+ DRC_CHARACTERISTIC* pDChar, int isBox) {
+ if (version == 0) {
+ if (isBox) FDKpushFor(hBs, 1); /* reserved */
+ pDChar->cicpIndex = FDKreadBits(hBs, 7);
+ if (pDChar->cicpIndex > 0) {
+ pDChar->present = 1;
+ pDChar->isCICP = 1;
+ } else {
+ pDChar->present = 0;
+ }
+ } else {
+ pDChar->present = FDKreadBits(hBs, 1);
+ if (isBox) pDChar->isCICP = FDKreadBits(hBs, 1);
+ if (pDChar->present) {
+ if (!isBox) pDChar->isCICP = FDKreadBits(hBs, 1);
+ if (pDChar->isCICP) {
+ if (isBox) FDKpushFor(hBs, 1); /* reserved */
+ pDChar->cicpIndex = FDKreadBits(hBs, 7);
+ } else {
+ pDChar->custom.left = FDKreadBits(hBs, 4);
+ pDChar->custom.right = FDKreadBits(hBs, 4);
+ }
+ }
+ }
+}
+
+static void _readBandBorder(HANDLE_FDK_BITSTREAM hBs, BAND_BORDER* pBBord,
+ int drcBandType, int isBox) {
+ if (drcBandType) {
+ if (isBox) FDKpushFor(hBs, 4); /* reserved */
+ pBBord->crossoverFreqIndex = FDKreadBits(hBs, 4);
+ } else {
+ if (isBox) FDKpushFor(hBs, 6); /* reserved */
+ pBBord->startSubBandIndex = FDKreadBits(hBs, 10);
+ }
+}
+
+static DRC_ERROR _readGainSet(HANDLE_FDK_BITSTREAM hBs, const int version,
+ int* gainSequenceIndex, GAIN_SET* pGSet,
+ int isBox) {
+ if (isBox) FDKpushFor(hBs, 2); /* reserved */
+ pGSet->gainCodingProfile = FDKreadBits(hBs, 2);
+ pGSet->gainInterpolationType = FDKreadBits(hBs, 1);
+ pGSet->fullFrame = FDKreadBits(hBs, 1);
+ pGSet->timeAlignment = FDKreadBits(hBs, 1);
+ pGSet->timeDeltaMinPresent = FDKreadBits(hBs, 1);
+
+ if (pGSet->timeDeltaMinPresent) {
+ int bsTimeDeltaMin;
+ if (isBox) FDKpushFor(hBs, 5); /* reserved */
+ bsTimeDeltaMin = FDKreadBits(hBs, 11);
+ pGSet->timeDeltaMin = bsTimeDeltaMin + 1;
+ }
+
+ if (pGSet->gainCodingProfile != GCP_CONSTANT) {
+ int i;
+ if (isBox) FDKpushFor(hBs, 3); /* reserved */
+ pGSet->bandCount = FDKreadBits(hBs, 4);
+ if (pGSet->bandCount > 4) return DE_MEMORY_ERROR;
+
+ if ((pGSet->bandCount > 1) || isBox) {
+ pGSet->drcBandType = FDKreadBits(hBs, 1);
+ }
+
+ for (i = 0; i < pGSet->bandCount; i++) {
+ if (version == 0) {
+ *gainSequenceIndex = (*gainSequenceIndex) + 1;
+ } else {
+ int indexPresent;
+ indexPresent = (isBox) ? 1 : FDKreadBits(hBs, 1);
+ if (indexPresent) {
+ int bsIndex;
+ bsIndex = FDKreadBits(hBs, 6);
+ *gainSequenceIndex = bsIndex;
+ } else {
+ *gainSequenceIndex = (*gainSequenceIndex) + 1;
+ }
+ }
+ pGSet->gainSequenceIndex[i] = *gainSequenceIndex;
+ _readDrcCharacteristic(hBs, version, &(pGSet->drcCharacteristic[i]),
+ isBox);
+ }
+ for (i = 1; i < pGSet->bandCount; i++) {
+ _readBandBorder(hBs, &(pGSet->bandBorder[i]), pGSet->drcBandType, isBox);
+ }
+ } else {
+ pGSet->bandCount = 1;
+ *gainSequenceIndex = (*gainSequenceIndex) + 1;
+ pGSet->gainSequenceIndex[0] = *gainSequenceIndex;
+ }
+
+ return DE_OK;
+}
+
+static DRC_ERROR _readCustomDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs,
+ const CHARACTERISTIC_SIDE side,
+ UCHAR* pCharacteristicFormat,
+ CUSTOM_DRC_CHAR* pCChar,
+ int isBox) {
+ if (isBox) FDKpushFor(hBs, 7); /* reserved */
+ *pCharacteristicFormat = FDKreadBits(hBs, 1);
+ if (*pCharacteristicFormat == CF_SIGMOID) {
+ int bsGain, bsIoRatio, bsExp;
+ if (isBox) FDKpushFor(hBs, 1); /* reserved */
+ bsGain = FDKreadBits(hBs, 6);
+ if (side == CS_LEFT) {
+ pCChar->sigmoid.gain = (FIXP_SGL)(bsGain << (FRACT_BITS - 1 - 6));
+ } else {
+ pCChar->sigmoid.gain = (FIXP_SGL)(-bsGain << (FRACT_BITS - 1 - 6));
+ }
+ bsIoRatio = FDKreadBits(hBs, 4);
+ /* pCChar->sigmoid.ioRatio = 0.05 + 0.15 * bsIoRatio; */
+ pCChar->sigmoid.ioRatio =
+ FL2FXCONST_SGL(0.05f / (float)(1 << 2)) +
+ (FIXP_SGL)((((3 * bsIoRatio) << (FRACT_BITS - 1)) / 5) >> 4);
+ bsExp = FDKreadBits(hBs, 4);
+ if (bsExp < 15) {
+ pCChar->sigmoid.exp = (FIXP_SGL)((1 + 2 * bsExp) << (FRACT_BITS - 1 - 5));
+ } else {
+ pCChar->sigmoid.exp = (FIXP_SGL)MAXVAL_SGL; /* represents infinity */
+ }
+ pCChar->sigmoid.flipSign = FDKreadBits(hBs, 1);
+ } else { /* CF_NODES */
+ int i, bsCharacteristicNodeCount, bsNodeLevelDelta, bsNodeGain;
+ if (isBox) FDKpushFor(hBs, 6); /* reserved */
+ bsCharacteristicNodeCount = FDKreadBits(hBs, 2);
+ pCChar->nodes.characteristicNodeCount = bsCharacteristicNodeCount + 1;
+ if (pCChar->nodes.characteristicNodeCount > 4) return DE_MEMORY_ERROR;
+ pCChar->nodes.nodeLevel[0] = DRC_INPUT_LOUDNESS_TARGET_SGL;
+ pCChar->nodes.nodeGain[0] = (FIXP_SGL)0;
+ for (i = 0; i < pCChar->nodes.characteristicNodeCount; i++) {
+ if (isBox) FDKpushFor(hBs, 3); /* reserved */
+ bsNodeLevelDelta = FDKreadBits(hBs, 5);
+ if (side == CS_LEFT) {
+ pCChar->nodes.nodeLevel[i + 1] =
+ pCChar->nodes.nodeLevel[i] -
+ (FIXP_SGL)((1 + bsNodeLevelDelta) << (FRACT_BITS - 1 - 7));
+ } else {
+ pCChar->nodes.nodeLevel[i + 1] =
+ pCChar->nodes.nodeLevel[i] +
+ (FIXP_SGL)((1 + bsNodeLevelDelta) << (FRACT_BITS - 1 - 7));
+ }
+ bsNodeGain = FDKreadBits(hBs, 8);
+ pCChar->nodes.nodeGain[i + 1] = (FIXP_SGL)(
+ (bsNodeGain - 128)
+ << (FRACT_BITS - 1 - 1 - 7)); /* 0.5f * bsNodeGain - 64.0f; */
+ }
+ }
+ return DE_OK;
+}
+
+static void _skipLoudEqInstructions(HANDLE_FDK_BITSTREAM hBs) {
+ int i;
+ int downmixIdPresent, additionalDownmixIdPresent,
+ additionalDownmixIdCount = 0;
+ int drcSetIdPresent, additionalDrcSetIdPresent, additionalDrcSetIdCount = 0;
+ int eqSetIdPresent, additionalEqSetIdPresent, additionalEqSetIdCount = 0;
+ int loudEqGainSequenceCount, drcCharacteristicFormatIsCICP;
+
+ FDKpushFor(hBs, 4); /* loudEqSetId */
+ FDKpushFor(hBs, 4); /* drcLocation */
+ downmixIdPresent = FDKreadBits(hBs, 1);
+ if (downmixIdPresent) {
+ FDKpushFor(hBs, 7); /* downmixId */
+ additionalDownmixIdPresent = FDKreadBits(hBs, 1);
+ if (additionalDownmixIdPresent) {
+ additionalDownmixIdCount = FDKreadBits(hBs, 7);
+ for (i = 0; i < additionalDownmixIdCount; i++) {
+ FDKpushFor(hBs, 7); /* additionalDownmixId */
+ }
+ }
+ }
+
+ drcSetIdPresent = FDKreadBits(hBs, 1);
+ if (drcSetIdPresent) {
+ FDKpushFor(hBs, 6); /* drcSetId */
+ additionalDrcSetIdPresent = FDKreadBits(hBs, 1);
+ if (additionalDrcSetIdPresent) {
+ additionalDrcSetIdCount = FDKreadBits(hBs, 6);
+ for (i = 0; i < additionalDrcSetIdCount; i++) {
+ FDKpushFor(hBs, 6); /* additionalDrcSetId; */
+ }
+ }
+ }
+
+ eqSetIdPresent = FDKreadBits(hBs, 1);
+ if (eqSetIdPresent) {
+ FDKpushFor(hBs, 6); /* eqSetId */
+ additionalEqSetIdPresent = FDKreadBits(hBs, 1);
+ if (additionalEqSetIdPresent) {
+ additionalEqSetIdCount = FDKreadBits(hBs, 6);
+ for (i = 0; i < additionalEqSetIdCount; i++) {
+ FDKpushFor(hBs, 6); /* additionalEqSetId; */
+ }
+ }
+ }
+
+ FDKpushFor(hBs, 1); /* loudnessAfterDrc */
+ FDKpushFor(hBs, 1); /* loudnessAfterEq */
+ loudEqGainSequenceCount = FDKreadBits(hBs, 6);
+ for (i = 0; i < loudEqGainSequenceCount; i++) {
+ FDKpushFor(hBs, 6); /* gainSequenceIndex */
+ drcCharacteristicFormatIsCICP = FDKreadBits(hBs, 1);
+ if (drcCharacteristicFormatIsCICP) {
+ FDKpushFor(hBs, 7); /* drcCharacteristic */
+ } else {
+ FDKpushFor(hBs, 4); /* drcCharacteristicLeftIndex */
+ FDKpushFor(hBs, 4); /* drcCharacteristicRightIndex */
+ }
+ FDKpushFor(hBs, 6); /* frequencyRangeIndex */
+ FDKpushFor(hBs, 3); /* bsLoudEqScaling */
+ FDKpushFor(hBs, 5); /* bsLoudEqOffset */
+ }
+}
+
+static void _skipEqSubbandGainSpline(HANDLE_FDK_BITSTREAM hBs) {
+ int nEqNodes, k, bits;
+ nEqNodes = FDKreadBits(hBs, 5);
+ nEqNodes += 2;
+ for (k = 0; k < nEqNodes; k++) {
+ bits = FDKreadBits(hBs, 1);
+ if (!bits) {
+ FDKpushFor(hBs, 4);
+ }
+ }
+ FDKpushFor(hBs, 4 * (nEqNodes - 1));
+ bits = FDKreadBits(hBs, 2);
+ switch (bits) {
+ case 0:
+ FDKpushFor(hBs, 5);
+ break;
+ case 1:
+ case 2:
+ FDKpushFor(hBs, 4);
+ break;
+ case 3:
+ FDKpushFor(hBs, 3);
+ break;
+ }
+ FDKpushFor(hBs, 5 * (nEqNodes - 1));
+}
+
+static void _skipEqCoefficients(HANDLE_FDK_BITSTREAM hBs) {
+ int j, k;
+ int eqDelayMaxPresent;
+ int uniqueFilterBlockCount, filterElementCount, filterElementGainPresent;
+ int uniqueTdFilterElementCount, eqFilterFormat, bsRealZeroRadiusOneCount,
+ realZeroCount, genericZeroCount, realPoleCount, complexPoleCount,
+ firFilterOrder;
+ int uniqueEqSubbandGainsCount, eqSubbandGainRepresentation,
+ eqSubbandGainCount;
+ EQ_SUBBAND_GAIN_FORMAT eqSubbandGainFormat;
+
+ eqDelayMaxPresent = FDKreadBits(hBs, 1);
+ if (eqDelayMaxPresent) {
+ FDKpushFor(hBs, 8); /* bsEqDelayMax */
+ }
+
+ uniqueFilterBlockCount = FDKreadBits(hBs, 6);
+ for (j = 0; j < uniqueFilterBlockCount; j++) {
+ filterElementCount = FDKreadBits(hBs, 6);
+ for (k = 0; k < filterElementCount; k++) {
+ FDKpushFor(hBs, 6); /* filterElementIndex */
+ filterElementGainPresent = FDKreadBits(hBs, 1);
+ if (filterElementGainPresent) {
+ FDKpushFor(hBs, 10); /* bsFilterElementGain */
+ }
+ }
+ }
+ uniqueTdFilterElementCount = FDKreadBits(hBs, 6);
+ for (j = 0; j < uniqueTdFilterElementCount; j++) {
+ eqFilterFormat = FDKreadBits(hBs, 1);
+ if (eqFilterFormat == 0) { /* pole/zero */
+ bsRealZeroRadiusOneCount = FDKreadBits(hBs, 3);
+ realZeroCount = FDKreadBits(hBs, 6);
+ genericZeroCount = FDKreadBits(hBs, 6);
+ realPoleCount = FDKreadBits(hBs, 4);
+ complexPoleCount = FDKreadBits(hBs, 4);
+ FDKpushFor(hBs, 2 * bsRealZeroRadiusOneCount * 1);
+ FDKpushFor(hBs, realZeroCount * 8);
+ FDKpushFor(hBs, genericZeroCount * 14);
+ FDKpushFor(hBs, realPoleCount * 8);
+ FDKpushFor(hBs, complexPoleCount * 14);
+ } else { /* FIR coefficients */
+ firFilterOrder = FDKreadBits(hBs, 7);
+ FDKpushFor(hBs, 1);
+ FDKpushFor(hBs, (firFilterOrder / 2 + 1) * 11);
+ }
+ }
+ uniqueEqSubbandGainsCount = FDKreadBits(hBs, 6);
+ if (uniqueEqSubbandGainsCount > 0) {
+ eqSubbandGainRepresentation = FDKreadBits(hBs, 1);
+ eqSubbandGainFormat = (EQ_SUBBAND_GAIN_FORMAT)FDKreadBits(hBs, 4);
+ switch (eqSubbandGainFormat) {
+ case GF_QMF32:
+ eqSubbandGainCount = 32;
+ break;
+ case GF_QMFHYBRID39:
+ eqSubbandGainCount = 39;
+ break;
+ case GF_QMF64:
+ eqSubbandGainCount = 64;
+ break;
+ case GF_QMFHYBRID71:
+ eqSubbandGainCount = 71;
+ break;
+ case GF_QMF128:
+ eqSubbandGainCount = 128;
+ break;
+ case GF_QMFHYBRID135:
+ eqSubbandGainCount = 135;
+ break;
+ case GF_UNIFORM:
+ default:
+ eqSubbandGainCount = FDKreadBits(hBs, 8);
+ eqSubbandGainCount++;
+ break;
+ }
+ for (k = 0; k < uniqueEqSubbandGainsCount; k++) {
+ if (eqSubbandGainRepresentation == 1) {
+ _skipEqSubbandGainSpline(hBs);
+ } else {
+ FDKpushFor(hBs, eqSubbandGainCount * 9);
+ }
+ }
+ }
+}
+
+static void _skipTdFilterCascade(HANDLE_FDK_BITSTREAM hBs,
+ const int eqChannelGroupCount) {
+ int i, eqCascadeGainPresent, filterBlockCount, eqPhaseAlignmentPresent;
+ for (i = 0; i < eqChannelGroupCount; i++) {
+ eqCascadeGainPresent = FDKreadBits(hBs, 1);
+ if (eqCascadeGainPresent) {
+ FDKpushFor(hBs, 10); /* bsEqCascadeGain */
+ }
+ filterBlockCount = FDKreadBits(hBs, 4);
+ FDKpushFor(hBs, filterBlockCount * 7); /* filterBlockIndex */
+ }
+ eqPhaseAlignmentPresent = FDKreadBits(hBs, 1);
+ {
+ if (eqPhaseAlignmentPresent) {
+ for (i = 0; i < eqChannelGroupCount; i++) {
+ FDKpushFor(hBs, (eqChannelGroupCount - i - 1) * 1);
+ }
+ }
+ }
+}
+
+static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
+ DRC_ERROR err = DE_OK;
+ int c, i, k, channelCount;
+ int downmixIdPresent, downmixId, eqApplyToDownmix, additionalDownmixIdPresent,
+ additionalDownmixIdCount = 0;
+ int additionalDrcSetIdPresent, additionalDrcSetIdCount;
+ int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent,
+ subbandGainsPresent, eqTransitionDurationPresent;
+
+ FDKpushFor(hBs, 6); /* eqSetId */
+ FDKpushFor(hBs, 4); /* eqSetComplexityLevel */
+ downmixIdPresent = FDKreadBits(hBs, 1);
+ if (downmixIdPresent) {
+ downmixId = FDKreadBits(hBs, 7);
+ eqApplyToDownmix = FDKreadBits(hBs, 1);
+ additionalDownmixIdPresent = FDKreadBits(hBs, 1);
+ if (additionalDownmixIdPresent) {
+ additionalDownmixIdCount = FDKreadBits(hBs, 7);
+ FDKpushFor(hBs, additionalDownmixIdCount * 7); /* additionalDownmixId */
+ }
+ } else {
+ downmixId = 0;
+ eqApplyToDownmix = 0;
+ }
+ FDKpushFor(hBs, 6); /* drcSetId */
+ additionalDrcSetIdPresent = FDKreadBits(hBs, 1);
+ if (additionalDrcSetIdPresent) {
+ additionalDrcSetIdCount = FDKreadBits(hBs, 6);
+ for (i = 0; i < additionalDrcSetIdCount; i++) {
+ FDKpushFor(hBs, 6); /* additionalDrcSetId */
+ }
+ }
+ FDKpushFor(hBs, 16); /* eqSetPurpose */
+ dependsOnEqSetPresent = FDKreadBits(hBs, 1);
+ if (dependsOnEqSetPresent) {
+ FDKpushFor(hBs, 6); /* dependsOnEqSet */
+ } else {
+ FDKpushFor(hBs, 1); /* noIndependentEqUse */
+ }
+
+ channelCount = hUniDrcConfig->channelLayout.baseChannelCount;
+ if ((downmixIdPresent == 1) && (eqApplyToDownmix == 1) && (downmixId != 0) &&
+ (downmixId != DOWNMIX_ID_ANY_DOWNMIX) &&
+ (additionalDownmixIdCount == 0)) {
+ DOWNMIX_INSTRUCTIONS* pDown =
+ selectDownmixInstructions(hUniDrcConfig, downmixId);
+ if (pDown == NULL) return DE_NOT_OK;
+
+ channelCount =
+ pDown->targetChannelCount; /* targetChannelCountFromDownmixId*/
+ } else if ((downmixId == DOWNMIX_ID_ANY_DOWNMIX) ||
+ (additionalDownmixIdCount > 1)) {
+ channelCount = 1;
+ }
+
+ eqChannelGroupCount = 0;
+ for (c = 0; c < channelCount; c++) {
+ UCHAR eqChannelGroupForChannel[8];
+ int newGroup = 1;
+ if (c >= 8) return DE_MEMORY_ERROR;
+ eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7);
+ for (k = 0; k < c; k++) {
+ if (eqChannelGroupForChannel[c] == eqChannelGroupForChannel[k]) {
+ newGroup = 0;
+ }
+ }
+ if (newGroup == 1) {
+ eqChannelGroupCount += 1;
+ }
+ }
+ tdFilterCascadePresent = FDKreadBits(hBs, 1);
+ if (tdFilterCascadePresent) {
+ _skipTdFilterCascade(hBs, eqChannelGroupCount);
+ }
+ subbandGainsPresent = FDKreadBits(hBs, 1);
+ if (subbandGainsPresent) {
+ FDKpushFor(hBs, eqChannelGroupCount * 6); /* subbandGainsIndex */
+ }
+ eqTransitionDurationPresent = FDKreadBits(hBs, 1);
+ if (eqTransitionDurationPresent) {
+ FDKpushFor(hBs, 5); /* bsEqTransitionDuration */
+ }
+ return err;
+}
+
+static void _skipDrcCoefficientsBasic(HANDLE_FDK_BITSTREAM hBs) {
+ FDKpushFor(hBs, 4); /* drcLocation */
+ FDKpushFor(hBs, 7); /* drcCharacteristic */
+}
+
+static DRC_ERROR _readDrcCoefficientsUniDrc(HANDLE_FDK_BITSTREAM hBs,
+ const int version,
+ DRC_COEFFICIENTS_UNI_DRC* pCoef) {
+ DRC_ERROR err = DE_OK;
+ int i, bsDrcFrameSize;
+ int gainSequenceIndex = -1;
+
+ pCoef->drcLocation = FDKreadBits(hBs, 4);
+ pCoef->drcFrameSizePresent = FDKreadBits(hBs, 1);
+
+ if (pCoef->drcFrameSizePresent == 1) {
+ bsDrcFrameSize = FDKreadBits(hBs, 15);
+ pCoef->drcFrameSize = bsDrcFrameSize + 1;
+ }
+ if (version == 0) {
+ int gainSequenceCount = 0, gainSetCount;
+ pCoef->characteristicLeftCount = 0;
+ pCoef->characteristicRightCount = 0;
+ gainSetCount = FDKreadBits(hBs, 6);
+ pCoef->gainSetCount = fMin(gainSetCount, 12);
+ for (i = 0; i < gainSetCount; i++) {
+ GAIN_SET tmpGset;
+ FDKmemclear(&tmpGset, sizeof(GAIN_SET));
+ err = _readGainSet(hBs, version, &gainSequenceIndex, &tmpGset, 0);
+ if (err) return err;
+ gainSequenceCount += tmpGset.bandCount;
+
+ if (i >= 12) continue;
+ pCoef->gainSet[i] = tmpGset;
+ }
+ pCoef->gainSequenceCount = gainSequenceCount;
+ } else { /* (version == 1) */
+ UCHAR drcCharacteristicLeftPresent, drcCharacteristicRightPresent;
+ UCHAR shapeFiltersPresent, shapeFilterCount, tmpPresent;
+ int gainSetCount;
+ drcCharacteristicLeftPresent = FDKreadBits(hBs, 1);
+ if (drcCharacteristicLeftPresent) {
+ pCoef->characteristicLeftCount = FDKreadBits(hBs, 4);
+ if ((pCoef->characteristicLeftCount + 1) > 8) return DE_MEMORY_ERROR;
+ for (i = 0; i < pCoef->characteristicLeftCount; i++) {
+ err = _readCustomDrcCharacteristic(
+ hBs, CS_LEFT, &(pCoef->characteristicLeftFormat[i + 1]),
+ &(pCoef->customCharacteristicLeft[i + 1]), 0);
+ if (err) return err;
+ }
+ }
+ drcCharacteristicRightPresent = FDKreadBits(hBs, 1);
+ if (drcCharacteristicRightPresent) {
+ pCoef->characteristicRightCount = FDKreadBits(hBs, 4);
+ if ((pCoef->characteristicRightCount + 1) > 8) return DE_MEMORY_ERROR;
+ for (i = 0; i < pCoef->characteristicRightCount; i++) {
+ err = _readCustomDrcCharacteristic(
+ hBs, CS_RIGHT, &(pCoef->characteristicRightFormat[i + 1]),
+ &(pCoef->customCharacteristicRight[i + 1]), 0);
+ if (err) return err;
+ }
+ }
+ shapeFiltersPresent = FDKreadBits(hBs, 1);
+ if (shapeFiltersPresent) {
+ shapeFilterCount = FDKreadBits(hBs, 4);
+ for (i = 0; i < shapeFilterCount; i++) {
+ tmpPresent = FDKreadBits(hBs, 1);
+ if (tmpPresent) /* lfCutParams */
+ FDKpushFor(hBs, 5);
+
+ tmpPresent = FDKreadBits(hBs, 1);
+ if (tmpPresent) /* lfBoostParams */
+ FDKpushFor(hBs, 5);
+
+ tmpPresent = FDKreadBits(hBs, 1);
+ if (tmpPresent) /* hfCutParams */
+ FDKpushFor(hBs, 5);
+
+ tmpPresent = FDKreadBits(hBs, 1);
+ if (tmpPresent) /* hfBoostParams */
+ FDKpushFor(hBs, 5);
+ }
+ }
+ pCoef->gainSequenceCount = FDKreadBits(hBs, 6);
+ gainSetCount = FDKreadBits(hBs, 6);
+ pCoef->gainSetCount = fMin(gainSetCount, 12);
+ for (i = 0; i < gainSetCount; i++) {
+ GAIN_SET tmpGset;
+ FDKmemclear(&tmpGset, sizeof(GAIN_SET));
+ err = _readGainSet(hBs, version, &gainSequenceIndex, &tmpGset, 0);
+ if (err) return err;
+
+ if (i >= 12) continue;
+ pCoef->gainSet[i] = tmpGset;
+ }
+ }
+ for (i = 0; i < 12; i++) {
+ pCoef->gainSetIndexForGainSequence[i] = 255;
+ }
+ for (i = 0; i < pCoef->gainSetCount; i++) {
+ int b;
+ for (b = 0; b < pCoef->gainSet[i].bandCount; b++) {
+ if (pCoef->gainSet[i].gainSequenceIndex[b] >= 12) continue;
+ pCoef->gainSetIndexForGainSequence[pCoef->gainSet[i]
+ .gainSequenceIndex[b]] = i;
+ }
+ }
+
+ return err;
+}
+
+static void _skipDrcInstructionsBasic(HANDLE_FDK_BITSTREAM hBs) {
+ int drcSetEffect;
+ int additionalDownmixIdPresent, additionalDownmixIdCount,
+ limiterPeakTargetPresent;
+ int drcSetTargetLoudnessPresent, drcSetTargetLoudnessValueLowerPresent;
+
+ FDKpushFor(hBs, 6); /* drcSetId */
+ FDKpushFor(hBs, 4); /* drcLocation */
+ FDKpushFor(hBs, 7); /* downmixId */
+ additionalDownmixIdPresent = FDKreadBits(hBs, 1);
+ if (additionalDownmixIdPresent) {
+ additionalDownmixIdCount = FDKreadBits(hBs, 3);
+ FDKpushFor(hBs, 7 * additionalDownmixIdCount); /* additionalDownmixId */
+ }
+
+ drcSetEffect = FDKreadBits(hBs, 16);
+ if (!(drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF))) {
+ limiterPeakTargetPresent = FDKreadBits(hBs, 1);
+ if (limiterPeakTargetPresent) {
+ FDKpushFor(hBs, 8); /* bsLimiterPeakTarget */
+ }
+ }
+
+ drcSetTargetLoudnessPresent = FDKreadBits(hBs, 1);
+ if (drcSetTargetLoudnessPresent) {
+ FDKpushFor(hBs, 6); /* bsDrcSetTargetLoudnessValueUpper */
+ drcSetTargetLoudnessValueLowerPresent = FDKreadBits(hBs, 1);
+ if (drcSetTargetLoudnessValueLowerPresent) {
+ FDKpushFor(hBs, 6); /* bsDrcSetTargetLoudnessValueLower */
+ }
+ }
+}
+
+static DRC_ERROR _readDrcInstructionsUniDrc(HANDLE_FDK_BITSTREAM hBs,
+ const int version,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ DRC_INSTRUCTIONS_UNI_DRC* pInst) {
+ DRC_ERROR err = DE_OK;
+ int i, g, c;
+ int downmixIdPresent, additionalDownmixIdPresent, additionalDownmixIdCount;
+ int bsLimiterPeakTarget, channelCount;
+ DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
+ int repeatParameters, bsRepeatParametersCount;
+ int repeatSequenceIndex, bsRepeatSequenceCount;
+ SCHAR* gainSetIndex = pInst->gainSetIndex;
+ SCHAR channelGroupForChannel[8];
+ DUCKING_MODIFICATION duckingModificationForChannelGroup[8];
+
+ pInst->drcSetId = FDKreadBits(hBs, 6);
+ if (version == 0) {
+ /* Assume all v0 DRC sets to be manageable in terms of complexity */
+ pInst->drcSetComplexityLevel = 2;
+ } else {
+ pInst->drcSetComplexityLevel = FDKreadBits(hBs, 4);
+ }
+ pInst->drcLocation = FDKreadBits(hBs, 4);
+ if (version == 0) {
+ downmixIdPresent = 1;
+ } else {
+ downmixIdPresent = FDKreadBits(hBs, 1);
+ }
+ if (downmixIdPresent) {
+ pInst->downmixId[0] = FDKreadBits(hBs, 7);
+ if (version == 0) {
+ if (pInst->downmixId[0] == 0)
+ pInst->drcApplyToDownmix = 0;
+ else
+ pInst->drcApplyToDownmix = 1;
+ } else {
+ pInst->drcApplyToDownmix = FDKreadBits(hBs, 1);
+ }
+
+ additionalDownmixIdPresent = FDKreadBits(hBs, 1);
+ if (additionalDownmixIdPresent) {
+ additionalDownmixIdCount = FDKreadBits(hBs, 3);
+ if ((1 + additionalDownmixIdCount) > 8) return DE_MEMORY_ERROR;
+ for (i = 0; i < additionalDownmixIdCount; i++) {
+ pInst->downmixId[i + 1] = FDKreadBits(hBs, 7);
+ }
+ pInst->downmixIdCount = 1 + additionalDownmixIdCount;
+ } else {
+ pInst->downmixIdCount = 1;
+ }
+ } else {
+ pInst->downmixId[0] = 0;
+ pInst->downmixIdCount = 1;
+ }
+
+ pInst->drcSetEffect = FDKreadBits(hBs, 16);
+
+ if ((pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) == 0) {
+ pInst->limiterPeakTargetPresent = FDKreadBits(hBs, 1);
+ if (pInst->limiterPeakTargetPresent) {
+ bsLimiterPeakTarget = FDKreadBits(hBs, 8);
+ pInst->limiterPeakTarget = -(FIXP_SGL)(
+ bsLimiterPeakTarget
+ << (FRACT_BITS - 1 - 3 - 5)); /* - bsLimiterPeakTarget * 0.125; */
+ }
+ }
+
+ pInst->drcSetTargetLoudnessPresent = FDKreadBits(hBs, 1);
+
+ /* set default values */
+ pInst->drcSetTargetLoudnessValueUpper = 0;
+ pInst->drcSetTargetLoudnessValueLower = -63;
+
+ if (pInst->drcSetTargetLoudnessPresent == 1) {
+ int bsDrcSetTargetLoudnessValueUpper, bsDrcSetTargetLoudnessValueLower;
+ int drcSetTargetLoudnessValueLowerPresent;
+ bsDrcSetTargetLoudnessValueUpper = FDKreadBits(hBs, 6);
+ pInst->drcSetTargetLoudnessValueUpper =
+ bsDrcSetTargetLoudnessValueUpper - 63;
+ drcSetTargetLoudnessValueLowerPresent = FDKreadBits(hBs, 1);
+ if (drcSetTargetLoudnessValueLowerPresent == 1) {
+ bsDrcSetTargetLoudnessValueLower = FDKreadBits(hBs, 6);
+ pInst->drcSetTargetLoudnessValueLower =
+ bsDrcSetTargetLoudnessValueLower - 63;
+ }
+ }
+
+ pInst->dependsOnDrcSetPresent = FDKreadBits(hBs, 1);
+
+ pInst->noIndependentUse = 0;
+ if (pInst->dependsOnDrcSetPresent) {
+ pInst->dependsOnDrcSet = FDKreadBits(hBs, 6);
+ } else {
+ pInst->noIndependentUse = FDKreadBits(hBs, 1);
+ }
+
+ if (version == 0) {
+ pInst->requiresEq = 0;
+ } else {
+ pInst->requiresEq = FDKreadBits(hBs, 1);
+ }
+
+ pCoef = selectDrcCoefficients(hUniDrcConfig, pInst->drcLocation);
+
+ pInst->drcChannelCount = channelCount =
+ hUniDrcConfig->channelLayout.baseChannelCount;
+
+ if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
+ DUCKING_MODIFICATION* pDModForChannel =
+ pInst->duckingModificationForChannel;
+ c = 0;
+ while (c < channelCount) {
+ int bsGainSetIndex;
+ bsGainSetIndex = FDKreadBits(hBs, 6);
+ if (c >= 8) return DE_MEMORY_ERROR;
+ gainSetIndex[c] = bsGainSetIndex - 1;
+ _decodeDuckingModification(hBs, &(pDModForChannel[c]), 0);
+
+ c++;
+ repeatParameters = FDKreadBits(hBs, 1);
+ if (repeatParameters == 1) {
+ bsRepeatParametersCount = FDKreadBits(hBs, 5);
+ bsRepeatParametersCount += 1;
+ for (i = 0; i < bsRepeatParametersCount; i++) {
+ if (c >= 8) return DE_MEMORY_ERROR;
+ gainSetIndex[c] = gainSetIndex[c - 1];
+ pDModForChannel[c] = pDModForChannel[c - 1];
+ c++;
+ }
+ }
+ }
+ if (c > channelCount) {
+ return DE_NOT_OK;
+ }
+
+ err = deriveDrcChannelGroups(
+ pInst->drcSetEffect, pInst->drcChannelCount, gainSetIndex,
+ pDModForChannel, &pInst->nDrcChannelGroups,
+ pInst->gainSetIndexForChannelGroup, channelGroupForChannel,
+ duckingModificationForChannelGroup);
+ if (err) return (err);
+ } else {
+ int deriveChannelCount = 0;
+ if (((version == 0) || (pInst->drcApplyToDownmix != 0)) &&
+ (pInst->downmixId[0] != DOWNMIX_ID_BASE_LAYOUT) &&
+ (pInst->downmixId[0] != DOWNMIX_ID_ANY_DOWNMIX) &&
+ (pInst->downmixIdCount == 1)) {
+ if (hUniDrcConfig->downmixInstructionsCount != 0) {
+ DOWNMIX_INSTRUCTIONS* pDown =
+ selectDownmixInstructions(hUniDrcConfig, pInst->downmixId[0]);
+ if (pDown == NULL) return DE_NOT_OK;
+ pInst->drcChannelCount = channelCount =
+ pDown->targetChannelCount; /* targetChannelCountFromDownmixId*/
+ } else {
+ deriveChannelCount = 1;
+ channelCount = 1;
+ }
+ } else if (((version == 0) || (pInst->drcApplyToDownmix != 0)) &&
+ ((pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) ||
+ (pInst->downmixIdCount > 1))) {
+ /* Set maximum channel count as upper border. The effective channel count
+ * is set at the process function. */
+ pInst->drcChannelCount = 8;
+ channelCount = 1;
+ }
+
+ c = 0;
+ while (c < channelCount) {
+ int bsGainSetIndex;
+ bsGainSetIndex = FDKreadBits(hBs, 6);
+ if (c >= 8) return DE_MEMORY_ERROR;
+ gainSetIndex[c] = bsGainSetIndex - 1;
+ c++;
+ repeatSequenceIndex = FDKreadBits(hBs, 1);
+
+ if (repeatSequenceIndex == 1) {
+ bsRepeatSequenceCount = FDKreadBits(hBs, 5);
+ bsRepeatSequenceCount += 1;
+ if (deriveChannelCount) {
+ channelCount = 1 + bsRepeatSequenceCount;
+ }
+ for (i = 0; i < bsRepeatSequenceCount; i++) {
+ if (c >= 8) return DE_MEMORY_ERROR;
+ gainSetIndex[c] = bsGainSetIndex - 1;
+ c++;
+ }
+ }
+ }
+ if (c > channelCount) {
+ return DE_NOT_OK;
+ }
+ if (deriveChannelCount) {
+ pInst->drcChannelCount = channelCount;
+ }
+
+ /* DOWNMIX_ID_ANY_DOWNMIX: channelCount is 1. Distribute gainSetIndex to all
+ * channels. */
+ if ((pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) ||
+ (pInst->downmixIdCount > 1)) {
+ for (c = 1; c < pInst->drcChannelCount; c++) {
+ gainSetIndex[c] = gainSetIndex[0];
+ }
+ }
+
+ err = deriveDrcChannelGroups(pInst->drcSetEffect, pInst->drcChannelCount,
+ gainSetIndex, NULL, &pInst->nDrcChannelGroups,
+ pInst->gainSetIndexForChannelGroup,
+ channelGroupForChannel, NULL);
+ if (err) return (err);
+
+ for (g = 0; g < pInst->nDrcChannelGroups; g++) {
+ int set, bandCount;
+ set = pInst->gainSetIndexForChannelGroup[g];
+
+ /* get bandCount */
+ if (pCoef != NULL && set < pCoef->gainSetCount) {
+ bandCount = pCoef->gainSet[set].bandCount;
+ } else {
+ bandCount = 1;
+ }
+
+ _decodeGainModification(hBs, version, bandCount,
+ pInst->gainModificationForChannelGroup[g], 0);
+ }
+ }
+
+ return err;
+}
+
+static DRC_ERROR _readChannelLayout(HANDLE_FDK_BITSTREAM hBs,
+ CHANNEL_LAYOUT* pChan) {
+ DRC_ERROR err = DE_OK;
+
+ pChan->baseChannelCount = FDKreadBits(hBs, 7);
+
+ if (pChan->baseChannelCount > 8) return DE_NOT_OK;
+
+ pChan->layoutSignalingPresent = FDKreadBits(hBs, 1);
+
+ if (pChan->layoutSignalingPresent) {
+ pChan->definedLayout = FDKreadBits(hBs, 8);
+
+ if (pChan->definedLayout == 0) {
+ int i;
+ for (i = 0; i < pChan->baseChannelCount; i++) {
+ if (i < 8) {
+ pChan->speakerPosition[i] = FDKreadBits(hBs, 7);
+ } else {
+ FDKpushFor(hBs, 7);
+ }
+ }
+ }
+ }
+ return err;
+}
+
+static DRC_ERROR _readDownmixInstructions(HANDLE_FDK_BITSTREAM hBs,
+ const int version,
+ CHANNEL_LAYOUT* pChan,
+ DOWNMIX_INSTRUCTIONS* pDown) {
+ DRC_ERROR err = DE_OK;
+
+ pDown->downmixId = FDKreadBits(hBs, 7);
+ pDown->targetChannelCount = FDKreadBits(hBs, 7);
+ pDown->targetLayout = FDKreadBits(hBs, 8);
+ pDown->downmixCoefficientsPresent = FDKreadBits(hBs, 1);
+
+ if (pDown->downmixCoefficientsPresent) {
+ int nDownmixCoeffs = pDown->targetChannelCount * pChan->baseChannelCount;
+ int i;
+ if (nDownmixCoeffs > 8 * 8) return DE_NOT_OK;
+ if (version == 0) {
+ pDown->bsDownmixOffset = 0;
+ for (i = 0; i < nDownmixCoeffs; i++) {
+ /* LFE downmix coefficients are not supported. */
+ pDown->downmixCoefficient[i] = downmixCoeff[FDKreadBits(hBs, 4)];
+ }
+ } else {
+ pDown->bsDownmixOffset = FDKreadBits(hBs, 4);
+ for (i = 0; i < nDownmixCoeffs; i++) {
+ pDown->downmixCoefficient[i] = downmixCoeffV1[FDKreadBits(hBs, 5)];
+ }
+ }
+ }
+ return err;
+}
+
+static DRC_ERROR _readDrcExtensionV1(HANDLE_FDK_BITSTREAM hBs,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
+ DRC_ERROR err = DE_OK;
+ int downmixInstructionsV1Present;
+ int drcCoeffsAndInstructionsUniDrcV1Present;
+ int loudEqInstructionsPresent, loudEqInstructionsCount;
+ int eqPresent, eqInstructionsCount;
+ int i, offset;
+ int diff = hUniDrcConfig->diff;
+
+ downmixInstructionsV1Present = FDKreadBits(hBs, 1);
+ if (downmixInstructionsV1Present == 1) {
+ diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV1,
+ FDKreadBits(hBs, 7));
+ offset = hUniDrcConfig->downmixInstructionsCountV0;
+ hUniDrcConfig->downmixInstructionsCount = fMin(
+ (UCHAR)(offset + hUniDrcConfig->downmixInstructionsCountV1), (UCHAR)6);
+ for (i = 0; i < hUniDrcConfig->downmixInstructionsCountV1; i++) {
+ DOWNMIX_INSTRUCTIONS tmpDown;
+ FDKmemclear(&tmpDown, sizeof(DOWNMIX_INSTRUCTIONS));
+ err = _readDownmixInstructions(hBs, 1, &hUniDrcConfig->channelLayout,
+ &tmpDown);
+ if (err) return err;
+ if ((offset + i) >= 6) continue;
+ if (!diff)
+ diff |= (FDKmemcmp(&tmpDown,
+ &(hUniDrcConfig->downmixInstructions[offset + i]),
+ sizeof(DOWNMIX_INSTRUCTIONS)) != 0);
+ hUniDrcConfig->downmixInstructions[offset + i] = tmpDown;
+ }
+ } else {
+ diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV1, 0);
+ }
+
+ drcCoeffsAndInstructionsUniDrcV1Present = FDKreadBits(hBs, 1);
+ if (drcCoeffsAndInstructionsUniDrcV1Present == 1) {
+ diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV1,
+ FDKreadBits(hBs, 3));
+ offset = hUniDrcConfig->drcCoefficientsUniDrcCountV0;
+ hUniDrcConfig->drcCoefficientsUniDrcCount =
+ fMin((UCHAR)(offset + hUniDrcConfig->drcCoefficientsUniDrcCountV1),
+ (UCHAR)2);
+ for (i = 0; i < hUniDrcConfig->drcCoefficientsUniDrcCountV1; i++) {
+ DRC_COEFFICIENTS_UNI_DRC tmpCoef;
+ FDKmemclear(&tmpCoef, sizeof(DRC_COEFFICIENTS_UNI_DRC));
+ err = _readDrcCoefficientsUniDrc(hBs, 1, &tmpCoef);
+ if (err) return err;
+ if ((offset + i) >= 2) continue;
+ if (!diff)
+ diff |= (FDKmemcmp(&tmpCoef,
+ &(hUniDrcConfig->drcCoefficientsUniDrc[offset + i]),
+ sizeof(DRC_COEFFICIENTS_UNI_DRC)) != 0);
+ hUniDrcConfig->drcCoefficientsUniDrc[offset + i] = tmpCoef;
+ }
+
+ diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV1,
+ FDKreadBits(hBs, 6));
+ offset = hUniDrcConfig->drcInstructionsUniDrcCount;
+ hUniDrcConfig->drcInstructionsUniDrcCount =
+ fMin((UCHAR)(offset + hUniDrcConfig->drcInstructionsUniDrcCountV1),
+ (UCHAR)12);
+ for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
+ DRC_INSTRUCTIONS_UNI_DRC tmpInst;
+ FDKmemclear(&tmpInst, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
+ err = _readDrcInstructionsUniDrc(hBs, 1, hUniDrcConfig, &tmpInst);
+ if (err) return err;
+ if ((offset + i) >= 12) continue;
+ if (!diff)
+ diff |= (FDKmemcmp(&tmpInst,
+ &(hUniDrcConfig->drcInstructionsUniDrc[offset + i]),
+ sizeof(DRC_INSTRUCTIONS_UNI_DRC)) != 0);
+ hUniDrcConfig->drcInstructionsUniDrc[offset + i] = tmpInst;
+ }
+ } else {
+ diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV1, 0);
+ diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV1, 0);
+ }
+
+ loudEqInstructionsPresent = FDKreadBits(hBs, 1);
+ if (loudEqInstructionsPresent == 1) {
+ loudEqInstructionsCount = FDKreadBits(hBs, 4);
+ for (i = 0; i < loudEqInstructionsCount; i++) {
+ _skipLoudEqInstructions(hBs);
+ }
+ }
+
+ eqPresent = FDKreadBits(hBs, 1);
+ if (eqPresent == 1) {
+ _skipEqCoefficients(hBs);
+ eqInstructionsCount = FDKreadBits(hBs, 4);
+ for (i = 0; i < eqInstructionsCount; i++) {
+ _skipEqInstructions(hBs, hUniDrcConfig);
+ }
+ }
+
+ hUniDrcConfig->diff = diff;
+
+ return err;
+}
+
+static DRC_ERROR _readUniDrcConfigExtension(
+ HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
+ DRC_ERROR err = DE_OK;
+ int k, bitSizeLen, extSizeBits, bitSize;
+ INT nBitsRemaining;
+ UNI_DRC_CONFIG_EXTENSION* pExt = &(hUniDrcConfig->uniDrcConfigExt);
+
+ k = 0;
+ pExt->uniDrcConfigExtType[k] = FDKreadBits(hBs, 4);
+ while (pExt->uniDrcConfigExtType[k] != UNIDRCCONFEXT_TERM) {
+ if (k >= (8 - 1)) return DE_MEMORY_ERROR;
+ bitSizeLen = FDKreadBits(hBs, 4);
+ extSizeBits = bitSizeLen + 4;
+
+ bitSize = FDKreadBits(hBs, extSizeBits);
+ pExt->extBitSize[k] = bitSize + 1;
+ nBitsRemaining = (INT)FDKgetValidBits(hBs);
+
+ switch (pExt->uniDrcConfigExtType[k]) {
+ case UNIDRCCONFEXT_V1:
+ err = _readDrcExtensionV1(hBs, hUniDrcConfig);
+ if (err) return err;
+ if (nBitsRemaining !=
+ ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs)))
+ return DE_NOT_OK;
+ break;
+ case UNIDRCCONFEXT_PARAM_DRC:
+ /* add future extensions here */
+ default:
+ FDKpushFor(hBs, pExt->extBitSize[k]);
+ break;
+ }
+ k++;
+ pExt->uniDrcConfigExtType[k] = FDKreadBits(hBs, 4);
+ }
+
+ return err;
+}
+
+DRC_ERROR
+drcDec_readUniDrcConfig(HANDLE_FDK_BITSTREAM hBs,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
+ DRC_ERROR err = DE_OK;
+ int i, diff = 0;
+ int drcDescriptionBasicPresent, drcCoefficientsBasicCount,
+ drcInstructionsBasicCount;
+ CHANNEL_LAYOUT tmpChan;
+ FDKmemclear(&tmpChan, sizeof(CHANNEL_LAYOUT));
+ if (hUniDrcConfig == NULL) return DE_NOT_OK;
+
+ diff |= _compAssign(&hUniDrcConfig->sampleRatePresent, FDKreadBits(hBs, 1));
+
+ if (hUniDrcConfig->sampleRatePresent == 1) {
+ diff |=
+ _compAssign(&hUniDrcConfig->sampleRate, FDKreadBits(hBs, 18) + 1000);
+ }
+
+ diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV0,
+ FDKreadBits(hBs, 7));
+
+ drcDescriptionBasicPresent = FDKreadBits(hBs, 1);
+ if (drcDescriptionBasicPresent == 1) {
+ drcCoefficientsBasicCount = FDKreadBits(hBs, 3);
+ drcInstructionsBasicCount = FDKreadBits(hBs, 4);
+ } else {
+ drcCoefficientsBasicCount = 0;
+ drcInstructionsBasicCount = 0;
+ }
+
+ diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV0,
+ FDKreadBits(hBs, 3));
+ diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV0,
+ FDKreadBits(hBs, 6));
+
+ err = _readChannelLayout(hBs, &tmpChan);
+ if (err) return err;
+
+ if (!diff)
+ diff |= (FDKmemcmp(&tmpChan, &hUniDrcConfig->channelLayout,
+ sizeof(CHANNEL_LAYOUT)) != 0);
+ hUniDrcConfig->channelLayout = tmpChan;
+
+ hUniDrcConfig->downmixInstructionsCount =
+ fMin(hUniDrcConfig->downmixInstructionsCountV0, (UCHAR)6);
+ for (i = 0; i < hUniDrcConfig->downmixInstructionsCountV0; i++) {
+ DOWNMIX_INSTRUCTIONS tmpDown;
+ FDKmemclear(&tmpDown, sizeof(DOWNMIX_INSTRUCTIONS));
+ err = _readDownmixInstructions(hBs, 0, &hUniDrcConfig->channelLayout,
+ &tmpDown);
+ if (err) return err;
+ if (i >= 6) continue;
+ if (!diff)
+ diff |= (FDKmemcmp(&tmpDown, &(hUniDrcConfig->downmixInstructions[i]),
+ sizeof(DOWNMIX_INSTRUCTIONS)) != 0);
+ hUniDrcConfig->downmixInstructions[i] = tmpDown;
+ }
+
+ for (i = 0; i < drcCoefficientsBasicCount; i++) {
+ _skipDrcCoefficientsBasic(hBs);
+ }
+ for (i = 0; i < drcInstructionsBasicCount; i++) {
+ _skipDrcInstructionsBasic(hBs);
+ }
+
+ hUniDrcConfig->drcCoefficientsUniDrcCount =
+ fMin(hUniDrcConfig->drcCoefficientsUniDrcCountV0, (UCHAR)2);
+ for (i = 0; i < hUniDrcConfig->drcCoefficientsUniDrcCountV0; i++) {
+ DRC_COEFFICIENTS_UNI_DRC tmpCoef;
+ FDKmemclear(&tmpCoef, sizeof(DRC_COEFFICIENTS_UNI_DRC));
+ err = _readDrcCoefficientsUniDrc(hBs, 0, &tmpCoef);
+ if (err) return err;
+ if (i >= 2) continue;
+ if (!diff)
+ diff |= (FDKmemcmp(&tmpCoef, &(hUniDrcConfig->drcCoefficientsUniDrc[i]),
+ sizeof(DRC_COEFFICIENTS_UNI_DRC)) != 0);
+ hUniDrcConfig->drcCoefficientsUniDrc[i] = tmpCoef;
+ }
+
+ hUniDrcConfig->drcInstructionsUniDrcCount =
+ fMin(hUniDrcConfig->drcInstructionsUniDrcCountV0, (UCHAR)12);
+ for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCountV0; i++) {
+ DRC_INSTRUCTIONS_UNI_DRC tmpInst;
+ FDKmemclear(&tmpInst, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
+ err = _readDrcInstructionsUniDrc(hBs, 0, hUniDrcConfig, &tmpInst);
+ if (err) return err;
+ if (i >= 12) continue;
+ if (!diff)
+ diff |= (FDKmemcmp(&tmpInst, &(hUniDrcConfig->drcInstructionsUniDrc[i]),
+ sizeof(DRC_INSTRUCTIONS_UNI_DRC)) != 0);
+ hUniDrcConfig->drcInstructionsUniDrc[i] = tmpInst;
+ }
+
+ diff |=
+ _compAssign(&hUniDrcConfig->uniDrcConfigExtPresent, FDKreadBits(hBs, 1));
+ hUniDrcConfig->diff = diff;
+
+ if (hUniDrcConfig->uniDrcConfigExtPresent == 1) {
+ err = _readUniDrcConfigExtension(hBs, hUniDrcConfig);
+ if (err) return err;
+ }
+
+ return err;
+}
+
+/*******************/
+/* loudnessInfoSet */
+/*******************/
+
+static DRC_ERROR _decodeMethodValue(HANDLE_FDK_BITSTREAM hBs,
+ const UCHAR methodDefinition,
+ FIXP_DBL* methodValue, INT isBox) {
+ int tmp;
+ FIXP_DBL val;
+ switch (methodDefinition) {
+ case MD_UNKNOWN_OTHER:
+ case MD_PROGRAM_LOUDNESS:
+ case MD_ANCHOR_LOUDNESS:
+ case MD_MAX_OF_LOUDNESS_RANGE:
+ case MD_MOMENTARY_LOUDNESS_MAX:
+ case MD_SHORT_TERM_LOUDNESS_MAX:
+ tmp = FDKreadBits(hBs, 8);
+ val = FL2FXCONST_DBL(-57.75f / (float)(1 << 7)) +
+ (FIXP_DBL)(
+ tmp << (DFRACT_BITS - 1 - 2 - 7)); /* -57.75 + tmp * 0.25; */
+ break;
+ case MD_LOUDNESS_RANGE:
+ tmp = FDKreadBits(hBs, 8);
+ if (tmp == 0)
+ val = (FIXP_DBL)0;
+ else if (tmp <= 128)
+ val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 2 - 7)); /* tmp * 0.25; */
+ else if (tmp <= 204) {
+ val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 1 - 7)) -
+ FL2FXCONST_DBL(32.0f / (float)(1 << 7)); /* 0.5 * tmp - 32.0f; */
+ } else {
+ /* downscale by 1 more bit to prevent overflow at intermediate result */
+ val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 8)) -
+ FL2FXCONST_DBL(134.0f / (float)(1 << 8)); /* tmp - 134.0; */
+ val <<= 1;
+ }
+ break;
+ case MD_MIXING_LEVEL:
+ tmp = FDKreadBits(hBs, isBox ? 8 : 5);
+ val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 7)) +
+ FL2FXCONST_DBL(80.0f / (float)(1 << 7)); /* tmp + 80.0; */
+ break;
+ case MD_ROOM_TYPE:
+ tmp = FDKreadBits(hBs, isBox ? 8 : 2);
+ val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 7)); /* tmp; */
+ break;
+ case MD_SHORT_TERM_LOUDNESS:
+ tmp = FDKreadBits(hBs, 8);
+ val = FL2FXCONST_DBL(-116.0f / (float)(1 << 7)) +
+ (FIXP_DBL)(
+ tmp << (DFRACT_BITS - 1 - 1 - 7)); /* -116.0 + tmp * 0.5; */
+ break;
+ default:
+ return DE_NOT_OK; /* invalid methodDefinition value */
+ }
+ *methodValue = val;
+ return DE_OK;
+}
+
+static DRC_ERROR _readLoudnessMeasurement(HANDLE_FDK_BITSTREAM hBs,
+ LOUDNESS_MEASUREMENT* pMeas) {
+ DRC_ERROR err = DE_OK;
+
+ pMeas->methodDefinition = FDKreadBits(hBs, 4);
+ err =
+ _decodeMethodValue(hBs, pMeas->methodDefinition, &pMeas->methodValue, 0);
+ if (err) return err;
+ pMeas->measurementSystem = FDKreadBits(hBs, 4);
+ pMeas->reliability = FDKreadBits(hBs, 2);
+
+ return err;
+}
+
+static DRC_ERROR _readLoudnessInfo(HANDLE_FDK_BITSTREAM hBs, const int version,
+ LOUDNESS_INFO* loudnessInfo) {
+ DRC_ERROR err = DE_OK;
+ int bsSamplePeakLevel, bsTruePeakLevel, i;
+ int measurementCount;
+
+ loudnessInfo->drcSetId = FDKreadBits(hBs, 6);
+ if (version >= 1) {
+ loudnessInfo->eqSetId = FDKreadBits(hBs, 6);
+ } else {
+ loudnessInfo->eqSetId = 0;
+ }
+ loudnessInfo->downmixId = FDKreadBits(hBs, 7);
+
+ loudnessInfo->samplePeakLevelPresent = FDKreadBits(hBs, 1);
+ if (loudnessInfo->samplePeakLevelPresent) {
+ bsSamplePeakLevel = FDKreadBits(hBs, 12);
+ if (bsSamplePeakLevel == 0) {
+ loudnessInfo->samplePeakLevelPresent = 0;
+ loudnessInfo->samplePeakLevel = (FIXP_DBL)0;
+ } else { /* 20.0 - bsSamplePeakLevel * 0.03125; */
+ loudnessInfo->samplePeakLevel =
+ FL2FXCONST_DBL(20.0f / (float)(1 << 7)) -
+ (FIXP_DBL)(bsSamplePeakLevel << (DFRACT_BITS - 1 - 5 - 7));
+ }
+ }
+
+ loudnessInfo->truePeakLevelPresent = FDKreadBits(hBs, 1);
+ if (loudnessInfo->truePeakLevelPresent) {
+ bsTruePeakLevel = FDKreadBits(hBs, 12);
+ if (bsTruePeakLevel == 0) {
+ loudnessInfo->truePeakLevelPresent = 0;
+ loudnessInfo->truePeakLevel = (FIXP_DBL)0;
+ } else {
+ loudnessInfo->truePeakLevel =
+ FL2FXCONST_DBL(20.0f / (float)(1 << 7)) -
+ (FIXP_DBL)(bsTruePeakLevel << (DFRACT_BITS - 1 - 5 - 7));
+ }
+ loudnessInfo->truePeakLevelMeasurementSystem = FDKreadBits(hBs, 4);
+ loudnessInfo->truePeakLevelReliability = FDKreadBits(hBs, 2);
+ }
+
+ measurementCount = FDKreadBits(hBs, 4);
+ loudnessInfo->measurementCount = fMin(measurementCount, 8);
+ for (i = 0; i < measurementCount; i++) {
+ LOUDNESS_MEASUREMENT tmpMeas;
+ FDKmemclear(&tmpMeas, sizeof(LOUDNESS_MEASUREMENT));
+ err = _readLoudnessMeasurement(hBs, &tmpMeas);
+ if (err) return err;
+ if (i >= 8) continue;
+ loudnessInfo->loudnessMeasurement[i] = tmpMeas;
+ }
+
+ return err;
+}
+
+static DRC_ERROR _readLoudnessInfoSetExtEq(
+ HANDLE_FDK_BITSTREAM hBs, HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
+ DRC_ERROR err = DE_OK;
+ int i, offset;
+ int diff = hLoudnessInfoSet->diff;
+
+ diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoAlbumCountV1,
+ FDKreadBits(hBs, 6));
+ diff |=
+ _compAssign(&hLoudnessInfoSet->loudnessInfoCountV1, FDKreadBits(hBs, 6));
+
+ offset = hLoudnessInfoSet->loudnessInfoAlbumCountV0;
+ hLoudnessInfoSet->loudnessInfoAlbumCount = fMin(
+ (UCHAR)(offset + hLoudnessInfoSet->loudnessInfoAlbumCountV1), (UCHAR)12);
+ for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCountV1; i++) {
+ LOUDNESS_INFO tmpLoud;
+ FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
+ err = _readLoudnessInfo(hBs, 1, &tmpLoud);
+ if (err) return err;
+ if ((offset + i) >= 12) continue;
+ if (!diff)
+ diff |= (FDKmemcmp(&tmpLoud,
+ &(hLoudnessInfoSet->loudnessInfoAlbum[offset + i]),
+ sizeof(LOUDNESS_INFO)) != 0);
+ hLoudnessInfoSet->loudnessInfoAlbum[offset + i] = tmpLoud;
+ }
+
+ offset = hLoudnessInfoSet->loudnessInfoCountV0;
+ hLoudnessInfoSet->loudnessInfoCount =
+ fMin((UCHAR)(offset + hLoudnessInfoSet->loudnessInfoCountV1), (UCHAR)12);
+ for (i = 0; i < hLoudnessInfoSet->loudnessInfoCountV1; i++) {
+ LOUDNESS_INFO tmpLoud;
+ FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
+ err = _readLoudnessInfo(hBs, 1, &tmpLoud);
+ if (err) return err;
+ if ((offset + i) >= 12) continue;
+ if (!diff)
+ diff |=
+ (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfo[offset + i]),
+ sizeof(LOUDNESS_INFO)) != 0);
+ hLoudnessInfoSet->loudnessInfo[offset + i] = tmpLoud;
+ }
+ hLoudnessInfoSet->diff = diff;
+ return err;
+}
+
+static DRC_ERROR _readLoudnessInfoSetExtension(
+ HANDLE_FDK_BITSTREAM hBs, HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
+ DRC_ERROR err = DE_OK;
+ int k, bitSizeLen, extSizeBits, bitSize;
+ INT nBitsRemaining;
+ LOUDNESS_INFO_SET_EXTENSION* pExt = &(hLoudnessInfoSet->loudnessInfoSetExt);
+
+ k = 0;
+ pExt->loudnessInfoSetExtType[k] = FDKreadBits(hBs, 4);
+ while (pExt->loudnessInfoSetExtType[k] != UNIDRCLOUDEXT_TERM) {
+ if (k >= (8 - 1)) return DE_MEMORY_ERROR;
+ bitSizeLen = FDKreadBits(hBs, 4);
+ extSizeBits = bitSizeLen + 4;
+
+ bitSize = FDKreadBits(hBs, extSizeBits);
+ pExt->extBitSize[k] = bitSize + 1;
+ nBitsRemaining = (INT)FDKgetValidBits(hBs);
+
+ switch (pExt->loudnessInfoSetExtType[k]) {
+ case UNIDRCLOUDEXT_EQ:
+ err = _readLoudnessInfoSetExtEq(hBs, hLoudnessInfoSet);
+ if (err) return err;
+ if (nBitsRemaining !=
+ ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs)))
+ return DE_NOT_OK;
+ break;
+ /* add future extensions here */
+ default:
+ FDKpushFor(hBs, pExt->extBitSize[k]);
+ break;
+ }
+ k++;
+ pExt->loudnessInfoSetExtType[k] = FDKreadBits(hBs, 4);
+ }
+
+ return err;
+}
+
+/* Parser for loundessInfoSet() */
+DRC_ERROR
+drcDec_readLoudnessInfoSet(HANDLE_FDK_BITSTREAM hBs,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
+ DRC_ERROR err = DE_OK;
+ int i, diff = 0;
+ if (hLoudnessInfoSet == NULL) return DE_NOT_OK;
+
+ diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoAlbumCountV0,
+ FDKreadBits(hBs, 6));
+ diff |=
+ _compAssign(&hLoudnessInfoSet->loudnessInfoCountV0, FDKreadBits(hBs, 6));
+
+ hLoudnessInfoSet->loudnessInfoAlbumCount =
+ fMin(hLoudnessInfoSet->loudnessInfoAlbumCountV0, (UCHAR)12);
+ for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCountV0; i++) {
+ LOUDNESS_INFO tmpLoud;
+ FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
+ err = _readLoudnessInfo(hBs, 0, &tmpLoud);
+ if (err) return err;
+ if (i >= 12) continue;
+ if (!diff)
+ diff |= (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfoAlbum[i]),
+ sizeof(LOUDNESS_INFO)) != 0);
+ hLoudnessInfoSet->loudnessInfoAlbum[i] = tmpLoud;
+ }
+
+ hLoudnessInfoSet->loudnessInfoCount =
+ fMin(hLoudnessInfoSet->loudnessInfoCountV0, (UCHAR)12);
+ for (i = 0; i < hLoudnessInfoSet->loudnessInfoCountV0; i++) {
+ LOUDNESS_INFO tmpLoud;
+ FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
+ err = _readLoudnessInfo(hBs, 0, &tmpLoud);
+ if (err) return err;
+ if (i >= 12) continue;
+ if (!diff)
+ diff |= (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfo[i]),
+ sizeof(LOUDNESS_INFO)) != 0);
+ hLoudnessInfoSet->loudnessInfo[i] = tmpLoud;
+ }
+
+ diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoSetExtPresent,
+ FDKreadBits(hBs, 1));
+ hLoudnessInfoSet->diff = diff;
+
+ if (hLoudnessInfoSet->loudnessInfoSetExtPresent) {
+ err = _readLoudnessInfoSetExtension(hBs, hLoudnessInfoSet);
+ if (err) return err;
+ }
+
+ return err;
+}
diff --git a/fdk-aac/libDRCdec/src/drcDec_reader.h b/fdk-aac/libDRCdec/src/drcDec_reader.h
new file mode 100644
index 0000000..1ab9b58
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDec_reader.h
@@ -0,0 +1,130 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef DRCDEC_READER_H
+#define DRCDEC_READER_H
+
+#include "drcDecoder.h"
+#include "drcDec_types.h"
+#include "FDK_bitstream.h"
+
+DRC_ERROR
+drcDec_readUniDrc(HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ const int frameSize, const int deltaTminDefault,
+ HANDLE_UNI_DRC_GAIN hUniDrcGain);
+
+DRC_ERROR
+drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int frameSize,
+ const int deltaTminDefault,
+ HANDLE_UNI_DRC_GAIN hUniDrcGain);
+
+DRC_ERROR
+drcDec_readUniDrcConfig(HANDLE_FDK_BITSTREAM hBs,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig);
+
+DRC_ERROR
+drcDec_readLoudnessInfoSet(HANDLE_FDK_BITSTREAM hBs,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet);
+
+#endif
diff --git a/fdk-aac/libDRCdec/src/drcDec_rom.cpp b/fdk-aac/libDRCdec/src/drcDec_rom.cpp
new file mode 100644
index 0000000..9f89689
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDec_rom.cpp
@@ -0,0 +1,323 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "drcDec_types.h"
+#include "drcDec_rom.h"
+
+const SCHAR deltaGain_codingProfile_0_1_huffman[24][2] = {
+ {1, 2}, {3, 4}, {-63, -65}, {5, -66}, {-64, 6}, {-80, 7},
+ {8, 9}, {-68, 10}, {11, 12}, {-56, -67}, {-61, 13}, {-62, -69},
+ {14, 15}, {16, -72}, {-71, 17}, {-70, -60}, {18, -59}, {19, 20},
+ {21, -79}, {-57, -73}, {22, -58}, {-76, 23}, {-75, -74}, {-78, -77}};
+
+const SCHAR deltaGain_codingProfile_2_huffman[48][2] = {
+ {1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12},
+ {13, -65}, {14, -64}, {15, -66}, {16, -67}, {17, 18}, {19, -68},
+ {20, -63}, {-69, 21}, {-59, 22}, {-61, -62}, {-60, 23}, {24, -58},
+ {-70, -57}, {-56, -71}, {25, 26}, {27, -55}, {-72, 28}, {-54, 29},
+ {-53, 30}, {-73, -52}, {31, -74}, {32, 33}, {-75, 34}, {-76, 35},
+ {-51, 36}, {-78, 37}, {-77, 38}, {-96, 39}, {-48, 40}, {-50, -79},
+ {41, 42}, {-80, -81}, {-82, 43}, {44, -49}, {45, -84}, {-83, -89},
+ {-86, 46}, {-90, -85}, {-91, -93}, {-92, 47}, {-88, -87}, {-95, -94}};
+
+const FIXP_SGL slopeSteepness[] = {FL2FXCONST_SGL(-3.0518f / (float)(1 << 2)),
+ FL2FXCONST_SGL(-1.2207f / (float)(1 << 2)),
+ FL2FXCONST_SGL(-0.4883f / (float)(1 << 2)),
+ FL2FXCONST_SGL(-0.1953f / (float)(1 << 2)),
+ FL2FXCONST_SGL(-0.0781f / (float)(1 << 2)),
+ FL2FXCONST_SGL(-0.0312f / (float)(1 << 2)),
+ FL2FXCONST_SGL(-0.005f / (float)(1 << 2)),
+ FL2FXCONST_SGL(0.0f / (float)(1 << 2)),
+ FL2FXCONST_SGL(0.005f / (float)(1 << 2)),
+ FL2FXCONST_SGL(0.0312f / (float)(1 << 2)),
+ FL2FXCONST_SGL(0.0781f / (float)(1 << 2)),
+ FL2FXCONST_SGL(0.1953f / (float)(1 << 2)),
+ FL2FXCONST_SGL(0.4883f / (float)(1 << 2)),
+ FL2FXCONST_SGL(1.2207f / (float)(1 << 2)),
+ FL2FXCONST_SGL(3.0518f / (float)(1 << 2))};
+
+const SCHAR slopeSteepness_huffman[14][2] = {
+ {1, -57}, {-58, 2}, {3, 4}, {5, 6}, {7, -56},
+ {8, -60}, {-61, -55}, {9, -59}, {10, -54}, {-64, 11},
+ {-51, 12}, {-62, -50}, {-63, 13}, {-52, -53}};
+
+const FIXP_DBL downmixCoeff[] = {
+ FL2FXCONST_DBL(1.0000000000 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.9440608763 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.8912509381 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.8413951416 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.7943282347 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.7498942093 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.7079457844 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.6683439176 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.6309573445 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.5956621435 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.5623413252 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.5308844442 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.5011872336 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.4216965034 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.3548133892 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.0000000000 / (float)(1 << 2))};
+
+const FIXP_DBL downmixCoeffV1[] = {
+ FL2FXCONST_DBL(3.1622776602 / (float)(1 << 2)),
+ FL2FXCONST_DBL(1.9952623150 / (float)(1 << 2)),
+ FL2FXCONST_DBL(1.6788040181 / (float)(1 << 2)),
+ FL2FXCONST_DBL(1.4125375446 / (float)(1 << 2)),
+ FL2FXCONST_DBL(1.1885022274 / (float)(1 << 2)),
+ FL2FXCONST_DBL(1.0000000000 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.9440608763 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.8912509381 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.8413951416 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.7943282347 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.7498942093 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.7079457844 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.6683439176 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.6309573445 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.5956621435 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.5623413252 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.5308844442 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.5011872336 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.4731512590 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.4466835922 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.4216965034 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.3981071706 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.3548133892 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.3162277660 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.2818382931 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.2511886432 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.1778279410 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.1000000000 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.0562341325 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.0316227766 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.0100000000 / (float)(1 << 2)),
+ FL2FXCONST_DBL(0.0000000000 / (float)(1 << 2))};
+
+const CUSTOM_DRC_CHAR_SIGMOID cicpDrcCharSigmoidLeft[] = {
+ {FL2FXCONST_SGL(32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(0.0f / (float)(1 << 2)),
+ FL2FXCONST_SGL(9.0f / (float)(1 << 5)), 0}, /* 1 */
+ {FL2FXCONST_SGL(32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(0.2f / (float)(1 << 2)),
+ FL2FXCONST_SGL(9.0f / (float)(1 << 5)), 0}, /* 2 */
+ {FL2FXCONST_SGL(32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(0.4f / (float)(1 << 2)),
+ FL2FXCONST_SGL(9.0f / (float)(1 << 5)), 0}, /* 3 */
+ {FL2FXCONST_SGL(32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(0.6f / (float)(1 << 2)),
+ FL2FXCONST_SGL(9.0f / (float)(1 << 5)), 0}, /* 4 */
+ {FL2FXCONST_SGL(32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(0.8f / (float)(1 << 2)),
+ FL2FXCONST_SGL(6.0f / (float)(1 << 5)), 0}, /* 5 */
+ {FL2FXCONST_SGL(32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
+ FL2FXCONST_SGL(5.0f / (float)(1 << 5)), 0}, /* 6 */
+};
+
+const CUSTOM_DRC_CHAR_SIGMOID cicpDrcCharSigmoidRight[] = {
+ {FL2FXCONST_SGL(-32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(0.0f / (float)(1 << 2)),
+ FL2FXCONST_SGL(12.0f / (float)(1 << 5)), 0}, /* 1 */
+ {FL2FXCONST_SGL(-32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(0.2f / (float)(1 << 2)),
+ FL2FXCONST_SGL(12.0f / (float)(1 << 5)), 0}, /* 2 */
+ {FL2FXCONST_SGL(-32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(0.4f / (float)(1 << 2)),
+ FL2FXCONST_SGL(12.0f / (float)(1 << 5)), 0}, /* 3 */
+ {FL2FXCONST_SGL(-32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(0.6f / (float)(1 << 2)),
+ FL2FXCONST_SGL(10.0f / (float)(1 << 5)), 0}, /* 4 */
+ {FL2FXCONST_SGL(-32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(0.8f / (float)(1 << 2)),
+ FL2FXCONST_SGL(8.0f / (float)(1 << 5)), 0}, /* 5 */
+ {FL2FXCONST_SGL(-32.0f / (float)(1 << 6)),
+ FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
+ FL2FXCONST_SGL(6.0f / (float)(1 << 5)), 0}, /* 6 */
+};
+
+const CUSTOM_DRC_CHAR_NODES cicpDrcCharNodesLeft[] = {
+ {2,
+ {FL2FXCONST_SGL(-31.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-41.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-53.0f / (float)(1 << 7))},
+ {FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(6.0f / (float)(1 << 7))}}, /* 7 */
+ {1,
+ {FL2FXCONST_SGL(-31.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-43.0f / (float)(1 << 7))},
+ {FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(6.0f / (float)(1 << 7))}}, /* 8 */
+ {2,
+ {FL2FXCONST_SGL(-31.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-41.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-65.0f / (float)(1 << 7))},
+ {FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(12.0f / (float)(1 << 7))}}, /* 9 */
+ {1,
+ {FL2FXCONST_SGL(-31.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-55.0f / (float)(1 << 7))},
+ {FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(12.0f / (float)(1 << 7))}}, /* 10 */
+ {1,
+ {FL2FXCONST_SGL(-31.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-50.0f / (float)(1 << 7))},
+ {FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(15.0f / (float)(1 << 7))}} /* 11 */
+};
+
+const CUSTOM_DRC_CHAR_NODES cicpDrcCharNodesRight[] = {
+ {4,
+ {FL2FXCONST_SGL(-31.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-21.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-11.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(9.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(19.0f / (float)(1 << 7))},
+ {FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-5.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-24.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-34.0f / (float)(1 << 7))}}, /* 7 */
+ {4,
+ {FL2FXCONST_SGL(-31.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-26.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-16.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(4.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(14.0f / (float)(1 << 7))},
+ {FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-5.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-24.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-34.0f / (float)(1 << 7))}}, /* 8 */
+ {3,
+ {FL2FXCONST_SGL(-31.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-21.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(9.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(29.0f / (float)(1 << 7))},
+ {FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-15.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-35.0f / (float)(1 << 7))}}, /* 9 */
+ {4,
+ {FL2FXCONST_SGL(-31.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-26.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-16.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(4.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(14.0f / (float)(1 << 7))},
+ {FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-5.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-24.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-34.0f / (float)(1 << 7))}}, /* 10 */
+ {4,
+ {FL2FXCONST_SGL(-31.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-26.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-16.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(4.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(14.0f / (float)(1 << 7))},
+ {FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(0.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-5.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-24.0f / (float)(1 << 7)),
+ FL2FXCONST_SGL(-34.0f / (float)(1 << 7))}} /* 11 */
+};
diff --git a/fdk-aac/libDRCdec/src/drcDec_rom.h b/fdk-aac/libDRCdec/src/drcDec_rom.h
new file mode 100644
index 0000000..daee882
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDec_rom.h
@@ -0,0 +1,120 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef DRCDEC_ROM_H
+#define DRCDEC_ROM_H
+
+extern const SCHAR deltaGain_codingProfile_0_1_huffman[24][2];
+extern const SCHAR deltaGain_codingProfile_2_huffman[48][2];
+
+extern const FIXP_SGL slopeSteepness[];
+extern const SCHAR slopeSteepness_huffman[14][2];
+
+extern const FIXP_DBL downmixCoeff[];
+extern const FIXP_DBL downmixCoeffV1[];
+
+extern const CUSTOM_DRC_CHAR_SIGMOID cicpDrcCharSigmoidLeft[];
+extern const CUSTOM_DRC_CHAR_SIGMOID cicpDrcCharSigmoidRight[];
+extern const CUSTOM_DRC_CHAR_NODES cicpDrcCharNodesLeft[];
+extern const CUSTOM_DRC_CHAR_NODES cicpDrcCharNodesRight[];
+
+#endif
diff --git a/fdk-aac/libDRCdec/src/drcDec_selectionProcess.cpp b/fdk-aac/libDRCdec/src/drcDec_selectionProcess.cpp
new file mode 100644
index 0000000..9228197
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDec_selectionProcess.cpp
@@ -0,0 +1,3099 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s): Andreas Hoelzer
+
+ Description: DRC Set Selection
+
+*******************************************************************************/
+
+#include "drcDec_selectionProcess.h"
+#include "drcDec_tools.h"
+
+#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL) MAXVAL_DBL
+
+typedef enum {
+ DETR_NONE = 0,
+ DETR_NIGHT = 1,
+ DETR_NOISY = 2,
+ DETR_LIMITED = 3,
+ DETR_LOWLEVEL = 4,
+ DETR_DIALOG = 5,
+ DETR_GENERAL_COMPR = 6,
+ DETR_EXPAND = 7,
+ DETR_ARTISTIC = 8,
+ DETR_COUNT
+} DRC_EFFECT_TYPE_REQUEST;
+
+typedef enum {
+ DFRT_EFFECT_TYPE,
+ DFRT_DYNAMIC_RANGE,
+ DFRT_DRC_CHARACTERISTIC
+} DRC_FEATURE_REQUEST_TYPE;
+
+typedef enum {
+ MDR_DEFAULT = 0,
+ MDR_PROGRAM_LOUDNESS = 1,
+ MDR_ANCHOR_LOUDNESS = 2
+} METHOD_DEFINITION_REQUEST;
+
+typedef enum {
+ MSR_DEFAULT = 0,
+ MSR_BS_1770_4 = 1,
+ MSR_USER = 2,
+ MSR_EXPERT_PANEL = 3,
+ MSR_RESERVED_A = 4,
+ MSR_RESERVED_B = 5,
+ MSR_RESERVED_C = 6,
+ MSR_RESERVED_D = 7,
+ MSR_RESERVED_E = 8
+} MEASUREMENT_SYSTEM_REQUEST;
+
+typedef enum {
+ LPR_DEFAULT = 0,
+ LPR_OFF = 1,
+ LPR_HIGHPASS = 2
+} LOUDNESS_PREPROCESSING_REQUEST;
+
+typedef enum {
+ DRMRT_SHORT_TERM_LOUDNESS_TO_AVG = 0,
+ DRMRT_MOMENTARY_LOUDNESS_TO_AVG = 1,
+ DRMRT_TOP_OF_LOUDNESS_RANGE_TO_AVG = 2
+} DYN_RANGE_MEASUREMENT_REQUEST_TYPE;
+
+typedef enum {
+ TCRT_DOWNMIX_ID = 0,
+ TCRT_TARGET_LAYOUT = 1,
+ TCRT_TARGET_CHANNEL_COUNT = 2
+} TARGET_CONFIG_REQUEST_TYPE;
+
+typedef shouldBeUnion {
+ struct {
+ UCHAR numRequests;
+ UCHAR numRequestsDesired;
+ DRC_EFFECT_TYPE_REQUEST request[MAX_REQUESTS_DRC_EFFECT_TYPE];
+ } drcEffectType;
+ struct {
+ DYN_RANGE_MEASUREMENT_REQUEST_TYPE measurementRequestType;
+ UCHAR requestedIsRange;
+ FIXP_DBL requestValue; /* e = 7 */
+ FIXP_DBL requestValueMin; /* e = 7 */
+ FIXP_DBL requestValueMax; /* e = 7 */
+ } dynamicRange;
+ UCHAR drcCharacteristic;
+}
+DRC_FEATURE_REQUEST;
+
+typedef struct {
+ /* system parameters */
+ SCHAR baseChannelCount;
+ SCHAR baseLayout; /* not supported */
+ TARGET_CONFIG_REQUEST_TYPE targetConfigRequestType;
+ UCHAR numDownmixIdRequests;
+ UCHAR downmixIdRequested[MAX_REQUESTS_DOWNMIX_ID];
+ UCHAR targetLayoutRequested;
+ UCHAR targetChannelCountRequested;
+ LONG audioSampleRate; /* needed for complexity estimation, currently not
+ supported */
+
+ /* loudness normalization parameters */
+ UCHAR loudnessNormalizationOn;
+ FIXP_DBL targetLoudness; /* e = 7 */
+ UCHAR albumMode;
+ UCHAR peakLimiterPresent;
+ UCHAR loudnessDeviationMax; /* resolution: 1 dB */
+ METHOD_DEFINITION_REQUEST loudnessMeasurementMethod;
+ MEASUREMENT_SYSTEM_REQUEST loudnessMeasurementSystem;
+ LOUDNESS_PREPROCESSING_REQUEST loudnessMeasurementPreProc; /* not supported */
+ LONG deviceCutOffFrequency; /* not supported */
+ FIXP_DBL loudnessNormalizationGainDbMax; /* e = 7 */
+ FIXP_DBL loudnessNormalizationGainModificationDb; /* e = 7 */
+ FIXP_DBL outputPeakLevelMax; /* e = 7 */
+
+ /* dynamic range control parameters */
+ UCHAR dynamicRangeControlOn;
+ UCHAR numDrcFeatureRequests;
+ DRC_FEATURE_REQUEST_TYPE drcFeatureRequestType[MAX_REQUESTS_DRC_FEATURE];
+ DRC_FEATURE_REQUEST drcFeatureRequest[MAX_REQUESTS_DRC_FEATURE];
+
+ /* other */
+ FIXP_SGL boost; /* e = 1 */
+ FIXP_SGL compress; /* e = 1 */
+ UCHAR drcCharacteristicTarget; /* not supported */
+} SEL_PROC_INPUT, *HANDLE_SEL_PROC_INPUT;
+
+/* Table E.1 of ISO/IEC DIS 23003-4: Recommended order of fallback effect type
+ * requests */
+static DRC_EFFECT_TYPE_REQUEST fallbackEffectTypeRequests[6][5] = {
+ /* Night */ {DETR_GENERAL_COMPR, DETR_NOISY, DETR_LIMITED, DETR_LOWLEVEL,
+ DETR_DIALOG},
+ /* Noisy */
+ {DETR_GENERAL_COMPR, DETR_NIGHT, DETR_LIMITED, DETR_LOWLEVEL, DETR_DIALOG},
+ /* Limited */
+ {DETR_GENERAL_COMPR, DETR_NIGHT, DETR_NOISY, DETR_LOWLEVEL, DETR_DIALOG},
+ /* LowLevel */
+ {DETR_GENERAL_COMPR, DETR_NOISY, DETR_NIGHT, DETR_LIMITED, DETR_DIALOG},
+ /* Dialog */
+ {DETR_GENERAL_COMPR, DETR_NIGHT, DETR_NOISY, DETR_LIMITED, DETR_LOWLEVEL},
+ /* General */
+ {DETR_NIGHT, DETR_NOISY, DETR_LIMITED, DETR_LOWLEVEL, DETR_DIALOG}};
+
+/*******************************************/
+typedef struct {
+ UCHAR selectionFlag;
+ UCHAR downmixIdRequestIndex;
+ FIXP_DBL outputPeakLevel; /* e = 7 */
+ FIXP_DBL loudnessNormalizationGainDbAdjusted; /* e = 7 */
+ FIXP_DBL outputLoudness; /* e = 7 */
+ DRC_INSTRUCTIONS_UNI_DRC* pInst;
+
+} DRCDEC_SELECTION_DATA;
+
+typedef struct {
+ UCHAR numData;
+ DRCDEC_SELECTION_DATA data[(12 + 1 + 6)];
+
+} DRCDEC_SELECTION;
+
+/*******************************************/
+/* helper functions */
+/*******************************************/
+
+static int _isError(int x) {
+ if (x < DRCDEC_SELECTION_PROCESS_WARNING) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/* compare and assign */
+static inline int _compAssign(UCHAR* dest, const UCHAR src) {
+ int diff = 0;
+ if (*dest != src) diff = 1;
+ *dest = src;
+ return diff;
+}
+
+static inline int _compAssign(SCHAR* dest, const SCHAR src) {
+ int diff = 0;
+ if (*dest != src) diff = 1;
+ *dest = src;
+ return diff;
+}
+
+static inline int _compAssign(FIXP_DBL* dest, const FIXP_DBL src) {
+ int diff = 0;
+ if (*dest != src) diff = 1;
+ *dest = src;
+ return diff;
+}
+
+static inline int _compAssign(FIXP_SGL* dest, const FIXP_SGL src) {
+ int diff = 0;
+ if (*dest != src) diff = 1;
+ *dest = src;
+ return diff;
+}
+
+static inline int _compAssign(TARGET_CONFIG_REQUEST_TYPE* dest, const int src) {
+ int diff = 0;
+ if (*dest != src) diff = 1;
+ *dest = (TARGET_CONFIG_REQUEST_TYPE)src;
+ return diff;
+}
+
+static inline int _compAssign(METHOD_DEFINITION_REQUEST* dest, const int src) {
+ int diff = 0;
+ if (*dest != src) diff = 1;
+ *dest = (METHOD_DEFINITION_REQUEST)src;
+ return diff;
+}
+
+static inline int _compAssign(DRC_FEATURE_REQUEST_TYPE* dest, const int src) {
+ int diff = 0;
+ if (*dest != src) diff = 1;
+ *dest = (DRC_FEATURE_REQUEST_TYPE)src;
+ return diff;
+}
+
+static inline int _compAssign(DRC_EFFECT_TYPE_REQUEST* dest, const int src) {
+ int diff = 0;
+ if (*dest != src) diff = 1;
+ *dest = (DRC_EFFECT_TYPE_REQUEST)src;
+ return diff;
+}
+
+static DRCDEC_SELECTION_DATA* _drcdec_selection_addNew(
+ DRCDEC_SELECTION* pSelection);
+
+static DRCDEC_SELECTION_DATA* _drcdec_selection_add(
+ DRCDEC_SELECTION* pSelection, DRCDEC_SELECTION_DATA* pDataIn);
+
+static int _drcdec_selection_clear(DRCDEC_SELECTION* pSelection);
+
+static int _drcdec_selection_getNumber(DRCDEC_SELECTION* pSelection);
+
+static int _drcdec_selection_setNumber(DRCDEC_SELECTION* pSelection, int num);
+
+static DRCDEC_SELECTION_DATA* _drcdec_selection_getAt(
+ DRCDEC_SELECTION* pSelection, int at);
+
+static int _swapSelectionAndClear(DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected);
+
+static int _swapSelection(DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected);
+
+/*******************************************/
+/* declarations of static functions */
+/*******************************************/
+
+static DRCDEC_SELECTION_PROCESS_RETURN _initDefaultParams(
+ HANDLE_SEL_PROC_INPUT hSelProcInput);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _initCodecModeParams(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, const SEL_PROC_CODEC_MODE codecMode);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelection(
+ SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_peakValue0(
+ DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _dynamicRangeMeasurement(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
+ UCHAR downmixIdRequested,
+ DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
+ int albumMode, int* peakToAveragePresent, FIXP_DBL* peakToAverage);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _channelLayoutToDownmixIdMapping(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _generateVirtualDrcSets(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ SEL_PROC_CODEC_MODE codecMode);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetRequestSelection(
+ SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ DRCDEC_SELECTION_DATA* pSelectionData, SEL_PROC_CODEC_MODE codecMode);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _selectDownmixMatrix(
+ HANDLE_SEL_PROC_OUTPUT hSelProcOutput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _getLoudness(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int albumMode,
+ METHOD_DEFINITION_REQUEST measurementMethodRequested,
+ MEASUREMENT_SYSTEM_REQUEST measurementSystemRequested,
+ FIXP_DBL targetLoudness, int drcSetId, int downmixIdRequested,
+ FIXP_DBL* pLoudnessNormalizationGain, FIXP_DBL* pLoudness);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _getMixingLevel(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int downmixIdRequested,
+ int drcSetIdRequested, int albumMode, FIXP_DBL* pMixingLevel);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _getSignalPeakLevel(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
+ int downmixIdRequested, int* explicitPeakInformationPresent,
+ FIXP_DBL* signalPeakLevelOut, /* e = 7 */
+ SEL_PROC_CODEC_MODE codecMode);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _extractLoudnessPeakToAverageValue(
+ LOUDNESS_INFO* loudnessInfo,
+ DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
+ int* pLoudnessPeakToAverageValuePresent,
+ FIXP_DBL* pLoudnessPeakToAverageValue);
+
+static DRCDEC_SELECTION_PROCESS_RETURN _selectAlbumLoudness(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected);
+
+static int _findMethodDefinition(LOUDNESS_INFO* pLoudnessInfo,
+ int methodDefinition, int startIndex);
+
+/*******************************************/
+/* public functions */
+/*******************************************/
+
+struct s_drcdec_selection_process {
+ SEL_PROC_CODEC_MODE codecMode;
+ SEL_PROC_INPUT selProcInput;
+ DRCDEC_SELECTION
+ selectionData[2]; /* 2 instances, one before and one after selection */
+};
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_Create(HANDLE_DRC_SELECTION_PROCESS* phInstance) {
+ HANDLE_DRC_SELECTION_PROCESS hInstance;
+ hInstance = (HANDLE_DRC_SELECTION_PROCESS)FDKcalloc(
+ 1, sizeof(struct s_drcdec_selection_process));
+
+ if (!hInstance) return DRCDEC_SELECTION_PROCESS_OUTOFMEMORY;
+
+ hInstance->codecMode = SEL_PROC_CODEC_MODE_UNDEFINED;
+
+ *phInstance = hInstance;
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_Init(HANDLE_DRC_SELECTION_PROCESS hInstance) {
+ if (!hInstance) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ _initDefaultParams(&hInstance->selProcInput);
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_SetCodecMode(HANDLE_DRC_SELECTION_PROCESS hInstance,
+ const SEL_PROC_CODEC_MODE codecMode) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+
+ if (!hInstance) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ switch (codecMode) {
+ case SEL_PROC_MPEG_4_AAC:
+ case SEL_PROC_MPEG_D_USAC:
+ case SEL_PROC_TEST_TIME_DOMAIN:
+ case SEL_PROC_TEST_QMF_DOMAIN:
+ case SEL_PROC_TEST_STFT_DOMAIN:
+ hInstance->codecMode = codecMode;
+ break;
+
+ case SEL_PROC_CODEC_MODE_UNDEFINED:
+ default:
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ retVal = _initCodecModeParams(&(hInstance->selProcInput),
+ hInstance->codecMode = codecMode);
+
+ return retVal;
+}
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_SetParam(HANDLE_DRC_SELECTION_PROCESS hInstance,
+ const SEL_PROC_USER_PARAM requestType,
+ FIXP_DBL requestValue, int* pDiff) {
+ INT requestValueInt = (INT)requestValue;
+ int i, diff = 0;
+ SEL_PROC_INPUT* pSelProcInput = &(hInstance->selProcInput);
+
+ switch (requestType) {
+ case SEL_PROC_LOUDNESS_NORMALIZATION_ON:
+ if ((requestValueInt != 0) && (requestValueInt != 1))
+ return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
+ diff |=
+ _compAssign(&pSelProcInput->loudnessNormalizationOn, requestValueInt);
+ break;
+ case SEL_PROC_TARGET_LOUDNESS:
+ /* Lower boundary: drcSetTargetLoudnessValueLower default value.
+ Upper boundary: drcSetTargetLoudnessValueUpper default value */
+ if ((requestValue < FL2FXCONST_DBL(-63.0f / (float)(1 << 7))) ||
+ (requestValue > (FIXP_DBL)0))
+ return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
+ if (requestValue >
+ FL2FXCONST_DBL(-10.0f /
+ (float)(1 << 7))) /* recommended maximum value */
+ requestValue = FL2FXCONST_DBL(-10.0f / (float)(1 << 7));
+ diff |= _compAssign(&pSelProcInput->targetLoudness, requestValue);
+ break;
+ case SEL_PROC_EFFECT_TYPE:
+ if ((requestValueInt < -1) || (requestValueInt >= DETR_COUNT))
+ return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
+ /* Caution. This overrides all drcFeatureRequests requested so far! */
+ if (requestValueInt == -1) {
+ diff |= _compAssign(&pSelProcInput->dynamicRangeControlOn, 0);
+ } else if (requestValueInt == DETR_NONE) {
+ diff |= _compAssign(&pSelProcInput->dynamicRangeControlOn, 1);
+ diff |= _compAssign(&pSelProcInput->numDrcFeatureRequests, 0);
+ } else {
+ diff |= _compAssign(&pSelProcInput->dynamicRangeControlOn, 1);
+ diff |= _compAssign(&pSelProcInput->numDrcFeatureRequests, 1);
+ diff |= _compAssign(&pSelProcInput->drcFeatureRequestType[0],
+ DFRT_EFFECT_TYPE);
+ diff |= _compAssign(&pSelProcInput->drcFeatureRequest[0]
+ .drcEffectType.numRequestsDesired,
+ 1);
+ diff |= _compAssign(
+ &pSelProcInput->drcFeatureRequest[0].drcEffectType.request[0],
+ requestValueInt);
+ if ((requestValueInt > DETR_NONE) &&
+ (requestValueInt <= DETR_GENERAL_COMPR)) {
+ /* use fallback effect type requests */
+ for (i = 0; i < 5; i++) {
+ diff |=
+ _compAssign(&pSelProcInput->drcFeatureRequest[0]
+ .drcEffectType.request[i + 1],
+ fallbackEffectTypeRequests[requestValueInt - 1][i]);
+ }
+ diff |= _compAssign(
+ &pSelProcInput->drcFeatureRequest[0].drcEffectType.numRequests,
+ 6);
+ } else {
+ diff |= _compAssign(
+ &pSelProcInput->drcFeatureRequest[0].drcEffectType.numRequests,
+ 1);
+ }
+ }
+ break;
+ case SEL_PROC_LOUDNESS_MEASUREMENT_METHOD:
+ if ((requestValueInt < 0) || (requestValueInt > 2))
+ return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
+ diff |= _compAssign(&pSelProcInput->loudnessMeasurementMethod,
+ requestValueInt);
+ break;
+ case SEL_PROC_DOWNMIX_ID:
+ diff |=
+ _compAssign(&pSelProcInput->targetConfigRequestType, TCRT_DOWNMIX_ID);
+ if (requestValueInt < 0) { /* negative requests signal no downmixId */
+ diff |= _compAssign(&pSelProcInput->numDownmixIdRequests, 0);
+ } else {
+ diff |= _compAssign(&pSelProcInput->numDownmixIdRequests, 1);
+ diff |=
+ _compAssign(&pSelProcInput->downmixIdRequested[0], requestValueInt);
+ }
+ break;
+ case SEL_PROC_TARGET_LAYOUT:
+ /* Request target layout according to ChannelConfiguration in ISO/IEC
+ * 23001-8 (CICP) */
+ if ((requestValueInt < 1) || (requestValueInt > 63))
+ return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
+ diff |= _compAssign(&pSelProcInput->targetConfigRequestType,
+ TCRT_TARGET_LAYOUT);
+ diff |=
+ _compAssign(&pSelProcInput->targetLayoutRequested, requestValueInt);
+ break;
+ case SEL_PROC_TARGET_CHANNEL_COUNT:
+ if ((requestValueInt < 1) || (requestValueInt > 8))
+ return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
+ diff |= _compAssign(&pSelProcInput->targetConfigRequestType,
+ TCRT_TARGET_CHANNEL_COUNT);
+ diff |= _compAssign(&pSelProcInput->targetChannelCountRequested,
+ requestValueInt);
+ break;
+ case SEL_PROC_BASE_CHANNEL_COUNT:
+ if (requestValueInt < 0)
+ return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
+ diff |= _compAssign(&pSelProcInput->baseChannelCount, requestValueInt);
+ break;
+ case SEL_PROC_SAMPLE_RATE:
+ if (requestValueInt < 0)
+ return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
+ diff |= _compAssign(&pSelProcInput->audioSampleRate, requestValueInt);
+ break;
+ case SEL_PROC_BOOST:
+ if ((requestValue < (FIXP_DBL)0) ||
+ (requestValue > FL2FXCONST_DBL(1.0f / (float)(1 << 1))))
+ return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
+ diff |= _compAssign(&pSelProcInput->boost, FX_DBL2FX_SGL(requestValue));
+ break;
+ case SEL_PROC_COMPRESS:
+ if ((requestValue < (FIXP_DBL)0) ||
+ (requestValue > FL2FXCONST_DBL(1.0f / (float)(1 << 1))))
+ return DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE;
+ diff |=
+ _compAssign(&pSelProcInput->compress, FX_DBL2FX_SGL(requestValue));
+ break;
+ default:
+ return DRCDEC_SELECTION_PROCESS_INVALID_PARAM;
+ }
+
+ if (pDiff != NULL) {
+ *pDiff |= diff;
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+FIXP_DBL
+drcDec_SelectionProcess_GetParam(HANDLE_DRC_SELECTION_PROCESS hInstance,
+ const SEL_PROC_USER_PARAM requestType) {
+ SEL_PROC_INPUT* pSelProcInput = &(hInstance->selProcInput);
+
+ switch (requestType) {
+ case SEL_PROC_LOUDNESS_NORMALIZATION_ON:
+ return (FIXP_DBL)pSelProcInput->loudnessNormalizationOn;
+ case SEL_PROC_DYNAMIC_RANGE_CONTROL_ON:
+ return (FIXP_DBL)pSelProcInput->dynamicRangeControlOn;
+ default:
+ return (FIXP_DBL)0;
+ }
+}
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_Delete(HANDLE_DRC_SELECTION_PROCESS* phInstance) {
+ if (phInstance == NULL || *phInstance == NULL)
+ return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;
+
+ FDKfree(*phInstance);
+ *phInstance = NULL;
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_Process(HANDLE_DRC_SELECTION_PROCESS hInstance,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ HANDLE_SEL_PROC_OUTPUT hSelProcOutput) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ DRCDEC_SELECTION* pCandidatesSelected;
+ DRCDEC_SELECTION* pCandidatesPotential;
+
+ if (hInstance == NULL) return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;
+
+ pCandidatesSelected = &(hInstance->selectionData[0]);
+ pCandidatesPotential = &(hInstance->selectionData[1]);
+ _drcdec_selection_setNumber(pCandidatesSelected, 0);
+ _drcdec_selection_setNumber(pCandidatesPotential, 0);
+
+ retVal = _generateVirtualDrcSets(&(hInstance->selProcInput), hUniDrcConfig,
+ hInstance->codecMode);
+ if (retVal) return (retVal);
+
+ if (hInstance->selProcInput.baseChannelCount !=
+ hUniDrcConfig->channelLayout.baseChannelCount) {
+ hInstance->selProcInput.baseChannelCount =
+ hUniDrcConfig->channelLayout.baseChannelCount;
+ }
+
+ if ((hInstance->selProcInput.targetConfigRequestType != 0) ||
+ (hInstance->selProcInput.targetConfigRequestType == 0 &&
+ hInstance->selProcInput.numDownmixIdRequests == 0)) {
+ retVal = _channelLayoutToDownmixIdMapping(&(hInstance->selProcInput),
+ hUniDrcConfig);
+
+ if (_isError(retVal)) return (retVal);
+ }
+
+ retVal = _drcSetPreSelection(&(hInstance->selProcInput), hUniDrcConfig,
+ hLoudnessInfoSet, &pCandidatesPotential,
+ &pCandidatesSelected, hInstance->codecMode);
+ if (retVal) return (retVal);
+
+ if (hInstance->selProcInput.albumMode) {
+ _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);
+
+ retVal = _selectAlbumLoudness(hLoudnessInfoSet, pCandidatesPotential,
+ pCandidatesSelected);
+ if (retVal) return (retVal);
+
+ if (_drcdec_selection_getNumber(pCandidatesSelected) == 0) {
+ _swapSelection(&pCandidatesPotential, &pCandidatesSelected);
+ }
+ }
+
+ _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);
+
+ retVal = _drcSetRequestSelection(&(hInstance->selProcInput), hUniDrcConfig,
+ hLoudnessInfoSet, &pCandidatesPotential,
+ &pCandidatesSelected);
+ if (retVal) return (retVal);
+
+ retVal = _drcSetFinalSelection(&(hInstance->selProcInput), hUniDrcConfig,
+ &pCandidatesPotential, &pCandidatesSelected,
+ hInstance->codecMode);
+ if (retVal) return (retVal);
+
+ retVal = _generateOutputInfo(
+ &(hInstance->selProcInput), hSelProcOutput, hUniDrcConfig,
+ hLoudnessInfoSet, &(pCandidatesSelected->data[0]), hInstance->codecMode);
+
+ if (_isError(retVal)) return (retVal);
+
+ retVal = _selectDownmixMatrix(hSelProcOutput, hUniDrcConfig);
+ if (retVal) return (retVal);
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/*******************************************/
+/* static functions */
+/*******************************************/
+
+static DRCDEC_SELECTION_PROCESS_RETURN _initDefaultParams(
+ HANDLE_SEL_PROC_INPUT hSelProcInput) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+
+ if (hSelProcInput == NULL) return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;
+
+ /* system parameters */
+ hSelProcInput->baseChannelCount = -1;
+ hSelProcInput->baseLayout = -1;
+ hSelProcInput->targetConfigRequestType = TCRT_DOWNMIX_ID;
+ hSelProcInput->numDownmixIdRequests = 0;
+
+ /* loudness normalization parameters */
+ hSelProcInput->albumMode = 0;
+ hSelProcInput->peakLimiterPresent = 0;
+ hSelProcInput->loudnessNormalizationOn = 1;
+ hSelProcInput->targetLoudness = FL2FXCONST_DBL(-24.0f / (float)(1 << 7));
+ hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
+ hSelProcInput->loudnessMeasurementMethod = MDR_DEFAULT;
+ hSelProcInput->loudnessMeasurementSystem = MSR_DEFAULT;
+ hSelProcInput->loudnessMeasurementPreProc = LPR_DEFAULT;
+ hSelProcInput->deviceCutOffFrequency = 500;
+ hSelProcInput->loudnessNormalizationGainDbMax =
+ (FIXP_DBL)MAXVAL_DBL; /* infinity as default */
+ hSelProcInput->loudnessNormalizationGainModificationDb = (FIXP_DBL)0;
+ hSelProcInput->outputPeakLevelMax = (FIXP_DBL)0;
+ if (hSelProcInput->peakLimiterPresent == 1) {
+ hSelProcInput->outputPeakLevelMax = FL2FXCONST_DBL(6.0f / (float)(1 << 7));
+ }
+
+ /* dynamic range control parameters */
+ hSelProcInput->dynamicRangeControlOn = 1;
+
+ hSelProcInput->numDrcFeatureRequests = 0;
+
+ /* other parameters */
+ hSelProcInput->boost = FL2FXCONST_SGL(1.f / (float)(1 << 1));
+ hSelProcInput->compress = FL2FXCONST_SGL(1.f / (float)(1 << 1));
+ hSelProcInput->drcCharacteristicTarget = 0;
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _initCodecModeParams(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, const SEL_PROC_CODEC_MODE codecMode) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+
+ if (hSelProcInput == NULL) return DRCDEC_SELECTION_PROCESS_INVALID_HANDLE;
+
+ switch (codecMode) {
+ case SEL_PROC_MPEG_H_3DA:
+ hSelProcInput->loudnessDeviationMax = 0;
+ hSelProcInput->peakLimiterPresent = 1; /* peak limiter is mandatory */
+ /* The peak limiter also has to catch overshoots due to user
+ interactivity, downmixing etc. Therefore the maximum output peak level is
+ reduced to 0 dB. */
+ hSelProcInput->outputPeakLevelMax = (FIXP_DBL)0;
+ break;
+ case SEL_PROC_MPEG_4_AAC:
+ case SEL_PROC_MPEG_D_USAC:
+ hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
+ hSelProcInput->peakLimiterPresent = 1;
+ /* A peak limiter is present at the end of the decoder, therefore we can
+ * allow for a maximum output peak level greater than full scale
+ */
+ hSelProcInput->outputPeakLevelMax =
+ FL2FXCONST_DBL(6.0f / (float)(1 << 7));
+ break;
+ case SEL_PROC_TEST_TIME_DOMAIN:
+ case SEL_PROC_TEST_QMF_DOMAIN:
+ case SEL_PROC_TEST_STFT_DOMAIN:
+ /* for testing, adapt to default settings in reference software */
+ hSelProcInput->loudnessNormalizationOn = 0;
+ hSelProcInput->dynamicRangeControlOn = 0;
+ break;
+ case SEL_PROC_CODEC_MODE_UNDEFINED:
+ default:
+ hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX;
+ hSelProcInput->peakLimiterPresent = 0;
+ }
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _channelLayoutToDownmixIdMapping(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+
+ DOWNMIX_INSTRUCTIONS* pDown = NULL;
+
+ int i;
+
+ hSelProcInput->numDownmixIdRequests = 0;
+
+ switch (hSelProcInput->targetConfigRequestType) {
+ case TCRT_DOWNMIX_ID:
+ if (hSelProcInput->numDownmixIdRequests == 0) {
+ hSelProcInput->downmixIdRequested[0] = 0;
+ hSelProcInput->numDownmixIdRequests = 1;
+ }
+
+ break;
+
+ case TCRT_TARGET_LAYOUT:
+ if (hSelProcInput->targetLayoutRequested == hSelProcInput->baseLayout) {
+ hSelProcInput->downmixIdRequested[0] = 0;
+ hSelProcInput->numDownmixIdRequests = 1;
+ }
+
+ if (hSelProcInput->numDownmixIdRequests == 0) {
+ for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
+ pDown = &(hUniDrcConfig->downmixInstructions[i]);
+
+ if (hSelProcInput->targetLayoutRequested == pDown->targetLayout) {
+ hSelProcInput
+ ->downmixIdRequested[hSelProcInput->numDownmixIdRequests] =
+ pDown->downmixId;
+ hSelProcInput->numDownmixIdRequests++;
+ }
+ }
+ }
+
+ if (hSelProcInput->baseLayout == -1) {
+ retVal = DRCDEC_SELECTION_PROCESS_WARNING;
+ }
+
+ if (hSelProcInput->numDownmixIdRequests == 0) {
+ hSelProcInput->downmixIdRequested[0] = 0;
+ hSelProcInput->numDownmixIdRequests = 1;
+ retVal = DRCDEC_SELECTION_PROCESS_WARNING;
+ }
+
+ break;
+
+ case TCRT_TARGET_CHANNEL_COUNT:
+ if (hSelProcInput->targetChannelCountRequested ==
+ hSelProcInput->baseChannelCount) {
+ hSelProcInput->downmixIdRequested[0] = 0;
+ hSelProcInput->numDownmixIdRequests = 1;
+ }
+
+ if (hSelProcInput->numDownmixIdRequests == 0) {
+ for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
+ pDown = &(hUniDrcConfig->downmixInstructions[i]);
+
+ if (hSelProcInput->targetChannelCountRequested ==
+ pDown->targetChannelCount) {
+ hSelProcInput
+ ->downmixIdRequested[hSelProcInput->numDownmixIdRequests] =
+ pDown->downmixId;
+ hSelProcInput->numDownmixIdRequests++;
+ }
+ }
+ }
+
+ if (hSelProcInput->baseChannelCount == -1) {
+ retVal = DRCDEC_SELECTION_PROCESS_WARNING;
+ }
+
+ if (hSelProcInput->numDownmixIdRequests == 0) {
+ retVal = DRCDEC_SELECTION_PROCESS_WARNING;
+ hSelProcInput->downmixIdRequested[0] = 0;
+ hSelProcInput->numDownmixIdRequests = 1;
+ }
+
+ break;
+
+ default:
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ return retVal;
+}
+
+/*******************************************/
+
+/* Note: Numbering of DRC pre-selection steps according to MPEG-D Part-4 DRC
+ * Amd1 */
+
+/* #1: DownmixId of DRC set matches the requested downmixId.
+ #2: Output channel layout of DRC set matches the requested layout.
+ #3: Channel count of DRC set matches the requested channel count. */
+static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement123(
+ int nRequestedDownmixId, DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
+ int* pMatchFound) {
+ int i;
+ *pMatchFound = 0;
+
+ for (i = 0; i < pDrcInstructionUniDrc->downmixIdCount; i++) {
+ if ((pDrcInstructionUniDrc->downmixId[i] == nRequestedDownmixId) ||
+ (pDrcInstructionUniDrc->downmixId[i] == DOWNMIX_ID_ANY_DOWNMIX) ||
+ ((pDrcInstructionUniDrc->downmixId[i] == DOWNMIX_ID_BASE_LAYOUT) &&
+ (pDrcInstructionUniDrc->drcSetId > 0))) {
+ *pMatchFound = 1;
+ break;
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/* #4: The DRC set is not a "Fade-" or "Ducking-" only DRC set. */
+static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement4(
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction, int nDynamicRangeControlOn,
+ int* pMatchFound) {
+ *pMatchFound = 0;
+
+ if (nDynamicRangeControlOn == 1) {
+ if ((pDrcInstruction->drcSetEffect != EB_FADE) &&
+ (pDrcInstruction->drcSetEffect != EB_DUCK_OTHER) &&
+ (pDrcInstruction->drcSetEffect != EB_DUCK_SELF) &&
+ (pDrcInstruction->drcSetEffect != 0 || pDrcInstruction->drcSetId < 0)) {
+ *pMatchFound = 1;
+ }
+ } else {
+ *pMatchFound = 1;
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/* #5: The number of DRC bands is supported. */
+static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5(
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
+ DRC_COEFFICIENTS_UNI_DRC* pCoef, int* pMatchFound) {
+ int i;
+
+ *pMatchFound = 1;
+
+ if (pCoef == NULL) /* check for parametricDRC */
+ {
+ *pMatchFound = 1;
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ }
+
+ for (i = 0; i < pDrcInstructionUniDrc->nDrcChannelGroups; i++) {
+ int indexDrcCoeff = pDrcInstructionUniDrc->gainSetIndexForChannelGroup[i];
+ int bandCount = 0;
+
+ if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */
+ {
+ *pMatchFound = 1;
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ }
+
+ GAIN_SET* gainSet = &(pCoef->gainSet[indexDrcCoeff]);
+ bandCount = gainSet->bandCount;
+
+ if (bandCount > 4) {
+ *pMatchFound = 0;
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/* #6: Independent use of DRC set is permitted.*/
+static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement6(
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc, int* pMatchFound) {
+ *pMatchFound = 0;
+
+ if (((pDrcInstructionUniDrc->dependsOnDrcSetPresent == 0) &&
+ (pDrcInstructionUniDrc->noIndependentUse == 0)) ||
+ (pDrcInstructionUniDrc->dependsOnDrcSetPresent == 1)) {
+ *pMatchFound = 1;
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/* #7: DRC sets that require EQ are only permitted if EQ is supported. */
+static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement7(
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc, int* pMatchFound) {
+ *pMatchFound = 1;
+
+ if (pDrcInstructionUniDrc->requiresEq) {
+ /* EQ is not supported */
+ *pMatchFound = 0;
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static void _setSelectionDataInfo(
+ DRCDEC_SELECTION_DATA* pData, FIXP_DBL loudness, /* e = 7 */
+ FIXP_DBL loudnessNormalizationGainDb, /* e = 7 */
+ FIXP_DBL loudnessNormalizationGainDbMax, /* e = 7 */
+ FIXP_DBL loudnessDeviationMax, /* e = 7 */
+ FIXP_DBL signalPeakLevel, /* e = 7 */
+ FIXP_DBL outputPeakLevelMax, /* e = 7 */
+ int applyAdjustment) {
+ FIXP_DBL adjustment = 0; /* e = 8 */
+
+ /* use e = 8 for all function parameters to prevent overflow */
+ loudness >>= 1;
+ loudnessNormalizationGainDb >>= 1;
+ loudnessNormalizationGainDbMax >>= 1;
+ loudnessDeviationMax >>= 1;
+ signalPeakLevel >>= 1;
+ outputPeakLevelMax >>= 1;
+
+ if (applyAdjustment) {
+ adjustment =
+ fMax((FIXP_DBL)0, signalPeakLevel + loudnessNormalizationGainDb -
+ outputPeakLevelMax);
+ adjustment = fMin(adjustment, fMax((FIXP_DBL)0, loudnessDeviationMax));
+ }
+
+ pData->loudnessNormalizationGainDbAdjusted = fMin(
+ loudnessNormalizationGainDb - adjustment, loudnessNormalizationGainDbMax);
+ pData->outputLoudness = loudness + pData->loudnessNormalizationGainDbAdjusted;
+ pData->outputPeakLevel =
+ signalPeakLevel + pData->loudnessNormalizationGainDbAdjusted;
+
+ /* shift back to e = 7 using saturation */
+ pData->loudnessNormalizationGainDbAdjusted = SATURATE_LEFT_SHIFT(
+ pData->loudnessNormalizationGainDbAdjusted, 1, DFRACT_BITS);
+ pData->outputLoudness =
+ SATURATE_LEFT_SHIFT(pData->outputLoudness, 1, DFRACT_BITS);
+ pData->outputPeakLevel =
+ SATURATE_LEFT_SHIFT(pData->outputPeakLevel, 1, DFRACT_BITS);
+}
+
+static int _targetLoudnessInRange(
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc, FIXP_DBL targetLoudness) {
+ int retVal = 0;
+
+ FIXP_DBL drcSetTargetLoudnessValueUpper =
+ ((FIXP_DBL)pDrcInstructionUniDrc->drcSetTargetLoudnessValueUpper)
+ << (DFRACT_BITS - 1 - 7);
+ FIXP_DBL drcSetTargetLoudnessValueLower =
+ ((FIXP_DBL)pDrcInstructionUniDrc->drcSetTargetLoudnessValueLower)
+ << (DFRACT_BITS - 1 - 7);
+
+ if (pDrcInstructionUniDrc->drcSetTargetLoudnessPresent &&
+ drcSetTargetLoudnessValueUpper >= targetLoudness &&
+ drcSetTargetLoudnessValueLower < targetLoudness) {
+ retVal = 1;
+ }
+
+ return retVal;
+}
+
+/* #8: The range of the target loudness specified for a DRC set has to include
+ * the requested decoder target loudness. */
+static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
+ SEL_PROC_INPUT* hSelProcInput, int downmixIdIndex,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
+ DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ int explicitPeakInformationPresent;
+ FIXP_DBL signalPeakLevel;
+ int addToCandidate = 0;
+
+ FIXP_DBL loudnessNormalizationGainDb;
+ FIXP_DBL loudness;
+
+ FIXP_DBL loudnessDeviationMax =
+ ((FIXP_DBL)hSelProcInput->loudnessDeviationMax) << (DFRACT_BITS - 1 - 7);
+ ;
+
+ if (hSelProcInput->loudnessNormalizationOn) {
+ retVal = _getLoudness(hLoudnessInfoSet, hSelProcInput->albumMode,
+ hSelProcInput->loudnessMeasurementMethod,
+ hSelProcInput->loudnessMeasurementSystem,
+ hSelProcInput->targetLoudness,
+ pDrcInstructionUniDrc->drcSetId,
+ hSelProcInput->downmixIdRequested[downmixIdIndex],
+ &loudnessNormalizationGainDb, &loudness);
+ if (retVal) return (retVal);
+ } else {
+ loudnessNormalizationGainDb = (FIXP_DBL)0;
+ loudness = UNDEFINED_LOUDNESS_VALUE;
+ }
+
+ retVal = _getSignalPeakLevel(
+ hSelProcInput, hUniDrcConfig, hLoudnessInfoSet, pDrcInstructionUniDrc,
+ hSelProcInput->downmixIdRequested[downmixIdIndex],
+ &explicitPeakInformationPresent, &signalPeakLevel, codecMode
+
+ );
+ if (retVal) return (retVal);
+
+ if (hSelProcInput->dynamicRangeControlOn) {
+ if (explicitPeakInformationPresent == 0) {
+ if (pDrcInstructionUniDrc->drcSetTargetLoudnessPresent &&
+ ((hSelProcInput->loudnessNormalizationOn &&
+ _targetLoudnessInRange(pDrcInstructionUniDrc,
+ hSelProcInput->targetLoudness)) ||
+ !hSelProcInput->loudnessNormalizationOn)) {
+ DRCDEC_SELECTION_DATA* pData =
+ _drcdec_selection_addNew(pCandidatesSelected);
+ if (pData == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ _setSelectionDataInfo(pData, loudness, loudnessNormalizationGainDb,
+ hSelProcInput->loudnessNormalizationGainDbMax,
+ loudnessDeviationMax, signalPeakLevel,
+ hSelProcInput->outputPeakLevelMax, 0);
+ pData->downmixIdRequestIndex = downmixIdIndex;
+ pData->pInst = pDrcInstructionUniDrc;
+ pData->selectionFlag =
+ 1; /* signal pre-selection step dealing with drcSetTargetLoudness */
+
+ if (hSelProcInput->loudnessNormalizationOn) {
+ pData->outputPeakLevel =
+ hSelProcInput->targetLoudness -
+ (((FIXP_DBL)pData->pInst->drcSetTargetLoudnessValueUpper)
+ << (DFRACT_BITS - 1 - 7));
+ } else {
+ pData->outputPeakLevel = (FIXP_DBL)0;
+ }
+ } else {
+ if ((!hSelProcInput->loudnessNormalizationOn) ||
+ (!pDrcInstructionUniDrc->drcSetTargetLoudnessPresent) ||
+ (hSelProcInput->loudnessNormalizationOn &&
+ _targetLoudnessInRange(pDrcInstructionUniDrc,
+ hSelProcInput->targetLoudness))) {
+ addToCandidate = 1;
+ }
+ }
+ } else {
+ addToCandidate = 1;
+ }
+
+ if (addToCandidate) {
+ DRCDEC_SELECTION_DATA* pData =
+ _drcdec_selection_addNew(pCandidatesPotential);
+ if (pData == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ _setSelectionDataInfo(pData, loudness, loudnessNormalizationGainDb,
+ hSelProcInput->loudnessNormalizationGainDbMax,
+ loudnessDeviationMax, signalPeakLevel,
+ hSelProcInput->outputPeakLevelMax, 0);
+ pData->downmixIdRequestIndex = downmixIdIndex;
+ pData->pInst = pDrcInstructionUniDrc;
+ pData->selectionFlag = 0;
+ }
+ } else {
+ if (pDrcInstructionUniDrc->drcSetId < 0) {
+ DRCDEC_SELECTION_DATA* pData =
+ _drcdec_selection_addNew(pCandidatesSelected);
+ if (pData == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ _setSelectionDataInfo(pData, loudness, loudnessNormalizationGainDb,
+ hSelProcInput->loudnessNormalizationGainDbMax,
+ loudnessDeviationMax, signalPeakLevel,
+ hSelProcInput->outputPeakLevelMax, 1);
+
+ pData->downmixIdRequestIndex = downmixIdIndex;
+ pData->pInst = pDrcInstructionUniDrc;
+ pData->selectionFlag = 0;
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/* #9: Clipping is minimized. */
+static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement9(
+ SEL_PROC_INPUT* hSelProcInput, DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected) {
+ int i;
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ DRCDEC_SELECTION_DATA* pCandidate =
+ _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ if (pCandidate->outputPeakLevel <= hSelProcInput->outputPeakLevelMax) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelectionSingleInstruction(
+ SEL_PROC_INPUT* hSelProcInput, int downmixIdIndex,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc,
+ DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ int matchFound = 0;
+ DRC_COEFFICIENTS_UNI_DRC* pCoef =
+ selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
+
+ retVal = _preSelectionRequirement123(
+ hSelProcInput->downmixIdRequested[downmixIdIndex], pDrcInstructionUniDrc,
+ &matchFound);
+
+ if (!retVal && matchFound)
+ retVal = _preSelectionRequirement4(pDrcInstructionUniDrc,
+ hSelProcInput->dynamicRangeControlOn,
+ &matchFound);
+
+ if (!retVal && matchFound)
+ retVal =
+ _preSelectionRequirement5(pDrcInstructionUniDrc, pCoef, &matchFound);
+
+ if (!retVal && matchFound)
+ retVal = _preSelectionRequirement6(pDrcInstructionUniDrc, &matchFound);
+
+ if (!retVal && matchFound)
+ retVal = _preSelectionRequirement7(pDrcInstructionUniDrc, &matchFound);
+
+ if (!retVal && matchFound)
+ retVal = _preSelectionRequirement8(
+ hSelProcInput, downmixIdIndex, hUniDrcConfig, hLoudnessInfoSet,
+ pDrcInstructionUniDrc, pCandidatesPotential, pCandidatesSelected,
+ codecMode);
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetSelectionAddCandidates(
+ SEL_PROC_INPUT* hSelProcInput, DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ int nHitCount = 0;
+ int i;
+
+ DRCDEC_SELECTION_DATA* pCandidate = NULL;
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc = NULL;
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ pDrcInstructionUniDrc = pCandidate->pInst;
+
+ if (_targetLoudnessInRange(pDrcInstructionUniDrc,
+ hSelProcInput->targetLoudness)) {
+ nHitCount++;
+ }
+ }
+
+ if (nHitCount != 0) {
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ pDrcInstructionUniDrc = pCandidate->pInst;
+
+ if (_targetLoudnessInRange(pDrcInstructionUniDrc,
+ hSelProcInput->targetLoudness)) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+ } else {
+ FIXP_DBL lowestPeakLevel = MAXVAL_DBL; /* e = 7 */
+ FIXP_DBL peakLevel = 0; /* e = 7 */
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ peakLevel = pCandidate->outputPeakLevel;
+
+ if (peakLevel < lowestPeakLevel) {
+ lowestPeakLevel = peakLevel;
+ }
+ }
+
+ /* add all with lowest peak level or max 1dB above */
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ FIXP_DBL loudnessDeviationMax =
+ ((FIXP_DBL)hSelProcInput->loudnessDeviationMax)
+ << (DFRACT_BITS - 1 - 7); /* e = 7 */
+
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ peakLevel = pCandidate->outputPeakLevel;
+
+ if (peakLevel == lowestPeakLevel ||
+ peakLevel <=
+ lowestPeakLevel + FL2FXCONST_DBL(1.0f / (float)(1 << 7))) {
+ FIXP_DBL adjustment =
+ fMax((FIXP_DBL)0, peakLevel - hSelProcInput->outputPeakLevelMax);
+ adjustment = fMin(adjustment, fMax((FIXP_DBL)0, loudnessDeviationMax));
+
+ pCandidate->loudnessNormalizationGainDbAdjusted -= adjustment;
+ pCandidate->outputPeakLevel -= adjustment;
+ pCandidate->outputLoudness -= adjustment;
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+ }
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _dependentDrcInstruction(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRC_INSTRUCTIONS_UNI_DRC* pInst,
+ DRC_INSTRUCTIONS_UNI_DRC** ppDrcInstructionsDependent) {
+ int i;
+ DRC_INSTRUCTIONS_UNI_DRC* pDependentDrc = NULL;
+
+ for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
+ pDependentDrc =
+ (DRC_INSTRUCTIONS_UNI_DRC*)&(hUniDrcConfig->drcInstructionsUniDrc[i]);
+
+ if (pDependentDrc->drcSetId == pInst->dependsOnDrcSet) {
+ break;
+ }
+ }
+
+ if (i == hUniDrcConfig->drcInstructionsUniDrcCount) {
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ if (pDependentDrc->dependsOnDrcSetPresent == 1) {
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ *ppDrcInstructionsDependent = pDependentDrc;
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _selectDrcSetEffectNone(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected) {
+ int i;
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ DRCDEC_SELECTION_DATA* pCandidate =
+ _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ if ((pCandidate->pInst->drcSetEffect & 0xff) == 0) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _selectSingleEffectType(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRC_EFFECT_TYPE_REQUEST effectType,
+ DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected) {
+ int i;
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ DRC_INSTRUCTIONS_UNI_DRC* pInst;
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionsDependent;
+
+ if (effectType == DETR_NONE) {
+ retVal = _selectDrcSetEffectNone(hUniDrcConfig, pCandidatesPotential,
+ pCandidatesSelected);
+ if (retVal) return (retVal);
+ } else {
+ int effectBitPosition = 1 << (effectType - 1);
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ DRCDEC_SELECTION_DATA* pCandidate =
+ _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ pInst = pCandidate->pInst;
+
+ if (!pInst->dependsOnDrcSetPresent) {
+ if ((pInst->drcSetEffect & effectBitPosition)) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ } else {
+ retVal = _dependentDrcInstruction(hUniDrcConfig, pInst,
+ &pDrcInstructionsDependent);
+ if (retVal) return (retVal);
+
+ if (((pInst->drcSetEffect & effectBitPosition)) ||
+ ((pDrcInstructionsDependent->drcSetEffect & effectBitPosition))) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+ }
+ }
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _selectEffectTypeFeature(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, DRC_FEATURE_REQUEST drcFeatureRequest,
+ DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ int i;
+ int desiredEffectTypeFound = 0;
+
+ for (i = 0; i < drcFeatureRequest.drcEffectType.numRequestsDesired; i++) {
+ retVal = _selectSingleEffectType(
+ hUniDrcConfig, drcFeatureRequest.drcEffectType.request[i],
+ *ppCandidatesPotential, *ppCandidatesSelected);
+ if (retVal) return (retVal);
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected)) {
+ desiredEffectTypeFound = 1;
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ }
+ }
+
+ if (!desiredEffectTypeFound) {
+ for (i = drcFeatureRequest.drcEffectType.numRequestsDesired;
+ i < drcFeatureRequest.drcEffectType.numRequests; i++) {
+ retVal = _selectSingleEffectType(
+ hUniDrcConfig, drcFeatureRequest.drcEffectType.request[i],
+ *ppCandidatesPotential, *ppCandidatesSelected);
+ if (retVal) return (retVal);
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected)) {
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ break;
+ }
+ }
+ }
+
+ _swapSelection(ppCandidatesPotential, ppCandidatesSelected);
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _selectDynamicRange(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ DRC_FEATURE_REQUEST drcFeatureRequest, UCHAR* pDownmixIdRequested,
+ int albumMode, DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* ppCandidatesSelected) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ int i;
+ int peakToAveragePresent;
+ FIXP_DBL peakToAverage;
+
+ FIXP_DBL minVal = MAXVAL_DBL;
+ FIXP_DBL val = 0;
+
+ int numSelectedCandidates = _drcdec_selection_getNumber(ppCandidatesSelected);
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ DRCDEC_SELECTION_DATA* pCandidate =
+ _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ retVal = _dynamicRangeMeasurement(
+ hLoudnessInfoSet, pCandidate->pInst,
+ pDownmixIdRequested[pCandidate->downmixIdRequestIndex],
+ drcFeatureRequest.dynamicRange.measurementRequestType, albumMode,
+ &peakToAveragePresent, &peakToAverage);
+ if (retVal) return (retVal);
+
+ if (peakToAveragePresent) {
+ if (!drcFeatureRequest.dynamicRange.requestedIsRange) {
+ val = fAbs(drcFeatureRequest.dynamicRange.requestValue - peakToAverage);
+
+ if (minVal > val) {
+ minVal = val;
+
+ _drcdec_selection_setNumber(ppCandidatesSelected,
+ numSelectedCandidates);
+ }
+ if (_drcdec_selection_add(ppCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ } else {
+ if ((peakToAverage >= drcFeatureRequest.dynamicRange.requestValueMin) &&
+ (peakToAverage <= drcFeatureRequest.dynamicRange.requestValueMax)) {
+ if (_drcdec_selection_add(ppCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+ }
+ }
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _selectSingleDrcCharacteristic(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, int requestedDrcCharacteristic,
+ DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected) {
+ int i, j, b;
+ int hit = 0;
+
+ DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;
+ DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
+ GAIN_SET* pGainSet = NULL;
+
+ if (requestedDrcCharacteristic < 1) {
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ pCoef = selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
+
+ if (pCoef == NULL) /* check for parametricDRC */
+ {
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ }
+
+ for (i = 0; i < _drcdec_selection_getNumber(*ppCandidatesPotential); i++) {
+ DRCDEC_SELECTION_DATA* pCandidate =
+ _drcdec_selection_getAt(*ppCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ pInst = pCandidate->pInst;
+
+ hit = 0;
+
+ for (j = 0; j < pInst->nDrcChannelGroups; j++) {
+ int bandCount = 0;
+ int indexDrcCoeff = pInst->gainSetIndexForChannelGroup[j];
+
+ if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */
+ {
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ }
+
+ pGainSet = &(pCoef->gainSet[indexDrcCoeff]);
+ bandCount = pGainSet->bandCount;
+
+ for (b = 0; b < bandCount; b++) {
+ if ((pGainSet->drcCharacteristic[b].isCICP) &&
+ (pGainSet->drcCharacteristic[b].cicpIndex ==
+ requestedDrcCharacteristic)) {
+ hit = 1;
+ break;
+ }
+ }
+
+ if (hit) break;
+ }
+
+ if (hit) {
+ if (_drcdec_selection_add(*ppCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected)) {
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _selectDrcCharacteristic(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, int drcCharacteristicRequested,
+ DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+
+ const int secondTry[12] = {0, 2, 3, 4, 5, 6, 5, 9, 10, 7, 8, 10};
+
+ retVal = _selectSingleDrcCharacteristic(
+ hUniDrcConfig, drcCharacteristicRequested, ppCandidatesPotential,
+ ppCandidatesSelected);
+ if (retVal) return (retVal);
+
+ if ((drcCharacteristicRequested <= 11) &&
+ (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0)) {
+ retVal = _selectSingleDrcCharacteristic(
+ hUniDrcConfig, secondTry[drcCharacteristicRequested],
+ ppCandidatesPotential, ppCandidatesSelected);
+ if (retVal) return (retVal);
+ }
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
+ if ((drcCharacteristicRequested >= 2) &&
+ (drcCharacteristicRequested <= 5)) {
+ retVal = _selectSingleDrcCharacteristic(
+ hUniDrcConfig, drcCharacteristicRequested - 1, ppCandidatesPotential,
+ ppCandidatesSelected);
+ if (retVal) return (retVal);
+ } else if (drcCharacteristicRequested == 11) {
+ retVal = _selectSingleDrcCharacteristic(
+ hUniDrcConfig, 9, ppCandidatesPotential, ppCandidatesSelected);
+ if (retVal) return (retVal);
+ }
+ }
+
+ _swapSelection(ppCandidatesPotential, ppCandidatesSelected);
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_peakValue0(
+ DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected) {
+ int i;
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ DRCDEC_SELECTION_DATA* pCandidate =
+ _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ if (pCandidate->outputPeakLevel <= FIXP_DBL(0)) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_downmixId(
+ HANDLE_SEL_PROC_INPUT hSelProcInput,
+ DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected) {
+ int i, j;
+ DRCDEC_SELECTION_DATA* pCandidate = NULL;
+ DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;
+
+ for (i = 0; i < _drcdec_selection_getNumber(*ppCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(*ppCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ pInst = pCandidate->pInst;
+
+ for (j = 0; j < pInst->downmixIdCount; j++) {
+ if (DOWNMIX_ID_BASE_LAYOUT != pInst->downmixId[j] &&
+ DOWNMIX_ID_ANY_DOWNMIX != pInst->downmixId[j] &&
+ hSelProcInput
+ ->downmixIdRequested[pCandidate->downmixIdRequestIndex] ==
+ pInst->downmixId[j]) {
+ if (_drcdec_selection_add(*ppCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+ }
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
+ _swapSelection(ppCandidatesPotential, ppCandidatesSelected);
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static int _crossSum(int value) {
+ int sum = 0;
+
+ while (value != 0) {
+ if ((value & 1) == 1) {
+ sum++;
+ }
+
+ value >>= 1;
+ }
+
+ return sum;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_effectTypes(
+ DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected) {
+ int i;
+ int minNumEffects = 1000;
+ int numEffects = 0;
+ int effects = 0;
+ DRCDEC_SELECTION_DATA* pCandidate = NULL;
+ DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ pInst = pCandidate->pInst;
+
+ effects = pInst->drcSetEffect;
+ effects &= 0xffff ^ (EB_GENERAL_COMPR);
+ numEffects = _crossSum(effects);
+
+ if (numEffects < minNumEffects) {
+ minNumEffects = numEffects;
+ }
+ }
+
+ /* add all with minimum number of effects */
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ pInst = pCandidate->pInst;
+
+ effects = pInst->drcSetEffect;
+ effects &= 0xffff ^ (EB_GENERAL_COMPR);
+ numEffects = _crossSum(effects);
+
+ if (numEffects == minNumEffects) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _selectSmallestTargetLoudnessValueUpper(
+ DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected) {
+ int i;
+ SCHAR minVal = 0x7F;
+ SCHAR val = 0;
+ DRCDEC_SELECTION_DATA* pCandidate = NULL;
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ val = pCandidate->pInst->drcSetTargetLoudnessValueUpper;
+
+ if (val < minVal) {
+ minVal = val;
+ }
+ }
+
+ /* add all with same smallest drcSetTargetLoudnessValueUpper */
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ val = pCandidate->pInst->drcSetTargetLoudnessValueUpper;
+
+ if (val == minVal) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_targetLoudness(
+ FIXP_DBL targetLoudness, DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ int i;
+ DRCDEC_SELECTION_DATA* pCandidate = NULL;
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ if (pCandidate->selectionFlag == 0) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+
+ if (_drcdec_selection_getNumber(pCandidatesSelected) == 0) {
+ retVal = _selectSmallestTargetLoudnessValueUpper(pCandidatesPotential,
+ pCandidatesSelected);
+ if (retVal) return (retVal);
+ }
+
+ if (_drcdec_selection_getNumber(pCandidatesSelected) > 1) {
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc = NULL;
+
+ _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ pDrcInstructionUniDrc = pCandidate->pInst;
+
+ if (_targetLoudnessInRange(pDrcInstructionUniDrc, targetLoudness)) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+
+ if (_drcdec_selection_getNumber(pCandidatesSelected) > 1) {
+ _swapSelectionAndClear(&pCandidatesPotential, &pCandidatesSelected);
+
+ retVal = _selectSmallestTargetLoudnessValueUpper(pCandidatesPotential,
+ pCandidatesSelected);
+ if (retVal) return (retVal);
+ }
+ }
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_peakValueLargest(
+ DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected) {
+ int i;
+ FIXP_DBL largestPeakLevel = MINVAL_DBL;
+ FIXP_DBL peakLevel = 0;
+ DRCDEC_SELECTION_DATA* pCandidate = NULL;
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ peakLevel = pCandidate->outputPeakLevel;
+
+ if (peakLevel > largestPeakLevel) {
+ largestPeakLevel = peakLevel;
+ }
+ }
+
+ /* add all with same largest peak level */
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ peakLevel = pCandidate->outputPeakLevel;
+
+ if (peakLevel == largestPeakLevel) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection_drcSetId(
+ DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected) {
+ int i;
+ int largestId = -1000;
+ int id = 0;
+ DRCDEC_SELECTION_DATA* pCandidate = NULL;
+ DRCDEC_SELECTION_DATA* pCandidateSelected = NULL;
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ pCandidate = _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ id = pCandidate->pInst->drcSetId;
+
+ if (id > largestId) {
+ largestId = id;
+ pCandidateSelected = pCandidate;
+ }
+ }
+
+ if (pCandidateSelected != NULL) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidateSelected) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ } else {
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetFinalSelection(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+
+ if (_drcdec_selection_getNumber(*ppCandidatesPotential) == 0) {
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ } else if (_drcdec_selection_getNumber(*ppCandidatesPotential) == 1) {
+ _swapSelection(ppCandidatesPotential, ppCandidatesSelected);
+ /* finished */
+ } else /* > 1 */
+ {
+ retVal = _drcSetFinalSelection_peakValue0(*ppCandidatesPotential,
+ *ppCandidatesSelected);
+ if (retVal) return (retVal);
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ retVal = _drcSetFinalSelection_downmixId(
+ hSelProcInput, ppCandidatesPotential, ppCandidatesSelected);
+ if (retVal) return (retVal);
+ }
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ retVal = _drcSetFinalSelection_effectTypes(*ppCandidatesPotential,
+ *ppCandidatesSelected);
+ if (retVal) return (retVal);
+ }
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ retVal = _drcSetFinalSelection_targetLoudness(
+ hSelProcInput->targetLoudness, *ppCandidatesPotential,
+ *ppCandidatesSelected);
+ if (retVal) return (retVal);
+ }
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ retVal = _drcSetFinalSelection_peakValueLargest(*ppCandidatesPotential,
+ *ppCandidatesSelected);
+ if (retVal) return (retVal);
+ }
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 1) {
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ retVal = _drcSetFinalSelection_drcSetId(*ppCandidatesPotential,
+ *ppCandidatesSelected);
+ if (retVal) return (retVal);
+ }
+ }
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _generateVirtualDrcSets(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ SEL_PROC_CODEC_MODE codecMode) {
+ int i;
+ int nMixes = hUniDrcConfig->downmixInstructionsCount + 1;
+ int index = hUniDrcConfig->drcInstructionsUniDrcCount;
+ int indexVirtual = -1;
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction =
+ &(hUniDrcConfig->drcInstructionsUniDrc[index]);
+
+ if (codecMode == SEL_PROC_MPEG_H_3DA) {
+ nMixes = 1;
+ }
+
+ if ((index + nMixes) > (12 + 1 + 6)) {
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ FDKmemset(pDrcInstruction, 0, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
+
+ pDrcInstruction->drcSetId = indexVirtual;
+ index++;
+ indexVirtual--;
+ pDrcInstruction->downmixIdCount = 1;
+
+ if ((codecMode == SEL_PROC_MPEG_H_3DA) &&
+ (hSelProcInput->numDownmixIdRequests)) {
+ pDrcInstruction->downmixId[0] = hSelProcInput->downmixIdRequested[0];
+ } else {
+ pDrcInstruction->downmixId[0] = DOWNMIX_ID_BASE_LAYOUT;
+ }
+
+ for (i = 1; i < nMixes; i++) {
+ pDrcInstruction = &(hUniDrcConfig->drcInstructionsUniDrc[index]);
+ FDKmemset(pDrcInstruction, 0, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
+ pDrcInstruction->drcSetId = indexVirtual;
+ pDrcInstruction->downmixId[0] =
+ hUniDrcConfig->downmixInstructions[i - 1].downmixId;
+ pDrcInstruction->downmixIdCount = 1;
+ index++;
+ indexVirtual--;
+ }
+
+ hUniDrcConfig->drcInstructionsCountInclVirtual =
+ hUniDrcConfig->drcInstructionsUniDrcCount + nMixes;
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ DRCDEC_SELECTION_DATA* pSelectionData, SEL_PROC_CODEC_MODE codecMode) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+
+ int i, j;
+ int hasDependend = 0;
+ int hasFading = 0;
+ int hasDucking = 0;
+ int selectedDrcSetIds;
+ int selectedDownmixIds;
+ FIXP_DBL mixingLevel = 0;
+ int albumMode = hSelProcInput->albumMode;
+ UCHAR* pDownmixIdRequested = hSelProcInput->downmixIdRequested;
+ FIXP_SGL boost = hSelProcInput->boost;
+ FIXP_SGL compress = hSelProcInput->compress;
+
+ hSelProcOutput->numSelectedDrcSets = 1;
+ hSelProcOutput->selectedDrcSetIds[0] = pSelectionData->pInst->drcSetId;
+ hSelProcOutput->selectedDownmixIds[0] =
+ pSelectionData->pInst->drcApplyToDownmix == 1
+ ? pSelectionData->pInst->downmixId[0]
+ : 0;
+ hSelProcOutput->loudnessNormalizationGainDb =
+ pSelectionData->loudnessNormalizationGainDbAdjusted +
+ hSelProcInput->loudnessNormalizationGainModificationDb;
+ hSelProcOutput->outputPeakLevelDb = pSelectionData->outputPeakLevel;
+
+ hSelProcOutput->boost = boost;
+ hSelProcOutput->compress = compress;
+ hSelProcOutput->baseChannelCount =
+ hUniDrcConfig->channelLayout.baseChannelCount;
+ hSelProcOutput->targetChannelCount =
+ hUniDrcConfig->channelLayout.baseChannelCount;
+ hSelProcOutput->activeDownmixId =
+ pDownmixIdRequested[pSelectionData->downmixIdRequestIndex];
+
+ _getMixingLevel(hLoudnessInfoSet, *pDownmixIdRequested,
+ hSelProcOutput->selectedDrcSetIds[0], albumMode,
+ &mixingLevel);
+ hSelProcOutput->mixingLevel = mixingLevel;
+
+ /*dependent*/
+ if (pSelectionData->pInst->dependsOnDrcSetPresent) {
+ int dependsOnDrcSetID = pSelectionData->pInst->dependsOnDrcSet;
+
+ for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) {
+ if (hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId ==
+ dependsOnDrcSetID) {
+ hSelProcOutput->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
+ hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
+ hSelProcOutput->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] =
+ hUniDrcConfig->drcInstructionsUniDrc[i].drcApplyToDownmix == 1
+ ? hUniDrcConfig->drcInstructionsUniDrc[i].downmixId[0]
+ : 0;
+ hSelProcOutput->numSelectedDrcSets++;
+ hasDependend = 1;
+ break;
+ }
+ }
+ }
+
+ /* fading */
+ if (hSelProcInput->albumMode == 0) {
+ for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
+ DRC_INSTRUCTIONS_UNI_DRC* pInst =
+ &(hUniDrcConfig->drcInstructionsUniDrc[i]);
+
+ if (pInst->drcSetEffect & EB_FADE) {
+ if (pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) {
+ hSelProcOutput->numSelectedDrcSets = hasDependend + 1;
+ hSelProcOutput
+ ->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
+ hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
+ hSelProcOutput
+ ->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] =
+ hUniDrcConfig->drcInstructionsUniDrc[i].drcApplyToDownmix == 1
+ ? hUniDrcConfig->drcInstructionsUniDrc[i].downmixId[0]
+ : 0;
+ hSelProcOutput->numSelectedDrcSets++;
+ hasFading = 1;
+
+ } else {
+ retVal = DRCDEC_SELECTION_PROCESS_NOT_OK;
+ if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+ }
+ }
+
+ /* ducking */
+ for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
+ DRC_INSTRUCTIONS_UNI_DRC* pInst =
+ &(hUniDrcConfig->drcInstructionsUniDrc[i]);
+
+ if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
+ for (j = 0; j < pInst->downmixIdCount; j++) {
+ if (pInst->downmixId[j] == hSelProcOutput->activeDownmixId) {
+ hSelProcOutput->numSelectedDrcSets =
+ hasDependend + 1; /* ducking overrides fading */
+
+ hSelProcOutput
+ ->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
+ hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
+ /* force ducking DRC set to be processed on base layout */
+ hSelProcOutput
+ ->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] = 0;
+ hSelProcOutput->numSelectedDrcSets++;
+ hasDucking = 1;
+ }
+ }
+ }
+ }
+
+ /* repeat for DOWNMIX_ID_BASE_LAYOUT if no ducking found*/
+
+ if (!hasDucking) {
+ for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
+ DRC_INSTRUCTIONS_UNI_DRC* pInst =
+ &(hUniDrcConfig->drcInstructionsUniDrc[i]);
+
+ if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
+ for (j = 0; j < pInst->downmixIdCount; j++) {
+ if (pInst->downmixId[j] == DOWNMIX_ID_BASE_LAYOUT) {
+ hSelProcOutput->numSelectedDrcSets = hasDependend + hasFading + 1;
+ hSelProcOutput
+ ->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] =
+ hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId;
+ /* force ducking DRC set to be processed on base layout */
+ hSelProcOutput
+ ->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] = 0;
+ hSelProcOutput->numSelectedDrcSets++;
+ }
+ }
+ }
+ }
+ }
+
+ if (hSelProcOutput->numSelectedDrcSets > 3) {
+ /* maximum permitted number of applied DRC sets is 3, see section 6.3.5 of
+ * ISO/IEC 23003-4 */
+ hSelProcOutput->numSelectedDrcSets = 0;
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ /* sorting: Ducking/Fading -> Dependent -> Selected */
+ if (hSelProcOutput->numSelectedDrcSets == 3) {
+ selectedDrcSetIds = hSelProcOutput->selectedDrcSetIds[0];
+ selectedDownmixIds = hSelProcOutput->selectedDownmixIds[0];
+ hSelProcOutput->selectedDrcSetIds[0] = hSelProcOutput->selectedDrcSetIds[2];
+ hSelProcOutput->selectedDownmixIds[0] =
+ hSelProcOutput->selectedDownmixIds[2];
+ hSelProcOutput->selectedDrcSetIds[2] = selectedDrcSetIds;
+ hSelProcOutput->selectedDownmixIds[2] = selectedDownmixIds;
+ } else if (hSelProcOutput->numSelectedDrcSets == 2) {
+ selectedDrcSetIds = hSelProcOutput->selectedDrcSetIds[0];
+ selectedDownmixIds = hSelProcOutput->selectedDownmixIds[0];
+ hSelProcOutput->selectedDrcSetIds[0] = hSelProcOutput->selectedDrcSetIds[1];
+ hSelProcOutput->selectedDownmixIds[0] =
+ hSelProcOutput->selectedDownmixIds[1];
+ hSelProcOutput->selectedDrcSetIds[1] = selectedDrcSetIds;
+ hSelProcOutput->selectedDownmixIds[1] = selectedDownmixIds;
+ }
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _selectDownmixMatrix(
+ HANDLE_SEL_PROC_OUTPUT hSelProcOutput,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
+ int i;
+ hSelProcOutput->baseChannelCount =
+ hUniDrcConfig->channelLayout.baseChannelCount;
+ hSelProcOutput->targetChannelCount =
+ hUniDrcConfig->channelLayout.baseChannelCount;
+ hSelProcOutput->targetLayout = -1;
+ hSelProcOutput->downmixMatrixPresent = 0;
+
+ if (hSelProcOutput->activeDownmixId != 0) {
+ for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
+ DOWNMIX_INSTRUCTIONS* pDown = &(hUniDrcConfig->downmixInstructions[i]);
+
+ if (hSelProcOutput->activeDownmixId == pDown->downmixId) {
+ hSelProcOutput->targetChannelCount = pDown->targetChannelCount;
+ hSelProcOutput->targetLayout = pDown->targetLayout;
+
+ if (pDown->downmixCoefficientsPresent) {
+ int j, k;
+ FIXP_DBL downmixOffset = getDownmixOffset(
+ pDown, hSelProcOutput->baseChannelCount); /* e = 1 */
+
+ for (j = 0; j < hSelProcOutput->baseChannelCount; j++) {
+ for (k = 0; k < hSelProcOutput->targetChannelCount; k++) {
+ hSelProcOutput->downmixMatrix[j][k] =
+ fMultDiv2(
+ downmixOffset,
+ pDown->downmixCoefficient[j + k * hSelProcOutput
+ ->baseChannelCount])
+ << 2;
+ }
+ }
+
+ hSelProcOutput->downmixMatrixPresent = 1;
+ }
+ break;
+ }
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelection(
+ SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected, SEL_PROC_CODEC_MODE codecMode) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ int i, j;
+
+ for (i = 0; i < hSelProcInput->numDownmixIdRequests; i++) {
+ for (j = 0; j < hUniDrcConfig->drcInstructionsCountInclVirtual; j++) {
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction =
+ &(hUniDrcConfig->drcInstructionsUniDrc[j]);
+ retVal = _drcSetPreSelectionSingleInstruction(
+ hSelProcInput, i, hUniDrcConfig, hLoudnessInfoSet, pDrcInstruction,
+ *ppCandidatesPotential, *ppCandidatesSelected, codecMode);
+ if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+
+ retVal = _preSelectionRequirement9(hSelProcInput, *ppCandidatesPotential,
+ *ppCandidatesSelected);
+ if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
+ retVal = _drcSetSelectionAddCandidates(
+ hSelProcInput, *ppCandidatesPotential, *ppCandidatesSelected);
+ if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _drcSetRequestSelection(
+ SEL_PROC_INPUT* hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal;
+ int i;
+
+ if (_drcdec_selection_getNumber(*ppCandidatesPotential) == 0) {
+ retVal = DRCDEC_SELECTION_PROCESS_NOT_OK;
+ if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ if (hSelProcInput->dynamicRangeControlOn) {
+ if (hSelProcInput->numDrcFeatureRequests == 0) {
+ retVal = _selectDrcSetEffectNone(hUniDrcConfig, *ppCandidatesPotential,
+ *ppCandidatesSelected);
+ if (retVal) return (retVal);
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) == 0) {
+ DRC_FEATURE_REQUEST fallbackRequest;
+ fallbackRequest.drcEffectType.numRequests = 5;
+ fallbackRequest.drcEffectType.numRequestsDesired = 5;
+ fallbackRequest.drcEffectType.request[0] = DETR_GENERAL_COMPR;
+ fallbackRequest.drcEffectType.request[1] = DETR_NIGHT;
+ fallbackRequest.drcEffectType.request[2] = DETR_NOISY;
+ fallbackRequest.drcEffectType.request[3] = DETR_LIMITED;
+ fallbackRequest.drcEffectType.request[4] = DETR_LOWLEVEL;
+
+ retVal = _selectEffectTypeFeature(hUniDrcConfig, fallbackRequest,
+ ppCandidatesPotential,
+ ppCandidatesSelected);
+ if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ } else {
+ for (i = 0; i < hSelProcInput->numDrcFeatureRequests; i++) {
+ if (hSelProcInput->drcFeatureRequestType[i] == DFRT_EFFECT_TYPE) {
+ retVal = _selectEffectTypeFeature(
+ hUniDrcConfig, hSelProcInput->drcFeatureRequest[i],
+ ppCandidatesPotential, ppCandidatesSelected);
+
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ else if (hSelProcInput->drcFeatureRequestType[i] ==
+ DFRT_DYNAMIC_RANGE) {
+ retVal = _selectDynamicRange(
+ hUniDrcConfig, hLoudnessInfoSet,
+ hSelProcInput->drcFeatureRequest[i],
+ hSelProcInput->downmixIdRequested, hSelProcInput->albumMode,
+ *ppCandidatesPotential, *ppCandidatesSelected);
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 0) {
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ }
+ if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ } else if (hSelProcInput->drcFeatureRequestType[i] ==
+ DFRT_DRC_CHARACTERISTIC) {
+ retVal = _selectDrcCharacteristic(
+ hUniDrcConfig,
+ hSelProcInput->drcFeatureRequest[i].drcCharacteristic,
+ ppCandidatesPotential, ppCandidatesSelected);
+
+ if (_drcdec_selection_getNumber(*ppCandidatesSelected) > 0) {
+ _swapSelectionAndClear(ppCandidatesPotential, ppCandidatesSelected);
+ }
+ if (retVal) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/*******************************************/
+static DRCDEC_SELECTION_PROCESS_RETURN _dynamicRangeMeasurement(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
+ UCHAR downmixIdRequested,
+ DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
+ int albumMode, int* pPeakToAveragePresent, FIXP_DBL* pPeakToAverage) {
+ int i;
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ int drcSetId = fMax(0, pInst->drcSetId);
+
+ *pPeakToAveragePresent = 0;
+
+ if (albumMode) {
+ for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCount; i++) {
+ LOUDNESS_INFO* pLoudnessInfo = &(hLoudnessInfoSet->loudnessInfoAlbum[i]);
+
+ if (drcSetId == pLoudnessInfo->drcSetId) {
+ if (downmixIdRequested == pLoudnessInfo->downmixId) {
+ retVal = _extractLoudnessPeakToAverageValue(
+ pLoudnessInfo, dynamicRangeMeasurementType, pPeakToAveragePresent,
+ pPeakToAverage);
+ if (retVal) return (retVal);
+ }
+ }
+ }
+ }
+
+ if (*pPeakToAveragePresent == 0) {
+ for (i = 0; i < hLoudnessInfoSet->loudnessInfoCount; i++) {
+ LOUDNESS_INFO* pLoudnessInfo = &(hLoudnessInfoSet->loudnessInfo[i]);
+
+ if (drcSetId == pLoudnessInfo->drcSetId) {
+ if (downmixIdRequested == pLoudnessInfo->downmixId) {
+ retVal = _extractLoudnessPeakToAverageValue(
+ pLoudnessInfo, dynamicRangeMeasurementType, pPeakToAveragePresent,
+ pPeakToAverage);
+ if (retVal) return (retVal);
+ }
+ }
+ }
+ }
+
+ return retVal;
+}
+/*******************************************/
+
+static DRCDEC_SELECTION_DATA* _drcdec_selection_addNew(
+ DRCDEC_SELECTION* pSelection) {
+ if (pSelection->numData < (12 + 1 + 6)) {
+ DRCDEC_SELECTION_DATA* pData = &(pSelection->data[pSelection->numData]);
+ FDKmemset(pData, 0, sizeof(DRCDEC_SELECTION_DATA));
+ pSelection->numData++;
+
+ return pData;
+ } else {
+ return NULL;
+ }
+}
+
+static DRCDEC_SELECTION_DATA* _drcdec_selection_add(
+ DRCDEC_SELECTION* pSelection, DRCDEC_SELECTION_DATA* pDataIn) {
+ if (pSelection->numData < (12 + 1 + 6)) {
+ DRCDEC_SELECTION_DATA* pData = &(pSelection->data[pSelection->numData]);
+ FDKmemcpy(pData, pDataIn, sizeof(DRCDEC_SELECTION_DATA));
+ pSelection->numData++;
+ return pData;
+ } else {
+ return NULL;
+ }
+}
+
+static int _drcdec_selection_clear(DRCDEC_SELECTION* pSelection) {
+ return pSelection->numData = 0;
+}
+
+static int _drcdec_selection_getNumber(DRCDEC_SELECTION* pSelection) {
+ return pSelection->numData;
+}
+
+static int _drcdec_selection_setNumber(DRCDEC_SELECTION* pSelection, int num) {
+ if (num >= 0 && num < pSelection->numData) {
+ return pSelection->numData = num;
+ } else {
+ return pSelection->numData;
+ }
+}
+
+static DRCDEC_SELECTION_DATA* _drcdec_selection_getAt(
+ DRCDEC_SELECTION* pSelection, int at) {
+ if (at >= 0 && at < (12 + 1 + 6)) {
+ return &(pSelection->data[at]);
+ } else {
+ return NULL;
+ }
+}
+
+static int _swapSelectionAndClear(DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected) {
+ DRCDEC_SELECTION* pTmp = *ppCandidatesPotential;
+ *ppCandidatesPotential = *ppCandidatesSelected;
+ *ppCandidatesSelected = pTmp;
+ _drcdec_selection_clear(*ppCandidatesSelected);
+ return 0;
+}
+
+static int _swapSelection(DRCDEC_SELECTION** ppCandidatesPotential,
+ DRCDEC_SELECTION** ppCandidatesSelected) {
+ DRCDEC_SELECTION* pTmp = *ppCandidatesPotential;
+ *ppCandidatesPotential = *ppCandidatesSelected;
+ *ppCandidatesSelected = pTmp;
+ return 0;
+}
+
+/*******************************************/
+
+static LOUDNESS_INFO* _getLoudnessInfoStructure(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId, int downmixId,
+ int albumMode) {
+ int i, j;
+ int count;
+
+ LOUDNESS_INFO* pLoudnessInfo = NULL;
+
+ if (albumMode) {
+ count = hLoudnessInfoSet->loudnessInfoAlbumCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
+ } else {
+ count = hLoudnessInfoSet->loudnessInfoCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
+ }
+
+ for (i = 0; i < count; i++) {
+ if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
+ (pLoudnessInfo[i].downmixId == downmixId)) {
+ for (j = 0; j < pLoudnessInfo[i].measurementCount; j++) {
+ if ((pLoudnessInfo[i].loudnessMeasurement[j].methodDefinition == 1) ||
+ (pLoudnessInfo[i].loudnessMeasurement[j].methodDefinition == 2)) {
+ return &pLoudnessInfo[i];
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static LOUDNESS_INFO* _getApplicableLoudnessInfoStructure(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId,
+ int downmixIdRequested, int albumMode) {
+ LOUDNESS_INFO* pLoudnessInfo = NULL;
+
+ /* default value */
+ pLoudnessInfo = _getLoudnessInfoStructure(hLoudnessInfoSet, drcSetId,
+ downmixIdRequested, albumMode);
+
+ /* fallback values */
+ if (pLoudnessInfo == NULL) {
+ pLoudnessInfo =
+ _getLoudnessInfoStructure(hLoudnessInfoSet, drcSetId, 0x7F, albumMode);
+ }
+
+ if (pLoudnessInfo == NULL) {
+ pLoudnessInfo = _getLoudnessInfoStructure(hLoudnessInfoSet, 0x3F,
+ downmixIdRequested, albumMode);
+ }
+
+ if (pLoudnessInfo == NULL) {
+ pLoudnessInfo = _getLoudnessInfoStructure(hLoudnessInfoSet, 0,
+ downmixIdRequested, albumMode);
+ }
+
+ if (pLoudnessInfo == NULL) {
+ pLoudnessInfo =
+ _getLoudnessInfoStructure(hLoudnessInfoSet, 0x3F, 0x7F, albumMode);
+ }
+
+ if (pLoudnessInfo == NULL) {
+ pLoudnessInfo =
+ _getLoudnessInfoStructure(hLoudnessInfoSet, 0, 0x7F, albumMode);
+ }
+
+ if (pLoudnessInfo == NULL) {
+ pLoudnessInfo =
+ _getLoudnessInfoStructure(hLoudnessInfoSet, drcSetId, 0, albumMode);
+ }
+
+ if (pLoudnessInfo == NULL) {
+ pLoudnessInfo =
+ _getLoudnessInfoStructure(hLoudnessInfoSet, 0x3F, 0, albumMode);
+ }
+
+ if (pLoudnessInfo == NULL) {
+ pLoudnessInfo =
+ _getLoudnessInfoStructure(hLoudnessInfoSet, 0, 0, albumMode);
+ }
+
+ return pLoudnessInfo;
+}
+
+/*******************************************/
+
+typedef struct {
+ FIXP_DBL value;
+ int order;
+} VALUE_ORDER;
+
+void _initValueOrder(VALUE_ORDER* pValue) {
+ pValue->value = (FIXP_DBL)0;
+ pValue->order = -1;
+}
+
+enum {
+ MS_BONUS0 = 0,
+ MS_BONUS1770,
+ MS_BONUSUSER,
+ MS_BONUSEXPERT,
+ MS_RESA,
+ MS_RESB,
+ MS_RESC,
+ MS_RESD,
+ MS_RESE,
+ MS_PROGRAMLOUDNESS,
+ MS_PEAKLOUDNESS
+};
+
+static DRCDEC_SELECTION_PROCESS_RETURN _getMethodValue(
+ VALUE_ORDER* pValueOrder, FIXP_DBL value, int measurementSystem,
+ int measurementSystemRequested) {
+ const int rows = 11;
+ const int columns = 12;
+ const int pOrdering[rows][columns] = {
+ {0, 0, 8, 0, 1, 3, 0, 5, 6, 7, 4, 2}, /* default = bonus1770 */
+ {0, 0, 8, 0, 1, 3, 0, 5, 6, 7, 4, 2}, /* bonus1770 */
+ {0, 0, 1, 0, 8, 5, 0, 2, 3, 4, 6, 7}, /* bonusUser */
+ {0, 0, 3, 0, 1, 8, 0, 4, 5, 6, 7, 2}, /* bonusExpert */
+ {0, 0, 5, 0, 1, 3, 0, 8, 6, 7, 4, 2}, /* ResA */
+ {0, 0, 5, 0, 1, 3, 0, 6, 8, 7, 4, 2}, /* ResB */
+ {0, 0, 5, 0, 1, 3, 0, 6, 7, 8, 4, 2}, /* ResC */
+ {0, 0, 3, 0, 1, 7, 0, 4, 5, 6, 8, 2}, /* ResD */
+ {0, 0, 1, 0, 7, 5, 0, 2, 3, 4, 6, 8}, /* ResE */
+ {0, 0, 1, 0, 0, 0, 0, 2, 3, 4, 0, 0}, /* ProgramLoudness */
+ {0, 7, 0, 0, 0, 0, 6, 5, 4, 3, 2, 1} /* PeakLoudness */
+ };
+
+ if (measurementSystemRequested < 0 || measurementSystemRequested >= rows ||
+ measurementSystem < 0 || measurementSystem >= columns) {
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ if (pOrdering[measurementSystemRequested][measurementSystem] >
+ pValueOrder->order) {
+ pValueOrder->order =
+ pOrdering[measurementSystemRequested][measurementSystem];
+ pValueOrder->value = value;
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/*******************************************/
+
+static DRCDEC_SELECTION_PROCESS_RETURN _getLoudness(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int albumMode,
+ METHOD_DEFINITION_REQUEST measurementMethodRequested,
+ MEASUREMENT_SYSTEM_REQUEST measurementSystemRequested,
+ FIXP_DBL targetLoudness, /* e = 7 */
+ int drcSetId, int downmixIdRequested,
+ FIXP_DBL* pLoudnessNormalizationGain, /* e = 7 */
+ FIXP_DBL* pLoudness) /* e = 7 */
+{
+ int index;
+
+ LOUDNESS_INFO* pLoudnessInfo = NULL;
+ VALUE_ORDER valueOrder;
+
+ /* map MDR_DEFAULT to MDR_PROGRAM_LOUDNESS */
+ METHOD_DEFINITION_REQUEST requestedMethodDefinition =
+ measurementMethodRequested < MDR_ANCHOR_LOUDNESS ? MDR_PROGRAM_LOUDNESS
+ : MDR_ANCHOR_LOUDNESS;
+
+ if (measurementMethodRequested > MDR_ANCHOR_LOUDNESS) {
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+
+ _initValueOrder(&valueOrder);
+
+ *pLoudness = UNDEFINED_LOUDNESS_VALUE;
+ *pLoudnessNormalizationGain = (FIXP_DBL)0;
+
+ if (drcSetId < 0) {
+ drcSetId = 0;
+ }
+
+ pLoudnessInfo = _getApplicableLoudnessInfoStructure(
+ hLoudnessInfoSet, drcSetId, downmixIdRequested, albumMode);
+
+ if (albumMode && (pLoudnessInfo == NULL)) {
+ pLoudnessInfo = _getApplicableLoudnessInfoStructure(
+ hLoudnessInfoSet, drcSetId, downmixIdRequested, 0);
+ }
+
+ if (pLoudnessInfo == NULL) {
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ }
+
+ index = -1;
+
+ do {
+ index = _findMethodDefinition(pLoudnessInfo, requestedMethodDefinition,
+ index + 1);
+
+ if (index >= 0) {
+ _getMethodValue(
+ &valueOrder, pLoudnessInfo->loudnessMeasurement[index].methodValue,
+ pLoudnessInfo->loudnessMeasurement[index].measurementSystem,
+ measurementSystemRequested);
+ }
+ } while (index >= 0);
+
+ /* repeat with other method definition */
+ if (valueOrder.order == -1) {
+ index = -1;
+
+ do {
+ index = _findMethodDefinition(
+ pLoudnessInfo,
+ requestedMethodDefinition == MDR_PROGRAM_LOUDNESS
+ ? MDR_ANCHOR_LOUDNESS
+ : MDR_PROGRAM_LOUDNESS,
+ index + 1);
+
+ if (index >= 0) {
+ _getMethodValue(
+ &valueOrder, pLoudnessInfo->loudnessMeasurement[index].methodValue,
+ pLoudnessInfo->loudnessMeasurement[index].measurementSystem,
+ measurementSystemRequested);
+ }
+ } while (index >= 0);
+ }
+
+ if (valueOrder.order == -1) {
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ } else {
+ *pLoudnessNormalizationGain = targetLoudness - valueOrder.value;
+ *pLoudness = valueOrder.value;
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/*******************************************/
+
+static int _truePeakLevelIsPresent(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ int drcSetId, int downmixId, int albumMode) {
+ int i;
+ int count;
+ LOUDNESS_INFO* pLoudnessInfo = NULL;
+
+ if (albumMode) {
+ count = hLoudnessInfoSet->loudnessInfoAlbumCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
+ } else {
+ count = hLoudnessInfoSet->loudnessInfoCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
+ }
+
+ for (i = 0; i < count; i++) {
+ if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
+ (pLoudnessInfo[i].downmixId == downmixId)) {
+ if (pLoudnessInfo[i].truePeakLevelPresent) return 1;
+ }
+ }
+
+ return 0;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _getTruePeakLevel(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId, int downmixId,
+ int albumMode, FIXP_DBL* pTruePeakLevel) {
+ int i;
+ int count;
+ LOUDNESS_INFO* pLoudnessInfo = NULL;
+
+ if (albumMode) {
+ count = hLoudnessInfoSet->loudnessInfoAlbumCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
+ } else {
+ count = hLoudnessInfoSet->loudnessInfoCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
+ }
+
+ for (i = 0; i < count; i++) {
+ if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
+ (pLoudnessInfo[i].downmixId == downmixId)) {
+ if (pLoudnessInfo[i].truePeakLevelPresent) {
+ *pTruePeakLevel = pLoudnessInfo[i].truePeakLevel;
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ }
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+}
+
+static int _samplePeakLevelIsPresent(HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ int drcSetId, int downmixId,
+ int albumMode) {
+ int i;
+ int count;
+ LOUDNESS_INFO* pLoudnessInfo = NULL;
+
+ if (albumMode) {
+ count = hLoudnessInfoSet->loudnessInfoAlbumCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
+ } else {
+ count = hLoudnessInfoSet->loudnessInfoCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
+ }
+
+ for (i = 0; i < count; i++) {
+ if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
+ (pLoudnessInfo[i].downmixId == downmixId)) {
+ if (pLoudnessInfo[i].samplePeakLevelPresent) return 1;
+ }
+ }
+
+ return 0;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _getSamplePeakLevel(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int drcSetId, int downmixId,
+ int albumMode, FIXP_DBL* pSamplePeakLevel /* e = 7 */
+) {
+ int i;
+ int count;
+ LOUDNESS_INFO* pLoudnessInfo = NULL;
+
+ if (albumMode) {
+ count = hLoudnessInfoSet->loudnessInfoAlbumCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
+ } else {
+ count = hLoudnessInfoSet->loudnessInfoCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
+ }
+
+ for (i = 0; i < count; i++) {
+ if ((pLoudnessInfo[i].drcSetId == drcSetId) &&
+ (pLoudnessInfo[i].downmixId == downmixId)) {
+ if (pLoudnessInfo[i].samplePeakLevelPresent) {
+ *pSamplePeakLevel = pLoudnessInfo[i].samplePeakLevel;
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ }
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+}
+
+static int _limiterPeakTargetIsPresent(
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction, int drcSetId, int downmixId) {
+ int i;
+
+ if (pDrcInstruction->limiterPeakTargetPresent) {
+ if ((pDrcInstruction->downmixId[0] == downmixId) ||
+ (pDrcInstruction->downmixId[0] == 0x7F)) {
+ return 1;
+ }
+
+ for (i = 0; i < pDrcInstruction->downmixIdCount; i++) {
+ if (pDrcInstruction->downmixId[i] == downmixId) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _getLimiterPeakTarget(
+ DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction, int drcSetId, int downmixId,
+ FIXP_DBL* pLimiterPeakTarget) {
+ int i;
+
+ if (pDrcInstruction->limiterPeakTargetPresent) {
+ if ((pDrcInstruction->downmixId[0] == downmixId) ||
+ (pDrcInstruction->downmixId[0] == 0x7F)) {
+ *pLimiterPeakTarget =
+ ((FX_SGL2FX_DBL(pDrcInstruction->limiterPeakTarget) >> 2));
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ }
+
+ for (i = 0; i < pDrcInstruction->downmixIdCount; i++) {
+ if (pDrcInstruction->downmixId[i] == downmixId) {
+ *pLimiterPeakTarget =
+ ((FX_SGL2FX_DBL(pDrcInstruction->limiterPeakTarget) >> 2));
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+ }
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+}
+
+static int _downmixCoefficientsArePresent(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ int downmixId, int* pIndex) {
+ int i;
+ *pIndex = -1;
+
+ for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
+ if (hUniDrcConfig->downmixInstructions[i].downmixId == downmixId) {
+ if (hUniDrcConfig->downmixInstructions[i].downmixCoefficientsPresent) {
+ *pIndex = i;
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _getSignalPeakLevel(
+ HANDLE_SEL_PROC_INPUT hSelProcInput, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, DRC_INSTRUCTIONS_UNI_DRC* pInst,
+ int downmixIdRequested, int* explicitPeakInformationPresent,
+ FIXP_DBL* signalPeakLevelOut, /* e = 7 */
+ SEL_PROC_CODEC_MODE codecMode
+
+) {
+ DRCDEC_SELECTION_PROCESS_RETURN retVal = DRCDEC_SELECTION_PROCESS_NO_ERROR;
+
+ int albumMode = hSelProcInput->albumMode;
+
+ FIXP_DBL signalPeakLevelTmp = (FIXP_DBL)0;
+ FIXP_DBL signalPeakLevel = FIXP_DBL(0);
+
+ int dmxId = downmixIdRequested;
+
+ int drcSetId = pInst->drcSetId;
+
+ if (drcSetId < 0) {
+ drcSetId = 0;
+ }
+
+ *explicitPeakInformationPresent = 1;
+
+ if (_truePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, dmxId, albumMode)) {
+ retVal = _getTruePeakLevel(hLoudnessInfoSet, drcSetId, dmxId, albumMode,
+ &signalPeakLevel);
+ if (retVal) return (retVal);
+ } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, dmxId,
+ albumMode)) {
+ retVal = _getSamplePeakLevel(hLoudnessInfoSet, drcSetId, dmxId, albumMode,
+ &signalPeakLevel);
+ if (retVal) return (retVal);
+ } else if (_truePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, dmxId,
+ albumMode)) {
+ retVal = _getTruePeakLevel(hLoudnessInfoSet, 0x3F, dmxId, albumMode,
+ &signalPeakLevel);
+ if (retVal) return (retVal);
+ } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, dmxId,
+ albumMode)) {
+ retVal = _getSamplePeakLevel(hLoudnessInfoSet, 0x3F, dmxId, albumMode,
+ &signalPeakLevel);
+ if (retVal) return (retVal);
+ } else if (_limiterPeakTargetIsPresent(pInst, drcSetId, dmxId)) {
+ retVal = _getLimiterPeakTarget(pInst, drcSetId, dmxId, &signalPeakLevel);
+ if (retVal) return (retVal);
+ } else if (dmxId != 0) {
+ int downmixInstructionIndex = 0;
+ FIXP_DBL downmixPeakLevelDB = 0;
+
+ *explicitPeakInformationPresent = 0;
+
+ signalPeakLevelTmp = FIXP_DBL(0);
+
+ if (_downmixCoefficientsArePresent(hUniDrcConfig, dmxId,
+ &downmixInstructionIndex)) {
+ FIXP_DBL dB_m;
+ int dB_e;
+ FIXP_DBL coeff;
+ FIXP_DBL sum, maxSum; /* e = 7, so it is possible to sum up up to 32
+ downmix coefficients (with e = 2) */
+ int i, j;
+ DOWNMIX_INSTRUCTIONS* pDown =
+ &(hUniDrcConfig->downmixInstructions[downmixInstructionIndex]);
+ FIXP_DBL downmixOffset = getDownmixOffset(
+ pDown, hUniDrcConfig->channelLayout.baseChannelCount); /* e = 1 */
+ maxSum = (FIXP_DBL)0;
+
+ for (i = 0; i < pDown->targetChannelCount; i++) {
+ sum = (FIXP_DBL)0;
+ for (j = 0; j < hUniDrcConfig->channelLayout.baseChannelCount; j++) {
+ coeff = pDown->downmixCoefficient[j + i * hUniDrcConfig->channelLayout
+ .baseChannelCount];
+ sum += coeff >> 5;
+ }
+ if (maxSum < sum) maxSum = sum;
+ }
+
+ maxSum = fMultDiv2(maxSum, downmixOffset) << 2;
+
+ if (maxSum == FL2FXCONST_DBL(1.0f / (float)(1 << 7))) {
+ downmixPeakLevelDB = (FIXP_DBL)0;
+ } else {
+ dB_m = lin2dB(maxSum, 7, &dB_e); /* e_maxSum = 7 */
+ downmixPeakLevelDB =
+ scaleValue(dB_m, dB_e - 7); /* e_downmixPeakLevelDB = 7 */
+ }
+ }
+
+ if (_truePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, 0, albumMode)) {
+ retVal = _getTruePeakLevel(hLoudnessInfoSet, drcSetId, 0, albumMode,
+ &signalPeakLevelTmp);
+ if (retVal) return (retVal);
+ } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, drcSetId, 0,
+ albumMode)) {
+ retVal = _getSamplePeakLevel(hLoudnessInfoSet, drcSetId, 0, albumMode,
+ &signalPeakLevelTmp);
+ if (retVal) return (retVal);
+ } else if (_truePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, 0, albumMode)) {
+ retVal = _getTruePeakLevel(hLoudnessInfoSet, 0x3F, 0, albumMode,
+ &signalPeakLevelTmp);
+ if (retVal) return (retVal);
+ } else if (_samplePeakLevelIsPresent(hLoudnessInfoSet, 0x3F, 0,
+ albumMode)) {
+ retVal = _getSamplePeakLevel(hLoudnessInfoSet, 0x3F, 0, albumMode,
+ &signalPeakLevelTmp);
+ if (retVal) return (retVal);
+ } else if (_limiterPeakTargetIsPresent(pInst, drcSetId, 0)) {
+ retVal = _getLimiterPeakTarget(pInst, drcSetId, 0, &signalPeakLevelTmp);
+ if (retVal) return (retVal);
+ }
+
+ signalPeakLevel = signalPeakLevelTmp + downmixPeakLevelDB;
+ } else {
+ signalPeakLevel = FIXP_DBL(0); /* worst case estimate */
+ *explicitPeakInformationPresent = FIXP_DBL(0);
+ }
+
+ *signalPeakLevelOut = signalPeakLevel;
+
+ return retVal;
+}
+
+static DRCDEC_SELECTION_PROCESS_RETURN _extractLoudnessPeakToAverageValue(
+ LOUDNESS_INFO* loudnessInfo,
+ DYN_RANGE_MEASUREMENT_REQUEST_TYPE dynamicRangeMeasurementType,
+ int* pLoudnessPeakToAverageValuePresent,
+ FIXP_DBL* pLoudnessPeakToAverageValue) {
+ int i;
+
+ VALUE_ORDER valueOrderLoudness;
+ VALUE_ORDER valueOrderPeakLoudness;
+
+ _initValueOrder(&valueOrderLoudness);
+ _initValueOrder(&valueOrderPeakLoudness);
+
+ LOUDNESS_MEASUREMENT* pLoudnessMeasure = NULL;
+
+ *pLoudnessPeakToAverageValuePresent = 0;
+
+ for (i = 0; i < loudnessInfo->measurementCount; i++) {
+ pLoudnessMeasure = &(loudnessInfo->loudnessMeasurement[i]);
+
+ if (pLoudnessMeasure->methodDefinition == MD_PROGRAM_LOUDNESS) {
+ _getMethodValue(&valueOrderLoudness, pLoudnessMeasure->methodValue,
+ pLoudnessMeasure->measurementSystem, MS_PROGRAMLOUDNESS);
+ }
+
+ if ((dynamicRangeMeasurementType == DRMRT_SHORT_TERM_LOUDNESS_TO_AVG) &&
+ (pLoudnessMeasure->methodDefinition == MD_SHORT_TERM_LOUDNESS_MAX)) {
+ _getMethodValue(&valueOrderPeakLoudness, pLoudnessMeasure->methodValue,
+ pLoudnessMeasure->measurementSystem, MS_PEAKLOUDNESS);
+ }
+
+ if ((dynamicRangeMeasurementType == DRMRT_MOMENTARY_LOUDNESS_TO_AVG) &&
+ (pLoudnessMeasure->methodDefinition == MD_MOMENTARY_LOUDNESS_MAX)) {
+ _getMethodValue(&valueOrderPeakLoudness, pLoudnessMeasure->methodValue,
+ pLoudnessMeasure->measurementSystem, MS_PEAKLOUDNESS);
+ }
+
+ if ((dynamicRangeMeasurementType == DRMRT_TOP_OF_LOUDNESS_RANGE_TO_AVG) &&
+ (pLoudnessMeasure->methodDefinition == MD_MAX_OF_LOUDNESS_RANGE)) {
+ _getMethodValue(&valueOrderPeakLoudness, pLoudnessMeasure->methodValue,
+ pLoudnessMeasure->measurementSystem, MS_PEAKLOUDNESS);
+ }
+ }
+
+ if ((valueOrderLoudness.order > -1) && (valueOrderPeakLoudness.order > -1)) {
+ *pLoudnessPeakToAverageValue =
+ valueOrderPeakLoudness.value - valueOrderLoudness.value;
+ *pLoudnessPeakToAverageValuePresent = 1;
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/*******************************************/
+
+static DRCDEC_SELECTION_PROCESS_RETURN _selectAlbumLoudness(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ DRCDEC_SELECTION* pCandidatesPotential,
+ DRCDEC_SELECTION* pCandidatesSelected) {
+ int i, j;
+
+ for (i = 0; i < _drcdec_selection_getNumber(pCandidatesPotential); i++) {
+ DRCDEC_SELECTION_DATA* pCandidate =
+ _drcdec_selection_getAt(pCandidatesPotential, i);
+ if (pCandidate == NULL) return DRCDEC_SELECTION_PROCESS_NOT_OK;
+
+ for (j = 0; j < hLoudnessInfoSet->loudnessInfoAlbumCount; j++) {
+ if (pCandidate->pInst->drcSetId ==
+ hLoudnessInfoSet->loudnessInfoAlbum[j].drcSetId) {
+ if (_drcdec_selection_add(pCandidatesSelected, pCandidate) == NULL)
+ return DRCDEC_SELECTION_PROCESS_NOT_OK;
+ }
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/*******************************************/
+
+static int _findMethodDefinition(LOUDNESS_INFO* pLoudnessInfo,
+ int methodDefinition, int startIndex) {
+ int i;
+ int index = -1;
+
+ for (i = startIndex; i < pLoudnessInfo->measurementCount; i++) {
+ if (pLoudnessInfo->loudnessMeasurement[i].methodDefinition ==
+ methodDefinition) {
+ index = i;
+ break;
+ }
+ }
+
+ return index;
+}
+
+/*******************************************/
+
+static DRCDEC_SELECTION_PROCESS_RETURN _getMixingLevel(
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet, int downmixIdRequested,
+ int drcSetIdRequested, int albumMode, FIXP_DBL* pMixingLevel) {
+ const FIXP_DBL mixingLevelDefault = FL2FXCONST_DBL(85.0f / (float)(1 << 7));
+
+ int i;
+ int count;
+
+ LOUDNESS_INFO* pLoudnessInfo = NULL;
+
+ *pMixingLevel = mixingLevelDefault;
+
+ if (drcSetIdRequested < 0) {
+ drcSetIdRequested = 0;
+ }
+
+ if (albumMode) {
+ count = hLoudnessInfoSet->loudnessInfoAlbumCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfoAlbum;
+ } else {
+ count = hLoudnessInfoSet->loudnessInfoCount;
+ pLoudnessInfo = hLoudnessInfoSet->loudnessInfo;
+ }
+
+ for (i = 0; i < count; i++) {
+ if ((drcSetIdRequested == pLoudnessInfo[i].drcSetId) &&
+ ((downmixIdRequested == pLoudnessInfo[i].downmixId) ||
+ (DOWNMIX_ID_ANY_DOWNMIX == pLoudnessInfo[i].downmixId))) {
+ int index = _findMethodDefinition(&pLoudnessInfo[i], MD_MIXING_LEVEL, 0);
+
+ if (index >= 0) {
+ *pMixingLevel = pLoudnessInfo[i].loudnessMeasurement[index].methodValue;
+ break;
+ }
+ }
+ }
+
+ return DRCDEC_SELECTION_PROCESS_NO_ERROR;
+}
+
+/*******************************************/
diff --git a/fdk-aac/libDRCdec/src/drcDec_selectionProcess.h b/fdk-aac/libDRCdec/src/drcDec_selectionProcess.h
new file mode 100644
index 0000000..9e0e3fb
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDec_selectionProcess.h
@@ -0,0 +1,217 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s): Andreas Hoelzer
+
+ Description: DRC Set Selection
+
+*******************************************************************************/
+
+#ifndef DRCDEC_SELECTIONPROCESS_H
+#define DRCDEC_SELECTIONPROCESS_H
+
+#include "drcDec_types.h"
+#include "drcDecoder.h"
+
+/* DRC set selection according to section 6.2 of ISO/IEC 23003-4 (MPEG-D DRC) */
+/* including ISO/IEC 23003-4/AMD1 (Amendment 1) */
+
+typedef struct s_drcdec_selection_process* HANDLE_DRC_SELECTION_PROCESS;
+
+typedef enum {
+ DRCDEC_SELECTION_PROCESS_NO_ERROR = 0,
+
+ DRCDEC_SELECTION_PROCESS_WARNING = -1000,
+
+ DRCDEC_SELECTION_PROCESS_NOT_OK = -2000,
+ DRCDEC_SELECTION_PROCESS_OUTOFMEMORY,
+ DRCDEC_SELECTION_PROCESS_INVALID_HANDLE,
+ DRCDEC_SELECTION_PROCESS_NOT_SUPPORTED,
+ DRCDEC_SELECTION_PROCESS_INVALID_PARAM,
+ DRCDEC_SELECTION_PROCESS_PARAM_OUT_OF_RANGE
+
+} DRCDEC_SELECTION_PROCESS_RETURN;
+
+typedef enum {
+ SEL_PROC_TEST_TIME_DOMAIN = -100,
+ SEL_PROC_TEST_QMF_DOMAIN,
+ SEL_PROC_TEST_STFT_DOMAIN,
+
+ SEL_PROC_CODEC_MODE_UNDEFINED = -1,
+ SEL_PROC_MPEG_4_AAC,
+ SEL_PROC_MPEG_D_USAC,
+ SEL_PROC_MPEG_H_3DA
+} SEL_PROC_CODEC_MODE;
+
+typedef enum {
+ /* set and get user param */
+ SEL_PROC_LOUDNESS_NORMALIZATION_ON,
+ /* get only user param */
+ SEL_PROC_DYNAMIC_RANGE_CONTROL_ON,
+ /* set only user params */
+ SEL_PROC_TARGET_LOUDNESS,
+ SEL_PROC_EFFECT_TYPE,
+ SEL_PROC_EFFECT_TYPE_FALLBACK_CODE,
+ SEL_PROC_LOUDNESS_MEASUREMENT_METHOD,
+ SEL_PROC_DOWNMIX_ID,
+ SEL_PROC_TARGET_LAYOUT,
+ SEL_PROC_TARGET_CHANNEL_COUNT,
+ SEL_PROC_BASE_CHANNEL_COUNT,
+ SEL_PROC_SAMPLE_RATE,
+ SEL_PROC_BOOST,
+ SEL_PROC_COMPRESS
+} SEL_PROC_USER_PARAM;
+
+typedef struct s_selection_process_output {
+ FIXP_DBL outputPeakLevelDb; /* e = 7 */
+ FIXP_DBL loudnessNormalizationGainDb; /* e = 7 */
+ FIXP_DBL outputLoudness; /* e = 7 */
+
+ UCHAR numSelectedDrcSets;
+ SCHAR selectedDrcSetIds[MAX_ACTIVE_DRCS];
+ UCHAR selectedDownmixIds[MAX_ACTIVE_DRCS];
+
+ UCHAR activeDownmixId;
+ UCHAR baseChannelCount;
+ UCHAR targetChannelCount;
+ SCHAR targetLayout;
+ UCHAR downmixMatrixPresent;
+ FIXP_DBL downmixMatrix[8][8]; /* e = 2 */
+
+ FIXP_SGL boost; /* e = 1 */
+ FIXP_SGL compress; /* e = 1 */
+
+ FIXP_DBL mixingLevel; /* e = 7 */
+
+} SEL_PROC_OUTPUT, *HANDLE_SEL_PROC_OUTPUT;
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_Create(HANDLE_DRC_SELECTION_PROCESS* phInstance);
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_Delete(HANDLE_DRC_SELECTION_PROCESS* phInstance);
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_Init(HANDLE_DRC_SELECTION_PROCESS hInstance);
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_SetCodecMode(HANDLE_DRC_SELECTION_PROCESS hInstance,
+ const SEL_PROC_CODEC_MODE codecMode);
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_SetParam(HANDLE_DRC_SELECTION_PROCESS hInstance,
+ const SEL_PROC_USER_PARAM requestType,
+ FIXP_DBL requestValue, int* pDiff);
+
+FIXP_DBL
+drcDec_SelectionProcess_GetParam(HANDLE_DRC_SELECTION_PROCESS hInstance,
+ const SEL_PROC_USER_PARAM requestType);
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_SetMpeghParams(
+ HANDLE_DRC_SELECTION_PROCESS hInstance, const int numGroupIdsRequested,
+ const int* groupIdRequested, const int numGroupPresetIdsRequested,
+ const int* groupPresetIdRequested,
+ const int* numMembersGroupPresetIdsRequested,
+ const int groupPresetIdRequestedPreference, int* pDiff);
+
+DRCDEC_SELECTION_PROCESS_RETURN
+drcDec_SelectionProcess_Process(HANDLE_DRC_SELECTION_PROCESS hInstance,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
+ HANDLE_SEL_PROC_OUTPUT hSelProcOutput);
+
+#endif
diff --git a/fdk-aac/libDRCdec/src/drcDec_tools.cpp b/fdk-aac/libDRCdec/src/drcDec_tools.cpp
new file mode 100644
index 0000000..9a6feb1
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDec_tools.cpp
@@ -0,0 +1,371 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "drcDec_types.h"
+#include "drcDec_tools.h"
+#include "fixpoint_math.h"
+#include "drcDecoder.h"
+
+int getDeltaTmin(const int sampleRate) {
+ /* half_ms = round (0.0005 * sampleRate); */
+ int half_ms = (sampleRate + 1000) / 2000;
+ int deltaTmin = 1;
+ if (sampleRate < 1000) {
+ return DE_NOT_OK;
+ }
+ while (deltaTmin <= half_ms) {
+ deltaTmin = deltaTmin << 1;
+ }
+ return deltaTmin;
+}
+
+DRC_COEFFICIENTS_UNI_DRC* selectDrcCoefficients(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int location) {
+ int n;
+ int c = -1;
+ for (n = 0; n < hUniDrcConfig->drcCoefficientsUniDrcCount; n++) {
+ if (hUniDrcConfig->drcCoefficientsUniDrc[n].drcLocation == location) {
+ c = n;
+ }
+ }
+ if (c >= 0) {
+ return &(hUniDrcConfig->drcCoefficientsUniDrc[c]);
+ }
+ return NULL; /* possible during bitstream parsing */
+}
+
+DRC_INSTRUCTIONS_UNI_DRC* selectDrcInstructions(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int drcSetId) {
+ int i;
+ for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) {
+ if (hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId == drcSetId) {
+ return &(hUniDrcConfig->drcInstructionsUniDrc[i]);
+ }
+ }
+ return NULL;
+}
+
+DOWNMIX_INSTRUCTIONS* selectDownmixInstructions(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int downmixId) {
+ int i;
+ for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
+ if (hUniDrcConfig->downmixInstructions[i].downmixId == downmixId) {
+ return &(hUniDrcConfig->downmixInstructions[i]);
+ }
+ }
+ return NULL;
+}
+
+DRC_ERROR
+deriveDrcChannelGroups(
+ const int drcSetEffect, /* in */
+ const int channelCount, /* in */
+ const SCHAR* gainSetIndex, /* in */
+ const DUCKING_MODIFICATION* duckingModificationForChannel, /* in */
+ UCHAR* nDrcChannelGroups, /* out */
+ SCHAR* uniqueIndex, /* out (gainSetIndexForChannelGroup) */
+ SCHAR* groupForChannel, /* out */
+ DUCKING_MODIFICATION* duckingModificationForChannelGroup) /* out */
+{
+ int duckingSequence = -1;
+ int c, n, g, match, idx;
+ FIXP_SGL factor;
+ FIXP_SGL uniqueScaling[8];
+
+ for (g = 0; g < 8; g++) {
+ uniqueIndex[g] = -10;
+ uniqueScaling[g] = FIXP_SGL(-1.0f);
+ }
+
+ g = 0;
+
+ if (drcSetEffect & EB_DUCK_OTHER) {
+ for (c = 0; c < channelCount; c++) {
+ match = 0;
+ if (c >= 8) return DE_MEMORY_ERROR;
+ idx = gainSetIndex[c];
+ factor = duckingModificationForChannel[c].duckingScaling;
+ if (idx < 0) {
+ for (n = 0; n < g; n++) {
+ if (uniqueScaling[n] == factor) {
+ match = 1;
+ groupForChannel[c] = n;
+ break;
+ }
+ }
+ if (match == 0) {
+ if (g >= 8) return DE_MEMORY_ERROR;
+ uniqueIndex[g] = idx;
+ uniqueScaling[g] = factor;
+ groupForChannel[c] = g;
+ g++;
+ }
+ } else {
+ if ((duckingSequence > 0) && (duckingSequence != idx)) {
+ return DE_NOT_OK;
+ }
+ duckingSequence = idx;
+ groupForChannel[c] = -1;
+ }
+ }
+ if (duckingSequence == -1) {
+ return DE_NOT_OK;
+ }
+ } else if (drcSetEffect & EB_DUCK_SELF) {
+ for (c = 0; c < channelCount; c++) {
+ match = 0;
+ if (c >= 8) return DE_MEMORY_ERROR;
+ idx = gainSetIndex[c];
+ factor = duckingModificationForChannel[c].duckingScaling;
+ if (idx >= 0) {
+ for (n = 0; n < g; n++) {
+ if ((uniqueIndex[n] == idx) && (uniqueScaling[n] == factor)) {
+ match = 1;
+ groupForChannel[c] = n;
+ break;
+ }
+ }
+ if (match == 0) {
+ if (g >= 8) return DE_MEMORY_ERROR;
+ uniqueIndex[g] = idx;
+ uniqueScaling[g] = factor;
+ groupForChannel[c] = g;
+ g++;
+ }
+ } else {
+ groupForChannel[c] = -1;
+ }
+ }
+ } else { /* no ducking */
+ for (c = 0; c < channelCount; c++) {
+ if (c >= 8) return DE_MEMORY_ERROR;
+ idx = gainSetIndex[c];
+ match = 0;
+ if (idx >= 0) {
+ for (n = 0; n < g; n++) {
+ if (uniqueIndex[n] == idx) {
+ match = 1;
+ groupForChannel[c] = n;
+ break;
+ }
+ }
+ if (match == 0) {
+ if (g >= 8) return DE_MEMORY_ERROR;
+ uniqueIndex[g] = idx;
+ groupForChannel[c] = g;
+ g++;
+ }
+ } else {
+ groupForChannel[c] = -1;
+ }
+ }
+ }
+ *nDrcChannelGroups = g;
+
+ if (drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
+ for (g = 0; g < *nDrcChannelGroups; g++) {
+ if (drcSetEffect & EB_DUCK_OTHER) {
+ uniqueIndex[g] = duckingSequence;
+ }
+ duckingModificationForChannelGroup[g].duckingScaling = uniqueScaling[g];
+ if (uniqueScaling[g] != FL2FXCONST_SGL(1.0f / (float)(1 << 2))) {
+ duckingModificationForChannelGroup[g].duckingScalingPresent = 1;
+ } else {
+ duckingModificationForChannelGroup[g].duckingScalingPresent = 0;
+ }
+ }
+ }
+
+ return DE_OK;
+}
+
+FIXP_DBL
+dB2lin(const FIXP_DBL dB_m, const int dB_e, int* pLin_e) {
+ /* get linear value from dB.
+ return lin_val = 10^(dB_val/20) = 2^(log2(10)/20*dB_val)
+ with dB_val = dB_m *2^dB_e and lin_val = lin_m * 2^lin_e */
+ FIXP_DBL lin_m =
+ f2Pow(fMult(dB_m, FL2FXCONST_DBL(0.1660964f * (float)(1 << 2))), dB_e - 2,
+ pLin_e);
+
+ return lin_m;
+}
+
+FIXP_DBL
+lin2dB(const FIXP_DBL lin_m, const int lin_e, int* pDb_e) {
+ /* get dB value from linear value.
+ return dB_val = 20*log10(lin_val)
+ with dB_val = dB_m *2^dB_e and lin_val = lin_m * 2^lin_e */
+ FIXP_DBL dB_m;
+
+ if (lin_m == (FIXP_DBL)0) { /* return very small value representing -inf */
+ dB_m = (FIXP_DBL)MINVAL_DBL;
+ *pDb_e = DFRACT_BITS - 1;
+ } else {
+ /* 20*log10(lin_val) = 20/log2(10)*log2(lin_val) */
+ dB_m = fMultDiv2(FL2FXCONST_DBL(6.02059991f / (float)(1 << 3)),
+ fLog2(lin_m, lin_e, pDb_e));
+ *pDb_e += 3 + 1;
+ }
+
+ return dB_m;
+}
+
+FIXP_DBL
+approxDb2lin(const FIXP_DBL dB_m, const int dB_e, int* pLin_e) {
+ /* get linear value from approximate dB.
+ return lin_val = 2^(dB_val/6)
+ with dB_val = dB_m *2^dB_e and lin_val = lin_m * 2^lin_e */
+ FIXP_DBL lin_m =
+ f2Pow(fMult(dB_m, FL2FXCONST_DBL(0.1666667f * (float)(1 << 2))), dB_e - 2,
+ pLin_e);
+
+ return lin_m;
+}
+
+int bitstreamContainsMultibandDrc(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ const int downmixId) {
+ int i, g, d, seq;
+ DRC_INSTRUCTIONS_UNI_DRC* pInst;
+ DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
+ int isMultiband = 0;
+
+ pCoef = selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
+ if (pCoef == NULL) return 0;
+
+ for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
+ pInst = &(hUniDrcConfig->drcInstructionsUniDrc[i]);
+ for (d = 0; d < pInst->downmixIdCount; d++) {
+ if (downmixId == pInst->downmixId[d]) {
+ for (g = 0; g < pInst->nDrcChannelGroups; g++) {
+ seq = pInst->gainSetIndexForChannelGroup[g];
+ if (pCoef->gainSet[seq].bandCount > 1) {
+ isMultiband = 1;
+ }
+ }
+ }
+ }
+ }
+
+ return isMultiband;
+}
+
+FIXP_DBL getDownmixOffset(DOWNMIX_INSTRUCTIONS* pDown, int baseChannelCount) {
+ FIXP_DBL downmixOffset = FL2FXCONST_DBL(1.0f / (1 << 1)); /* e = 1 */
+ if ((pDown->bsDownmixOffset == 1) || (pDown->bsDownmixOffset == 2)) {
+ int e_a, e_downmixOffset;
+ FIXP_DBL a, q;
+ if (baseChannelCount <= pDown->targetChannelCount) return downmixOffset;
+
+ q = fDivNorm((FIXP_DBL)pDown->targetChannelCount,
+ (FIXP_DBL)baseChannelCount); /* e = 0 */
+ a = lin2dB(q, 0, &e_a);
+ if (pDown->bsDownmixOffset == 2) {
+ e_a += 1; /* a *= 2 */
+ }
+ /* a = 0.5 * round (a) */
+ a = fixp_round(a, e_a) >> 1;
+ downmixOffset = dB2lin(a, e_a, &e_downmixOffset);
+ downmixOffset = scaleValue(downmixOffset, e_downmixOffset - 1);
+ }
+ return downmixOffset;
+}
diff --git a/fdk-aac/libDRCdec/src/drcDec_tools.h b/fdk-aac/libDRCdec/src/drcDec_tools.h
new file mode 100644
index 0000000..77a0ab7
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDec_tools.h
@@ -0,0 +1,146 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef DRCDEC_TOOLS_H
+#define DRCDEC_TOOLS_H
+
+#include "drcDec_types.h"
+#include "drcDec_selectionProcess.h"
+
+int getDeltaTmin(const int sampleRate);
+
+DRC_COEFFICIENTS_UNI_DRC* selectDrcCoefficients(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int location);
+
+DRC_INSTRUCTIONS_UNI_DRC* selectDrcInstructions(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int drcSetId);
+
+DOWNMIX_INSTRUCTIONS* selectDownmixInstructions(
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int downmixId);
+
+DRC_ERROR
+deriveDrcChannelGroups(
+ const int drcSetEffect, /* in */
+ const int channelCount, /* in */
+ const SCHAR* gainSetIndex, /* in */
+ const DUCKING_MODIFICATION* duckingModificationForChannel, /* in */
+ UCHAR* nDrcChannelGroups, /* out */
+ SCHAR* uniqueIndex, /* out (gainSetIndexForChannelGroup) */
+ SCHAR* groupForChannel, /* out */
+ DUCKING_MODIFICATION* duckingModificationForChannelGroup); /* out */
+
+FIXP_DBL
+dB2lin(const FIXP_DBL dB_m, const int dB_e, int* pLin_e);
+
+FIXP_DBL
+lin2dB(const FIXP_DBL lin_m, const int lin_e, int* pDb_e);
+
+FIXP_DBL
+approxDb2lin(const FIXP_DBL dB_m, const int dB_e, int* pLin_e);
+
+int bitstreamContainsMultibandDrc(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ const int downmixId);
+
+FIXP_DBL
+getDownmixOffset(DOWNMIX_INSTRUCTIONS* pDown, int baseChannelCount);
+
+#endif
diff --git a/fdk-aac/libDRCdec/src/drcDec_types.h b/fdk-aac/libDRCdec/src/drcDec_types.h
new file mode 100644
index 0000000..28c17f3
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDec_types.h
@@ -0,0 +1,428 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef DRCDEC_TYPES_H
+#define DRCDEC_TYPES_H
+
+#include "common_fix.h"
+
+/* Data structures corresponding to static and dynamic DRC/Loudness payload
+ as defined in section 7 of MPEG-D DRC standard, ISO/IEC 23003-4 */
+
+/**************/
+/* uniDrcGain */
+/**************/
+
+typedef struct {
+ FIXP_SGL gainDb; /* e = 7 */
+ SHORT time;
+} GAIN_NODE;
+
+/* uniDrcGainExtension() (Table 56) */
+typedef struct {
+ UCHAR uniDrcGainExtType[8];
+ ULONG extBitSize[8 - 1];
+} UNI_DRC_GAIN_EXTENSION;
+
+/* uniDrcGain() (Table 55) */
+typedef struct {
+ UCHAR nNodes[12]; /* unsaturated value, i.e. as provided in bitstream */
+ GAIN_NODE gainNode[12][16];
+
+ UCHAR uniDrcGainExtPresent;
+ UNI_DRC_GAIN_EXTENSION uniDrcGainExtension;
+} UNI_DRC_GAIN, *HANDLE_UNI_DRC_GAIN;
+
+/****************/
+/* uniDrcConfig */
+/****************/
+
+typedef enum {
+ EB_NIGHT = 0x0001,
+ EB_NOISY = 0x0002,
+ EB_LIMITED = 0x0004,
+ EB_LOWLEVEL = 0x0008,
+ EB_DIALOG = 0x0010,
+ EB_GENERAL_COMPR = 0x0020,
+ EB_EXPAND = 0x0040,
+ EB_ARTISTIC = 0x0080,
+ EB_CLIPPING = 0x0100,
+ EB_FADE = 0x0200,
+ EB_DUCK_OTHER = 0x0400,
+ EB_DUCK_SELF = 0x0800
+} EFFECT_BIT;
+
+typedef enum {
+ GCP_REGULAR = 0,
+ GCP_FADING = 1,
+ GCP_CLIPPING_DUCKING = 2,
+ GCP_CONSTANT = 3
+} GAIN_CODING_PROFILE;
+
+typedef enum { GIT_SPLINE = 0, GIT_LINEAR = 1 } GAIN_INTERPOLATION_TYPE;
+
+typedef enum { CS_LEFT = 0, CS_RIGHT = 1 } CHARACTERISTIC_SIDE;
+
+typedef enum { CF_SIGMOID = 0, CF_NODES = 1 } CHARACTERISTIC_FORMAT;
+
+typedef enum {
+ GF_QMF32 = 0x1,
+ GF_QMFHYBRID39 = 0x2,
+ GF_QMF64 = 0x3,
+ GF_QMFHYBRID71 = 0x4,
+ GF_QMF128 = 0x5,
+ GF_QMFHYBRID135 = 0x6,
+ GF_UNIFORM = 0x7
+} EQ_SUBBAND_GAIN_FORMAT;
+
+typedef struct {
+ UCHAR duckingScalingPresent;
+ FIXP_SGL duckingScaling; /* e = 2 */
+} DUCKING_MODIFICATION;
+
+typedef struct {
+ UCHAR targetCharacteristicLeftPresent;
+ UCHAR targetCharacteristicLeftIndex;
+ UCHAR targetCharacteristicRightPresent;
+ UCHAR targetCharacteristicRightIndex;
+ UCHAR gainScalingPresent;
+ FIXP_SGL attenuationScaling; /* e = 2 */
+ FIXP_SGL amplificationScaling; /* e = 2 */
+ UCHAR gainOffsetPresent;
+ FIXP_SGL gainOffset; /* e = 4 */
+} GAIN_MODIFICATION;
+
+typedef union {
+ UCHAR crossoverFreqIndex;
+ USHORT startSubBandIndex;
+} BAND_BORDER;
+
+typedef struct {
+ UCHAR left;
+ UCHAR right;
+} CUSTOM_INDEX;
+
+typedef struct {
+ UCHAR present;
+ UCHAR isCICP;
+ union {
+ UCHAR cicpIndex;
+ CUSTOM_INDEX custom;
+ };
+} DRC_CHARACTERISTIC;
+
+typedef struct {
+ UCHAR gainCodingProfile;
+ UCHAR gainInterpolationType;
+ UCHAR fullFrame;
+ UCHAR timeAlignment;
+ UCHAR timeDeltaMinPresent;
+ USHORT timeDeltaMin;
+ UCHAR bandCount;
+ UCHAR drcBandType;
+ UCHAR gainSequenceIndex[4];
+ DRC_CHARACTERISTIC drcCharacteristic[4];
+ BAND_BORDER bandBorder[4];
+} GAIN_SET;
+
+typedef struct {
+ FIXP_SGL gain; /* e = 6 */
+ FIXP_SGL ioRatio; /* e = 2 */
+ FIXP_SGL exp; /* e = 5 */
+ UCHAR flipSign;
+} CUSTOM_DRC_CHAR_SIGMOID;
+
+typedef struct {
+ UCHAR characteristicNodeCount;
+ FIXP_SGL nodeLevel[4 + 1]; /* e = 7 */
+ FIXP_SGL nodeGain[4 + 1]; /* e = 7 */
+} CUSTOM_DRC_CHAR_NODES;
+
+typedef shouldBeUnion {
+ CUSTOM_DRC_CHAR_SIGMOID sigmoid;
+ CUSTOM_DRC_CHAR_NODES nodes;
+}
+CUSTOM_DRC_CHAR;
+
+/* drcCoefficientsUniDrc() (Table 67) */
+typedef struct {
+ UCHAR drcLocation;
+ UCHAR drcFrameSizePresent;
+ USHORT drcFrameSize;
+ UCHAR characteristicLeftCount;
+ UCHAR characteristicLeftFormat[8];
+ CUSTOM_DRC_CHAR customCharacteristicLeft[8];
+ UCHAR characteristicRightCount;
+ UCHAR characteristicRightFormat[8];
+ CUSTOM_DRC_CHAR customCharacteristicRight[8];
+ UCHAR
+ gainSequenceCount; /* unsaturated value, i.e. as provided in bitstream */
+ UCHAR gainSetCount; /* saturated to 12 */
+ GAIN_SET gainSet[12];
+ /* derived data */
+ UCHAR gainSetIndexForGainSequence[12];
+} DRC_COEFFICIENTS_UNI_DRC;
+
+/* drcInstructionsUniDrc() (Table 72) */
+typedef struct {
+ SCHAR drcSetId;
+ UCHAR drcSetComplexityLevel;
+ UCHAR drcLocation;
+ UCHAR drcApplyToDownmix;
+ UCHAR downmixIdCount;
+ UCHAR downmixId[8];
+ USHORT drcSetEffect;
+ UCHAR limiterPeakTargetPresent;
+ FIXP_SGL limiterPeakTarget; /* e = 5 */
+ UCHAR drcSetTargetLoudnessPresent;
+ SCHAR drcSetTargetLoudnessValueUpper;
+ SCHAR drcSetTargetLoudnessValueLower;
+ UCHAR dependsOnDrcSetPresent;
+ union {
+ SCHAR dependsOnDrcSet;
+ UCHAR noIndependentUse;
+ };
+ UCHAR requiresEq;
+ shouldBeUnion {
+ GAIN_MODIFICATION gainModificationForChannelGroup[8][4];
+ DUCKING_MODIFICATION duckingModificationForChannel[8];
+ };
+ SCHAR gainSetIndex[8];
+
+ /* derived data */
+ UCHAR drcChannelCount;
+ UCHAR nDrcChannelGroups;
+ SCHAR gainSetIndexForChannelGroup[8];
+} DRC_INSTRUCTIONS_UNI_DRC;
+
+/* channelLayout() (Table 62) */
+typedef struct {
+ UCHAR baseChannelCount;
+ UCHAR layoutSignalingPresent;
+ UCHAR definedLayout;
+ UCHAR speakerPosition[8];
+} CHANNEL_LAYOUT;
+
+/* downmixInstructions() (Table 63) */
+typedef struct {
+ UCHAR downmixId;
+ UCHAR targetChannelCount;
+ UCHAR targetLayout;
+ UCHAR downmixCoefficientsPresent;
+ UCHAR bsDownmixOffset;
+ FIXP_DBL downmixCoefficient[8 * 8]; /* e = 2 */
+} DOWNMIX_INSTRUCTIONS;
+
+typedef struct {
+ UCHAR uniDrcConfigExtType[8];
+ ULONG extBitSize[8 - 1];
+} UNI_DRC_CONFIG_EXTENSION;
+
+/* uniDrcConfig() (Table 57) */
+typedef struct {
+ UCHAR sampleRatePresent;
+ ULONG sampleRate;
+ UCHAR downmixInstructionsCountV0;
+ UCHAR downmixInstructionsCountV1;
+ UCHAR downmixInstructionsCount; /* saturated to 6 */
+ UCHAR drcCoefficientsUniDrcCountV0;
+ UCHAR drcCoefficientsUniDrcCountV1;
+ UCHAR drcCoefficientsUniDrcCount; /* saturated to 2 */
+ UCHAR drcInstructionsUniDrcCountV0;
+ UCHAR drcInstructionsUniDrcCountV1;
+ UCHAR drcInstructionsUniDrcCount; /* saturated to (12 + 1 + 6) */
+ CHANNEL_LAYOUT channelLayout;
+ DOWNMIX_INSTRUCTIONS downmixInstructions[6];
+ DRC_COEFFICIENTS_UNI_DRC drcCoefficientsUniDrc[2];
+ DRC_INSTRUCTIONS_UNI_DRC drcInstructionsUniDrc[(12 + 1 + 6)];
+ UCHAR uniDrcConfigExtPresent;
+ UNI_DRC_CONFIG_EXTENSION uniDrcConfigExt;
+
+ /* derived data */
+ UCHAR drcInstructionsCountInclVirtual;
+ UCHAR diff;
+} UNI_DRC_CONFIG, *HANDLE_UNI_DRC_CONFIG;
+
+/*******************/
+/* loudnessInfoSet */
+/*******************/
+
+typedef enum {
+ MD_UNKNOWN_OTHER = 0,
+ MD_PROGRAM_LOUDNESS = 1,
+ MD_ANCHOR_LOUDNESS = 2,
+ MD_MAX_OF_LOUDNESS_RANGE = 3,
+ MD_MOMENTARY_LOUDNESS_MAX = 4,
+ MD_SHORT_TERM_LOUDNESS_MAX = 5,
+ MD_LOUDNESS_RANGE = 6,
+ MD_MIXING_LEVEL = 7,
+ MD_ROOM_TYPE = 8,
+ MD_SHORT_TERM_LOUDNESS = 9
+} METHOD_DEFINITION;
+
+typedef enum {
+ MS_UNKNOWN_OTHER = 0,
+ MS_EBU_R_128 = 1,
+ MS_BS_1770_4 = 2,
+ MS_BS_1770_4_PRE_PROCESSING = 3,
+ MS_USER = 4,
+ MS_EXPERT_PANEL = 5,
+ MS_BS_1771_1 = 6,
+ MS_RESERVED_A = 7,
+ MS_RESERVED_B = 8,
+ MS_RESERVED_C = 9,
+ MS_RESERVED_D = 10,
+ MS_RESERVED_E = 11
+} MEASUREMENT_SYSTEM;
+
+typedef enum {
+ R_UKNOWN = 0,
+ R_UNVERIFIED = 1,
+ R_CEILING = 2,
+ R_ACCURATE = 3
+} RELIABILITY;
+
+typedef struct {
+ UCHAR methodDefinition;
+ FIXP_DBL methodValue; /* e = 7 for all methodDefinitions */
+ UCHAR measurementSystem;
+ UCHAR reliability;
+} LOUDNESS_MEASUREMENT;
+
+/* loudnessInfo() (Table 59) */
+typedef struct {
+ SCHAR drcSetId;
+ UCHAR eqSetId;
+ UCHAR downmixId;
+ UCHAR samplePeakLevelPresent;
+ FIXP_DBL samplePeakLevel; /* e = 7 */
+ UCHAR truePeakLevelPresent;
+ FIXP_DBL truePeakLevel; /* e = 7 */
+ UCHAR truePeakLevelMeasurementSystem;
+ UCHAR truePeakLevelReliability;
+ UCHAR measurementCount; /* saturated to 8 */
+ LOUDNESS_MEASUREMENT loudnessMeasurement[8];
+} LOUDNESS_INFO;
+
+/* loudnessInfoSetExtension() (Table 61) */
+typedef struct {
+ UCHAR loudnessInfoSetExtType[8];
+ ULONG extBitSize[8 - 1];
+} LOUDNESS_INFO_SET_EXTENSION;
+
+/* loudnessInfoSet() (Table 58) */
+typedef struct {
+ UCHAR loudnessInfoAlbumCountV0;
+ UCHAR loudnessInfoAlbumCountV1;
+ UCHAR loudnessInfoAlbumCount; /* saturated to 12 */
+ UCHAR loudnessInfoCountV0;
+ UCHAR loudnessInfoCountV1;
+ UCHAR loudnessInfoCount; /* saturated to 12 */
+ LOUDNESS_INFO loudnessInfoAlbum[12];
+ LOUDNESS_INFO loudnessInfo[12];
+ UCHAR loudnessInfoSetExtPresent;
+ LOUDNESS_INFO_SET_EXTENSION loudnessInfoSetExt;
+ /* derived data */
+ UCHAR diff;
+} LOUDNESS_INFO_SET, *HANDLE_LOUDNESS_INFO_SET;
+
+#endif
diff --git a/fdk-aac/libDRCdec/src/drcDecoder.h b/fdk-aac/libDRCdec/src/drcDecoder.h
new file mode 100644
index 0000000..9826a7b
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcDecoder.h
@@ -0,0 +1,142 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef DRCDECODER_H
+#define DRCDECODER_H
+
+/* drcDecoder.h: definitions used in all submodules */
+
+#define MAX_ACTIVE_DRCS 3
+
+typedef enum { DM_REGULAR_DELAY = 0, DM_LOW_DELAY = 1 } DELAY_MODE;
+
+typedef enum {
+ DE_OK = 0,
+ DE_NOT_OK = -100,
+ DE_PARAM_OUT_OF_RANGE,
+ DE_PARAM_INVALID,
+ DE_MEMORY_ERROR
+} DRC_ERROR;
+
+typedef enum { SDM_OFF, SDM_QMF64, SDM_QMF71, SDM_STFT256 } SUBBAND_DOMAIN_MODE;
+
+#define DOWNMIX_ID_BASE_LAYOUT 0x0
+#define DOWNMIX_ID_ANY_DOWNMIX 0x7F
+#define DRC_SET_ID_NO_DRC 0x0
+#define DRC_SET_ID_ANY_DRC 0x3F
+
+#define LOCATION_MP4_INSTREAM_UNIDRC 0x1
+#define LOCATION_MP4_DYN_RANGE_INFO 0x2
+#define LOCATION_MP4_COMPRESSION_VALUE 0x3
+#define LOCATION_SELECTED \
+ LOCATION_MP4_INSTREAM_UNIDRC /* set to location selected by system */
+
+#define MAX_REQUESTS_DOWNMIX_ID 15
+#define MAX_REQUESTS_DRC_FEATURE 7
+#define MAX_REQUESTS_DRC_EFFECT_TYPE 15
+
+#define DEFAULT_LOUDNESS_DEVIATION_MAX 63
+
+#define DRC_INPUT_LOUDNESS_TARGET FL2FXCONST_DBL(-31.0f / (float)(1 << 7))
+#define DRC_INPUT_LOUDNESS_TARGET_SGL FL2FXCONST_SGL(-31.0f / (float)(1 << 7))
+
+#endif
diff --git a/fdk-aac/libDRCdec/src/drcGainDec_init.cpp b/fdk-aac/libDRCdec/src/drcGainDec_init.cpp
new file mode 100644
index 0000000..38f3243
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcGainDec_init.cpp
@@ -0,0 +1,344 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "drcDec_types.h"
+#include "drcDec_tools.h"
+#include "drcDec_gainDecoder.h"
+#include "drcGainDec_init.h"
+
+static DRC_ERROR _generateDrcInstructionsDerivedData(
+ HANDLE_DRC_GAIN_DECODER hGainDec, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
+ DRC_INSTRUCTIONS_UNI_DRC* pInst, DRC_COEFFICIENTS_UNI_DRC* pCoef,
+ ACTIVE_DRC* pActiveDrc) {
+ DRC_ERROR err = DE_OK;
+ int g;
+ int gainElementCount = 0;
+ UCHAR nDrcChannelGroups = 0;
+ SCHAR gainSetIndexForChannelGroup[8];
+
+ err = deriveDrcChannelGroups(
+ pInst->drcSetEffect, pInst->drcChannelCount, pInst->gainSetIndex,
+ pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)
+ ? pInst->duckingModificationForChannel
+ : NULL,
+ &nDrcChannelGroups, gainSetIndexForChannelGroup,
+ pActiveDrc->channelGroupForChannel,
+ pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)
+ ? pActiveDrc->duckingModificationForChannelGroup
+ : NULL);
+ if (err) return (err);
+
+ /* sanity check */
+ if (nDrcChannelGroups != pInst->nDrcChannelGroups) return DE_NOT_OK;
+ for (g = 0; g < pInst->nDrcChannelGroups; g++) {
+ if (gainSetIndexForChannelGroup[g] != pInst->gainSetIndexForChannelGroup[g])
+ return DE_NOT_OK;
+ }
+
+ for (g = 0; g < pInst->nDrcChannelGroups; g++) {
+ int seq = pInst->gainSetIndexForChannelGroup[g];
+ if (seq != -1 && (hUniDrcConfig->drcCoefficientsUniDrcCount == 0 ||
+ seq >= pCoef->gainSetCount)) {
+ pActiveDrc->channelGroupIsParametricDrc[g] = 1;
+ } else {
+ pActiveDrc->channelGroupIsParametricDrc[g] = 0;
+ if (seq >= pCoef->gainSetCount) {
+ return DE_NOT_OK;
+ }
+ }
+ }
+
+ /* gainElementCount */
+ if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
+ for (g = 0; g < pInst->nDrcChannelGroups; g++) {
+ pActiveDrc->bandCountForChannelGroup[g] = 1;
+ }
+ pActiveDrc->gainElementCount =
+ pInst->nDrcChannelGroups; /* one gain element per channel group */
+ } else {
+ for (g = 0; g < pInst->nDrcChannelGroups; g++) {
+ if (pActiveDrc->channelGroupIsParametricDrc[g]) {
+ gainElementCount++;
+ pActiveDrc->bandCountForChannelGroup[g] = 1;
+ } else {
+ int seq, bandCount;
+ seq = pInst->gainSetIndexForChannelGroup[g];
+ bandCount = pCoef->gainSet[seq].bandCount;
+ pActiveDrc->bandCountForChannelGroup[g] = bandCount;
+ gainElementCount += bandCount;
+ }
+ }
+ pActiveDrc->gainElementCount = gainElementCount;
+ }
+
+ /* prepare gainElementForGroup (cumulated sum of bandCountForChannelGroup) */
+ pActiveDrc->gainElementForGroup[0] = 0;
+ for (g = 1; g < pInst->nDrcChannelGroups; g++) {
+ pActiveDrc->gainElementForGroup[g] =
+ pActiveDrc->gainElementForGroup[g - 1] +
+ pActiveDrc->bandCountForChannelGroup[g - 1]; /* index of first gain
+ sequence in channel
+ group */
+ }
+
+ return DE_OK;
+}
+
+DRC_ERROR
+initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
+ const int sampleRate) {
+ int i, j, k;
+
+ if (frameSize < 1) {
+ return DE_NOT_OK;
+ }
+
+ hGainDec->frameSize = frameSize;
+
+ if (hGainDec->frameSize * 1000 < sampleRate) {
+ return DE_NOT_OK;
+ }
+
+ hGainDec->deltaTminDefault = getDeltaTmin(sampleRate);
+ if (hGainDec->deltaTminDefault > hGainDec->frameSize) {
+ return DE_NOT_OK;
+ }
+
+ for (i = 0; i < MAX_ACTIVE_DRCS; i++) {
+ for (j = 0; j < 8; j++) {
+ /* use startup node at the beginning */
+ hGainDec->activeDrc[i].lnbIndexForChannel[j][0] = 0;
+ for (k = 1; k < NUM_LNB_FRAMES; k++) {
+ hGainDec->activeDrc[i].lnbIndexForChannel[j][k] = -1;
+ }
+ }
+ }
+
+ for (j = 0; j < 8; j++) {
+ hGainDec->channelGain[j] = FL2FXCONST_DBL(1.0f / (float)(1 << 8));
+ }
+
+ for (i = 0; i < 4 * 1024 / 256; i++) {
+ hGainDec->dummySubbandGains[i] = FL2FXCONST_DBL(1.0f / (float)(1 << 7));
+ }
+
+ hGainDec->status = 0; /* startup */
+
+ return DE_OK;
+}
+
+void initDrcGainBuffers(const int frameSize, DRC_GAIN_BUFFERS* drcGainBuffers) {
+ int i, c, j;
+ /* prepare 12 instances of node buffers */
+ for (i = 0; i < 12; i++) {
+ for (j = 0; j < NUM_LNB_FRAMES; j++) {
+ drcGainBuffers->linearNodeBuffer[i].nNodes[j] = 1;
+ drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].gainLin =
+ FL2FXCONST_DBL(1.0f / (float)(1 << 7));
+ if (j == 0) {
+ drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time =
+ 0; /* initialize last node with startup node */
+ } else {
+ drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time =
+ frameSize - 1;
+ }
+ }
+ }
+
+ /* prepare dummyLnb, a linearNodeBuffer containing a constant gain of 0 dB,
+ * for the "no DRC processing" case */
+ drcGainBuffers->dummyLnb.gainInterpolationType = GIT_LINEAR;
+ for (i = 0; i < NUM_LNB_FRAMES; i++) {
+ drcGainBuffers->dummyLnb.nNodes[i] = 1;
+ drcGainBuffers->dummyLnb.linearNode[i][0].gainLin =
+ FL2FXCONST_DBL(1.0f / (float)(1 << 7));
+ drcGainBuffers->dummyLnb.linearNode[i][0].time = frameSize - 1;
+ }
+
+ /* prepare channelGain delay line */
+ for (c = 0; c < 8; c++) {
+ for (i = 0; i < NUM_LNB_FRAMES; i++) {
+ drcGainBuffers->channelGain[c][i] =
+ FL2FXCONST_DBL(1.0f / (float)(1 << 8));
+ }
+ }
+
+ drcGainBuffers->lnbPointer = 0;
+}
+
+DRC_ERROR
+initActiveDrc(HANDLE_DRC_GAIN_DECODER hGainDec,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int drcSetIdSelected,
+ const int downmixIdSelected) {
+ int g, isMultiband = 0;
+ DRC_ERROR err = DE_OK;
+ DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;
+ DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
+
+ pInst = selectDrcInstructions(hUniDrcConfig, drcSetIdSelected);
+ if (pInst == NULL) {
+ return DE_NOT_OK;
+ }
+
+ if (pInst->drcSetId >= 0) {
+ pCoef = selectDrcCoefficients(hUniDrcConfig, pInst->drcLocation);
+ if (pCoef == NULL) {
+ return DE_NOT_OK;
+ }
+
+ if (pCoef->drcFrameSizePresent) {
+ if (pCoef->drcFrameSize != hGainDec->frameSize) {
+ return DE_NOT_OK;
+ }
+ }
+
+ err = _generateDrcInstructionsDerivedData(
+ hGainDec, hUniDrcConfig, pInst, pCoef,
+ &(hGainDec->activeDrc[hGainDec->nActiveDrcs]));
+ if (err) return err;
+ }
+
+ hGainDec->activeDrc[hGainDec->nActiveDrcs].pInst = pInst;
+ hGainDec->activeDrc[hGainDec->nActiveDrcs].pCoef = pCoef;
+
+ for (g = 0; g < pInst->nDrcChannelGroups; g++) {
+ if (hGainDec->activeDrc[hGainDec->nActiveDrcs].bandCountForChannelGroup[g] >
+ 1) {
+ if (hGainDec->multiBandActiveDrcIndex != -1) {
+ return DE_NOT_OK;
+ }
+ isMultiband = 1;
+ }
+ }
+
+ if (isMultiband) {
+ /* Keep activeDrc index of multiband DRC set */
+ hGainDec->multiBandActiveDrcIndex = hGainDec->nActiveDrcs;
+ }
+
+ if ((hGainDec->channelGainActiveDrcIndex == -1) &&
+ (downmixIdSelected == DOWNMIX_ID_BASE_LAYOUT) &&
+ (hUniDrcConfig->drcInstructionsUniDrcCount >
+ 0)) { /* use this activeDrc to apply channelGains */
+ hGainDec->channelGainActiveDrcIndex = hGainDec->nActiveDrcs;
+ }
+
+ hGainDec->nActiveDrcs++;
+ if (hGainDec->nActiveDrcs > MAX_ACTIVE_DRCS) return DE_NOT_OK;
+
+ return DE_OK;
+}
+
+DRC_ERROR
+initActiveDrcOffset(HANDLE_DRC_GAIN_DECODER hGainDec) {
+ int a, accGainElementCount;
+
+ accGainElementCount = 0;
+ for (a = 0; a < hGainDec->nActiveDrcs; a++) {
+ hGainDec->activeDrc[a].activeDrcOffset = accGainElementCount;
+ accGainElementCount += hGainDec->activeDrc[a].gainElementCount;
+ }
+
+ if (accGainElementCount > 12) return DE_NOT_OK;
+
+ return DE_OK;
+}
diff --git a/fdk-aac/libDRCdec/src/drcGainDec_init.h b/fdk-aac/libDRCdec/src/drcGainDec_init.h
new file mode 100644
index 0000000..9215bc3
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcGainDec_init.h
@@ -0,0 +1,120 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef DRCGAINDEC_INIT_H
+#define DRCGAINDEC_INIT_H
+
+DRC_ERROR
+initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
+ const int sampleRate);
+
+void initDrcGainBuffers(const int frameSize, DRC_GAIN_BUFFERS* drcGainBuffers);
+
+DRC_ERROR
+initActiveDrc(HANDLE_DRC_GAIN_DECODER hGainDec,
+ HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int drcSetIdSelected,
+ const int downmixIdSelected);
+
+DRC_ERROR
+initActiveDrcOffset(HANDLE_DRC_GAIN_DECODER hGainDec);
+
+#endif
diff --git a/fdk-aac/libDRCdec/src/drcGainDec_preprocess.cpp b/fdk-aac/libDRCdec/src/drcGainDec_preprocess.cpp
new file mode 100644
index 0000000..c543c53
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcGainDec_preprocess.cpp
@@ -0,0 +1,715 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "drcDec_types.h"
+#include "drcDec_gainDecoder.h"
+#include "drcGainDec_preprocess.h"
+#include "drcDec_tools.h"
+#include "FDK_matrixCalloc.h"
+#include "drcDec_rom.h"
+
+#define SLOPE_FACTOR_DB_TO_LINEAR \
+ FL2FXCONST_DBL(0.1151f * (float)(1 << 3)) /* ln(10) / 20 */
+
+typedef struct {
+ int drcSetEffect;
+ DUCKING_MODIFICATION* pDMod;
+ GAIN_MODIFICATION* pGMod;
+ int drcCharacteristicPresent;
+ CHARACTERISTIC_FORMAT characteristicFormatSource[2];
+ const CUSTOM_DRC_CHAR* pCCharSource[2];
+ CHARACTERISTIC_FORMAT characteristicFormatTarget[2];
+ const CUSTOM_DRC_CHAR* pCCharTarget[2];
+ int slopeIsNegative;
+ int limiterPeakTargetPresent;
+ FIXP_SGL limiterPeakTarget;
+ FIXP_DBL loudnessNormalizationGainDb;
+ FIXP_SGL compress;
+ FIXP_SGL boost;
+} NODE_MODIFICATION;
+
+static DRC_ERROR _getCicpCharacteristic(
+ const int cicpCharacteristic,
+ CHARACTERISTIC_FORMAT pCharacteristicFormat[2],
+ const CUSTOM_DRC_CHAR* pCCharSource[2]) {
+ if ((cicpCharacteristic < 1) || (cicpCharacteristic > 11)) {
+ return DE_NOT_OK;
+ }
+
+ if (cicpCharacteristic < 7) { /* sigmoid characteristic */
+ pCharacteristicFormat[CS_LEFT] = CF_SIGMOID;
+ pCCharSource[CS_LEFT] =
+ (const CUSTOM_DRC_CHAR*)(&cicpDrcCharSigmoidLeft[cicpCharacteristic -
+ 1]);
+ pCharacteristicFormat[CS_RIGHT] = CF_SIGMOID;
+ pCCharSource[CS_RIGHT] =
+ (const CUSTOM_DRC_CHAR*)(&cicpDrcCharSigmoidRight[cicpCharacteristic -
+ 1]);
+ } else { /* nodes characteristic */
+ pCharacteristicFormat[CS_LEFT] = CF_NODES;
+ pCCharSource[CS_LEFT] =
+ (const CUSTOM_DRC_CHAR*)(&cicpDrcCharNodesLeft[cicpCharacteristic - 7]);
+ pCharacteristicFormat[CS_RIGHT] = CF_NODES;
+ pCCharSource[CS_RIGHT] =
+ (const CUSTOM_DRC_CHAR*)(&cicpDrcCharNodesRight[cicpCharacteristic -
+ 7]);
+ }
+ return DE_OK;
+}
+
+static int _getSign(FIXP_SGL in) {
+ if (in > (FIXP_DBL)0) return 1;
+ if (in < (FIXP_DBL)0) return -1;
+ return 0;
+}
+
+static DRC_ERROR _getSlopeSign(const CHARACTERISTIC_FORMAT drcCharFormat,
+ const CUSTOM_DRC_CHAR* pCChar, int* pSlopeSign) {
+ if (drcCharFormat == CF_SIGMOID) {
+ *pSlopeSign = (pCChar->sigmoid.flipSign ? 1 : -1);
+ } else {
+ int k, slopeSign = 0, tmp_slopeSign;
+ for (k = 0; k < pCChar->nodes.characteristicNodeCount; k++) {
+ if (pCChar->nodes.nodeLevel[k + 1] > pCChar->nodes.nodeLevel[k]) {
+ tmp_slopeSign =
+ _getSign(pCChar->nodes.nodeGain[k + 1] - pCChar->nodes.nodeGain[k]);
+ } else {
+ tmp_slopeSign = -_getSign(pCChar->nodes.nodeGain[k + 1] -
+ pCChar->nodes.nodeGain[k]);
+ }
+ if ((slopeSign || tmp_slopeSign) && (slopeSign == -tmp_slopeSign))
+ return DE_NOT_OK; /* DRC characteristic is not invertible */
+ else
+ slopeSign = tmp_slopeSign;
+ }
+ *pSlopeSign = slopeSign;
+ }
+ return DE_OK;
+}
+
+static DRC_ERROR _isSlopeNegative(const CHARACTERISTIC_FORMAT drcCharFormat[2],
+ const CUSTOM_DRC_CHAR* pCChar[2],
+ int* pSlopeIsNegative) {
+ DRC_ERROR err = DE_OK;
+ int slopeSign[2] = {0, 0};
+
+ err = _getSlopeSign(drcCharFormat[CS_LEFT], pCChar[CS_LEFT],
+ &slopeSign[CS_LEFT]);
+ if (err) return err;
+
+ err = _getSlopeSign(drcCharFormat[CS_RIGHT], pCChar[CS_RIGHT],
+ &slopeSign[CS_RIGHT]);
+ if (err) return err;
+
+ if ((slopeSign[CS_LEFT] || slopeSign[CS_RIGHT]) &&
+ (slopeSign[CS_LEFT] == -slopeSign[CS_RIGHT]))
+ return DE_NOT_OK; /* DRC characteristic is not invertible */
+
+ *pSlopeIsNegative = (slopeSign[CS_LEFT] < 0);
+ return DE_OK;
+}
+
+static DRC_ERROR _prepareDrcCharacteristic(const DRC_CHARACTERISTIC* pDChar,
+ DRC_COEFFICIENTS_UNI_DRC* pCoef,
+ const int b,
+ NODE_MODIFICATION* pNodeMod) {
+ DRC_ERROR err = DE_OK;
+ pNodeMod->drcCharacteristicPresent = pDChar->present;
+ if (pNodeMod->drcCharacteristicPresent) {
+ if (pDChar->isCICP == 1) {
+ err = _getCicpCharacteristic(pDChar->cicpIndex,
+ pNodeMod->characteristicFormatSource,
+ pNodeMod->pCCharSource);
+ if (err) return err;
+ } else {
+ pNodeMod->characteristicFormatSource[CS_LEFT] =
+ (CHARACTERISTIC_FORMAT)
+ pCoef->characteristicLeftFormat[pDChar->custom.left];
+ pNodeMod->pCCharSource[CS_LEFT] =
+ &(pCoef->customCharacteristicLeft[pDChar->custom.left]);
+ pNodeMod->characteristicFormatSource[CS_RIGHT] =
+ (CHARACTERISTIC_FORMAT)
+ pCoef->characteristicRightFormat[pDChar->custom.right];
+ pNodeMod->pCCharSource[CS_RIGHT] =
+ &(pCoef->customCharacteristicRight[pDChar->custom.right]);
+ }
+ err = _isSlopeNegative(pNodeMod->characteristicFormatSource,
+ pNodeMod->pCCharSource, &pNodeMod->slopeIsNegative);
+ if (err) return err;
+
+ if (pNodeMod->pGMod != NULL) {
+ if (pNodeMod->pGMod[b].targetCharacteristicLeftPresent) {
+ pNodeMod->characteristicFormatTarget[CS_LEFT] =
+ (CHARACTERISTIC_FORMAT)pCoef->characteristicLeftFormat
+ [pNodeMod->pGMod[b].targetCharacteristicLeftIndex];
+ pNodeMod->pCCharTarget[CS_LEFT] =
+ &(pCoef->customCharacteristicLeft
+ [pNodeMod->pGMod[b].targetCharacteristicLeftIndex]);
+ }
+ if (pNodeMod->pGMod[b].targetCharacteristicRightPresent) {
+ pNodeMod->characteristicFormatTarget[CS_RIGHT] =
+ (CHARACTERISTIC_FORMAT)pCoef->characteristicRightFormat
+ [pNodeMod->pGMod[b].targetCharacteristicRightIndex];
+ pNodeMod->pCCharTarget[CS_RIGHT] =
+ &(pCoef->customCharacteristicRight
+ [pNodeMod->pGMod[b].targetCharacteristicRightIndex]);
+ }
+ }
+ }
+ return DE_OK;
+}
+
+static DRC_ERROR _compressorIO_sigmoid_common(
+ const FIXP_DBL tmp, /* e = 7 */
+ const FIXP_DBL gainDbLimit, /* e = 6 */
+ const FIXP_DBL exp, /* e = 5 */
+ const int inverse, FIXP_DBL* out) /* e = 7 */
+{
+ FIXP_DBL x, tmp1, tmp2, invExp, denom;
+ int e_x, e_tmp1, e_tmp2, e_invExp, e_denom, e_out;
+
+ if (exp < FL2FXCONST_DBL(1.0f / (float)(1 << 5))) {
+ return DE_NOT_OK;
+ }
+
+ /* x = tmp / gainDbLimit; */
+ x = fDivNormSigned(tmp, gainDbLimit, &e_x);
+ e_x += 7 - 6;
+ if (x < (FIXP_DBL)0) {
+ return DE_NOT_OK;
+ }
+
+ /* out = tmp / pow(1.0f +/- pow(x, exp), 1.0f/exp); */
+ tmp1 = fPow(x, e_x, exp, 5, &e_tmp1);
+ if (inverse) tmp1 = -tmp1;
+ tmp2 = fAddNorm(FL2FXCONST_DBL(1.0f / (float)(1 << 1)), 1, tmp1, e_tmp1,
+ &e_tmp2);
+ invExp = fDivNorm(FL2FXCONST_DBL(1.0f / (float)(1 << 1)), exp, &e_invExp);
+ e_invExp += 1 - 5;
+ denom = fPow(tmp2, e_tmp2, invExp, e_invExp, &e_denom);
+ *out = fDivNormSigned(tmp, denom, &e_out);
+ e_out += 7 - e_denom;
+ *out = scaleValueSaturate(*out, e_out - 7);
+ return DE_OK;
+}
+
+static DRC_ERROR _compressorIO_sigmoid(const CUSTOM_DRC_CHAR_SIGMOID* pCChar,
+ const FIXP_DBL inLevelDb, /* e = 7 */
+ FIXP_DBL* outGainDb) /* e = 7 */
+{
+ FIXP_DBL tmp;
+ FIXP_SGL exp = pCChar->exp;
+ DRC_ERROR err = DE_OK;
+
+ tmp = fMultDiv2((DRC_INPUT_LOUDNESS_TARGET >> 1) - (inLevelDb >> 1),
+ pCChar->ioRatio);
+ tmp = SATURATE_LEFT_SHIFT(tmp, 2 + 1 + 1, DFRACT_BITS);
+ if (exp < (FIXP_SGL)MAXVAL_SGL) {
+ /* x = tmp / gainDbLimit; */
+ /* *outGainDb = tmp / pow(1.0f + pow(x, exp), 1.0f/exp); */
+ err = _compressorIO_sigmoid_common(tmp, FX_SGL2FX_DBL(pCChar->gain),
+ FX_SGL2FX_DBL(exp), 0, outGainDb);
+ if (err) return err;
+ } else {
+ *outGainDb =
+ tmp; /* scaling of outGainDb (7) is equal to scaling of tmp (7) */
+ }
+ if (pCChar->flipSign == 1) {
+ *outGainDb = -*outGainDb;
+ }
+ return err;
+}
+
+static DRC_ERROR _compressorIO_sigmoid_inverse(
+ const CUSTOM_DRC_CHAR_SIGMOID* pCChar, const FIXP_SGL gainDb,
+ FIXP_DBL* inLev) {
+ DRC_ERROR err = DE_OK;
+ FIXP_SGL ioRatio = pCChar->ioRatio;
+ FIXP_SGL exp = pCChar->exp;
+ FIXP_DBL tmp = FX_SGL2FX_DBL(gainDb), tmp_out;
+ int e_out;
+
+ if (pCChar->flipSign == 1) {
+ tmp = -tmp;
+ }
+ if (exp < (FIXP_SGL)MAXVAL_SGL) {
+ /* x = tmp / gainDbLimit; */
+ /* tmp = tmp / pow(1.0f - pow(x, exp), 1.0f / exp); */
+ err = _compressorIO_sigmoid_common(tmp, FX_SGL2FX_DBL(pCChar->gain),
+ FX_SGL2FX_DBL(exp), 1, &tmp);
+ if (err) return err;
+ }
+ if (ioRatio == (FIXP_SGL)0) {
+ return DE_NOT_OK;
+ }
+ tmp_out = fDivNormSigned(tmp, FX_SGL2FX_DBL(ioRatio), &e_out);
+ e_out += 7 - 2;
+ tmp_out = fAddNorm(DRC_INPUT_LOUDNESS_TARGET, 7, -tmp_out, e_out, &e_out);
+ *inLev = scaleValueSaturate(tmp_out, e_out - 7);
+
+ return err;
+}
+
+static DRC_ERROR _compressorIO_nodes(const CUSTOM_DRC_CHAR_NODES* pCChar,
+ const FIXP_DBL inLevelDb, /* e = 7 */
+ FIXP_DBL* outGainDb) /* e = 7 */
+{
+ int n;
+ FIXP_DBL w;
+ const FIXP_SGL* nodeLevel = pCChar->nodeLevel;
+ const FIXP_SGL* nodeGain = pCChar->nodeGain;
+
+ if (inLevelDb < DRC_INPUT_LOUDNESS_TARGET) {
+ for (n = 0; n < pCChar->characteristicNodeCount; n++) {
+ if ((inLevelDb <= FX_SGL2FX_DBL(nodeLevel[n])) &&
+ (inLevelDb > FX_SGL2FX_DBL(nodeLevel[n + 1]))) {
+ w = fDivNorm(inLevelDb - FX_SGL2FX_DBL(nodeLevel[n + 1]),
+ FX_SGL2FX_DBL(nodeLevel[n] - nodeLevel[n + 1]));
+ *outGainDb = fMult(w, nodeGain[n]) +
+ fMult((FIXP_DBL)MAXVAL_DBL - w, nodeGain[n + 1]);
+ /* *outGainDb = (w * nodeGain[n] + (1.0-w) * nodeGain[n+1]); */
+ return DE_OK;
+ }
+ }
+ } else {
+ for (n = 0; n < pCChar->characteristicNodeCount; n++) {
+ if ((inLevelDb >= FX_SGL2FX_DBL(nodeLevel[n])) &&
+ (inLevelDb < FX_SGL2FX_DBL(nodeLevel[n + 1]))) {
+ w = fDivNorm(FX_SGL2FX_DBL(nodeLevel[n + 1]) - inLevelDb,
+ FX_SGL2FX_DBL(nodeLevel[n + 1] - nodeLevel[n]));
+ *outGainDb = fMult(w, nodeGain[n]) +
+ fMult((FIXP_DBL)MAXVAL_DBL - w, nodeGain[n + 1]);
+ /* *outGainDb = (w * nodeGain[n] + (1.0-w) * nodeGain[n+1]); */
+ return DE_OK;
+ }
+ }
+ }
+ *outGainDb = FX_SGL2FX_DBL(nodeGain[pCChar->characteristicNodeCount]);
+ return DE_OK;
+}
+
+static DRC_ERROR _compressorIO_nodes_inverse(
+ const CUSTOM_DRC_CHAR_NODES* pCChar, const FIXP_SGL gainDb, /* e = 7 */
+ FIXP_DBL* inLev) /* e = 7 */
+{
+ int n;
+ int k;
+ FIXP_DBL w;
+ int gainIsNegative = 0;
+ const FIXP_SGL* nodeLevel = pCChar->nodeLevel;
+ const FIXP_SGL* nodeGain = pCChar->nodeGain;
+ int nodeCount = pCChar->characteristicNodeCount;
+ for (k = 0; k < nodeCount; k++) {
+ if (pCChar->nodeGain[k + 1] < (FIXP_SGL)0) {
+ gainIsNegative = 1;
+ }
+ }
+ if (gainIsNegative == 1) {
+ if (gainDb <= nodeGain[nodeCount]) {
+ *inLev = FX_SGL2FX_DBL(nodeLevel[nodeCount]);
+ } else {
+ if (gainDb >= (FIXP_SGL)0) {
+ *inLev = DRC_INPUT_LOUDNESS_TARGET;
+ } else {
+ for (n = 0; n < nodeCount; n++) {
+ if ((gainDb <= nodeGain[n]) && (gainDb > nodeGain[n + 1])) {
+ FIXP_SGL gainDelta = nodeGain[n] - nodeGain[n + 1];
+ if (gainDelta == (FIXP_SGL)0) {
+ *inLev = FX_SGL2FX_DBL(nodeLevel[n]);
+ return DE_OK;
+ }
+ w = fDivNorm(gainDb - nodeGain[n + 1], gainDelta);
+ *inLev = fMult(w, nodeLevel[n]) +
+ fMult((FIXP_DBL)MAXVAL_DBL - w, nodeLevel[n + 1]);
+ /* *inLev = (w * nodeLevel[n] + (1.0-w) * nodeLevel[n+1]); */
+ return DE_OK;
+ }
+ }
+ *inLev = FX_SGL2FX_DBL(nodeLevel[nodeCount]);
+ }
+ }
+ } else {
+ if (gainDb >= nodeGain[nodeCount]) {
+ *inLev = FX_SGL2FX_DBL(nodeLevel[nodeCount]);
+ } else {
+ if (gainDb <= (FIXP_SGL)0) {
+ *inLev = DRC_INPUT_LOUDNESS_TARGET;
+ } else {
+ for (n = 0; n < nodeCount; n++) {
+ if ((gainDb >= nodeGain[n]) && (gainDb < nodeGain[n + 1])) {
+ FIXP_SGL gainDelta = nodeGain[n + 1] - nodeGain[n];
+ if (gainDelta == (FIXP_SGL)0) {
+ *inLev = FX_SGL2FX_DBL(nodeLevel[n]);
+ return DE_OK;
+ }
+ w = fDivNorm(nodeGain[n + 1] - gainDb, gainDelta);
+ *inLev = fMult(w, nodeLevel[n]) +
+ fMult((FIXP_DBL)MAXVAL_DBL - w, nodeLevel[n + 1]);
+ /* *inLev = (w * nodeLevel[n] + (1.0-w) * nodeLevel[n+1]); */
+ return DE_OK;
+ }
+ }
+ *inLev = FX_SGL2FX_DBL(nodeLevel[nodeCount]);
+ }
+ }
+ }
+ return DE_OK;
+}
+
+static DRC_ERROR _mapGain(const CHARACTERISTIC_FORMAT pCCharFormatSource,
+ const CUSTOM_DRC_CHAR* pCCharSource,
+ const CHARACTERISTIC_FORMAT pCCharFormatTarget,
+ const CUSTOM_DRC_CHAR* pCCharTarget,
+ const FIXP_SGL gainInDb, /* e = 7 */
+ FIXP_DBL* gainOutDb) /* e = 7 */
+{
+ FIXP_DBL inLevel = (FIXP_DBL)0;
+ DRC_ERROR err = DE_OK;
+
+ switch (pCCharFormatSource) {
+ case CF_SIGMOID:
+ err = _compressorIO_sigmoid_inverse(
+ (const CUSTOM_DRC_CHAR_SIGMOID*)pCCharSource, gainInDb, &inLevel);
+ if (err) return err;
+ break;
+ case CF_NODES:
+ err = _compressorIO_nodes_inverse(
+ (const CUSTOM_DRC_CHAR_NODES*)pCCharSource, gainInDb, &inLevel);
+ if (err) return err;
+ break;
+ default:
+ return DE_NOT_OK;
+ }
+ switch (pCCharFormatTarget) {
+ case CF_SIGMOID:
+ err = _compressorIO_sigmoid((const CUSTOM_DRC_CHAR_SIGMOID*)pCCharTarget,
+ inLevel, gainOutDb);
+ if (err) return err;
+ break;
+ case CF_NODES:
+ err = _compressorIO_nodes((const CUSTOM_DRC_CHAR_NODES*)pCCharTarget,
+ inLevel, gainOutDb);
+ if (err) return err;
+ break;
+ default:
+ break;
+ }
+ return DE_OK;
+}
+
+static DRC_ERROR _toLinear(
+ const NODE_MODIFICATION* nodeMod, const int drcBand,
+ const FIXP_SGL gainDb, /* in: gain value in dB, e = 7 */
+ const FIXP_SGL slopeDb, /* in: slope value in dB/deltaTmin, e = 2 */
+ FIXP_DBL* gainLin, /* out: linear gain value, e = 7 */
+ FIXP_DBL* slopeLin) /* out: linear slope value, e = 7 */
+{
+ FIXP_DBL gainRatio_m = FL2FXCONST_DBL(1.0f / (float)(1 << 1));
+ GAIN_MODIFICATION* pGMod = NULL;
+ DUCKING_MODIFICATION* pDMod = nodeMod->pDMod;
+ FIXP_DBL tmp_dbl, gainDb_modified, gainDb_offset, gainDb_out, gainLin_m,
+ slopeLin_m;
+ int gainLin_e, gainRatio_e = 1, gainDb_out_e;
+ if (nodeMod->pGMod != NULL) {
+ pGMod = &(nodeMod->pGMod[drcBand]);
+ }
+ if (((nodeMod->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) == 0) &&
+ (nodeMod->drcSetEffect != EB_FADE) &&
+ (nodeMod->drcSetEffect != EB_CLIPPING)) {
+ DRC_ERROR err = DE_OK;
+ FIXP_DBL gainDbMapped;
+
+ if ((pGMod != NULL) && (nodeMod->drcCharacteristicPresent)) {
+ if (((gainDb > (FIXP_SGL)0) && nodeMod->slopeIsNegative) ||
+ ((gainDb < (FIXP_SGL)0) && !nodeMod->slopeIsNegative)) {
+ /* left side */
+ if (pGMod->targetCharacteristicLeftPresent == 1) {
+ err = _mapGain(nodeMod->characteristicFormatSource[CS_LEFT],
+ nodeMod->pCCharSource[CS_LEFT],
+ nodeMod->characteristicFormatTarget[CS_LEFT],
+ nodeMod->pCCharTarget[CS_LEFT], gainDb, &gainDbMapped);
+ if (err) return err;
+ gainRatio_m = fDivNormSigned(
+ gainDbMapped, FX_SGL2FX_DBL(gainDb),
+ &gainRatio_e); /* target characteristic in payload */
+ }
+ }
+
+ else { /* if (((gainDb < (FIXP_SGL)0) && nodeMod->slopeIsNegative) ||
+ ((gainDb > (FIXP_SGL)0) && !nodeMod->slopeIsNegative)) */
+
+ /* right side */
+ if (pGMod->targetCharacteristicRightPresent == 1) {
+ err =
+ _mapGain(nodeMod->characteristicFormatSource[CS_RIGHT],
+ nodeMod->pCCharSource[CS_RIGHT],
+ nodeMod->characteristicFormatTarget[CS_RIGHT],
+ nodeMod->pCCharTarget[CS_RIGHT], gainDb, &gainDbMapped);
+ if (err) return err;
+ gainRatio_m = fDivNormSigned(
+ gainDbMapped, FX_SGL2FX_DBL(gainDb),
+ &gainRatio_e); /* target characteristic in payload */
+ }
+ }
+ }
+ if (gainDb < (FIXP_SGL)0) {
+ gainRatio_m = fMultDiv2(gainRatio_m, nodeMod->compress);
+ } else {
+ gainRatio_m = fMultDiv2(gainRatio_m, nodeMod->boost);
+ }
+ gainRatio_e += 2;
+ }
+ if ((pGMod != NULL) && (pGMod->gainScalingPresent == 1)) {
+ if (gainDb < (FIXP_SGL)0) {
+ gainRatio_m = fMultDiv2(gainRatio_m, pGMod->attenuationScaling);
+ } else {
+ gainRatio_m = fMultDiv2(gainRatio_m, pGMod->amplificationScaling);
+ }
+ gainRatio_e += 3;
+ }
+ if ((pDMod != NULL) &&
+ (nodeMod->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) &&
+ (pDMod->duckingScalingPresent == 1)) {
+ gainRatio_m = fMultDiv2(gainRatio_m, pDMod->duckingScaling);
+ gainRatio_e += 3;
+ }
+
+ gainDb_modified =
+ fMultDiv2(gainDb, gainRatio_m); /* resulting e: 7 + gainRatio_e + 1*/
+ gainDb_offset = (FIXP_DBL)0;
+
+ if ((pGMod != NULL) && (pGMod->gainOffsetPresent == 1)) {
+ /* *gainLin *= (float)pow(2.0, (double)(pGMod->gainOffset/6.0f)); */
+ gainDb_offset += FX_SGL2FX_DBL(pGMod->gainOffset) >> 4; /* resulting e: 8 */
+ }
+ if ((nodeMod->limiterPeakTargetPresent == 1) &&
+ (nodeMod->drcSetEffect ==
+ EB_CLIPPING)) { /* The only drcSetEffect is "clipping prevention" */
+ /* loudnessNormalizationGainModificationDb is included in
+ * loudnessNormalizationGainDb */
+ /* *gainLin *= (float)pow(2.0, max(0.0, -nodeModification->limiterPeakTarget
+ * - nodeModification->loudnessNormalizationGainDb)/6.0); */
+ gainDb_offset += fMax(
+ (FIXP_DBL)0,
+ (FX_SGL2FX_DBL(-nodeMod->limiterPeakTarget) >> 3) -
+ (nodeMod->loudnessNormalizationGainDb >> 1)); /* resulting e: 8 */
+ }
+ if (gainDb_offset != (FIXP_DBL)0) {
+ gainDb_out = fAddNorm(gainDb_modified, 7 + gainRatio_e + 1, gainDb_offset,
+ 8, &gainDb_out_e);
+ } else {
+ gainDb_out = gainDb_modified;
+ gainDb_out_e = 7 + gainRatio_e + 1;
+ }
+
+ /* *gainLin = (float)pow(2.0, (double)(gainDb_modified[1] / 6.0f)); */
+ gainLin_m = approxDb2lin(gainDb_out, gainDb_out_e, &gainLin_e);
+ *gainLin = scaleValueSaturate(gainLin_m, gainLin_e - 7);
+
+ /* *slopeLin = SLOPE_FACTOR_DB_TO_LINEAR * gainRatio * *gainLin * slopeDb; */
+ if (slopeDb == (FIXP_SGL)0) {
+ *slopeLin = (FIXP_DBL)0;
+ } else {
+ tmp_dbl =
+ fMult(slopeDb, SLOPE_FACTOR_DB_TO_LINEAR); /* resulting e: 2 - 3 = -1 */
+ tmp_dbl = fMult(tmp_dbl, gainRatio_m); /* resulting e: -1 + gainRatio_e */
+ if (gainDb_offset !=
+ (FIXP_DBL)0) { /* recalculate gainLin from gainDb that wasn't modified
+ by gainOffset and limiterPeakTarget */
+ gainLin_m = approxDb2lin(gainDb_modified, 7 + gainRatio_e, &gainLin_e);
+ }
+ slopeLin_m = fMult(tmp_dbl, gainLin_m);
+ *slopeLin =
+ scaleValueSaturate(slopeLin_m, -1 + gainRatio_e + gainLin_e - 7);
+ }
+
+ if ((nodeMod->limiterPeakTargetPresent == 1) &&
+ (nodeMod->drcSetEffect == EB_CLIPPING)) {
+ if (*gainLin >= FL2FXCONST_DBL(1.0f / (float)(1 << 7))) {
+ *gainLin = FL2FXCONST_DBL(1.0f / (float)(1 << 7));
+ *slopeLin = (FIXP_DBL)0;
+ }
+ }
+
+ return DE_OK;
+}
+
+/* prepare buffers containing linear nodes for each gain sequence */
+DRC_ERROR
+prepareDrcGain(HANDLE_DRC_GAIN_DECODER hGainDec,
+ HANDLE_UNI_DRC_GAIN hUniDrcGain, const FIXP_SGL compress,
+ const FIXP_SGL boost, const FIXP_DBL loudnessNormalizationGainDb,
+ const int activeDrcIndex) {
+ int b, g, gainElementIndex;
+ DRC_GAIN_BUFFERS* drcGainBuffers = &(hGainDec->drcGainBuffers);
+ NODE_MODIFICATION nodeMod;
+ FDKmemclear(&nodeMod, sizeof(NODE_MODIFICATION));
+ ACTIVE_DRC* pActiveDrc = &(hGainDec->activeDrc[activeDrcIndex]);
+ DRC_INSTRUCTIONS_UNI_DRC* pInst = pActiveDrc->pInst;
+ if (pInst == NULL) return DE_NOT_OK;
+
+ nodeMod.drcSetEffect = pInst->drcSetEffect;
+
+ nodeMod.compress = compress;
+ nodeMod.boost = boost;
+ nodeMod.loudnessNormalizationGainDb = loudnessNormalizationGainDb;
+ nodeMod.limiterPeakTargetPresent = pInst->limiterPeakTargetPresent;
+ nodeMod.limiterPeakTarget = pInst->limiterPeakTarget;
+
+ gainElementIndex = 0;
+ for (g = 0; g < pInst->nDrcChannelGroups; g++) {
+ int gainSetIndex = 0;
+ int nDrcBands = 0;
+ DRC_COEFFICIENTS_UNI_DRC* pCoef = pActiveDrc->pCoef;
+ if (pCoef == NULL) return DE_NOT_OK;
+
+ if (!pActiveDrc->channelGroupIsParametricDrc[g]) {
+ gainSetIndex = pInst->gainSetIndexForChannelGroup[g];
+
+ if (nodeMod.drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
+ nodeMod.pDMod = &(pActiveDrc->duckingModificationForChannelGroup[g]);
+ nodeMod.pGMod = NULL;
+ } else {
+ nodeMod.pGMod = pInst->gainModificationForChannelGroup[g];
+ nodeMod.pDMod = NULL;
+ }
+
+ nDrcBands = pActiveDrc->bandCountForChannelGroup[g];
+ for (b = 0; b < nDrcBands; b++) {
+ DRC_ERROR err = DE_OK;
+ GAIN_SET* pGainSet = &(pCoef->gainSet[gainSetIndex]);
+ int seq = pGainSet->gainSequenceIndex[b];
+ DRC_CHARACTERISTIC* pDChar = &(pGainSet->drcCharacteristic[b]);
+
+ /* linearNodeBuffer contains a copy of the gain sequences (consisting of
+ nodes) that are relevant for decoding. It also contains gain
+ sequences of previous frames. */
+ LINEAR_NODE_BUFFER* pLnb =
+ &(drcGainBuffers->linearNodeBuffer[pActiveDrc->activeDrcOffset +
+ gainElementIndex]);
+ int i, lnbp;
+ lnbp = drcGainBuffers->lnbPointer;
+ pLnb->gainInterpolationType =
+ (GAIN_INTERPOLATION_TYPE)pGainSet->gainInterpolationType;
+
+ err = _prepareDrcCharacteristic(pDChar, pCoef, b, &nodeMod);
+ if (err) return err;
+
+ /* copy a node buffer and convert from dB to linear */
+ pLnb->nNodes[lnbp] = fMin((int)hUniDrcGain->nNodes[seq], 16);
+ for (i = 0; i < pLnb->nNodes[lnbp]; i++) {
+ FIXP_DBL gainLin, slopeLin;
+ err = _toLinear(&nodeMod, b, hUniDrcGain->gainNode[seq][i].gainDb,
+ (FIXP_SGL)0, &gainLin, &slopeLin);
+ if (err) return err;
+ pLnb->linearNode[lnbp][i].gainLin = gainLin;
+ pLnb->linearNode[lnbp][i].time = hUniDrcGain->gainNode[seq][i].time;
+ }
+ gainElementIndex++;
+ }
+ } else {
+ /* parametric DRC not supported */
+ gainElementIndex++;
+ }
+ }
+ return DE_OK;
+}
diff --git a/fdk-aac/libDRCdec/src/drcGainDec_preprocess.h b/fdk-aac/libDRCdec/src/drcGainDec_preprocess.h
new file mode 100644
index 0000000..4647407
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcGainDec_preprocess.h
@@ -0,0 +1,111 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef DRCGAINDEC_PREPROCESS_H
+#define DRCGAINDEC_PREPROCESS_H
+
+DRC_ERROR
+prepareDrcGain(HANDLE_DRC_GAIN_DECODER hGainDec,
+ HANDLE_UNI_DRC_GAIN hUniDrcGain, const FIXP_SGL compress,
+ const FIXP_SGL boost, const FIXP_DBL loudnessNormalizationGainDb,
+ const int activeDrcIndex);
+#endif
diff --git a/fdk-aac/libDRCdec/src/drcGainDec_process.cpp b/fdk-aac/libDRCdec/src/drcGainDec_process.cpp
new file mode 100644
index 0000000..70c9533
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcGainDec_process.cpp
@@ -0,0 +1,532 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "drcDec_types.h"
+#include "drcDec_gainDecoder.h"
+#include "drcGainDec_process.h"
+
+#define E_TGAINSTEP 12
+
+static DRC_ERROR _prepareLnbIndex(ACTIVE_DRC* pActiveDrc,
+ const int channelOffset,
+ const int drcChannelOffset,
+ const int numChannelsProcessed,
+ const int lnbPointer) {
+ int g, c;
+ DRC_INSTRUCTIONS_UNI_DRC* pInst = pActiveDrc->pInst;
+
+ /* channelOffset: start index of physical channels
+ numChannelsProcessed: number of processed channels, physical channels and
+ DRC channels channelOffset + drcChannelOffset: start index of DRC channels,
+ i.e. the channel order referenced in pInst.sequenceIndex */
+
+ /* sanity checks */
+ if ((channelOffset + numChannelsProcessed) > 8) return DE_NOT_OK;
+
+ if ((channelOffset + drcChannelOffset + numChannelsProcessed) > 8)
+ return DE_NOT_OK;
+
+ if ((channelOffset + drcChannelOffset) < 0) return DE_NOT_OK;
+
+ /* prepare lnbIndexForChannel, a map of indices from each channel to its
+ * corresponding linearNodeBuffer instance */
+ for (c = channelOffset; c < channelOffset + numChannelsProcessed; c++) {
+ if (pInst->drcSetId > 0) {
+ int drcChannel = c + drcChannelOffset;
+ /* fallback for configuration with more physical channels than DRC
+ channels: reuse DRC gain of first channel. This is necessary for HE-AAC
+ mono with stereo output */
+ if (drcChannel >= pInst->drcChannelCount) drcChannel = 0;
+ g = pActiveDrc->channelGroupForChannel[drcChannel];
+ if ((g >= 0) && !pActiveDrc->channelGroupIsParametricDrc[g]) {
+ pActiveDrc->lnbIndexForChannel[c][lnbPointer] =
+ pActiveDrc->activeDrcOffset + pActiveDrc->gainElementForGroup[g];
+ }
+ }
+ }
+
+ return DE_OK;
+}
+
+static DRC_ERROR _interpolateDrcGain(
+ const GAIN_INTERPOLATION_TYPE gainInterpolationType,
+ const SHORT timePrev, /* time0 */
+ const SHORT tGainStep, /* time1 - time0 */
+ const SHORT start, const SHORT stop, const SHORT stepsize,
+ const FIXP_DBL gainLeft, const FIXP_DBL gainRight, const FIXP_DBL slopeLeft,
+ const FIXP_DBL slopeRight, FIXP_DBL* buffer) {
+ int n, n_buf;
+ int start_modulo, start_offset;
+
+ if (tGainStep < 0) {
+ return DE_NOT_OK;
+ }
+ if (tGainStep == 0) {
+ return DE_OK;
+ }
+
+ /* get start index offset and buffer index for downsampled interpolation */
+ /* start_modulo = (start+timePrev)%stepsize; */ /* stepsize is a power of 2 */
+ start_modulo = (start + timePrev) & (stepsize - 1);
+ start_offset = (start_modulo ? stepsize - start_modulo : 0);
+ /* n_buf = (start + timePrev + start_offset)/stepsize; */
+ n_buf = (start + timePrev + start_offset) >> (15 - fixnormz_S(stepsize));
+
+ { /* gainInterpolationType == GIT_LINEAR */
+ LONG a;
+ /* runs = ceil((stop - start - start_offset)/stepsize). This works for
+ * stepsize = 2^N only. */
+ INT runs = (INT)(stop - start - start_offset + stepsize - 1) >>
+ (30 - CountLeadingBits(stepsize));
+ INT n_min = fMin(
+ fMin(CntLeadingZeros(gainRight), CntLeadingZeros(gainLeft)) - 1, 8);
+ a = (LONG)((gainRight << n_min) - (gainLeft << n_min)) / tGainStep;
+ LONG a_step = a * stepsize;
+ n = start + start_offset;
+ a = a * n + (LONG)(gainLeft << n_min);
+ buffer += n_buf;
+#if defined(FUNCTION_interpolateDrcGain_func1)
+ interpolateDrcGain_func1(buffer, a, a_step, n_min, runs);
+#else
+ a -= a_step;
+ n_min = 8 - n_min;
+ for (int i = 0; i < runs; i++) {
+ a += a_step;
+ buffer[i] = fMultDiv2(buffer[i], (FIXP_DBL)a) << n_min;
+ }
+#endif /* defined(FUNCTION_interpolateDrcGain_func1) */
+ }
+ return DE_OK;
+}
+
+static DRC_ERROR _processNodeSegments(
+ const int frameSize, const GAIN_INTERPOLATION_TYPE gainInterpolationType,
+ const int nNodes, const NODE_LIN* pNodeLin, const int offset,
+ const SHORT stepsize,
+ const NODE_LIN nodePrevious, /* the last node of the previous frame */
+ const FIXP_DBL channelGain, FIXP_DBL* buffer) {
+ DRC_ERROR err = DE_OK;
+ SHORT timePrev, duration, start, stop, time;
+ int n;
+ FIXP_DBL gainLin = FL2FXCONST_DBL(1.0f / (float)(1 << 7)), gainLinPrev;
+ FIXP_DBL slopeLin = (FIXP_DBL)0, slopeLinPrev = (FIXP_DBL)0;
+
+ timePrev = nodePrevious.time + offset;
+ gainLinPrev = nodePrevious.gainLin;
+ for (n = 0; n < nNodes; n++) {
+ time = pNodeLin[n].time + offset;
+ duration = time - timePrev;
+ gainLin = pNodeLin[n].gainLin;
+ if (channelGain != FL2FXCONST_DBL(1.0f / (float)(1 << 8)))
+ gainLin =
+ SATURATE_LEFT_SHIFT(fMultDiv2(gainLin, channelGain), 9, DFRACT_BITS);
+
+ if ((timePrev >= (frameSize - 1)) ||
+ (time < 0)) { /* This segment (between previous and current node) lies
+ outside of this audio frame */
+ timePrev = time;
+ gainLinPrev = gainLin;
+ slopeLinPrev = slopeLin;
+ continue;
+ }
+
+ /* start and stop are the boundaries of the region of this segment that lie
+ within this audio frame. Their values are relative to the beginning of
+ this segment. stop is the first sample that isn't processed any more. */
+ start = fMax(-timePrev, 1);
+ stop = fMin(time, (SHORT)(frameSize - 1)) - timePrev + 1;
+
+ err = _interpolateDrcGain(gainInterpolationType, timePrev, duration, start,
+ stop, stepsize, gainLinPrev, gainLin,
+ slopeLinPrev, slopeLin, buffer);
+ if (err) return err;
+
+ timePrev = time;
+ gainLinPrev = gainLin;
+ }
+ return err;
+}
+
+/* process DRC on time-domain signal */
+DRC_ERROR
+processDrcTime(HANDLE_DRC_GAIN_DECODER hGainDec, const int activeDrcIndex,
+ const int delaySamples, const int channelOffset,
+ const int drcChannelOffset, const int numChannelsProcessed,
+ const int timeDataChannelOffset, FIXP_DBL* deinterleavedAudio) {
+ DRC_ERROR err = DE_OK;
+ int c, b, i;
+ ACTIVE_DRC* pActiveDrc = &(hGainDec->activeDrc[activeDrcIndex]);
+ DRC_GAIN_BUFFERS* pDrcGainBuffers = &(hGainDec->drcGainBuffers);
+ int lnbPointer = pDrcGainBuffers->lnbPointer, lnbIx;
+ LINEAR_NODE_BUFFER* pLinearNodeBuffer = pDrcGainBuffers->linearNodeBuffer;
+ LINEAR_NODE_BUFFER* pDummyLnb = &(pDrcGainBuffers->dummyLnb);
+ int offset = 0;
+
+ if (hGainDec->delayMode == DM_REGULAR_DELAY) {
+ offset = hGainDec->frameSize;
+ }
+
+ if ((delaySamples + offset) >
+ (NUM_LNB_FRAMES - 2) *
+ hGainDec->frameSize) /* if delaySamples is too big, NUM_LNB_FRAMES
+ should be increased */
+ return DE_NOT_OK;
+
+ err = _prepareLnbIndex(pActiveDrc, channelOffset, drcChannelOffset,
+ numChannelsProcessed, lnbPointer);
+ if (err) return err;
+
+ deinterleavedAudio +=
+ channelOffset * timeDataChannelOffset; /* apply channelOffset */
+
+ /* signal processing loop */
+ for (c = channelOffset; c < channelOffset + numChannelsProcessed; c++) {
+ if (activeDrcIndex == hGainDec->channelGainActiveDrcIndex)
+ pDrcGainBuffers->channelGain[c][lnbPointer] = hGainDec->channelGain[c];
+
+ b = 0;
+ {
+ LINEAR_NODE_BUFFER *pLnb, *pLnbPrevious;
+ NODE_LIN nodePrevious;
+ int lnbPointerDiff;
+ FIXP_DBL channelGain;
+ /* get pointer to oldest linearNodes */
+ lnbIx = lnbPointer + 1 - NUM_LNB_FRAMES;
+ while (lnbIx < 0) lnbIx += NUM_LNB_FRAMES;
+
+ if (activeDrcIndex == hGainDec->channelGainActiveDrcIndex)
+ channelGain = pDrcGainBuffers->channelGain[c][lnbIx];
+ else
+ channelGain = FL2FXCONST_DBL(1.0f / (float)(1 << 8));
+
+ /* Loop over all node buffers in linearNodeBuffer.
+ All nodes which are not relevant for the current frame are sorted out
+ inside _processNodeSegments. */
+ for (i = 0; i < NUM_LNB_FRAMES - 1; i++) {
+ /* Prepare previous node */
+ if (pActiveDrc->lnbIndexForChannel[c][lnbIx] >= 0)
+ pLnbPrevious = &(
+ pLinearNodeBuffer[pActiveDrc->lnbIndexForChannel[c][lnbIx] + b]);
+ else
+ pLnbPrevious = pDummyLnb;
+ nodePrevious =
+ pLnbPrevious->linearNode[lnbIx][pLnbPrevious->nNodes[lnbIx] - 1];
+ nodePrevious.time -= hGainDec->frameSize;
+ if (channelGain != FL2FXCONST_DBL(1.0f / (float)(1 << 8)))
+ nodePrevious.gainLin = SATURATE_LEFT_SHIFT(
+ fMultDiv2(nodePrevious.gainLin,
+ pDrcGainBuffers->channelGain[c][lnbIx]),
+ 9, DFRACT_BITS);
+
+ /* Prepare current linearNodeBuffer instance */
+ lnbIx++;
+ if (lnbIx >= NUM_LNB_FRAMES) lnbIx = 0;
+
+ /* if lnbIndexForChannel changes over time, use the old indices for
+ * smooth transitions */
+ if (pActiveDrc->lnbIndexForChannel[c][lnbIx] >= 0)
+ pLnb = &(
+ pLinearNodeBuffer[pActiveDrc->lnbIndexForChannel[c][lnbIx] + b]);
+ else /* lnbIndexForChannel = -1 means "no DRC processing", due to
+ drcInstructionsIndex < 0, drcSetId < 0 or channel group < 0 */
+ pLnb = pDummyLnb;
+
+ if (activeDrcIndex == hGainDec->channelGainActiveDrcIndex)
+ channelGain = pDrcGainBuffers->channelGain[c][lnbIx];
+
+ /* number of frames of offset with respect to lnbPointer */
+ lnbPointerDiff = i - (NUM_LNB_FRAMES - 2);
+
+ err = _processNodeSegments(
+ hGainDec->frameSize, pLnb->gainInterpolationType,
+ pLnb->nNodes[lnbIx], pLnb->linearNode[lnbIx],
+ lnbPointerDiff * hGainDec->frameSize + delaySamples + offset, 1,
+ nodePrevious, channelGain, deinterleavedAudio);
+ if (err) return err;
+ }
+ deinterleavedAudio += timeDataChannelOffset; /* proceed to next channel */
+ }
+ }
+ return DE_OK;
+}
+
+/* process DRC on subband-domain signal */
+DRC_ERROR
+processDrcSubband(HANDLE_DRC_GAIN_DECODER hGainDec, const int activeDrcIndex,
+ const int delaySamples, const int channelOffset,
+ const int drcChannelOffset, const int numChannelsProcessed,
+ const int processSingleTimeslot,
+ FIXP_DBL* deinterleavedAudioReal[],
+ FIXP_DBL* deinterleavedAudioImag[]) {
+ DRC_ERROR err = DE_OK;
+ int b, c, g, m, m_start, m_stop, s, i;
+ FIXP_DBL gainSb;
+ DRC_INSTRUCTIONS_UNI_DRC* pInst = hGainDec->activeDrc[activeDrcIndex].pInst;
+ DRC_GAIN_BUFFERS* pDrcGainBuffers = &(hGainDec->drcGainBuffers);
+ ACTIVE_DRC* pActiveDrc = &(hGainDec->activeDrc[activeDrcIndex]);
+ int activeDrcOffset = pActiveDrc->activeDrcOffset;
+ int lnbPointer = pDrcGainBuffers->lnbPointer, lnbIx;
+ LINEAR_NODE_BUFFER* pLinearNodeBuffer = pDrcGainBuffers->linearNodeBuffer;
+ FIXP_DBL(*subbandGains)[4 * 1024 / 256] = hGainDec->subbandGains;
+ FIXP_DBL* dummySubbandGains = hGainDec->dummySubbandGains;
+ SUBBAND_DOMAIN_MODE subbandDomainMode = hGainDec->subbandDomainSupported;
+ int signalIndex = 0;
+ int frameSizeSb = 0;
+ int nDecoderSubbands;
+ SHORT L = 0; /* L: downsampling factor */
+ int offset = 0;
+ FIXP_DBL *audioReal = NULL, *audioImag = NULL;
+
+ if (hGainDec->delayMode == DM_REGULAR_DELAY) {
+ offset = hGainDec->frameSize;
+ }
+
+ if ((delaySamples + offset) >
+ (NUM_LNB_FRAMES - 2) *
+ hGainDec->frameSize) /* if delaySamples is too big, NUM_LNB_FRAMES
+ should be increased */
+ return DE_NOT_OK;
+
+ switch (subbandDomainMode) {
+#if ((1024 / 256) >= (4096 / SUBBAND_DOWNSAMPLING_FACTOR_QMF64))
+ case SDM_QMF64:
+ nDecoderSubbands = SUBBAND_NUM_BANDS_QMF64;
+ L = SUBBAND_DOWNSAMPLING_FACTOR_QMF64;
+ /* analysisDelay = SUBBAND_ANALYSIS_DELAY_QMF64; */
+ break;
+ case SDM_QMF71:
+ nDecoderSubbands = SUBBAND_NUM_BANDS_QMF71;
+ L = SUBBAND_DOWNSAMPLING_FACTOR_QMF71;
+ /* analysisDelay = SUBBAND_ANALYSIS_DELAY_QMF71; */
+ break;
+#else
+ case SDM_QMF64:
+ case SDM_QMF71:
+ /* QMF domain processing is not supported. */
+ return DE_NOT_OK;
+#endif
+ case SDM_STFT256:
+ nDecoderSubbands = SUBBAND_NUM_BANDS_STFT256;
+ L = SUBBAND_DOWNSAMPLING_FACTOR_STFT256;
+ /* analysisDelay = SUBBAND_ANALYSIS_DELAY_STFT256; */
+ break;
+ default:
+ return DE_NOT_OK;
+ }
+
+ /* frameSizeSb = hGainDec->frameSize/L; */ /* L is a power of 2 */
+ frameSizeSb =
+ hGainDec->frameSize >> (15 - fixnormz_S(L)); /* timeslots per frame */
+
+ if ((processSingleTimeslot < 0) || (processSingleTimeslot >= frameSizeSb)) {
+ m_start = 0;
+ m_stop = frameSizeSb;
+ } else {
+ m_start = processSingleTimeslot;
+ m_stop = m_start + 1;
+ }
+
+ err = _prepareLnbIndex(pActiveDrc, channelOffset, drcChannelOffset,
+ numChannelsProcessed, lnbPointer);
+ if (err) return err;
+
+ if (!pActiveDrc->subbandGainsReady) /* only for the first time per frame that
+ processDrcSubband is called */
+ {
+ /* write subbandGains */
+ for (g = 0; g < pInst->nDrcChannelGroups; g++) {
+ b = 0;
+ {
+ LINEAR_NODE_BUFFER* pLnb =
+ &(pLinearNodeBuffer[activeDrcOffset +
+ pActiveDrc->gainElementForGroup[g] + b]);
+ NODE_LIN nodePrevious;
+ int lnbPointerDiff;
+
+ for (m = 0; m < frameSizeSb; m++) {
+ subbandGains[activeDrcOffset + g][b * frameSizeSb + m] =
+ FL2FXCONST_DBL(1.0f / (float)(1 << 7));
+ }
+
+ lnbIx = lnbPointer - (NUM_LNB_FRAMES - 1);
+ while (lnbIx < 0) lnbIx += NUM_LNB_FRAMES;
+
+ /* Loop over all node buffers in linearNodeBuffer.
+ All nodes which are not relevant for the current frame are sorted out
+ inside _processNodeSegments. */
+ for (i = 0; i < NUM_LNB_FRAMES - 1; i++) {
+ /* Prepare previous node */
+ nodePrevious = pLnb->linearNode[lnbIx][pLnb->nNodes[lnbIx] - 1];
+ nodePrevious.time -= hGainDec->frameSize;
+
+ lnbIx++;
+ if (lnbIx >= NUM_LNB_FRAMES) lnbIx = 0;
+
+ /* number of frames of offset with respect to lnbPointer */
+ lnbPointerDiff = i - (NUM_LNB_FRAMES - 2);
+
+ err = _processNodeSegments(
+ hGainDec->frameSize, pLnb->gainInterpolationType,
+ pLnb->nNodes[lnbIx], pLnb->linearNode[lnbIx],
+ lnbPointerDiff * hGainDec->frameSize + delaySamples + offset -
+ (L - 1) / 2,
+ L, nodePrevious, FL2FXCONST_DBL(1.0f / (float)(1 << 8)),
+ &(subbandGains[activeDrcOffset + g][b * frameSizeSb]));
+ if (err) return err;
+ }
+ }
+ }
+ pActiveDrc->subbandGainsReady = 1;
+ }
+
+ for (c = channelOffset; c < channelOffset + numChannelsProcessed; c++) {
+ FIXP_DBL* thisSubbandGainsBuffer;
+ if (pInst->drcSetId > 0)
+ g = pActiveDrc->channelGroupForChannel[c + drcChannelOffset];
+ else
+ g = -1;
+
+ audioReal = deinterleavedAudioReal[signalIndex];
+ if (subbandDomainMode != SDM_STFT256) {
+ audioImag = deinterleavedAudioImag[signalIndex];
+ }
+
+ if ((g >= 0) && !pActiveDrc->channelGroupIsParametricDrc[g]) {
+ thisSubbandGainsBuffer = subbandGains[activeDrcOffset + g];
+ } else {
+ thisSubbandGainsBuffer = dummySubbandGains;
+ }
+
+ for (m = m_start; m < m_stop; m++) {
+ INT n_min = 8;
+ { /* single-band DRC */
+ gainSb = thisSubbandGainsBuffer[m];
+ if (activeDrcIndex == hGainDec->channelGainActiveDrcIndex)
+ gainSb = SATURATE_LEFT_SHIFT(
+ fMultDiv2(gainSb, hGainDec->channelGain[c]), 9, DFRACT_BITS);
+ /* normalize gainSb for keeping signal precision */
+ n_min = fMin(CntLeadingZeros(gainSb) - 1, n_min);
+ gainSb <<= n_min;
+ n_min = 8 - n_min;
+ if (subbandDomainMode ==
+ SDM_STFT256) { /* For STFT filterbank, real and imaginary parts are
+ interleaved. */
+ for (s = 0; s < nDecoderSubbands; s++) {
+ *audioReal = fMultDiv2(*audioReal, gainSb) << n_min;
+ audioReal++;
+ *audioReal = fMultDiv2(*audioReal, gainSb) << n_min;
+ audioReal++;
+ }
+ } else {
+ for (s = 0; s < nDecoderSubbands; s++) {
+ *audioReal = fMultDiv2(*audioReal, gainSb) << n_min;
+ audioReal++;
+ *audioImag = fMultDiv2(*audioImag, gainSb) << n_min;
+ audioImag++;
+ }
+ }
+ }
+ }
+ signalIndex++;
+ }
+ return DE_OK;
+}
diff --git a/fdk-aac/libDRCdec/src/drcGainDec_process.h b/fdk-aac/libDRCdec/src/drcGainDec_process.h
new file mode 100644
index 0000000..f751aba
--- /dev/null
+++ b/fdk-aac/libDRCdec/src/drcGainDec_process.h
@@ -0,0 +1,119 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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-D DRC decoder library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef DRCGAINDEC_PROCESS_H
+#define DRCGAINDEC_PROCESS_H
+
+DRC_ERROR
+processDrcTime(HANDLE_DRC_GAIN_DECODER hGainDec, const int activeDrcIndex,
+ const int delaySamples, const int channelOffset,
+ const int drcChannelOffset, const int numChannelsProcessed,
+ const int timeDataChannelOffset, FIXP_DBL* deinterleavedAudio);
+
+DRC_ERROR
+processDrcSubband(HANDLE_DRC_GAIN_DECODER hGainDec, const int activeDrcIndex,
+ const int delaySamples, const int channelOffset,
+ const int drcChannelOffset, const int numChannelsProcessed,
+ const int processSingleTimeslot,
+ FIXP_DBL* deinterleavedAudioReal[],
+ FIXP_DBL* deinterleavedAudioImag[]);
+#endif
diff --git a/fdk-aac/libFDK/include/FDK_archdef.h b/fdk-aac/libFDK/include/FDK_archdef.h
new file mode 100644
index 0000000..b4fef8a
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_archdef.h
@@ -0,0 +1,270 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef FDK_ARCHDEF_H
+#define FDK_ARCHDEF_H
+
+/* Unify some few toolchain specific defines to avoid having large "or" macro
+ * contraptions all over the source code. */
+
+/* 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(_MSC_VER) && defined(_M_X64)) || defined(__x86_64__)
+#define __x86__
+#endif
+
+#if defined(_M_ARM) && !defined(__arm__) || defined(__aarch64__) || defined(_M_ARM64)
+#define __arm__
+#endif
+
+#if defined(_ARCH_PPC) && !defined(__powerpc__)
+#define __powerpc__ 1
+#endif
+
+#if (__TARGET_ARCH_ARM == 5) || defined(__TARGET_FEATURE_DSPMUL) || \
+ (_M_ARM == 5) || defined(__ARM_ARCH_5TEJ__) || defined(__ARM_ARCH_7EM__)
+/* Define __ARM_ARCH_5TE__ if armv5te features are supported */
+#define __ARM_ARCH_5TE__
+#endif
+
+#if (__TARGET_ARCH_ARM == 6) || defined(__ARM_ARCH_6J__) || \
+ defined(__ARM_ARCH_6ZK__)
+/* Define __ARM_ARCH_6__ if the armv6 intructions are being supported. */
+#define __ARM_ARCH_5TE__
+#define __ARM_ARCH_6__
+#endif
+
+#if defined(__TARGET_ARCH_7_R) || defined(__ARM_ARCH_7R__)
+/* Define __ARM_ARCH_7_A__ if the armv7 intructions are being supported. */
+#define __ARM_ARCH_5TE__
+#define __ARM_ARCH_6__
+#define __ARM_ARCH_7_R__
+#endif
+
+#if defined(__TARGET_ARCH_7_A) || defined(__ARM_ARCH_7A__) || \
+ ((__ARM_ARCH == 8) && (__ARM_32BIT_STATE == 1))
+/* Define __ARM_ARCH_7_A__ if the armv7 intructions are being supported. */
+#define __ARM_ARCH_5TE__
+#define __ARM_ARCH_6__
+#define __ARM_ARCH_7_A__
+#endif
+
+#if defined(__TARGET_ARCH_7_M) || defined(__ARM_ARCH_7_M__)
+/* Define __ARM_ARCH_7M__ if the ARMv7-M instructions are being supported, e.g.
+ * Cortex-M3. */
+#define __ARM_ARCH_7M__
+#endif
+
+#if defined(__TARGET_ARCH_7E_M) || defined(__ARM_ARCH_7E_M__)
+/* Define __ARM_ARCH_7EM__ if the ARMv7-ME instructions are being supported,
+ * e.g. Cortex-M4. */
+#define __ARM_ARCH_7EM__
+#endif
+
+#if defined(__aarch64__) || defined(_M_ARM64)
+#define __ARM_ARCH_8__
+#endif
+
+#ifdef _M_ARM
+#include "armintr.h"
+#endif
+
+/* Define preferred Multiplication type */
+
+#if defined(__mips__)
+#define ARCH_PREFER_MULT_16x16
+#undef SINETABLE_16BIT
+#undef POW2COEFF_16BIT
+#undef LDCOEFF_16BIT
+#undef WINDOWTABLE_16BIT
+
+#elif defined(__arm__) && defined(__ARM_ARCH_8__)
+#define ARCH_PREFER_MULT_32x16
+#define SINETABLE_16BIT
+#define POW2COEFF_16BIT
+#define LDCOEFF_16BIT
+#define WINDOWTABLE_16BIT
+
+#elif defined(__arm__) && defined(__ARM_ARCH_5TE__)
+#define ARCH_PREFER_MULT_32x16
+#define SINETABLE_16BIT
+#define POW2COEFF_16BIT
+#define LDCOEFF_16BIT
+#define WINDOWTABLE_16BIT
+
+#elif defined(__arm__) && defined(__ARM_ARCH_7M__)
+#define ARCH_PREFER_MULT_32x16
+#define SINETABLE_16BIT
+#define POW2COEFF_16BIT
+#define LDCOEFF_16BIT
+#define WINDOWTABLE_16BIT
+
+#elif defined(__arm__) && defined(__ARM_ARCH_7EM__)
+#define ARCH_PREFER_MULT_32x32
+#define ARCH_PREFER_MULT_32x16
+#define SINETABLE_16BIT
+#define POW2COEFF_16BIT
+#define LDCOEFF_16BIT
+#define WINDOWTABLE_16BIT
+
+#elif defined(__arm__) && !defined(__ARM_ARCH_5TE__)
+#define ARCH_PREFER_MULT_16x16
+#undef SINETABLE_16BIT
+#undef WINDOWTABLE_16BIT
+#undef POW2COEFF_16BIT
+#undef LDCOEFF_16BIT
+
+#elif defined(__x86__)
+#define ARCH_PREFER_MULT_32x16
+#define SINETABLE_16BIT
+#define WINDOWTABLE_16BIT
+#define POW2COEFF_16BIT
+#define LDCOEFF_16BIT
+
+#elif defined(__powerpc__)
+#define ARCH_PREFER_MULT_32x32
+#define ARCH_PREFER_MULT_32x16
+#define SINETABLE_16BIT
+#define POW2COEFF_16BIT
+#define LDCOEFF_16BIT
+#define WINDOWTABLE_16BIT
+
+#else
+#warning >>>> Please set architecture characterization defines for your platform (FDK_HIGH_PERFORMANCE)! <<<<
+
+#endif /* Architecture switches */
+
+#ifdef SINETABLE_16BIT
+#define FIXP_STB FIXP_SGL /* STB sinus Tab used in transformation */
+#define FIXP_STP FIXP_SPK
+#define STC(a) (FX_DBL2FXCONST_SGL(a))
+#else
+#define FIXP_STB FIXP_DBL
+#define FIXP_STP FIXP_DPK
+#define STC(a) ((FIXP_DBL)(LONG)(a))
+#endif /* defined(SINETABLE_16BIT) */
+
+#define STCP(cos, sin) \
+ { \
+ { STC(cos), STC(sin) } \
+ }
+
+#ifdef WINDOWTABLE_16BIT
+#define FIXP_WTB FIXP_SGL /* single FIXP_SGL values */
+#define FX_DBL2FX_WTB(x) FX_DBL2FX_SGL(x)
+#define FIXP_WTP FIXP_SPK /* packed FIXP_SGL values */
+#define WTC(a) FX_DBL2FXCONST_SGL(a)
+#else /* SINETABLE_16BIT */
+#define FIXP_WTB FIXP_DBL
+#define FX_DBL2FX_WTB(x) (x)
+#define FIXP_WTP FIXP_DPK
+#define WTC(a) (FIXP_DBL)(a)
+#endif /* SINETABLE_16BIT */
+
+#define WTCP(a, b) \
+ { \
+ { WTC(a), WTC(b) } \
+ }
+
+#endif /* FDK_ARCHDEF_H */
diff --git a/fdk-aac/libFDK/include/FDK_bitbuffer.h b/fdk-aac/libFDK/include/FDK_bitbuffer.h
new file mode 100644
index 0000000..19a24b3
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_bitbuffer.h
@@ -0,0 +1,177 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Lohwasser
+
+ Description: common bitbuffer read/write routines
+
+*******************************************************************************/
+
+#ifndef FDK_BITBUFFER_H
+#define FDK_BITBUFFER_H
+
+#include "FDK_archdef.h"
+#include "machine_type.h"
+
+/* leave 3 bits headroom so MAX_BUFSIZE can be represented in bits as well. */
+#define MAX_BUFSIZE_BYTES (0x10000000)
+
+typedef struct {
+ UINT ValidBits;
+ UINT ReadOffset;
+ UINT WriteOffset;
+ UINT BitNdx;
+
+ UCHAR *Buffer;
+ UINT bufSize;
+ UINT bufBits;
+} FDK_BITBUF;
+
+typedef FDK_BITBUF *HANDLE_FDK_BITBUF;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const UINT BitMask[32 + 1];
+
+/** The BitBuffer Functions are called straight from FDK_bitstream Interface.
+ For Functions functional survey look there.
+*/
+
+void FDK_CreateBitBuffer(HANDLE_FDK_BITBUF *hBitBuffer, UCHAR *pBuffer,
+ UINT bufSize);
+
+void FDK_InitBitBuffer(HANDLE_FDK_BITBUF hBitBuffer, UCHAR *pBuffer,
+ UINT bufSize, UINT validBits);
+
+void FDK_ResetBitBuffer(HANDLE_FDK_BITBUF hBitBuffer);
+
+void FDK_DeleteBitBuffer(HANDLE_FDK_BITBUF hBitBuffer);
+
+INT FDK_get(HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits);
+
+INT FDK_get32(HANDLE_FDK_BITBUF hBitBuf);
+
+void FDK_put(HANDLE_FDK_BITBUF hBitBuffer, UINT value, const UINT numberOfBits);
+
+INT FDK_getBwd(HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits);
+void FDK_putBwd(HANDLE_FDK_BITBUF hBitBuffer, UINT value,
+ const UINT numberOfBits);
+
+void FDK_pushBack(HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits,
+ UCHAR config);
+
+void FDK_pushForward(HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits,
+ UCHAR config);
+
+UINT FDK_getValidBits(HANDLE_FDK_BITBUF hBitBuffer);
+
+INT FDK_getFreeBits(HANDLE_FDK_BITBUF hBitBuffer);
+
+void FDK_Feed(HANDLE_FDK_BITBUF hBitBuffer, const UCHAR inputBuffer[],
+ const UINT bufferSize, UINT *bytesValid);
+
+void FDK_Copy(HANDLE_FDK_BITBUF hBitBufDst, HANDLE_FDK_BITBUF hBitBufSrc,
+ UINT *bytesValid);
+
+void FDK_Fetch(HANDLE_FDK_BITBUF hBitBuffer, UCHAR outBuf[], UINT *writeBytes);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/fdk-aac/libFDK/include/FDK_bitstream.h b/fdk-aac/libFDK/include/FDK_bitstream.h
new file mode 100644
index 0000000..f799026
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_bitstream.h
@@ -0,0 +1,642 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Lohwasser
+
+ Description: bitstream interface to bitbuffer routines
+
+*******************************************************************************/
+
+#ifndef FDK_BITSTREAM_H
+#define FDK_BITSTREAM_H
+
+#include "FDK_bitbuffer.h"
+#include "machine_type.h"
+
+#include "genericStds.h"
+
+#define CACHE_BITS 32
+
+#define BUFSIZE_DUMMY_VALUE MAX_BUFSIZE_BYTES
+
+typedef enum { BS_READER, BS_WRITER } FDK_BS_CFG;
+
+typedef struct {
+ UINT CacheWord;
+ UINT BitsInCache;
+ FDK_BITBUF hBitBuf;
+ UINT ConfigCache;
+} FDK_BITSTREAM;
+
+typedef FDK_BITSTREAM *HANDLE_FDK_BITSTREAM;
+
+/**
+ * \brief CreateBitStream Function.
+ *
+ * Create and initialize bitstream with extern allocated buffer.
+ *
+ * \param pBuffer Pointer to BitBuffer array.
+ * \param bufSize Length of BitBuffer array. (awaits size 2^n and <=
+ * MAX_BUFSIZE_BYTES)
+ * \param config Initialize BitStream as Reader or Writer.
+ */
+FDK_INLINE
+HANDLE_FDK_BITSTREAM FDKcreateBitStream(UCHAR *pBuffer, UINT bufSize,
+ FDK_BS_CFG config = BS_READER) {
+ HANDLE_FDK_BITSTREAM hBitStream =
+ (HANDLE_FDK_BITSTREAM)FDKcalloc(1, sizeof(FDK_BITSTREAM));
+ if (hBitStream == NULL) return NULL;
+ FDK_InitBitBuffer(&hBitStream->hBitBuf, pBuffer, bufSize, 0);
+
+ /* init cache */
+ hBitStream->CacheWord = hBitStream->BitsInCache = 0;
+ hBitStream->ConfigCache = config;
+
+ return hBitStream;
+}
+
+/**
+ * \brief Initialize BistreamBuffer. BitBuffer can point to filled BitBuffer
+ * array .
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param pBuffer Pointer to BitBuffer array.
+ * \param bufSize Length of BitBuffer array in bytes. (awaits size 2^n and <=
+ * MAX_BUFSIZE_BYTES)
+ * \param validBits Number of valid BitBuffer filled Bits.
+ * \param config Initialize BitStream as Reader or Writer.
+ * \return void
+ */
+FDK_INLINE
+void FDKinitBitStream(HANDLE_FDK_BITSTREAM hBitStream, UCHAR *pBuffer,
+ UINT bufSize, UINT validBits,
+ FDK_BS_CFG config = BS_READER) {
+ FDK_InitBitBuffer(&hBitStream->hBitBuf, pBuffer, bufSize, validBits);
+
+ /* init cache */
+ hBitStream->CacheWord = hBitStream->BitsInCache = 0;
+ hBitStream->ConfigCache = config;
+}
+
+/**
+ * \brief ResetBitbuffer Function. Reset states in BitBuffer and Cache.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param config Initialize BitStream as Reader or Writer.
+ * \return void
+ */
+FDK_INLINE void FDKresetBitbuffer(HANDLE_FDK_BITSTREAM hBitStream,
+ FDK_BS_CFG config = BS_READER) {
+ FDK_ResetBitBuffer(&hBitStream->hBitBuf);
+
+ /* init cache */
+ hBitStream->CacheWord = hBitStream->BitsInCache = 0;
+ hBitStream->ConfigCache = config;
+}
+
+/** DeleteBitStream.
+
+ Deletes the in Create Bitstream allocated BitStream and BitBuffer.
+*/
+FDK_INLINE void FDKdeleteBitStream(HANDLE_FDK_BITSTREAM hBitStream) {
+ FDK_DeleteBitBuffer(&hBitStream->hBitBuf);
+ FDKfree(hBitStream);
+}
+
+/**
+ * \brief ReadBits Function (forward). This function returns a number of
+ * sequential bits from the input bitstream.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param numberOfBits The number of bits to be retrieved. ( (0),1 <=
+ * numberOfBits <= 32)
+ * \return the requested bits, right aligned
+ * \return
+ */
+
+FDK_INLINE UINT FDKreadBits(HANDLE_FDK_BITSTREAM hBitStream,
+ const UINT numberOfBits) {
+ UINT bits = 0;
+ INT missingBits = (INT)numberOfBits - (INT)hBitStream->BitsInCache;
+
+ FDK_ASSERT(numberOfBits <= 32);
+ if (missingBits > 0) {
+ if (missingBits != 32) bits = hBitStream->CacheWord << missingBits;
+ hBitStream->CacheWord = FDK_get32(&hBitStream->hBitBuf);
+ hBitStream->BitsInCache += CACHE_BITS;
+ }
+
+ hBitStream->BitsInCache -= numberOfBits;
+
+ return (bits | (hBitStream->CacheWord >> hBitStream->BitsInCache)) &
+ BitMask[numberOfBits];
+}
+
+FDK_INLINE UINT FDKreadBit(HANDLE_FDK_BITSTREAM hBitStream) {
+ if (!hBitStream->BitsInCache) {
+ hBitStream->CacheWord = FDK_get32(&hBitStream->hBitBuf);
+ hBitStream->BitsInCache = CACHE_BITS - 1;
+ return hBitStream->CacheWord >> 31;
+ }
+ hBitStream->BitsInCache--;
+
+ return (hBitStream->CacheWord >> hBitStream->BitsInCache) & 1;
+}
+
+/**
+ * \brief Read2Bits Function (forward). This function reads 2 sequential
+ * bits from the input bitstream. It is the optimized version
+ of FDKreadBits() for reading 2 bits.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \return the requested bits, right aligned
+ * \return
+ */
+FDK_INLINE UINT FDKread2Bits(HANDLE_FDK_BITSTREAM hBitStream) {
+ /*
+ ** Version corresponds to optimized FDKreadBits implementation
+ ** calling FDK_get32, that keeps read pointer aligned.
+ */
+ UINT bits = 0;
+ INT missingBits = 2 - (INT)hBitStream->BitsInCache;
+ if (missingBits > 0) {
+ bits = hBitStream->CacheWord << missingBits;
+ hBitStream->CacheWord = FDK_get32(&hBitStream->hBitBuf);
+ hBitStream->BitsInCache += CACHE_BITS;
+ }
+
+ hBitStream->BitsInCache -= 2;
+
+ return (bits | (hBitStream->CacheWord >> hBitStream->BitsInCache)) & 0x3;
+}
+
+/**
+ * \brief ReadBits Function (backward). This function returns a number of
+ * sequential bits from the input bitstream.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param numberOfBits The number of bits to be retrieved.
+ * \return the requested bits, right aligned
+ */
+FDK_INLINE UINT FDKreadBitsBwd(HANDLE_FDK_BITSTREAM hBitStream,
+ const UINT numberOfBits) {
+ const UINT validMask = BitMask[numberOfBits];
+
+ if (hBitStream->BitsInCache <= numberOfBits) {
+ const INT freeBits = (CACHE_BITS - 1) - hBitStream->BitsInCache;
+
+ hBitStream->CacheWord = (hBitStream->CacheWord << freeBits) |
+ FDK_getBwd(&hBitStream->hBitBuf, freeBits);
+ hBitStream->BitsInCache += freeBits;
+ }
+
+ hBitStream->BitsInCache -= numberOfBits;
+
+ return (hBitStream->CacheWord >> hBitStream->BitsInCache) & validMask;
+}
+
+/**
+ * \brief read an integer value using a varying number of bits from the
+ * bitstream
+ *
+ * q.v. ISO/IEC FDIS 23003-3 Table 16
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param nBits1 number of bits to read for a small integer value or escape
+ * value
+ * \param nBits2 number of bits to read for a medium sized integer value or
+ * escape value
+ * \param nBits3 number of bits to read for a large integer value
+ * \return integer value read from bitstream
+ */
+FDK_INLINE UINT escapedValue(HANDLE_FDK_BITSTREAM hBitStream, int nBits1,
+ int nBits2, int nBits3) {
+ UINT value = FDKreadBits(hBitStream, nBits1);
+
+ if (value == (UINT)(1 << nBits1) - 1) {
+ UINT valueAdd = FDKreadBits(hBitStream, nBits2);
+ value += valueAdd;
+ if (valueAdd == (UINT)(1 << nBits2) - 1) {
+ value += FDKreadBits(hBitStream, nBits3);
+ }
+ }
+
+ return value;
+}
+
+/**
+ * \brief return a number of bits from the bitBuffer.
+ * You have to know what you do! Cache has to be synchronized before
+ * using this function.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param numBits The number of bits to be retrieved.
+ * \return the requested bits, right aligned
+ */
+FDK_INLINE UINT FDKgetBits(HANDLE_FDK_BITSTREAM hBitStream, UINT numBits) {
+ return FDK_get(&hBitStream->hBitBuf, numBits);
+}
+
+/**
+ * \brief WriteBits Function. This function writes numberOfBits of value into
+ * bitstream.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param value The data to be written
+ * \param numberOfBits The number of bits to be written
+ * \return Number of bits written
+ */
+FDK_INLINE UCHAR FDKwriteBits(HANDLE_FDK_BITSTREAM hBitStream, UINT value,
+ const UINT numberOfBits) {
+ const UINT validMask = BitMask[numberOfBits];
+
+ if (hBitStream == NULL) {
+ return numberOfBits;
+ }
+
+ if ((hBitStream->BitsInCache + numberOfBits) < CACHE_BITS) {
+ hBitStream->BitsInCache += numberOfBits;
+ hBitStream->CacheWord =
+ (hBitStream->CacheWord << numberOfBits) | (value & validMask);
+ } else {
+ /* Put always 32 bits into memory */
+ /* - fill cache's LSBits with MSBits of value */
+ /* - store 32 bits in memory using subroutine */
+ /* - fill remaining bits into cache's LSBits */
+ /* - upper bits in cache are don't care */
+
+ /* Compute number of bits to be filled into cache */
+ int missing_bits = CACHE_BITS - hBitStream->BitsInCache;
+ int remaining_bits = numberOfBits - missing_bits;
+ value = value & validMask;
+ /* Avoid shift left by 32 positions */
+ UINT CacheWord =
+ (missing_bits == 32) ? 0 : (hBitStream->CacheWord << missing_bits);
+ CacheWord |= (value >> (remaining_bits));
+ FDK_put(&hBitStream->hBitBuf, CacheWord, 32);
+
+ hBitStream->CacheWord = value;
+ hBitStream->BitsInCache = remaining_bits;
+ }
+
+ return numberOfBits;
+}
+
+/**
+ * \brief WriteBits Function (backward). This function writes numberOfBits of
+ * value into bitstream.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param value Variable holds data to be written.
+ * \param numberOfBits The number of bits to be written.
+ * \return number of bits written
+ */
+FDK_INLINE UCHAR FDKwriteBitsBwd(HANDLE_FDK_BITSTREAM hBitStream, UINT value,
+ const UINT numberOfBits) {
+ const UINT validMask = BitMask[numberOfBits];
+
+ if ((hBitStream->BitsInCache + numberOfBits) <= CACHE_BITS) {
+ hBitStream->BitsInCache += numberOfBits;
+ hBitStream->CacheWord =
+ (hBitStream->CacheWord << numberOfBits) | (value & validMask);
+ } else {
+ FDK_putBwd(&hBitStream->hBitBuf, hBitStream->CacheWord,
+ hBitStream->BitsInCache);
+ hBitStream->BitsInCache = numberOfBits;
+ hBitStream->CacheWord = (value & validMask);
+ }
+
+ return numberOfBits;
+}
+
+/**
+ * \brief write an integer value using a varying number of bits from the
+ * bitstream
+ *
+ * q.v. ISO/IEC FDIS 23003-3 Table 16
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param value the data to be written
+ * \param nBits1 number of bits to write for a small integer value or escape
+ * value
+ * \param nBits2 number of bits to write for a medium sized integer value or
+ * escape value
+ * \param nBits3 number of bits to write for a large integer value
+ * \return number of bits written
+ */
+FDK_INLINE UCHAR FDKwriteEscapedValue(HANDLE_FDK_BITSTREAM hBitStream,
+ UINT value, UINT nBits1, UINT nBits2,
+ UINT nBits3) {
+ UCHAR nbits = 0;
+ UINT tmp = (1 << nBits1) - 1;
+
+ if (value < tmp) {
+ nbits += FDKwriteBits(hBitStream, value, nBits1);
+ } else {
+ nbits += FDKwriteBits(hBitStream, tmp, nBits1);
+ value -= tmp;
+ tmp = (1 << nBits2) - 1;
+
+ if (value < tmp) {
+ nbits += FDKwriteBits(hBitStream, value, nBits2);
+ } else {
+ nbits += FDKwriteBits(hBitStream, tmp, nBits2);
+ value -= tmp;
+
+ nbits += FDKwriteBits(hBitStream, value, nBits3);
+ }
+ }
+
+ return nbits;
+}
+
+/**
+ * \brief SyncCache Function. Clear cache after read forward.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \return void
+ */
+FDK_INLINE void FDKsyncCache(HANDLE_FDK_BITSTREAM hBitStream) {
+ if (hBitStream->ConfigCache == BS_READER)
+ FDK_pushBack(&hBitStream->hBitBuf, hBitStream->BitsInCache,
+ hBitStream->ConfigCache);
+ else if (hBitStream->BitsInCache) /* BS_WRITER */
+ FDK_put(&hBitStream->hBitBuf, hBitStream->CacheWord,
+ hBitStream->BitsInCache);
+
+ hBitStream->BitsInCache = 0;
+ hBitStream->CacheWord = 0;
+}
+
+/**
+ * \brief SyncCache Function. Clear cache after read backwards.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \return void
+ */
+FDK_INLINE void FDKsyncCacheBwd(HANDLE_FDK_BITSTREAM hBitStream) {
+ if (hBitStream->ConfigCache == BS_READER) {
+ FDK_pushForward(&hBitStream->hBitBuf, hBitStream->BitsInCache,
+ hBitStream->ConfigCache);
+ } else { /* BS_WRITER */
+ FDK_putBwd(&hBitStream->hBitBuf, hBitStream->CacheWord,
+ hBitStream->BitsInCache);
+ }
+
+ hBitStream->BitsInCache = 0;
+ hBitStream->CacheWord = 0;
+}
+
+/**
+ * \brief Byte Alignment Function with anchor
+ * This function performs the byte_alignment() syntactic function on the
+ * input stream, i.e. some bits will be discarded so that the next bits to be
+ * read/written would be aligned on a byte boundary with respect to the
+ * given alignment anchor.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param alignmentAnchor bit position to be considered as origin for byte
+ * alignment
+ * \return void
+ */
+FDK_INLINE void FDKbyteAlign(HANDLE_FDK_BITSTREAM hBitStream,
+ UINT alignmentAnchor) {
+ FDKsyncCache(hBitStream);
+ if (hBitStream->ConfigCache == BS_READER) {
+ FDK_pushForward(
+ &hBitStream->hBitBuf,
+ (UINT)((INT)8 - (((INT)alignmentAnchor -
+ (INT)FDK_getValidBits(&hBitStream->hBitBuf)) &
+ 0x07)) &
+ 0x07,
+ hBitStream->ConfigCache);
+ } else {
+ FDK_put(&hBitStream->hBitBuf, 0,
+ (8 - ((FDK_getValidBits(&hBitStream->hBitBuf) - alignmentAnchor) &
+ 0x07)) &
+ 0x07);
+ }
+}
+
+/**
+ * \brief Push Back(Cache) / For / BiDirectional Function.
+ * PushBackCache function ungets a number of bits erroneously
+ * read/written by the last Get() call. NB: The number of bits to be stuffed
+ * back into the stream may never exceed the number of bits returned by
+ * the immediately preceding Get() call.
+ *
+ * PushBack function ungets a number of bits (combines cache and bitbuffer
+ * indices) PushFor function gets a number of bits (combines cache and
+ * bitbuffer indices) PushBiDirectional gets/ungets number of bits as
+ * defined in PusBack/For function NB: The sign of bits is not known, so
+ * the function checks direction and calls appropriate function. (positive
+ * sign pushFor, negative sign pushBack )
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param numberOfBits The number of bits to be pushed back/for.
+ * \return void
+ */
+FDK_INLINE void FDKpushBackCache(HANDLE_FDK_BITSTREAM hBitStream,
+ const UINT numberOfBits) {
+ FDK_ASSERT((hBitStream->BitsInCache + numberOfBits) <= CACHE_BITS);
+ hBitStream->BitsInCache += numberOfBits;
+}
+
+FDK_INLINE void FDKpushBack(HANDLE_FDK_BITSTREAM hBitStream,
+ const UINT numberOfBits) {
+ if ((hBitStream->BitsInCache + numberOfBits) < CACHE_BITS &&
+ (hBitStream->ConfigCache == BS_READER)) {
+ hBitStream->BitsInCache += numberOfBits;
+ FDKsyncCache(hBitStream); /* sync cache to avoid invalid cache */
+ } else {
+ FDKsyncCache(hBitStream);
+ FDK_pushBack(&hBitStream->hBitBuf, numberOfBits, hBitStream->ConfigCache);
+ }
+}
+
+FDK_INLINE void FDKpushFor(HANDLE_FDK_BITSTREAM hBitStream,
+ const UINT numberOfBits) {
+ if ((hBitStream->BitsInCache > numberOfBits) &&
+ (hBitStream->ConfigCache == BS_READER)) {
+ hBitStream->BitsInCache -= numberOfBits;
+ } else {
+ FDKsyncCache(hBitStream);
+ FDK_pushForward(&hBitStream->hBitBuf, numberOfBits,
+ hBitStream->ConfigCache);
+ }
+}
+
+FDK_INLINE void FDKpushBiDirectional(HANDLE_FDK_BITSTREAM hBitStream,
+ const INT numberOfBits) {
+ if (numberOfBits >= 0)
+ FDKpushFor(hBitStream, numberOfBits);
+ else
+ FDKpushBack(hBitStream, -numberOfBits);
+}
+
+/**
+ * \brief GetValidBits Function. Clear cache and return valid Bits from
+ * Bitbuffer.
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \return amount of valid bits that still can be read or were already written.
+ *
+ */
+FDK_INLINE UINT FDKgetValidBits(HANDLE_FDK_BITSTREAM hBitStream) {
+ FDKsyncCache(hBitStream);
+ return FDK_getValidBits(&hBitStream->hBitBuf);
+}
+
+/**
+ * \brief return amount of unused Bits from Bitbuffer.
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \return amount of free bits that still can be written into the bitstream
+ */
+FDK_INLINE INT FDKgetFreeBits(HANDLE_FDK_BITSTREAM hBitStream) {
+ return FDK_getFreeBits(&hBitStream->hBitBuf);
+}
+
+/**
+ * \brief Fill the BitBuffer with a number of input bytes from external source.
+ * The bytesValid variable returns the number of ramaining valid bytes in
+ * extern inputBuffer.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param inputBuffer Pointer to input buffer with bitstream data.
+ * \param bufferSize Total size of inputBuffer array.
+ * \param bytesValid Input: number of valid bytes in inputBuffer. Output: bytes
+ * still left unread in inputBuffer.
+ * \return void
+ */
+FDK_INLINE void FDKfeedBuffer(HANDLE_FDK_BITSTREAM hBitStream,
+ const UCHAR inputBuffer[], const UINT bufferSize,
+ UINT *bytesValid) {
+ FDKsyncCache(hBitStream);
+ FDK_Feed(&hBitStream->hBitBuf, inputBuffer, bufferSize, bytesValid);
+}
+
+/**
+ * \brief fill destination BitBuffer with a number of bytes from source
+ * BitBuffer. The bytesValid variable returns the number of ramaining valid
+ * bytes in source BitBuffer.
+ *
+ * \param hBSDst HANDLE_FDK_BITSTREAM handle to write data into
+ * \param hBSSrc HANDLE_FDK_BITSTREAM handle to read data from
+ * \param bytesValid Input: number of valid bytes in inputBuffer. Output:
+ * bytes still left unread in inputBuffer.
+ * \return void
+ */
+FDK_INLINE void FDKcopyBuffer(HANDLE_FDK_BITSTREAM hBSDst,
+ HANDLE_FDK_BITSTREAM hBSSrc, UINT *bytesValid) {
+ FDKsyncCache(hBSSrc);
+ FDK_Copy(&hBSDst->hBitBuf, &hBSSrc->hBitBuf, bytesValid);
+}
+
+/**
+ * \brief fill the outputBuffer with all valid bytes hold in BitBuffer. The
+ * WriteBytes variable returns the number of written Bytes.
+ *
+ * \param hBitStream HANDLE_FDK_BITSTREAM handle
+ * \param outputBuffer Pointer to output buffer.
+ * \param writeBytes Number of bytes write to output buffer.
+ * \return void
+ */
+FDK_INLINE void FDKfetchBuffer(HANDLE_FDK_BITSTREAM hBitStream,
+ UCHAR *outputBuffer, UINT *writeBytes) {
+ FDKsyncCache(hBitStream);
+ FDK_Fetch(&hBitStream->hBitBuf, outputBuffer, writeBytes);
+}
+
+#endif
diff --git a/fdk-aac/libFDK/include/FDK_core.h b/fdk-aac/libFDK/include/FDK_core.h
new file mode 100644
index 0000000..9543522
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_core.h
@@ -0,0 +1,122 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Manuel Jander
+
+ Description: FDK tools versioning support
+
+*******************************************************************************/
+
+#ifndef FDK_CORE_H
+#define FDK_CORE_H
+
+#include "FDK_audio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Get FDK_tools library information.
+ * @return Return 0 on success and a negative errorcode on failure (see
+ * errorcodes.h).
+ */
+int FDK_toolsGetLibInfo(LIB_INFO *info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/fdk-aac/libFDK/include/FDK_crc.h b/fdk-aac/libFDK/include/FDK_crc.h
new file mode 100644
index 0000000..6c7040c
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_crc.h
@@ -0,0 +1,225 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: CRC calculation
+
+*******************************************************************************/
+
+#ifndef FDK_CRC_H
+#define FDK_CRC_H
+
+#include "FDK_bitstream.h"
+
+#define MAX_CRC_REGS \
+ 3 /*!< Maximal number of overlapping crc region in ADTS channel pair element \
+ is two. Select three independent regions preventively. */
+
+/**
+ * This structure describes single crc region used for crc calculation.
+ */
+typedef struct {
+ UCHAR isActive;
+ INT maxBits;
+ INT bitBufCntBits;
+ INT validBits;
+
+} CCrcRegData;
+
+/**
+ * CRC info structure.
+ */
+typedef struct {
+ CCrcRegData crcRegData[MAX_CRC_REGS]; /*!< Multiple crc region description. */
+ const USHORT*
+ pCrcLookup; /*!< Pointer to lookup table filled in FDK_crcInit(). */
+
+ USHORT crcPoly; /*!< CRC generator polynom. */
+ USHORT crcMask; /*!< CRC mask. */
+ USHORT startValue; /*!< CRC start value. */
+ UCHAR crcLen; /*!< CRC length. */
+
+ UINT regStart; /*!< Start region marker for synchronization. */
+ UINT regStop; /*!< Stop region marker for synchronization. */
+
+ USHORT crcValue; /*!< Crc value to be calculated. */
+
+} FDK_CRCINFO;
+
+/**
+ * CRC info handle.
+ */
+typedef FDK_CRCINFO* HANDLE_FDK_CRCINFO;
+
+/**
+ * \brief Initialize CRC structure.
+ *
+ * The function initializes existing crc info structure with denoted
+ * configuration.
+ *
+ * \param hCrcInfo Pointer to an outlying allocated crc info
+ * structure.
+ * \param crcPoly Configure crc polynom.
+ * \param crcStartValue Configure crc start value.
+ * \param crcLen Configure crc length.
+ *
+ * \return none
+ */
+void FDKcrcInit(HANDLE_FDK_CRCINFO hCrcInfo, const UINT crcPoly,
+ const UINT crcStartValue, const UINT crcLen);
+
+/**
+ * \brief Reset CRC info structure.
+ *
+ * This function clears all intern states of the crc structure.
+ *
+ * \param hCrcInfo Pointer to crc info stucture.
+ *
+ * \return none
+ */
+void FDKcrcReset(HANDLE_FDK_CRCINFO hCrcInfo);
+
+/**
+ * \brief Start CRC region with maximum number of bits.
+ *
+ * This function marks position in bitstream to be used as start point for crc
+ * calculation. Bitstream range for crc calculation can be limited or kept
+ * dynamic depending on mBits parameter. The crc region has to be terminated
+ * with FDKcrcEndReg() in each case.
+ *
+ * \param hCrcInfo Pointer to crc info stucture.
+ * \param hBs Pointer to current bit buffer structure.
+ * \param mBits Number of bits in crc region to be calculated.
+ * - mBits > 0: Zero padding will be used for CRC
+ * calculation, if there are less than mBits bits available.
+ * - mBits < 0: No zero padding is done.
+ * - mBits = 0: The number of bits used in crc
+ * calculation is dynamically, depending on bitstream position between
+ * FDKcrcStartReg() and FDKcrcEndReg()
+ * call.
+ *
+ * \return ID for the created region, -1 in case of an error
+ */
+INT FDKcrcStartReg(HANDLE_FDK_CRCINFO hCrcInfo, const HANDLE_FDK_BITSTREAM hBs,
+ const INT mBits);
+
+/**
+ * \brief Ends CRC region.
+ *
+ * This function terminates crc region specified with FDKcrcStartReg(). The
+ * number of bits in crc region depends on mBits parameter of FDKcrcStartReg().
+ * This function calculates and updates crc in info structure.
+ *
+ * \param hCrcInfo Pointer to crc info stucture.
+ * \param hBs Pointer to current bit buffer structure.
+ * \param reg Crc region ID created in FDKcrcStartReg().
+ *
+ * \return 0 on success
+ */
+INT FDKcrcEndReg(HANDLE_FDK_CRCINFO hCrcInfo, const HANDLE_FDK_BITSTREAM hBs,
+ const INT reg);
+
+/**
+ * \brief This function returns crc value from info struct.
+ *
+ * \param hCrcInfo Pointer to crc info stucture.
+ *
+ * \return CRC value masked with crc length.
+ */
+USHORT FDKcrcGetCRC(const HANDLE_FDK_CRCINFO hCrcInfo);
+
+#endif /* FDK_CRC_H */
diff --git a/fdk-aac/libFDK/include/FDK_decorrelate.h b/fdk-aac/libFDK/include/FDK_decorrelate.h
new file mode 100644
index 0000000..733aaae
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_decorrelate.h
@@ -0,0 +1,314 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Markus Lohwasser
+
+ Description: FDK Tools Decorrelator
+
+*******************************************************************************/
+
+#ifndef FDK_DECORRELATE_H
+#define FDK_DECORRELATE_H
+
+#include "common_fix.h"
+
+#define FIXP_MPS FIXP_DBL
+
+#ifndef ARCH_PREFER_MULT_32x32
+#define FIXP_DECORR FIXP_SGL
+#define FX_DECORR2FX_DBL FX_SGL2FX_DBL
+#define FX_DECORR2FX_SGL
+#define FX_DBL2FX_DECORR FX_DBL2FX_SGL
+#define FX_SGL2FX_DECORR
+#define DECORR(a) (FX_DBL2FXCONST_SGL(a))
+#define FL2FXCONST_DECORR FL2FXCONST_SGL
+#else
+#define FIXP_DECORR FIXP_DBL
+#define FX_DECORR2FX_DBL
+#define FX_DECORR2FX_SGL FX_DBL2FX_SGL
+#define FX_DBL2FX_DECORR
+#define FX_SGL2FX_DECORR FX_SGL2FX_DBL
+#define DECORR(a) FIXP_DBL(a)
+#define FL2FXCONST_DECORR FL2FXCONST_DBL
+#endif
+
+/*--------------- enums -------------------------------*/
+
+/**
+ * Decorrelator types.
+ */
+typedef enum {
+ DECORR_MPS, /**< Decorrelator type used by MPS LP/HQ */
+ DECORR_PS, /**< Decorrelator type used by HEAACv2 and MPS LP */
+ DECORR_USAC, /**< Decorrelator type used by USAC */
+ DECORR_LD /**< Decorrelator type used by MPS Low Delay */
+} FDK_DECORR_TYPE;
+
+/**
+ * Ducker types.
+ */
+typedef enum {
+ DUCKER_AUTOMATIC, /**< FDKdecorrelateInit() chooses correct ducker type
+ depending on provided parameters. */
+ DUCKER_MPS, /**< Force ducker type to MPS. */
+ DUCKER_PS /**< Force ducker type to PS. */
+} FDK_DUCKER_TYPE;
+
+/**
+ * Reverb band types.
+ */
+typedef enum {
+ NOT_EXIST, /**< Mark reverb band as non-existing (number of bands = 0). */
+ DELAY, /**< Reverb bands just contains delay elements and no allpass filters.
+ */
+ COMMON_REAL, /**< Real filter coeffs, common filter coeffs within one reverb
+ band */
+ COMMON_CPLX, /**< Complex filter coeffs, common filter coeffs within one
+ reverb band */
+ INDEP_CPLX, /**< Complex filter coeffs, independent filter coeffs for each
+ hybrid band */
+ INDEP_CPLX_PS /**< PS optimized implementation of general INDEP_CPLX type */
+} REVBAND_FILT_TYPE;
+
+typedef struct DECORR_DEC *HANDLE_DECORR_DEC;
+
+typedef struct DUCKER_INSTANCE {
+ int hybridBands;
+ int parameterBands;
+ int partiallyComplex;
+ FDK_DUCKER_TYPE duckerType;
+
+ const UCHAR *qs_next;
+ const UCHAR *mapProcBands2HybBands;
+ const UCHAR *mapHybBands2ProcBands;
+ /* interleaved SmoothDirectNrg[] and SmoothReverbNrg[],
+ non-interleaved SmoothDirectNrg[] in case of parametric stereo */
+ FIXP_MPS SmoothDirRevNrg[2 * (28)];
+
+ /*
+ parametric stereo
+ */
+ FIXP_MPS peakDecay[(28)];
+ FIXP_MPS peakDiff[(28)];
+ FIXP_DBL maxValDirectData;
+ FIXP_DBL maxValReverbData;
+ SCHAR scaleDirectNrg;
+ SCHAR scaleReverbNrg;
+ SCHAR scaleSmoothDirRevNrg;
+ SCHAR headroomSmoothDirRevNrg;
+
+} DUCKER_INSTANCE;
+
+typedef struct DECORR_FILTER_INSTANCE {
+ FIXP_MPS *stateCplx;
+ FIXP_DBL *DelayBufferCplx;
+
+ const FIXP_DECORR *numeratorReal;
+ const FIXP_STP *coeffsPacked;
+ const FIXP_DECORR *denominatorReal;
+} DECORR_FILTER_INSTANCE;
+
+typedef struct DECORR_DEC {
+ INT L_stateBufferCplx;
+ FIXP_DBL *stateBufferCplx;
+ INT L_delayBufferCplx;
+ FIXP_DBL *delayBufferCplx;
+
+ const REVBAND_FILT_TYPE *REV_filtType;
+ const UCHAR *REV_bandOffset;
+ const UCHAR *REV_delay;
+ const SCHAR *REV_filterOrder;
+ INT reverbBandDelayBufferIndex[(4)];
+ UCHAR stateBufferOffset[(3)];
+
+ DECORR_FILTER_INSTANCE Filter[(71)];
+ DUCKER_INSTANCE ducker;
+
+ int numbins;
+ int partiallyComplex;
+} DECORR_DEC;
+
+/**
+ * \brief Create one instance of Decorrelator.
+ *
+ * \param hDecorrDec A pointer to a decorrelator instance which was
+ * allocated externally.
+ * \param bufferCplx Externally allocated buffer (allocate (2*( ( 825 )
+ * + ( 373 ) )) FIXP_DBL values).
+ * \param bufLen Length of bufferCplx. Must be >= (2*( ( 825 ) + (
+ * 373 ) )).
+ *
+ * \return 0 on success.
+ */
+INT FDKdecorrelateOpen(HANDLE_DECORR_DEC hDecorrDec, FIXP_DBL *bufferCplx,
+ const INT bufLen);
+
+/**
+ * \brief Initialize and configure Decorrelator instance.
+ *
+ * \param hDecorrDec A Decorrelator handle.
+ * \param nrHybBands Number of (hybrid) bands.
+ * \param decorrType Decorrelator type to use.
+ * \param duckerType Ducker type to use (in general use
+ * DUCKER_AUTOMATIC).
+ * \param decorrConfig Depending on decorrType values of 0,1,2 are
+ * allowed.
+ * \param seed Seed of decorrelator instance. Allowed maximum
+ * valued depends on decorrType.
+ * \param partiallyComplex Low power or high quality processing 0: HQ, 1: LQ
+ * (only allowed for DECORR_MPS | DECORR_PS).
+ * \param useFractDelay Indicate usage of fractional delay 0: off, 1: on
+ * (currently not supported).
+ * \param isLegacyPS Indicate if DECORR_PS is used for HEAACv2 (for all
+ * other cases: isLegacyPS = 0). The purpose of this parameter is to select the
+ * correct number of param bands for the ducker.
+ * \param initStatesFlag Indicates whether the states buffer has to be
+ * cleared.
+ *
+ * \return 0 on success.
+ */
+INT FDKdecorrelateInit(HANDLE_DECORR_DEC hDecorrDec, const INT nrHybBands,
+ const FDK_DECORR_TYPE decorrType,
+ const FDK_DUCKER_TYPE duckerType, const INT decorrConfig,
+ const INT seed, const INT partiallyComplex,
+ const INT useFractDelay, const INT isLegacyPS,
+ const INT initStatesFlag);
+
+/**
+ * \brief Apply Decorrelator on input data.
+ *
+ * Function applies decorrelator and ducker inplace on hybrid input data.
+ * Modified hybrid data will be returned inplace.
+ *
+ * \param hDecorrDec A decorrelator handle.
+ * \param dataRealIn In (hybrid) data.
+ * \param dataImagIn In (hybrid) data.
+ * \param dataRealOut Out (hybrid) data (can be same as dataRealIn for
+ * in-place calculation).
+ * \param dataImagOut Out (hybrid) data (can be same as dataImagIn for
+ * in-place calculation).
+ * \param startHybBand Hybrid band to start with decorrelation.
+ *
+ * \return 0 on success.
+ */
+INT FDKdecorrelateApply(HANDLE_DECORR_DEC hDecorrDec, FIXP_DBL *dataRealIn,
+ FIXP_DBL *dataImagIn, FIXP_DBL *dataRealOut,
+ FIXP_DBL *dataImagOut, const INT startHybBand);
+
+/**
+ * \brief Destroy a Decorrelator instance.
+ *
+ * Deallocate whole memory of decorraltor and inside ducker.
+ *
+ * \param hDecorrDec Pointer to a decoderrolator handle. Null initialized on
+ * return.
+ *
+ * \return 0 on success.
+ */
+INT FDKdecorrelateClose(HANDLE_DECORR_DEC hDecorrDec);
+
+/**
+ * \brief Get max value address of direct signal.
+ *
+ * Get max value address of direct signal needed for ducker energy calculation.
+ *
+ * \param hDecorrDec Pointer to a decoderrolator handle.
+ *
+ * \return address of max value
+ */
+FIXP_DBL *getAddrDirectSignalMaxVal(HANDLE_DECORR_DEC hDecorrDec);
+
+#endif /* FDK_DECORRELATE_H */
diff --git a/fdk-aac/libFDK/include/FDK_hybrid.h b/fdk-aac/libFDK/include/FDK_hybrid.h
new file mode 100644
index 0000000..583f299
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_hybrid.h
@@ -0,0 +1,255 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Markus Lohwasser
+
+ Description: FDK Tools Hybrid Filterbank
+
+*******************************************************************************/
+
+#ifndef FDK_HYBRID_H
+#define FDK_HYBRID_H
+
+#include "common_fix.h"
+
+/*--------------- enums -------------------------------*/
+
+/**
+ * Hybrid Filterband modes.
+ */
+typedef enum {
+ THREE_TO_TEN,
+ THREE_TO_TWELVE,
+ THREE_TO_SIXTEEN
+
+} FDK_HYBRID_MODE;
+
+/*--------------- structure definitions ---------------*/
+typedef const struct FDK_HYBRID_SETUP *HANDLE_FDK_HYBRID_SETUP;
+
+typedef struct {
+ FIXP_DBL *bufferLFReal[3]; /*!< LF real filter states. */
+ FIXP_DBL *bufferLFImag[3]; /*!< LF imag filter states. */
+ FIXP_DBL *bufferHFReal[13]; /*!< HF real delay lines. */
+ FIXP_DBL *bufferHFImag[13]; /*!< HF imag delay lines. */
+
+ INT bufferLFpos; /*!< Position to write incoming data into ringbuffer. */
+ INT bufferHFpos; /*!< Delay line positioning. */
+ INT nrBands; /*!< Number of QMF bands. */
+ INT cplxBands; /*!< Number of complex QMF bands.*/
+ UCHAR hfMode; /*!< Flag signalizes treatment of HF bands. */
+
+ FIXP_DBL *pLFmemory; /*!< Pointer to LF states buffer. */
+ FIXP_DBL *pHFmemory; /*!< Pointer to HF states buffer. */
+
+ UINT LFmemorySize; /*!< Size of LF states buffer. */
+ UINT HFmemorySize; /*!< Size of HF states buffer. */
+
+ HANDLE_FDK_HYBRID_SETUP pSetup; /*!< Pointer to filter setup. */
+
+} FDK_ANA_HYB_FILTER;
+
+typedef struct {
+ INT nrBands; /*!< Number of QMF bands. */
+ INT cplxBands; /*!< Number of complex QMF bands.*/
+
+ HANDLE_FDK_HYBRID_SETUP pSetup; /*!< Pointer to filter setup. */
+
+} FDK_SYN_HYB_FILTER;
+
+typedef FDK_ANA_HYB_FILTER *HANDLE_FDK_ANA_HYB_FILTER;
+typedef FDK_SYN_HYB_FILTER *HANDLE_FDK_SYN_HYB_FILTER;
+
+/**
+ * \brief Create one instance of Hybrid Analyis Filterbank.
+ *
+ * \param hAnalysisHybFilter Pointer to an outlying allocated Hybrid Analysis
+ * Filterbank structure.
+ * \param pLFmemory Pointer to outlying buffer used LF filtering.
+ * \param LFmemorySize Size of pLFmemory in bytes.
+ * \param pHFmemory Pointer to outlying buffer used HF delay line.
+ * \param HFmemorySize Size of pLFmemory in bytes.
+ *
+ * \return 0 on success.
+ */
+INT FDKhybridAnalysisOpen(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
+ FIXP_DBL *const pLFmemory, const UINT LFmemorySize,
+ FIXP_DBL *const pHFmemory, const UINT HFmemorySize);
+
+/**
+ * \brief Initialize and configure Hybrid Analysis Filterbank instance.
+ *
+ * \param hAnalysisHybFilter A Hybrid Analysis Filterbank handle.
+ * \param mode Select hybrid filter configuration.
+ * \param qmfBands Number of qmf bands to be processed.
+ * \param cplxBands Number of complex qmf bands to be processed.
+ * \param initStatesFlag Indicates whether the states buffer has to be
+ * cleared.
+ *
+ * \return 0 on success.
+ */
+INT FDKhybridAnalysisInit(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
+ const FDK_HYBRID_MODE mode, const INT qmfBands,
+ const INT cplxBands, const INT initStatesFlag);
+
+/**
+ * \brief Adjust Hybrid Analysis Filterbank states.
+ *
+ * \param hAnalysisHybFilter A Hybrid Analysis Filterbank handle.
+ * \param scalingValue Scaling value to be applied on filter states.
+ *
+ * \return 0 on success.
+ */
+INT FDKhybridAnalysisScaleStates(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
+ const INT scalingValue);
+
+/**
+ * \brief Apply Hybrid Analysis Filterbank on Qmf input data.
+ *
+ * \param hAnalysisHybFilter A Hybrid Analysis Filterbank handle.
+ * \param pQmfReal Qmf input data.
+ * \param pQmfImag Qmf input data.
+ * \param pHybridReal Hybrid output data.
+ * \param pHybridImag Hybrid output data.
+ *
+ * \return 0 on success.
+ */
+INT FDKhybridAnalysisApply(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
+ const FIXP_DBL *const pQmfReal,
+ const FIXP_DBL *const pQmfImag,
+ FIXP_DBL *const pHybridReal,
+ FIXP_DBL *const pHybridImag);
+
+/**
+ * \brief Close a Hybrid Analysis Filterbank instance.
+ *
+ * \param hAnalysisHybFilter Pointer to a Hybrid Analysis Filterbank instance.
+ *
+ * \return 0 on success.
+ */
+INT FDKhybridAnalysisClose(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter);
+
+/**
+ * \brief Initialize and configure Hybrdid Synthesis Filterbank instance.
+ *
+ * \param hSynthesisHybFilter A Hybrid Synthesis Filterbank handle.
+ * \param mode Select hybrid filter configuration.
+ * \param qmfBands Number of qmf bands to be processed.
+ * \param cplxBands Number of complex qmf bands to be processed.
+ *
+ * \return 0 on success.
+ */
+INT FDKhybridSynthesisInit(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
+ const FDK_HYBRID_MODE mode, const INT qmfBands,
+ const INT cplxBands);
+
+/**
+ * \brief Apply Hybrid Analysis Filterbank on Hybrid data.
+ *
+ * \param hSynthesisHybFilter A Hybrid Analysis Filterbandk handle.
+ * \param pHybridReal Hybrid input data.
+ * \param pHybridImag Hybrid input data.
+ * \param pQmfReal Qmf output data.
+ * \param pQmfImag Qmf output data.
+ *
+ */
+void FDKhybridSynthesisApply(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
+ const FIXP_DBL *const pHybridReal,
+ const FIXP_DBL *const pHybridImag,
+ FIXP_DBL *const pQmfReal,
+ FIXP_DBL *const pQmfImag);
+
+#endif /* FDK_HYBRID_H */
diff --git a/fdk-aac/libFDK/include/FDK_lpc.h b/fdk-aac/libFDK/include/FDK_lpc.h
new file mode 100644
index 0000000..851dd1f
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_lpc.h
@@ -0,0 +1,218 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Manuel Jander
+
+ Description: LPC related functions
+
+*******************************************************************************/
+
+#ifndef FDK_LPC_H
+#define FDK_LPC_H
+
+#include "common_fix.h"
+
+#define LPC_MAX_ORDER 24
+
+/*
+ * Experimental solution for lattice filter substitution.
+ * LPC_SYNTHESIS_IIR macro must be activated in aacdec_tns.cpp.
+ * When LPC_SYNTHESIS_IIR enabled, there will be a substitution of the default
+ * lpc synthesis lattice filter by an IIR synthesis filter (with a conversionof
+ * the filter coefs). LPC_TNS related macros are intended to implement the data
+ * types used by the CLpc_Synthesis variant which is used for this solution.
+ * */
+
+/* #define LPC_TNS_LOWER_PRECISION */
+
+typedef FIXP_DBL FIXP_LPC_TNS;
+#define FX_DBL2FX_LPC_TNS(x) (x)
+#define FX_DBL2FXCONST_LPC_TNS(x) (x)
+#define FX_LPC_TNS2FX_DBL(x) (x)
+#define FL2FXCONST_LPC_TNS(val) FL2FXCONST_DBL(val)
+#define MAXVAL_LPC_TNS MAXVAL_DBL
+
+typedef FIXP_SGL FIXP_LPC;
+#define FX_DBL2FX_LPC(x) FX_DBL2FX_SGL((FIXP_DBL)(x))
+#define FX_DBL2FXCONST_LPC(x) FX_DBL2FXCONST_SGL(x)
+#define FX_LPC2FX_DBL(x) FX_SGL2FX_DBL(x)
+#define FL2FXCONST_LPC(val) FL2FXCONST_SGL(val)
+#define MAXVAL_LPC MAXVAL_SGL
+
+/**
+ * \brief Obtain residual signal through LPC analysis.
+ * \param signal pointer to buffer holding signal to be analysed. Residual is
+ * returned there (in place)
+ * \param signal_size the size of the input data in pData
+ * \param lpcCoeff_m the LPC filter coefficient mantissas
+ * \param lpcCoeff_e the LPC filter coefficient exponent
+ * \param order the LPC filter order (size of coeff)
+ * \param filtState Pointer to state buffer of size order
+ * \param filtStateIndex pointer to state index storage
+ */
+void CLpc_Analysis(FIXP_DBL signal[], const int signal_size,
+ const FIXP_LPC lpcCoeff_m[], const int lpcCoeff_e,
+ const int order, FIXP_DBL *filtState, int *filtStateIndex);
+
+/**
+ * \brief Synthesize signal fom residual through LPC synthesis, using LP
+ * coefficients.
+ * \param signal pointer to buffer holding the residual signal. The synthesis is
+ * returned there (in place)
+ * \param signal_size the size of the input data in pData
+ * \param inc buffer traversal increment for signal
+ * \param coeff the LPC filter coefficients
+ * \param coeff_e exponent of coeff
+ * \param order the LPC filter order (size of coeff)
+ * \param state state buffer of size LPC_MAX_ORDER
+ * \param pStateIndex pointer to state index storage
+ */
+void CLpc_Synthesis(FIXP_DBL *signal, const int signal_size, const int signal_e,
+ const int inc, const FIXP_LPC_TNS *lpcCoeff_m,
+ const int lpcCoeff_e, const int order, FIXP_DBL *state,
+ int *pStateIndex);
+void CLpc_Synthesis(FIXP_DBL *signal, const int signal_size, const int signal_e,
+ const int inc, const FIXP_LPC coeff[], const int coeff_e,
+ const int order, FIXP_DBL *filtState, int *pStateIndex);
+
+/**
+ * \brief Synthesize signal fom residual through LPC synthesis, using ParCor
+ * coefficients. The algorithm assumes a filter gain of max 1.0. If the filter
+ * gain is higher, this must be accounted into the values of signal_e
+ * and/or signal_e_out to avoid overflows.
+ * \param signal pointer to buffer holding the residual signal. The synthesis is
+ * returned there (in place)
+ * \param signal_size the size of the input data in pData
+ * \param inc buffer traversal increment for signal
+ * \param coeff the LPC filter coefficients
+ * \param coeff_e exponent of coeff
+ * \param order the LPC filter order (size of coeff)
+ * \param state state buffer of size LPC_MAX_ORDER
+ */
+void CLpc_SynthesisLattice(FIXP_DBL *signal, const int signal_size,
+ const int signal_e, const int signal_e_out,
+ const int inc, const FIXP_SGL *coeff,
+ const int order, FIXP_DBL *state);
+
+void CLpc_SynthesisLattice(FIXP_DBL *RESTRICT signal, const int signal_size,
+ const int signal_e, const int signal_e_out,
+ const int inc, const FIXP_DBL *RESTRICT coeff,
+ const int order, FIXP_DBL *RESTRICT state);
+
+/**
+ * \brief
+ */
+INT CLpc_ParcorToLpc(const FIXP_LPC_TNS reflCoeff[], FIXP_LPC_TNS LpcCoeff[],
+ INT numOfCoeff, FIXP_DBL workBuffer[]);
+INT CLpc_ParcorToLpc(const FIXP_LPC reflCoeff[], FIXP_LPC LpcCoeff[],
+ const int numOfCoeff, FIXP_DBL workBuffer[]);
+
+/**
+ * \brief Calculate ParCor (Partial autoCorrelation, reflection) coefficients
+ * from autocorrelation coefficients using the Schur algorithm (instead of
+ * Levinson Durbin).
+ * \param acorr order+1 autocorrelation coefficients
+ * \param reflCoeff output reflection /ParCor coefficients. The first
+ * coefficient which is always 1.0 is ommitted.
+ * \param order number of acorr / reflCoeff coefficients.
+ * \param pPredictionGain_m prediction gain mantissa
+ * \param pPredictionGain_e prediction gain exponent
+ */
+void CLpc_AutoToParcor(FIXP_DBL acorr[], const int acorr_e,
+ FIXP_LPC reflCoeff[], const int order,
+ FIXP_DBL *pPredictionGain_m, INT *pPredictionGain_e);
+
+#endif /* FDK_LPC_H */
diff --git a/fdk-aac/libFDK/include/FDK_matrixCalloc.h b/fdk-aac/libFDK/include/FDK_matrixCalloc.h
new file mode 100644
index 0000000..ffb54fe
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_matrixCalloc.h
@@ -0,0 +1,230 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: matrix memory allocation
+
+*******************************************************************************/
+
+#ifndef FDK_MATRIXCALLOC_H
+#define FDK_MATRIXCALLOC_H
+
+#include "machine_type.h"
+#include "genericStds.h"
+
+/* It is recommended to use FDK_ALLOCATE_MEMORY_1D instead of fdkCallocMatrix1D
+ */
+void* fdkCallocMatrix1D(UINT dim1, UINT size);
+void* fdkCallocMatrix1D_aligned(UINT dim1, UINT size);
+/* It is recommended to use FDK_ALLOCATE_MEMORY_1D_INT instead of
+ * fdkCallocMatrix1D_int */
+void* fdkCallocMatrix1D_int(UINT dim1, UINT size, MEMORY_SECTION s);
+void* fdkCallocMatrix1D_int_aligned(UINT dim1, UINT size, MEMORY_SECTION s);
+/* It is recommended to use FDK_FREE_MEMORY_1D instead of fdkFreeMatrix1D */
+void fdkFreeMatrix1D(void* p);
+void fdkFreeMatrix1D_aligned(void* p);
+
+/* It is recommended to use FDK_ALLOCATE_MEMORY_2D instead of fdkCallocMatrix2D
+ */
+void** fdkCallocMatrix2D(UINT dim1, UINT dim2, UINT size);
+void** fdkCallocMatrix2D_aligned(UINT dim1, UINT dim2, UINT size);
+/* It is recommended to use FDK_ALLOCATE_MEMORY_2D_INT instead of
+ * fdkCallocMatrix2D_int */
+void** fdkCallocMatrix2D_int(UINT dim1, UINT dim2, UINT size, MEMORY_SECTION s);
+/* It is recommended to use FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED instead of
+ * fdkCallocMatrix2D_int_aligned */
+void** fdkCallocMatrix2D_int_aligned(UINT dim1, UINT dim2, UINT size,
+ MEMORY_SECTION s);
+/* It is recommended to use FDK_FREE_MEMORY_2D instead of fdkFreeMatrix2D */
+void fdkFreeMatrix2D(void** p);
+/* It is recommended to use FDK_FREE_MEMORY_2D_ALIGNED instead of
+ * fdkFreeMatrix2D_aligned */
+void fdkFreeMatrix2D_aligned(void** p);
+
+/* It is recommended to use FDK_ALLOCATE_MEMORY_3D instead of fdkCallocMatrix3D
+ */
+void*** fdkCallocMatrix3D(UINT dim1, UINT dim2, UINT dim3, UINT size);
+/* It is recommended to use FDK_ALLOCATE_MEMORY_3D_INT instead of
+ * fdkCallocMatrix3D_int */
+void*** fdkCallocMatrix3D_int(UINT dim1, UINT dim2, UINT dim3, UINT size,
+ MEMORY_SECTION s);
+/* It is recommended to use FDK_FREE_MEMORY_3D instead of fdkFreeMatrix3D */
+void fdkFreeMatrix3D(void*** p);
+
+#define FDK_ALLOCATE_MEMORY_1D(a, dim1, type) \
+ if (((a) = (type*)fdkCallocMatrix1D((dim1), sizeof(type))) == NULL) { \
+ goto bail; \
+ }
+
+#define FDK_ALLOCATE_MEMORY_1D_ALIGNED(a, dim1, type) \
+ if (((a) = (type*)fdkCallocMatrix1D_aligned((dim1), sizeof(type))) == \
+ NULL) { \
+ goto bail; \
+ }
+
+#define FDK_ALLOCATE_MEMORY_1D_P(a, dim1, type, ptype) \
+ if (((a) = (ptype)fdkCallocMatrix1D((dim1), sizeof(type))) == NULL) { \
+ goto bail; \
+ }
+
+#define FDK_ALLOCATE_MEMORY_1D_INT(a, dim1, type, s) \
+ if (((a) = (type*)fdkCallocMatrix1D_int((dim1), sizeof(type), (s))) == \
+ NULL) { \
+ goto bail; \
+ }
+
+#define FDK_FREE_MEMORY_1D(a) \
+ do { \
+ fdkFreeMatrix1D((void*)(a)); \
+ (a) = NULL; \
+ } while (0)
+
+#define FDK_FREE_MEMORY_1D_ALIGNED(a) \
+ do { \
+ fdkFreeMatrix1D_aligned((void*)(a)); \
+ (a) = NULL; \
+ } while (0)
+
+#define FDK_ALLOCATE_MEMORY_2D(a, dim1, dim2, type) \
+ if (((a) = (type**)fdkCallocMatrix2D((dim1), (dim2), sizeof(type))) == \
+ NULL) { \
+ goto bail; \
+ }
+
+#define FDK_ALLOCATE_MEMORY_2D_INT(a, dim1, dim2, type, s) \
+ if (((a) = (type**)fdkCallocMatrix2D_int((dim1), (dim2), sizeof(type), \
+ (s))) == NULL) { \
+ goto bail; \
+ }
+
+#define FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(a, dim1, dim2, type, s) \
+ if (((a) = (type**)fdkCallocMatrix2D_int_aligned( \
+ (dim1), (dim2), sizeof(type), (s))) == NULL) { \
+ goto bail; \
+ }
+
+#define FDK_FREE_MEMORY_2D(a) \
+ do { \
+ fdkFreeMatrix2D((void**)(a)); \
+ (a) = NULL; \
+ } while (0)
+
+#define FDK_FREE_MEMORY_2D_ALIGNED(a) \
+ do { \
+ fdkFreeMatrix2D_aligned((void**)(a)); \
+ (a) = NULL; \
+ } while (0)
+
+#define FDK_ALLOCATE_MEMORY_3D(a, dim1, dim2, dim3, type) \
+ if (((a) = (type***)fdkCallocMatrix3D((dim1), (dim2), (dim3), \
+ sizeof(type))) == NULL) { \
+ goto bail; \
+ }
+
+#define FDK_ALLOCATE_MEMORY_3D_INT(a, dim1, dim2, dim3, type, s) \
+ if (((a) = (type***)fdkCallocMatrix3D_int((dim1), (dim2), (dim3), \
+ sizeof(type), (s))) == NULL) { \
+ goto bail; \
+ }
+
+#define FDK_FREE_MEMORY_3D(a) \
+ do { \
+ fdkFreeMatrix3D((void***)(a)); \
+ (a) = NULL; \
+ } while (0)
+
+#endif /* FDK_MATRIXCALLOC_H */
diff --git a/fdk-aac/libFDK/include/FDK_qmf_domain.h b/fdk-aac/libFDK/include/FDK_qmf_domain.h
new file mode 100644
index 0000000..5c12682
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_qmf_domain.h
@@ -0,0 +1,416 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: Module to efficiently handle QMF data for multiple channels and
+ to share the data between e.g. SBR and MPS
+
+*******************************************************************************/
+
+#ifndef FDK_QMF_DOMAIN_H
+#define FDK_QMF_DOMAIN_H
+
+#include "qmf.h"
+
+typedef enum {
+ QMF_DOMAIN_OK = 0x0, /*!< No error occurred. */
+ QMF_DOMAIN_OUT_OF_MEMORY =
+ 0x1, /*!< QMF-Configuration demands for more memory than allocated on
+ heap. */
+ QMF_DOMAIN_INIT_ERROR =
+ 0x2, /*!< An error during filterbank-setup occurred. */
+ QMF_DOMAIN_RESAMPLER_INIT_ERROR =
+ 0x3 /*!< An error during QMF-resampler-setup occurred. */
+} QMF_DOMAIN_ERROR;
+
+#define CMPLX_MOD (2)
+
+#define QMF_MAX_WB_SECTIONS (5) /* maximum number of workbuffer sections */
+#define QMF_WB_SECTION_SIZE (1024 * 2)
+
+H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL)
+H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL)
+H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL)
+H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL)
+H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL)
+H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL)
+
+#define QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS (64)
+#define QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS (QMF_MAX_SYNTHESIS_BANDS)
+#define QMF_DOMAIN_MAX_QMF_PROC_BANDS (64)
+#define QMF_DOMAIN_MAX_TIMESLOTS (64)
+#define QMF_DOMAIN_MAX_OV_TIMESLOTS (12)
+
+#define QMF_DOMAIN_ANALYSIS_QMF_BANDS_16 (16)
+#define QMF_DOMAIN_ANALYSIS_QMF_BANDS_24 (24)
+#define QMF_DOMAIN_ANALYSIS_QMF_BANDS_32 (32)
+
+#define QMF_DOMAIN_TIMESLOTS_16 (16)
+#define QMF_DOMAIN_TIMESLOTS_32 (32)
+
+#define QMF_DOMAIN_OV_TIMESLOTS_16 (3)
+#define QMF_DOMAIN_OV_TIMESLOTS_32 (6)
+
+H_ALLOC_MEM(AnaQmfStates, FIXP_QAS)
+H_ALLOC_MEM(SynQmfStates, FIXP_QSS)
+H_ALLOC_MEM(QmfSlotsReal, FIXP_DBL *)
+H_ALLOC_MEM(QmfSlotsImag, FIXP_DBL *)
+H_ALLOC_MEM(QmfOverlapBuffer, FIXP_DBL)
+
+H_ALLOC_MEM(AnaQmfStates16, FIXP_QAS)
+H_ALLOC_MEM(AnaQmfStates24, FIXP_QAS)
+H_ALLOC_MEM(AnaQmfStates32, FIXP_QAS)
+H_ALLOC_MEM(QmfSlotsReal16, FIXP_DBL *)
+H_ALLOC_MEM(QmfSlotsReal32, FIXP_DBL *)
+H_ALLOC_MEM(QmfSlotsImag16, FIXP_DBL *)
+H_ALLOC_MEM(QmfSlotsImag32, FIXP_DBL *)
+H_ALLOC_MEM(QmfOverlapBuffer16, FIXP_DBL)
+H_ALLOC_MEM(QmfOverlapBuffer32, FIXP_DBL)
+
+#define QDOM_PCM INT_PCM
+
+/**
+ * Structure to hold the configuration data which is global whithin a QMF domain
+ * instance.
+ */
+typedef struct {
+ UCHAR qmfDomainExplicitConfig; /*!< Flag to signal that QMF domain is set
+ explicitly instead of SBR and MPS init
+ routines. */
+ UCHAR nInputChannels; /*!< Number of QMF input channels. */
+ UCHAR nInputChannels_requested; /*!< Corresponding requested not yet active
+ configuration parameter. */
+ UCHAR nOutputChannels; /*!< Number of QMF output channels. */
+ UCHAR nOutputChannels_requested; /*!< Corresponding requested not yet active
+ configuration parameter. */
+ UCHAR
+ parkChannel; /*!< signal to automatically allocate additional memory to
+ park a channel if only one processing channel is
+ available. */
+ UCHAR parkChannel_requested;
+ QDOM_PCM
+ *TDinput; /*!< Pointer to time domain data used as input for the QMF
+ analysis. */
+ FIXP_DBL *
+ pWorkBuffer[QMF_MAX_WB_SECTIONS]; /*!< Pointerarray to volatile memory. */
+ UINT flags; /*!< Flags to be set on all QMF analysis/synthesis filter
+ instances. */
+ UINT flags_requested; /*!< Corresponding requested not yet active
+ configuration parameter. */
+ UCHAR nBandsAnalysis; /*!< Number of QMF analysis bands for all input
+ channels. */
+ UCHAR nBandsAnalysis_requested; /*!< Corresponding requested not yet active
+ configuration parameter. */
+ USHORT nBandsSynthesis; /*!< Number of QMF synthesis bands for all output
+ channels. */
+ USHORT
+ nBandsSynthesis_requested; /*!< Corresponding requested not yet active
+ configuration parameter. */
+ UCHAR nQmfTimeSlots; /*!< Number of QMF time slots (stored in work buffer
+ memory). */
+ UCHAR nQmfTimeSlots_requested; /*!< Corresponding requested not yet active
+ configuration parameter. */
+ UCHAR
+ nQmfOvTimeSlots; /*!< Number of QMF overlap/delay time slots (stored in
+ persistent memory). */
+ UCHAR nQmfOvTimeSlots_requested; /*!< Corresponding requested not yet active
+ configuration parameter. */
+ UCHAR nQmfProcBands; /*!< Number of QMF bands which are processed by the
+ decoder. Typically this is equal to nBandsSynthesis
+ but it may differ if the QMF based resampler is being
+ used. */
+ UCHAR nQmfProcBands_requested; /*!< Corresponding requested not yet active
+ configuration parameter. */
+ UCHAR
+ nQmfProcChannels; /*!< Number of complete QMF channels which need to
+ coexist in memory at the same time. For most cases
+ this is 1 which means the work buffer can be shared
+ between audio channels. */
+ UCHAR
+ nQmfProcChannels_requested; /*!< Corresponding requested not yet active
+ configuration parameter. */
+} FDK_QMF_DOMAIN_GC;
+typedef FDK_QMF_DOMAIN_GC *HANDLE_FDK_QMF_DOMAIN_GC;
+
+/**
+ * Structure representing one QMF input channel. This includes the QMF analysis
+ * and the QMF domain data representation needed by the codec. Work buffer data
+ * may be shared between channels if the codec processes all QMF channels in a
+ * consecutive order.
+ */
+typedef struct {
+ HANDLE_FDK_QMF_DOMAIN_GC
+ pGlobalConf; /*!< Pointer to global configuration structure. */
+ QMF_FILTER_BANK fb; /*!< QMF (analysis) filter bank structure. */
+ QMF_SCALE_FACTOR scaling; /*!< Structure with scaling information. */
+ UCHAR workBuf_nTimeSlots; /*!< Work buffer dimension for this channel is
+ (workBuf_nTimeSlots * workBuf_nBands *
+ CMPLX_MOD). */
+ UCHAR workBuf_nBands; /*!< Work buffer dimension for this channel is
+ (workBuf_nTimeSlots * workBuf_nBands * CMPLX_MOD). */
+ USHORT workBufferOffset; /*!< Offset within work buffer. */
+ USHORT workBufferSectSize; /*!< Size of work buffer section. */
+ FIXP_QAS *
+ pAnaQmfStates; /*!< Pointer to QMF analysis states (persistent memory). */
+ FIXP_DBL
+ *pOverlapBuffer; /*!< Pointer to QMF overlap/delay memory (persistent
+ memory). */
+ FIXP_DBL **pWorkBuffer; /*!< Pointer array to available work buffers. */
+ FIXP_DBL *
+ *hQmfSlotsReal; /*!< Handle for QMF real data time slot pointer array. */
+ FIXP_DBL **hQmfSlotsImag; /*!< Handle for QMF imaginary data time slot pointer
+ array. */
+} FDK_QMF_DOMAIN_IN;
+typedef FDK_QMF_DOMAIN_IN *HANDLE_FDK_QMF_DOMAIN_IN;
+
+/**
+ * Structure representing one QMF output channel.
+ */
+typedef struct {
+ QMF_FILTER_BANK fb; /*!< QMF (synthesis) filter bank structure. */
+ FIXP_QSS *pSynQmfStates; /*!< Pointer to QMF synthesis states (persistent
+ memory). */
+} FDK_QMF_DOMAIN_OUT;
+typedef FDK_QMF_DOMAIN_OUT *HANDLE_FDK_QMF_DOMAIN_OUT;
+
+/**
+ * Structure representing the QMF domain for multiple channels.
+ */
+typedef struct {
+ FDK_QMF_DOMAIN_GC globalConf; /*!< Global configuration structure. */
+ FDK_QMF_DOMAIN_IN
+ QmfDomainIn[((8) + (1))]; /*!< Array of QMF domain input structures */
+ FDK_QMF_DOMAIN_OUT
+ QmfDomainOut[((8) + (1))]; /*!< Array of QMF domain output structures */
+} FDK_QMF_DOMAIN;
+typedef FDK_QMF_DOMAIN *HANDLE_FDK_QMF_DOMAIN;
+
+/**
+ * \brief Check whether analysis- and synthesis-filterbank-states have been
+ * initialized.
+ *
+ * \param qd Pointer to QMF domain structure.
+ *
+ * \return 1 if initialized, 0 else
+ */
+int FDK_QmfDomain_IsInitialized(const HANDLE_FDK_QMF_DOMAIN qd);
+
+/**
+ * \brief Initialize QMF analysis and synthesis filter banks and set up QMF data
+ * representation.
+ *
+ * \param qd Pointer to QMF domain structure.
+ * \param extra_flags Initialize filter banks with extra flags which were not
+ * set in the global config flags field.
+ *
+ * \return 0 on success.
+ */
+int FDK_QmfDomain_InitFilterBank(HANDLE_FDK_QMF_DOMAIN qd, UINT extra_flags);
+
+/**
+ * \brief When QMF processing of one channel is finished copy the overlap/delay
+ * part into the persistent memory to be used in the next frame.
+ *
+ * \param qd_ch Pointer to a QMF domain input channel.
+ * \param offset
+ *
+ * \return void
+ */
+void FDK_QmfDomain_SaveOverlap(HANDLE_FDK_QMF_DOMAIN_IN qd_ch, int offset);
+
+/**
+ * \brief Get one slot of QMF data and adapt the scaling.
+ *
+ * \param qd_ch Pointer to a QMF domain input channel.
+ * \param ts Time slot number to be obtained.
+ * \param start_band Start index of QMF bands to be obtained.
+ * \param stop_band Stop index of QMF band to be obtained.
+ * \param pQmfOutReal Output buffer (real QMF data).
+ * \param pQmfOutImag Output buffer (imag QMF data).
+ * \param exp_out Target exponent (scaling) of data.
+ *
+ * \return void
+ */
+void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
+ const int start_band, const int stop_band,
+ FIXP_DBL *pQmfOutReal, FIXP_DBL *pQmfOutImag,
+ const int exp_out);
+
+/**
+ * \brief Direct access to the work buffer associated with a certain channel (no
+ * time slot pointer array is used).
+ *
+ * \param qd_ch Pointer to a QMF domain input channel.
+ * \param ts Time slot number to be obtained.
+ * \param ppQmfReal Returns the pointer to the requested part of the work buffer
+ * (real time slot).
+ * \param ppQmfImag Returns the pointer to the requested part of the work buffer
+ * (imag time slot).
+ *
+ * \return void
+ */
+void FDK_QmfDomain_GetWorkBuffer(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch,
+ const int ts, FIXP_DBL **ppQmfReal,
+ FIXP_DBL **ppQmfImag);
+
+/**
+ * \brief For the case that the work buffer associated to this channel is not
+ * identical to the processing channel work buffer copy the data into the
+ * processing channel.
+ *
+ * \param qd_ch Pointer to a QMF domain input channel.
+ * \return void
+ */
+void FDK_QmfDomain_WorkBuffer2ProcChannel(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch);
+
+/**
+ * \brief For the case of stereoCfgIndex3 with HBE the HBE buffer is copied into
+ * the processing channel work buffer and the processing channel work buffer is
+ * copied into the HBE buffer.
+ *
+ * \param qd_ch Pointer to a QMF domain input channel.
+ * \param ppQmfReal Pointer to a HBE QMF data buffer (real).
+ * \param ppQmfImag Pointer to a HBE QMF data buffer (imag).
+ *
+ * \return void
+ */
+void FDK_QmfDomain_QmfData2HBE(HANDLE_FDK_QMF_DOMAIN_IN qd_ch,
+ FIXP_DBL **ppQmfReal, FIXP_DBL **ppQmfImag);
+
+/**
+ * \brief Set all fields for requested parametervalues in global config struct
+ * FDK_QMF_DOMAIN_GC to 0.
+ *
+ * \param hgc Pointer to a QMF domain global config struct.
+ */
+void FDK_QmfDomain_ClearRequested(HANDLE_FDK_QMF_DOMAIN_GC hgc);
+
+/**
+ * \brief Check for parameter-change requests in global config and
+ * (re-)configure QMF domain accordingly.
+ *
+ * \param hqd Pointer to QMF domain
+ *
+ * \return errorcode
+ */
+QMF_DOMAIN_ERROR FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd);
+
+/**
+ * \brief Free QMF workbuffer, QMF persistent memory and configuration
+ * variables.
+ *
+ * \param hqd Pointer to QMF domain
+ */
+void FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd);
+
+/**
+ * \brief Clear QMF overlap buffers and QMF filter bank states.
+ *
+ * \param hqd Pointer to QMF domain
+ */
+QMF_DOMAIN_ERROR FDK_QmfDomain_ClearPersistentMemory(HANDLE_FDK_QMF_DOMAIN hqd);
+
+/**
+ * \brief Free QMF workbuffer and QMF persistent memory.
+ *
+ * \param hqd Pointer to QMF domain
+ *
+ * \param dmx_lp_mode downmix low power mode flag
+ */
+void FDK_QmfDomain_Close(HANDLE_FDK_QMF_DOMAIN hqd);
+
+#endif /* FDK_QMF_DOMAIN_H */
diff --git a/fdk-aac/libFDK/include/FDK_tools_rom.h b/fdk-aac/libFDK/include/FDK_tools_rom.h
new file mode 100644
index 0000000..d1cb980
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_tools_rom.h
@@ -0,0 +1,398 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Oliver Moser
+
+ Description: ROM tables used by FDK tools
+
+*******************************************************************************/
+
+#ifndef FDK_TOOLS_ROM_H
+#define FDK_TOOLS_ROM_H
+
+#include "common_fix.h"
+#include "FDK_audio.h"
+
+/* sinetables */
+
+/* None radix2 rotation vectors */
+extern RAM_ALIGN const FIXP_STB RotVectorReal60[60];
+extern RAM_ALIGN const FIXP_STB RotVectorImag60[60];
+extern RAM_ALIGN const FIXP_STB RotVectorReal192[192];
+extern RAM_ALIGN const FIXP_STB RotVectorImag192[192];
+extern RAM_ALIGN const FIXP_STB RotVectorReal240[210];
+extern RAM_ALIGN const FIXP_STB RotVectorImag240[210];
+extern RAM_ALIGN const FIXP_STB RotVectorReal480[480];
+extern RAM_ALIGN const FIXP_STB RotVectorImag480[480];
+extern RAM_ALIGN const FIXP_STB RotVectorReal6[6];
+extern RAM_ALIGN const FIXP_STB RotVectorImag6[6];
+extern RAM_ALIGN const FIXP_STB RotVectorReal12[12];
+extern RAM_ALIGN const FIXP_STB RotVectorImag12[12];
+extern RAM_ALIGN const FIXP_STB RotVectorReal24[24];
+extern RAM_ALIGN const FIXP_STB RotVectorImag24[24];
+extern RAM_ALIGN const FIXP_STB RotVectorReal48[48];
+extern RAM_ALIGN const FIXP_STB RotVectorImag48[48];
+extern RAM_ALIGN const FIXP_STB RotVectorReal80[80];
+extern RAM_ALIGN const FIXP_STB RotVectorImag80[80];
+extern RAM_ALIGN const FIXP_STB RotVectorReal96[96];
+extern RAM_ALIGN const FIXP_STB RotVectorImag96[96];
+extern RAM_ALIGN const FIXP_STB RotVectorReal384[384];
+extern RAM_ALIGN const FIXP_STB RotVectorImag384[384];
+extern RAM_ALIGN const FIXP_STB RotVectorReal20[20];
+extern RAM_ALIGN const FIXP_STB RotVectorImag20[20];
+extern RAM_ALIGN const FIXP_STB RotVectorReal120[120];
+extern RAM_ALIGN const FIXP_STB RotVectorImag120[120];
+
+/* Regular sine tables */
+extern RAM_ALIGN const FIXP_STP SineTable1024[];
+extern RAM_ALIGN const FIXP_STP SineTable512[];
+extern RAM_ALIGN const FIXP_STP SineTable480[];
+extern RAM_ALIGN const FIXP_STP SineTable384[];
+extern RAM_ALIGN const FIXP_STP SineTable80[];
+#ifdef INCLUDE_SineTable10
+extern RAM_ALIGN const FIXP_STP SineTable10[];
+#endif
+
+/* AAC-LC windows */
+extern RAM_ALIGN const FIXP_WTP SineWindow1024[];
+extern RAM_ALIGN const FIXP_WTP KBDWindow1024[];
+extern RAM_ALIGN const FIXP_WTP SineWindow128[];
+extern RAM_ALIGN const FIXP_WTP KBDWindow128[];
+
+extern RAM_ALIGN const FIXP_WTP SineWindow960[];
+extern RAM_ALIGN const FIXP_WTP KBDWindow960[];
+extern RAM_ALIGN const FIXP_WTP SineWindow120[];
+extern RAM_ALIGN const FIXP_WTP KBDWindow120[];
+
+/* AAC-LD windows */
+extern RAM_ALIGN const FIXP_WTP SineWindow512[];
+#define LowOverlapWindow512 SineWindow128
+extern RAM_ALIGN const FIXP_WTP SineWindow480[];
+#define LowOverlapWindow480 SineWindow120
+
+/* USAC TCX Window */
+extern RAM_ALIGN const FIXP_WTP SineWindow256[256];
+extern RAM_ALIGN const FIXP_WTP SineWindow192[];
+
+/* USAC 8/3 windows */
+extern RAM_ALIGN const FIXP_WTP SineWindow768[];
+extern RAM_ALIGN const FIXP_WTP KBDWindow768[];
+extern RAM_ALIGN const FIXP_WTP SineWindow96[];
+extern RAM_ALIGN const FIXP_WTP KBDWindow96[];
+
+/* DCT and others */
+extern RAM_ALIGN const FIXP_WTP SineWindow64[];
+extern RAM_ALIGN const FIXP_WTP SineWindow48[];
+extern RAM_ALIGN const FIXP_WTP SineWindow32[];
+extern RAM_ALIGN const FIXP_WTP SineWindow24[];
+extern RAM_ALIGN const FIXP_WTP SineWindow16[];
+extern RAM_ALIGN const FIXP_WTP SineWindow8[];
+
+/**
+ * \brief Helper table for window slope mapping. You should prefer the usage of
+ * the function FDKgetWindowSlope(), this table is only made public for some
+ * optimized access inside dct.cpp.
+ */
+extern const FIXP_WTP *const windowSlopes[2][4][9];
+
+/**
+ * \brief Window slope access helper. Obtain a window of given length and shape.
+ * \param length Length of the window slope.
+ * \param shape Shape index of the window slope. 0: sine window, 1:
+ * Kaiser-Bessel. Any other value is applied a mask of 1 to, mapping it to
+ * either 0 or 1.
+ * \param Pointer to window slope or NULL if the requested window slope is not
+ * available.
+ */
+const FIXP_WTP *FDKgetWindowSlope(int length, int shape);
+
+extern const FIXP_WTP sin_twiddle_L64[];
+
+/*
+ * Filter coefficient type definition
+ */
+
+#if defined(ARCH_PREFER_MULT_16x16) || defined(ARCH_PREFER_MULT_32x16)
+#define QMF_COEFF_16BIT
+#endif
+
+#define QMF_FILTER_PROTOTYPE_SIZE 640
+#define QMF_NO_POLY 5
+
+#ifdef QMF_COEFF_16BIT
+#define FIXP_PFT FIXP_SGL
+#define FIXP_QTW FIXP_SGL
+#define FX_DBL2FX_QTW(x) FX_DBL2FX_SGL(x)
+#else
+#define FIXP_PFT FIXP_DBL
+#define FIXP_QTW FIXP_DBL
+
+#define FX_DBL2FX_QTW(x) (x)
+
+#endif
+
+#define QMF640_PFT_TABLE_SIZE (640 / 2 + QMF_NO_POLY)
+
+/* Resampling twiddles for QMF */
+
+/* Not resampling twiddles */
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_cos32[32];
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_sin32[32];
+/* Adapted analysis post-twiddles for down-sampled HQ SBR */
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_cos_downsamp32[32];
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_sin_downsamp32[32];
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_cos64[64];
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_sin64[64];
+extern RAM_ALIGN const FIXP_PFT
+ qmf_pfilt640[QMF640_PFT_TABLE_SIZE + QMF_NO_POLY];
+extern RAM_ALIGN const FIXP_PFT qmf_pfilt640_vector[640];
+
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_cos40[40];
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_sin40[40];
+extern RAM_ALIGN const FIXP_PFT qmf_pfilt400[];
+extern RAM_ALIGN const FIXP_PFT qmf_pfilt200[];
+extern RAM_ALIGN const FIXP_PFT qmf_pfilt120[];
+
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_cos24[24];
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_sin24[24];
+extern RAM_ALIGN const FIXP_PFT qmf_pfilt240[];
+
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_cos16[16];
+extern RAM_ALIGN const FIXP_QTW qmf_phaseshift_sin16[16];
+
+#define QMF640_CLDFB_PFT_TABLE_SIZE (640)
+#define QMF320_CLDFB_PFT_TABLE_SIZE (320)
+#define QMF_CLDFB_PFT_SCALE 1
+
+extern const FIXP_QTW qmf_phaseshift_cos32_cldfb_ana[32];
+extern const FIXP_QTW qmf_phaseshift_cos32_cldfb_syn[32];
+extern const FIXP_QTW qmf_phaseshift_sin32_cldfb[32];
+
+extern const FIXP_QTW qmf_phaseshift_cos16_cldfb_ana[16];
+extern const FIXP_QTW qmf_phaseshift_cos16_cldfb_syn[16];
+extern const FIXP_QTW qmf_phaseshift_sin16_cldfb[16];
+
+extern const FIXP_QTW qmf_phaseshift_cos8_cldfb_ana[8];
+extern const FIXP_QTW qmf_phaseshift_cos8_cldfb_syn[8];
+extern const FIXP_QTW qmf_phaseshift_sin8_cldfb[8];
+
+extern const FIXP_QTW qmf_phaseshift_cos64_cldfb[64];
+extern const FIXP_QTW qmf_phaseshift_sin64_cldfb[64];
+
+extern RAM_ALIGN const FIXP_PFT qmf_cldfb_640[QMF640_CLDFB_PFT_TABLE_SIZE];
+extern RAM_ALIGN const FIXP_PFT qmf_cldfb_320[QMF320_CLDFB_PFT_TABLE_SIZE];
+#define QMF160_CLDFB_PFT_TABLE_SIZE (160)
+extern RAM_ALIGN const FIXP_PFT qmf_cldfb_160[QMF160_CLDFB_PFT_TABLE_SIZE];
+#define QMF80_CLDFB_PFT_TABLE_SIZE (80)
+extern RAM_ALIGN const FIXP_PFT qmf_cldfb_80[QMF80_CLDFB_PFT_TABLE_SIZE];
+
+#define QMF320_MPSLDFB_PFT_TABLE_SIZE (320)
+#define QMF640_MPSLDFB_PFT_TABLE_SIZE (640)
+#define QMF_MPSLDFB_PFT_SCALE 1
+
+extern const FIXP_PFT qmf_mpsldfb_320[QMF320_MPSLDFB_PFT_TABLE_SIZE];
+extern RAM_ALIGN const FIXP_PFT qmf_mpsldfb_640[QMF640_MPSLDFB_PFT_TABLE_SIZE];
+
+/**
+ * Audio bitstream element specific syntax flags:
+ */
+#define AC_EL_GA_CCE 0x00000001 /*!< GA AAC coupling channel element (CCE) */
+
+/*
+ * Raw Data Block list items.
+ */
+typedef enum {
+ element_instance_tag,
+ common_window, /* -> decision for link_sequence */
+ global_gain,
+ ics_info, /* ics_reserved_bit, window_sequence, window_shape, max_sfb,
+ scale_factor_grouping, predictor_data_present, ltp_data_present,
+ ltp_data */
+ max_sfb,
+ ms, /* ms_mask_present, ms_used */
+ /*predictor_data_present,*/ /* part of ics_info */
+ ltp_data_present,
+ ltp_data,
+ section_data,
+ scale_factor_data,
+ pulse, /* pulse_data_present, pulse_data */
+ tns_data_present,
+ tns_data,
+ gain_control_data_present,
+ gain_control_data,
+ esc1_hcr,
+ esc2_rvlc,
+ spectral_data,
+
+ scale_factor_data_usac,
+ core_mode, /* -> decision for link_sequence */
+ common_tw,
+ lpd_channel_stream,
+ tw_data,
+ noise,
+ ac_spectral_data,
+ fac_data,
+ tns_active, /* introduced in MPEG-D usac CD */
+ tns_data_present_usac,
+ common_max_sfb,
+
+ coupled_elements, /* only for CCE parsing */
+ gain_element_lists, /* only for CCE parsing */
+
+ /* Non data list items */
+ adtscrc_start_reg1,
+ adtscrc_start_reg2,
+ adtscrc_end_reg1,
+ adtscrc_end_reg2,
+ drmcrc_start_reg,
+ drmcrc_end_reg,
+ next_channel,
+ next_channel_loop,
+ link_sequence,
+ end_of_sequence
+} rbd_id_t;
+
+struct element_list {
+ const rbd_id_t *id;
+ const struct element_list *next[2];
+};
+
+typedef struct element_list element_list_t;
+/**
+ * \brief get elementary stream pieces list for given parameters.
+ * \param aot audio object type
+ * \param epConfig the epConfig value from the current Audio Specific Config
+ * \param nChannels amount of channels contained in the current element.
+ * \param layer the layer of the current element.
+ * \param elFlags element specific flags.
+ * \return element_list_t parser guidance structure.
+ */
+const element_list_t *getBitstreamElementList(AUDIO_OBJECT_TYPE aot,
+ SCHAR epConfig, UCHAR nChannels,
+ UCHAR layer, UINT elFlags);
+
+typedef enum {
+ /* n.a. */
+ FDK_FORMAT_1_0 = 1, /* mono */
+ FDK_FORMAT_2_0 = 2, /* stereo */
+ FDK_FORMAT_3_0_FC = 3, /* 3/0.0 */
+ FDK_FORMAT_3_1_0 = 4, /* 3/1.0 */
+ FDK_FORMAT_5_0 = 5, /* 3/2.0 */
+ FDK_FORMAT_5_1 = 6, /* 5.1 */
+ FDK_FORMAT_7_1_ALT = 7, /* 5/2.1 ALT */
+ /* 8 n.a.*/
+ FDK_FORMAT_3_0_RC = 9, /* 2/1.0 */
+ FDK_FORMAT_2_2_0 = 10, /* 2/2.0 */
+ FDK_FORMAT_6_1 = 11, /* 3/3.1 */
+ FDK_FORMAT_7_1 = 12, /* 3/4.1 */
+ FDK_FORMAT_22_2 = 13, /* 22.2 */
+ FDK_FORMAT_5_2_1 = 14, /* 5/2.1*/
+ FDK_FORMAT_5_5_2 = 15, /* 5/5.2 */
+ FDK_FORMAT_9_1 = 16, /* 5/4.1 */
+ FDK_FORMAT_6_5_1 = 17, /* 6/5.1 */
+ FDK_FORMAT_6_7_1 = 18, /* 6/7.1 */
+ FDK_FORMAT_5_6_1 = 19, /* 5/6.1 */
+ FDK_FORMAT_7_6_1 = 20, /* 7/6.1 */
+ FDK_FORMAT_IN_LISTOFCHANNELS = 21,
+ FDK_FORMAT_OUT_LISTOFCHANNELS = 22,
+ /* 20 formats + In & Out list of channels */
+ FDK_NFORMATS = 23,
+ FDK_FORMAT_FAIL = -1
+} FDK_converter_formatid_t;
+
+extern const INT format_nchan[FDK_NFORMATS + 9 - 2];
+
+#endif
diff --git a/fdk-aac/libFDK/include/FDK_trigFcts.h b/fdk-aac/libFDK/include/FDK_trigFcts.h
new file mode 100644
index 0000000..153ca4c
--- /dev/null
+++ b/fdk-aac/libFDK/include/FDK_trigFcts.h
@@ -0,0 +1,258 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Haricharan Lakshman, Manuel Jander
+
+ Description: Trigonometric functions fixed point fractional implementation.
+
+*******************************************************************************/
+
+#if !defined(FDK_TRIGFCTS_H)
+#define FDK_TRIGFCTS_H
+
+#include "common_fix.h"
+
+#include "FDK_tools_rom.h"
+
+/* Fixed point precision definitions */
+#define Q(format) ((FIXP_DBL)(((LONG)1) << (format)))
+
+#ifndef M_PI
+#define M_PI (3.14159265358979323846f)
+#endif
+
+/*!
+ * Inverse tangent function.
+ */
+
+/* --- fixp_atan() ---- */
+#define Q_ATANINP (25) // Input in q25, Output in q30
+#define Q_ATANOUT (30)
+#define ATI_SF ((DFRACT_BITS - 1) - Q_ATANINP) /* 6 */
+#define ATI_SCALE ((float)(1 << ATI_SF))
+#define ATO_SF ((DFRACT_BITS - 1) - Q_ATANOUT) /* 1 ] -pi/2 .. pi/2 [ */
+#define ATO_SCALE ((float)(1 << ATO_SF))
+/* --- fixp_atan2() --- */
+#define Q_ATAN2OUT (29)
+#define AT2O_SF ((DFRACT_BITS - 1) - Q_ATAN2OUT) /* 2 ] -pi .. pi ] */
+#define AT2O_SCALE ((float)(1 << AT2O_SF))
+// --------------------
+
+FIXP_DBL fixp_atan(FIXP_DBL x);
+FIXP_DBL fixp_atan2(FIXP_DBL y, FIXP_DBL x);
+
+FIXP_DBL fixp_cos(FIXP_DBL x, int scale);
+FIXP_DBL fixp_sin(FIXP_DBL x, int scale);
+
+#define FIXP_COS_SIN
+
+#include "FDK_tools_rom.h"
+
+#define SINETAB SineTable512
+#define LD 9
+
+#ifndef FUNCTION_inline_fixp_cos_sin
+
+#define FUNCTION_inline_fixp_cos_sin
+
+/*
+ * Calculates coarse lookup index and sign for sine.
+ * Returns delta x residual.
+ */
+static inline FIXP_DBL fixp_sin_cos_residual_inline(FIXP_DBL x, int scale,
+ FIXP_DBL *sine,
+ FIXP_DBL *cosine) {
+ FIXP_DBL residual;
+ int s;
+ int shift = (31 - scale - LD - 1);
+ int ssign = 1;
+ int csign = 1;
+
+ residual = fMult(x, FL2FXCONST_DBL(1.0 / M_PI));
+ s = ((LONG)residual) >> shift;
+
+ residual &= ((1 << shift) - 1);
+ residual = fMult(residual, FL2FXCONST_DBL(M_PI / 4.0)) << 2;
+ residual <<= scale;
+
+ /* Sine sign symmetry */
+ if (s & ((1 << LD) << 1)) {
+ ssign = -ssign;
+ }
+ /* Cosine sign symmetry */
+ if ((s + (1 << LD)) & ((1 << LD) << 1)) {
+ csign = -csign;
+ }
+
+ s = fAbs(s);
+
+ s &= (((1 << LD) << 1) - 1); /* Modulo PI */
+
+ if (s > (1 << LD)) {
+ s = ((1 << LD) << 1) - s;
+ }
+
+ {
+ LONG sl, cl;
+ /* Because of packed table */
+ if (s > (1 << (LD - 1))) {
+ FIXP_STP tmp;
+ /* Cosine/Sine simetry for angles greater than PI/4 */
+ s = (1 << LD) - s;
+ tmp = SINETAB[s];
+ sl = (LONG)tmp.v.re;
+ cl = (LONG)tmp.v.im;
+ } else {
+ FIXP_STP tmp;
+ tmp = SINETAB[s];
+ sl = (LONG)tmp.v.im;
+ cl = (LONG)tmp.v.re;
+ }
+
+#ifdef SINETABLE_16BIT
+ *sine = (FIXP_DBL)((sl * ssign) << (DFRACT_BITS - FRACT_BITS));
+ *cosine = (FIXP_DBL)((cl * csign) << (DFRACT_BITS - FRACT_BITS));
+#else
+ /* scale down by 1 for overflow prevention. This is undone at the calling
+ * function. */
+ *sine = (FIXP_DBL)(sl * ssign) >> 1;
+ *cosine = (FIXP_DBL)(cl * csign) >> 1;
+#endif
+ }
+
+ return residual;
+}
+
+/**
+ * \brief Calculate cosine and sine value each of 2 angles different angle
+ * values.
+ * \param x1 first angle value
+ * \param x2 second angle value
+ * \param scale exponent of x1 and x2
+ * \param out pointer to 4 FIXP_DBL locations, were the values cos(x1), sin(x1),
+ * cos(x2), sin(x2) will be stored into.
+ */
+static inline void inline_fixp_cos_sin(FIXP_DBL x1, FIXP_DBL x2,
+ const int scale, FIXP_DBL *out) {
+ FIXP_DBL residual, error0, error1, sine, cosine;
+ residual = fixp_sin_cos_residual_inline(x1, scale, &sine, &cosine);
+ error0 = fMultDiv2(sine, residual);
+ error1 = fMultDiv2(cosine, residual);
+
+#ifdef SINETABLE_16BIT
+ *out++ = cosine - (error0 << 1);
+ *out++ = sine + (error1 << 1);
+#else
+ /* Undo downscaling by 1 which was done at fixp_sin_cos_residual_inline */
+ *out++ = SATURATE_LEFT_SHIFT(cosine - (error0 << 1), 1, DFRACT_BITS);
+ *out++ = SATURATE_LEFT_SHIFT(sine + (error1 << 1), 1, DFRACT_BITS);
+#endif
+
+ residual = fixp_sin_cos_residual_inline(x2, scale, &sine, &cosine);
+ error0 = fMultDiv2(sine, residual);
+ error1 = fMultDiv2(cosine, residual);
+
+#ifdef SINETABLE_16BIT
+ *out++ = cosine - (error0 << 1);
+ *out++ = sine + (error1 << 1);
+#else
+ *out++ = SATURATE_LEFT_SHIFT(cosine - (error0 << 1), 1, DFRACT_BITS);
+ *out++ = SATURATE_LEFT_SHIFT(sine + (error1 << 1), 1, DFRACT_BITS);
+#endif
+}
+#endif
+
+#endif /* !defined(FDK_TRIGFCTS_H) */
diff --git a/fdk-aac/libFDK/include/abs.h b/fdk-aac/libFDK/include/abs.h
new file mode 100644
index 0000000..0846c96
--- /dev/null
+++ b/fdk-aac/libFDK/include/abs.h
@@ -0,0 +1,136 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Lohwasser
+
+ Description: fixed point abs definitions
+
+*******************************************************************************/
+
+#if !defined(ABS_H)
+#define ABS_H
+
+#if defined(__mips__)
+#include "mips/abs_mips.h"
+
+#elif defined(__x86__)
+#include "x86/abs_x86.h"
+
+#endif /* all cores */
+
+/*************************************************************************
+ *************************************************************************
+ Software fallbacks for missing functions
+**************************************************************************
+**************************************************************************/
+
+#if !defined(FUNCTION_fixabs_D)
+inline FIXP_DBL fixabs_D(FIXP_DBL x) {
+ return ((x) > (FIXP_DBL)(0)) ? (x) : -(x);
+}
+#endif
+
+#if !defined(FUNCTION_fixabs_I)
+inline INT fixabs_I(INT x) { return ((x) > (INT)(0)) ? (x) : -(x); }
+#endif
+
+#if !defined(FUNCTION_fixabs_S)
+inline FIXP_SGL fixabs_S(FIXP_SGL x) {
+ return ((x) > (FIXP_SGL)(0)) ? (x) : -(x);
+}
+#endif
+
+#endif /* ABS_H */
diff --git a/fdk-aac/libFDK/include/arm/clz_arm.h b/fdk-aac/libFDK/include/arm/clz_arm.h
new file mode 100644
index 0000000..1c3e1fb
--- /dev/null
+++ b/fdk-aac/libFDK/include/arm/clz_arm.h
@@ -0,0 +1,164 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(CLZ_ARM_H)
+#define CLZ_ARM_H
+
+#if defined(__arm__)
+
+#if defined(__GNUC__)
+/* ARM gcc*/
+
+#if defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_8__)
+#define FUNCTION_fixnormz_D
+#define FUNCTION_fixnorm_D
+#define FUNCTION_fixnormz_S
+#define FUNCTION_fixnorm_S
+
+#ifdef FUNCTION_fixnormz_D
+inline INT fixnormz_D(LONG value) {
+ INT result;
+#if defined(__ARM_ARCH_8__)
+ asm("clz %w0, %w1 " : "=r"(result) : "r"(value));
+#else
+ asm("clz %0, %1 " : "=r"(result) : "r"(value));
+#endif
+ return result;
+}
+#endif /* #ifdef FUNCTION_fixnormz_D */
+
+#ifdef FUNCTION_fixnorm_D
+inline INT fixnorm_D(LONG value) {
+ if (!value) return 0;
+ if (value < 0) value = ~value;
+ return fixnormz_D(value) - 1;
+}
+#endif /* #ifdef FUNCTION_fixnorm_D */
+
+#ifdef FUNCTION_fixnormz_S
+inline INT fixnormz_S(SHORT value) {
+ INT result;
+ result = (LONG)(value << 16);
+ if (result == 0)
+ result = 16;
+ else
+ result = fixnormz_D(result);
+ return result;
+}
+#endif /* #ifdef FUNCTION_fixnormz_S */
+
+#ifdef FUNCTION_fixnorm_S
+inline INT fixnorm_S(SHORT value) {
+ LONG lvalue = (LONG)(value << 16);
+ if (!lvalue) return 0;
+ if (lvalue < 0) lvalue = ~lvalue;
+ return fixnormz_D(lvalue) - 1;
+}
+#endif /* #ifdef FUNCTION_fixnorm_S */
+
+#endif
+
+#endif /* arm toolchain */
+
+#endif /* __arm__ */
+
+#endif /* !defined(CLZ_ARM_H) */
diff --git a/fdk-aac/libFDK/include/arm/cplx_mul_arm.h b/fdk-aac/libFDK/include/arm/cplx_mul_arm.h
new file mode 100644
index 0000000..a448e33
--- /dev/null
+++ b/fdk-aac/libFDK/include/arm/cplx_mul_arm.h
@@ -0,0 +1,201 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(CPLX_MUL_ARM_H)
+#define CPLX_MUL_ARM_H
+
+#if defined(__arm__) && defined(__GNUC__)
+
+#if defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__) || \
+ defined(__ARM_ARCH_8__)
+#define FUNCTION_cplxMultDiv2_32x16
+#define FUNCTION_cplxMultDiv2_32x16X2
+#endif
+
+#define FUNCTION_cplxMultDiv2_32x32X2
+#ifdef FUNCTION_cplxMultDiv2_32x32X2
+inline void cplxMultDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_DBL b_Re,
+ const FIXP_DBL b_Im) {
+ LONG tmp1, tmp2;
+
+#ifdef __ARM_ARCH_8__
+ asm("smull %x0, %w2, %w4; \n" /* tmp1 = a_Re * b_Re */
+ "smull %x1, %w2, %w5; \n" /* tmp2 = a_Re * b_Im */
+ "smsubl %x0, %w3, %w5, %x0; \n" /* tmp1 -= a_Im * b_Im */
+ "smaddl %x1, %w3, %w4, %x1; \n" /* tmp2 += a_Im * b_Re */
+ "asr %x0, %x0, #32 \n"
+ "asr %x1, %x1, #32 \n"
+ : "=&r"(tmp1), "=&r"(tmp2)
+ : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im));
+#elif defined(__ARM_ARCH_6__)
+ asm("smmul %0, %2, %4;\n" /* tmp1 = a_Re * b_Re */
+ "smmls %0, %3, %5, %0;\n" /* tmp1 -= a_Im * b_Im */
+ "smmul %1, %2, %5;\n" /* tmp2 = a_Re * b_Im */
+ "smmla %1, %3, %4, %1;\n" /* tmp2 += a_Im * b_Re */
+ : "=&r"(tmp1), "=&r"(tmp2)
+ : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im));
+#else
+ LONG discard;
+ asm("smull %2, %0, %7, %6;\n" /* tmp1 = -a_Im * b_Im */
+ "smlal %2, %0, %3, %5;\n" /* tmp1 += a_Re * b_Re */
+ "smull %2, %1, %3, %6;\n" /* tmp2 = a_Re * b_Im */
+ "smlal %2, %1, %4, %5;\n" /* tmp2 += a_Im * b_Re */
+ : "=&r"(tmp1), "=&r"(tmp2), "=&r"(discard)
+ : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im), "r"(-a_Im));
+#endif
+ *c_Re = tmp1;
+ *c_Im = tmp2;
+}
+#endif /* FUNCTION_cplxMultDiv2_32x32X2 */
+
+#if defined(FUNCTION_cplxMultDiv2_32x16)
+inline void cplxMultDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, FIXP_SPK wpk) {
+#ifdef __ARM_ARCH_8__
+ FIXP_DBL b_Im = FX_SGL2FX_DBL(wpk.v.im);
+ FIXP_DBL b_Re = FX_SGL2FX_DBL(wpk.v.re);
+ cplxMultDiv2(c_Re, c_Im, a_Re, a_Im, b_Re, b_Im);
+#else
+ LONG tmp1, tmp2;
+ const LONG w = wpk.w;
+ asm("smulwt %0, %3, %4;\n"
+ "rsb %1,%0,#0;\n"
+ "smlawb %0, %2, %4, %1;\n"
+ "smulwt %1, %2, %4;\n"
+ "smlawb %1, %3, %4, %1;\n"
+ : "=&r"(tmp1), "=&r"(tmp2)
+ : "r"(a_Re), "r"(a_Im), "r"(w));
+ *c_Re = tmp1;
+ *c_Im = tmp2;
+#endif
+}
+#endif /* FUNCTION_cplxMultDiv2_32x16 */
+
+#ifdef FUNCTION_cplxMultDiv2_32x16X2
+inline void cplxMultDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_SGL b_Re,
+ const FIXP_SGL b_Im) {
+#ifdef __ARM_ARCH_8__
+ FIXP_DBL b_re = FX_SGL2FX_DBL(b_Re);
+ FIXP_DBL b_im = FX_SGL2FX_DBL(b_Im);
+ cplxMultDiv2(c_Re, c_Im, a_Re, a_Im, b_re, b_im);
+#else
+ LONG tmp1, tmp2;
+
+ asm("smulwb %0, %3, %5;\n" /* %7 = -a_Im * b_Im */
+ "rsb %1,%0,#0;\n"
+ "smlawb %0, %2, %4, %1;\n" /* tmp1 = a_Re * b_Re - a_Im * b_Im */
+ "smulwb %1, %2, %5;\n" /* %7 = a_Re * b_Im */
+ "smlawb %1, %3, %4, %1;\n" /* tmp2 = a_Im * b_Re + a_Re * b_Im */
+ : "=&r"(tmp1), "=&r"(tmp2)
+ : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im));
+
+ *c_Re = tmp1;
+ *c_Im = tmp2;
+#endif
+}
+#endif /* FUNCTION_cplxMultDiv2_32x16X2 */
+
+#endif
+
+#endif /* !defined(CPLX_MUL_ARM_H) */
diff --git a/fdk-aac/libFDK/include/arm/fixmadd_arm.h b/fdk-aac/libFDK/include/arm/fixmadd_arm.h
new file mode 100644
index 0000000..1378660
--- /dev/null
+++ b/fdk-aac/libFDK/include/arm/fixmadd_arm.h
@@ -0,0 +1,220 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(FIXMADD_ARM_H)
+#define FIXMADD_ARM_H
+
+#if defined(__arm__)
+
+/* #############################################################################
+ */
+#if defined(__GNUC__) && defined(__arm__)
+/* #############################################################################
+ */
+/* ARM GNU GCC */
+
+#ifdef __ARM_ARCH_8__
+#define FUNCTION_fixmadddiv2_DD
+#ifdef FUNCTION_fixmadddiv2_DD
+inline FIXP_DBL fixmadddiv2_DD(FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) {
+ INT64 result;
+ asm("smull %x0, %w1, %w2; \n"
+ "asr %x0, %x0, #32; \n"
+ "add %w0, %w3, %w0; \n"
+ : "=&r"(result)
+ : "r"(a), "r"(b), "r"(x));
+ return (INT)result;
+}
+#endif /* #ifdef FUNCTION_fixmadddiv2_DD */
+
+#define FUNCTION_fixmsubdiv2_DD
+#ifdef FUNCTION_fixmsubdiv2_DD
+inline FIXP_DBL fixmsubdiv2_DD(FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) {
+ INT64 result;
+ asm("smull %x0, %w1, %w2; \n"
+ "asr %x0, %x0, #32; \n"
+ "sub %w0, %w3, %w0; \n"
+ : "=&r"(result)
+ : "r"(a), "r"(b), "r"(x));
+ return (INT)result;
+}
+#endif /* #ifdef FUNCTION_fixmsubdiv2_DD */
+
+#elif defined(__ARM_ARCH_6__)
+#define FUNCTION_fixmadddiv2_DD
+#ifdef FUNCTION_fixmadddiv2_DD
+inline FIXP_DBL fixmadddiv2_DD(FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) {
+ INT result;
+ asm("smmla %0, %1, %2, %3;\n" : "=r"(result) : "r"(a), "r"(b), "r"(x));
+ return result;
+}
+#endif /* #ifdef FUNCTION_fixmadddiv2_DD */
+
+#define FUNCTION_fixmsubdiv2_DD
+#ifdef FUNCTION_fixmsubdiv2_DD
+inline FIXP_DBL fixmsubdiv2_DD(FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) {
+ INT result;
+ asm("smmls %0, %1, %2, %3;\n" : "=r"(result) : "r"(a), "r"(b), "r"(x));
+ return result;
+}
+#endif /* #ifdef FUNCTION_fixmsubdiv2_DD */
+
+#else
+#define FUNCTION_fixmadddiv2_DD
+#ifdef FUNCTION_fixmadddiv2_DD
+inline FIXP_DBL fixmadddiv2_DD(FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) {
+ INT discard = 0;
+ INT result = x;
+ asm("smlal %0, %1, %2, %3;\n" : "+r"(discard), "+r"(result) : "r"(a), "r"(b));
+ return result;
+}
+#endif /* #ifdef FUNCTION_fixmadddiv2_DD */
+#endif
+
+#if defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__)
+
+#define FUNCTION_fixmadddiv2_DS
+#ifdef FUNCTION_fixmadddiv2_DS
+inline FIXP_DBL fixmadddiv2_DS(FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) {
+ INT result;
+ asm("smlawb %0, %1, %2, %3 " : "=r"(result) : "r"(a), "r"(b), "r"(x));
+ return result;
+}
+#endif /* #ifdef FUNCTION_fixmadddiv2_DS */
+
+#endif /* defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__) */
+
+#define FUNCTION_fixmadddiv2BitExact_DD
+#ifdef FUNCTION_fixmadddiv2BitExact_DD
+#define fixmadddiv2BitExact_DD(a, b, c) fixmadddiv2_DD(a, b, c)
+#endif /* #ifdef FUNCTION_fixmadddiv2BitExact_DD */
+
+#define FUNCTION_fixmsubdiv2BitExact_DD
+#ifdef FUNCTION_fixmsubdiv2BitExact_DD
+inline FIXP_DBL fixmsubdiv2BitExact_DD(FIXP_DBL x, const FIXP_DBL a,
+ const FIXP_DBL b) {
+ return x - fixmuldiv2BitExact_DD(a, b);
+}
+#endif /* #ifdef FUNCTION_fixmsubdiv2BitExact_DD */
+
+#define FUNCTION_fixmadddiv2BitExact_DS
+#ifdef FUNCTION_fixmadddiv2BitExact_DS
+#define fixmadddiv2BitExact_DS(a, b, c) fixmadddiv2_DS(a, b, c)
+#endif /* #ifdef FUNCTION_fixmadddiv2BitExact_DS */
+
+#define FUNCTION_fixmsubdiv2BitExact_DS
+#ifdef FUNCTION_fixmsubdiv2BitExact_DS
+inline FIXP_DBL fixmsubdiv2BitExact_DS(FIXP_DBL x, const FIXP_DBL a,
+ const FIXP_SGL b) {
+ return x - fixmuldiv2BitExact_DS(a, b);
+}
+#endif /* #ifdef FUNCTION_fixmsubdiv2BitExact_DS */
+
+/* #############################################################################
+ */
+#endif /* toolchain */
+ /* #############################################################################
+ */
+
+#endif /* __arm__ */
+
+#endif /* !defined(FIXMADD_ARM_H) */
diff --git a/fdk-aac/libFDK/include/arm/fixmul_arm.h b/fdk-aac/libFDK/include/arm/fixmul_arm.h
new file mode 100644
index 0000000..077e5c6
--- /dev/null
+++ b/fdk-aac/libFDK/include/arm/fixmul_arm.h
@@ -0,0 +1,198 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(FIXMUL_ARM_H)
+#define FIXMUL_ARM_H
+
+#if defined(__arm__)
+
+#if defined(__GNUC__) && defined(__arm__)
+/* ARM with GNU compiler */
+
+#define FUNCTION_fixmuldiv2_DD
+
+#define FUNCTION_fixmuldiv2BitExact_DD
+#ifdef FUNCTION_fixmuldiv2BitExact_DD
+#define fixmuldiv2BitExact_DD(a, b) fixmuldiv2_DD(a, b)
+#endif /* #ifdef FUNCTION_fixmuldiv2BitExact_DD */
+
+#define FUNCTION_fixmulBitExact_DD
+#ifdef FUNCTION_fixmulBitExact_DD
+#define fixmulBitExact_DD(a, b) (fixmuldiv2BitExact_DD(a, b) << 1)
+#endif /* #ifdef FUNCTION_fixmulBitExact_DD */
+
+#define FUNCTION_fixmuldiv2BitExact_DS
+#ifdef FUNCTION_fixmuldiv2BitExact_DS
+#define fixmuldiv2BitExact_DS(a, b) fixmuldiv2_DS(a, b)
+#endif /* #ifdef FUNCTION_fixmuldiv2BitExact_DS */
+
+#define FUNCTION_fixmulBitExact_DS
+#ifdef FUNCTION_fixmulBitExact_DS
+#define fixmulBitExact_DS(a, b) fixmul_DS(a, b)
+#endif /* #ifdef FUNCTION_fixmulBitExact_DS */
+
+#ifdef FUNCTION_fixmuldiv2_DD
+inline INT fixmuldiv2_DD(const INT a, const INT b) {
+ INT result;
+#if defined(__ARM_ARCH_8__)
+ INT64 result64;
+ __asm__(
+ "smull %x0, %w1, %w2;\n"
+ "asr %x0, %x0, #32; "
+ : "=r"(result64)
+ : "r"(a), "r"(b));
+ result = (INT)result64;
+#elif defined(__ARM_ARCH_6__) || defined(__TARGET_ARCH_7E_M)
+ __asm__("smmul %0, %1, %2" : "=r"(result) : "r"(a), "r"(b));
+#else
+ INT discard;
+ __asm__("smull %0, %1, %2, %3"
+ : "=&r"(discard), "=r"(result)
+ : "r"(a), "r"(b));
+#endif
+ return result;
+}
+#endif /* #ifdef FUNCTION_fixmuldiv2_DD */
+
+#if defined(__ARM_ARCH_8__)
+#define FUNCTION_fixmuldiv2_SD
+#ifdef FUNCTION_fixmuldiv2_SD
+inline INT fixmuldiv2_SD(const SHORT a, const INT b) {
+ return fixmuldiv2_DD((INT)(a << 16), b);
+}
+#endif /* #ifdef FUNCTION_fixmuldiv2_SD */
+#elif defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__)
+#define FUNCTION_fixmuldiv2_SD
+#ifdef FUNCTION_fixmuldiv2_SD
+inline INT fixmuldiv2_SD(const SHORT a, const INT b) {
+ INT result;
+ __asm__("smulwb %0, %1, %2" : "=r"(result) : "r"(b), "r"(a));
+ return result;
+}
+#endif /* #ifdef FUNCTION_fixmuldiv2_SD */
+#endif
+
+#define FUNCTION_fixmul_DD
+#ifdef FUNCTION_fixmul_DD
+#if defined(__ARM_ARCH_8__)
+inline INT fixmul_DD(const INT a, const INT b) {
+ INT64 result64;
+
+ __asm__(
+ "smull %x0, %w1, %w2;\n"
+ "asr %x0, %x0, #31; "
+ : "=r"(result64)
+ : "r"(a), "r"(b));
+ return (INT)result64;
+}
+#else
+inline INT fixmul_DD(const INT a, const INT b) {
+ return (fixmuldiv2_DD(a, b) << 1);
+}
+#endif /* __ARM_ARCH_8__ */
+#endif /* #ifdef FUNCTION_fixmul_DD */
+
+#endif /* defined(__GNUC__) && defined(__arm__) */
+
+#endif /* __arm__ */
+
+#endif /* !defined(FIXMUL_ARM_H) */
diff --git a/fdk-aac/libFDK/include/arm/scale_arm.h b/fdk-aac/libFDK/include/arm/scale_arm.h
new file mode 100644
index 0000000..0bf4f66
--- /dev/null
+++ b/fdk-aac/libFDK/include/arm/scale_arm.h
@@ -0,0 +1,163 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: ARM scaling operations
+
+*******************************************************************************/
+
+#if !defined(SCALE_ARM_H)
+#define SCALE_ARM_H
+
+#if defined(__GNUC__) /* GCC Compiler */
+
+#if defined(__ARM_ARCH_6__)
+
+inline static INT shiftRightSat(INT src, int scale) {
+ INT result;
+ asm("ssat %0,%2,%0;\n"
+
+ : "=&r"(result)
+ : "r"(src >> scale), "M"(SAMPLE_BITS));
+
+ return result;
+}
+
+#define SATURATE_INT_PCM_RIGHT_SHIFT(src, scale) shiftRightSat(src, scale)
+
+inline static INT shiftLeftSat(INT src, int scale) {
+ INT result;
+ asm("ssat %0,%2,%0;\n"
+
+ : "=&r"(result)
+ : "r"(src << scale), "M"(SAMPLE_BITS));
+
+ return result;
+}
+
+#define SATURATE_INT_PCM_LEFT_SHIFT(src, scale) shiftLeftSat(src, scale)
+
+#endif /* __ARM_ARCH_6__ */
+
+#endif /* compiler selection */
+
+#define FUNCTION_scaleValueInPlace
+#ifdef FUNCTION_scaleValueInPlace
+inline void scaleValueInPlace(FIXP_DBL *value, /*!< Value */
+ INT scalefactor /*!< Scalefactor */
+) {
+ INT newscale;
+ if ((newscale = scalefactor) >= 0)
+ *value <<= newscale;
+ else
+ *value >>= -newscale;
+}
+#endif /* #ifdef FUNCTION_scaleValueInPlace */
+
+#define SATURATE_RIGHT_SHIFT(src, scale, dBits) \
+ ((((LONG)(src) ^ ((LONG)(src) >> (DFRACT_BITS - 1))) >> (scale)) > \
+ (LONG)(((1U) << ((dBits)-1)) - 1)) \
+ ? ((LONG)(src) >> (DFRACT_BITS - 1)) ^ (LONG)(((1U) << ((dBits)-1)) - 1) \
+ : ((LONG)(src) >> (scale))
+
+#define SATURATE_LEFT_SHIFT(src, scale, dBits) \
+ (((LONG)(src) ^ ((LONG)(src) >> (DFRACT_BITS - 1))) > \
+ ((LONG)(((1U) << ((dBits)-1)) - 1) >> (scale))) \
+ ? ((LONG)(src) >> (DFRACT_BITS - 1)) ^ (LONG)(((1U) << ((dBits)-1)) - 1) \
+ : ((LONG)(src) << (scale))
+
+#endif /* !defined(SCALE_ARM_H) */
diff --git a/fdk-aac/libFDK/include/arm/scramble_arm.h b/fdk-aac/libFDK/include/arm/scramble_arm.h
new file mode 100644
index 0000000..a7cfe65
--- /dev/null
+++ b/fdk-aac/libFDK/include/arm/scramble_arm.h
@@ -0,0 +1,174 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: bitreversal of input data
+
+*******************************************************************************/
+
+#if !defined(SCRAMBLE_ARM_H)
+#define SCRAMBLE_ARM_H
+
+#if defined(FUNCTION_scramble)
+#if defined(__GNUC__)
+
+#define FUNCTION_scramble
+
+#if defined(__ARM_ARCH_5TE__)
+#define USE_LDRD_STRD /* LDRD requires 8 byte data alignment. */
+#endif
+
+inline void scramble(FIXP_DBL x[], INT n) {
+ FDK_ASSERT(!(((INT)x) & (ALIGNMENT_DEFAULT - 1)));
+ asm("mov r2, #1;\n" /* r2(m) = 1; */
+ "sub r3, %1, #1;\n" /* r3 = n-1; */
+ "mov r4, #0;\n" /* r4(j) = 0; */
+
+ "scramble_m_loop%=:\n" /* { */
+ "mov r5, %1;\n" /* r5(k) = 1; */
+
+ "scramble_k_loop%=:\n" /* { */
+ "mov r5, r5, lsr #1;\n" /* k >>= 1; */
+ "eor r4, r4, r5;\n" /* j ^=k; */
+ "ands r10, r4, r5;\n" /* r10 = r4 & r5; */
+ "beq scramble_k_loop%=;\n" /* } while (r10 == 0); */
+
+ "cmp r4, r2;\n" /* if (r4 < r2) break; */
+ "bcc scramble_m_loop_end%=;\n"
+
+#ifdef USE_LDRD_STRD
+ "mov r5, r2, lsl #3;\n" /* m(r5) = r2*4*2 */
+ "ldrd r10, [%0, r5];\n" /* r10 = x[r5], x7 = x[r5+1] */
+ "mov r6, r4, lsl #3;\n" /* j(r6) = r4*4*2 */
+ "ldrd r8, [%0, r6];\n" /* r8 = x[r6], r9 = x[r6+1]; */
+ "strd r10, [%0, r6];\n" /* x[r6,r6+1] = r10,r11; */
+ "strd r8, [%0, r5];\n" /* x[r5,r5+1] = r8,r9; */
+#else
+ "mov r5, r2, lsl #3;\n" /* m(r5) = r2*4*2 */
+ "ldr r10, [%0, r5];\n"
+ "mov r6, r4, lsl #3;\n" /* j(r6) = r4*4*2 */
+ "ldr r11, [%0, r6];\n"
+
+ "str r10, [%0, r6];\n"
+ "str r11, [%0, r5];\n"
+
+ "add r5, r5, #4;"
+ "ldr r10, [%0, r5];\n"
+ "add r6, r6, #4;"
+ "ldr r11, [%0, r6];\n"
+ "str r10, [%0, r6];\n"
+ "str r11, [%0, r5];\n"
+#endif
+ "scramble_m_loop_end%=:\n"
+ "add r2, r2, #1;\n" /* r2++; */
+ "cmp r2, r3;\n"
+ "bcc scramble_m_loop%=;\n" /* } while (r2(m) < r3(n-1)); */
+ :
+ : "r"(x), "r"(n)
+#ifdef USE_LDRD_STRD
+ : "r2", "r3", "r4", "r5", "r10", "r11", "r8", "r9", "r6");
+#else
+ : "r2", "r3", "r4", "r5", "r10", "r11", "r6");
+#endif
+}
+#else
+/* Force C implementation if no assembler version available. */
+#undef FUNCTION_scramble
+#endif /* Toolchain selection. */
+
+#endif /* defined(FUNCTION_scramble) */
+#endif /* !defined(SCRAMBLE_ARM_H) */
diff --git a/fdk-aac/libFDK/include/autocorr2nd.h b/fdk-aac/libFDK/include/autocorr2nd.h
new file mode 100644
index 0000000..e01989b
--- /dev/null
+++ b/fdk-aac/libFDK/include/autocorr2nd.h
@@ -0,0 +1,137 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Lohwasser
+
+ Description: fixed point abs definitions
+
+*******************************************************************************/
+
+#ifndef AUTOCORR2ND_H
+#define AUTOCORR2ND_H
+
+#include "common_fix.h"
+
+typedef struct {
+ FIXP_DBL r00r;
+ FIXP_DBL r11r;
+ FIXP_DBL r22r;
+ FIXP_DBL r01r;
+ FIXP_DBL r02r;
+ FIXP_DBL r12r;
+ FIXP_DBL r01i;
+ FIXP_DBL r02i;
+ FIXP_DBL r12i;
+ FIXP_DBL det;
+ int det_scale;
+} ACORR_COEFS;
+
+#define LPC_ORDER 2
+
+INT autoCorr2nd_real(
+ ACORR_COEFS *ac, /*!< Pointer to autocorrelation coeffs */
+ const FIXP_DBL *reBuffer, /*!< Pointer to to real part of spectrum */
+ const int len /*!< Number of qmf slots */
+);
+
+INT autoCorr2nd_cplx(
+ ACORR_COEFS *ac, /*!< Pointer to autocorrelation coeffs */
+ const FIXP_DBL *reBuffer, /*!< Pointer to to real part of spectrum */
+ const FIXP_DBL *imBuffer, /*!< Pointer to imag part of spectrum */
+ const int len /*!< Number of qmf slots */
+);
+
+#endif /* AUTOCORR2ND_H */
diff --git a/fdk-aac/libFDK/include/clz.h b/fdk-aac/libFDK/include/clz.h
new file mode 100644
index 0000000..df75618
--- /dev/null
+++ b/fdk-aac/libFDK/include/clz.h
@@ -0,0 +1,205 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Marc Gayer
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(CLZ_H)
+#define CLZ_H
+
+#include "FDK_archdef.h"
+#include "machine_type.h"
+
+#if defined(__arm__)
+#include "arm/clz_arm.h"
+
+#elif defined(__mips__)
+#include "mips/clz_mips.h"
+
+#elif defined(__x86__)
+#include "x86/clz_x86.h"
+
+#elif defined(__powerpc__)
+#include "ppc/clz_ppc.h"
+
+#endif /* all cores */
+
+/*************************************************************************
+ *************************************************************************
+ Software fallbacks for missing functions.
+**************************************************************************
+**************************************************************************/
+
+#if !defined(FUNCTION_fixnormz_S)
+#ifdef FUNCTION_fixnormz_D
+inline INT fixnormz_S(SHORT a) {
+ if (a < 0) {
+ return 0;
+ }
+ return fixnormz_D((INT)(a)) - 16;
+}
+#else
+inline INT fixnormz_S(SHORT a) {
+ int leadingBits = 0;
+ a = ~a;
+ while (a & 0x8000) {
+ leadingBits++;
+ a <<= 1;
+ }
+
+ return (leadingBits);
+}
+#endif
+#endif
+
+#if !defined(FUNCTION_fixnormz_D)
+inline INT fixnormz_D(LONG a) {
+ INT leadingBits = 0;
+ a = ~a;
+ while (a & 0x80000000) {
+ leadingBits++;
+ a <<= 1;
+ }
+
+ return (leadingBits);
+}
+#endif
+
+/*****************************************************************************
+
+ functionname: fixnorm_D
+ description: Count leading ones or zeros of operand val for dfract/LONG INT
+values. Return this value minus 1. Return 0 if operand==0.
+*****************************************************************************/
+#if !defined(FUNCTION_fixnorm_S)
+#ifdef FUNCTION_fixnorm_D
+inline INT fixnorm_S(FIXP_SGL val) {
+ if (val == (FIXP_SGL)0) {
+ return 0;
+ }
+ return fixnorm_D((INT)(val)) - 16;
+}
+#else
+inline INT fixnorm_S(FIXP_SGL val) {
+ INT leadingBits = 0;
+ if (val != (FIXP_SGL)0) {
+ if (val < (FIXP_SGL)0) {
+ val = ~val;
+ }
+ leadingBits = fixnormz_S(val) - 1;
+ }
+ return (leadingBits);
+}
+#endif
+#endif
+
+#if !defined(FUNCTION_fixnorm_D)
+inline INT fixnorm_D(FIXP_DBL val) {
+ INT leadingBits = 0;
+ if (val != (FIXP_DBL)0) {
+ if (val < (FIXP_DBL)0) {
+ val = ~val;
+ }
+ leadingBits = fixnormz_D(val) - 1;
+ }
+ return (leadingBits);
+}
+#endif
+
+#endif /* CLZ_H */
diff --git a/fdk-aac/libFDK/include/common_fix.h b/fdk-aac/libFDK/include/common_fix.h
new file mode 100644
index 0000000..7c08225
--- /dev/null
+++ b/fdk-aac/libFDK/include/common_fix.h
@@ -0,0 +1,449 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description: Flexible fixpoint library configuration
+
+*******************************************************************************/
+
+#ifndef COMMON_FIX_H
+#define COMMON_FIX_H
+
+#include "FDK_archdef.h"
+#include "machine_type.h"
+
+/* ***** Start of former fix.h ****** */
+
+/* Define bit sizes of integer fixpoint fractional data types */
+#define FRACT_BITS 16 /* single precision */
+#define DFRACT_BITS 32 /* double precision */
+#define ACCU_BITS 40 /* double precision plus overflow */
+
+/* Fixpoint equivalent type fot PCM audio time domain data. */
+#if defined(SAMPLE_BITS)
+#if (SAMPLE_BITS == DFRACT_BITS)
+#define FIXP_PCM FIXP_DBL
+#define MAXVAL_FIXP_PCM MAXVAL_DBL
+#define MINVAL_FIXP_PCM MINVAL_DBL
+#define FX_PCM2FX_DBL(x) ((FIXP_DBL)(x))
+#define FX_DBL2FX_PCM(x) ((INT_PCM)(x))
+#elif (SAMPLE_BITS == FRACT_BITS)
+#define FIXP_PCM FIXP_SGL
+#define MAXVAL_FIXP_PCM MAXVAL_SGL
+#define MINVAL_FIXP_PCM MINVAL_SGL
+#define FX_PCM2FX_DBL(x) FX_SGL2FX_DBL((FIXP_SGL)(x))
+#define FX_DBL2FX_PCM(x) FX_DBL2FX_SGL(x)
+#else
+#error SAMPLE_BITS different from FRACT_BITS or DFRACT_BITS not implemented!
+#endif
+#endif
+
+/* ****** End of former fix.h ****** */
+
+#define SGL_MASK ((1UL << FRACT_BITS) - 1) /* 16bit: (2^16)-1 = 0xFFFF */
+
+#define MAX_SHIFT_SGL \
+ (FRACT_BITS - 1) /* maximum possible shift for FIXP_SGL values */
+#define MAX_SHIFT_DBL \
+ (DFRACT_BITS - 1) /* maximum possible shift for FIXP_DBL values */
+
+/* Scale factor from/to float/fixpoint values. DO NOT USE THESE VALUES AS
+ * SATURATION LIMITS !! */
+#define FRACT_FIX_SCALE ((INT64(1) << (FRACT_BITS - 1)))
+#define DFRACT_FIX_SCALE ((INT64(1) << (DFRACT_BITS - 1)))
+
+/* Max and Min values for saturation purposes. DO NOT USE THESE VALUES AS SCALE
+ * VALUES !! */
+#define MAXVAL_SGL \
+ ((signed)0x00007FFF) /* this has to be synchronized to FRACT_BITS */
+#define MINVAL_SGL \
+ ((signed)0xFFFF8000) /* this has to be synchronized to FRACT_BITS */
+#define MAXVAL_DBL \
+ ((signed)0x7FFFFFFF) /* this has to be synchronized to DFRACT_BITS */
+#define MINVAL_DBL \
+ ((signed)0x80000000) /* this has to be synchronized to DFRACT_BITS */
+
+#define FX_DBL2FXCONST_SGL(val) \
+ ((((((val) >> (DFRACT_BITS - FRACT_BITS - 1)) + 1) > \
+ (((LONG)1 << FRACT_BITS) - 1)) && \
+ ((LONG)(val) > 0)) \
+ ? (FIXP_SGL)(SHORT)(((LONG)1 << (FRACT_BITS - 1)) - 1) \
+ : (FIXP_SGL)(SHORT)((((val) >> (DFRACT_BITS - FRACT_BITS - 1)) + 1) >> \
+ 1))
+
+#define shouldBeUnion union /* unions are possible */
+
+typedef SHORT FIXP_SGL;
+typedef LONG FIXP_DBL;
+
+/* macros for compile-time conversion of constant float values to fixedpoint */
+#define FL2FXCONST_SPC FL2FXCONST_DBL
+
+#define MINVAL_DBL_CONST MINVAL_DBL
+#define MINVAL_SGL_CONST MINVAL_SGL
+
+#define FL2FXCONST_SGL(val) \
+ (FIXP_SGL)( \
+ ((val) >= 0) \
+ ? ((((double)(val) * (FRACT_FIX_SCALE) + 0.5) >= \
+ (double)(MAXVAL_SGL)) \
+ ? (SHORT)(MAXVAL_SGL) \
+ : (SHORT)((double)(val) * (double)(FRACT_FIX_SCALE) + 0.5)) \
+ : ((((double)(val) * (FRACT_FIX_SCALE)-0.5) <= \
+ (double)(MINVAL_SGL_CONST)) \
+ ? (SHORT)(MINVAL_SGL_CONST) \
+ : (SHORT)((double)(val) * (double)(FRACT_FIX_SCALE)-0.5)))
+
+#define FL2FXCONST_DBL(val) \
+ (FIXP_DBL)( \
+ ((val) >= 0) \
+ ? ((((double)(val) * (DFRACT_FIX_SCALE) + 0.5) >= \
+ (double)(MAXVAL_DBL)) \
+ ? (LONG)(MAXVAL_DBL) \
+ : (LONG)((double)(val) * (double)(DFRACT_FIX_SCALE) + 0.5)) \
+ : ((((double)(val) * (DFRACT_FIX_SCALE)-0.5) <= \
+ (double)(MINVAL_DBL_CONST)) \
+ ? (LONG)(MINVAL_DBL_CONST) \
+ : (LONG)((double)(val) * (double)(DFRACT_FIX_SCALE)-0.5)))
+
+/* macros for runtime conversion of float values to integer fixedpoint. NO
+ * OVERFLOW CHECK!!! */
+#define FL2FX_SPC FL2FX_DBL
+#define FL2FX_SGL(val) \
+ ((val) > 0.0f ? (SHORT)((val) * (float)(FRACT_FIX_SCALE) + 0.5f) \
+ : (SHORT)((val) * (float)(FRACT_FIX_SCALE)-0.5f))
+#define FL2FX_DBL(val) \
+ ((val) > 0.0f ? (LONG)((val) * (float)(DFRACT_FIX_SCALE) + 0.5f) \
+ : (LONG)((val) * (float)(DFRACT_FIX_SCALE)-0.5f))
+
+/* macros for runtime conversion of fixedpoint values to other fixedpoint. NO
+ * ROUNDING!!! */
+#define FX_ACC2FX_SGL(val) ((FIXP_SGL)((val) >> (ACCU_BITS - FRACT_BITS)))
+#define FX_ACC2FX_DBL(val) ((FIXP_DBL)((val) >> (ACCU_BITS - DFRACT_BITS)))
+#define FX_SGL2FX_ACC(val) ((FIXP_ACC)((LONG)(val) << (ACCU_BITS - FRACT_BITS)))
+#define FX_SGL2FX_DBL(val) \
+ ((FIXP_DBL)((LONG)(val) << (DFRACT_BITS - FRACT_BITS)))
+#define FX_DBL2FX_SGL(val) ((FIXP_SGL)((val) >> (DFRACT_BITS - FRACT_BITS)))
+
+/* ############################################################# */
+
+/* macros for runtime conversion of integer fixedpoint values to float. */
+
+/* #define FX_DBL2FL(val) ((float)(pow(2.,-31.)*(float)val)) */ /* version #1
+ */
+#define FX_DBL2FL(val) \
+ ((float)((double)(val) / (double)DFRACT_FIX_SCALE)) /* version #2 - \
+ identical to class \
+ dfract cast from \
+ dfract to float */
+#define FX_DBL2DOUBLE(val) (((double)(val) / (double)DFRACT_FIX_SCALE))
+
+/* ############################################################# */
+#include "fixmul.h"
+
+FDK_INLINE LONG fMult(SHORT a, SHORT b) { return fixmul_SS(a, b); }
+FDK_INLINE LONG fMult(SHORT a, LONG b) { return fixmul_SD(a, b); }
+FDK_INLINE LONG fMult(LONG a, SHORT b) { return fixmul_DS(a, b); }
+FDK_INLINE LONG fMult(LONG a, LONG b) { return fixmul_DD(a, b); }
+FDK_INLINE LONG fPow2(LONG a) { return fixpow2_D(a); }
+FDK_INLINE LONG fPow2(SHORT a) { return fixpow2_S(a); }
+
+FDK_INLINE LONG fMultDiv2(SHORT a, SHORT b) { return fixmuldiv2_SS(a, b); }
+FDK_INLINE LONG fMultDiv2(SHORT a, LONG b) { return fixmuldiv2_SD(a, b); }
+FDK_INLINE LONG fMultDiv2(LONG a, SHORT b) { return fixmuldiv2_DS(a, b); }
+FDK_INLINE LONG fMultDiv2(LONG a, LONG b) { return fixmuldiv2_DD(a, b); }
+FDK_INLINE LONG fPow2Div2(LONG a) { return fixpow2div2_D(a); }
+FDK_INLINE LONG fPow2Div2(SHORT a) { return fixpow2div2_S(a); }
+
+FDK_INLINE LONG fMultDiv2BitExact(LONG a, LONG b) {
+ return fixmuldiv2BitExact_DD(a, b);
+}
+FDK_INLINE LONG fMultDiv2BitExact(SHORT a, LONG b) {
+ return fixmuldiv2BitExact_SD(a, b);
+}
+FDK_INLINE LONG fMultDiv2BitExact(LONG a, SHORT b) {
+ return fixmuldiv2BitExact_DS(a, b);
+}
+FDK_INLINE LONG fMultBitExact(LONG a, LONG b) {
+ return fixmulBitExact_DD(a, b);
+}
+FDK_INLINE LONG fMultBitExact(SHORT a, LONG b) {
+ return fixmulBitExact_SD(a, b);
+}
+FDK_INLINE LONG fMultBitExact(LONG a, SHORT b) {
+ return fixmulBitExact_DS(a, b);
+}
+
+/* ********************************************************************************
+ */
+#include "abs.h"
+
+FDK_INLINE FIXP_DBL fAbs(FIXP_DBL x) { return fixabs_D(x); }
+FDK_INLINE FIXP_SGL fAbs(FIXP_SGL x) { return fixabs_S(x); }
+
+#if !defined(__LP64__)
+FDK_INLINE INT fAbs(INT x) { return fixabs_I(x); }
+#endif
+
+ /* ********************************************************************************
+ */
+
+#include "clz.h"
+
+FDK_INLINE INT fNormz(INT64 x) {
+ INT clz = fixnormz_D((INT)(x >> 32));
+ if (clz == 32) clz += fixnormz_D((INT)x);
+ return clz;
+}
+FDK_INLINE INT fNormz(FIXP_DBL x) { return fixnormz_D(x); }
+FDK_INLINE INT fNormz(FIXP_SGL x) { return fixnormz_S(x); }
+FDK_INLINE INT fNorm(FIXP_DBL x) { return fixnorm_D(x); }
+FDK_INLINE INT fNorm(FIXP_SGL x) { return fixnorm_S(x); }
+
+ /* ********************************************************************************
+ */
+ /* ********************************************************************************
+ */
+ /* ********************************************************************************
+ */
+
+#include "clz.h"
+#define fixp_abs(x) fAbs(x)
+#define fixMin(a, b) fMin(a, b)
+#define fixMax(a, b) fMax(a, b)
+#define CntLeadingZeros(x) fixnormz_D(x)
+#define CountLeadingBits(x) fixnorm_D(x)
+
+#include "fixmadd.h"
+
+/* y = (x+0.5*a*b) */
+FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) {
+ return fixmadddiv2_DD(x, a, b);
+}
+FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) {
+ return fixmadddiv2_SD(x, a, b);
+}
+FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) {
+ return fixmadddiv2_DS(x, a, b);
+}
+FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) {
+ return fixmadddiv2_SS(x, a, b);
+}
+
+FDK_INLINE FIXP_DBL fPow2AddDiv2(FIXP_DBL x, FIXP_DBL a) {
+ return fixpadddiv2_D(x, a);
+}
+FDK_INLINE FIXP_DBL fPow2AddDiv2(FIXP_DBL x, FIXP_SGL a) {
+ return fixpadddiv2_S(x, a);
+}
+
+/* y = 2*(x+0.5*a*b) = (2x+a*b) */
+FDK_INLINE FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) {
+ return fixmadd_DD(x, a, b);
+}
+inline FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) {
+ return fixmadd_SD(x, a, b);
+}
+inline FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) {
+ return fixmadd_DS(x, a, b);
+}
+inline FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) {
+ return fixmadd_SS(x, a, b);
+}
+
+inline FIXP_DBL fPow2Add(FIXP_DBL x, FIXP_DBL a) { return fixpadd_D(x, a); }
+inline FIXP_DBL fPow2Add(FIXP_DBL x, FIXP_SGL a) { return fixpadd_S(x, a); }
+
+/* y = (x-0.5*a*b) */
+inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) {
+ return fixmsubdiv2_DD(x, a, b);
+}
+inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) {
+ return fixmsubdiv2_SD(x, a, b);
+}
+inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) {
+ return fixmsubdiv2_DS(x, a, b);
+}
+inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) {
+ return fixmsubdiv2_SS(x, a, b);
+}
+
+/* y = 2*(x-0.5*a*b) = (2*x-a*b) */
+FDK_INLINE FIXP_DBL fMultSub(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) {
+ return fixmsub_DD(x, a, b);
+}
+inline FIXP_DBL fMultSub(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) {
+ return fixmsub_SD(x, a, b);
+}
+inline FIXP_DBL fMultSub(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) {
+ return fixmsub_DS(x, a, b);
+}
+inline FIXP_DBL fMultSub(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) {
+ return fixmsub_SS(x, a, b);
+}
+
+FDK_INLINE FIXP_DBL fMultAddDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) {
+ return fixmadddiv2BitExact_DD(x, a, b);
+}
+FDK_INLINE FIXP_DBL fMultAddDiv2BitExact(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) {
+ return fixmadddiv2BitExact_SD(x, a, b);
+}
+FDK_INLINE FIXP_DBL fMultAddDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) {
+ return fixmadddiv2BitExact_DS(x, a, b);
+}
+FDK_INLINE FIXP_DBL fMultSubDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) {
+ return fixmsubdiv2BitExact_DD(x, a, b);
+}
+FDK_INLINE FIXP_DBL fMultSubDiv2BitExact(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) {
+ return fixmsubdiv2BitExact_SD(x, a, b);
+}
+FDK_INLINE FIXP_DBL fMultSubDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) {
+ return fixmsubdiv2BitExact_DS(x, a, b);
+}
+
+#include "fixminmax.h"
+
+FDK_INLINE FIXP_DBL fMin(FIXP_DBL a, FIXP_DBL b) { return fixmin_D(a, b); }
+FDK_INLINE FIXP_DBL fMax(FIXP_DBL a, FIXP_DBL b) { return fixmax_D(a, b); }
+
+FDK_INLINE FIXP_SGL fMin(FIXP_SGL a, FIXP_SGL b) { return fixmin_S(a, b); }
+FDK_INLINE FIXP_SGL fMax(FIXP_SGL a, FIXP_SGL b) { return fixmax_S(a, b); }
+
+#if !defined(__LP64__)
+FDK_INLINE INT fMax(INT a, INT b) { return fixmax_I(a, b); }
+FDK_INLINE INT fMin(INT a, INT b) { return fixmin_I(a, b); }
+#endif
+
+inline UINT fMax(UINT a, UINT b) { return fixmax_UI(a, b); }
+inline UINT fMin(UINT a, UINT b) { return fixmin_UI(a, b); }
+
+inline UCHAR fMax(UCHAR a, UCHAR b) {
+ return (UCHAR)fixmax_UI((UINT)a, (UINT)b);
+}
+inline UCHAR fMin(UCHAR a, UCHAR b) {
+ return (UCHAR)fixmin_UI((UINT)a, (UINT)b);
+}
+
+/* Complex data types */
+typedef shouldBeUnion {
+ /* vector representation for arithmetic */
+ struct {
+ FIXP_SGL re;
+ FIXP_SGL im;
+ } v;
+ /* word representation for memory move */
+ LONG w;
+}
+FIXP_SPK;
+
+typedef shouldBeUnion {
+ /* vector representation for arithmetic */
+ struct {
+ FIXP_DBL re;
+ FIXP_DBL im;
+ } v;
+ /* word representation for memory move */
+ INT64 w;
+}
+FIXP_DPK;
+
+#include "fixmul.h"
+#include "fixmadd.h"
+#include "cplx_mul.h"
+#include "fixpoint_math.h"
+
+#endif
diff --git a/fdk-aac/libFDK/include/cplx_mul.h b/fdk-aac/libFDK/include/cplx_mul.h
new file mode 100644
index 0000000..eb1afce
--- /dev/null
+++ b/fdk-aac/libFDK/include/cplx_mul.h
@@ -0,0 +1,266 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(CPLX_MUL_H)
+#define CPLX_MUL_H
+
+#include "common_fix.h"
+
+#if defined(__arm__) || defined(_M_ARM)
+#include "arm/cplx_mul_arm.h"
+
+#elif defined(__GNUC__) && defined(__mips__) && __mips_isa_rev < 6
+#include "mips/cplx_mul_mips.h"
+
+#endif /* #if defined all cores: bfin, arm, etc. */
+
+/* #############################################################################
+ */
+
+/* Fallback generic implementations */
+
+#if !defined(FUNCTION_cplxMultDiv2_32x16X2)
+#define FUNCTION_cplxMultDiv2_32x16X2
+
+inline void cplxMultDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_SGL b_Re,
+ const FIXP_SGL b_Im) {
+ *c_Re = fMultDiv2(a_Re, b_Re) - fMultDiv2(a_Im, b_Im);
+ *c_Im = fMultDiv2(a_Re, b_Im) + fMultDiv2(a_Im, b_Re);
+}
+#endif
+
+#if !defined(FUNCTION_cplxMultDiv2_16x16X2)
+#define FUNCTION_cplxMultDiv2_16x16X2
+
+inline void cplxMultDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_SGL a_Re,
+ const FIXP_SGL a_Im, const FIXP_SGL b_Re,
+ const FIXP_SGL b_Im) {
+ *c_Re = fMultDiv2(a_Re, b_Re) - fMultDiv2(a_Im, b_Im);
+ *c_Im = fMultDiv2(a_Re, b_Im) + fMultDiv2(a_Im, b_Re);
+}
+
+inline void cplxMultDiv2(FIXP_SGL *c_Re, FIXP_SGL *c_Im, const FIXP_SGL a_Re,
+ const FIXP_SGL a_Im, const FIXP_SGL b_Re,
+ const FIXP_SGL b_Im) {
+ *c_Re = FX_DBL2FX_SGL(fMultDiv2(a_Re, b_Re) - fMultDiv2(a_Im, b_Im));
+ *c_Im = FX_DBL2FX_SGL(fMultDiv2(a_Re, b_Im) + fMultDiv2(a_Im, b_Re));
+}
+#endif
+
+#if !defined(FUNCTION_cplxMultDiv2_32x16)
+#define FUNCTION_cplxMultDiv2_32x16
+
+inline void cplxMultDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_SPK w) {
+ cplxMultDiv2(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im);
+}
+#endif
+
+#if !defined(FUNCTION_cplxMultDiv2_16x16)
+#define FUNCTION_cplxMultDiv2_16x16
+
+inline void cplxMultDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_SGL a_Re,
+ const FIXP_SGL a_Im, const FIXP_SPK w) {
+ cplxMultDiv2(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im);
+}
+
+inline void cplxMultDiv2(FIXP_SGL *c_Re, FIXP_SGL *c_Im, const FIXP_SGL a_Re,
+ const FIXP_SGL a_Im, const FIXP_SPK w) {
+ cplxMultDiv2(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im);
+}
+#endif
+
+#if !defined(FUNCTION_cplxMultSubDiv2_32x16X2)
+#define FUNCTION_cplxMultSubDiv2_32x16X2
+
+inline void cplxMultSubDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_SGL b_Re,
+ const FIXP_SGL b_Im) {
+ *c_Re -= fMultDiv2(a_Re, b_Re) - fMultDiv2(a_Im, b_Im);
+ *c_Im -= fMultDiv2(a_Re, b_Im) + fMultDiv2(a_Im, b_Re);
+}
+#endif
+
+#if !defined(FUNCTION_cplxMultDiv2_32x32X2)
+#define FUNCTION_cplxMultDiv2_32x32X2
+
+inline void cplxMultDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_DBL b_Re,
+ const FIXP_DBL b_Im) {
+ *c_Re = fMultDiv2(a_Re, b_Re) - fMultDiv2(a_Im, b_Im);
+ *c_Im = fMultDiv2(a_Re, b_Im) + fMultDiv2(a_Im, b_Re);
+}
+#endif
+
+#if !defined(FUNCTION_cplxMultDiv2_32x32)
+#define FUNCTION_cplxMultDiv2_32x32
+
+inline void cplxMultDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_DPK w) {
+ cplxMultDiv2(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im);
+}
+#endif
+
+#if !defined(FUNCTION_cplxMultSubDiv2_32x32X2)
+#define FUNCTION_cplxMultSubDiv2_32x32X2
+
+inline void cplxMultSubDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_DBL b_Re,
+ const FIXP_DBL b_Im) {
+ *c_Re -= fMultDiv2(a_Re, b_Re) - fMultDiv2(a_Im, b_Im);
+ *c_Im -= fMultDiv2(a_Re, b_Im) + fMultDiv2(a_Im, b_Re);
+}
+#endif
+
+ /* #############################################################################
+ */
+
+#if !defined(FUNCTION_cplxMult_32x16X2)
+#define FUNCTION_cplxMult_32x16X2
+
+inline void cplxMult(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_SGL b_Re,
+ const FIXP_SGL b_Im) {
+ *c_Re = fMult(a_Re, b_Re) - fMult(a_Im, b_Im);
+ *c_Im = fMult(a_Re, b_Im) + fMult(a_Im, b_Re);
+}
+inline void cplxMult(FIXP_SGL *c_Re, FIXP_SGL *c_Im, const FIXP_SGL a_Re,
+ const FIXP_SGL a_Im, const FIXP_SGL b_Re,
+ const FIXP_SGL b_Im) {
+ *c_Re = FX_DBL2FX_SGL(fMult(a_Re, b_Re) - fMult(a_Im, b_Im));
+ *c_Im = FX_DBL2FX_SGL(fMult(a_Re, b_Im) + fMult(a_Im, b_Re));
+}
+#endif
+
+#if !defined(FUNCTION_cplxMult_32x16)
+#define FUNCTION_cplxMult_32x16
+
+inline void cplxMult(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_SPK w) {
+ cplxMult(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im);
+}
+#endif
+
+#if !defined(FUNCTION_cplxMult_32x32X2)
+#define FUNCTION_cplxMult_32x32X2
+
+inline void cplxMult(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_DBL b_Re,
+ const FIXP_DBL b_Im) {
+ *c_Re = fMult(a_Re, b_Re) - fMult(a_Im, b_Im);
+ *c_Im = fMult(a_Re, b_Im) + fMult(a_Im, b_Re);
+}
+#endif
+
+#if !defined(FUNCTION_cplxMult_32x32)
+#define FUNCTION_cplxMult_32x32
+inline void cplxMult(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re,
+ const FIXP_DBL a_Im, const FIXP_DPK w) {
+ cplxMult(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im);
+}
+#endif
+
+ /* #############################################################################
+ */
+
+#endif /* CPLX_MUL_H */
diff --git a/fdk-aac/libFDK/include/dct.h b/fdk-aac/libFDK/include/dct.h
new file mode 100644
index 0000000..308afcb
--- /dev/null
+++ b/fdk-aac/libFDK/include/dct.h
@@ -0,0 +1,171 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: Library functions to calculate standard DCTs. This will most
+ likely be replaced by hand-optimized functions for the specific
+ target processor.
+
+*******************************************************************************/
+
+#ifndef DCT_H
+#define DCT_H
+
+#include "common_fix.h"
+
+void dct_getTables(const FIXP_WTP **ptwiddle, const FIXP_STP **sin_twiddle,
+ int *sin_step, int length);
+
+/**
+ * \brief Calculate DCT type II of given length. The DCT IV is
+ * calculated by a complex FFT, with some pre and post twiddeling.
+ * A factor of sqrt(2/(N-1)) is NOT applied.
+ * \param pDat pointer to input/output data (in place processing).
+ * \param size size of pDat.
+ * \param pDat_e pointer to an integer containing the exponent of the data
+ * referenced by pDat. The exponent is updated accordingly.
+ */
+void dct_II(FIXP_DBL *pDat, FIXP_DBL *tmp, int size, int *pDat_e);
+
+/**
+ * \brief Calculate DCT type III of given length. The DCT IV is
+ * calculated by a complex FFT, with some pre and post twiddeling.
+ * Note that the factor 0.5 for the sum term x[0] is 1.0 instead of 0.5.
+ * A factor of sqrt(2/N) is NOT applied.
+ * \param pDat pointer to input/output data (in place processing).
+ * \param size size of pDat.
+ * \param pDat_e pointer to an integer containing the exponent of the data
+ * referenced by pDat. The exponent is updated accordingly.
+ */
+void dct_III(FIXP_DBL *pDat, FIXP_DBL *tmp, int size, int *pDat_e);
+
+/**
+ * \brief Calculate DST type III of given length. The DST III is
+ * calculated by a DCT III of mirrored input and sign-flipping of odd
+ * output coefficients.
+ * Note that the factor 0.5 for the sum term x[N-1] is 1.0 instead of
+ * 0.5. A factor of sqrt(2/N) is NOT applied.
+ * \param pDat pointer to input/output data (in place processing).
+ * \param size size of pDat.
+ * \param pDat_e pointer to an integer containing the exponent of the data
+ * referenced by pDat. The exponent is updated accordingly.
+ */
+void dst_III(FIXP_DBL *pDat, FIXP_DBL *tmp, int size, int *pDat_e);
+
+/**
+ * \brief Calculate DCT type IV of given length. The DCT IV is
+ * calculated by a complex FFT, with some pre and post twiddeling.
+ * A factor of sqrt(2/N) is NOT applied.
+ * \param pDat pointer to input/output data (in place processing).
+ * \param size size of pDat.
+ * \param pDat_e pointer to an integer containing the exponent of the data
+ * referenced by pDat. The exponent is updated accordingly.
+ */
+void dct_IV(FIXP_DBL *pDat, int size, int *pDat_e);
+
+/**
+ * \brief Calculate DST type IV of given length. The DST IV is
+ * calculated by a complex FFT, with some pre and post twiddeling.
+ * A factor of sqrt(2/N) is NOT applied.
+ * \param pDat pointer to input/output data (in place processing).
+ * \param size size of pDat.
+ * \param pDat_e pointer to an integer containing the exponent of the data
+ * referenced by pDat. The exponent is updated accordingly.
+ */
+void dst_IV(FIXP_DBL *pDat, int size, int *pDat_e);
+
+#endif
diff --git a/fdk-aac/libFDK/include/fft.h b/fdk-aac/libFDK/include/fft.h
new file mode 100644
index 0000000..d394046
--- /dev/null
+++ b/fdk-aac/libFDK/include/fft.h
@@ -0,0 +1,263 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Josef Hoepfl, DSP Solutions
+
+ Description: Fix point FFT
+
+*******************************************************************************/
+
+#ifndef FFT_H
+#define FFT_H
+
+#include "common_fix.h"
+
+/**
+ * \brief Perform an inplace complex valued FFT of length 2^n
+ *
+ * \param length Length of the FFT to be calculated.
+ * \param pInput Input/Output data buffer. The input data must have at least 1
+ * bit scale headroom. The values are interleaved, real/imag pairs.
+ * \param scalefactor Pointer to an INT, which contains the current scale of the
+ * input data, which is updated according to the FFT scale.
+ */
+void fft(int length, FIXP_DBL *pInput, INT *scalefactor);
+
+/**
+ * \brief Perform an inplace complex valued IFFT of length 2^n
+ *
+ * \param length Length of the FFT to be calculated.
+ * \param pInput Input/Output data buffer. The input data must have at least 1
+ * bit scale headroom. The values are interleaved, real/imag pairs.
+ * \param scalefactor Pointer to an INT, which contains the current scale of the
+ * input data, which is updated according to the IFFT scale.
+ */
+void ifft(int length, FIXP_DBL *pInput, INT *scalefactor);
+
+/*
+ * Frequently used and fixed short length FFTs.
+ */
+
+#ifndef FUNCTION_fft_4
+/**
+ * \brief Perform an inplace complex valued FFT of length 4
+ *
+ * \param pInput Input/Output data buffer. The input data must have at least 1
+ * bit scale headroom. The values are interleaved, real/imag pairs.
+ */
+LNK_SECTION_CODE_L1
+static FDK_FORCEINLINE void fft_4(FIXP_DBL *x) {
+ FIXP_DBL a00, a10, a20, a30, tmp0, tmp1;
+
+ a00 = (x[0] + x[4]) >> 1; /* Re A + Re B */
+ a10 = (x[2] + x[6]) >> 1; /* Re C + Re D */
+ a20 = (x[1] + x[5]) >> 1; /* Im A + Im B */
+ a30 = (x[3] + x[7]) >> 1; /* Im C + Im D */
+
+ x[0] = a00 + a10; /* Re A' = Re A + Re B + Re C + Re D */
+ x[1] = a20 + a30; /* Im A' = Im A + Im B + Im C + Im D */
+
+ tmp0 = a00 - x[4]; /* Re A - Re B */
+ tmp1 = a20 - x[5]; /* Im A - Im B */
+
+ x[4] = a00 - a10; /* Re C' = Re A + Re B - Re C - Re D */
+ x[5] = a20 - a30; /* Im C' = Im A + Im B - Im C - Im D */
+
+ a10 = a10 - x[6]; /* Re C - Re D */
+ a30 = a30 - x[7]; /* Im C - Im D */
+
+ x[2] = tmp0 + a30; /* Re B' = Re A - Re B + Im C - Im D */
+ x[6] = tmp0 - a30; /* Re D' = Re A - Re B - Im C + Im D */
+ x[3] = tmp1 - a10; /* Im B' = Im A - Im B - Re C + Re D */
+ x[7] = tmp1 + a10; /* Im D' = Im A - Im B + Re C - Re D */
+}
+#endif /* FUNCTION_fft_4 */
+
+#ifndef FUNCTION_fft_8
+LNK_SECTION_CODE_L1
+static FDK_FORCEINLINE void fft_8(FIXP_DBL *x) {
+ FIXP_SPK w_PiFOURTH = {{FIXP_SGL(0x5A82), FIXP_SGL(0x5A82)}};
+
+ FIXP_DBL a00, a10, a20, a30;
+ FIXP_DBL y[16];
+
+ a00 = (x[0] + x[8]) >> 1;
+ a10 = x[4] + x[12];
+ a20 = (x[1] + x[9]) >> 1;
+ a30 = x[5] + x[13];
+
+ y[0] = a00 + (a10 >> 1);
+ y[4] = a00 - (a10 >> 1);
+ y[1] = a20 + (a30 >> 1);
+ y[5] = a20 - (a30 >> 1);
+
+ a00 = a00 - x[8];
+ a10 = (a10 >> 1) - x[12];
+ a20 = a20 - x[9];
+ a30 = (a30 >> 1) - x[13];
+
+ y[2] = a00 + a30;
+ y[6] = a00 - a30;
+ y[3] = a20 - a10;
+ y[7] = a20 + a10;
+
+ a00 = (x[2] + x[10]) >> 1;
+ a10 = x[6] + x[14];
+ a20 = (x[3] + x[11]) >> 1;
+ a30 = x[7] + x[15];
+
+ y[8] = a00 + (a10 >> 1);
+ y[12] = a00 - (a10 >> 1);
+ y[9] = a20 + (a30 >> 1);
+ y[13] = a20 - (a30 >> 1);
+
+ a00 = a00 - x[10];
+ a10 = (a10 >> 1) - x[14];
+ a20 = a20 - x[11];
+ a30 = (a30 >> 1) - x[15];
+
+ y[10] = a00 + a30;
+ y[14] = a00 - a30;
+ y[11] = a20 - a10;
+ y[15] = a20 + a10;
+
+ FIXP_DBL vr, vi, ur, ui;
+
+ ur = y[0] >> 1;
+ ui = y[1] >> 1;
+ vr = y[8];
+ vi = y[9];
+ x[0] = ur + (vr >> 1);
+ x[1] = ui + (vi >> 1);
+ x[8] = ur - (vr >> 1);
+ x[9] = ui - (vi >> 1);
+
+ ur = y[4] >> 1;
+ ui = y[5] >> 1;
+ vi = y[12];
+ vr = y[13];
+ x[4] = ur + (vr >> 1);
+ x[5] = ui - (vi >> 1);
+ x[12] = ur - (vr >> 1);
+ x[13] = ui + (vi >> 1);
+
+ ur = y[10];
+ ui = y[11];
+
+ cplxMultDiv2(&vi, &vr, ui, ur, w_PiFOURTH);
+
+ ur = y[2];
+ ui = y[3];
+ x[2] = (ur >> 1) + vr;
+ x[3] = (ui >> 1) + vi;
+ x[10] = (ur >> 1) - vr;
+ x[11] = (ui >> 1) - vi;
+
+ ur = y[14];
+ ui = y[15];
+
+ cplxMultDiv2(&vr, &vi, ui, ur, w_PiFOURTH);
+
+ ur = y[6];
+ ui = y[7];
+ x[6] = (ur >> 1) + vr;
+ x[7] = (ui >> 1) - vi;
+ x[14] = (ur >> 1) - vr;
+ x[15] = (ui >> 1) + vi;
+}
+#endif /* FUNCTION_fft_8 */
+
+#endif
diff --git a/fdk-aac/libFDK/include/fft_rad2.h b/fdk-aac/libFDK/include/fft_rad2.h
new file mode 100644
index 0000000..b820b7d
--- /dev/null
+++ b/fdk-aac/libFDK/include/fft_rad2.h
@@ -0,0 +1,121 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef FFT_RAD2_H
+#define FFT_RAD2_H
+
+#include "common_fix.h"
+
+/**
+ * \brief Performe an inplace complex valued FFT of 2^n length
+ *
+ * \param x Input/Output data buffer. The input data must have at least 1 bit
+ * scale headroom. The values are interleaved, real/imag pairs.
+ * \param ldn log2 of FFT length
+ * \param trigdata Pointer to a sinetable of a length of at least (2^ldn)/2 sine
+ * values.
+ * \param trigDataSize length of the sinetable "trigdata".
+ */
+void dit_fft(FIXP_DBL *x, const INT ldn, const FIXP_STP *trigdata,
+ const INT trigDataSize);
+
+#endif /* FFT_RAD2_H */
diff --git a/fdk-aac/libFDK/include/fixmadd.h b/fdk-aac/libFDK/include/fixmadd.h
new file mode 100644
index 0000000..1672456
--- /dev/null
+++ b/fdk-aac/libFDK/include/fixmadd.h
@@ -0,0 +1,333 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(FIXMADD_H)
+#define FIXMADD_H
+
+#include "FDK_archdef.h"
+#include "machine_type.h"
+#include "fixmul.h"
+
+#if defined(__arm__)
+#include "arm/fixmadd_arm.h"
+
+#endif /* all cores */
+
+/*************************************************************************
+ *************************************************************************
+ Software fallbacks for missing functions.
+**************************************************************************
+**************************************************************************/
+
+/* Divide by two versions. */
+
+#if !defined(FUNCTION_fixmadddiv2_DD)
+inline FIXP_DBL fixmadddiv2_DD(FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) {
+ return (x + fMultDiv2(a, b));
+}
+#endif
+
+#if !defined(FUNCTION_fixmadddiv2_SD)
+inline FIXP_DBL fixmadddiv2_SD(FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) {
+#ifdef FUNCTION_fixmadddiv2_DS
+ return fixmadddiv2_DS(x, b, a);
+#else
+ return fixmadddiv2_DD(x, FX_SGL2FX_DBL(a), b);
+#endif
+}
+#endif
+
+#if !defined(FUNCTION_fixmadddiv2_DS)
+inline FIXP_DBL fixmadddiv2_DS(FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) {
+#ifdef FUNCTION_fixmadddiv2_SD
+ return fixmadddiv2_SD(x, b, a);
+#else
+ return fixmadddiv2_DD(x, a, FX_SGL2FX_DBL(b));
+#endif
+}
+#endif
+
+#if !defined(FUNCTION_fixmadddiv2_SS)
+inline FIXP_DBL fixmadddiv2_SS(FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) {
+ return x + fMultDiv2(a, b);
+}
+#endif
+
+#if !defined(FUNCTION_fixmsubdiv2_DD)
+inline FIXP_DBL fixmsubdiv2_DD(FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) {
+ return (x - fMultDiv2(a, b));
+}
+#endif
+
+#if !defined(FUNCTION_fixmsubdiv2_SD)
+inline FIXP_DBL fixmsubdiv2_SD(FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) {
+#ifdef FUNCTION_fixmsubdiv2_DS
+ return fixmsubdiv2_DS(x, b, a);
+#else
+ return fixmsubdiv2_DD(x, FX_SGL2FX_DBL(a), b);
+#endif
+}
+#endif
+
+#if !defined(FUNCTION_fixmsubdiv2_DS)
+inline FIXP_DBL fixmsubdiv2_DS(FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) {
+#ifdef FUNCTION_fixmsubdiv2_SD
+ return fixmsubdiv2_SD(x, b, a);
+#else
+ return fixmsubdiv2_DD(x, a, FX_SGL2FX_DBL(b));
+#endif
+}
+#endif
+
+#if !defined(FUNCTION_fixmsubdiv2_SS)
+inline FIXP_DBL fixmsubdiv2_SS(FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) {
+ return x - fMultDiv2(a, b);
+}
+#endif
+
+#if !defined(FUNCTION_fixmadddiv2BitExact_DD)
+#define FUNCTION_fixmadddiv2BitExact_DD
+inline FIXP_DBL fixmadddiv2BitExact_DD(FIXP_DBL x, const FIXP_DBL a,
+ const FIXP_DBL b) {
+ return x + fMultDiv2BitExact(a, b);
+}
+#endif
+#if !defined(FUNCTION_fixmadddiv2BitExact_SD)
+#define FUNCTION_fixmadddiv2BitExact_SD
+inline FIXP_DBL fixmadddiv2BitExact_SD(FIXP_DBL x, const FIXP_SGL a,
+ const FIXP_DBL b) {
+#ifdef FUNCTION_fixmadddiv2BitExact_DS
+ return fixmadddiv2BitExact_DS(x, b, a);
+#else
+ return x + fMultDiv2BitExact(a, b);
+#endif
+}
+#endif
+#if !defined(FUNCTION_fixmadddiv2BitExact_DS)
+#define FUNCTION_fixmadddiv2BitExact_DS
+inline FIXP_DBL fixmadddiv2BitExact_DS(FIXP_DBL x, const FIXP_DBL a,
+ const FIXP_SGL b) {
+#ifdef FUNCTION_fixmadddiv2BitExact_SD
+ return fixmadddiv2BitExact_SD(x, b, a);
+#else
+ return x + fMultDiv2BitExact(a, b);
+#endif
+}
+#endif
+
+#if !defined(FUNCTION_fixmsubdiv2BitExact_DD)
+#define FUNCTION_fixmsubdiv2BitExact_DD
+inline FIXP_DBL fixmsubdiv2BitExact_DD(FIXP_DBL x, const FIXP_DBL a,
+ const FIXP_DBL b) {
+ return x - fMultDiv2BitExact(a, b);
+}
+#endif
+#if !defined(FUNCTION_fixmsubdiv2BitExact_SD)
+#define FUNCTION_fixmsubdiv2BitExact_SD
+inline FIXP_DBL fixmsubdiv2BitExact_SD(FIXP_DBL x, const FIXP_SGL a,
+ const FIXP_DBL b) {
+#ifdef FUNCTION_fixmsubdiv2BitExact_DS
+ return fixmsubdiv2BitExact_DS(x, b, a);
+#else
+ return x - fMultDiv2BitExact(a, b);
+#endif
+}
+#endif
+#if !defined(FUNCTION_fixmsubdiv2BitExact_DS)
+#define FUNCTION_fixmsubdiv2BitExact_DS
+inline FIXP_DBL fixmsubdiv2BitExact_DS(FIXP_DBL x, const FIXP_DBL a,
+ const FIXP_SGL b) {
+#ifdef FUNCTION_fixmsubdiv2BitExact_SD
+ return fixmsubdiv2BitExact_SD(x, b, a);
+#else
+ return x - fMultDiv2BitExact(a, b);
+#endif
+}
+#endif
+
+ /* Normal versions */
+
+#if !defined(FUNCTION_fixmadd_DD)
+inline FIXP_DBL fixmadd_DD(FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) {
+ return fixmadddiv2_DD(x, a, b) << 1;
+}
+#endif
+#if !defined(FUNCTION_fixmadd_SD)
+inline FIXP_DBL fixmadd_SD(FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) {
+#ifdef FUNCTION_fixmadd_DS
+ return fixmadd_DS(x, b, a);
+#else
+ return fixmadd_DD(x, FX_SGL2FX_DBL(a), b);
+#endif
+}
+#endif
+#if !defined(FUNCTION_fixmadd_DS)
+inline FIXP_DBL fixmadd_DS(FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) {
+#ifdef FUNCTION_fixmadd_SD
+ return fixmadd_SD(x, b, a);
+#else
+ return fixmadd_DD(x, a, FX_SGL2FX_DBL(b));
+#endif
+}
+#endif
+#if !defined(FUNCTION_fixmadd_SS)
+inline FIXP_DBL fixmadd_SS(FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) {
+ return (x + fMultDiv2(a, b)) << 1;
+}
+#endif
+
+#if !defined(FUNCTION_fixmsub_DD)
+inline FIXP_DBL fixmsub_DD(FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) {
+ return fixmsubdiv2_DD(x, a, b) << 1;
+}
+#endif
+#if !defined(FUNCTION_fixmsub_SD)
+inline FIXP_DBL fixmsub_SD(FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) {
+#ifdef FUNCTION_fixmsub_DS
+ return fixmsub_DS(x, b, a);
+#else
+ return fixmsub_DD(x, FX_SGL2FX_DBL(a), b);
+#endif
+}
+#endif
+#if !defined(FUNCTION_fixmsub_DS)
+inline FIXP_DBL fixmsub_DS(FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) {
+#ifdef FUNCTION_fixmsub_SD
+ return fixmsub_SD(x, b, a);
+#else
+ return fixmsub_DD(x, a, FX_SGL2FX_DBL(b));
+#endif
+}
+#endif
+#if !defined(FUNCTION_fixmsub_SS)
+inline FIXP_DBL fixmsub_SS(FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) {
+ return (x - fMultDiv2(a, b)) << 1;
+}
+#endif
+
+#if !defined(FUNCTION_fixpow2adddiv2_D)
+#ifdef FUNCTION_fixmadddiv2_DD
+#define fixpadddiv2_D(x, a) fixmadddiv2_DD(x, a, a)
+#else
+inline INT fixpadddiv2_D(FIXP_DBL x, const FIXP_DBL a) {
+ return (x + fPow2Div2(a));
+}
+#endif
+#endif
+#if !defined(FUNCTION_fixpow2add_D)
+inline INT fixpadd_D(FIXP_DBL x, const FIXP_DBL a) { return (x + fPow2(a)); }
+#endif
+
+#if !defined(FUNCTION_fixpow2adddiv2_S)
+#ifdef FUNCTION_fixmadddiv2_SS
+#define fixpadddiv2_S(x, a) fixmadddiv2_SS(x, a, a)
+#else
+inline INT fixpadddiv2_S(FIXP_DBL x, const FIXP_SGL a) {
+ return (x + fPow2Div2(a));
+}
+#endif
+#endif
+#if !defined(FUNCTION_fixpow2add_S)
+inline INT fixpadd_S(FIXP_DBL x, const FIXP_SGL a) { return (x + fPow2(a)); }
+#endif
+
+#endif /* FIXMADD_H */
diff --git a/fdk-aac/libFDK/include/fixminmax.h b/fdk-aac/libFDK/include/fixminmax.h
new file mode 100644
index 0000000..69ef35d
--- /dev/null
+++ b/fdk-aac/libFDK/include/fixminmax.h
@@ -0,0 +1,131 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description: min/max inline functions and defines
+
+*******************************************************************************/
+
+#ifndef FIXMINMAX_H
+#define FIXMINMAX_H
+
+#include "FDK_archdef.h"
+#include "machine_type.h"
+
+/* Inline Function to determine the smaller/bigger value of two values with same
+ * type. */
+
+template <class T>
+inline T fixmin(T a, T b) {
+ return (a < b ? a : b);
+}
+
+template <class T>
+inline T fixmax(T a, T b) {
+ return (a > b ? a : b);
+}
+
+#define fixmax_D(a, b) fixmax(a, b)
+#define fixmin_D(a, b) fixmin(a, b)
+#define fixmax_S(a, b) fixmax(a, b)
+#define fixmin_S(a, b) fixmin(a, b)
+#define fixmax_I(a, b) fixmax(a, b)
+#define fixmin_I(a, b) fixmin(a, b)
+#define fixmax_UI(a, b) fixmax(a, b)
+#define fixmin_UI(a, b) fixmin(a, b)
+
+#endif
diff --git a/fdk-aac/libFDK/include/fixmul.h b/fdk-aac/libFDK/include/fixmul.h
new file mode 100644
index 0000000..8eeb7ab
--- /dev/null
+++ b/fdk-aac/libFDK/include/fixmul.h
@@ -0,0 +1,298 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Stefan Gewinner
+
+ Description: fixed point multiplication
+
+*******************************************************************************/
+
+#if !defined(FIXMUL_H)
+#define FIXMUL_H
+
+#include "FDK_archdef.h"
+#include "machine_type.h"
+
+#if defined(__arm__)
+#include "arm/fixmul_arm.h"
+
+#elif defined(__mips__)
+#include "mips/fixmul_mips.h"
+
+#elif defined(__x86__)
+#include "x86/fixmul_x86.h"
+
+#elif defined(__powerpc__)
+#include "ppc/fixmul_ppc.h"
+
+#endif /* all cores */
+
+/*************************************************************************
+ *************************************************************************
+ Software fallbacks for missing functions
+**************************************************************************
+**************************************************************************/
+
+#if !defined(FUNCTION_fixmuldiv2_DD)
+#define FUNCTION_fixmuldiv2_DD
+inline LONG fixmuldiv2_DD(const LONG a, const LONG b) {
+ return (LONG)((((INT64)a) * b) >> 32);
+}
+#endif
+
+#if !defined(FUNCTION_fixmuldiv2BitExact_DD)
+#define FUNCTION_fixmuldiv2BitExact_DD
+inline LONG fixmuldiv2BitExact_DD(const LONG a, const LONG b) {
+ return (LONG)((((INT64)a) * b) >> 32);
+}
+#endif
+
+#if !defined(FUNCTION_fixmul_DD)
+#define FUNCTION_fixmul_DD
+inline LONG fixmul_DD(const LONG a, const LONG b) {
+ return fixmuldiv2_DD(a, b) << 1;
+}
+#endif
+
+#if !defined(FUNCTION_fixmulBitExact_DD)
+#define FUNCTION_fixmulBitExact_DD
+inline LONG fixmulBitExact_DD(const LONG a, const LONG b) {
+ return ((LONG)((((INT64)a) * b) >> 32)) << 1;
+}
+#endif
+
+#if !defined(FUNCTION_fixmuldiv2_SS)
+#define FUNCTION_fixmuldiv2_SS
+inline LONG fixmuldiv2_SS(const SHORT a, const SHORT b) {
+ return ((LONG)a * b);
+}
+#endif
+
+#if !defined(FUNCTION_fixmul_SS)
+#define FUNCTION_fixmul_SS
+inline LONG fixmul_SS(const SHORT a, const SHORT b) { return (a * b) << 1; }
+#endif
+
+#if !defined(FUNCTION_fixmuldiv2_SD)
+#define FUNCTION_fixmuldiv2_SD
+inline LONG fixmuldiv2_SD(const SHORT a, const LONG b)
+#ifdef FUNCTION_fixmuldiv2_DS
+{
+ return fixmuldiv2_DS(b, a);
+}
+#else
+{
+ return fixmuldiv2_DD(FX_SGL2FX_DBL(a), b);
+}
+#endif
+#endif
+
+#if !defined(FUNCTION_fixmuldiv2_DS)
+#define FUNCTION_fixmuldiv2_DS
+inline LONG fixmuldiv2_DS(const LONG a, const SHORT b)
+#ifdef FUNCTION_fixmuldiv2_SD
+{
+ return fixmuldiv2_SD(b, a);
+}
+#else
+{
+ return fixmuldiv2_DD(a, FX_SGL2FX_DBL(b));
+}
+#endif
+#endif
+
+#if !defined(FUNCTION_fixmuldiv2BitExact_SD)
+#define FUNCTION_fixmuldiv2BitExact_SD
+inline LONG fixmuldiv2BitExact_SD(const SHORT a, const LONG b)
+#ifdef FUNCTION_fixmuldiv2BitExact_DS
+{
+ return fixmuldiv2BitExact_DS(b, a);
+}
+#else
+{
+ return (LONG)((((INT64)a) * b) >> 16);
+}
+#endif
+#endif
+
+#if !defined(FUNCTION_fixmuldiv2BitExact_DS)
+#define FUNCTION_fixmuldiv2BitExact_DS
+inline LONG fixmuldiv2BitExact_DS(const LONG a, const SHORT b)
+#ifdef FUNCTION_fixmuldiv2BitExact_SD
+{
+ return fixmuldiv2BitExact_SD(b, a);
+}
+#else
+{
+ return (LONG)((((INT64)a) * b) >> 16);
+}
+#endif
+#endif
+
+#if !defined(FUNCTION_fixmul_SD)
+#define FUNCTION_fixmul_SD
+inline LONG fixmul_SD(const SHORT a, const LONG b) {
+#ifdef FUNCTION_fixmul_DS
+ return fixmul_DS(b, a);
+#else
+ return fixmuldiv2_SD(a, b) << 1;
+#endif
+}
+#endif
+
+#if !defined(FUNCTION_fixmul_DS)
+#define FUNCTION_fixmul_DS
+inline LONG fixmul_DS(const LONG a, const SHORT b) {
+#ifdef FUNCTION_fixmul_SD
+ return fixmul_SD(b, a);
+#else
+ return fixmuldiv2_DS(a, b) << 1;
+#endif
+}
+#endif
+
+#if !defined(FUNCTION_fixmulBitExact_SD)
+#define FUNCTION_fixmulBitExact_SD
+inline LONG fixmulBitExact_SD(const SHORT a, const LONG b)
+#ifdef FUNCTION_fixmulBitExact_DS
+{
+ return fixmulBitExact_DS(b, a);
+}
+#else
+{
+ return (LONG)(((((INT64)a) * b) >> 16) << 1);
+}
+#endif
+#endif
+
+#if !defined(FUNCTION_fixmulBitExact_DS)
+#define FUNCTION_fixmulBitExact_DS
+inline LONG fixmulBitExact_DS(const LONG a, const SHORT b)
+#ifdef FUNCTION_fixmulBitExact_SD
+{
+ return fixmulBitExact_SD(b, a);
+}
+#else
+{
+ return (LONG)(((((INT64)a) * b) >> 16) << 1);
+}
+#endif
+#endif
+
+#if !defined(FUNCTION_fixpow2div2_D)
+#define FUNCTION_fixpow2div2_D
+inline LONG fixpow2div2_D(const LONG a) { return fixmuldiv2_DD(a, a); }
+#endif
+
+#if !defined(FUNCTION_fixpow2_D)
+#define FUNCTION_fixpow2_D
+inline LONG fixpow2_D(const LONG a) { return fixpow2div2_D(a) << 1; }
+#endif
+
+#if !defined(FUNCTION_fixpow2div2_S)
+#define FUNCTION_fixpow2div2_S
+inline LONG fixpow2div2_S(const SHORT a) { return fixmuldiv2_SS(a, a); }
+#endif
+
+#if !defined(FUNCTION_fixpow2_S)
+#define FUNCTION_fixpow2_S
+inline LONG fixpow2_S(const SHORT a) {
+ LONG result = fixpow2div2_S(a) << 1;
+ return result ^ (result >> 31);
+}
+#endif
+
+#endif /* FIXMUL_H */
diff --git a/fdk-aac/libFDK/include/fixpoint_math.h b/fdk-aac/libFDK/include/fixpoint_math.h
new file mode 100644
index 0000000..3805892
--- /dev/null
+++ b/fdk-aac/libFDK/include/fixpoint_math.h
@@ -0,0 +1,921 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Gayer
+
+ Description: Fixed point specific mathematical functions
+
+*******************************************************************************/
+
+#ifndef FIXPOINT_MATH_H
+#define FIXPOINT_MATH_H
+
+#include "common_fix.h"
+#include "scale.h"
+
+/*
+ * Data definitions
+ */
+
+#define LD_DATA_SCALING (64.0f)
+#define LD_DATA_SHIFT 6 /* pow(2, LD_DATA_SHIFT) = LD_DATA_SCALING */
+
+#define MAX_LD_PRECISION 10
+#define LD_PRECISION 10
+
+/* Taylor series coefficients for ln(1-x), centered at 0 (MacLaurin polynomial).
+ */
+#ifndef LDCOEFF_16BIT
+LNK_SECTION_CONSTDATA_L1
+static const FIXP_DBL ldCoeff[MAX_LD_PRECISION] = {
+ FL2FXCONST_DBL(-1.0), FL2FXCONST_DBL(-1.0 / 2.0),
+ FL2FXCONST_DBL(-1.0 / 3.0), FL2FXCONST_DBL(-1.0 / 4.0),
+ FL2FXCONST_DBL(-1.0 / 5.0), FL2FXCONST_DBL(-1.0 / 6.0),
+ FL2FXCONST_DBL(-1.0 / 7.0), FL2FXCONST_DBL(-1.0 / 8.0),
+ FL2FXCONST_DBL(-1.0 / 9.0), FL2FXCONST_DBL(-1.0 / 10.0)};
+#else /* LDCOEFF_16BIT */
+LNK_SECTION_CONSTDATA_L1
+static const FIXP_SGL ldCoeff[MAX_LD_PRECISION] = {
+ FL2FXCONST_SGL(-1.0), FL2FXCONST_SGL(-1.0 / 2.0),
+ FL2FXCONST_SGL(-1.0 / 3.0), FL2FXCONST_SGL(-1.0 / 4.0),
+ FL2FXCONST_SGL(-1.0 / 5.0), FL2FXCONST_SGL(-1.0 / 6.0),
+ FL2FXCONST_SGL(-1.0 / 7.0), FL2FXCONST_SGL(-1.0 / 8.0),
+ FL2FXCONST_SGL(-1.0 / 9.0), FL2FXCONST_SGL(-1.0 / 10.0)};
+#endif /* LDCOEFF_16BIT */
+
+/*****************************************************************************
+
+ functionname: invSqrtNorm2
+ description: delivers 1/sqrt(op) normalized to .5...1 and the shift value
+of the OUTPUT
+
+*****************************************************************************/
+#define SQRT_BITS 7
+#define SQRT_VALUES (128 + 2)
+#define SQRT_BITS_MASK 0x7f
+#define SQRT_FRACT_BITS_MASK 0x007FFFFF
+
+extern const FIXP_DBL invSqrtTab[SQRT_VALUES];
+
+/*
+ * Hardware specific implementations
+ */
+
+#if defined(__x86__)
+#include "x86/fixpoint_math_x86.h"
+#endif /* target architecture selector */
+
+/*
+ * Fallback implementations
+ */
+#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
+
+/**
+ * \brief deprecated. Use fLog2() instead.
+ */
+#define CalcLdData(op) fLog2(op, 0)
+
+void LdDataVector(FIXP_DBL *srcVector, FIXP_DBL *destVector, INT number);
+
+extern const UINT exp2_tab_long[32];
+extern const UINT exp2w_tab_long[32];
+extern const UINT exp2x_tab_long[32];
+
+LNK_SECTION_CODE_L1
+FDK_INLINE FIXP_DBL CalcInvLdData(const FIXP_DBL x) {
+ int set_zero = (x < FL2FXCONST_DBL(-31.0 / 64.0)) ? 0 : 1;
+ int set_max = (x >= FL2FXCONST_DBL(31.0 / 64.0)) | (x == FL2FXCONST_DBL(0.0));
+
+ FIXP_SGL frac = (FIXP_SGL)((LONG)x & 0x3FF);
+ UINT index3 = (UINT)(LONG)(x >> 10) & 0x1F;
+ UINT index2 = (UINT)(LONG)(x >> 15) & 0x1F;
+ UINT index1 = (UINT)(LONG)(x >> 20) & 0x1F;
+ int exp = fMin(31, ((x > FL2FXCONST_DBL(0.0f)) ? (31 - (int)(x >> 25))
+ : (int)(-(x >> 25))));
+
+ UINT lookup1 = exp2_tab_long[index1] * set_zero;
+ UINT lookup2 = exp2w_tab_long[index2];
+ UINT lookup3 = exp2x_tab_long[index3];
+ UINT lookup3f =
+ lookup3 + (UINT)(LONG)fMultDiv2((FIXP_DBL)(0x0016302F), (FIXP_SGL)frac);
+
+ UINT lookup12 = (UINT)(LONG)fMult((FIXP_DBL)lookup1, (FIXP_DBL)lookup2);
+ UINT lookup = (UINT)(LONG)fMult((FIXP_DBL)lookup12, (FIXP_DBL)lookup3f);
+
+ FIXP_DBL retVal = (lookup << 3) >> exp;
+
+ if (set_max) {
+ retVal = (FIXP_DBL)MAXVAL_DBL;
+ }
+
+ return retVal;
+}
+
+void InitLdInt();
+FIXP_DBL CalcLdInt(INT i);
+
+extern const USHORT sqrt_tab[49];
+
+inline FIXP_DBL sqrtFixp_lookup(FIXP_DBL x) {
+ UINT y = (INT)x;
+ UCHAR is_zero = (y == 0);
+ INT zeros = fixnormz_D(y) & 0x1e;
+ y <<= zeros;
+ UINT idx = (y >> 26) - 16;
+ USHORT frac = (y >> 10) & 0xffff;
+ USHORT nfrac = 0xffff ^ frac;
+ UINT t = (UINT)nfrac * sqrt_tab[idx] + (UINT)frac * sqrt_tab[idx + 1];
+ t = t >> (zeros >> 1);
+ return (is_zero ? 0 : t);
+}
+
+inline FIXP_DBL sqrtFixp_lookup(FIXP_DBL x, INT *x_e) {
+ UINT y = (INT)x;
+ INT e;
+
+ if (x == (FIXP_DBL)0) {
+ return x;
+ }
+
+ /* Normalize */
+ e = fixnormz_D(y);
+ y <<= e;
+ e = *x_e - e + 2;
+
+ /* Correct odd exponent. */
+ if (e & 1) {
+ y >>= 1;
+ e++;
+ }
+ /* Get square root */
+ UINT idx = (y >> 26) - 16;
+ USHORT frac = (y >> 10) & 0xffff;
+ USHORT nfrac = 0xffff ^ frac;
+ UINT t = (UINT)nfrac * sqrt_tab[idx] + (UINT)frac * sqrt_tab[idx + 1];
+
+ /* Write back exponent */
+ *x_e = e >> 1;
+ return (FIXP_DBL)(LONG)(t >> 1);
+}
+
+void InitInvSqrtTab();
+
+#ifndef FUNCTION_invSqrtNorm2
+/**
+ * \brief calculate 1.0/sqrt(op)
+ * \param op_m mantissa of input value.
+ * \param result_e pointer to return the exponent of the result
+ * \return mantissa of the result
+ */
+/*****************************************************************************
+ delivers 1/sqrt(op) normalized to .5...1 and the shift value of the OUTPUT,
+ i.e. the denormalized result is 1/sqrt(op) = invSqrtNorm(op) * 2^(shift)
+ uses Newton-iteration for approximation
+ Q(n+1) = Q(n) + Q(n) * (0.5 - 2 * V * Q(n)^2)
+ with Q = 0.5* V ^-0.5; 0.5 <= V < 1.0
+*****************************************************************************/
+static FDK_FORCEINLINE FIXP_DBL invSqrtNorm2(FIXP_DBL op, INT *shift) {
+ FIXP_DBL val = op;
+ FIXP_DBL reg1, reg2;
+
+ if (val == FL2FXCONST_DBL(0.0)) {
+ *shift = 16;
+ return ((LONG)MAXVAL_DBL); /* maximum positive value */
+ }
+
+#define INVSQRTNORM2_LINEAR_INTERPOLATE
+#define INVSQRTNORM2_LINEAR_INTERPOLATE_HQ
+
+ /* normalize input, calculate shift value */
+ FDK_ASSERT(val > FL2FXCONST_DBL(0.0));
+ *shift = fNormz(val) - 1; /* CountLeadingBits() is not necessary here since
+ test value is always > 0 */
+ val <<= *shift; /* normalized input V */
+ *shift += 2; /* bias for exponent */
+
+#if defined(INVSQRTNORM2_LINEAR_INTERPOLATE)
+ INT index =
+ (INT)(val >> (DFRACT_BITS - 1 - (SQRT_BITS + 1))) & SQRT_BITS_MASK;
+ FIXP_DBL Fract =
+ (FIXP_DBL)(((INT)val & SQRT_FRACT_BITS_MASK) << (SQRT_BITS + 1));
+ FIXP_DBL diff = invSqrtTab[index + 1] - invSqrtTab[index];
+ reg1 = invSqrtTab[index] + (fMultDiv2(diff, Fract) << 1);
+#if defined(INVSQRTNORM2_LINEAR_INTERPOLATE_HQ)
+ /* reg1 = t[i] + (t[i+1]-t[i])*fract ... already computed ...
+ + (1-fract)fract*(t[i+2]-t[i+1])/2 */
+ if (Fract != (FIXP_DBL)0) {
+ /* fract = fract * (1 - fract) */
+ Fract = fMultDiv2(Fract, (FIXP_DBL)((ULONG)0x80000000 - (ULONG)Fract)) << 1;
+ diff = diff - (invSqrtTab[index + 2] - invSqrtTab[index + 1]);
+ reg1 = fMultAddDiv2(reg1, Fract, diff);
+ }
+#endif /* INVSQRTNORM2_LINEAR_INTERPOLATE_HQ */
+#else
+#error \
+ "Either define INVSQRTNORM2_NEWTON_ITERATE or INVSQRTNORM2_LINEAR_INTERPOLATE"
+#endif
+ /* calculate the output exponent = input exp/2 */
+ if (*shift & 0x00000001) { /* odd shift values ? */
+ /* Note: Do not use rounded value 0x5A82799A to avoid overflow with
+ * shift-by-2 */
+ reg2 = (FIXP_DBL)0x5A827999;
+ /* FL2FXCONST_DBL(0.707106781186547524400844362104849f);*/ /* 1/sqrt(2);
+ */
+ reg1 = fMultDiv2(reg1, reg2) << 2;
+ }
+
+ *shift = *shift >> 1;
+
+ return (reg1);
+}
+#endif /* FUNCTION_invSqrtNorm2 */
+
+#ifndef FUNCTION_sqrtFixp
+static FDK_FORCEINLINE FIXP_DBL sqrtFixp(FIXP_DBL op) {
+ INT tmp_exp = 0;
+ FIXP_DBL tmp_inv = invSqrtNorm2(op, &tmp_exp);
+
+ FDK_ASSERT(tmp_exp > 0);
+ return ((FIXP_DBL)(fMultDiv2((op << (tmp_exp - 1)), tmp_inv) << 2));
+}
+#endif /* FUNCTION_sqrtFixp */
+
+#ifndef FUNCTION_invFixp
+/**
+ * \brief calculate 1.0/op
+ * \param op mantissa of the input value.
+ * \return mantissa of the result with implicit exponent of 31
+ * \exceptions are provided for op=0,1 setting max. positive value
+ */
+static inline FIXP_DBL invFixp(FIXP_DBL op) {
+ if ((op == (FIXP_DBL)0x00000000) || (op == (FIXP_DBL)0x00000001)) {
+ return ((LONG)MAXVAL_DBL);
+ }
+ INT tmp_exp;
+ FIXP_DBL tmp_inv = invSqrtNorm2(op, &tmp_exp);
+ FDK_ASSERT((31 - (2 * tmp_exp + 1)) >= 0);
+ int shift = 31 - (2 * tmp_exp + 1);
+ tmp_inv = fPow2Div2(tmp_inv);
+ if (shift) {
+ tmp_inv = ((tmp_inv >> (shift - 1)) + (FIXP_DBL)1) >> 1;
+ }
+ return tmp_inv;
+}
+
+/**
+ * \brief calculate 1.0/(op_m * 2^op_e)
+ * \param op_m mantissa of the input value.
+ * \param op_e pointer into were the exponent of the input value is stored, and
+ * the result will be stored into.
+ * \return mantissa of the result
+ */
+static inline FIXP_DBL invFixp(FIXP_DBL op_m, int *op_e) {
+ if ((op_m == (FIXP_DBL)0x00000000) || (op_m == (FIXP_DBL)0x00000001)) {
+ *op_e = 31 - *op_e;
+ return ((LONG)MAXVAL_DBL);
+ }
+
+ INT tmp_exp;
+ FIXP_DBL tmp_inv = invSqrtNorm2(op_m, &tmp_exp);
+
+ *op_e = (tmp_exp << 1) - *op_e + 1;
+ return fPow2Div2(tmp_inv);
+}
+#endif /* FUNCTION_invFixp */
+
+#ifndef FUNCTION_schur_div
+
+/**
+ * \brief Divide two FIXP_DBL values with given precision.
+ * \param num dividend
+ * \param denum divisor
+ * \param count amount of significant bits of the result (starting to the MSB)
+ * \return num/divisor
+ */
+
+FIXP_DBL schur_div(FIXP_DBL num, FIXP_DBL denum, INT count);
+
+#endif /* FUNCTION_schur_div */
+
+FIXP_DBL mul_dbl_sgl_rnd(const FIXP_DBL op1, const FIXP_SGL op2);
+
+#ifndef FUNCTION_fMultNorm
+/**
+ * \brief multiply two values with normalization, thus max precision.
+ * Author: Robert Weidner
+ *
+ * \param f1 first factor
+ * \param f2 second factor
+ * \param result_e pointer to an INT where the exponent of the result is stored
+ * into
+ * \return mantissa of the product f1*f2
+ */
+FIXP_DBL fMultNorm(FIXP_DBL f1, FIXP_DBL f2, INT *result_e);
+
+/**
+ * \brief Multiply 2 values using maximum precision. The exponent of the result
+ * is 0.
+ * \param f1_m mantissa of factor 1
+ * \param f2_m mantissa of factor 2
+ * \return mantissa of the result with exponent equal to 0
+ */
+inline FIXP_DBL fMultNorm(FIXP_DBL f1, FIXP_DBL f2) {
+ FIXP_DBL m;
+ INT e;
+
+ m = fMultNorm(f1, f2, &e);
+
+ m = scaleValueSaturate(m, e);
+
+ return m;
+}
+
+/**
+ * \brief Multiply 2 values with exponent and use given exponent for the
+ * mantissa of the result.
+ * \param f1_m mantissa of factor 1
+ * \param f1_e exponent of factor 1
+ * \param f2_m mantissa of factor 2
+ * \param f2_e exponent of factor 2
+ * \param result_e exponent for the returned mantissa of the result
+ * \return mantissa of the result with exponent equal to result_e
+ */
+inline FIXP_DBL fMultNorm(FIXP_DBL f1_m, INT f1_e, FIXP_DBL f2_m, INT f2_e,
+ INT result_e) {
+ FIXP_DBL m;
+ INT e;
+
+ m = fMultNorm(f1_m, f2_m, &e);
+
+ m = scaleValueSaturate(m, e + f1_e + f2_e - result_e);
+
+ return m;
+}
+#endif /* FUNCTION_fMultNorm */
+
+#ifndef FUNCTION_fMultI
+/**
+ * \brief Multiplies a fractional value and a integer value and performs
+ * rounding to nearest
+ * \param a fractional value
+ * \param b integer value
+ * \return integer value
+ */
+inline INT fMultI(FIXP_DBL a, INT b) {
+ FIXP_DBL m, mi;
+ INT m_e;
+
+ m = fMultNorm(a, (FIXP_DBL)b, &m_e);
+
+ if (m_e < (INT)0) {
+ if (m_e > (INT)-DFRACT_BITS) {
+ m = m >> ((-m_e) - 1);
+ mi = (m + (FIXP_DBL)1) >> 1;
+ } else {
+ mi = (FIXP_DBL)0;
+ }
+ } else {
+ mi = scaleValueSaturate(m, m_e);
+ }
+
+ return ((INT)mi);
+}
+#endif /* FUNCTION_fMultI */
+
+#ifndef FUNCTION_fMultIfloor
+/**
+ * \brief Multiplies a fractional value and a integer value and performs floor
+ * rounding
+ * \param a fractional value
+ * \param b integer value
+ * \return integer value
+ */
+inline INT fMultIfloor(FIXP_DBL a, INT b) {
+ FIXP_DBL m, mi;
+ INT m_e;
+
+ m = fMultNorm(a, (FIXP_DBL)b, &m_e);
+
+ if (m_e < (INT)0) {
+ if (m_e > (INT)-DFRACT_BITS) {
+ mi = m >> (-m_e);
+ } else {
+ mi = (FIXP_DBL)0;
+ if (m < (FIXP_DBL)0) {
+ mi = (FIXP_DBL)-1;
+ }
+ }
+ } else {
+ mi = scaleValueSaturate(m, m_e);
+ }
+
+ return ((INT)mi);
+}
+#endif /* FUNCTION_fMultIfloor */
+
+#ifndef FUNCTION_fMultIceil
+/**
+ * \brief Multiplies a fractional value and a integer value and performs ceil
+ * rounding
+ * \param a fractional value
+ * \param b integer value
+ * \return integer value
+ */
+inline INT fMultIceil(FIXP_DBL a, INT b) {
+ FIXP_DBL m, mi;
+ INT m_e;
+
+ m = fMultNorm(a, (FIXP_DBL)b, &m_e);
+
+ if (m_e < (INT)0) {
+ if (m_e > (INT)-DFRACT_BITS) {
+ mi = (m >> (-m_e));
+ if ((LONG)m & ((1 << (-m_e)) - 1)) {
+ mi = mi + (FIXP_DBL)1;
+ }
+ } else {
+ mi = (FIXP_DBL)1;
+ if (m < (FIXP_DBL)0) {
+ mi = (FIXP_DBL)0;
+ }
+ }
+ } else {
+ mi = scaleValueSaturate(m, m_e);
+ }
+
+ return ((INT)mi);
+}
+#endif /* FUNCTION_fMultIceil */
+
+#ifndef FUNCTION_fDivNorm
+/**
+ * \brief Divide 2 FIXP_DBL values with normalization of input values.
+ * \param num numerator
+ * \param denum denominator
+ * \param result_e pointer to an INT where the exponent of the result is stored
+ * into
+ * \return num/denum with exponent = *result_e
+ */
+FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom, INT *result_e);
+
+/**
+ * \brief Divide 2 positive FIXP_DBL values with normalization of input values.
+ * \param num numerator
+ * \param denum denominator
+ * \return num/denum with exponent = 0
+ */
+FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom);
+
+/**
+ * \brief Divide 2 signed FIXP_DBL values with normalization of input values.
+ * \param num numerator
+ * \param denum denominator
+ * \param result_e pointer to an INT where the exponent of the result is stored
+ * into
+ * \return num/denum with exponent = *result_e
+ */
+FIXP_DBL fDivNormSigned(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e);
+
+/**
+ * \brief Divide 2 signed FIXP_DBL values with normalization of input values.
+ * \param num numerator
+ * \param denum denominator
+ * \return num/denum with exponent = 0
+ */
+FIXP_DBL fDivNormSigned(FIXP_DBL num, FIXP_DBL denom);
+#endif /* FUNCTION_fDivNorm */
+
+/**
+ * \brief Adjust mantissa to exponent -1
+ * \param a_m mantissa of value to be adjusted
+ * \param pA_e pointer to the exponen of a_m
+ * \return adjusted mantissa
+ */
+inline FIXP_DBL fAdjust(FIXP_DBL a_m, INT *pA_e) {
+ INT shift;
+
+ shift = fNorm(a_m) - 1;
+ *pA_e -= shift;
+
+ return scaleValue(a_m, shift);
+}
+
+#ifndef FUNCTION_fAddNorm
+/**
+ * \brief Add two values with normalization
+ * \param a_m mantissa of first summand
+ * \param a_e exponent of first summand
+ * \param a_m mantissa of second summand
+ * \param a_e exponent of second summand
+ * \param pResult_e pointer to where the exponent of the result will be stored
+ * to.
+ * \return mantissa of result
+ */
+inline FIXP_DBL fAddNorm(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e,
+ INT *pResult_e) {
+ INT result_e;
+ FIXP_DBL result_m;
+
+ /* If one of the summands is zero, return the other.
+ This is necessary for the summation of a very small number to zero */
+ if (a_m == (FIXP_DBL)0) {
+ *pResult_e = b_e;
+ return b_m;
+ }
+ if (b_m == (FIXP_DBL)0) {
+ *pResult_e = a_e;
+ return a_m;
+ }
+
+ a_m = fAdjust(a_m, &a_e);
+ b_m = fAdjust(b_m, &b_e);
+
+ if (a_e > b_e) {
+ result_m = a_m + (b_m >> fMin(a_e - b_e, DFRACT_BITS - 1));
+ result_e = a_e;
+ } else {
+ result_m = (a_m >> fMin(b_e - a_e, DFRACT_BITS - 1)) + b_m;
+ result_e = b_e;
+ }
+
+ *pResult_e = result_e;
+ return result_m;
+}
+
+inline FIXP_DBL fAddNorm(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e,
+ INT result_e) {
+ FIXP_DBL result_m;
+
+ a_m = scaleValue(a_m, a_e - result_e);
+ b_m = scaleValue(b_m, b_e - result_e);
+
+ result_m = a_m + b_m;
+
+ return result_m;
+}
+#endif /* FUNCTION_fAddNorm */
+
+/**
+ * \brief Divide 2 FIXP_DBL values with normalization of input values.
+ * \param num numerator
+ * \param denum denomintator
+ * \return num/denum with exponent = 0
+ */
+FIXP_DBL fDivNormHighPrec(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e);
+
+#ifndef FUNCTION_fPow
+/**
+ * \brief return 2 ^ (exp_m * 2^exp_e)
+ * \param exp_m mantissa of the exponent to 2.0f
+ * \param exp_e exponent of the exponent to 2.0f
+ * \param result_e pointer to a INT where the exponent of the result will be
+ * stored into
+ * \return mantissa of the result
+ */
+FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e, INT *result_e);
+
+/**
+ * \brief return 2 ^ (exp_m * 2^exp_e). This version returns only the mantissa
+ * with implicit exponent of zero.
+ * \param exp_m mantissa of the exponent to 2.0f
+ * \param exp_e exponent of the exponent to 2.0f
+ * \return mantissa of the result
+ */
+FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e);
+
+/**
+ * \brief return x ^ (exp_m * 2^exp_e), where log2(x) = baseLd_m * 2^(baseLd_e).
+ * This saves the need to compute log2() of constant values (when x is a
+ * constant).
+ * \param baseLd_m mantissa of log2() of x.
+ * \param baseLd_e exponent of log2() of x.
+ * \param exp_m mantissa of the exponent to 2.0f
+ * \param exp_e exponent of the exponent to 2.0f
+ * \param result_e pointer to a INT where the exponent of the result will be
+ * stored into
+ * \return mantissa of the result
+ */
+FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e,
+ INT *result_e);
+
+/**
+ * \brief return x ^ (exp_m * 2^exp_e), where log2(x) = baseLd_m * 2^(baseLd_e).
+ * This saves the need to compute log2() of constant values (when x is a
+ * constant). This version does not return an exponent, which is
+ * implicitly 0.
+ * \param baseLd_m mantissa of log2() of x.
+ * \param baseLd_e exponent of log2() of x.
+ * \param exp_m mantissa of the exponent to 2.0f
+ * \param exp_e exponent of the exponent to 2.0f
+ * \return mantissa of the result
+ */
+FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e);
+
+/**
+ * \brief return (base_m * 2^base_e) ^ (exp * 2^exp_e). Use fLdPow() instead
+ * whenever possible.
+ * \param base_m mantissa of the base.
+ * \param base_e exponent of the base.
+ * \param exp_m mantissa of power to be calculated of the base.
+ * \param exp_e exponent of power to be calculated of the base.
+ * \param result_e pointer to a INT where the exponent of the result will be
+ * stored into.
+ * \return mantissa of the result.
+ */
+FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
+ INT *result_e);
+
+/**
+ * \brief return (base_m * 2^base_e) ^ N
+ * \param base_m mantissa of the base
+ * \param base_e exponent of the base
+ * \param N power to be calculated of the base
+ * \param result_e pointer to a INT where the exponent of the result will be
+ * stored into
+ * \return mantissa of the result
+ */
+FIXP_DBL fPowInt(FIXP_DBL base_m, INT base_e, INT N, INT *result_e);
+#endif /* #ifndef FUNCTION_fPow */
+
+#ifndef FUNCTION_fLog2
+/**
+ * \brief Calculate log(argument)/log(2) (logarithm with base 2). deprecated.
+ * Use fLog2() instead.
+ * \param arg mantissa of the argument
+ * \param arg_e exponent of the argument
+ * \param result_e pointer to an INT to store the exponent of the result
+ * \return the mantissa of the result.
+ * \param
+ */
+FIXP_DBL CalcLog2(FIXP_DBL arg, INT arg_e, INT *result_e);
+
+/**
+ * \brief calculate logarithm of base 2 of x_m * 2^(x_e)
+ * \param x_m mantissa of the input value.
+ * \param x_e exponent of the input value.
+ * \param pointer to an INT where the exponent of the result is returned into.
+ * \return mantissa of the result.
+ */
+FDK_INLINE FIXP_DBL fLog2(FIXP_DBL x_m, INT x_e, INT *result_e) {
+ FIXP_DBL result_m;
+
+ /* Short cut for zero and negative numbers. */
+ if (x_m <= FL2FXCONST_DBL(0.0f)) {
+ *result_e = DFRACT_BITS - 1;
+ return FL2FXCONST_DBL(-1.0f);
+ }
+
+ /* Calculate log2() */
+ {
+ FIXP_DBL x2_m;
+
+ /* Move input value x_m * 2^x_e toward 1.0, where the taylor approximation
+ of the function log(1-x) centered at 0 is most accurate. */
+ {
+ INT b_norm;
+
+ b_norm = fNormz(x_m) - 1;
+ x2_m = x_m << b_norm;
+ x_e = x_e - b_norm;
+ }
+
+ /* map x from log(x) domain to log(1-x) domain. */
+ x2_m = -(x2_m + FL2FXCONST_DBL(-1.0));
+
+ /* Taylor polynomial approximation of ln(1-x) */
+ {
+ FIXP_DBL px2_m;
+ result_m = FL2FXCONST_DBL(0.0);
+ px2_m = x2_m;
+ for (int i = 0; i < LD_PRECISION; i++) {
+ result_m = fMultAddDiv2(result_m, ldCoeff[i], px2_m);
+ px2_m = fMult(px2_m, x2_m);
+ }
+ }
+ /* Multiply result with 1/ln(2) = 1.0 + 0.442695040888 (get log2(x) from
+ * ln(x) result). */
+ result_m =
+ fMultAddDiv2(result_m, result_m,
+ FL2FXCONST_DBL(2.0 * 0.4426950408889634073599246810019));
+
+ /* Add exponent part. log2(x_m * 2^x_e) = log2(x_m) + x_e */
+ if (x_e != 0) {
+ int enorm;
+
+ enorm = DFRACT_BITS - fNorm((FIXP_DBL)x_e);
+ /* The -1 in the right shift of result_m compensates the fMultDiv2() above
+ * in the taylor polynomial evaluation loop.*/
+ result_m = (result_m >> (enorm - 1)) +
+ ((FIXP_DBL)x_e << (DFRACT_BITS - 1 - enorm));
+
+ *result_e = enorm;
+ } else {
+ /* 1 compensates the fMultDiv2() above in the taylor polynomial evaluation
+ * loop.*/
+ *result_e = 1;
+ }
+ }
+
+ return result_m;
+}
+
+/**
+ * \brief calculate logarithm of base 2 of x_m * 2^(x_e)
+ * \param x_m mantissa of the input value.
+ * \param x_e exponent of the input value.
+ * \return mantissa of the result with implicit exponent of LD_DATA_SHIFT.
+ */
+FDK_INLINE FIXP_DBL fLog2(FIXP_DBL x_m, INT x_e) {
+ if (x_m <= FL2FXCONST_DBL(0.0f)) {
+ x_m = FL2FXCONST_DBL(-1.0f);
+ } else {
+ INT result_e;
+ x_m = fLog2(x_m, x_e, &result_e);
+ x_m = scaleValue(x_m, result_e - LD_DATA_SHIFT);
+ }
+ return x_m;
+}
+
+#endif /* FUNCTION_fLog2 */
+
+#ifndef FUNCTION_fAddSaturate
+/**
+ * \brief Add with saturation of the result.
+ * \param a first summand
+ * \param b second summand
+ * \return saturated sum of a and b.
+ */
+inline FIXP_SGL fAddSaturate(const FIXP_SGL a, const FIXP_SGL b) {
+ LONG sum;
+
+ sum = (LONG)(SHORT)a + (LONG)(SHORT)b;
+ sum = fMax(fMin((INT)sum, (INT)MAXVAL_SGL), (INT)MINVAL_SGL);
+ return (FIXP_SGL)(SHORT)sum;
+}
+
+/**
+ * \brief Add with saturation of the result.
+ * \param a first summand
+ * \param b second summand
+ * \return saturated sum of a and b.
+ */
+inline FIXP_DBL fAddSaturate(const FIXP_DBL a, const FIXP_DBL b) {
+ LONG sum;
+
+ sum = (LONG)(a >> 1) + (LONG)(b >> 1);
+ sum = fMax(fMin((INT)sum, (INT)(MAXVAL_DBL >> 1)), (INT)(MINVAL_DBL >> 1));
+ return (FIXP_DBL)(LONG)(sum << 1);
+}
+#endif /* FUNCTION_fAddSaturate */
+
+INT fixp_floorToInt(FIXP_DBL f_inp, INT sf);
+FIXP_DBL fixp_floor(FIXP_DBL f_inp, INT sf);
+
+INT fixp_ceilToInt(FIXP_DBL f_inp, INT sf);
+FIXP_DBL fixp_ceil(FIXP_DBL f_inp, INT sf);
+
+INT fixp_truncateToInt(FIXP_DBL f_inp, INT sf);
+FIXP_DBL fixp_truncate(FIXP_DBL f_inp, INT sf);
+
+INT fixp_roundToInt(FIXP_DBL f_inp, INT sf);
+FIXP_DBL fixp_round(FIXP_DBL f_inp, INT sf);
+
+/*****************************************************************************
+
+ array for 1/n, n=1..80
+
+****************************************************************************/
+
+extern const FIXP_DBL invCount[80];
+
+LNK_SECTION_INITCODE
+inline void InitInvInt(void) {}
+
+/**
+ * \brief Calculate the value of 1/i where i is a integer value. It supports
+ * input values from 1 upto (80-1).
+ * \param intValue Integer input value.
+ * \param FIXP_DBL representation of 1/intValue
+ */
+inline FIXP_DBL GetInvInt(int intValue) {
+ return invCount[fMin(fMax(intValue, 0), 80 - 1)];
+}
+
+#endif /* FIXPOINT_MATH_H */
diff --git a/fdk-aac/libFDK/include/huff_nodes.h b/fdk-aac/libFDK/include/huff_nodes.h
new file mode 100644
index 0000000..0dda5d3
--- /dev/null
+++ b/fdk-aac/libFDK/include/huff_nodes.h
@@ -0,0 +1,258 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Omer Osman
+
+ Description: MPEG-D SAC/USAC/SAOC Huffman Part0 Tables
+
+*******************************************************************************/
+
+#ifndef HUFF_NODES_H
+#define HUFF_NODES_H
+
+#include "genericStds.h"
+
+typedef struct {
+ SHORT nodeTab[39][2];
+
+} HUFF_RES_NODES;
+
+/* 1D Nodes */
+typedef struct {
+ SHORT nodeTab[30][2];
+
+} HUFF_CLD_NOD_1D;
+
+typedef struct {
+ SHORT nodeTab[7][2];
+
+} HUFF_ICC_NOD_1D;
+
+typedef struct {
+ SHORT nodeTab[50][2];
+
+} HUFF_CPC_NOD_1D;
+
+typedef struct {
+ SHORT nodeTab[15][2];
+
+} HUFF_OLD_NOD_1D;
+
+typedef struct {
+ SHORT nodeTab[63][2];
+
+} HUFF_NRG_NOD_1D;
+
+/* 2D Nodes */
+typedef struct {
+ SHORT lav3[15][2];
+ SHORT lav5[35][2];
+ SHORT lav7[63][2];
+ SHORT lav9[99][2];
+
+} HUFF_CLD_NOD_2D;
+
+typedef struct {
+ SHORT lav1[3][2];
+ SHORT lav3[15][2];
+ SHORT lav5[35][2];
+ SHORT lav7[63][2];
+
+} HUFF_ICC_NOD_2D;
+
+typedef struct {
+ SHORT lav3[15][2];
+ SHORT lav6[48][2];
+ SHORT lav9[99][2];
+ SHORT lav12[168][2];
+
+} HUFF_OLD_NOD_2D;
+
+typedef struct {
+ SHORT lav3[15][2];
+ SHORT lav5[35][2];
+ SHORT lav7[63][2];
+ SHORT lav9[99][2];
+
+} HUFF_NRG_NOD_2D_df;
+
+typedef struct {
+ SHORT lav3[15][2];
+ SHORT lav6[48][2];
+ SHORT lav9[99][2];
+ SHORT lav12[168][2];
+
+} HUFF_NRG_NOD_2D_dt;
+
+typedef struct {
+ HUFF_NRG_NOD_2D_df df[2];
+ HUFF_NRG_NOD_2D_dt dt[2];
+ HUFF_NRG_NOD_2D_df dp[2];
+
+} HUFF_NRG_NOD_2D;
+
+/* Complete bs Parameter Nodes */
+typedef struct {
+ const HUFF_CLD_NOD_1D *h1D[3];
+ const HUFF_CLD_NOD_2D *h2D[3][2];
+
+} HUFF_CLD_NODES;
+
+typedef struct {
+ const HUFF_ICC_NOD_1D *h1D[3];
+ const HUFF_ICC_NOD_2D *h2D[3][2];
+
+} HUFF_ICC_NODES;
+
+typedef struct {
+ const HUFF_OLD_NOD_1D *h1D[3];
+ const HUFF_OLD_NOD_2D *h2D[3][2];
+
+} HUFF_OLD_NODES;
+
+typedef struct {
+ const HUFF_NRG_NOD_1D *h1D[3];
+ const HUFF_NRG_NOD_2D *h2D;
+
+} HUFF_NRG_NODES;
+
+/* parameter instance */
+typedef struct {
+ SHORT cld[30][2];
+ SHORT icc[7][2];
+ SHORT ipd[7][2];
+ SHORT old[15][2];
+ SHORT nrg[63][2];
+} HUFF_PT0_NODES;
+
+typedef struct {
+ SHORT nodeTab[3][2];
+
+} HUFF_LAV_NODES;
+
+/* USAC specific */
+typedef struct {
+ SHORT nodeTab[7][2];
+
+} HUFF_IPD_NOD_1D;
+
+typedef struct {
+ SHORT lav1[3][2];
+ SHORT lav3[15][2];
+ SHORT lav5[35][2];
+ SHORT lav7[63][2];
+
+} HUFF_IPD_NOD_2D;
+
+typedef struct {
+ HUFF_IPD_NOD_1D h1D[3];
+ HUFF_IPD_NOD_2D h2D[3][2];
+
+} HUFF_IPD_NODES;
+
+/* non-lossy coding decoder */
+extern const HUFF_PT0_NODES FDK_huffPart0Nodes;
+extern const HUFF_LAV_NODES FDK_huffLavIdxNodes;
+
+extern const HUFF_ICC_NODES FDK_huffICCNodes;
+extern const HUFF_CLD_NODES FDK_huffCLDNodes;
+extern const HUFF_RES_NODES FDK_huffReshapeNodes;
+
+extern const HUFF_OLD_NODES huffOLDNodes;
+
+extern const HUFF_IPD_NODES FDK_huffIPDNodes;
+
+#endif /* HUFF_NODES_H */
diff --git a/fdk-aac/libFDK/include/mdct.h b/fdk-aac/libFDK/include/mdct.h
new file mode 100644
index 0000000..1382374
--- /dev/null
+++ b/fdk-aac/libFDK/include/mdct.h
@@ -0,0 +1,253 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Manuel Jander, Josef Hoepfl, Youliy Ninov, Daniel Hagel
+
+ Description: MDCT/MDST routines
+
+*******************************************************************************/
+
+#ifndef MDCT_H
+#define MDCT_H
+
+#include "common_fix.h"
+
+#define MDCT_OUT_HEADROOM 2 /* Output additional headroom */
+#define PCM_OUT_BITS SAMPLE_BITS
+#define PCM_OUT_HEADROOM 8 /* Must have the same values as DMXH_HEADROOM */
+
+#define MDCT_OUTPUT_SCALE (-MDCT_OUT_HEADROOM + (DFRACT_BITS - SAMPLE_BITS))
+/* Refer to "Output word length" in ISO/IEC 14496-3:2008(E) 23.2.3.6 */
+#define MDCT_OUTPUT_GAIN 16
+
+#if (MDCT_OUTPUT_SCALE >= 0)
+#define IMDCT_SCALE(x) SATURATE_RIGHT_SHIFT(x, MDCT_OUTPUT_SCALE, PCM_OUT_BITS)
+#else
+#define IMDCT_SCALE(x) SATURATE_LEFT_SHIFT(x, -MDCT_OUTPUT_SCALE, PCM_OUT_BITS)
+#endif
+#define IMDCT_SCALE_DBL(x) (FIXP_DBL)(x)
+#define IMDCT_SCALE_DBL_LSH1(x) SATURATE_LEFT_SHIFT_ALT((x), 1, DFRACT_BITS)
+
+#define MLT_FLAG_CURR_ALIAS_SYMMETRY 1
+
+typedef enum {
+ BLOCK_LONG = 0, /* normal long block */
+ BLOCK_START, /* long start block */
+ BLOCK_SHORT, /* 8 short blocks sequence */
+ BLOCK_STOP /* long stop block*/
+} BLOCK_TYPE;
+
+typedef enum { SHAPE_SINE = 0, SHAPE_KBD, SHAPE_LOL } WINDOW_SHAPE;
+
+/**
+ * \brief MDCT persistent data
+ */
+typedef struct {
+ union {
+ FIXP_DBL *freq;
+ FIXP_DBL *time;
+ } overlap; /**< Pointer to overlap memory */
+
+ const FIXP_WTP *prev_wrs; /**< pointer to previous right window slope */
+ int prev_tl; /**< previous transform length */
+ int prev_nr; /**< previous right window offset */
+ int prev_fr; /**< previous right window slope length */
+ int ov_offset; /**< overlap time data fill level */
+ int ov_size; /**< Overlap buffer size in words */
+
+ int prevAliasSymmetry;
+ int prevPrevAliasSymmetry;
+
+ FIXP_DBL *pFacZir;
+ FIXP_DBL *pAsymOvlp; /**< pointer to asymmetric overlap (used for stereo LPD
+ transition) */
+} mdct_t;
+
+typedef mdct_t *H_MDCT;
+
+/**
+ * \brief Initialize as valid MDCT handle
+ *
+ * \param hMdct handle of an allocated MDCT handle.
+ * \param overlap pointer to FIXP_DBL overlap buffer.
+ * \param overlapBufferSize size in FIXP_DBLs of the given overlap buffer.
+ */
+void mdct_init(H_MDCT hMdct, FIXP_DBL *overlap, INT overlapBufferSize);
+
+/**
+ * \brief perform MDCT transform (time domain to frequency domain) with given
+ * parameters.
+ *
+ * \param hMdct handle of an allocated MDCT handle.
+ * \param pTimeData pointer to input time domain signal
+ * \param noInSamples number of input samples
+ * \param mdctData pointer to where the resulting MDCT spectrum will be stored
+ * into.
+ * \param nSpec number of spectra
+ * \param pMdctData_e pointer to the input data exponent. Updated accordingly on
+ * return for output data.
+ * \return number of input samples processed.
+ */
+INT mdct_block(H_MDCT hMdct, const INT_PCM *pTimeData, const INT noInSamples,
+ FIXP_DBL *RESTRICT mdctData, const INT nSpec, const INT tl,
+ const FIXP_WTP *pRightWindowPart, const INT fr,
+ SHORT *pMdctData_e);
+
+/**
+ * \brief add/multiply 2/N transform gain and MPEG4 part 3 defined output gain
+ * (see definition of MDCT_OUTPUT_GAIN) to given mantissa factor and exponent.
+ * \param pGain pointer to the mantissa of a gain factor to be applied to IMDCT
+ * data.
+ * \param pExponent pointer to the exponent of a gain factor to be applied to
+ * IMDCT data.
+ * \param tl length of the IMDCT where the gain *pGain * (2 ^ *pExponent) will
+ * be applied to.
+ */
+void imdct_gain(FIXP_DBL *pGain, int *pExponent, int tl);
+
+/**
+ * \brief drain buffered output samples into given buffer. Changes the MDCT
+ * state.
+ */
+INT imdct_drain(H_MDCT hMdct, FIXP_DBL *pTimeData, INT nrSamplesRoom);
+
+/**
+ * \brief Copy overlap time domain data to given buffer. Does not change the
+ * MDCT state.
+ * \return number of actually copied samples (ov + nr).
+ */
+INT imdct_copy_ov_and_nr(H_MDCT hMdct, FIXP_DBL *pTimeData, INT nrSamples);
+
+/**
+ * \brief Adapt MDCT parameters for non-matching window slopes.
+ * \param hMdct handle of an allocated MDCT handle.
+ * \param pfl pointer to left overlap window side length.
+ * \param pnl pointer to length of the left n part of the window.
+ * \param tl transform length.
+ * \param wls pointer to the left side overlap window coefficients.
+ * \param noOutSamples desired number of output samples.
+ */
+void imdct_adapt_parameters(H_MDCT hMdct, int *pfl, int *pnl, int tl,
+ const FIXP_WTP *wls, int noOutSamples);
+
+/**
+ * \brief perform several inverse MLT transforms (frequency domain to time
+ * domain) with given parameters.
+ *
+ * \param hMdct handle of an allocated MDCT handle.
+ * \param output pointer to where the output time domain signal will be stored
+ * into.
+ * \param spectrum pointer to the input MDCT spectra.
+ * \param scalefactors exponents of the input spectrum.
+ * \param nSpec number of MDCT spectrums.
+ * \param noOutSamples desired number of output samples.
+ * \param tl transform length.
+ * \param wls pointer to the left side overlap window coefficients.
+ * \param fl left overlap window side length.
+ * \param wrs pointer to the right side overlap window coefficients of all
+ * individual IMDCTs.
+ * \param fr right overlap window side length of all individual IMDCTs.
+ * \param gain factor to apply to output samples (if != 0).
+ * \param flags flags controlling the type of transform
+ * \return number of output samples returned.
+ */
+INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum,
+ const SHORT scalefactor[], const INT nSpec,
+ const INT noOutSamples, const INT tl, const FIXP_WTP *wls,
+ INT fl, const FIXP_WTP *wrs, const INT fr, FIXP_DBL gain,
+ int flags);
+
+#endif /* MDCT_H */
diff --git a/fdk-aac/libFDK/include/mips/abs_mips.h b/fdk-aac/libFDK/include/mips/abs_mips.h
new file mode 100644
index 0000000..dbb2063
--- /dev/null
+++ b/fdk-aac/libFDK/include/mips/abs_mips.h
@@ -0,0 +1,125 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(ABS_MIPS_H)
+#define ABS_MIPS_H
+
+#if defined(__mips__)
+
+#if defined(__GNUC__) && defined(__mips__)
+
+#if defined(__mips_dsp)
+#define FUNCTION_fixabs_D
+#define FUNCTION_fixabs_I
+#define FUNCTION_fixabs_S
+inline FIXP_DBL fixabs_D(FIXP_DBL x) { return __builtin_mips_absq_s_w(x); }
+inline FIXP_SGL fixabs_S(FIXP_SGL x) {
+ return ((x) > (FIXP_SGL)(0)) ? (x) : -(x);
+}
+inline INT fixabs_I(INT x) { return __builtin_mips_absq_s_w(x); }
+#endif /* __mips_dsp */
+
+#endif /* defined(__GNUC__) && defined(__mips__) */
+
+#endif /*__mips__ */
+
+#endif /* !defined(ABS_MIPS_H) */
diff --git a/fdk-aac/libFDK/include/mips/clz_mips.h b/fdk-aac/libFDK/include/mips/clz_mips.h
new file mode 100644
index 0000000..748f6c2
--- /dev/null
+++ b/fdk-aac/libFDK/include/mips/clz_mips.h
@@ -0,0 +1,134 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(CLZ_MIPS_H)
+#define CLZ_MIPS_H
+
+#if defined(__mips__)
+
+#if defined(__mips__) && (__GNUC__ == 2) && (mips >= 32)
+
+#define FUNCTION_fixnormz_D
+inline INT fixnormz_D(LONG value) {
+ INT result;
+ __asm__("clz %0,%1" : "=d"(result) : "d"(value));
+
+ return result;
+}
+
+#elif defined(__mips__) && (__GNUC__ == 3) && (__mips >= 32)
+
+#define FUNCTION_fixnormz_D
+INT inline fixnormz_D(LONG value) {
+ INT result;
+ __asm__("clz %[result], %[value]"
+ : [result] "=r"(result)
+ : [value] "r"(value));
+
+ return result;
+}
+
+#endif
+
+#endif /* __mips__ */
+
+#endif /* !defined(CLZ_MIPS_H) */
diff --git a/fdk-aac/libFDK/include/mips/cplx_mul_mips.h b/fdk-aac/libFDK/include/mips/cplx_mul_mips.h
new file mode 100644
index 0000000..4ade3e5
--- /dev/null
+++ b/fdk-aac/libFDK/include/mips/cplx_mul_mips.h
@@ -0,0 +1,133 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(CPLX_MUL_MIPS_H)
+#define CPLX_MUL_MIPS_H
+
+#if defined(__GNUC__) && defined(__mips__)
+
+//#define FUNCTION_cplxMultDiv2_32x16
+//#define FUNCTION_cplxMultDiv2_32x16X2
+#define FUNCTION_cplxMultDiv2_32x32X2
+//#define FUNCTION_cplxMult_32x16
+//#define FUNCTION_cplxMult_32x16X2
+#define FUNCTION_cplxMult_32x32X2
+
+#if defined(FUNCTION_cplxMultDiv2_32x32X2)
+inline void cplxMultDiv2(FIXP_DBL *c_Re, FIXP_DBL *c_Im, FIXP_DBL a_Re,
+ FIXP_DBL a_Im, FIXP_DBL b_Re, FIXP_DBL b_Im) {
+ *c_Re = (((long long)a_Re * (long long)b_Re) - ((long long)a_Im * (long long)b_Im))>>32;
+ *c_Im = (((long long)a_Re * (long long)b_Im) + ((long long)a_Im * (long long)b_Re))>>32;
+}
+#endif
+
+#if defined(FUNCTION_cplxMult_32x32X2)
+inline void cplxMult(FIXP_DBL *c_Re, FIXP_DBL *c_Im, FIXP_DBL a_Re,
+ FIXP_DBL a_Im, FIXP_DBL b_Re, FIXP_DBL b_Im) {
+ *c_Re = ((((long long)a_Re * (long long)b_Re) - ((long long)a_Im * (long long)b_Im))>>32)<<1;
+ *c_Im = ((((long long)a_Re * (long long)b_Im) + ((long long)a_Im * (long long)b_Re))>>32)<<1;
+}
+#endif
+
+#endif /* defined(__GNUC__) && defined(__mips__) */
+
+#endif /* !defined(CPLX_MUL_MIPS_H) */
diff --git a/fdk-aac/libFDK/include/mips/fixmul_mips.h b/fdk-aac/libFDK/include/mips/fixmul_mips.h
new file mode 100644
index 0000000..06cf530
--- /dev/null
+++ b/fdk-aac/libFDK/include/mips/fixmul_mips.h
@@ -0,0 +1,130 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(FIXMUL_MIPS_H)
+#define FIXMUL_MIPS_H
+
+#if defined(__mips__)
+
+#if (__GNUC__) && defined(__mips__)
+/* MIPS GCC based compiler */
+
+#define FUNCTION_fixmuldiv2_DD
+
+#define FUNCTION_fixmuldiv2BitExact_DD
+#define fixmuldiv2BitExact_DD(a, b) fixmuldiv2_DD(a, b)
+
+inline INT fixmuldiv2_DD(const INT a, const INT b) {
+ INT result;
+
+ result = ((long long)a * b) >> 32;
+
+ return result;
+}
+
+#endif /* (__GNUC__) && defined(__mips__) */
+
+#endif /* __mips__ */
+
+#define FUNCTION_fixmulBitExact_DD
+#define fixmulBitExact_DD fixmul_DD
+#endif /* !defined(FIXMUL_MIPS_H) */
diff --git a/fdk-aac/libFDK/include/mips/scale_mips.h b/fdk-aac/libFDK/include/mips/scale_mips.h
new file mode 100644
index 0000000..3c141fc
--- /dev/null
+++ b/fdk-aac/libFDK/include/mips/scale_mips.h
@@ -0,0 +1,122 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef SCALE_MIPS_H
+#define SCALE_MIPS_H
+
+#if defined(__mips_dsp)
+
+/*!
+ *
+ * \brief Scale input value by 2^{scale} and saturate output to 2^{dBits-1}
+ * \return scaled and saturated value
+ *
+ * This macro scales src value right or left and applies saturation to
+ * (2^dBits)-1 maxima output.
+ */
+#define SATURATE_RIGHT_SHIFT(src, scale, dBits) \
+ (__builtin_mips_shll_s_w((src) >> (scale), (DFRACT_BITS - (dBits))) >> \
+ (DFRACT_BITS - (dBits)))
+
+#endif /*__mips_dsp */
+
+#endif /* SCALE_MIPS_H */
diff --git a/fdk-aac/libFDK/include/mips/scramble_mips.h b/fdk-aac/libFDK/include/mips/scramble_mips.h
new file mode 100644
index 0000000..08c2e6d
--- /dev/null
+++ b/fdk-aac/libFDK/include/mips/scramble_mips.h
@@ -0,0 +1,133 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef SCRAMBLE_MIPS_H
+#define SCRAMBLE_MIPS_H
+
+#define FUNCTION_scramble
+
+#if defined(FUNCTION_scramble)
+inline void scramble(FIXP_DBL *x, INT n) {
+ INT m, j;
+ int ldn = 1;
+ do {
+ ldn++;
+ } while ((1 << ldn) < n);
+
+ for (m = 1, j = 0; m < n - 1; m++) {
+ j = __builtin_mips_bitrev(m) >> (16 - ldn);
+
+ if (j > m) {
+ FIXP_DBL tmp;
+ tmp = x[2 * m];
+ x[2 * m] = x[2 * j];
+ x[2 * j] = tmp;
+
+ tmp = x[2 * m + 1];
+ x[2 * m + 1] = x[2 * j + 1];
+ x[2 * j + 1] = tmp;
+ }
+ }
+}
+#endif
+
+#endif /* SCRAMBLE_MIPS_H */
diff --git a/fdk-aac/libFDK/include/nlc_dec.h b/fdk-aac/libFDK/include/nlc_dec.h
new file mode 100644
index 0000000..cca97f1
--- /dev/null
+++ b/fdk-aac/libFDK/include/nlc_dec.h
@@ -0,0 +1,187 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Omer Osman
+
+ Description: SAC/SAOC Dec Noiseless Coding
+
+*******************************************************************************/
+
+#ifndef NLC_DEC_H
+#define NLC_DEC_H
+
+#include "FDK_bitstream.h"
+#include "huff_nodes.h"
+#include "common_fix.h"
+
+typedef enum {
+
+ SAC_DECODER,
+ SAOC_DECODER,
+ USAC_DECODER
+
+} DECODER_TYPE;
+
+typedef enum {
+ t_CLD,
+ t_ICC,
+ t_IPD,
+ t_OLD,
+ t_IOC,
+ t_NRG,
+ t_DCLD,
+ t_DMG,
+ t_PDG
+
+} DATA_TYPE;
+
+typedef enum {
+
+ BACKWARDS = 0x0,
+ FORWARDS = 0x1
+
+} DIRECTION;
+
+typedef enum {
+
+ DIFF_FREQ = 0x0,
+ DIFF_TIME = 0x1
+
+} DIFF_TYPE;
+
+typedef enum {
+
+ HUFF_1D = 0x0,
+ HUFF_2D = 0x1
+
+} CODING_SCHEME;
+
+typedef enum {
+
+ FREQ_PAIR = 0x0,
+ TIME_PAIR = 0x1
+
+} PAIRING;
+
+#ifndef HUFFDEC_PARAMS
+#define HUFFDEC_PARMS
+
+#define PAIR_SHIFT 4
+#define PAIR_MASK 0xf
+
+#define MAX_ENTRIES 168
+#define HANDLE_HUFF_NODE const SHORT(*)[MAX_ENTRIES][2]
+
+#endif /* HUFFDECPARAMS */
+
+#define HUFFDEC_OK 0
+#define HUFFDEC_NOTOK (-1)
+
+typedef int ERROR_t;
+
+ERROR_t EcDataPairDec(DECODER_TYPE DECODER, HANDLE_FDK_BITSTREAM strm,
+ SCHAR *aaOutData1, SCHAR *aaOutData2, SCHAR *aHistory,
+ DATA_TYPE data_type, int startBand, int dataBands,
+ int pair_flag, int coarse_flag,
+ int allowDiffTimeBack_flag);
+
+/* needed for GES- & STP-tool */
+ERROR_t huff_dec_reshape(HANDLE_FDK_BITSTREAM strm, int *out_data, int num_val);
+
+extern ERROR_t sym_restoreIPD(HANDLE_FDK_BITSTREAM strm, int lav,
+ SCHAR data[2]);
+
+#endif
diff --git a/fdk-aac/libFDK/include/ppc/clz_ppc.h b/fdk-aac/libFDK/include/ppc/clz_ppc.h
new file mode 100644
index 0000000..bfd23c6
--- /dev/null
+++ b/fdk-aac/libFDK/include/ppc/clz_ppc.h
@@ -0,0 +1,102 @@
+
+/* -----------------------------------------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+ All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
+the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
+This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
+audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
+independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
+of the MPEG specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
+may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
+individually for the purpose of encoding or decoding bit streams in products that are compliant with
+the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
+these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
+software may already be covered under those patent licenses when it is used for those licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
+are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
+applications information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification, are permitted without
+payment of copyright license fees provided that you satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
+your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation and/or other materials
+provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
+You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived from this library without
+prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
+software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
+and the date of any change. For modified versions of the FDK AAC Codec, the term
+"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
+"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
+ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
+respect to this software.
+
+You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
+by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
+"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
+of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
+including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
+or business interruption, however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of this software, even if
+advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------------------------------------- */
+
+/*************************** Fraunhofer IIS FDK Tools **********************
+
+ Author(s):
+ Description: fixed point intrinsics
+
+******************************************************************************/
+
+#if defined(__powerpc__) && (defined(__GNUC__) || defined(__xlC__))
+
+#define FUNCTION_fixnormz_D
+
+inline INT fixnormz_D(LONG value)
+{
+ INT result;
+ __asm__ ("cntlzw %0, %1" : "=r" (result) : "r" (value));
+ return result;
+}
+
+#endif /* __powerpc__ && (__GNUC__ || __xlC__) */
diff --git a/fdk-aac/libFDK/include/ppc/fixmul_ppc.h b/fdk-aac/libFDK/include/ppc/fixmul_ppc.h
new file mode 100644
index 0000000..9e2745c
--- /dev/null
+++ b/fdk-aac/libFDK/include/ppc/fixmul_ppc.h
@@ -0,0 +1,115 @@
+
+/* -----------------------------------------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+ All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
+the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
+This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
+audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
+independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
+of the MPEG specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
+may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
+individually for the purpose of encoding or decoding bit streams in products that are compliant with
+the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
+these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
+software may already be covered under those patent licenses when it is used for those licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
+are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
+applications information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification, are permitted without
+payment of copyright license fees provided that you satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
+your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation and/or other materials
+provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
+You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived from this library without
+prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
+software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
+and the date of any change. For modified versions of the FDK AAC Codec, the term
+"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
+"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
+ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
+respect to this software.
+
+You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
+by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
+"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
+of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
+including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
+or business interruption, however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of this software, even if
+advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------------------------------------- */
+
+/*************************** Fraunhofer IIS FDK Tools **********************
+
+ Author(s):
+ Description: fixed point intrinsics
+
+******************************************************************************/
+
+#if defined(__powerpc__) && (defined(__GNUC__) || defined(__xlC__))
+
+#define FUNCTION_fixmuldiv2_DD
+
+#define FUNCTION_fixmuldiv2BitExact_DD
+#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b)
+
+#define FUNCTION_fixmulBitExact_DD
+#define fixmulBitExact_DD(a,b) fixmul_DD(a,b)
+
+#define FUNCTION_fixmuldiv2BitExact_DS
+#define fixmuldiv2BitExact_DS(a,b) fixmuldiv2_DS(a,b)
+
+#define FUNCTION_fixmulBitExact_DS
+#define fixmulBitExact_DS(a,b) fixmul_DS(a,b)
+
+
+inline INT fixmuldiv2_DD (const INT a, const INT b)
+{
+ INT result;
+ __asm__ ("mulhw %0, %1, %2" : "=r" (result) : "r" (a), "r" (b));
+ return result;
+}
+
+#endif /* __powerpc__ && (__GNUC__ || __xlC__) */
diff --git a/fdk-aac/libFDK/include/qmf.h b/fdk-aac/libFDK/include/qmf.h
new file mode 100644
index 0000000..609c6f1
--- /dev/null
+++ b/fdk-aac/libFDK/include/qmf.h
@@ -0,0 +1,301 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file qmf.h
+ \brief Complex qmf analysis/synthesis
+ \author Markus Werner
+
+*/
+
+#ifndef QMF_H
+#define QMF_H
+
+#include "common_fix.h"
+#include "FDK_tools_rom.h"
+#include "dct.h"
+
+#define FIXP_QAS FIXP_PCM
+#define QAS_BITS SAMPLE_BITS
+
+#define FIXP_QSS FIXP_DBL
+#define QSS_BITS DFRACT_BITS
+
+/* Flags for QMF intialization */
+/* Low Power mode flag */
+#define QMF_FLAG_LP 1
+/* Filter is not symmetric. This flag is set internally in the QMF
+ * initialization as required. */
+/* DO NOT PASS THIS FLAG TO qmfInitAnalysisFilterBank or
+ * qmfInitSynthesisFilterBank */
+#define QMF_FLAG_NONSYMMETRIC 2
+/* Complex Low Delay Filter Bank (or std symmetric filter bank) */
+#define QMF_FLAG_CLDFB 4
+/* Flag indicating that the states should be kept. */
+#define QMF_FLAG_KEEP_STATES 8
+/* Complex Low Delay Filter Bank used in MPEG Surround Encoder */
+#define QMF_FLAG_MPSLDFB 16
+/* Complex Low Delay Filter Bank used in MPEG Surround Encoder allows a
+ * optimized calculation of the modulation in qmfForwardModulationHQ() */
+#define QMF_FLAG_MPSLDFB_OPTIMIZE_MODULATION 32
+/* Flag to indicate HE-AAC down-sampled SBR mode (decoder) -> adapt analysis
+ * post twiddling */
+#define QMF_FLAG_DOWNSAMPLED 64
+
+#define QMF_MAX_SYNTHESIS_BANDS (64)
+
+/*!
+ * \brief Algorithmic scaling in sbrForwardModulation()
+ *
+ * The scaling in sbrForwardModulation() is caused by:
+ *
+ * \li 1 R_SHIFT in sbrForwardModulation()
+ * \li 5/6 R_SHIFT in dct3() if using 32/64 Bands
+ * \li 1 omitted gain of 2.0 in qmfForwardModulation()
+ */
+#define ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK 7
+
+/*!
+ * \brief Algorithmic scaling in cplxSynthesisQmfFiltering()
+ *
+ * The scaling in cplxSynthesisQmfFiltering() is caused by:
+ *
+ * \li 5/6 R_SHIFT in dct2() if using 32/64 Bands
+ * \li 1 omitted gain of 2.0 in qmfInverseModulation()
+ * \li -6 division by 64 in synthesis filterbank
+ * \li x bits external influence
+ */
+#define ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK 1
+
+typedef struct {
+ int lb_scale; /*!< Scale of low band area */
+ int ov_lb_scale; /*!< Scale of adjusted overlap low band area */
+ int hb_scale; /*!< Scale of high band area */
+ int ov_hb_scale; /*!< Scale of adjusted overlap high band area */
+} QMF_SCALE_FACTOR;
+
+struct QMF_FILTER_BANK {
+ const FIXP_PFT *p_filter; /*!< Pointer to filter coefficients */
+
+ void *FilterStates; /*!< Pointer to buffer of filter states
+ FIXP_PCM in analyse and
+ FIXP_DBL in synthesis filter */
+ int FilterSize; /*!< Size of prototype filter. */
+ const FIXP_QTW *t_cos; /*!< Modulation tables. */
+ const FIXP_QTW *t_sin;
+ int filterScale; /*!< filter scale */
+
+ int no_channels; /*!< Total number of channels (subbands) */
+ int no_col; /*!< Number of time slots */
+ int lsb; /*!< Top of low subbands */
+ int usb; /*!< Top of high subbands */
+
+ int synScalefactor; /*!< Scale factor of synthesis qmf (syn only) */
+ int outScalefactor; /*!< Scale factor of output data (syn only) */
+ FIXP_DBL outGain_m; /*!< Mantissa of gain output data (syn only) (init with
+ 0x80000000 to ignore) */
+ int outGain_e; /*!< Exponent of gain output data (syn only) */
+
+ UINT flags; /*!< flags */
+ UCHAR p_stride; /*!< Stride Factor of polyphase filters */
+};
+
+typedef struct QMF_FILTER_BANK *HANDLE_QMF_FILTER_BANK;
+
+void qmfAnalysisFiltering(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
+ FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
+ FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
+ QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
+ const LONG *timeIn, /*!< Time signal */
+ const int timeIn_e, /*!< Exponent of audio data */
+ const int stride, /*!< Stride factor of audio data */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
+);
+
+void qmfAnalysisFiltering(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
+ FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
+ FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
+ QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
+ const INT_PCM *timeIn, /*!< Time signal */
+ const int timeIn_e, /*!< Exponent of audio data */
+ const int stride, /*!< Stride factor of audio data */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
+);
+
+void qmfSynthesisFiltering(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
+ FIXP_DBL **QmfBufferReal, /*!< Pointer to real subband slots */
+ FIXP_DBL **QmfBufferImag, /*!< Pointer to imag subband slots */
+ const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */
+ const int ov_len, /*!< Length of band overlap */
+ INT_PCM *timeOut, /*!< Time signal */
+ const INT stride, /*!< Stride factor of audio data */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer. It must be
+ aligned */
+);
+
+int qmfInitAnalysisFilterBank(
+ HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
+ FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */
+ int noCols, /*!< Number of time slots */
+ int lsb, /*!< Number of lower bands */
+ int usb, /*!< Number of upper bands */
+ int no_channels, /*!< Number of critically sampled bands */
+ int flags); /*!< Flags */
+
+void qmfAnalysisFilteringSlot(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
+ FIXP_DBL *qmfReal, /*!< Low and High band, real */
+ FIXP_DBL *qmfImag, /*!< Low and High band, imag */
+ const LONG *timeIn, /*!< Pointer to input */
+ const int stride, /*!< stride factor of input */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */
+);
+
+void qmfAnalysisFilteringSlot(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
+ FIXP_DBL *qmfReal, /*!< Low and High band, real */
+ FIXP_DBL *qmfImag, /*!< Low and High band, imag */
+ const INT_PCM *timeIn, /*!< Pointer to input */
+ const int stride, /*!< stride factor of input */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
+);
+int qmfInitSynthesisFilterBank(
+ HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */
+ FIXP_QSS *pFilterStates, /*!< Pointer to filter state buffer */
+ int noCols, /*!< Number of time slots */
+ int lsb, /*!< Number of lower bands */
+ int usb, /*!< Number of upper bands */
+ int no_channels, /*!< Number of critically sampled bands */
+ int flags); /*!< Flags */
+
+void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
+ const FIXP_DBL *realSlot,
+ const FIXP_DBL *imagSlot,
+ const int scaleFactorLowBand,
+ const int scaleFactorHighBand, INT_PCM *timeOut,
+ const int timeOut_e, FIXP_DBL *pWorkBuffer);
+
+void qmfChangeOutScalefactor(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
+ int outScalefactor /*!< New scaling factor for output data */
+);
+
+int qmfGetOutScalefactor(
+ HANDLE_QMF_FILTER_BANK synQmf /*!< Handle of Qmf Synthesis Bank */
+);
+
+void qmfChangeOutGain(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
+ FIXP_DBL outputGain, /*!< New gain for output data (mantissa) */
+ int outputGainScale /*!< New gain for output data (exponent) */
+);
+void qmfSynPrototypeFirSlot(
+ HANDLE_QMF_FILTER_BANK qmf,
+ FIXP_DBL *RESTRICT realSlot, /*!< Input: Pointer to real Slot */
+ FIXP_DBL *RESTRICT imagSlot, /*!< Input: Pointer to imag Slot */
+ INT_PCM *RESTRICT timeOut, /*!< Time domain data */
+ const int timeOut_e);
+
+#endif /*ifndef QMF_H */
diff --git a/fdk-aac/libFDK/include/qmf_pcm.h b/fdk-aac/libFDK/include/qmf_pcm.h
new file mode 100644
index 0000000..f24e0cd
--- /dev/null
+++ b/fdk-aac/libFDK/include/qmf_pcm.h
@@ -0,0 +1,405 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Markus Lohwasser, Josef Hoepfl, Manuel Jander
+
+ Description: QMF filterbank
+
+*******************************************************************************/
+
+#ifndef QMF_PCM_H
+#define QMF_PCM_H
+
+/*
+ All Synthesis functions dependent on datatype INT_PCM_QMFOUT
+ Should only be included by qmf.cpp, but not compiled separately, please
+ exclude compilation from project, if done otherwise. Is optional included
+ twice to duplicate all functions with two different pre-definitions, as:
+ #define INT_PCM_QMFOUT LONG
+ and ...
+ #define INT_PCM_QMFOUT SHORT
+ needed to run QMF synthesis in both 16bit and 32bit sample output format.
+*/
+
+#define QSSCALE (0)
+#define FX_DBL2FX_QSS(x) (x)
+#define FX_QSS2FX_DBL(x) (x)
+
+/*!
+ \brief Perform Synthesis Prototype Filtering on a single slot of input data.
+
+ The filter takes 2 * qmf->no_channels of input data and
+ generates qmf->no_channels time domain output samples.
+*/
+/* static */
+#ifndef FUNCTION_qmfSynPrototypeFirSlot
+void qmfSynPrototypeFirSlot(
+#else
+void qmfSynPrototypeFirSlot_fallback(
+#endif
+ HANDLE_QMF_FILTER_BANK qmf,
+ FIXP_DBL *RESTRICT realSlot, /*!< Input: Pointer to real Slot */
+ FIXP_DBL *RESTRICT imagSlot, /*!< Input: Pointer to imag Slot */
+ INT_PCM_QMFOUT *RESTRICT timeOut, /*!< Time domain data */
+ int stride) {
+ FIXP_QSS *FilterStates = (FIXP_QSS *)qmf->FilterStates;
+ int no_channels = qmf->no_channels;
+ const FIXP_PFT *p_Filter = qmf->p_filter;
+ int p_stride = qmf->p_stride;
+ int j;
+ FIXP_QSS *RESTRICT sta = FilterStates;
+ const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm;
+ int scale = (DFRACT_BITS - SAMPLE_BITS_QMFOUT) - 1 - qmf->outScalefactor -
+ qmf->outGain_e;
+
+ p_flt =
+ p_Filter + p_stride * QMF_NO_POLY; /* 5th of 330 */
+ p_fltm = p_Filter + (qmf->FilterSize / 2) -
+ p_stride * QMF_NO_POLY; /* 5 + (320 - 2*5) = 315th of 330 */
+
+ FIXP_SGL gain = FX_DBL2FX_SGL(qmf->outGain_m);
+
+ FIXP_DBL rnd_val = 0;
+
+ if (scale > 0) {
+ if (scale < (DFRACT_BITS - 1))
+ rnd_val = FIXP_DBL(1 << (scale - 1));
+ else
+ scale = (DFRACT_BITS - 1);
+ } else {
+ scale = fMax(scale, -(DFRACT_BITS - 1));
+ }
+
+ for (j = no_channels - 1; j >= 0; j--) {
+ FIXP_DBL imag = imagSlot[j]; /* no_channels-1 .. 0 */
+ FIXP_DBL real = realSlot[j]; /* no_channels-1 .. 0 */
+ {
+ INT_PCM_QMFOUT tmp;
+ FIXP_DBL Are = fMultAddDiv2(FX_QSS2FX_DBL(sta[0]), p_fltm[0], real);
+
+ /* This PCM formatting performs:
+ - multiplication with 16-bit gain, if not -1.0f
+ - rounding, if shift right is applied
+ - apply shift left (or right) with saturation to 32 (or 16) bits
+ - store output with --stride in 32 (or 16) bit format
+ */
+ if (gain != (FIXP_SGL)(-32768)) /* -1.0f */
+ {
+ Are = fMult(Are, gain);
+ }
+ if (scale >= 0) {
+ FDK_ASSERT(
+ Are <=
+ (Are + rnd_val)); /* Round-addition must not overflow, might be
+ equal for rnd_val=0 */
+ tmp = (INT_PCM_QMFOUT)(
+ SATURATE_RIGHT_SHIFT(Are + rnd_val, scale, SAMPLE_BITS_QMFOUT));
+ } else {
+ tmp = (INT_PCM_QMFOUT)(
+ SATURATE_LEFT_SHIFT(Are, -scale, SAMPLE_BITS_QMFOUT));
+ }
+
+ { timeOut[(j)*stride] = tmp; }
+ }
+
+ sta[0] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[1]), p_flt[4], imag));
+ sta[1] =
+ FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[2]), p_fltm[1], real));
+ sta[2] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[3]), p_flt[3], imag));
+ sta[3] =
+ FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[4]), p_fltm[2], real));
+ sta[4] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[5]), p_flt[2], imag));
+ sta[5] =
+ FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[6]), p_fltm[3], real));
+ sta[6] = FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[7]), p_flt[1], imag));
+ sta[7] =
+ FX_DBL2FX_QSS(fMultAddDiv2(FX_QSS2FX_DBL(sta[8]), p_fltm[4], real));
+ sta[8] = FX_DBL2FX_QSS(fMultDiv2(p_flt[0], imag));
+ p_flt += (p_stride * QMF_NO_POLY);
+ p_fltm -= (p_stride * QMF_NO_POLY);
+ sta += 9; // = (2*QMF_NO_POLY-1);
+ }
+}
+
+#ifndef FUNCTION_qmfSynPrototypeFirSlot_NonSymmetric
+/*!
+ \brief Perform Synthesis Prototype Filtering on a single slot of input data.
+
+ The filter takes 2 * qmf->no_channels of input data and
+ generates qmf->no_channels time domain output samples.
+*/
+static void qmfSynPrototypeFirSlot_NonSymmetric(
+ HANDLE_QMF_FILTER_BANK qmf,
+ FIXP_DBL *RESTRICT realSlot, /*!< Input: Pointer to real Slot */
+ FIXP_DBL *RESTRICT imagSlot, /*!< Input: Pointer to imag Slot */
+ INT_PCM_QMFOUT *RESTRICT timeOut, /*!< Time domain data */
+ int stride) {
+ FIXP_QSS *FilterStates = (FIXP_QSS *)qmf->FilterStates;
+ int no_channels = qmf->no_channels;
+ const FIXP_PFT *p_Filter = qmf->p_filter;
+ int p_stride = qmf->p_stride;
+ int j;
+ FIXP_QSS *RESTRICT sta = FilterStates;
+ const FIXP_PFT *RESTRICT p_flt, *RESTRICT p_fltm;
+ int scale = (DFRACT_BITS - SAMPLE_BITS_QMFOUT) - 1 - qmf->outScalefactor -
+ qmf->outGain_e;
+
+ p_flt = p_Filter; /*!< Pointer to first half of filter coefficients */
+ p_fltm =
+ &p_flt[qmf->FilterSize / 2]; /* at index 320, overall 640 coefficients */
+
+ FIXP_SGL gain = FX_DBL2FX_SGL(qmf->outGain_m);
+
+ FIXP_DBL rnd_val = (FIXP_DBL)0;
+
+ if (scale > 0) {
+ if (scale < (DFRACT_BITS - 1))
+ rnd_val = FIXP_DBL(1 << (scale - 1));
+ else
+ scale = (DFRACT_BITS - 1);
+ } else {
+ scale = fMax(scale, -(DFRACT_BITS - 1));
+ }
+
+ for (j = no_channels - 1; j >= 0; j--) {
+ FIXP_DBL imag = imagSlot[j]; /* no_channels-1 .. 0 */
+ FIXP_DBL real = realSlot[j]; /* no_channels-1 .. 0 */
+ {
+ INT_PCM_QMFOUT tmp;
+ FIXP_DBL Are = sta[0] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[4], real));
+
+ /* This PCM formatting performs:
+ - multiplication with 16-bit gain, if not -1.0f
+ - rounding, if shift right is applied
+ - apply shift left (or right) with saturation to 32 (or 16) bits
+ - store output with --stride in 32 (or 16) bit format
+ */
+ if (gain != (FIXP_SGL)(-32768)) /* -1.0f */
+ {
+ Are = fMult(Are, gain);
+ }
+ if (scale > 0) {
+ FDK_ASSERT(Are <
+ (Are + rnd_val)); /* Round-addition must not overflow */
+ tmp = (INT_PCM_QMFOUT)(
+ SATURATE_RIGHT_SHIFT(Are + rnd_val, scale, SAMPLE_BITS_QMFOUT));
+ } else {
+ tmp = (INT_PCM_QMFOUT)(
+ SATURATE_LEFT_SHIFT(Are, -scale, SAMPLE_BITS_QMFOUT));
+ }
+ timeOut[j * stride] = tmp;
+ }
+
+ sta[0] = sta[1] + FX_DBL2FX_QSS(fMultDiv2(p_flt[4], imag));
+ sta[1] = sta[2] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[3], real));
+ sta[2] = sta[3] + FX_DBL2FX_QSS(fMultDiv2(p_flt[3], imag));
+
+ sta[3] = sta[4] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[2], real));
+ sta[4] = sta[5] + FX_DBL2FX_QSS(fMultDiv2(p_flt[2], imag));
+ sta[5] = sta[6] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[1], real));
+ sta[6] = sta[7] + FX_DBL2FX_QSS(fMultDiv2(p_flt[1], imag));
+
+ sta[7] = sta[8] + FX_DBL2FX_QSS(fMultDiv2(p_fltm[0], real));
+ sta[8] = FX_DBL2FX_QSS(fMultDiv2(p_flt[0], imag));
+
+ p_flt += (p_stride * QMF_NO_POLY);
+ p_fltm += (p_stride * QMF_NO_POLY);
+ sta += 9; // = (2*QMF_NO_POLY-1);
+ }
+}
+#endif /* FUNCTION_qmfSynPrototypeFirSlot_NonSymmetric */
+
+void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf,
+ const FIXP_DBL *realSlot,
+ const FIXP_DBL *imagSlot,
+ const int scaleFactorLowBand,
+ const int scaleFactorHighBand,
+ INT_PCM_QMFOUT *timeOut, const int stride,
+ FIXP_DBL *pWorkBuffer) {
+ if (!(synQmf->flags & QMF_FLAG_LP))
+ qmfInverseModulationHQ(synQmf, realSlot, imagSlot, scaleFactorLowBand,
+ scaleFactorHighBand, pWorkBuffer);
+ else {
+ if (synQmf->flags & QMF_FLAG_CLDFB) {
+ qmfInverseModulationLP_odd(synQmf, realSlot, scaleFactorLowBand,
+ scaleFactorHighBand, pWorkBuffer);
+ } else {
+ qmfInverseModulationLP_even(synQmf, realSlot, scaleFactorLowBand,
+ scaleFactorHighBand, pWorkBuffer);
+ }
+ }
+
+ if (synQmf->flags & QMF_FLAG_NONSYMMETRIC) {
+ qmfSynPrototypeFirSlot_NonSymmetric(synQmf, pWorkBuffer,
+ pWorkBuffer + synQmf->no_channels,
+ timeOut, stride);
+ } else {
+ qmfSynPrototypeFirSlot(synQmf, pWorkBuffer,
+ pWorkBuffer + synQmf->no_channels, timeOut, stride);
+ }
+}
+
+/*!
+ *
+ * \brief Perform complex-valued subband synthesis of the
+ * low band and the high band and store the
+ * time domain data in timeOut
+ *
+ * First step: Calculate the proper scaling factor of current
+ * spectral data in qmfReal/qmfImag, old spectral data in the overlap
+ * range and filter states.
+ *
+ * Second step: Perform Frequency-to-Time mapping with inverse
+ * Modulation slot-wise.
+ *
+ * Third step: Perform FIR-filter slot-wise. To save space for filter
+ * states, the MAC operations are executed directly on the filter states
+ * instead of accumulating several products in the accumulator. The
+ * buffer shift at the end of the function should be replaced by a
+ * modulo operation, which is available on some DSPs.
+ *
+ * Last step: Copy the upper part of the spectral data to the overlap buffer.
+ *
+ * The qmf coefficient table is symmetric. The symmetry is exploited by
+ * shrinking the coefficient table to half the size. The addressing mode
+ * takes care of the symmetries. If the #define #QMFTABLE_FULL is set,
+ * coefficient addressing works on the full table size. The code will be
+ * slightly faster and slightly more compact.
+ *
+ * Workbuffer requirement: 2 x sizeof(**QmfBufferReal) * synQmf->no_channels
+ * The workbuffer must be aligned
+ */
+void qmfSynthesisFiltering(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
+ FIXP_DBL **QmfBufferReal, /*!< Low and High band, real */
+ FIXP_DBL **QmfBufferImag, /*!< Low and High band, imag */
+ const QMF_SCALE_FACTOR *scaleFactor,
+ const INT ov_len, /*!< split Slot of overlap and actual slots */
+ INT_PCM_QMFOUT *timeOut, /*!< Pointer to output */
+ const INT stride, /*!< stride factor of output */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
+) {
+ int i;
+ int L = synQmf->no_channels;
+ int scaleFactorHighBand;
+ int scaleFactorLowBand_ov, scaleFactorLowBand_no_ov;
+
+ FDK_ASSERT(synQmf->no_channels >= synQmf->lsb);
+ FDK_ASSERT(synQmf->no_channels >= synQmf->usb);
+
+ /* adapt scaling */
+ scaleFactorHighBand = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK -
+ scaleFactor->hb_scale - synQmf->filterScale;
+ scaleFactorLowBand_ov = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK -
+ scaleFactor->ov_lb_scale - synQmf->filterScale;
+ scaleFactorLowBand_no_ov = -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK -
+ scaleFactor->lb_scale - synQmf->filterScale;
+
+ for (i = 0; i < synQmf->no_col; i++) /* ----- no_col loop ----- */
+ {
+ const FIXP_DBL *QmfBufferImagSlot = NULL;
+
+ int scaleFactorLowBand =
+ (i < ov_len) ? scaleFactorLowBand_ov : scaleFactorLowBand_no_ov;
+
+ if (!(synQmf->flags & QMF_FLAG_LP)) QmfBufferImagSlot = QmfBufferImag[i];
+
+ qmfSynthesisFilteringSlot(synQmf, QmfBufferReal[i], QmfBufferImagSlot,
+ scaleFactorLowBand, scaleFactorHighBand,
+ timeOut + (i * L * stride), stride, pWorkBuffer);
+ } /* no_col loop i */
+}
+#endif /* QMF_PCM_H */
diff --git a/fdk-aac/libFDK/include/scale.h b/fdk-aac/libFDK/include/scale.h
new file mode 100644
index 0000000..30fa089
--- /dev/null
+++ b/fdk-aac/libFDK/include/scale.h
@@ -0,0 +1,298 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: Scaling operations
+
+*******************************************************************************/
+
+#ifndef SCALE_H
+#define SCALE_H
+
+#include "common_fix.h"
+#include "genericStds.h"
+#include "fixminmax.h"
+
+#define SCALE_INLINE
+
+#if defined(__arm__)
+#include "arm/scale_arm.h"
+
+#elif defined(__mips__)
+#include "mips/scale_mips.h"
+
+#endif
+
+void scaleValues(FIXP_SGL *vector, INT len, INT scalefactor);
+void scaleValues(FIXP_DBL *vector, INT len, INT scalefactor);
+void scaleValues(FIXP_DBL *dst, const FIXP_DBL *src, INT len, INT scalefactor);
+#if (SAMPLE_BITS == 16)
+void scaleValues(FIXP_PCM *dst, const FIXP_DBL *src, INT len, INT scalefactor);
+#endif
+void scaleValues(FIXP_PCM *dst, const FIXP_SGL *src, INT len, INT scalefactor);
+void scaleCplxValues(FIXP_DBL *r_dst, FIXP_DBL *i_dst, const FIXP_DBL *r_src,
+ const FIXP_DBL *i_src, INT len, INT scalefactor);
+void scaleValuesWithFactor(FIXP_DBL *vector, FIXP_DBL factor, INT len,
+ INT scalefactor);
+void scaleValuesSaturate(FIXP_DBL *vector, INT len, INT scalefactor);
+void scaleValuesSaturate(FIXP_DBL *dst, FIXP_DBL *src, INT len,
+ INT scalefactor);
+void scaleValuesSaturate(FIXP_SGL *dst, FIXP_DBL *src, INT len,
+ INT scalefactor);
+void scaleValuesSaturate(INT_PCM *dst, FIXP_DBL *src, INT len, INT scalefactor);
+void scaleValuesSaturate(FIXP_SGL *vector, INT len, INT scalefactor);
+void scaleValuesSaturate(FIXP_SGL *dst, FIXP_SGL *src, INT len,
+ INT scalefactor);
+void scaleValuesSaturate(INT_PCM *dst, INT_PCM *src, INT len, INT scalefactor);
+INT getScalefactorShort(const SHORT *vector, INT len);
+INT getScalefactorPCM(const INT_PCM *vector, INT len, INT stride);
+INT getScalefactor(const FIXP_DBL *vector, INT len);
+INT getScalefactor(const FIXP_SGL *vector, INT len);
+
+#ifndef FUNCTION_scaleValue
+/*!
+ *
+ * \brief Multiply input by \f$ 2^{scalefactor} \f$
+ *
+ * \return Scaled input
+ *
+ */
+#define FUNCTION_scaleValue
+inline FIXP_DBL scaleValue(const FIXP_DBL value, /*!< Value */
+ INT scalefactor /*!< Scalefactor */
+) {
+ if (scalefactor > 0)
+ return (value << scalefactor);
+ else
+ return (value >> (-scalefactor));
+}
+inline FIXP_SGL scaleValue(const FIXP_SGL value, /*!< Value */
+ INT scalefactor /*!< Scalefactor */
+) {
+ if (scalefactor > 0)
+ return (value << scalefactor);
+ else
+ return (value >> (-scalefactor));
+}
+#endif
+
+#ifndef FUNCTION_scaleValueSaturate
+/*!
+ *
+ * \brief Multiply input by \f$ 2^{scalefactor} \f$
+ * \param value The value to be scaled.
+ * \param the shift amount
+ * \return \f$ value * 2^scalefactor \f$
+ *
+ */
+#define FUNCTION_scaleValueSaturate
+inline FIXP_DBL scaleValueSaturate(const FIXP_DBL value,
+ INT scalefactor /* in range -31 ... +31 */
+) {
+ int headroom = fixnormz_D(
+ (INT)value ^ (INT)((value >> 31))); /* headroom in range 1...32 */
+ if (scalefactor >= 0) {
+ /* shift left: saturate in case of headroom less/equal scalefactor */
+ if (headroom <= scalefactor) {
+ if (value > (FIXP_DBL)0)
+ return (FIXP_DBL)MAXVAL_DBL; /* 0x7FFF.FFFF */
+ else
+ return (FIXP_DBL)MINVAL_DBL + (FIXP_DBL)1; /* 0x8000.0001 */
+ } else {
+ return fMax((value << scalefactor), (FIXP_DBL)MINVAL_DBL + (FIXP_DBL)1);
+ }
+ } else {
+ scalefactor = -scalefactor;
+ /* shift right: clear in case of 32-headroom greater/equal -scalefactor */
+ if ((DFRACT_BITS - headroom) <= scalefactor) {
+ return (FIXP_DBL)0;
+ } else {
+ return fMax((value >> scalefactor), (FIXP_DBL)MINVAL_DBL + (FIXP_DBL)1);
+ }
+ }
+}
+#endif
+
+#ifndef FUNCTION_scaleValueInPlace
+/*!
+ *
+ * \brief Multiply input by \f$ 2^{scalefactor} \f$ in place
+ *
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValueInPlace
+inline void scaleValueInPlace(FIXP_DBL *value, /*!< Value */
+ INT scalefactor /*!< Scalefactor */
+) {
+ INT newscale;
+ /* Note: The assignment inside the if conditional allows combining a load with
+ * the compare to zero (on ARM and maybe others) */
+ if ((newscale = (scalefactor)) >= 0) {
+ *(value) <<= newscale;
+ } else {
+ *(value) >>= -newscale;
+ }
+}
+#endif
+
+ /*!
+ *
+ * \brief Scale input value by 2^{scale} and saturate output to 2^{dBits-1}
+ * \return scaled and saturated value
+ *
+ * This macro scales src value right or left and applies saturation to
+ * (2^dBits)-1 maxima output.
+ */
+
+#ifndef SATURATE_RIGHT_SHIFT
+#define SATURATE_RIGHT_SHIFT(src, scale, dBits) \
+ ((((LONG)(src) >> (scale)) > (LONG)(((1U) << ((dBits)-1)) - 1)) \
+ ? (LONG)(((1U) << ((dBits)-1)) - 1) \
+ : (((LONG)(src) >> (scale)) < ~((LONG)(((1U) << ((dBits)-1)) - 1))) \
+ ? ~((LONG)(((1U) << ((dBits)-1)) - 1)) \
+ : ((LONG)(src) >> (scale)))
+#endif
+
+#ifndef SATURATE_LEFT_SHIFT
+#define SATURATE_LEFT_SHIFT(src, scale, dBits) \
+ (((LONG)(src) > ((LONG)(((1U) << ((dBits)-1)) - 1) >> (scale))) \
+ ? (LONG)(((1U) << ((dBits)-1)) - 1) \
+ : ((LONG)(src) < ~((LONG)(((1U) << ((dBits)-1)) - 1) >> (scale))) \
+ ? ~((LONG)(((1U) << ((dBits)-1)) - 1)) \
+ : ((LONG)(src) << (scale)))
+#endif
+
+#ifndef SATURATE_SHIFT
+#define SATURATE_SHIFT(src, scale, dBits) \
+ (((scale) < 0) ? SATURATE_LEFT_SHIFT((src), -(scale), (dBits)) \
+ : SATURATE_RIGHT_SHIFT((src), (scale), (dBits)))
+#endif
+
+/*
+ * Alternative shift and saturate left, saturates to -0.99999 instead of -1.0000
+ * to avoid problems when inverting the sign of the result.
+ */
+#ifndef SATURATE_LEFT_SHIFT_ALT
+#define SATURATE_LEFT_SHIFT_ALT(src, scale, dBits) \
+ (((LONG)(src) > ((LONG)(((1U) << ((dBits)-1)) - 1) >> (scale))) \
+ ? (LONG)(((1U) << ((dBits)-1)) - 1) \
+ : ((LONG)(src) <= ~((LONG)(((1U) << ((dBits)-1)) - 1) >> (scale))) \
+ ? ~((LONG)(((1U) << ((dBits)-1)) - 2)) \
+ : ((LONG)(src) << (scale)))
+#endif
+
+#ifndef SATURATE_RIGHT_SHIFT_ALT
+#define SATURATE_RIGHT_SHIFT_ALT(src, scale, dBits) \
+ ((((LONG)(src) >> (scale)) > (LONG)(((1U) << ((dBits)-1)) - 1)) \
+ ? (LONG)(((1U) << ((dBits)-1)) - 1) \
+ : (((LONG)(src) >> (scale)) < ~((LONG)(((1U) << ((dBits)-1)) - 2))) \
+ ? ~((LONG)(((1U) << ((dBits)-1)) - 2)) \
+ : ((LONG)(src) >> (scale)))
+#endif
+
+#ifndef SATURATE_INT_PCM_RIGHT_SHIFT
+#define SATURATE_INT_PCM_RIGHT_SHIFT(src, scale) \
+ SATURATE_RIGHT_SHIFT(src, scale, SAMPLE_BITS)
+#endif
+
+#ifndef SATURATE_INT_PCM_LEFT_SHIFT
+#define SATURATE_INT_PCM_LEFT_SHIFT(src, scale) \
+ SATURATE_LEFT_SHIFT(src, scale, SAMPLE_BITS)
+#endif
+
+#endif /* #ifndef SCALE_H */
diff --git a/fdk-aac/libFDK/include/scramble.h b/fdk-aac/libFDK/include/scramble.h
new file mode 100644
index 0000000..f07ebed
--- /dev/null
+++ b/fdk-aac/libFDK/include/scramble.h
@@ -0,0 +1,153 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef SCRAMBLE_H
+#define SCRAMBLE_H
+
+#include "common_fix.h"
+
+#if defined(__arm__)
+#include "arm/scramble_arm.h"
+
+#elif defined(__mips__) && defined(__mips_dsp)
+#include "mips/scramble_mips.h"
+
+#endif
+
+/*****************************************************************************
+
+ functionname: scramble
+ description: bitreversal of input data
+ returns:
+ input:
+ output:
+
+*****************************************************************************/
+#if !defined(FUNCTION_scramble)
+
+/* default scramble functionality */
+inline void scramble(FIXP_DBL *x, INT length) {
+ INT m, k, j;
+ FDK_ASSERT(!(((INT)(INT64)x) & (ALIGNMENT_DEFAULT - 1)));
+ C_ALLOC_ALIGNED_CHECK(x);
+
+ for (m = 1, j = 0; m < length - 1; m++) {
+ {
+ for (k = length >> 1; (!((j ^= k) & k)); k >>= 1)
+ ;
+ }
+
+ if (j > m) {
+ FIXP_DBL tmp;
+ tmp = x[2 * m];
+ x[2 * m] = x[2 * j];
+ x[2 * j] = tmp;
+
+ tmp = x[2 * m + 1];
+ x[2 * m + 1] = x[2 * j + 1];
+ x[2 * j + 1] = tmp;
+ }
+ }
+}
+#endif /* !defined(FUNCTION_scramble) */
+
+#endif /* SCRAMBLE_H */
diff --git a/fdk-aac/libFDK/include/x86/abs_x86.h b/fdk-aac/libFDK/include/x86/abs_x86.h
new file mode 100644
index 0000000..efd6433
--- /dev/null
+++ b/fdk-aac/libFDK/include/x86/abs_x86.h
@@ -0,0 +1,123 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(ABS_X86_H)
+#define ABS_X86_H
+
+#if defined(__x86__)
+
+#if defined(__x86_64__)
+
+inline INT fixabs_D(INT x) { return ((x) > (INT)(0)) ? (x) : -(x); }
+inline INT fixabs_S(INT x) { return ((x) > (INT)(0)) ? (x) : -(x); }
+
+#define fixabs_I(x) fixabs_D(x)
+
+#define FUNCTION_fixabs_S
+#define FUNCTION_fixabs_D
+#define FUNCTION_fixabs_I
+
+#endif /* __x86_64__ */
+
+#endif /*__x86__ */
+
+#endif /* !defined(ABS_X86_H) */
diff --git a/fdk-aac/libFDK/include/x86/clz_x86.h b/fdk-aac/libFDK/include/x86/clz_x86.h
new file mode 100644
index 0000000..badca29
--- /dev/null
+++ b/fdk-aac/libFDK/include/x86/clz_x86.h
@@ -0,0 +1,165 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Manuel Jander
+
+ Description: x86 version of count leading zero / bits
+
+*******************************************************************************/
+
+#if !defined(CLZ_X86_H)
+#define CLZ_X86_H
+
+#if defined(__GNUC__) && (defined(__x86__) || defined(__x86_64__))
+
+#define FUNCTION_fixnormz_D
+#define FUNCTION_fixnorm_D
+
+inline INT fixnormz_D(LONG value) {
+ INT result;
+
+ if (value != 0) {
+ result = __builtin_clz(value);
+ } else {
+ result = 32;
+ }
+ 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;
+}
+
+#elif (_MSC_VER > 1200) && (defined(_M_IX86) || defined(_M_X64))
+
+#include <intrin.h>
+
+#define FUNCTION_fixnormz_D
+#define FUNCTION_fixnorm_D
+
+inline INT fixnormz_D(LONG value) {
+ unsigned long result = 0;
+ unsigned char err;
+ err = _BitScanReverse(&result, value);
+ if (err) {
+ return 31 - result;
+ } else {
+ return 32;
+ }
+}
+
+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 /* toolchain */
+#endif /* !defined(CLZ_X86_H) */
diff --git a/fdk-aac/libFDK/include/x86/fixmul_x86.h b/fdk-aac/libFDK/include/x86/fixmul_x86.h
new file mode 100644
index 0000000..84e6316
--- /dev/null
+++ b/fdk-aac/libFDK/include/x86/fixmul_x86.h
@@ -0,0 +1,187 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: fixed point intrinsics
+
+*******************************************************************************/
+
+#if !defined(FIXMUL_X86_H)
+#define FIXMUL_X86_H
+
+#if defined(__x86__)
+
+#if defined(_MSC_VER) && defined(_M_IX86)
+/* Intel x86 */
+
+#define FUNCTION_fixmul_DD
+#define FUNCTION_fixmuldiv2_DD
+#define FUNCTION_fixmuldiv2BitExact_DD
+#define fixmuldiv2BitExact_DD(a, b) fixmuldiv2_DD(a, b)
+#define FUNCTION_fixmulBitExact_DD
+#define fixmulBitExact_DD(a, b) fixmul_DD(a, b)
+
+#define FUNCTION_fixmuldiv2BitExact_DS
+#define fixmuldiv2BitExact_DS(a, b) fixmuldiv2_DS(a, b)
+
+#define FUNCTION_fixmulBitExact_DS
+#define fixmulBitExact_DS(a, b) fixmul_DS(a, b)
+
+inline INT fixmul_DD(INT a, const INT b) {
+ __asm
+ {
+ mov eax, a
+ imul b
+ shl edx, 1
+ mov a, edx
+ }
+ return a;
+}
+
+inline INT fixmuldiv2_DD(INT a, const INT b) {
+ __asm
+ {
+ mov eax, a
+ imul b
+ mov a, edx
+ }
+ return a;
+}
+
+/* #############################################################################
+ */
+#elif (defined(__GNUC__) || defined(__gnu_linux__)) && defined(__x86__)
+
+#define FUNCTION_fixmul_DD
+#define FUNCTION_fixmuldiv2_DD
+
+#define FUNCTION_fixmuldiv2BitExact_DD
+#define fixmuldiv2BitExact_DD(a, b) fixmuldiv2_DD(a, b)
+
+#define FUNCTION_fixmulBitExact_DD
+#define fixmulBitExact_DD(a, b) fixmul_DD(a, b)
+
+#define FUNCTION_fixmuldiv2BitExact_DS
+#define fixmuldiv2BitExact_DS(a, b) fixmuldiv2_DS(a, b)
+
+#define FUNCTION_fixmulBitExact_DS
+#define fixmulBitExact_DS(a, b) fixmul_DS(a, b)
+
+inline INT fixmul_DD(INT a, const INT b) {
+ INT result;
+
+ asm("imul %2;\n"
+ "shl $1, %0;\n"
+ : "=d"(result), "+a"(a)
+ : "r"(b));
+
+ return result;
+}
+
+inline INT fixmuldiv2_DD(INT a, const INT b) {
+ INT result;
+
+ asm("imul %2;" : "=d"(result), "+a"(a) : "r"(b));
+
+ return result;
+}
+
+#endif /* (defined(__GNUC__)||defined(__gnu_linux__)) && defined(__x86__) */
+
+#endif /* __x86__ */
+
+#endif /* !defined(FIXMUL_X86_H) */
diff --git a/fdk-aac/libFDK/include/x86/fixpoint_math_x86.h b/fdk-aac/libFDK/include/x86/fixpoint_math_x86.h
new file mode 100644
index 0000000..d81fb26
--- /dev/null
+++ b/fdk-aac/libFDK/include/x86/fixpoint_math_x86.h
@@ -0,0 +1,208 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Manuel Jander
+
+ Description: Fixed point specific mathematical functions for x86
+
+*******************************************************************************/
+
+#if !defined(FIXPOINT_MATH_X86_H)
+#define FIXPOINT_MATH_X86_H
+
+#define FUNCTION_sqrtFixp
+
+#include <math.h>
+
+#ifdef FUNCTION_sqrtFixp
+static inline FIXP_DBL sqrtFixp(const FIXP_DBL op) {
+ FIXP_DBL result;
+ /* result =
+ * (FIXP_DBL)(INT)(sqrt((double)(INT)op)*46340.950011841578559133736114903);
+ */
+ result = (FIXP_DBL)(INT)(sqrt((float)(INT)op) * 46340.9492f);
+ FDK_ASSERT(result >= (FIXP_DBL)0);
+ return result;
+}
+#endif /* FUNCTION_sqrtFixp */
+
+#include <math.h>
+
+#define FUNCTION_invSqrtNorm2
+/**
+ * \brief calculate 1.0/sqrt(op)
+ * \param op_m mantissa of input value.
+ * \param result_e pointer to return the exponent of the result
+ * \return mantissa of the result
+ */
+#ifdef FUNCTION_invSqrtNorm2
+inline FIXP_DBL invSqrtNorm2(FIXP_DBL op_m, INT *result_e) {
+ float result;
+ if (op_m == (FIXP_DBL)0) {
+ *result_e = 16;
+ return ((LONG)0x7fffffff);
+ }
+ result = (float)(1.0 / sqrt(0.5f * (float)(INT)op_m));
+ result = (float)ldexp(frexpf(result, result_e), DFRACT_BITS - 1);
+ *result_e += 15;
+
+ FDK_ASSERT(result >= 0);
+ return (FIXP_DBL)(INT)result;
+}
+#endif /* FUNCTION_invSqrtNorm2 */
+
+#define FUNCTION_invFixp
+/**
+ * \brief calculate 1.0/op
+ * \param op mantissa of the input value.
+ * \return mantissa of the result with implizit exponent of 31
+ */
+#ifdef FUNCTION_invFixp
+inline FIXP_DBL invFixp(FIXP_DBL op) {
+ float result;
+ INT result_e;
+ if ((op == (FIXP_DBL)0) || (op == (FIXP_DBL)1)) {
+ return ((LONG)0x7fffffff);
+ }
+ result = (float)(1.0 / (float)(INT)op);
+ result = frexpf(result, &result_e);
+ result = ldexpf(result, 31 + result_e);
+
+ return (FIXP_DBL)(INT)result;
+}
+
+/**
+ * \brief calculate 1.0/(op_m * 2^op_e)
+ * \param op_m mantissa of the input value.
+ * \param op_e pointer into were the exponent of the input value is stored, and
+ * the result will be stored into.
+ * \return mantissa of the result
+ */
+inline FIXP_DBL invFixp(FIXP_DBL op_m, int *op_e) {
+ float result;
+ INT result_e;
+ if ((op_m == (FIXP_DBL)0x00000000) || (op_m == (FIXP_DBL)0x00000001)) {
+ *op_e = 31 - *op_e;
+ return ((LONG)0x7fffffff);
+ }
+ result = (float)(1.0 / (float)(INT)op_m);
+ result = ldexpf(frexpf(result, &result_e), DFRACT_BITS - 1);
+ *op_e = result_e - *op_e + 31;
+ return (FIXP_DBL)(INT)result;
+}
+#endif /* FUNCTION_invFixp */
+
+#define FUNCTION_schur_div
+/**
+ * \brief Divide two FIXP_DBL values with given precision.
+ * \param num dividend
+ * \param denum divisor
+ * \param count amount of significant bits of the result (starting to the MSB)
+ * \return num/divisor
+ */
+#ifdef FUNCTION_schur_div
+inline FIXP_DBL schur_div(FIXP_DBL num, FIXP_DBL denum, INT count) {
+ (void)count;
+ /* same asserts than for fallback implementation */
+ FDK_ASSERT(num >= (FIXP_DBL)0);
+ FDK_ASSERT(denum > (FIXP_DBL)0);
+ FDK_ASSERT(num <= denum);
+
+ return (num == denum) ? (FIXP_DBL)MAXVAL_DBL
+ : (FIXP_DBL)(INT)(((INT64)(INT)num << 31) / (INT)denum);
+}
+#endif /* FUNCTION_schur_div */
+#endif /* !defined(FIXPOINT_MATH_X86_H) */
diff --git a/fdk-aac/libFDK/src/FDK_bitbuffer.cpp b/fdk-aac/libFDK/src/FDK_bitbuffer.cpp
new file mode 100644
index 0000000..98905ea
--- /dev/null
+++ b/fdk-aac/libFDK/src/FDK_bitbuffer.cpp
@@ -0,0 +1,489 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Lohwasser
+
+ Description: common bitbuffer read/write routines
+
+*******************************************************************************/
+
+#include "FDK_bitbuffer.h"
+
+#include "genericStds.h"
+#include "common_fix.h"
+#include "fixminmax.h"
+
+const UINT BitMask[32 + 1] = {
+ 0x0, 0x1, 0x3, 0x7, 0xf, 0x1f,
+ 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff,
+ 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff,
+ 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff,
+ 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff,
+ 0x3fffffff, 0x7fffffff, 0xffffffff};
+
+void FDK_CreateBitBuffer(HANDLE_FDK_BITBUF *hBitBuf, UCHAR *pBuffer,
+ UINT bufSize) {
+ FDK_InitBitBuffer(*hBitBuf, pBuffer, bufSize, 0);
+
+ FDKmemclear((*hBitBuf)->Buffer, bufSize * sizeof(UCHAR));
+}
+
+void FDK_DeleteBitBuffer(HANDLE_FDK_BITBUF hBitBuf) { ; }
+
+void FDK_InitBitBuffer(HANDLE_FDK_BITBUF hBitBuf, UCHAR *pBuffer, UINT bufSize,
+ UINT validBits) {
+ hBitBuf->ValidBits = validBits;
+ hBitBuf->ReadOffset = 0;
+ hBitBuf->WriteOffset = 0;
+ hBitBuf->BitNdx = 0;
+
+ hBitBuf->Buffer = pBuffer;
+ hBitBuf->bufSize = bufSize;
+ hBitBuf->bufBits = (bufSize << 3);
+ /*assure bufsize (2^n) */
+ FDK_ASSERT(hBitBuf->ValidBits <= hBitBuf->bufBits);
+ FDK_ASSERT((bufSize > 0) && (bufSize <= MAX_BUFSIZE_BYTES));
+ {
+ UINT x = 0, n = bufSize;
+ for (x = 0; n > 0; x++, n >>= 1) {
+ }
+ if (bufSize != ((UINT)1 << (x - 1))) {
+ FDK_ASSERT(0);
+ }
+ }
+}
+
+void FDK_ResetBitBuffer(HANDLE_FDK_BITBUF hBitBuf) {
+ hBitBuf->ValidBits = 0;
+ hBitBuf->ReadOffset = 0;
+ hBitBuf->WriteOffset = 0;
+ hBitBuf->BitNdx = 0;
+}
+
+#ifndef FUNCTION_FDK_get
+INT FDK_get(HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits) {
+ UINT byteOffset = hBitBuf->BitNdx >> 3;
+ UINT bitOffset = hBitBuf->BitNdx & 0x07;
+
+ hBitBuf->BitNdx = (hBitBuf->BitNdx + numberOfBits) & (hBitBuf->bufBits - 1);
+ hBitBuf->ValidBits -= numberOfBits;
+
+ UINT byteMask = hBitBuf->bufSize - 1;
+
+ UINT tx = (hBitBuf->Buffer[byteOffset & byteMask] << 24) |
+ (hBitBuf->Buffer[(byteOffset + 1) & byteMask] << 16) |
+ (hBitBuf->Buffer[(byteOffset + 2) & byteMask] << 8) |
+ hBitBuf->Buffer[(byteOffset + 3) & byteMask];
+
+ if (bitOffset) {
+ tx <<= bitOffset;
+ tx |= hBitBuf->Buffer[(byteOffset + 4) & byteMask] >> (8 - bitOffset);
+ }
+
+ return (tx >> (32 - numberOfBits));
+}
+#endif /* #ifndef FUNCTION_FDK_get */
+
+#ifndef FUNCTION_FDK_get32
+INT FDK_get32(HANDLE_FDK_BITBUF hBitBuf) {
+ UINT BitNdx = hBitBuf->BitNdx + 32;
+ hBitBuf->BitNdx = BitNdx & (hBitBuf->bufBits - 1);
+ hBitBuf->ValidBits = (UINT)((INT)hBitBuf->ValidBits - (INT)32);
+
+ UINT byteOffset = (BitNdx - 1) >> 3;
+ if (BitNdx <= hBitBuf->bufBits) {
+ UINT cache = (hBitBuf->Buffer[(byteOffset - 3)] << 24) |
+ (hBitBuf->Buffer[(byteOffset - 2)] << 16) |
+ (hBitBuf->Buffer[(byteOffset - 1)] << 8) |
+ hBitBuf->Buffer[(byteOffset - 0)];
+
+ if ((BitNdx = (BitNdx & 7)) != 0) {
+ cache = (cache >> (8 - BitNdx)) |
+ ((UINT)hBitBuf->Buffer[byteOffset - 4] << (24 + BitNdx));
+ }
+ return (cache);
+ } else {
+ UINT byte_mask = hBitBuf->bufSize - 1;
+ UINT cache = (hBitBuf->Buffer[(byteOffset - 3) & byte_mask] << 24) |
+ (hBitBuf->Buffer[(byteOffset - 2) & byte_mask] << 16) |
+ (hBitBuf->Buffer[(byteOffset - 1) & byte_mask] << 8) |
+ hBitBuf->Buffer[(byteOffset - 0) & byte_mask];
+
+ if ((BitNdx = (BitNdx & 7)) != 0) {
+ cache = (cache >> (8 - BitNdx)) |
+ ((UINT)hBitBuf->Buffer[(byteOffset - 4) & byte_mask]
+ << (24 + BitNdx));
+ }
+ return (cache);
+ }
+}
+#endif
+
+INT FDK_getBwd(HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits) {
+ UINT byteOffset = hBitBuf->BitNdx >> 3;
+ UINT bitOffset = hBitBuf->BitNdx & 0x07;
+ UINT byteMask = hBitBuf->bufSize - 1;
+ int i;
+
+ hBitBuf->BitNdx = (hBitBuf->BitNdx - numberOfBits) & (hBitBuf->bufBits - 1);
+ hBitBuf->ValidBits += numberOfBits;
+
+ UINT tx = hBitBuf->Buffer[(byteOffset - 3) & byteMask] << 24 |
+ hBitBuf->Buffer[(byteOffset - 2) & byteMask] << 16 |
+ hBitBuf->Buffer[(byteOffset - 1) & byteMask] << 8 |
+ hBitBuf->Buffer[byteOffset & byteMask];
+ UINT txa = 0x0;
+
+ tx >>= (8 - bitOffset);
+
+ if (bitOffset && numberOfBits > 24) {
+ tx |= hBitBuf->Buffer[(byteOffset - 4) & byteMask] << (24 + bitOffset);
+ }
+
+ /* in place turn around */
+ for (i = 0; i < 16; i++) {
+ UINT bitMaskR = 0x00000001 << i;
+ UINT bitMaskL = 0x80000000 >> i;
+
+ txa |= (tx & bitMaskR) << (31 - (i << 1));
+ txa |= (tx & bitMaskL) >> (31 - (i << 1));
+ }
+
+ return (txa >> (32 - numberOfBits));
+}
+
+void FDK_put(HANDLE_FDK_BITBUF hBitBuf, UINT value, const UINT numberOfBits) {
+ if (numberOfBits != 0) {
+ UINT byteOffset0 = hBitBuf->BitNdx >> 3;
+ UINT bitOffset = hBitBuf->BitNdx & 0x7;
+
+ hBitBuf->BitNdx = (hBitBuf->BitNdx + numberOfBits) & (hBitBuf->bufBits - 1);
+ hBitBuf->ValidBits += numberOfBits;
+
+ UINT byteMask = hBitBuf->bufSize - 1;
+
+ UINT byteOffset1 = (byteOffset0 + 1) & byteMask;
+ UINT byteOffset2 = (byteOffset0 + 2) & byteMask;
+ UINT byteOffset3 = (byteOffset0 + 3) & byteMask;
+
+ // Create tmp containing free bits at the left border followed by bits to
+ // write, LSB's are cleared, if available Create mask to apply upon all
+ // buffer bytes
+ UINT tmp = (value << (32 - numberOfBits)) >> bitOffset;
+ UINT mask = ~((BitMask[numberOfBits] << (32 - numberOfBits)) >> bitOffset);
+
+ // read all 4 bytes from buffer and create a 32-bit cache
+ UINT cache = (((UINT)hBitBuf->Buffer[byteOffset0]) << 24) |
+ (((UINT)hBitBuf->Buffer[byteOffset1]) << 16) |
+ (((UINT)hBitBuf->Buffer[byteOffset2]) << 8) |
+ (((UINT)hBitBuf->Buffer[byteOffset3]) << 0);
+
+ cache = (cache & mask) | tmp;
+ hBitBuf->Buffer[byteOffset0] = (UCHAR)(cache >> 24);
+ hBitBuf->Buffer[byteOffset1] = (UCHAR)(cache >> 16);
+ hBitBuf->Buffer[byteOffset2] = (UCHAR)(cache >> 8);
+ hBitBuf->Buffer[byteOffset3] = (UCHAR)(cache >> 0);
+
+ if ((bitOffset + numberOfBits) > 32) {
+ UINT byteOffset4 = (byteOffset0 + 4) & byteMask;
+ // remaining bits: in range 1..7
+ // replace MSBits of next byte in buffer by LSBits of "value"
+ int bits = (bitOffset + numberOfBits) & 7;
+ cache =
+ (UINT)hBitBuf->Buffer[byteOffset4] & (~(BitMask[bits] << (8 - bits)));
+ cache |= value << (8 - bits);
+ hBitBuf->Buffer[byteOffset4] = (UCHAR)cache;
+ }
+ }
+}
+
+void FDK_putBwd(HANDLE_FDK_BITBUF hBitBuf, UINT value,
+ const UINT numberOfBits) {
+ UINT byteOffset = hBitBuf->BitNdx >> 3;
+ UINT bitOffset = 7 - (hBitBuf->BitNdx & 0x07);
+ UINT byteMask = hBitBuf->bufSize - 1;
+
+ UINT mask = ~(BitMask[numberOfBits] << bitOffset);
+ UINT tmp = 0x0000;
+ int i;
+
+ hBitBuf->BitNdx = (hBitBuf->BitNdx - numberOfBits) & (hBitBuf->bufBits - 1);
+ hBitBuf->ValidBits -= numberOfBits;
+
+ /* in place turn around */
+ for (i = 0; i < 16; i++) {
+ UINT bitMaskR = 0x00000001 << i;
+ UINT bitMaskL = 0x80000000 >> i;
+
+ tmp |= (value & bitMaskR) << (31 - (i << 1));
+ tmp |= (value & bitMaskL) >> (31 - (i << 1));
+ }
+ value = tmp;
+ tmp = value >> (32 - numberOfBits) << bitOffset;
+
+ hBitBuf->Buffer[byteOffset & byteMask] =
+ (hBitBuf->Buffer[byteOffset & byteMask] & (mask)) | (UCHAR)(tmp);
+ hBitBuf->Buffer[(byteOffset - 1) & byteMask] =
+ (hBitBuf->Buffer[(byteOffset - 1) & byteMask] & (mask >> 8)) |
+ (UCHAR)(tmp >> 8);
+ hBitBuf->Buffer[(byteOffset - 2) & byteMask] =
+ (hBitBuf->Buffer[(byteOffset - 2) & byteMask] & (mask >> 16)) |
+ (UCHAR)(tmp >> 16);
+ hBitBuf->Buffer[(byteOffset - 3) & byteMask] =
+ (hBitBuf->Buffer[(byteOffset - 3) & byteMask] & (mask >> 24)) |
+ (UCHAR)(tmp >> 24);
+
+ if ((bitOffset + numberOfBits) > 32) {
+ hBitBuf->Buffer[(byteOffset - 4) & byteMask] =
+ (UCHAR)(value >> (64 - numberOfBits - bitOffset)) |
+ (hBitBuf->Buffer[(byteOffset - 4) & byteMask] &
+ ~(BitMask[bitOffset] >> (32 - numberOfBits)));
+ }
+}
+
+#ifndef FUNCTION_FDK_pushBack
+void FDK_pushBack(HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits,
+ UCHAR config) {
+ hBitBuf->ValidBits =
+ (config == 0) ? (UINT)((INT)hBitBuf->ValidBits + (INT)numberOfBits)
+ : ((UINT)((INT)hBitBuf->ValidBits - (INT)numberOfBits));
+ hBitBuf->BitNdx = ((UINT)((INT)hBitBuf->BitNdx - (INT)numberOfBits)) &
+ (hBitBuf->bufBits - 1);
+}
+#endif
+
+void FDK_pushForward(HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits,
+ UCHAR config) {
+ hBitBuf->ValidBits =
+ (config == 0) ? ((UINT)((INT)hBitBuf->ValidBits - (INT)numberOfBits))
+ : (UINT)((INT)hBitBuf->ValidBits + (INT)numberOfBits);
+ hBitBuf->BitNdx =
+ (UINT)((INT)hBitBuf->BitNdx + (INT)numberOfBits) & (hBitBuf->bufBits - 1);
+}
+
+#ifndef FUNCTION_FDK_getValidBits
+UINT FDK_getValidBits(HANDLE_FDK_BITBUF hBitBuf) { return hBitBuf->ValidBits; }
+#endif /* #ifndef FUNCTION_FDK_getValidBits */
+
+INT FDK_getFreeBits(HANDLE_FDK_BITBUF hBitBuf) {
+ return (hBitBuf->bufBits - hBitBuf->ValidBits);
+}
+
+void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer,
+ const UINT bufferSize, UINT *bytesValid) {
+ inputBuffer = &inputBuffer[bufferSize - *bytesValid];
+
+ UINT bTotal = 0;
+
+ UINT bToRead = (hBitBuf->bufBits - hBitBuf->ValidBits) >> 3;
+ UINT noOfBytes =
+ fMin(bToRead,
+ *bytesValid); //(bToRead < *bytesValid) ? bToRead : *bytesValid ;
+
+ while (noOfBytes > 0) {
+ /* split read to buffer size */
+ bToRead = hBitBuf->bufSize - hBitBuf->ReadOffset;
+ bToRead = fMin(bToRead,
+ noOfBytes); //(bToRead < noOfBytes) ? bToRead : noOfBytes ;
+
+ /* copy 'bToRead' bytes from 'ptr' to inputbuffer */
+ FDKmemcpy(&hBitBuf->Buffer[hBitBuf->ReadOffset], inputBuffer,
+ bToRead * sizeof(UCHAR));
+
+ /* add noOfBits to number of valid bits in buffer */
+ hBitBuf->ValidBits += bToRead << 3;
+ bTotal += bToRead;
+ inputBuffer += bToRead;
+
+ hBitBuf->ReadOffset =
+ (hBitBuf->ReadOffset + bToRead) & (hBitBuf->bufSize - 1);
+ noOfBytes -= bToRead;
+ }
+
+ *bytesValid -= bTotal;
+}
+
+void CopyAlignedBlock(HANDLE_FDK_BITBUF h_BitBufSrc, UCHAR *RESTRICT dstBuffer,
+ UINT bToRead) {
+ UINT byteOffset = h_BitBufSrc->BitNdx >> 3;
+ const UINT byteMask = h_BitBufSrc->bufSize - 1;
+
+ UCHAR *RESTRICT pBBB = h_BitBufSrc->Buffer;
+ for (UINT i = 0; i < bToRead; i++) {
+ dstBuffer[i] = pBBB[(byteOffset + i) & byteMask];
+ }
+
+ bToRead <<= 3;
+
+ h_BitBufSrc->BitNdx =
+ (h_BitBufSrc->BitNdx + bToRead) & (h_BitBufSrc->bufBits - 1);
+ h_BitBufSrc->ValidBits -= bToRead;
+}
+
+void FDK_Copy(HANDLE_FDK_BITBUF h_BitBufDst, HANDLE_FDK_BITBUF h_BitBufSrc,
+ UINT *bytesValid) {
+ INT bTotal = 0;
+
+ /* limit noOfBytes to valid bytes in src buffer and available bytes in dst
+ * buffer */
+ UINT bToRead = h_BitBufSrc->ValidBits >> 3;
+ UINT noOfBytes =
+ fMin(bToRead,
+ *bytesValid); //(*bytesValid < bToRead) ? *bytesValid : bToRead ;
+ bToRead = FDK_getFreeBits(h_BitBufDst);
+ noOfBytes =
+ fMin(bToRead, noOfBytes); //(bToRead < noOfBytes) ? bToRead : noOfBytes;
+
+ while (noOfBytes > 0) {
+ /* Split Read to buffer size */
+ bToRead = h_BitBufDst->bufSize - h_BitBufDst->ReadOffset;
+ bToRead = fMin(noOfBytes,
+ bToRead); //(noOfBytes < bToRead) ? noOfBytes : bToRead ;
+
+ /* copy 'bToRead' bytes from buffer to buffer */
+ if (!(h_BitBufSrc->BitNdx & 0x07)) {
+ CopyAlignedBlock(h_BitBufSrc,
+ h_BitBufDst->Buffer + h_BitBufDst->ReadOffset, bToRead);
+ } else {
+ for (UINT i = 0; i < bToRead; i++) {
+ h_BitBufDst->Buffer[h_BitBufDst->ReadOffset + i] =
+ (UCHAR)FDK_get(h_BitBufSrc, 8);
+ }
+ }
+
+ /* add noOfBits to number of valid bits in buffer */
+ h_BitBufDst->ValidBits += bToRead << 3;
+ bTotal += bToRead;
+
+ h_BitBufDst->ReadOffset =
+ (h_BitBufDst->ReadOffset + bToRead) & (h_BitBufDst->bufSize - 1);
+ noOfBytes -= bToRead;
+ }
+
+ *bytesValid -= bTotal;
+}
+
+void FDK_Fetch(HANDLE_FDK_BITBUF hBitBuf, UCHAR *outBuf, UINT *writeBytes) {
+ UCHAR *RESTRICT outputBuffer = outBuf;
+ UINT bTotal = 0;
+
+ UINT bToWrite = (hBitBuf->ValidBits) >> 3;
+ UINT noOfBytes =
+ fMin(bToWrite,
+ *writeBytes); //(bToWrite < *writeBytes) ? bToWrite : *writeBytes ;
+
+ while (noOfBytes > 0) {
+ /* split write to buffer size */
+ bToWrite = hBitBuf->bufSize - hBitBuf->WriteOffset;
+ bToWrite = fMin(
+ bToWrite, noOfBytes); //(bToWrite < noOfBytes) ? bToWrite : noOfBytes ;
+
+ /* copy 'bToWrite' bytes from bitbuffer to outputbuffer */
+ FDKmemcpy(outputBuffer, &hBitBuf->Buffer[hBitBuf->WriteOffset],
+ bToWrite * sizeof(UCHAR));
+
+ /* sub noOfBits from number of valid bits in buffer */
+ hBitBuf->ValidBits -= bToWrite << 3;
+ bTotal += bToWrite;
+ outputBuffer += bToWrite;
+
+ hBitBuf->WriteOffset =
+ (hBitBuf->WriteOffset + bToWrite) & (hBitBuf->bufSize - 1);
+ noOfBytes -= bToWrite;
+ }
+
+ *writeBytes = bTotal;
+}
diff --git a/fdk-aac/libFDK/src/FDK_core.cpp b/fdk-aac/libFDK/src/FDK_core.cpp
new file mode 100644
index 0000000..75ea8a2
--- /dev/null
+++ b/fdk-aac/libFDK/src/FDK_core.cpp
@@ -0,0 +1,145 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Manuel Jander
+
+ Description: FDK tools versioning support
+
+*******************************************************************************/
+
+#include "FDK_core.h"
+
+/* FDK tools library info */
+#define FDK_TOOLS_LIB_VL0 3
+#define FDK_TOOLS_LIB_VL1 0
+#define FDK_TOOLS_LIB_VL2 0
+#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_TIME __TIME__
+#endif
+
+int FDK_toolsGetLibInfo(LIB_INFO *info) {
+ UINT v;
+ int i;
+
+ if (info == NULL) {
+ return -1;
+ }
+
+ /* search for next free tab */
+ i = FDKlibInfo_lookup(info, FDK_TOOLS);
+ if (i < 0) return -1;
+
+ info += i;
+
+ v = LIB_VERSION(FDK_TOOLS_LIB_VL0, FDK_TOOLS_LIB_VL1, FDK_TOOLS_LIB_VL2);
+
+ FDKsprintf(info->versionStr, "%d.%d.%d", ((v >> 24) & 0xff),
+ ((v >> 16) & 0xff), ((v >> 8) & 0xff));
+
+ info->module_id = FDK_TOOLS;
+ info->version = v;
+ info->build_date = FDK_TOOLS_LIB_BUILD_DATE;
+ info->build_time = FDK_TOOLS_LIB_BUILD_TIME;
+ info->title = FDK_TOOLS_LIB_TITLE;
+ info->flags = 1;
+
+ return 0;
+}
diff --git a/fdk-aac/libFDK/src/FDK_crc.cpp b/fdk-aac/libFDK/src/FDK_crc.cpp
new file mode 100644
index 0000000..ecbddb1
--- /dev/null
+++ b/fdk-aac/libFDK/src/FDK_crc.cpp
@@ -0,0 +1,526 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: CRC calculation
+
+*******************************************************************************/
+
+#include "FDK_crc.h"
+
+/*---------------- constants -----------------------*/
+
+/**
+ * \brief This table defines precalculated lookup tables for crc polynom x^16
+ * + x^15 + x^2 + x^0.
+ */
+static const USHORT crcLookup_16_15_2_0[256] = {
+ 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 0x8033,
+ 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, 0x8063, 0x0066,
+ 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, 0x0050, 0x8055, 0x805f,
+ 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, 0x80c3, 0x00c6, 0x00cc, 0x80c9,
+ 0x00d8, 0x80dd, 0x80d7, 0x00d2, 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb,
+ 0x00ee, 0x00e4, 0x80e1, 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be,
+ 0x00b4, 0x80b1, 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087,
+ 0x0082, 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
+ 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, 0x01e0,
+ 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, 0x81d3, 0x01d6,
+ 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, 0x0140, 0x8145, 0x814f,
+ 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, 0x8173, 0x0176, 0x017c, 0x8179,
+ 0x0168, 0x816d, 0x8167, 0x0162, 0x8123, 0x0126, 0x012c, 0x8129, 0x0138,
+ 0x813d, 0x8137, 0x0132, 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e,
+ 0x0104, 0x8101, 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317,
+ 0x0312, 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
+ 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, 0x8353,
+ 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, 0x03c0, 0x83c5,
+ 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, 0x83f3, 0x03f6, 0x03fc,
+ 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, 0x83a3, 0x03a6, 0x03ac, 0x83a9,
+ 0x03b8, 0x83bd, 0x83b7, 0x03b2, 0x0390, 0x8395, 0x839f, 0x039a, 0x838b,
+ 0x038e, 0x0384, 0x8381, 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e,
+ 0x0294, 0x8291, 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7,
+ 0x02a2, 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
+ 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, 0x8243,
+ 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, 0x0270, 0x8275,
+ 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, 0x0220, 0x8225, 0x822f,
+ 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, 0x8213, 0x0216, 0x021c, 0x8219,
+ 0x0208, 0x820d, 0x8207, 0x0202};
+
+/**
+ * \brief This table defines precalculated lookup tables for crc polynom x^16
+ * + x^12 + x^5 + x^0.
+ */
+static const USHORT crcLookup_16_12_5_0[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108,
+ 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210,
+ 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b,
+ 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401,
+ 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee,
+ 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6,
+ 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d,
+ 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5,
+ 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc,
+ 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4,
+ 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd,
+ 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13,
+ 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a,
+ 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e,
+ 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1,
+ 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb,
+ 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0,
+ 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8,
+ 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657,
+ 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9,
+ 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882,
+ 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e,
+ 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07,
+ 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d,
+ 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74,
+ 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
+
+/**
+ * \brief This table defines precalculated lookup tables for crc polynom x^16 + x^14 + x^13 + x^12 + x^11 + x^5 + x^3 + x^2 + x^0.
+ */
+static const USHORT crcLookup_16_14_13_12_11_5_3_2_0[256] =
+{
+ 0x0000, 0x782f, 0xf05e, 0x8871, 0x9893, 0xe0bc, 0x68cd, 0x10e2,
+ 0x4909, 0x3126, 0xb957, 0xc178, 0xd19a, 0xa9b5, 0x21c4, 0x59eb,
+ 0x9212, 0xea3d, 0x624c, 0x1a63, 0x0a81, 0x72ae, 0xfadf, 0x82f0,
+ 0xdb1b, 0xa334, 0x2b45, 0x536a, 0x4388, 0x3ba7, 0xb3d6, 0xcbf9,
+ 0x5c0b, 0x2424, 0xac55, 0xd47a, 0xc498, 0xbcb7, 0x34c6, 0x4ce9,
+ 0x1502, 0x6d2d, 0xe55c, 0x9d73, 0x8d91, 0xf5be, 0x7dcf, 0x05e0,
+ 0xce19, 0xb636, 0x3e47, 0x4668, 0x568a, 0x2ea5, 0xa6d4, 0xdefb,
+ 0x8710, 0xff3f, 0x774e, 0x0f61, 0x1f83, 0x67ac, 0xefdd, 0x97f2,
+ 0xb816, 0xc039, 0x4848, 0x3067, 0x2085, 0x58aa, 0xd0db, 0xa8f4,
+ 0xf11f, 0x8930, 0x0141, 0x796e, 0x698c, 0x11a3, 0x99d2, 0xe1fd,
+ 0x2a04, 0x522b, 0xda5a, 0xa275, 0xb297, 0xcab8, 0x42c9, 0x3ae6,
+ 0x630d, 0x1b22, 0x9353, 0xeb7c, 0xfb9e, 0x83b1, 0x0bc0, 0x73ef,
+ 0xe41d, 0x9c32, 0x1443, 0x6c6c, 0x7c8e, 0x04a1, 0x8cd0, 0xf4ff,
+ 0xad14, 0xd53b, 0x5d4a, 0x2565, 0x3587, 0x4da8, 0xc5d9, 0xbdf6,
+ 0x760f, 0x0e20, 0x8651, 0xfe7e, 0xee9c, 0x96b3, 0x1ec2, 0x66ed,
+ 0x3f06, 0x4729, 0xcf58, 0xb777, 0xa795, 0xdfba, 0x57cb, 0x2fe4,
+ 0x0803, 0x702c, 0xf85d, 0x8072, 0x9090, 0xe8bf, 0x60ce, 0x18e1,
+ 0x410a, 0x3925, 0xb154, 0xc97b, 0xd999, 0xa1b6, 0x29c7, 0x51e8,
+ 0x9a11, 0xe23e, 0x6a4f, 0x1260, 0x0282, 0x7aad, 0xf2dc, 0x8af3,
+ 0xd318, 0xab37, 0x2346, 0x5b69, 0x4b8b, 0x33a4, 0xbbd5, 0xc3fa,
+ 0x5408, 0x2c27, 0xa456, 0xdc79, 0xcc9b, 0xb4b4, 0x3cc5, 0x44ea,
+ 0x1d01, 0x652e, 0xed5f, 0x9570, 0x8592, 0xfdbd, 0x75cc, 0x0de3,
+ 0xc61a, 0xbe35, 0x3644, 0x4e6b, 0x5e89, 0x26a6, 0xaed7, 0xd6f8,
+ 0x8f13, 0xf73c, 0x7f4d, 0x0762, 0x1780, 0x6faf, 0xe7de, 0x9ff1,
+ 0xb015, 0xc83a, 0x404b, 0x3864, 0x2886, 0x50a9, 0xd8d8, 0xa0f7,
+ 0xf91c, 0x8133, 0x0942, 0x716d, 0x618f, 0x19a0, 0x91d1, 0xe9fe,
+ 0x2207, 0x5a28, 0xd259, 0xaa76, 0xba94, 0xc2bb, 0x4aca, 0x32e5,
+ 0x6b0e, 0x1321, 0x9b50, 0xe37f, 0xf39d, 0x8bb2, 0x03c3, 0x7bec,
+ 0xec1e, 0x9431, 0x1c40, 0x646f, 0x748d, 0x0ca2, 0x84d3, 0xfcfc,
+ 0xa517, 0xdd38, 0x5549, 0x2d66, 0x3d84, 0x45ab, 0xcdda, 0xb5f5,
+ 0x7e0c, 0x0623, 0x8e52, 0xf67d, 0xe69f, 0x9eb0, 0x16c1, 0x6eee,
+ 0x3705, 0x4f2a, 0xc75b, 0xbf74, 0xaf96, 0xd7b9, 0x5fc8, 0x27e7,
+};
+
+/**
+ * \brief This table defines precalculated lookup tables for crc polynom x^16
+ * + x^15 + x^5 + x^0.
+ */
+static const USHORT crcLookup_16_15_5_0[256] = {
+ 0x0000, 0x8021, 0x8063, 0x0042, 0x80e7, 0x00c6, 0x0084, 0x80a5, 0x81ef,
+ 0x01ce, 0x018c, 0x81ad, 0x0108, 0x8129, 0x816b, 0x014a, 0x83ff, 0x03de,
+ 0x039c, 0x83bd, 0x0318, 0x8339, 0x837b, 0x035a, 0x0210, 0x8231, 0x8273,
+ 0x0252, 0x82f7, 0x02d6, 0x0294, 0x82b5, 0x87df, 0x07fe, 0x07bc, 0x879d,
+ 0x0738, 0x8719, 0x875b, 0x077a, 0x0630, 0x8611, 0x8653, 0x0672, 0x86d7,
+ 0x06f6, 0x06b4, 0x8695, 0x0420, 0x8401, 0x8443, 0x0462, 0x84c7, 0x04e6,
+ 0x04a4, 0x8485, 0x85cf, 0x05ee, 0x05ac, 0x858d, 0x0528, 0x8509, 0x854b,
+ 0x056a, 0x8f9f, 0x0fbe, 0x0ffc, 0x8fdd, 0x0f78, 0x8f59, 0x8f1b, 0x0f3a,
+ 0x0e70, 0x8e51, 0x8e13, 0x0e32, 0x8e97, 0x0eb6, 0x0ef4, 0x8ed5, 0x0c60,
+ 0x8c41, 0x8c03, 0x0c22, 0x8c87, 0x0ca6, 0x0ce4, 0x8cc5, 0x8d8f, 0x0dae,
+ 0x0dec, 0x8dcd, 0x0d68, 0x8d49, 0x8d0b, 0x0d2a, 0x0840, 0x8861, 0x8823,
+ 0x0802, 0x88a7, 0x0886, 0x08c4, 0x88e5, 0x89af, 0x098e, 0x09cc, 0x89ed,
+ 0x0948, 0x8969, 0x892b, 0x090a, 0x8bbf, 0x0b9e, 0x0bdc, 0x8bfd, 0x0b58,
+ 0x8b79, 0x8b3b, 0x0b1a, 0x0a50, 0x8a71, 0x8a33, 0x0a12, 0x8ab7, 0x0a96,
+ 0x0ad4, 0x8af5, 0x9f1f, 0x1f3e, 0x1f7c, 0x9f5d, 0x1ff8, 0x9fd9, 0x9f9b,
+ 0x1fba, 0x1ef0, 0x9ed1, 0x9e93, 0x1eb2, 0x9e17, 0x1e36, 0x1e74, 0x9e55,
+ 0x1ce0, 0x9cc1, 0x9c83, 0x1ca2, 0x9c07, 0x1c26, 0x1c64, 0x9c45, 0x9d0f,
+ 0x1d2e, 0x1d6c, 0x9d4d, 0x1de8, 0x9dc9, 0x9d8b, 0x1daa, 0x18c0, 0x98e1,
+ 0x98a3, 0x1882, 0x9827, 0x1806, 0x1844, 0x9865, 0x992f, 0x190e, 0x194c,
+ 0x996d, 0x19c8, 0x99e9, 0x99ab, 0x198a, 0x9b3f, 0x1b1e, 0x1b5c, 0x9b7d,
+ 0x1bd8, 0x9bf9, 0x9bbb, 0x1b9a, 0x1ad0, 0x9af1, 0x9ab3, 0x1a92, 0x9a37,
+ 0x1a16, 0x1a54, 0x9a75, 0x1080, 0x90a1, 0x90e3, 0x10c2, 0x9067, 0x1046,
+ 0x1004, 0x9025, 0x916f, 0x114e, 0x110c, 0x912d, 0x1188, 0x91a9, 0x91eb,
+ 0x11ca, 0x937f, 0x135e, 0x131c, 0x933d, 0x1398, 0x93b9, 0x93fb, 0x13da,
+ 0x1290, 0x92b1, 0x92f3, 0x12d2, 0x9277, 0x1256, 0x1214, 0x9235, 0x975f,
+ 0x177e, 0x173c, 0x971d, 0x17b8, 0x9799, 0x97db, 0x17fa, 0x16b0, 0x9691,
+ 0x96d3, 0x16f2, 0x9657, 0x1676, 0x1634, 0x9615, 0x14a0, 0x9481, 0x94c3,
+ 0x14e2, 0x9447, 0x1466, 0x1424, 0x9405, 0x954f, 0x156e, 0x152c, 0x950d,
+ 0x15a8, 0x9589, 0x95cb, 0x15ea,
+};
+
+/*--------------- function declarations --------------------*/
+
+static inline INT calcCrc_Bits(USHORT *const pCrc, USHORT crcMask,
+ USHORT crcPoly, HANDLE_FDK_BITSTREAM hBs,
+ INT nBits);
+
+static inline INT calcCrc_Bytes(USHORT *const pCrc, const USHORT *pCrcLookup,
+ HANDLE_FDK_BITSTREAM hBs, INT nBytes);
+
+static void crcCalc(HANDLE_FDK_CRCINFO hCrcInfo, HANDLE_FDK_BITSTREAM hBs,
+ const INT reg);
+
+/*------------- function definitions ----------------*/
+
+void FDKcrcInit(HANDLE_FDK_CRCINFO hCrcInfo, const UINT crcPoly,
+ const UINT crcStartValue, const UINT crcLen) {
+ /* crc polynom example:
+ DAB+ FireCode:
+ x^16 + x^14 + x^13 + x^12 + x^11 + x^5 + x^3 + x^2 + x^0
+ (1) 0111 1000 0010 1101 -> 0x782d
+
+ x^16 + x^15 + x^5 + x^0 (1) 1000 0000 0010 0001 -> 0x8021
+ x^16 + x^15 + x^2 + x^0 (1) 1000 0000 0000 0101 -> 0x8005
+ x^16 + x^12 + x^5 + x^0 (1) 0001 0000 0010 0001 -> 0x1021
+ x^8 + x^4 + x^3 + x^2 + x^0 (1) 0001 1101 -> 0x001d */
+
+ hCrcInfo->crcLen = crcLen;
+ hCrcInfo->crcPoly = crcPoly;
+ hCrcInfo->startValue = crcStartValue;
+ hCrcInfo->crcMask = (crcLen) ? (1 << (crcLen - 1)) : 0;
+
+ FDKcrcReset(hCrcInfo);
+
+ hCrcInfo->pCrcLookup =
+ 0; /* Preset 0 for "crcLen" != 16 or unknown 16-bit polynoms "crcPoly" */
+
+ if (hCrcInfo->crcLen == 16) {
+ switch (crcPoly) {
+ case 0x8021:
+ hCrcInfo->pCrcLookup = crcLookup_16_15_5_0;
+ break;
+ case 0x8005:
+ hCrcInfo->pCrcLookup = crcLookup_16_15_2_0;
+ break;
+ case 0x1021:
+ hCrcInfo->pCrcLookup = crcLookup_16_12_5_0;
+ break;
+ case 0x782d:
+ hCrcInfo->pCrcLookup = crcLookup_16_14_13_12_11_5_3_2_0;
+ break;
+ case 0x001d:
+ default:
+ /* no lookup table */
+ break;
+ }
+ }
+}
+
+void FDKcrcReset(HANDLE_FDK_CRCINFO hCrcInfo) {
+ int i;
+
+ hCrcInfo->crcValue = hCrcInfo->startValue;
+
+ for (i = 0; i < MAX_CRC_REGS; i++) {
+ hCrcInfo->crcRegData[i].isActive = 0;
+ }
+ hCrcInfo->regStart = 0;
+ hCrcInfo->regStop = 0;
+}
+
+INT FDKcrcStartReg(HANDLE_FDK_CRCINFO hCrcInfo, const HANDLE_FDK_BITSTREAM hBs,
+ const INT mBits) {
+ int reg = hCrcInfo->regStart;
+
+ FDK_ASSERT(hCrcInfo->crcRegData[reg].isActive == 0);
+ hCrcInfo->crcRegData[reg].isActive = 1;
+ hCrcInfo->crcRegData[reg].maxBits = mBits;
+ hCrcInfo->crcRegData[reg].validBits = (INT)FDKgetValidBits(hBs);
+ hCrcInfo->crcRegData[reg].bitBufCntBits = 0;
+
+ hCrcInfo->regStart = (hCrcInfo->regStart + 1) % MAX_CRC_REGS;
+
+ return (reg);
+}
+
+INT FDKcrcEndReg(HANDLE_FDK_CRCINFO hCrcInfo, const HANDLE_FDK_BITSTREAM hBs,
+ const INT reg) {
+ FDK_ASSERT((reg == (INT)hCrcInfo->regStop) &&
+ (hCrcInfo->crcRegData[reg].isActive == 1));
+
+ if (hBs->ConfigCache == BS_WRITER) {
+ hCrcInfo->crcRegData[reg].bitBufCntBits =
+ (INT)FDKgetValidBits(hBs) - hCrcInfo->crcRegData[reg].validBits;
+ } else {
+ hCrcInfo->crcRegData[reg].bitBufCntBits =
+ hCrcInfo->crcRegData[reg].validBits - (INT)FDKgetValidBits(hBs);
+ }
+
+ if (hCrcInfo->crcRegData[reg].maxBits == 0) {
+ hCrcInfo->crcRegData[reg].maxBits = hCrcInfo->crcRegData[reg].bitBufCntBits;
+ }
+
+ crcCalc(hCrcInfo, hBs, reg);
+
+ hCrcInfo->crcRegData[reg].isActive = 0;
+ hCrcInfo->regStop = (hCrcInfo->regStop + 1) % MAX_CRC_REGS;
+
+ return 0;
+}
+
+USHORT FDKcrcGetCRC(const HANDLE_FDK_CRCINFO hCrcInfo) {
+ return (hCrcInfo->crcValue & (((hCrcInfo->crcMask - 1) << 1) + 1));
+}
+
+/**
+ * \brief Calculate crc bits.
+ *
+ * Calculate crc starting at current bitstream postion over nBits.
+ *
+ * \param pCrc Pointer to an outlying allocated crc info
+ * structure.
+ * \param crcMask CrcMask in use.
+ * \param crcPoly Crc polynom in use.
+ * \param hBs Handle to current bit buffer structure.
+ * \param nBits Number of processing bits.
+ *
+ * \return Number of processed bits.
+ */
+static inline INT calcCrc_Bits(USHORT *const pCrc, USHORT crcMask,
+ USHORT crcPoly, HANDLE_FDK_BITSTREAM hBs,
+ INT nBits) {
+ int i;
+ USHORT crc = *pCrc; /* get crc value */
+
+ if (hBs != NULL) {
+ for (i = 0; (i < nBits); i++) {
+ USHORT tmp = FDKreadBit(hBs); // process single bit
+ tmp ^= ((crc & crcMask) ? 1 : 0);
+ if (tmp != 0) tmp = crcPoly;
+ crc <<= 1;
+ crc ^= tmp;
+ }
+ } else {
+ for (i = 0; (i < nBits); i++) {
+ USHORT tmp = (crc & crcMask) ? crcPoly : 0; // process single bit
+ crc <<= 1;
+ crc ^= tmp;
+ }
+ }
+ *pCrc = crc; /* update crc value */
+
+ return nBits;
+}
+
+/**
+ * \brief Calculate crc bytes.
+ *
+ * Calculate crc starting at current bitstream postion over nBytes.
+ *
+ * \param pCrc Pointer to an outlying allocated crc info
+ * structure.
+ * \param pCrcLookup Pointer to lookup table used for fast crc
+ * calculation.
+ * \param hBs Handle to current bit buffer structure.
+ * \param nBits Number of processing bytes.
+ *
+ * \return Number of processed bits.
+ */
+
+static inline INT calcCrc_Bytes(USHORT *const pCrc, const USHORT *pCrcLookup,
+ HANDLE_FDK_BITSTREAM hBs, INT nBytes) {
+ int i;
+ USHORT crc = *pCrc; /* get crc value */
+
+ if (hBs != NULL) {
+ ULONG data;
+ INT bits;
+ for (i = 0; i < (nBytes >> 2); i++) {
+ data = (ULONG)FDKreadBits(hBs, 32);
+ crc =
+ (crc << 8) ^ pCrcLookup[((crc >> 8) ^ ((USHORT)(data >> 24))) & 0xFF];
+ crc =
+ (crc << 8) ^ pCrcLookup[((crc >> 8) ^ ((USHORT)(data >> 16))) & 0xFF];
+ crc =
+ (crc << 8) ^ pCrcLookup[((crc >> 8) ^ ((USHORT)(data >> 8))) & 0xFF];
+ crc =
+ (crc << 8) ^ pCrcLookup[((crc >> 8) ^ ((USHORT)(data >> 0))) & 0xFF];
+ }
+ bits = (nBytes & 3) << 3;
+ if (bits > 0) {
+ data = (ULONG)FDKreadBits(hBs, bits);
+ for (bits -= 8; bits >= 0; bits -= 8)
+ crc = (crc << 8) ^
+ pCrcLookup[((crc >> 8) ^ (USHORT)(data >> bits)) & 0xFF];
+ }
+ } else {
+ for (i = 0; i < nBytes; i++) {
+ crc = (crc << 8) ^ pCrcLookup[(crc >> 8) & 0xFF];
+ }
+ }
+
+ *pCrc = crc; /* update crc value */
+ //fprintf(stderr, "\n\n crc[%d]=%04x\n", i, crc);
+
+ return (nBytes);
+}
+
+/**
+ * \brief Calculate crc.
+ *
+ * Calculate crc. Lenght depends on mBits parameter in FDKcrcStartReg()
+ * configuration.
+ *
+ * \param hCrcInfo Pointer to an outlying allocated crc info
+ * structure.
+ * \param hBs Pointer to current bit buffer structure.
+ * \param reg Crc region ID.
+ *
+ * \return Number of processed bits.
+ */
+static void crcCalc(HANDLE_FDK_CRCINFO hCrcInfo, HANDLE_FDK_BITSTREAM hBs,
+ const INT reg) {
+ USHORT crc = hCrcInfo->crcValue;
+ CCrcRegData *rD = &hCrcInfo->crcRegData[reg];
+ FDK_BITSTREAM bsReader;
+
+ if (hBs->ConfigCache == BS_READER) {
+ bsReader = *hBs;
+ FDKpushBiDirectional(&bsReader,
+ -(rD->validBits - (INT)FDKgetValidBits(&bsReader)));
+ } else {
+ FDKinitBitStream(&bsReader, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize,
+ hBs->hBitBuf.ValidBits, BS_READER);
+ FDKpushBiDirectional(&bsReader, rD->validBits);
+ }
+
+ int bits, rBits;
+ rBits = (rD->maxBits >= 0) ? rD->maxBits : -rD->maxBits; /* ramaining bits */
+ if ((rD->maxBits > 0) && ((rD->bitBufCntBits >> 3 << 3) < rBits)) {
+ bits = rD->bitBufCntBits;
+ } else {
+ bits = rBits;
+ }
+
+ int words = bits >> 3; /* processing bytes */
+ int mBits = bits & 0x7; /* modulo bits */
+
+ if (hCrcInfo->pCrcLookup) {
+ rBits -= (calcCrc_Bytes(&crc, hCrcInfo->pCrcLookup, &bsReader, words) << 3);
+ } else {
+ rBits -= calcCrc_Bits(&crc, hCrcInfo->crcMask, hCrcInfo->crcPoly, &bsReader,
+ words << 3);
+ }
+
+ /* remaining valid bits*/
+ if (mBits != 0) {
+ rBits -= calcCrc_Bits(&crc, hCrcInfo->crcMask, hCrcInfo->crcPoly, &bsReader,
+ mBits);
+ }
+
+ if (rBits != 0) {
+ /* zero bytes */
+ if ((hCrcInfo->pCrcLookup) && (rBits > 8)) {
+ rBits -=
+ (calcCrc_Bytes(&crc, hCrcInfo->pCrcLookup, NULL, rBits >> 3) << 3);
+ }
+ /* remaining zero bits */
+ if (rBits != 0) {
+ calcCrc_Bits(&crc, hCrcInfo->crcMask, hCrcInfo->crcPoly, NULL, rBits);
+ }
+ }
+
+ //fprintf(stderr, "\n\n crc=%04x\n", crc);
+ hCrcInfo->crcValue = crc;
+}
diff --git a/fdk-aac/libFDK/src/FDK_decorrelate.cpp b/fdk-aac/libFDK/src/FDK_decorrelate.cpp
new file mode 100644
index 0000000..c5de79a
--- /dev/null
+++ b/fdk-aac/libFDK/src/FDK_decorrelate.cpp
@@ -0,0 +1,1746 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Markus Lohwasser
+
+ Description: FDK Tools Decorrelator
+
+*******************************************************************************/
+
+#include "FDK_decorrelate.h"
+
+#define PC_NUM_BANDS (8)
+#define PC_NUM_HYB_BANDS (PC_NUM_BANDS - 3 + 10)
+
+#define DUCK_ALPHA (0.8f)
+#define DUCK_GAMMA (1.5f)
+#define ABS_THR (1e-9f * 32768 * 32768)
+#define ABS_THR_FDK ((FIXP_DBL)1)
+
+#define DECORR_ZERO_PADDING 0
+
+#define DECORR_FILTER_ORDER_BAND_0_MPS (20)
+#define DECORR_FILTER_ORDER_BAND_1_MPS (15)
+#define DECORR_FILTER_ORDER_BAND_2_MPS (6)
+#define DECORR_FILTER_ORDER_BAND_3_MPS (3)
+
+#define DECORR_FILTER_ORDER_BAND_0_USAC (10)
+#define DECORR_FILTER_ORDER_BAND_1_USAC (8)
+#define DECORR_FILTER_ORDER_BAND_2_USAC (3)
+#define DECORR_FILTER_ORDER_BAND_3_USAC (2)
+
+#define DECORR_FILTER_ORDER_BAND_0_LD (0)
+#define DECORR_FILTER_ORDER_BAND_1_LD (DECORR_FILTER_ORDER_BAND_1_MPS)
+#define DECORR_FILTER_ORDER_BAND_2_LD (DECORR_FILTER_ORDER_BAND_2_MPS)
+#define DECORR_FILTER_ORDER_BAND_3_LD (DECORR_FILTER_ORDER_BAND_3_MPS)
+
+#define MAX_DECORR_SEED_MPS \
+ (5) /* 4 is worst case for 7272 mode for low power */
+ /* 5 is worst case for 7271 and 7272 mode for high quality */
+#define MAX_DECORR_SEED_USAC (1)
+#define MAX_DECORR_SEED_LD (4)
+
+#define DECORR_FILTER_ORDER_PS (12)
+#define NUM_DECORR_CONFIGS \
+ (3) /* different configs defined by bsDecorrConfig bitstream field */
+
+/* REV_bandOffset_... tables map (hybrid) bands to the corresponding reverb
+ bands. Within each reverb band the same processing is applied. Instead of QMF
+ split frequencies the corresponding hybrid band offsets are stored directly
+ */
+static const UCHAR REV_bandOffset_MPS_HQ[NUM_DECORR_CONFIGS][(4)] = {
+ {8, 21, 30, 71}, {8, 56, 71, 71}, {0, 21, 71, 71}};
+/* REV_bandOffset_USAC[] are equivalent to REV_bandOffset_MPS_HQ */
+static const UCHAR REV_bandOffset_PS_HQ[(4)] = {30, 42, 71, 71};
+static const UCHAR REV_bandOffset_PS_LP[(4)] = {14, 42, 71, 71};
+static const UCHAR REV_bandOffset_LD[NUM_DECORR_CONFIGS][(4)] = {
+ {0, 14, 23, 64}, {0, 49, 64, 64}, {0, 14, 64, 64}};
+
+/* REV_delay_... tables define the number of delay elements within each reverb
+ * band */
+/* REV_filterOrder_... tables define the filter order within each reverb band */
+static const UCHAR REV_delay_MPS[(4)] = {8, 7, 2, 1};
+static const SCHAR REV_filterOrder_MPS[(4)] = {
+ DECORR_FILTER_ORDER_BAND_0_MPS, DECORR_FILTER_ORDER_BAND_1_MPS,
+ DECORR_FILTER_ORDER_BAND_2_MPS, DECORR_FILTER_ORDER_BAND_3_MPS};
+static const UCHAR REV_delay_PS_HQ[(4)] = {2, 14, 1, 0};
+static const UCHAR REV_delay_PS_LP[(4)] = {8, 14, 1, 0};
+static const SCHAR REV_filterOrder_PS[(4)] = {DECORR_FILTER_ORDER_PS, -1, -1,
+ -1};
+static const UCHAR REV_delay_USAC[(4)] = {11, 10, 5, 2};
+static const SCHAR REV_filterOrder_USAC[(4)] = {
+ DECORR_FILTER_ORDER_BAND_0_USAC, DECORR_FILTER_ORDER_BAND_1_USAC,
+ DECORR_FILTER_ORDER_BAND_2_USAC, DECORR_FILTER_ORDER_BAND_3_USAC};
+
+/* REV_filtType_... tables define the type of processing (filtering with
+ different properties or pure delay) done in each reverb band. This is mapped
+ to specialized routines. */
+static const REVBAND_FILT_TYPE REV_filtType_MPS[(4)] = {
+ COMMON_REAL, COMMON_REAL, COMMON_REAL, COMMON_REAL};
+
+static const REVBAND_FILT_TYPE REV_filtType_PS[(4)] = {INDEP_CPLX_PS, DELAY,
+ DELAY, NOT_EXIST};
+
+/* initialization values of ring buffer offsets for the 3 concatenated allpass
+ * filters (PS type decorrelator). */
+static const UCHAR stateBufferOffsetInit[(3)] = {0, 6, 14};
+
+static const REVBAND_FILT_TYPE REV_filtType_LD[(4)] = {
+ NOT_EXIST, COMMON_REAL, COMMON_REAL, COMMON_REAL};
+
+/*** mapping of hybrid bands to processing (/parameter?) bands ***/
+/* table for PS decorr running in legacy PS decoder. */
+static const UCHAR kernels_20_to_71_PS[(71) + 1] = {
+ 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14,
+ 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19};
+
+/*** mapping of processing (/parameter?) bands to hybrid bands ***/
+/* table for PS decorr running in legacy PS decoder. */
+static const UCHAR kernels_20_to_71_offset_PS[(20) + 1] = {
+ 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 21, 25, 30, 42, 71};
+
+static const UCHAR kernels_28_to_71[(71) + 1] = {
+ 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23,
+ 23, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26,
+ 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27};
+
+static const UCHAR kernels_28_to_71_offset[(28) + 1] = {
+ 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 21, 23, 25, 27, 30, 33, 37, 42, 48, 55, 71};
+
+/* LD-MPS defined in SAOC standart (mapping qmf -> param bands)*/
+static const UCHAR kernels_23_to_64[(64) + 1] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 14,
+ 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
+ 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+};
+
+static const UCHAR kernels_23_to_64_offset[(23) + 1] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 14, 16, 18, 20, 23, 26, 30, 35, 41, 48, 64};
+
+static inline int SpatialDecGetProcessingBand(int hybridBand,
+ const UCHAR *tab) {
+ return tab[hybridBand];
+}
+
+/* helper inline function */
+static inline int SpatialDecGetQmfBand(int paramBand, const UCHAR *tab) {
+ return (int)tab[paramBand];
+}
+
+#define DUCKER_MAX_NRG_SCALE (24)
+#define DUCKER_HEADROOM_BITS (3)
+
+#define FILTER_SF (2)
+
+#ifdef ARCH_PREFER_MULT_32x32
+#define FIXP_DUCK_GAIN FIXP_DBL
+#define FX_DBL2FX_DUCK_GAIN
+#define FL2FXCONST_DUCK FL2FXCONST_DBL
+#else
+#define FIXP_DUCK_GAIN FIXP_SGL
+#define FX_DBL2FX_DUCK_GAIN FX_DBL2FX_SGL
+#define FL2FXCONST_DUCK FL2FXCONST_SGL
+#endif
+#define PS_DUCK_PEAK_DECAY_FACTOR (0.765928338364649f)
+#define PS_DUCK_FILTER_COEFF (0.25f)
+#define DUCK_ALPHA_FDK FL2FXCONST_DUCK(DUCK_ALPHA)
+#define DUCK_ONE_MINUS_ALPHA_X4_FDK FL2FXCONST_DUCK(4.0f * (1.0f - DUCK_ALPHA))
+#define DUCK_GAMMA_FDK FL2FXCONST_DUCK(DUCK_GAMMA / 2)
+#define PS_DUCK_PEAK_DECAY_FACTOR_FDK FL2FXCONST_DUCK(PS_DUCK_PEAK_DECAY_FACTOR)
+#define PS_DUCK_FILTER_COEFF_FDK FL2FXCONST_DUCK(PS_DUCK_FILTER_COEFF)
+RAM_ALIGN
+const FIXP_STP DecorrPsCoeffsCplx[][4] = {
+ {STCP(0x5d6940eb, 0x5783153e), STCP(0xadcd41a8, 0x0e0373ed),
+ STCP(0xbad41f3e, 0x14fba045), STCP(0xc1eb6694, 0x0883227d)},
+ {STCP(0x5d6940eb, 0xa87ceac2), STCP(0xadcd41a8, 0xf1fc8c13),
+ STCP(0xbad41f3e, 0xeb045fbb), STCP(0xc1eb6694, 0xf77cdd83)},
+ {STCP(0xaec24162, 0x62e9d75b), STCP(0xb7169316, 0x28751048),
+ STCP(0xd224c0cc, 0x37e05050), STCP(0xc680864f, 0x18e88cba)},
+ {STCP(0xaec24162, 0x9d1628a5), STCP(0xb7169316, 0xd78aefb8),
+ STCP(0xd224c0cc, 0xc81fafb0), STCP(0xc680864f, 0xe7177346)},
+ {STCP(0x98012341, 0x4aa00ed1), STCP(0xc89ca1b2, 0xc1ab6bff),
+ STCP(0xf8ea394e, 0xb8106bf4), STCP(0xcf542d73, 0xd888b99b)},
+ {STCP(0x43b137b3, 0x6ca2ca40), STCP(0xe0649cc4, 0xb2d69cca),
+ STCP(0x22130c21, 0xc0405382), STCP(0xdbbf8fba, 0xcce3c7cc)},
+ {STCP(0x28fc4d71, 0x86bd3b87), STCP(0x09ccfeb9, 0xad319baf),
+ STCP(0x46e51f02, 0xf1e5ea55), STCP(0xf30d5e34, 0xc2b0e335)},
+ {STCP(0xc798f756, 0x72e73c7d), STCP(0x3b6c3c1e, 0xc580dc72),
+ STCP(0x2828a6ba, 0x3c1a14fb), STCP(0x14b733bb, 0xc4dcaae1)},
+ {STCP(0x46dcadd3, 0x956795c7), STCP(0x52f32fae, 0xf78048cd),
+ STCP(0xd7d75946, 0x3c1a14fb), STCP(0x306017cb, 0xd82c0a75)},
+ {STCP(0xabe197de, 0x607a675e), STCP(0x460cef6e, 0x2d3b264e),
+ STCP(0xb91ae0fe, 0xf1e5ea55), STCP(0x3e03e5e0, 0xf706590e)},
+ {STCP(0xb1b4f509, 0x9abcaf5f), STCP(0xfeb0b4be, 0x535fb8ba),
+ STCP(0x1ba96f8e, 0xbd37e6d8), STCP(0x30f6dbbb, 0x271a0743)},
+ {STCP(0xce75b52a, 0x89f9be61), STCP(0xb26e4dda, 0x101054c5),
+ STCP(0x1a475d2e, 0x3f714b19), STCP(0xf491f154, 0x3a6baf46)},
+ {STCP(0xee8fdfcb, 0x813181fa), STCP(0xe11e1a00, 0xbb9a6039),
+ STCP(0xc3e582f5, 0xe71ab533), STCP(0xc9eb35e2, 0x0ffd212a)},
+ {STCP(0x0fd7d92f, 0x80fbf975), STCP(0x38adccbc, 0xd571bbf4),
+ STCP(0x38c3aefc, 0xe87cc794), STCP(0xdafe8c3d, 0xd9b16100)},
+ {STCP(0x300d9e10, 0x895cc359), STCP(0x32b9843e, 0x2b52adcc),
+ STCP(0xe9ded9f4, 0x356ce0ed), STCP(0x0fdd5ca3, 0xd072932e)},
+ {STCP(0x4d03b4f8, 0x99c2dec3), STCP(0xe2bc8d94, 0x3744e195),
+ STCP(0xeb40ec55, 0xcde9ed22), STCP(0x2e67e231, 0xf893470b)},
+ {STCP(0x64c4deb3, 0xb112790f), STCP(0xc7b32682, 0xf099172d),
+ STCP(0x2ebf44cf, 0x135d014a), STCP(0x1a2bacd5, 0x23334254)},
+ {STCP(0x75b5f9aa, 0xcdb81e14), STCP(0x028d9bb1, 0xc9dc45b9),
+ STCP(0xd497893f, 0x11faeee9), STCP(0xee40ff71, 0x24a91b85)},
+ {STCP(0x7eb1cd81, 0xedc3feec), STCP(0x31491897, 0xf765f6d8),
+ STCP(0x1098dc89, 0xd7ee574e), STCP(0xda6b816d, 0x011f35cf)},
+ {STCP(0x7f1cde01, 0x0f0b7727), STCP(0x118ce49d, 0x2a5ecda4),
+ STCP(0x0f36ca28, 0x24badaa3), STCP(0xef2908a4, 0xe1ee3743)},
+ {STCP(0x76efee25, 0x2f4e8c3a), STCP(0xdde3be2a, 0x17f92215),
+ STCP(0xde9bf36c, 0xf22b4839), STCP(0x1128fc0c, 0xe5c95f5a)},
+ {STCP(0x66b87d65, 0x4c5ede42), STCP(0xe43f351a, 0xe6bf22dc),
+ STCP(0x1e0d3e85, 0xf38d5a9a), STCP(0x1c0f44a3, 0x02c92fe3)},
+ {STCP(0x4f8f36b7, 0x6445680f), STCP(0x10867ea2, 0xe3072740),
+ STCP(0xf4ef6cfa, 0x1ab67076), STCP(0x09562a8a, 0x1742bb8b)},
+ {STCP(0x3304f6ec, 0x7564812a), STCP(0x1be4f1a8, 0x0894d75a),
+ STCP(0xf6517f5b, 0xe8a05d98), STCP(0xf1bb0053, 0x10a78853)},
+ {STCP(0x1307b2c5, 0x7e93d532), STCP(0xfe098e27, 0x18f02a58),
+ STCP(0x1408d459, 0x084c6e44), STCP(0xedafe5bd, 0xfbc15b2e)},
+ {STCP(0xf1c111cd, 0x7f346c97), STCP(0xeb5ca6a0, 0x02efee93),
+ STCP(0xef4df9b6, 0x06ea5be4), STCP(0xfc149289, 0xf0d53ce4)},
+ {STCP(0xd1710001, 0x773b6beb), STCP(0xfa1aeb8c, 0xf06655ff),
+ STCP(0x05884983, 0xf2a4c7c5), STCP(0x094f13df, 0xf79c01bf)},
+ {STCP(0xb446be0b, 0x6732cfca), STCP(0x0a743752, 0xf9220dfa),
+ STCP(0x04263722, 0x0a046a2c), STCP(0x08ced80b, 0x0347e9c2)},
+ {STCP(0x9c3b1202, 0x503018a5), STCP(0x05fcf01a, 0x05cd8529),
+ STCP(0xf95263e2, 0xfd3bdb3f), STCP(0x00c68cf9, 0x0637cb7f)},
+ {STCP(0x8aee2710, 0x33c187ec), STCP(0xfdd253f8, 0x038e09b9),
+ STCP(0x0356ce0f, 0xfe9ded9f), STCP(0xfd6c3054, 0x01c8060a)}};
+
+const FIXP_DECORR DecorrNumeratorReal0_USAC
+ [MAX_DECORR_SEED_USAC][DECORR_FILTER_ORDER_BAND_0_USAC + 1] = {
+ {DECORR(0x05bf4880), DECORR(0x08321c00), DECORR(0xe9315ee0),
+ DECORR(0x07d9dd20), DECORR(0x02224994), DECORR(0x0009d200),
+ DECORR(0xf8a29358), DECORR(0xf4e310d0), DECORR(0xef901fc0),
+ DECORR(0xebda0460), DECORR(0x40000000)}};
+
+const FIXP_DECORR DecorrNumeratorReal1_USAC
+ [MAX_DECORR_SEED_USAC][DECORR_FILTER_ORDER_BAND_1_USAC + 1] = {
+ {DECORR(0xf82f8378), DECORR(0xfef588c2), DECORR(0x02eddbd8),
+ DECORR(0x041c2450), DECORR(0xf7edcd60), DECORR(0x07e29310),
+ DECORR(0xfa4ece48), DECORR(0xed9f8a20), DECORR(0x40000000)}};
+
+/* identical to MPS coeffs for reverb band 3: DecorrNumeratorReal3[0] */
+const FIXP_DECORR
+ DecorrNumeratorReal2_USAC[MAX_DECORR_SEED_USAC]
+ [DECORR_FILTER_ORDER_BAND_2_USAC + 1] = {
+ {DECORR(0x0248e8a8), DECORR(0xfde95838),
+ DECORR(0x084823c0), DECORR(0x40000000)}};
+
+const FIXP_DECORR
+ DecorrNumeratorReal3_USAC[MAX_DECORR_SEED_USAC]
+ [DECORR_FILTER_ORDER_BAND_3_USAC + 1] = {
+ {DECORR(0xff2b020c), DECORR(0x02393830),
+ DECORR(0x40000000)}};
+
+/* const FIXP_DECORR DecorrNumeratorReal0_LD[MAX_DECORR_SEED_LD][] does not
+ * exist */
+
+RAM_ALIGN
+const FIXP_DECORR DecorrNumeratorReal1_LD[MAX_DECORR_SEED_LD]
+ [DECORR_FILTER_ORDER_BAND_1_LD + 1] = {
+ {
+ DECORR(0xf310cb29),
+ DECORR(0x1932d745),
+ DECORR(0x0cc2d917),
+ DECORR(0xddde064e),
+ DECORR(0xf234a626),
+ DECORR(0x198551a6),
+ DECORR(0x17141b6a),
+ DECORR(0xf298803d),
+ DECORR(0xef98be92),
+ DECORR(0x09ea1706),
+ DECORR(0x28fbdff4),
+ DECORR(0x1a869eb9),
+ DECORR(0xdeefe147),
+ DECORR(0xcde2adda),
+ DECORR(0x13ddc619),
+ DECORR(0x40000000),
+ },
+ {
+ DECORR(0x041d7dbf),
+ DECORR(0x01b7309c),
+ DECORR(0xfb599834),
+ DECORR(0x092fc5ed),
+ DECORR(0xf2fd7c25),
+ DECORR(0xdd51e2eb),
+ DECORR(0xf62fe72b),
+ DECORR(0x0b15d588),
+ DECORR(0xf1f091a7),
+ DECORR(0xed1bbbfe),
+ DECORR(0x03526899),
+ DECORR(0x180cb256),
+ DECORR(0xecf1433d),
+ DECORR(0xf626ab95),
+ DECORR(0x197dd27e),
+ DECORR(0x40000000),
+ },
+ {
+ DECORR(0x157a786c),
+ DECORR(0x0028c98c),
+ DECORR(0xf5eff57b),
+ DECORR(0x11f7d04f),
+ DECORR(0xf390d28d),
+ DECORR(0x18947081),
+ DECORR(0xe5dc2319),
+ DECORR(0xf4cc0235),
+ DECORR(0x2394d47f),
+ DECORR(0xe069230e),
+ DECORR(0x03a1a773),
+ DECORR(0xfbc9b092),
+ DECORR(0x15a0173b),
+ DECORR(0x0e9ecdf0),
+ DECORR(0xd309b2c7),
+ DECORR(0x40000000),
+ },
+ {
+ DECORR(0xe0ce703b),
+ DECORR(0xe508b672),
+ DECORR(0xef362398),
+ DECORR(0xffe788ef),
+ DECORR(0x2fda3749),
+ DECORR(0x4671c0c6),
+ DECORR(0x3c003494),
+ DECORR(0x2387707c),
+ DECORR(0xd2107d2e),
+ DECORR(0xb3e47e08),
+ DECORR(0xacd0abca),
+ DECORR(0xc70791df),
+ DECORR(0x0b586e85),
+ DECORR(0x2f11cda7),
+ DECORR(0x3a4a210b),
+ DECORR(0x40000000),
+ },
+};
+
+RAM_ALIGN
+const FIXP_DECORR DecorrNumeratorReal2_LD[MAX_DECORR_SEED_LD]
+ [DECORR_FILTER_ORDER_BAND_2_LD + 1 +
+ DECORR_ZERO_PADDING] = {
+ {
+ DECORR(0xffb4a234),
+ DECORR(0x01ac71a2),
+ DECORR(0xf2bca010),
+ DECORR(0xfe3d7593),
+ DECORR(0x093e9976),
+ DECORR(0xf2c5f3f5),
+ DECORR(0x40000000),
+ },
+ {
+ DECORR(0xe303afb8),
+ DECORR(0xcd70c2bb),
+ DECORR(0xf1e2ad7e),
+ DECORR(0x0c8ffbe2),
+ DECORR(0x21f80abf),
+ DECORR(0x3d08410c),
+ DECORR(0x40000000),
+ },
+ {
+ DECORR(0xe26809d5),
+ DECORR(0x0efbcfa4),
+ DECORR(0x210c1a97),
+ DECORR(0xfe60af4e),
+ DECORR(0xeda01a51),
+ DECORR(0x00faf468),
+ DECORR(0x40000000),
+ },
+ {
+ DECORR(0x1edc5d64),
+ DECORR(0xe5b2e35c),
+ DECORR(0xe94b1c45),
+ DECORR(0x30a6f1e1),
+ DECORR(0xf04e52de),
+ DECORR(0xe30de45a),
+ DECORR(0x40000000),
+ },
+};
+
+RAM_ALIGN
+const FIXP_DECORR DecorrNumeratorReal3_LD[MAX_DECORR_SEED_LD]
+ [DECORR_FILTER_ORDER_BAND_3_LD + 1] = {
+ {
+ DECORR(0x0248e8a7),
+ DECORR(0xfde9583b),
+ DECORR(0x084823bb),
+ DECORR(0x40000000),
+ },
+ {
+ DECORR(0x1db22d0e),
+ DECORR(0xfc773992),
+ DECORR(0x0e819a74),
+ DECORR(0x40000000),
+ },
+ {
+ DECORR(0x0fcb923a),
+ DECORR(0x0154b7ff),
+ DECORR(0xe70cb647),
+ DECORR(0x40000000),
+ },
+ {
+ DECORR(0xe39f559b),
+ DECORR(0xe06dd6ca),
+ DECORR(0x19f71f71),
+ DECORR(0x40000000),
+ },
+};
+
+FIXP_DBL *getAddrDirectSignalMaxVal(HANDLE_DECORR_DEC self) {
+ return &(self->ducker.maxValDirectData);
+}
+
+static INT DecorrFilterInit(DECORR_FILTER_INSTANCE *const self,
+ FIXP_MPS *pStateBufferCplx,
+ FIXP_DBL *pDelayBufferCplx, INT *offsetStateBuffer,
+ INT *offsetDelayBuffer, INT const decorr_seed,
+ INT const reverb_band, INT const useFractDelay,
+ INT const noSampleDelay, INT const filterOrder,
+ FDK_DECORR_TYPE const decorrType) {
+ INT errorCode = 0;
+ switch (decorrType) {
+ case DECORR_USAC:
+ if (useFractDelay) {
+ return 1;
+ } else {
+ FDK_ASSERT(decorr_seed == 0);
+
+ switch (reverb_band) {
+ case 0:
+ self->numeratorReal = DecorrNumeratorReal0_USAC[decorr_seed];
+ break;
+ case 1:
+ self->numeratorReal = DecorrNumeratorReal1_USAC[decorr_seed];
+ break;
+ case 2:
+ self->numeratorReal = DecorrNumeratorReal2_USAC[decorr_seed];
+ break;
+ case 3:
+ self->numeratorReal = DecorrNumeratorReal3_USAC[decorr_seed];
+ break;
+ }
+ }
+ break;
+ case DECORR_LD:
+ FDK_ASSERT(decorr_seed < MAX_DECORR_SEED_LD);
+ switch (reverb_band) {
+ case 0:
+ self->numeratorReal = NULL;
+ break;
+ case 1:
+ self->numeratorReal = DecorrNumeratorReal1_LD[decorr_seed];
+ break;
+ case 2:
+ self->numeratorReal = DecorrNumeratorReal2_LD[decorr_seed];
+ break;
+ case 3:
+ self->numeratorReal = DecorrNumeratorReal3_LD[decorr_seed];
+ break;
+ }
+ break;
+ default:
+ return 1;
+ }
+
+ self->stateCplx = pStateBufferCplx + (*offsetStateBuffer);
+ *offsetStateBuffer += 2 * filterOrder;
+ self->DelayBufferCplx = pDelayBufferCplx + (*offsetDelayBuffer);
+ *offsetDelayBuffer += 2 * noSampleDelay;
+
+ return errorCode;
+}
+
+/*******************************************************************************
+*******************************************************************************/
+static INT DecorrFilterInitPS(DECORR_FILTER_INSTANCE *const self,
+ FIXP_MPS *pStateBufferCplx,
+ FIXP_DBL *pDelayBufferCplx,
+ INT *offsetStateBuffer, INT *offsetDelayBuffer,
+ INT const hybridBand, INT const reverbBand,
+ INT const noSampleDelay) {
+ INT errorCode = 0;
+
+ if (reverbBand == 0) {
+ self->coeffsPacked = DecorrPsCoeffsCplx[hybridBand];
+
+ self->stateCplx = pStateBufferCplx + (*offsetStateBuffer);
+ *offsetStateBuffer += 2 * DECORR_FILTER_ORDER_PS;
+ }
+
+ self->DelayBufferCplx = pDelayBufferCplx + (*offsetDelayBuffer);
+ *offsetDelayBuffer += 2 * noSampleDelay;
+
+ return errorCode;
+}
+
+LNK_SECTION_CODE_L1
+static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
+ FIXP_DBL *dataRealIn, FIXP_DBL *dataImagIn,
+ FIXP_DBL *dataRealOut, FIXP_DBL *dataImagOut,
+ INT start, INT stop,
+ INT reverbBandNoSampleDelay,
+ INT reverbBandDelayBufferIndex) {
+ INT i;
+ INT offset = 2 * reverbBandNoSampleDelay;
+ FIXP_MPS *pDelayBuffer =
+ &filter[start].DelayBufferCplx[reverbBandDelayBufferIndex];
+
+ /* Memory for the delayline has been allocated in a consecutive order, so we
+ can address from filter to filter with a constant length.
+ Be aware that real and imaginary part of the delayline are stored in
+ interleaved order.
+ */
+ if (dataImagIn == NULL) {
+ for (i = start; i < stop; i++) {
+ FIXP_DBL tmp;
+
+ tmp = *pDelayBuffer;
+ *pDelayBuffer = dataRealIn[i];
+ dataRealOut[i] = tmp;
+ pDelayBuffer += offset;
+ }
+ } else {
+ if ((i = stop - start) != 0) {
+ dataRealIn += start;
+ dataImagIn += start;
+ dataRealOut += start;
+ dataImagOut += start;
+#ifdef FUNCTION_DecorrFilterApplyPASS_func1
+ DecorrFilterApplyPASS_func1(i, dataRealIn, dataImagIn, dataRealOut,
+ dataImagOut, pDelayBuffer, offset);
+#else
+ do {
+ FIXP_DBL delay_re, delay_im, real, imag;
+
+ real = *dataRealIn++;
+ imag = *dataImagIn++;
+ delay_re = pDelayBuffer[0];
+ delay_im = pDelayBuffer[1];
+ pDelayBuffer[0] = real;
+ pDelayBuffer[1] = imag;
+ *dataRealOut++ = delay_re;
+ *dataImagOut++ = delay_im;
+ pDelayBuffer += offset;
+ } while (--i != 0);
+#endif
+ }
+ }
+
+ return (INT)0;
+}
+
+#ifndef FUNCTION_DecorrFilterApplyREAL
+LNK_SECTION_CODE_L1
+static INT DecorrFilterApplyREAL(DECORR_FILTER_INSTANCE const filter[],
+ FIXP_DBL *dataRealIn, FIXP_DBL *dataImagIn,
+ FIXP_DBL *dataRealOut, FIXP_DBL *dataImagOut,
+ INT start, INT stop, INT reverbFilterOrder,
+ INT reverbBandNoSampleDelay,
+ INT reverbBandDelayBufferIndex) {
+ INT i, j;
+ FIXP_DBL xReal, xImag, yReal, yImag;
+
+ const FIXP_DECORR *pFilter = filter[start].numeratorReal;
+
+ INT offsetDelayBuffer = (2 * reverbBandNoSampleDelay) - 1;
+ FIXP_MPS *pDelayBuffer =
+ &filter[start].DelayBufferCplx[reverbBandDelayBufferIndex];
+
+ INT offsetStates = 2 * reverbFilterOrder;
+ FIXP_DBL *pStates = filter[start].stateCplx;
+
+ /* Memory for the delayline has been allocated in a consecutive order, so we
+ can address from filter to filter with a constant length. The same is valid
+ for the states.
+ Be aware that real and imaginary part of the delayline and the states are
+ stored in interleaved order.
+ All filter in a reverb band have the same filter coefficients.
+ Exploit symmetry: numeratorReal[i] =
+ denominatorReal[reverbFilterLength-1-i] Do not accumulate the highest
+ states which are always zero.
+ */
+ if (reverbFilterOrder == 2) {
+ FIXP_DECORR nFilt0L, nFilt0H;
+
+ nFilt0L = pFilter[0];
+ nFilt0H = pFilter[1];
+
+ for (i = start; i < stop; i++) {
+ xReal = *pDelayBuffer;
+ *pDelayBuffer = dataRealIn[i];
+ pDelayBuffer++;
+
+ xImag = *pDelayBuffer;
+ *pDelayBuffer = dataImagIn[i];
+ pDelayBuffer += offsetDelayBuffer;
+
+ yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << FILTER_SF;
+ yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << FILTER_SF;
+
+ dataRealOut[i] = yReal;
+ dataImagOut[i] = yImag;
+
+ pStates[0] =
+ pStates[2] + fMultDiv2(xReal, nFilt0H) - fMultDiv2(yReal, nFilt0H);
+ pStates[1] =
+ pStates[3] + fMultDiv2(xImag, nFilt0H) - fMultDiv2(yImag, nFilt0H);
+ pStates[2] = (xReal >> FILTER_SF) - fMultDiv2(yReal, nFilt0L);
+ pStates[3] = (xImag >> FILTER_SF) - fMultDiv2(yImag, nFilt0L);
+ pStates += offsetStates;
+ }
+ } else if (reverbFilterOrder == 3) {
+ FIXP_DECORR nFilt0L, nFilt0H, nFilt1L;
+
+ nFilt0L = pFilter[0];
+ nFilt0H = pFilter[1];
+ nFilt1L = pFilter[2];
+
+ for (i = start; i < stop; i++) {
+ xReal = *pDelayBuffer;
+ *pDelayBuffer = dataRealIn[i];
+ pDelayBuffer++;
+
+ xImag = *pDelayBuffer;
+ *pDelayBuffer = dataImagIn[i];
+ pDelayBuffer += offsetDelayBuffer;
+
+ yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << FILTER_SF;
+ yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << FILTER_SF;
+
+ dataRealOut[i] = yReal;
+ dataImagOut[i] = yImag;
+
+ pStates[0] =
+ pStates[2] + fMultDiv2(xReal, nFilt0H) - fMultDiv2(yReal, nFilt1L);
+ pStates[1] =
+ pStates[3] + fMultDiv2(xImag, nFilt0H) - fMultDiv2(yImag, nFilt1L);
+ pStates[2] =
+ pStates[4] + fMultDiv2(xReal, nFilt1L) - fMultDiv2(yReal, nFilt0H);
+ pStates[3] =
+ pStates[5] + fMultDiv2(xImag, nFilt1L) - fMultDiv2(yImag, nFilt0H);
+ pStates[4] = (xReal >> FILTER_SF) - fMultDiv2(yReal, nFilt0L);
+ pStates[5] = (xImag >> FILTER_SF) - fMultDiv2(yImag, nFilt0L);
+ pStates += offsetStates;
+ }
+ } else if (reverbFilterOrder == 6) {
+ FIXP_DECORR nFilt0L, nFilt0H, nFilt1L, nFilt1H, nFilt2L, nFilt2H;
+
+ nFilt0L = pFilter[0];
+ nFilt0H = pFilter[1];
+ nFilt1L = pFilter[2];
+ nFilt1H = pFilter[3];
+ nFilt2L = pFilter[4];
+ nFilt2H = pFilter[5];
+
+ for (i = start; i < stop; i++) {
+ xReal = *pDelayBuffer;
+ *pDelayBuffer = dataRealIn[i];
+ pDelayBuffer++;
+
+ xImag = *pDelayBuffer;
+ *pDelayBuffer = dataImagIn[i];
+ pDelayBuffer += offsetDelayBuffer;
+
+ yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << FILTER_SF;
+ yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << FILTER_SF;
+ dataRealOut[i] = yReal;
+ dataImagOut[i] = yImag;
+
+ pStates[0] =
+ pStates[2] + fMultDiv2(xReal, nFilt0H) - fMultDiv2(yReal, nFilt2H);
+ pStates[1] =
+ pStates[3] + fMultDiv2(xImag, nFilt0H) - fMultDiv2(yImag, nFilt2H);
+ pStates[2] =
+ pStates[4] + fMultDiv2(xReal, nFilt1L) - fMultDiv2(yReal, nFilt2L);
+ pStates[3] =
+ pStates[5] + fMultDiv2(xImag, nFilt1L) - fMultDiv2(yImag, nFilt2L);
+ pStates[4] =
+ pStates[6] + fMultDiv2(xReal, nFilt1H) - fMultDiv2(yReal, nFilt1H);
+ pStates[5] =
+ pStates[7] + fMultDiv2(xImag, nFilt1H) - fMultDiv2(yImag, nFilt1H);
+ pStates[6] =
+ pStates[8] + fMultDiv2(xReal, nFilt2L) - fMultDiv2(yReal, nFilt1L);
+ pStates[7] =
+ pStates[9] + fMultDiv2(xImag, nFilt2L) - fMultDiv2(yImag, nFilt1L);
+ pStates[8] =
+ pStates[10] + fMultDiv2(xReal, nFilt2H) - fMultDiv2(yReal, nFilt0H);
+ pStates[9] =
+ pStates[11] + fMultDiv2(xImag, nFilt2H) - fMultDiv2(yImag, nFilt0H);
+ pStates[10] = (xReal >> FILTER_SF) - fMultDiv2(yReal, nFilt0L);
+ pStates[11] = (xImag >> FILTER_SF) - fMultDiv2(yImag, nFilt0L);
+ pStates += offsetStates;
+ }
+ } else {
+ FIXP_DECORR nFilt0L, nFilt0H;
+ for (i = start; i < stop; i++) {
+ xReal = *pDelayBuffer;
+ *pDelayBuffer = dataRealIn[i];
+ pDelayBuffer++;
+
+ xImag = *pDelayBuffer;
+ *pDelayBuffer = dataImagIn[i];
+ pDelayBuffer += offsetDelayBuffer;
+
+ nFilt0L = pFilter[0];
+ yReal = (pStates[0] + fMultDiv2(xReal, nFilt0L)) << 2;
+ yImag = (pStates[1] + fMultDiv2(xImag, nFilt0L)) << 2;
+ dataRealOut[i] = yReal;
+ dataImagOut[i] = yImag;
+
+ for (j = 1; j < reverbFilterOrder; j++) {
+ nFilt0L = pFilter[j];
+ nFilt0H = pFilter[reverbFilterOrder - j];
+ pStates[2 * j - 2] = pStates[2 * j] + fMultDiv2(xReal, nFilt0L) -
+ fMultDiv2(yReal, nFilt0H);
+ pStates[2 * j - 1] = pStates[2 * j + 1] + fMultDiv2(xImag, nFilt0L) -
+ fMultDiv2(yImag, nFilt0H);
+ }
+ nFilt0L = pFilter[j];
+ nFilt0H = pFilter[reverbFilterOrder - j];
+ pStates[2 * j - 2] =
+ fMultDiv2(xReal, nFilt0L) - fMultDiv2(yReal, nFilt0H);
+ pStates[2 * j - 1] =
+ fMultDiv2(xImag, nFilt0L) - fMultDiv2(yImag, nFilt0H);
+
+ pStates += offsetStates;
+ }
+ }
+
+ return (INT)0;
+}
+#endif /* #ifndef FUNCTION_DecorrFilterApplyREAL */
+
+#ifndef FUNCTION_DecorrFilterApplyCPLX_PS
+LNK_SECTION_CODE_L1
+static INT DecorrFilterApplyCPLX_PS(
+ DECORR_FILTER_INSTANCE const filter[], FIXP_DBL *dataRealIn,
+ FIXP_DBL *dataImagIn, FIXP_DBL *dataRealOut, FIXP_DBL *dataImagOut,
+ INT start, INT stop, INT reverbFilterOrder, INT reverbBandNoSampleDelay,
+ INT reverbBandDelayBufferIndex, UCHAR *stateBufferOffset) {
+ /* r = real, j = imaginary */
+ FIXP_DBL r_data_a, j_data_a, r_data_b, j_data_b, r_stage_mult, j_stage_mult;
+ FIXP_STP rj_coeff;
+
+ /* get pointer to current position in input delay buffer of filter with
+ * starting-index */
+ FIXP_DBL *pDelayBuffer =
+ &filter[start].DelayBufferCplx[reverbBandDelayBufferIndex]; /* increases
+ by 2 every
+ other call
+ of this
+ function */
+ /* determine the increment for this pointer to get to the correct position in
+ * the delay buffer of the next filter */
+ INT offsetDelayBuffer = (2 * reverbBandNoSampleDelay) - 1;
+
+ /* pointer to current position in state buffer */
+ FIXP_DBL *pStates = filter[start].stateCplx;
+ INT pStatesIncrement = 2 * reverbFilterOrder;
+
+ /* stateBufferOffset-pointers */
+ FIXP_DBL *pStateBufferOffset0 = pStates + stateBufferOffset[0];
+ FIXP_DBL *pStateBufferOffset1 = pStates + stateBufferOffset[1];
+ FIXP_DBL *pStateBufferOffset2 = pStates + stateBufferOffset[2];
+
+ /* traverse all hybrid-bands inbetween start- and stop-index */
+ for (int i = start; i < stop; i++) {
+ /* 1. input delay (real/imaginary values interleaved) */
+
+ /* load delayed real input value */
+ r_data_a = *pDelayBuffer;
+ /* store incoming real data value to delay buffer and increment pointer */
+ *pDelayBuffer++ = dataRealIn[i];
+
+ /* load delayed imaginary input value */
+ j_data_a = *pDelayBuffer;
+ /* store incoming imaginary data value to delay buffer */
+ *pDelayBuffer = dataImagIn[i];
+ /* increase delay buffer by offset */
+ pDelayBuffer += offsetDelayBuffer;
+
+ /* 2. Phi(k)-stage */
+
+ /* create pointer to coefficient table (real and imaginary coefficients
+ * interleaved) */
+ const FIXP_STP *pCoeffs = filter[i].coeffsPacked;
+
+ /* the first two entries of the coefficient table are the
+ * Phi(k)-multiplicants */
+ rj_coeff = *pCoeffs++;
+ /* multiply value from input delay buffer by looked-up values */
+ cplxMultDiv2(&r_data_b, &j_data_b, r_data_a, j_data_a, rj_coeff);
+
+ /* 3. process all three filter stages */
+
+ /* stage 0 */
+
+ /* get coefficients from lookup table */
+ rj_coeff = *pCoeffs++;
+
+ /* multiply output of last stage by coefficient */
+ cplxMultDiv2(&r_stage_mult, &j_stage_mult, r_data_b, j_data_b, rj_coeff);
+ r_stage_mult <<= 1;
+ j_stage_mult <<= 1;
+
+ /* read and add value from state buffer (this is the input for the next
+ * stage) */
+ r_data_a = r_stage_mult + pStateBufferOffset0[0];
+ j_data_a = j_stage_mult + pStateBufferOffset0[1];
+
+ /* negate r_data_a to perform multiplication with complex conjugate of
+ * rj_coeff */
+ cplxMultDiv2(&r_stage_mult, &j_stage_mult, -r_data_a, j_data_a, rj_coeff);
+
+ /* add stage input to shifted result */
+ r_stage_mult = r_data_b + (r_stage_mult << 1);
+ j_stage_mult = j_data_b - (j_stage_mult << 1);
+
+ /* store result to state buffer */
+ pStateBufferOffset0[0] = r_stage_mult;
+ pStateBufferOffset0[1] = j_stage_mult;
+ pStateBufferOffset0 += pStatesIncrement;
+
+ /* stage 1 */
+
+ /* get coefficients from lookup table */
+ rj_coeff = *pCoeffs++;
+
+ /* multiply output of last stage by coefficient */
+ cplxMultDiv2(&r_stage_mult, &j_stage_mult, r_data_a, j_data_a, rj_coeff);
+ r_stage_mult <<= 1;
+ j_stage_mult <<= 1;
+
+ /* read and add value from state buffer (this is the input for the next
+ * stage) */
+ r_data_b = r_stage_mult + pStateBufferOffset1[0];
+ j_data_b = j_stage_mult + pStateBufferOffset1[1];
+
+ /* negate r_data_b to perform multiplication with complex conjugate of
+ * rj_coeff */
+ cplxMultDiv2(&r_stage_mult, &j_stage_mult, -r_data_b, j_data_b, rj_coeff);
+
+ /* add stage input to shifted result */
+ r_stage_mult = r_data_a + (r_stage_mult << 1);
+ j_stage_mult = j_data_a - (j_stage_mult << 1);
+
+ /* store result to state buffer */
+ pStateBufferOffset1[0] = r_stage_mult;
+ pStateBufferOffset1[1] = j_stage_mult;
+ pStateBufferOffset1 += pStatesIncrement;
+
+ /* stage 2 */
+
+ /* get coefficients from lookup table */
+ rj_coeff = *pCoeffs++;
+
+ /* multiply output of last stage by coefficient */
+ cplxMultDiv2(&r_stage_mult, &j_stage_mult, r_data_b, j_data_b, rj_coeff);
+ r_stage_mult <<= 1;
+ j_stage_mult <<= 1;
+
+ /* read and add value from state buffer (this is the input for the next
+ * stage) */
+ r_data_a = r_stage_mult + pStateBufferOffset2[0];
+ j_data_a = j_stage_mult + pStateBufferOffset2[1];
+
+ /* negate r_data_a to perform multiplication with complex conjugate of
+ * rj_coeff */
+ cplxMultDiv2(&r_stage_mult, &j_stage_mult, -r_data_a, j_data_a, rj_coeff);
+
+ /* add stage input to shifted result */
+ r_stage_mult = r_data_b + (r_stage_mult << 1);
+ j_stage_mult = j_data_b - (j_stage_mult << 1);
+
+ /* store result to state buffer */
+ pStateBufferOffset2[0] = r_stage_mult;
+ pStateBufferOffset2[1] = j_stage_mult;
+ pStateBufferOffset2 += pStatesIncrement;
+
+ /* write filter output */
+ dataRealOut[i] = r_data_a << 1;
+ dataImagOut[i] = j_data_a << 1;
+
+ } /* end of band/filter loop (outer loop) */
+
+ /* update stateBufferOffset with respect to ring buffer boundaries */
+ if (stateBufferOffset[0] == 4)
+ stateBufferOffset[0] = 0;
+ else
+ stateBufferOffset[0] += 2;
+
+ if (stateBufferOffset[1] == 12)
+ stateBufferOffset[1] = 6;
+ else
+ stateBufferOffset[1] += 2;
+
+ if (stateBufferOffset[2] == 22)
+ stateBufferOffset[2] = 14;
+ else
+ stateBufferOffset[2] += 2;
+
+ return (INT)0;
+}
+
+#endif /* FUNCTION_DecorrFilterApplyCPLX_PS */
+
+/*******************************************************************************
+*******************************************************************************/
+static INT DuckerInit(DUCKER_INSTANCE *const self, int const hybridBands,
+ int partiallyComplex, const FDK_DUCKER_TYPE duckerType,
+ const int nParamBands, int initStatesFlag) {
+ INT errorCode = 0;
+
+ if (self) {
+ switch (nParamBands) {
+ case (20):
+ FDK_ASSERT(hybridBands == 71);
+ self->mapHybBands2ProcBands = kernels_20_to_71_PS;
+ self->mapProcBands2HybBands = kernels_20_to_71_offset_PS;
+ self->parameterBands = (20);
+ break;
+ case (28):
+
+ self->mapHybBands2ProcBands = kernels_28_to_71;
+ self->mapProcBands2HybBands = kernels_28_to_71_offset;
+ self->parameterBands = (28);
+ break;
+ case (23):
+ FDK_ASSERT(hybridBands == 64 || hybridBands == 32);
+ self->mapHybBands2ProcBands = kernels_23_to_64;
+ self->mapProcBands2HybBands = kernels_23_to_64_offset;
+ self->parameterBands = (23);
+ break;
+ default:
+ return 1;
+ }
+ self->qs_next = &self->mapProcBands2HybBands[1];
+
+ self->maxValDirectData = FL2FXCONST_DBL(-1.0f);
+ self->maxValReverbData = FL2FXCONST_DBL(-1.0f);
+ self->scaleDirectNrg = 2 * DUCKER_MAX_NRG_SCALE;
+ self->scaleReverbNrg = 2 * DUCKER_MAX_NRG_SCALE;
+ self->scaleSmoothDirRevNrg = 2 * DUCKER_MAX_NRG_SCALE;
+ self->headroomSmoothDirRevNrg = 2 * DUCKER_MAX_NRG_SCALE;
+ self->hybridBands = hybridBands;
+ self->partiallyComplex = partiallyComplex;
+
+ if (initStatesFlag && (duckerType == DUCKER_PS)) {
+ int pb;
+ for (pb = 0; pb < self->parameterBands; pb++) {
+ self->SmoothDirRevNrg[pb] = (FIXP_MPS)0;
+ }
+ }
+ } else
+ errorCode = 1;
+
+ return errorCode;
+}
+
+ /*******************************************************************************
+ *******************************************************************************/
+
+#ifndef FUNCTION_DuckerCalcEnergy
+static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
+ FIXP_DBL const inputReal[(71)],
+ FIXP_DBL const inputImag[(71)],
+ FIXP_DBL energy[(28)], FIXP_DBL inputMaxVal,
+ SCHAR *nrgScale, int mode, /* 1:(ps) 0:(else) */
+ int startHybBand) {
+ INT err = 0;
+ int qs, maxHybBand;
+ int maxHybridBand = self->hybridBands - 1;
+
+ maxHybBand = maxHybridBand;
+
+ FDKmemclear(energy, (28) * sizeof(FIXP_DBL));
+
+ if (mode == 1) {
+ int pb;
+ int clz;
+ FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
+
+ if (maxVal == FL2FXCONST_DBL(-1.0f)) {
+#ifdef FUNCTION_DuckerCalcEnergy_func2
+ maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
+ maxHybBand, maxHybridBand);
+#else
+ FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
+ for (qs = startHybBand; qs <= maxHybBand; qs++) {
+ localMaxVal |= fAbs(inputReal[qs]);
+ localMaxVal |= fAbs(inputImag[qs]);
+ }
+ for (; qs <= maxHybridBand; qs++) {
+ localMaxVal |= fAbs(inputReal[qs]);
+ }
+ maxVal = localMaxVal;
+#endif
+ }
+
+ clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
+ clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
+ *nrgScale = (SCHAR)clz << 1;
+
+ /* Initialize pb since it would stay uninitialized for the case startHybBand
+ * > maxHybBand. */
+ pb = SpatialDecGetProcessingBand(maxHybBand, self->mapHybBands2ProcBands);
+ for (qs = startHybBand; qs <= maxHybBand; qs++) {
+ pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
+ energy[pb] =
+ fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
+ fPow2Div2(inputImag[qs] << clz));
+ }
+ pb++;
+
+ for (; pb <= SpatialDecGetProcessingBand(maxHybridBand,
+ self->mapHybBands2ProcBands);
+ pb++) {
+ FDK_ASSERT(pb != SpatialDecGetProcessingBand(
+ qs - 1, self->mapHybBands2ProcBands));
+ int qs_next;
+ FIXP_DBL nrg = 0;
+ qs_next = (int)self->qs_next[pb];
+ for (; qs < qs_next; qs++) {
+ nrg = fAddSaturate(nrg, fPow2Div2(inputReal[qs] << clz));
+ }
+ energy[pb] = nrg;
+ }
+ } else {
+ int clz;
+ FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
+
+ maxVal = inputMaxVal;
+
+ if (maxVal == FL2FXCONST_DBL(-1.0f)) {
+#ifdef FUNCTION_DuckerCalcEnergy_func2
+ maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
+ maxHybBand, maxHybridBand);
+#else
+ FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
+ for (qs = startHybBand; qs <= maxHybBand; qs++) {
+ localMaxVal |= fAbs(inputReal[qs]);
+ localMaxVal |= fAbs(inputImag[qs]);
+ }
+ for (; qs <= maxHybridBand; qs++) {
+ localMaxVal |= fAbs(inputReal[qs]);
+ }
+ maxVal = localMaxVal;
+#endif
+ }
+
+ clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
+ clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
+ *nrgScale = (SCHAR)clz << 1;
+
+#ifdef FUNCTION_DuckerCalcEnergy_func4
+ DuckerCalcEnergy_func4(inputReal, inputImag, energy,
+ self->mapHybBands2ProcBands, clz, startHybBand,
+ maxHybBand, maxHybridBand);
+#else
+ for (qs = startHybBand; qs <= maxHybBand; qs++) {
+ int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
+ energy[pb] =
+ fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
+ fPow2Div2(inputImag[qs] << clz));
+ }
+
+ for (; qs <= maxHybridBand; qs++) {
+ int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
+ energy[pb] = fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz));
+ }
+#endif /* FUNCTION_DuckerCalcEnergy_func4 */
+ }
+
+ {
+ /* Catch overflows which have been observed in erred bitstreams to avoid
+ * assertion failures later. */
+ int pb;
+ for (pb = 0; pb < (28); pb++) {
+ energy[pb] = (FIXP_DBL)((LONG)energy[pb] & (LONG)MAXVAL_DBL);
+ }
+ }
+ return err;
+}
+#endif /* #ifndef FUNCTION_DuckerCalcEnergy */
+
+LNK_SECTION_CODE_L1
+static INT DuckerApply(DUCKER_INSTANCE *const self,
+ FIXP_DBL const directNrg[(28)],
+ FIXP_DBL outputReal[(71)], FIXP_DBL outputImag[(71)],
+ int startHybBand) {
+ INT err = 0;
+ int qs = startHybBand;
+ int qs_next = 0;
+ int pb = 0;
+ int startParamBand = 0;
+ int hybBands;
+ int hybridBands = self->hybridBands;
+
+ C_ALLOC_SCRATCH_START(reverbNrg, FIXP_DBL, (28));
+
+ FIXP_DBL *smoothDirRevNrg = &self->SmoothDirRevNrg[0];
+ FIXP_DUCK_GAIN duckGain = 0;
+
+ int doScaleNrg = 0;
+ int scaleDirectNrg = 0;
+ int scaleReverbNrg = 0;
+ int scaleSmoothDirRevNrg = 0;
+ FIXP_DBL maxDirRevNrg = FL2FXCONST_DBL(0.0);
+
+ hybBands = hybridBands;
+
+ startParamBand =
+ SpatialDecGetProcessingBand(startHybBand, self->mapHybBands2ProcBands);
+
+ DuckerCalcEnergy(self, outputReal, outputImag, reverbNrg,
+ self->maxValReverbData, &(self->scaleReverbNrg), 0,
+ startHybBand);
+
+ if ((self->scaleDirectNrg != self->scaleReverbNrg) ||
+ (self->scaleDirectNrg != self->scaleSmoothDirRevNrg) ||
+ (self->headroomSmoothDirRevNrg == 0)) {
+ int scale;
+
+ scale = fixMin(self->scaleDirectNrg, self->scaleSmoothDirRevNrg +
+ self->headroomSmoothDirRevNrg - 1);
+ scale = fixMin(scale, self->scaleReverbNrg);
+
+ scaleDirectNrg = fMax(fMin(self->scaleDirectNrg - scale, (DFRACT_BITS - 1)),
+ -(DFRACT_BITS - 1));
+ scaleReverbNrg = fMax(fMin(self->scaleReverbNrg - scale, (DFRACT_BITS - 1)),
+ -(DFRACT_BITS - 1));
+ scaleSmoothDirRevNrg =
+ fMax(fMin(self->scaleSmoothDirRevNrg - scale, (DFRACT_BITS - 1)),
+ -(DFRACT_BITS - 1));
+
+ self->scaleSmoothDirRevNrg = (SCHAR)scale;
+
+ doScaleNrg = 1;
+ }
+ for (pb = startParamBand; pb < self->parameterBands; pb++) {
+ FIXP_DBL tmp1;
+ FIXP_DBL tmp2;
+ INT s;
+
+ /* smoothDirRevNrg[2*pb ] = fMult(smoothDirRevNrg[2*pb ],DUCK_ALPHA_FDK) +
+ fMultDiv2(directNrg[pb],DUCK_ONE_MINUS_ALPHA_X4_FDK);
+ smoothDirRevNrg[2*pb+1] = fMult(smoothDirRevNrg[2*pb+1],DUCK_ALPHA_FDK) +
+ fMultDiv2(reverbNrg[pb],DUCK_ONE_MINUS_ALPHA_X4_FDK); tmp1 =
+ fMult(smoothDirRevNrg[2*pb],DUCK_GAMMA_FDK); tmp2 =
+ smoothDirRevNrg[2*pb+1] >> 1;
+ */
+ tmp1 = smoothDirRevNrg[2 * pb + 0];
+ tmp2 = smoothDirRevNrg[2 * pb + 1];
+ tmp1 = fMult(tmp1, DUCK_ALPHA_FDK);
+ tmp2 = fMult(tmp2, DUCK_ALPHA_FDK);
+
+ if (doScaleNrg) {
+ int scaleSmoothDirRevNrg_asExponent = -scaleSmoothDirRevNrg;
+
+ tmp1 = scaleValue(tmp1, scaleSmoothDirRevNrg_asExponent);
+ tmp2 = scaleValue(tmp2, scaleSmoothDirRevNrg_asExponent);
+ tmp1 = fMultAddDiv2(tmp1, scaleValue(directNrg[pb], -scaleDirectNrg),
+ DUCK_ONE_MINUS_ALPHA_X4_FDK);
+ tmp2 = fMultAddDiv2(tmp2, scaleValue(reverbNrg[pb], -scaleReverbNrg),
+ DUCK_ONE_MINUS_ALPHA_X4_FDK);
+ } else {
+ tmp1 = fMultAddDiv2(tmp1, directNrg[pb], DUCK_ONE_MINUS_ALPHA_X4_FDK);
+ tmp2 = fMultAddDiv2(tmp2, reverbNrg[pb], DUCK_ONE_MINUS_ALPHA_X4_FDK);
+ }
+
+ smoothDirRevNrg[2 * pb] = tmp1;
+ smoothDirRevNrg[2 * pb + 1] = tmp2;
+
+ maxDirRevNrg |= fAbs(tmp1);
+ maxDirRevNrg |= fAbs(tmp2);
+
+ tmp1 = fMult(tmp1, DUCK_GAMMA_FDK);
+ tmp2 = tmp2 >> 1;
+
+ qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
+
+ if (tmp2 > tmp1) { /* true for about 20% */
+ /* gain smaller than 1.0 */
+ tmp1 = sqrtFixp(tmp1);
+ tmp2 = invSqrtNorm2(tmp2, &s);
+ duckGain = FX_DBL2FX_DUCK_GAIN(fMultDiv2(tmp1, tmp2) << s);
+ } else { /* true for about 80 % */
+ tmp2 = smoothDirRevNrg[2 * pb] >> 1;
+ tmp1 = fMult(smoothDirRevNrg[2 * pb + 1], DUCK_GAMMA_FDK);
+ if (tmp2 > tmp1) { /* true for about 20% */
+ if (tmp1 <= (tmp2 >> 2)) {
+ /* limit gain to 2.0 */
+ if (qs < hybBands) {
+ for (; qs < qs_next; qs++) {
+ outputReal[qs] = outputReal[qs] << 1;
+ outputImag[qs] = outputImag[qs] << 1;
+ }
+ } else {
+ for (; qs < qs_next; qs++) {
+ outputReal[qs] = outputReal[qs] << 1;
+ }
+ }
+ /* skip general gain*output section */
+ continue;
+ } else {
+ /* gain from 1.0 to 2.0 */
+ tmp2 = sqrtFixp(tmp2 >> 2);
+ tmp1 = invSqrtNorm2(tmp1, &s);
+ duckGain = FX_DBL2FX_DUCK_GAIN(fMult(tmp1, tmp2) << s);
+ }
+ } else { /* true for about 60% */
+ /* gain = 1.0; output does not change; update qs index */
+ qs = qs_next;
+ continue;
+ }
+ }
+
+#ifdef FUNCTION_DuckerApply_func1
+ qs = DuckerApply_func1(qs, hybBands, qs_next, outputReal, outputImag,
+ duckGain);
+#else
+ /* general gain*output section */
+ if (qs < hybBands) { /* true for about 39% */
+ for (; qs < qs_next; qs++) { /* runs about 2 times */
+ outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
+ outputImag[qs] = fMultDiv2(outputImag[qs], duckGain) << 2;
+ }
+ } else {
+ for (; qs < qs_next; qs++) {
+ outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
+ }
+ }
+#endif
+ } /* pb */
+
+ self->headroomSmoothDirRevNrg =
+ (SCHAR)fixMax(0, CntLeadingZeros(maxDirRevNrg) - 1);
+
+ C_ALLOC_SCRATCH_END(reverbNrg, FIXP_DBL, (28));
+
+ return err;
+}
+
+LNK_SECTION_CODE_L1
+static INT DuckerApplyPS(DUCKER_INSTANCE *const self,
+ FIXP_DBL const directNrg[(28)],
+ FIXP_DBL outputReal[(71)], FIXP_DBL outputImag[(71)],
+ int startHybBand) {
+ int qs = startHybBand;
+ int pb = 0;
+ int startParamBand =
+ SpatialDecGetProcessingBand(startHybBand, self->mapHybBands2ProcBands);
+ int hybBands;
+
+ int doScaleNrg = 0;
+ int scaleDirectNrg = 0;
+ int scaleSmoothDirRevNrg = 0;
+ FIXP_DBL maxDirRevNrg = FL2FXCONST_DBL(0.0);
+
+ if ((self->scaleDirectNrg != self->scaleSmoothDirRevNrg) ||
+ (self->headroomSmoothDirRevNrg == 0)) {
+ int scale;
+
+ scale = fixMin(self->scaleDirectNrg, self->scaleSmoothDirRevNrg +
+ self->headroomSmoothDirRevNrg - 2);
+
+ scaleDirectNrg = fMax(fMin(self->scaleDirectNrg - scale, (DFRACT_BITS - 1)),
+ -(DFRACT_BITS - 1));
+ scaleSmoothDirRevNrg =
+ fMax(fMin(self->scaleSmoothDirRevNrg - scale, (DFRACT_BITS - 1)),
+ -(DFRACT_BITS - 1));
+
+ self->scaleSmoothDirRevNrg = (SCHAR)scale;
+
+ doScaleNrg = 1;
+ }
+
+ hybBands = self->hybridBands;
+
+ FDK_ASSERT((self->parameterBands == (28)) || (self->parameterBands == (20)));
+ for (pb = startParamBand; pb < self->parameterBands; pb++) {
+ FIXP_DBL directNrg2 = directNrg[pb];
+
+ if (doScaleNrg) {
+ directNrg2 = scaleValue(directNrg2, -scaleDirectNrg);
+ self->peakDiff[pb] =
+ scaleValue(self->peakDiff[pb], -scaleSmoothDirRevNrg);
+ self->peakDecay[pb] =
+ scaleValue(self->peakDecay[pb], -scaleSmoothDirRevNrg);
+ self->SmoothDirRevNrg[pb] =
+ scaleValue(self->SmoothDirRevNrg[pb], -scaleSmoothDirRevNrg);
+ }
+ self->peakDecay[pb] = fixMax(
+ directNrg2, fMult(self->peakDecay[pb], PS_DUCK_PEAK_DECAY_FACTOR_FDK));
+ self->peakDiff[pb] =
+ self->peakDiff[pb] +
+ fMult(PS_DUCK_FILTER_COEFF_FDK,
+ (self->peakDecay[pb] - directNrg2 - self->peakDiff[pb]));
+ self->SmoothDirRevNrg[pb] =
+ fixMax(self->SmoothDirRevNrg[pb] +
+ fMult(PS_DUCK_FILTER_COEFF_FDK,
+ (directNrg2 - self->SmoothDirRevNrg[pb])),
+ FL2FXCONST_DBL(0));
+
+ maxDirRevNrg |= fAbs(self->peakDiff[pb]);
+ maxDirRevNrg |= fAbs(self->SmoothDirRevNrg[pb]);
+
+ if ((self->peakDiff[pb] == FL2FXCONST_DBL(0)) &&
+ (self->SmoothDirRevNrg[pb] == FL2FXCONST_DBL(0))) {
+ int qs_next;
+
+ qs = fMax(qs, SpatialDecGetQmfBand(pb, self->mapProcBands2HybBands));
+ qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
+
+ FIXP_DBL *pOutputReal = &outputReal[qs];
+ FIXP_DBL *pOutputImag = &outputImag[qs];
+
+ if (qs < hybBands) {
+ for (; qs < qs_next; qs++) {
+ *pOutputReal++ = FL2FXCONST_DBL(0);
+ *pOutputImag++ = FL2FXCONST_DBL(0);
+ }
+ } else {
+ for (; qs < qs_next; qs++) {
+ *pOutputReal++ = FL2FXCONST_DBL(0);
+ }
+ }
+ } else if (self->peakDiff[pb] != FL2FXCONST_DBL(0)) {
+ FIXP_DBL multiplication =
+ fMult(FL2FXCONST_DUCK(0.75f), self->peakDiff[pb]);
+ if (multiplication > (self->SmoothDirRevNrg[pb] >> 1)) {
+ FIXP_DBL num, denom, duckGain;
+ int scale, qs_next;
+
+ /* implement x/y as (sqrt(x)*invSqrt(y))^2 */
+ num = sqrtFixp(self->SmoothDirRevNrg[pb] >> 1);
+ denom = self->peakDiff[pb] +
+ FL2FXCONST_DBL(ABS_THR / (32768.0f * 32768.0f * 128.0f * 1.5f));
+ denom = invSqrtNorm2(denom, &scale);
+
+ /* duck output whether duckGain != 1.f */
+ qs = fMax(qs, SpatialDecGetQmfBand(pb, self->mapProcBands2HybBands));
+ qs_next = fMin((int)self->qs_next[pb], self->hybridBands);
+
+ duckGain = fMult(num, denom);
+ duckGain = fPow2Div2(duckGain << scale);
+ duckGain = fMultDiv2(FL2FXCONST_DUCK(2.f / 3.f), duckGain) << 3;
+
+ FIXP_DBL *pOutputReal = &outputReal[qs];
+ FIXP_DBL *pOutputImag = &outputImag[qs];
+
+ if (qs < hybBands) {
+ for (; qs < qs_next; qs++) {
+ *pOutputReal = fMult(*pOutputReal, duckGain);
+ pOutputReal++; /* don't move in front of "=" above, because then the
+ fract class treats it differently and provides
+ wrong argument to fMult() (seen on win32/msvc8) */
+ *pOutputImag = fMult(*pOutputImag, duckGain);
+ pOutputImag++;
+ }
+ } else {
+ for (; qs < qs_next; qs++) {
+ *pOutputReal = fMult(*pOutputReal, duckGain);
+ pOutputReal++;
+ }
+ }
+ }
+ }
+ } /* pb */
+
+ self->headroomSmoothDirRevNrg =
+ (SCHAR)fixMax(0, CntLeadingZeros(maxDirRevNrg) - 1);
+
+ return 0;
+}
+
+INT FDKdecorrelateOpen(HANDLE_DECORR_DEC hDecorrDec, FIXP_DBL *bufferCplx,
+ const INT bufLen) {
+ HANDLE_DECORR_DEC self = hDecorrDec;
+
+ if (bufLen < (2 * ((825) + (373)))) return 1;
+
+ /* assign all memory to stateBufferCplx. It is reassigned during
+ * FDKdecorrelateInit() */
+ self->stateBufferCplx = bufferCplx;
+ self->L_stateBufferCplx = 0;
+
+ self->delayBufferCplx = NULL;
+ self->L_delayBufferCplx = 0;
+
+ return 0;
+}
+
+static int distributeBuffer(HANDLE_DECORR_DEC self, const int L_stateBuf,
+ const int L_delayBuf) {
+ /* factor 2 because of complex values */
+ if ((2 * ((825) + (373))) < 2 * (L_stateBuf + L_delayBuf)) {
+ return 1;
+ }
+
+ self->L_stateBufferCplx = 2 * L_stateBuf;
+ self->delayBufferCplx = self->stateBufferCplx + 2 * L_stateBuf;
+ self->L_delayBufferCplx = 2 * L_delayBuf;
+
+ return 0;
+}
+INT FDKdecorrelateInit(HANDLE_DECORR_DEC hDecorrDec, const INT nrHybBands,
+ const FDK_DECORR_TYPE decorrType,
+ const FDK_DUCKER_TYPE duckerType, const INT decorrConfig,
+ const INT seed, const INT partiallyComplex,
+ const INT useFractDelay, const INT isLegacyPS,
+ const INT initStatesFlag) {
+ INT errorCode = 0;
+ int i, rb, i_start;
+ int nParamBands = 28;
+
+ INT offsetStateBuffer = 0;
+ INT offsetDelayBuffer = 0;
+
+ const UCHAR *REV_bandOffset;
+
+ const SCHAR *REV_filterOrder;
+
+ hDecorrDec->partiallyComplex = partiallyComplex;
+ hDecorrDec->numbins = nrHybBands;
+
+ switch (decorrType) {
+ case DECORR_PS:
+ /* ignore decorrConfig, seed */
+ if (partiallyComplex) {
+ hDecorrDec->REV_bandOffset = REV_bandOffset_PS_LP;
+ hDecorrDec->REV_delay = REV_delay_PS_LP;
+ errorCode = distributeBuffer(hDecorrDec, (168), (533));
+ } else {
+ hDecorrDec->REV_bandOffset = REV_bandOffset_PS_HQ;
+ hDecorrDec->REV_delay = REV_delay_PS_HQ;
+ errorCode = distributeBuffer(hDecorrDec, (360), (257));
+ }
+ hDecorrDec->REV_filterOrder = REV_filterOrder_PS;
+ hDecorrDec->REV_filtType = REV_filtType_PS;
+
+ /* Initialize ring buffer offsets for PS specific filter implementation.
+ */
+ for (i = 0; i < (3); i++)
+ hDecorrDec->stateBufferOffset[i] = stateBufferOffsetInit[i];
+
+ break;
+ case DECORR_USAC:
+ if (partiallyComplex) return 1;
+ if (seed != 0) return 1;
+ hDecorrDec->REV_bandOffset =
+ REV_bandOffset_MPS_HQ[decorrConfig]; /* reverb band layout is
+ inherited from MPS standard */
+ hDecorrDec->REV_filterOrder = REV_filterOrder_USAC;
+ hDecorrDec->REV_delay = REV_delay_USAC;
+ if (useFractDelay) {
+ return 1; /* not yet supported */
+ } else {
+ hDecorrDec->REV_filtType = REV_filtType_MPS; /* the filter types are
+ inherited from MPS
+ standard */
+ }
+ /* bsDecorrConfig == 1 is worst case */
+ errorCode = distributeBuffer(hDecorrDec, (509), (643));
+ break;
+ case DECORR_LD:
+ if (partiallyComplex) return 1;
+ if (useFractDelay) return 1;
+ if (decorrConfig > 2) return 1;
+ if (seed > (MAX_DECORR_SEED_LD - 1)) return 1;
+ if (!(nrHybBands == 64 || nrHybBands == 32))
+ return 1; /* actually just qmf bands and no hybrid bands */
+ hDecorrDec->REV_bandOffset = REV_bandOffset_LD[decorrConfig];
+ hDecorrDec->REV_filterOrder = REV_filterOrder_MPS; /* the filter orders
+ are inherited from
+ MPS standard */
+ hDecorrDec->REV_delay =
+ REV_delay_MPS; /* the delays in each reverb band are inherited from
+ MPS standard */
+ hDecorrDec->REV_filtType = REV_filtType_LD;
+ errorCode = distributeBuffer(hDecorrDec, (825), (373));
+ break;
+ default:
+ return 1;
+ }
+
+ if (errorCode) {
+ return errorCode;
+ }
+
+ if (initStatesFlag) {
+ FDKmemclear(
+ hDecorrDec->stateBufferCplx,
+ hDecorrDec->L_stateBufferCplx * sizeof(*hDecorrDec->stateBufferCplx));
+ FDKmemclear(
+ hDecorrDec->delayBufferCplx,
+ hDecorrDec->L_delayBufferCplx * sizeof(*hDecorrDec->delayBufferCplx));
+ FDKmemclear(hDecorrDec->reverbBandDelayBufferIndex,
+ sizeof(hDecorrDec->reverbBandDelayBufferIndex));
+ }
+
+ REV_bandOffset = hDecorrDec->REV_bandOffset;
+
+ REV_filterOrder = hDecorrDec->REV_filterOrder;
+
+ i_start = 0;
+ for (rb = 0; rb < (4); rb++) {
+ int i_stop;
+
+ i_stop = REV_bandOffset[rb];
+
+ if (i_stop <= i_start) {
+ continue;
+ }
+
+ for (i = i_start; i < i_stop; i++) {
+ switch (decorrType) {
+ case DECORR_PS:
+ errorCode = DecorrFilterInitPS(
+ &hDecorrDec->Filter[i], hDecorrDec->stateBufferCplx,
+ hDecorrDec->delayBufferCplx, &offsetStateBuffer,
+ &offsetDelayBuffer, i, rb, hDecorrDec->REV_delay[rb]);
+ break;
+ default:
+ errorCode = DecorrFilterInit(
+ &hDecorrDec->Filter[i], hDecorrDec->stateBufferCplx,
+ hDecorrDec->delayBufferCplx, &offsetStateBuffer,
+ &offsetDelayBuffer, seed, rb, useFractDelay,
+ hDecorrDec->REV_delay[rb], REV_filterOrder[rb], decorrType);
+ break;
+ }
+ }
+
+ i_start = i_stop;
+ } /* loop over reverbBands */
+
+ if (!(offsetStateBuffer <= hDecorrDec->L_stateBufferCplx) ||
+ !(offsetDelayBuffer <= hDecorrDec->L_delayBufferCplx)) {
+ return errorCode = 1;
+ }
+
+ if (duckerType == DUCKER_AUTOMATIC) {
+ /* Choose correct ducker type according to standards: */
+ switch (decorrType) {
+ case DECORR_PS:
+ hDecorrDec->ducker.duckerType = DUCKER_PS;
+ if (isLegacyPS) {
+ nParamBands = (20);
+ } else {
+ nParamBands = (28);
+ }
+ break;
+ case DECORR_USAC:
+ hDecorrDec->ducker.duckerType = DUCKER_MPS;
+ nParamBands = (28);
+ break;
+ case DECORR_LD:
+ hDecorrDec->ducker.duckerType = DUCKER_MPS;
+ nParamBands = (23);
+ break;
+ default:
+ return 1;
+ }
+ }
+
+ errorCode = DuckerInit(
+ &hDecorrDec->ducker, hDecorrDec->numbins, hDecorrDec->partiallyComplex,
+ hDecorrDec->ducker.duckerType, nParamBands, initStatesFlag);
+
+ return errorCode;
+}
+
+INT FDKdecorrelateClose(HANDLE_DECORR_DEC hDecorrDec) {
+ INT err = 0;
+
+ if (hDecorrDec == NULL) {
+ return 1;
+ }
+
+ hDecorrDec->stateBufferCplx = NULL;
+ hDecorrDec->L_stateBufferCplx = 0;
+ hDecorrDec->delayBufferCplx = NULL;
+ hDecorrDec->L_delayBufferCplx = 0;
+
+ return err;
+}
+
+LNK_SECTION_CODE_L1
+INT FDKdecorrelateApply(HANDLE_DECORR_DEC hDecorrDec, FIXP_DBL *dataRealIn,
+ FIXP_DBL *dataImagIn, FIXP_DBL *dataRealOut,
+ FIXP_DBL *dataImagOut, const INT startHybBand) {
+ HANDLE_DECORR_DEC self = hDecorrDec;
+ INT err = 0;
+ INT rb, stop, start;
+
+ if (self != NULL) {
+ int nHybBands = 0;
+ /* copy new samples */
+ nHybBands = self->numbins;
+
+ FIXP_DBL directNrg[(28)];
+
+ DuckerCalcEnergy(
+ &self->ducker, dataRealIn, dataImagIn, directNrg,
+ self->ducker.maxValDirectData, &(self->ducker.scaleDirectNrg),
+ (self->ducker.duckerType == DUCKER_PS) ? 1 : 0, startHybBand);
+
+ /* complex-valued hybrid bands */
+ for (stop = 0, rb = 0; rb < (4); rb++) {
+ start = fMax(stop, startHybBand);
+ stop = fMin(self->REV_bandOffset[rb], (UCHAR)nHybBands);
+
+ if (start < stop) {
+ switch (hDecorrDec->REV_filtType[rb]) {
+ case DELAY:
+ err = DecorrFilterApplyPASS(&self->Filter[0], dataRealIn,
+ dataImagIn, dataRealOut, dataImagOut,
+ start, stop, self->REV_delay[rb],
+ self->reverbBandDelayBufferIndex[rb]);
+ break;
+ case INDEP_CPLX_PS:
+ err = DecorrFilterApplyCPLX_PS(
+ &self->Filter[0], dataRealIn, dataImagIn, dataRealOut,
+ dataImagOut, start, stop, self->REV_filterOrder[rb],
+ self->REV_delay[rb], self->reverbBandDelayBufferIndex[rb],
+ self->stateBufferOffset);
+ break;
+ case COMMON_REAL:
+ err = DecorrFilterApplyREAL(
+ &self->Filter[0], dataRealIn, dataImagIn, dataRealOut,
+ dataImagOut, start, stop, self->REV_filterOrder[rb],
+ self->REV_delay[rb], self->reverbBandDelayBufferIndex[rb]);
+ break;
+ default:
+ err = 1;
+ break;
+ }
+ if (err != 0) {
+ goto bail;
+ }
+ } /* if start < stop */
+ } /* loop over reverb bands */
+
+ for (rb = 0; rb < (4); rb++) {
+ self->reverbBandDelayBufferIndex[rb] += 2;
+ if (self->reverbBandDelayBufferIndex[rb] >= 2 * self->REV_delay[rb])
+ self->reverbBandDelayBufferIndex[rb] = 0;
+ }
+
+ switch (self->ducker.duckerType) {
+ case DUCKER_PS:
+ err = DuckerApplyPS(&self->ducker, directNrg, dataRealOut, dataImagOut,
+ startHybBand);
+ if (err != 0) goto bail;
+ break;
+ default:
+ err = DuckerApply(&self->ducker, directNrg, dataRealOut, dataImagOut,
+ startHybBand);
+ if (err != 0) goto bail;
+ break;
+ }
+ }
+
+bail:
+ return err;
+}
diff --git a/fdk-aac/libFDK/src/FDK_hybrid.cpp b/fdk-aac/libFDK/src/FDK_hybrid.cpp
new file mode 100644
index 0000000..b661f82
--- /dev/null
+++ b/fdk-aac/libFDK/src/FDK_hybrid.cpp
@@ -0,0 +1,813 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Markus Lohwasser
+
+ Description: FDK Tools Hybrid Filterbank
+
+*******************************************************************************/
+
+#include "FDK_hybrid.h"
+
+#include "fft.h"
+
+/*--------------- defines -----------------------------*/
+#define FFT_IDX_R(a) (2 * a)
+#define FFT_IDX_I(a) (2 * a + 1)
+
+#define HYB_COEF8_0 (0.00746082949812f)
+#define HYB_COEF8_1 (0.02270420949825f)
+#define HYB_COEF8_2 (0.04546865930473f)
+#define HYB_COEF8_3 (0.07266113929591f)
+#define HYB_COEF8_4 (0.09885108575264f)
+#define HYB_COEF8_5 (0.11793710567217f)
+#define HYB_COEF8_6 (0.12500000000000f)
+#define HYB_COEF8_7 (HYB_COEF8_5)
+#define HYB_COEF8_8 (HYB_COEF8_4)
+#define HYB_COEF8_9 (HYB_COEF8_3)
+#define HYB_COEF8_10 (HYB_COEF8_2)
+#define HYB_COEF8_11 (HYB_COEF8_1)
+#define HYB_COEF8_12 (HYB_COEF8_0)
+
+/*--------------- structure definitions ---------------*/
+
+#if defined(ARCH_PREFER_MULT_32x16)
+#define FIXP_HTB FIXP_SGL /* SGL data type. */
+#define FIXP_HTP FIXP_SPK /* Packed SGL data type. */
+#define HTC(a) (FX_DBL2FXCONST_SGL(a)) /* Cast to SGL */
+#define FL2FXCONST_HTB FL2FXCONST_SGL
+#else
+#define FIXP_HTB FIXP_DBL /* SGL data type. */
+#define FIXP_HTP FIXP_DPK /* Packed DBL data type. */
+#define HTC(a) ((FIXP_DBL)(LONG)(a)) /* Cast to DBL */
+#define FL2FXCONST_HTB FL2FXCONST_DBL
+#endif
+
+#define HTCP(real, imag) \
+ { \
+ { HTC(real), HTC(imag) } \
+ } /* How to arrange the packed values. */
+
+struct FDK_HYBRID_SETUP {
+ UCHAR nrQmfBands; /*!< Number of QMF bands to be converted to hybrid. */
+ UCHAR nHybBands[3]; /*!< Number of Hybrid bands generated by nrQmfBands. */
+ SCHAR kHybrid[3]; /*!< Filter configuration of each QMF band. */
+ UCHAR protoLen; /*!< Prototype filter length. */
+ UCHAR filterDelay; /*!< Delay caused by hybrid filter. */
+ const INT
+ *pReadIdxTable; /*!< Helper table to access input data ringbuffer. */
+};
+
+/*--------------- constants ---------------------------*/
+static const INT ringbuffIdxTab[2 * 13] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12};
+
+static const FDK_HYBRID_SETUP setup_3_16 = {3, {8, 4, 4}, {8, 4, 4},
+ 13, (13 - 1) / 2, ringbuffIdxTab};
+static const FDK_HYBRID_SETUP setup_3_12 = {3, {8, 2, 2}, {8, 2, 2},
+ 13, (13 - 1) / 2, ringbuffIdxTab};
+static const FDK_HYBRID_SETUP setup_3_10 = {3, {6, 2, 2}, {-8, -2, 2},
+ 13, (13 - 1) / 2, ringbuffIdxTab};
+
+static const FIXP_HTP HybFilterCoef8[] = {
+ HTCP(0x10000000, 0x00000000), HTCP(0x0df26407, 0xfa391882),
+ HTCP(0xff532109, 0x00acdef7), HTCP(0x08f26d36, 0xf70d92ca),
+ HTCP(0xfee34b5f, 0x02af570f), HTCP(0x038f276e, 0xf7684793),
+ HTCP(0x00000000, 0x05d1eac2), HTCP(0x00000000, 0x05d1eac2),
+ HTCP(0x038f276e, 0x0897b86d), HTCP(0xfee34b5f, 0xfd50a8f1),
+ HTCP(0x08f26d36, 0x08f26d36), HTCP(0xff532109, 0xff532109),
+ HTCP(0x0df26407, 0x05c6e77e)};
+
+static const FIXP_HTB HybFilterCoef2[3] = {FL2FXCONST_HTB(0.01899487526049f),
+ FL2FXCONST_HTB(-0.07293139167538f),
+ FL2FXCONST_HTB(0.30596630545168f)};
+
+static const FIXP_HTB HybFilterCoef4[13] = {FL2FXCONST_HTB(-0.00305151927305f),
+ FL2FXCONST_HTB(-0.00794862316203f),
+ FL2FXCONST_HTB(0.0f),
+ FL2FXCONST_HTB(0.04318924038756f),
+ FL2FXCONST_HTB(0.12542448210445f),
+ FL2FXCONST_HTB(0.21227807049160f),
+ FL2FXCONST_HTB(0.25f),
+ FL2FXCONST_HTB(0.21227807049160f),
+ FL2FXCONST_HTB(0.12542448210445f),
+ FL2FXCONST_HTB(0.04318924038756f),
+ FL2FXCONST_HTB(0.0f),
+ FL2FXCONST_HTB(-0.00794862316203f),
+ FL2FXCONST_HTB(-0.00305151927305f)};
+
+/*--------------- function declarations ---------------*/
+static INT kChannelFiltering(const FIXP_DBL *const pQmfReal,
+ const FIXP_DBL *const pQmfImag,
+ const INT *const pReadIdx,
+ FIXP_DBL *const mHybridReal,
+ FIXP_DBL *const mHybridImag,
+ const SCHAR hybridConfig);
+
+/*--------------- function definitions ----------------*/
+
+INT FDKhybridAnalysisOpen(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
+ FIXP_DBL *const pLFmemory, const UINT LFmemorySize,
+ FIXP_DBL *const pHFmemory, const UINT HFmemorySize) {
+ INT err = 0;
+
+ /* Save pointer to extern memory. */
+ hAnalysisHybFilter->pLFmemory = pLFmemory;
+ hAnalysisHybFilter->LFmemorySize = LFmemorySize;
+
+ hAnalysisHybFilter->pHFmemory = pHFmemory;
+ hAnalysisHybFilter->HFmemorySize = HFmemorySize;
+
+ return err;
+}
+
+INT FDKhybridAnalysisInit(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
+ const FDK_HYBRID_MODE mode, const INT qmfBands,
+ const INT cplxBands, const INT initStatesFlag) {
+ int k;
+ INT err = 0;
+ FIXP_DBL *pMem = NULL;
+ HANDLE_FDK_HYBRID_SETUP setup = NULL;
+
+ switch (mode) {
+ case THREE_TO_TEN:
+ setup = &setup_3_10;
+ break;
+ case THREE_TO_TWELVE:
+ setup = &setup_3_12;
+ break;
+ case THREE_TO_SIXTEEN:
+ setup = &setup_3_16;
+ break;
+ default:
+ err = -1;
+ goto bail;
+ }
+
+ /* Initialize handle. */
+ hAnalysisHybFilter->pSetup = setup;
+ if (initStatesFlag) {
+ hAnalysisHybFilter->bufferLFpos = setup->protoLen - 1;
+ hAnalysisHybFilter->bufferHFpos = 0;
+ }
+ hAnalysisHybFilter->nrBands = qmfBands;
+ hAnalysisHybFilter->cplxBands = cplxBands;
+ hAnalysisHybFilter->hfMode = 0;
+
+ /* Check available memory. */
+ if (((2 * setup->nrQmfBands * setup->protoLen * sizeof(FIXP_DBL)) >
+ hAnalysisHybFilter->LFmemorySize)) {
+ err = -2;
+ goto bail;
+ }
+ if (hAnalysisHybFilter->HFmemorySize != 0) {
+ if (((setup->filterDelay *
+ ((qmfBands - setup->nrQmfBands) + (cplxBands - setup->nrQmfBands)) *
+ sizeof(FIXP_DBL)) > hAnalysisHybFilter->HFmemorySize)) {
+ err = -3;
+ goto bail;
+ }
+ }
+
+ /* Distribute LF memory. */
+ pMem = hAnalysisHybFilter->pLFmemory;
+ for (k = 0; k < setup->nrQmfBands; k++) {
+ hAnalysisHybFilter->bufferLFReal[k] = pMem;
+ pMem += setup->protoLen;
+ hAnalysisHybFilter->bufferLFImag[k] = pMem;
+ pMem += setup->protoLen;
+ }
+
+ /* Distribute HF memory. */
+ if (hAnalysisHybFilter->HFmemorySize != 0) {
+ pMem = hAnalysisHybFilter->pHFmemory;
+ for (k = 0; k < setup->filterDelay; k++) {
+ hAnalysisHybFilter->bufferHFReal[k] = pMem;
+ pMem += (qmfBands - setup->nrQmfBands);
+ hAnalysisHybFilter->bufferHFImag[k] = pMem;
+ pMem += (cplxBands - setup->nrQmfBands);
+ }
+ }
+
+ if (initStatesFlag) {
+ /* Clear LF buffer */
+ for (k = 0; k < setup->nrQmfBands; k++) {
+ FDKmemclear(hAnalysisHybFilter->bufferLFReal[k],
+ setup->protoLen * sizeof(FIXP_DBL));
+ FDKmemclear(hAnalysisHybFilter->bufferLFImag[k],
+ setup->protoLen * sizeof(FIXP_DBL));
+ }
+
+ if (hAnalysisHybFilter->HFmemorySize != 0) {
+ if (qmfBands > setup->nrQmfBands) {
+ /* Clear HF buffer */
+ for (k = 0; k < setup->filterDelay; k++) {
+ FDKmemclear(hAnalysisHybFilter->bufferHFReal[k],
+ (qmfBands - setup->nrQmfBands) * sizeof(FIXP_DBL));
+ FDKmemclear(hAnalysisHybFilter->bufferHFImag[k],
+ (cplxBands - setup->nrQmfBands) * sizeof(FIXP_DBL));
+ }
+ }
+ }
+ }
+
+bail:
+ return err;
+}
+
+INT FDKhybridAnalysisScaleStates(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
+ const INT scalingValue) {
+ INT err = 0;
+
+ if (hAnalysisHybFilter == NULL) {
+ err = 1; /* invalid handle */
+ } else {
+ int k;
+ HANDLE_FDK_HYBRID_SETUP setup = hAnalysisHybFilter->pSetup;
+
+ /* Scale LF buffer */
+ for (k = 0; k < setup->nrQmfBands; k++) {
+ scaleValues(hAnalysisHybFilter->bufferLFReal[k], setup->protoLen,
+ scalingValue);
+ scaleValues(hAnalysisHybFilter->bufferLFImag[k], setup->protoLen,
+ scalingValue);
+ }
+ if (hAnalysisHybFilter->nrBands > setup->nrQmfBands) {
+ /* Scale HF buffer */
+ for (k = 0; k < setup->filterDelay; k++) {
+ scaleValues(hAnalysisHybFilter->bufferHFReal[k],
+ (hAnalysisHybFilter->nrBands - setup->nrQmfBands),
+ scalingValue);
+ scaleValues(hAnalysisHybFilter->bufferHFImag[k],
+ (hAnalysisHybFilter->cplxBands - setup->nrQmfBands),
+ scalingValue);
+ }
+ }
+ }
+ return err;
+}
+
+INT FDKhybridAnalysisApply(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
+ const FIXP_DBL *const pQmfReal,
+ const FIXP_DBL *const pQmfImag,
+ FIXP_DBL *const pHybridReal,
+ FIXP_DBL *const pHybridImag) {
+ int k, hybOffset = 0;
+ INT err = 0;
+ const int nrQmfBandsLF =
+ hAnalysisHybFilter->pSetup
+ ->nrQmfBands; /* number of QMF bands to be converted to hybrid */
+
+ const int writIndex = hAnalysisHybFilter->bufferLFpos;
+ int readIndex = hAnalysisHybFilter->bufferLFpos;
+
+ if (++readIndex >= hAnalysisHybFilter->pSetup->protoLen) readIndex = 0;
+ const INT *pBufferLFreadIdx =
+ &hAnalysisHybFilter->pSetup->pReadIdxTable[readIndex];
+
+ /*
+ * LF buffer.
+ */
+ for (k = 0; k < nrQmfBandsLF; k++) {
+ /* New input sample. */
+ hAnalysisHybFilter->bufferLFReal[k][writIndex] = pQmfReal[k];
+ hAnalysisHybFilter->bufferLFImag[k][writIndex] = pQmfImag[k];
+
+ /* Perform hybrid filtering. */
+ err |=
+ kChannelFiltering(hAnalysisHybFilter->bufferLFReal[k],
+ hAnalysisHybFilter->bufferLFImag[k], pBufferLFreadIdx,
+ pHybridReal + hybOffset, pHybridImag + hybOffset,
+ hAnalysisHybFilter->pSetup->kHybrid[k]);
+
+ hybOffset += hAnalysisHybFilter->pSetup->nHybBands[k];
+ }
+
+ hAnalysisHybFilter->bufferLFpos =
+ readIndex; /* Index where to write next input sample. */
+
+ if (hAnalysisHybFilter->nrBands > nrQmfBandsLF) {
+ /*
+ * HF buffer.
+ */
+ if (hAnalysisHybFilter->hfMode != 0) {
+ /* HF delay compensation was applied outside. */
+ FDKmemcpy(
+ pHybridReal + hybOffset, &pQmfReal[nrQmfBandsLF],
+ (hAnalysisHybFilter->nrBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
+ FDKmemcpy(
+ pHybridImag + hybOffset, &pQmfImag[nrQmfBandsLF],
+ (hAnalysisHybFilter->cplxBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
+ } else {
+ FDK_ASSERT(hAnalysisHybFilter->HFmemorySize != 0);
+ /* HF delay compensation, filterlength/2. */
+ FDKmemcpy(
+ pHybridReal + hybOffset,
+ hAnalysisHybFilter->bufferHFReal[hAnalysisHybFilter->bufferHFpos],
+ (hAnalysisHybFilter->nrBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
+ FDKmemcpy(
+ pHybridImag + hybOffset,
+ hAnalysisHybFilter->bufferHFImag[hAnalysisHybFilter->bufferHFpos],
+ (hAnalysisHybFilter->cplxBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
+
+ FDKmemcpy(
+ hAnalysisHybFilter->bufferHFReal[hAnalysisHybFilter->bufferHFpos],
+ &pQmfReal[nrQmfBandsLF],
+ (hAnalysisHybFilter->nrBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
+ FDKmemcpy(
+ hAnalysisHybFilter->bufferHFImag[hAnalysisHybFilter->bufferHFpos],
+ &pQmfImag[nrQmfBandsLF],
+ (hAnalysisHybFilter->cplxBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
+
+ if (++hAnalysisHybFilter->bufferHFpos >=
+ hAnalysisHybFilter->pSetup->filterDelay)
+ hAnalysisHybFilter->bufferHFpos = 0;
+ }
+ } /* process HF part*/
+
+ return err;
+}
+
+INT FDKhybridAnalysisClose(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter) {
+ INT err = 0;
+
+ if (hAnalysisHybFilter != NULL) {
+ hAnalysisHybFilter->pLFmemory = NULL;
+ hAnalysisHybFilter->pHFmemory = NULL;
+ hAnalysisHybFilter->LFmemorySize = 0;
+ hAnalysisHybFilter->HFmemorySize = 0;
+ }
+
+ return err;
+}
+
+INT FDKhybridSynthesisInit(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
+ const FDK_HYBRID_MODE mode, const INT qmfBands,
+ const INT cplxBands) {
+ INT err = 0;
+ HANDLE_FDK_HYBRID_SETUP setup = NULL;
+
+ switch (mode) {
+ case THREE_TO_TEN:
+ setup = &setup_3_10;
+ break;
+ case THREE_TO_TWELVE:
+ setup = &setup_3_12;
+ break;
+ case THREE_TO_SIXTEEN:
+ setup = &setup_3_16;
+ break;
+ default:
+ err = -1;
+ goto bail;
+ }
+
+ hSynthesisHybFilter->pSetup = setup;
+ hSynthesisHybFilter->nrBands = qmfBands;
+ hSynthesisHybFilter->cplxBands = cplxBands;
+
+bail:
+ return err;
+}
+
+void FDKhybridSynthesisApply(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
+ const FIXP_DBL *const pHybridReal,
+ const FIXP_DBL *const pHybridImag,
+ FIXP_DBL *const pQmfReal,
+ FIXP_DBL *const pQmfImag) {
+ int k, n, hybOffset = 0;
+ const INT nrQmfBandsLF = hSynthesisHybFilter->pSetup->nrQmfBands;
+
+ /*
+ * LF buffer.
+ */
+ for (k = 0; k < nrQmfBandsLF; k++) {
+ const int nHybBands = hSynthesisHybFilter->pSetup->nHybBands[k];
+
+ FIXP_DBL accu1 = FL2FXCONST_DBL(0.f);
+ FIXP_DBL accu2 = FL2FXCONST_DBL(0.f);
+
+ /* Perform hybrid filtering. */
+ for (n = 0; n < nHybBands; n++) {
+ accu1 += pHybridReal[hybOffset + n];
+ accu2 += pHybridImag[hybOffset + n];
+ }
+ pQmfReal[k] = accu1;
+ pQmfImag[k] = accu2;
+
+ hybOffset += nHybBands;
+ }
+
+ if (hSynthesisHybFilter->nrBands > nrQmfBandsLF) {
+ /*
+ * HF buffer.
+ */
+ FDKmemcpy(&pQmfReal[nrQmfBandsLF], &pHybridReal[hybOffset],
+ (hSynthesisHybFilter->nrBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
+ FDKmemcpy(
+ &pQmfImag[nrQmfBandsLF], &pHybridImag[hybOffset],
+ (hSynthesisHybFilter->cplxBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
+ }
+
+ return;
+}
+
+static void dualChannelFiltering(const FIXP_DBL *const pQmfReal,
+ const FIXP_DBL *const pQmfImag,
+ const INT *const pReadIdx,
+ FIXP_DBL *const mHybridReal,
+ FIXP_DBL *const mHybridImag,
+ const INT invert) {
+ FIXP_DBL r1, r6;
+ FIXP_DBL i1, i6;
+
+ const FIXP_HTB f0 = HybFilterCoef2[0]; /* corresponds to p1 and p11 */
+ const FIXP_HTB f1 = HybFilterCoef2[1]; /* corresponds to p3 and p9 */
+ const FIXP_HTB f2 = HybFilterCoef2[2]; /* corresponds to p5 and p7 */
+
+ /* symmetric filter coefficients */
+ r1 = fMultDiv2(f0, pQmfReal[pReadIdx[1]]) +
+ fMultDiv2(f0, pQmfReal[pReadIdx[11]]);
+ i1 = fMultDiv2(f0, pQmfImag[pReadIdx[1]]) +
+ fMultDiv2(f0, pQmfImag[pReadIdx[11]]);
+ r1 += fMultDiv2(f1, pQmfReal[pReadIdx[3]]) +
+ fMultDiv2(f1, pQmfReal[pReadIdx[9]]);
+ i1 += fMultDiv2(f1, pQmfImag[pReadIdx[3]]) +
+ fMultDiv2(f1, pQmfImag[pReadIdx[9]]);
+ r1 += fMultDiv2(f2, pQmfReal[pReadIdx[5]]) +
+ fMultDiv2(f2, pQmfReal[pReadIdx[7]]);
+ i1 += fMultDiv2(f2, pQmfImag[pReadIdx[5]]) +
+ fMultDiv2(f2, pQmfImag[pReadIdx[7]]);
+
+ r6 = pQmfReal[pReadIdx[6]] >> 2;
+ i6 = pQmfImag[pReadIdx[6]] >> 2;
+
+ FDK_ASSERT((invert == 0) || (invert == 1));
+ mHybridReal[0 + invert] = (r6 + r1) << 1;
+ mHybridImag[0 + invert] = (i6 + i1) << 1;
+
+ mHybridReal[1 - invert] = (r6 - r1) << 1;
+ mHybridImag[1 - invert] = (i6 - i1) << 1;
+}
+
+static void fourChannelFiltering(const FIXP_DBL *const pQmfReal,
+ const FIXP_DBL *const pQmfImag,
+ const INT *const pReadIdx,
+ FIXP_DBL *const mHybridReal,
+ FIXP_DBL *const mHybridImag,
+ const INT invert) {
+ const FIXP_HTB *p = HybFilterCoef4;
+
+ FIXP_DBL fft[8];
+
+ static const FIXP_DBL cr[13] = {
+ FL2FXCONST_DBL(0.f), FL2FXCONST_DBL(-0.70710678118655f),
+ FL2FXCONST_DBL(-1.f), FL2FXCONST_DBL(-0.70710678118655f),
+ FL2FXCONST_DBL(0.f), FL2FXCONST_DBL(0.70710678118655f),
+ FL2FXCONST_DBL(1.f), FL2FXCONST_DBL(0.70710678118655f),
+ FL2FXCONST_DBL(0.f), FL2FXCONST_DBL(-0.70710678118655f),
+ FL2FXCONST_DBL(-1.f), FL2FXCONST_DBL(-0.70710678118655f),
+ FL2FXCONST_DBL(0.f)};
+ static const FIXP_DBL ci[13] = {
+ FL2FXCONST_DBL(-1.f), FL2FXCONST_DBL(-0.70710678118655f),
+ FL2FXCONST_DBL(0.f), FL2FXCONST_DBL(0.70710678118655f),
+ FL2FXCONST_DBL(1.f), FL2FXCONST_DBL(0.70710678118655f),
+ FL2FXCONST_DBL(0.f), FL2FXCONST_DBL(-0.70710678118655f),
+ FL2FXCONST_DBL(-1.f), FL2FXCONST_DBL(-0.70710678118655f),
+ FL2FXCONST_DBL(0.f), FL2FXCONST_DBL(0.70710678118655f),
+ FL2FXCONST_DBL(1.f)};
+
+ /* FIR filter. */
+ /* pre twiddeling with pre-twiddling coefficients c[n] */
+ /* multiplication with filter coefficients p[n] */
+ /* hint: (a + ib)*(c + id) = (a*c - b*d) + i(a*d + b*c) */
+ /* write to fft coefficient n' */
+ fft[FFT_IDX_R(0)] =
+ (fMult(p[10], (fMultSub(fMultDiv2(cr[2], pQmfReal[pReadIdx[2]]), ci[2],
+ pQmfImag[pReadIdx[2]]))) +
+ fMult(p[6], (fMultSub(fMultDiv2(cr[6], pQmfReal[pReadIdx[6]]), ci[6],
+ pQmfImag[pReadIdx[6]]))) +
+ fMult(p[2], (fMultSub(fMultDiv2(cr[10], pQmfReal[pReadIdx[10]]), ci[10],
+ pQmfImag[pReadIdx[10]]))));
+ fft[FFT_IDX_I(0)] =
+ (fMult(p[10], (fMultAdd(fMultDiv2(ci[2], pQmfReal[pReadIdx[2]]), cr[2],
+ pQmfImag[pReadIdx[2]]))) +
+ fMult(p[6], (fMultAdd(fMultDiv2(ci[6], pQmfReal[pReadIdx[6]]), cr[6],
+ pQmfImag[pReadIdx[6]]))) +
+ fMult(p[2], (fMultAdd(fMultDiv2(ci[10], pQmfReal[pReadIdx[10]]), cr[10],
+ pQmfImag[pReadIdx[10]]))));
+
+ /* twiddle dee dum */
+ fft[FFT_IDX_R(1)] =
+ (fMult(p[9], (fMultSub(fMultDiv2(cr[3], pQmfReal[pReadIdx[3]]), ci[3],
+ pQmfImag[pReadIdx[3]]))) +
+ fMult(p[5], (fMultSub(fMultDiv2(cr[7], pQmfReal[pReadIdx[7]]), ci[7],
+ pQmfImag[pReadIdx[7]]))) +
+ fMult(p[1], (fMultSub(fMultDiv2(cr[11], pQmfReal[pReadIdx[11]]), ci[11],
+ pQmfImag[pReadIdx[11]]))));
+ fft[FFT_IDX_I(1)] =
+ (fMult(p[9], (fMultAdd(fMultDiv2(ci[3], pQmfReal[pReadIdx[3]]), cr[3],
+ pQmfImag[pReadIdx[3]]))) +
+ fMult(p[5], (fMultAdd(fMultDiv2(ci[7], pQmfReal[pReadIdx[7]]), cr[7],
+ pQmfImag[pReadIdx[7]]))) +
+ fMult(p[1], (fMultAdd(fMultDiv2(ci[11], pQmfReal[pReadIdx[11]]), cr[11],
+ pQmfImag[pReadIdx[11]]))));
+
+ /* twiddle dee dee */
+ fft[FFT_IDX_R(2)] =
+ (fMult(p[12], (fMultSub(fMultDiv2(cr[0], pQmfReal[pReadIdx[0]]), ci[0],
+ pQmfImag[pReadIdx[0]]))) +
+ fMult(p[8], (fMultSub(fMultDiv2(cr[4], pQmfReal[pReadIdx[4]]), ci[4],
+ pQmfImag[pReadIdx[4]]))) +
+ fMult(p[4], (fMultSub(fMultDiv2(cr[8], pQmfReal[pReadIdx[8]]), ci[8],
+ pQmfImag[pReadIdx[8]]))) +
+ fMult(p[0], (fMultSub(fMultDiv2(cr[12], pQmfReal[pReadIdx[12]]), ci[12],
+ pQmfImag[pReadIdx[12]]))));
+ fft[FFT_IDX_I(2)] =
+ (fMult(p[12], (fMultAdd(fMultDiv2(ci[0], pQmfReal[pReadIdx[0]]), cr[0],
+ pQmfImag[pReadIdx[0]]))) +
+ fMult(p[8], (fMultAdd(fMultDiv2(ci[4], pQmfReal[pReadIdx[4]]), cr[4],
+ pQmfImag[pReadIdx[4]]))) +
+ fMult(p[4], (fMultAdd(fMultDiv2(ci[8], pQmfReal[pReadIdx[8]]), cr[8],
+ pQmfImag[pReadIdx[8]]))) +
+ fMult(p[0], (fMultAdd(fMultDiv2(ci[12], pQmfReal[pReadIdx[12]]), cr[12],
+ pQmfImag[pReadIdx[12]]))));
+
+ fft[FFT_IDX_R(3)] =
+ (fMult(p[11], (fMultSub(fMultDiv2(cr[1], pQmfReal[pReadIdx[1]]), ci[1],
+ pQmfImag[pReadIdx[1]]))) +
+ fMult(p[7], (fMultSub(fMultDiv2(cr[5], pQmfReal[pReadIdx[5]]), ci[5],
+ pQmfImag[pReadIdx[5]]))) +
+ fMult(p[3], (fMultSub(fMultDiv2(cr[9], pQmfReal[pReadIdx[9]]), ci[9],
+ pQmfImag[pReadIdx[9]]))));
+ fft[FFT_IDX_I(3)] =
+ (fMult(p[11], (fMultAdd(fMultDiv2(ci[1], pQmfReal[pReadIdx[1]]), cr[1],
+ pQmfImag[pReadIdx[1]]))) +
+ fMult(p[7], (fMultAdd(fMultDiv2(ci[5], pQmfReal[pReadIdx[5]]), cr[5],
+ pQmfImag[pReadIdx[5]]))) +
+ fMult(p[3], (fMultAdd(fMultDiv2(ci[9], pQmfReal[pReadIdx[9]]), cr[9],
+ pQmfImag[pReadIdx[9]]))));
+
+ /* fft modulation */
+ /* here: fast manual fft modulation for a fft of length M=4 */
+ /* fft_4{x[n]} = x[0]*exp(-i*2*pi/4*m*0) + x[1]*exp(-i*2*pi/4*m*1) +
+ x[2]*exp(-i*2*pi/4*m*2) + x[3]*exp(-i*2*pi/4*m*3) */
+
+ /*
+ fft bin m=0:
+ X[0, n] = x[0] + x[1] + x[2] + x[3]
+ */
+ mHybridReal[0] = fft[FFT_IDX_R(0)] + fft[FFT_IDX_R(1)] + fft[FFT_IDX_R(2)] +
+ fft[FFT_IDX_R(3)];
+ mHybridImag[0] = fft[FFT_IDX_I(0)] + fft[FFT_IDX_I(1)] + fft[FFT_IDX_I(2)] +
+ fft[FFT_IDX_I(3)];
+
+ /*
+ fft bin m=1:
+ X[1, n] = x[0] - i*x[1] - x[2] + i*x[3]
+ */
+ mHybridReal[1] = fft[FFT_IDX_R(0)] + fft[FFT_IDX_I(1)] - fft[FFT_IDX_R(2)] -
+ fft[FFT_IDX_I(3)];
+ mHybridImag[1] = fft[FFT_IDX_I(0)] - fft[FFT_IDX_R(1)] - fft[FFT_IDX_I(2)] +
+ fft[FFT_IDX_R(3)];
+
+ /*
+ fft bin m=2:
+ X[2, n] = x[0] - x[1] + x[2] - x[3]
+ */
+ mHybridReal[2] = fft[FFT_IDX_R(0)] - fft[FFT_IDX_R(1)] + fft[FFT_IDX_R(2)] -
+ fft[FFT_IDX_R(3)];
+ mHybridImag[2] = fft[FFT_IDX_I(0)] - fft[FFT_IDX_I(1)] + fft[FFT_IDX_I(2)] -
+ fft[FFT_IDX_I(3)];
+
+ /*
+ fft bin m=3:
+ X[3, n] = x[0] + j*x[1] - x[2] - j*x[3]
+ */
+ mHybridReal[3] = fft[FFT_IDX_R(0)] - fft[FFT_IDX_I(1)] - fft[FFT_IDX_R(2)] +
+ fft[FFT_IDX_I(3)];
+ mHybridImag[3] = fft[FFT_IDX_I(0)] + fft[FFT_IDX_R(1)] - fft[FFT_IDX_I(2)] -
+ fft[FFT_IDX_R(3)];
+}
+
+static void eightChannelFiltering(const FIXP_DBL *const pQmfReal,
+ const FIXP_DBL *const pQmfImag,
+ const INT *const pReadIdx,
+ FIXP_DBL *const mHybridReal,
+ FIXP_DBL *const mHybridImag,
+ const INT invert) {
+ const FIXP_HTP *p = HybFilterCoef8;
+ INT k, sc;
+
+ FIXP_DBL mfft[16 + ALIGNMENT_DEFAULT];
+ FIXP_DBL *pfft = (FIXP_DBL *)ALIGN_PTR(mfft);
+
+ FIXP_DBL accu1, accu2, accu3, accu4;
+
+ /* pre twiddeling */
+ pfft[FFT_IDX_R(0)] =
+ pQmfReal[pReadIdx[6]] >>
+ (3 + 1); /* fMultDiv2(p[0].v.re, pQmfReal[pReadIdx[6]]); */
+ pfft[FFT_IDX_I(0)] =
+ pQmfImag[pReadIdx[6]] >>
+ (3 + 1); /* fMultDiv2(p[0].v.re, pQmfImag[pReadIdx[6]]); */
+
+ cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[7]], pQmfImag[pReadIdx[7]],
+ p[1]);
+ pfft[FFT_IDX_R(1)] = accu1;
+ pfft[FFT_IDX_I(1)] = accu2;
+
+ cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[0]], pQmfImag[pReadIdx[0]],
+ p[2]);
+ cplxMultDiv2(&accu3, &accu4, pQmfReal[pReadIdx[8]], pQmfImag[pReadIdx[8]],
+ p[3]);
+ pfft[FFT_IDX_R(2)] = accu1 + accu3;
+ pfft[FFT_IDX_I(2)] = accu2 + accu4;
+
+ cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[1]], pQmfImag[pReadIdx[1]],
+ p[4]);
+ cplxMultDiv2(&accu3, &accu4, pQmfReal[pReadIdx[9]], pQmfImag[pReadIdx[9]],
+ p[5]);
+ pfft[FFT_IDX_R(3)] = accu1 + accu3;
+ pfft[FFT_IDX_I(3)] = accu2 + accu4;
+
+ pfft[FFT_IDX_R(4)] = fMultDiv2(pQmfImag[pReadIdx[10]], p[7].v.im) -
+ fMultDiv2(pQmfImag[pReadIdx[2]], p[6].v.im);
+ pfft[FFT_IDX_I(4)] = fMultDiv2(pQmfReal[pReadIdx[2]], p[6].v.im) -
+ fMultDiv2(pQmfReal[pReadIdx[10]], p[7].v.im);
+
+ cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[3]], pQmfImag[pReadIdx[3]],
+ p[8]);
+ cplxMultDiv2(&accu3, &accu4, pQmfReal[pReadIdx[11]], pQmfImag[pReadIdx[11]],
+ p[9]);
+ pfft[FFT_IDX_R(5)] = accu1 + accu3;
+ pfft[FFT_IDX_I(5)] = accu2 + accu4;
+
+ cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[4]], pQmfImag[pReadIdx[4]],
+ p[10]);
+ cplxMultDiv2(&accu3, &accu4, pQmfReal[pReadIdx[12]], pQmfImag[pReadIdx[12]],
+ p[11]);
+ pfft[FFT_IDX_R(6)] = accu1 + accu3;
+ pfft[FFT_IDX_I(6)] = accu2 + accu4;
+
+ cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[5]], pQmfImag[pReadIdx[5]],
+ p[12]);
+ pfft[FFT_IDX_R(7)] = accu1;
+ pfft[FFT_IDX_I(7)] = accu2;
+
+ /* fft modulation */
+ fft_8(pfft);
+ sc = 1 + 2;
+
+ if (invert) {
+ mHybridReal[0] = pfft[FFT_IDX_R(7)] << sc;
+ mHybridImag[0] = pfft[FFT_IDX_I(7)] << sc;
+ mHybridReal[1] = pfft[FFT_IDX_R(0)] << sc;
+ mHybridImag[1] = pfft[FFT_IDX_I(0)] << sc;
+
+ mHybridReal[2] = pfft[FFT_IDX_R(6)] << sc;
+ mHybridImag[2] = pfft[FFT_IDX_I(6)] << sc;
+ mHybridReal[3] = pfft[FFT_IDX_R(1)] << sc;
+ mHybridImag[3] = pfft[FFT_IDX_I(1)] << sc;
+
+ mHybridReal[4] = pfft[FFT_IDX_R(2)] << sc;
+ mHybridReal[4] += pfft[FFT_IDX_R(5)] << sc;
+ mHybridImag[4] = pfft[FFT_IDX_I(2)] << sc;
+ mHybridImag[4] += pfft[FFT_IDX_I(5)] << sc;
+
+ mHybridReal[5] = pfft[FFT_IDX_R(3)] << sc;
+ mHybridReal[5] += pfft[FFT_IDX_R(4)] << sc;
+ mHybridImag[5] = pfft[FFT_IDX_I(3)] << sc;
+ mHybridImag[5] += pfft[FFT_IDX_I(4)] << sc;
+ } else {
+ for (k = 0; k < 8; k++) {
+ mHybridReal[k] = pfft[FFT_IDX_R(k)] << sc;
+ mHybridImag[k] = pfft[FFT_IDX_I(k)] << sc;
+ }
+ }
+}
+
+static INT kChannelFiltering(const FIXP_DBL *const pQmfReal,
+ const FIXP_DBL *const pQmfImag,
+ const INT *const pReadIdx,
+ FIXP_DBL *const mHybridReal,
+ FIXP_DBL *const mHybridImag,
+ const SCHAR hybridConfig) {
+ INT err = 0;
+
+ switch (hybridConfig) {
+ case 2:
+ case -2:
+ dualChannelFiltering(pQmfReal, pQmfImag, pReadIdx, mHybridReal,
+ mHybridImag, (hybridConfig < 0) ? 1 : 0);
+ break;
+ case 4:
+ case -4:
+ fourChannelFiltering(pQmfReal, pQmfImag, pReadIdx, mHybridReal,
+ mHybridImag, (hybridConfig < 0) ? 1 : 0);
+ break;
+ case 8:
+ case -8:
+ eightChannelFiltering(pQmfReal, pQmfImag, pReadIdx, mHybridReal,
+ mHybridImag, (hybridConfig < 0) ? 1 : 0);
+ break;
+ default:
+ err = -1;
+ }
+
+ return err;
+}
diff --git a/fdk-aac/libFDK/src/FDK_lpc.cpp b/fdk-aac/libFDK/src/FDK_lpc.cpp
new file mode 100644
index 0000000..7d7e691
--- /dev/null
+++ b/fdk-aac/libFDK/src/FDK_lpc.cpp
@@ -0,0 +1,487 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Manuel Jander
+
+ Description: LPC related functions
+
+*******************************************************************************/
+
+#include "FDK_lpc.h"
+
+/* Internal scaling of LPC synthesis to avoid overflow of filte states.
+ This depends on the LPC order, because the LPC order defines the amount
+ of MAC operations. */
+static SCHAR order_ld[LPC_MAX_ORDER] = {
+ /* Assume that Synthesis filter output does not clip and filter
+ accu does change no more than 1.0 for each iteration.
+ ceil(0.5*log((1:24))/log(2)) */
+ 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3};
+
+/* IIRLattice */
+#ifndef FUNCTION_CLpc_SynthesisLattice_SGL
+void CLpc_SynthesisLattice(FIXP_DBL *signal, const int signal_size,
+ const int signal_e, const int signal_e_out,
+ const int inc, const FIXP_SGL *coeff,
+ const int order, FIXP_DBL *state) {
+ int i, j;
+ FIXP_DBL *pSignal;
+ int shift;
+
+ FDK_ASSERT(order <= LPC_MAX_ORDER);
+ FDK_ASSERT(order > 0);
+
+ if (inc == -1)
+ pSignal = &signal[signal_size - 1];
+ else
+ pSignal = &signal[0];
+
+ /*
+ tmp = x(k) - K(M)*g(M);
+ for m=M-1:-1:1
+ tmp = tmp - K(m) * g(m);
+ g(m+1) = g(m) + K(m) * tmp;
+ endfor
+ g(1) = tmp;
+
+ y(k) = tmp;
+ */
+
+ shift = -order_ld[order - 1];
+
+ for (i = signal_size; i != 0; i--) {
+ FIXP_DBL *pState = state + order - 1;
+ const FIXP_SGL *pCoeff = coeff + order - 1;
+ FIXP_DBL tmp;
+
+ tmp = scaleValue(*pSignal, shift + signal_e) -
+ fMultDiv2(*pCoeff--, *pState--);
+ for (j = order - 1; j != 0; j--) {
+ tmp = fMultSubDiv2(tmp, pCoeff[0], pState[0]);
+ pState[1] = pState[0] + (fMultDiv2(*pCoeff--, tmp) << 2);
+ pState--;
+ }
+
+ *pSignal = scaleValueSaturate(tmp, -shift - signal_e_out);
+
+ /* exponent of state[] is -1 */
+ pState[1] = tmp << 1;
+ pSignal += inc;
+ }
+}
+#endif
+
+#ifndef FUNCTION_CLpc_SynthesisLattice_DBL
+void CLpc_SynthesisLattice(FIXP_DBL *signal, const int signal_size,
+ const int signal_e, const int signal_e_out,
+ const int inc, const FIXP_DBL *coeff,
+ const int order, FIXP_DBL *state) {
+ int i, j;
+ FIXP_DBL *pSignal;
+
+ FDK_ASSERT(order <= LPC_MAX_ORDER);
+ FDK_ASSERT(order > 0);
+
+ if (inc == -1)
+ pSignal = &signal[signal_size - 1];
+ else
+ pSignal = &signal[0];
+
+ FDK_ASSERT(signal_size > 0);
+ for (i = signal_size; i != 0; i--) {
+ FIXP_DBL *pState = state + order - 1;
+ const FIXP_DBL *pCoeff = coeff + order - 1;
+ FIXP_DBL tmp, accu;
+
+ accu =
+ fMultSubDiv2(scaleValue(*pSignal, signal_e - 1), *pCoeff--, *pState--);
+ tmp = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS);
+
+ for (j = order - 1; j != 0; j--) {
+ accu = fMultSubDiv2(tmp >> 1, pCoeff[0], pState[0]);
+ tmp = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS);
+
+ accu = fMultAddDiv2(pState[0] >> 1, *pCoeff--, tmp);
+ pState[1] = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS);
+
+ pState--;
+ }
+
+ *pSignal = scaleValue(tmp, -signal_e_out);
+
+ /* exponent of state[] is 0 */
+ pState[1] = tmp;
+ pSignal += inc;
+ }
+}
+
+#endif
+
+/* LPC_SYNTHESIS_IIR version */
+void CLpc_Synthesis(FIXP_DBL *signal, const int signal_size, const int signal_e,
+ const int inc, const FIXP_LPC_TNS *lpcCoeff_m,
+ const int lpcCoeff_e, const int order, FIXP_DBL *state,
+ int *pStateIndex) {
+ int i, j;
+ FIXP_DBL *pSignal;
+ int stateIndex = *pStateIndex;
+
+ FIXP_LPC_TNS coeff[2 * LPC_MAX_ORDER];
+ FDKmemcpy(&coeff[0], lpcCoeff_m, order * sizeof(FIXP_LPC_TNS));
+ FDKmemcpy(&coeff[order], lpcCoeff_m, order * sizeof(FIXP_LPC_TNS));
+
+ FDK_ASSERT(order <= LPC_MAX_ORDER);
+ FDK_ASSERT(stateIndex < order);
+
+ if (inc == -1)
+ pSignal = &signal[signal_size - 1];
+ else
+ pSignal = &signal[0];
+
+ /* y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order) */
+
+ for (i = 0; i < signal_size; i++) {
+ FIXP_DBL x;
+ const FIXP_LPC_TNS *pCoeff = coeff + order - stateIndex;
+
+ x = scaleValue(*pSignal, -(lpcCoeff_e + 1));
+ for (j = 0; j < order; j++) {
+ x -= fMultDiv2(state[j], pCoeff[j]);
+ }
+ x = SATURATE_SHIFT(x, -lpcCoeff_e - 1, DFRACT_BITS);
+
+ /* Update states */
+ stateIndex = ((stateIndex - 1) < 0) ? (order - 1) : (stateIndex - 1);
+ state[stateIndex] = x;
+
+ *pSignal = scaleValue(x, signal_e);
+ pSignal += inc;
+ }
+
+ *pStateIndex = stateIndex;
+}
+/* default version */
+void CLpc_Synthesis(FIXP_DBL *signal, const int signal_size, const int signal_e,
+ const int inc, const FIXP_LPC *lpcCoeff_m,
+ const int lpcCoeff_e, const int order, FIXP_DBL *state,
+ int *pStateIndex) {
+ int i, j;
+ FIXP_DBL *pSignal;
+ int stateIndex = *pStateIndex;
+
+ FIXP_LPC coeff[2 * LPC_MAX_ORDER];
+ FDKmemcpy(&coeff[0], lpcCoeff_m, order * sizeof(FIXP_LPC));
+ FDKmemcpy(&coeff[order], lpcCoeff_m, order * sizeof(FIXP_LPC));
+
+ FDK_ASSERT(order <= LPC_MAX_ORDER);
+ FDK_ASSERT(stateIndex < order);
+
+ if (inc == -1)
+ pSignal = &signal[signal_size - 1];
+ else
+ pSignal = &signal[0];
+
+ /* y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order) */
+
+ for (i = 0; i < signal_size; i++) {
+ FIXP_DBL x;
+ const FIXP_LPC *pCoeff = coeff + order - stateIndex;
+
+ x = scaleValue(*pSignal, -(lpcCoeff_e + 1));
+ for (j = 0; j < order; j++) {
+ x -= fMultDiv2(state[j], pCoeff[j]);
+ }
+ x = SATURATE_SHIFT(x, -lpcCoeff_e - 1, DFRACT_BITS);
+
+ /* Update states */
+ stateIndex = ((stateIndex - 1) < 0) ? (order - 1) : (stateIndex - 1);
+ state[stateIndex] = x;
+
+ *pSignal = scaleValue(x, signal_e);
+ pSignal += inc;
+ }
+
+ *pStateIndex = stateIndex;
+}
+
+/* FIR */
+void CLpc_Analysis(FIXP_DBL *RESTRICT signal, const int signal_size,
+ const FIXP_LPC lpcCoeff_m[], const int lpcCoeff_e,
+ const int order, FIXP_DBL *RESTRICT filtState,
+ int *filtStateIndex) {
+ int stateIndex;
+ INT i, j, shift = lpcCoeff_e + 1; /* +1, because fMultDiv2 */
+ FIXP_DBL tmp;
+
+ if (order <= 0) {
+ return;
+ }
+ if (filtStateIndex != NULL) {
+ stateIndex = *filtStateIndex;
+ } else {
+ stateIndex = 0;
+ }
+
+ /* keep filter coefficients twice and save memory copy operation in
+ modulo state buffer */
+ FIXP_LPC coeff[2 * LPC_MAX_ORDER];
+ FIXP_LPC *pCoeff;
+ FDKmemcpy(&coeff[0], lpcCoeff_m, order * sizeof(FIXP_LPC));
+ FDKmemcpy(&coeff[order], lpcCoeff_m, order * sizeof(FIXP_LPC));
+
+ /*
+ # Analysis filter, obtain residual.
+ for k = 0:BL-1
+ err(i-BL+k) = a * inputSignal(i-BL+k:-1:i-BL-M+k);
+ endfor
+ */
+
+ FDK_ASSERT(shift >= 0);
+
+ for (j = 0; j < signal_size; j++) {
+ pCoeff = &coeff[(order - stateIndex)];
+
+ tmp = signal[j] >> shift;
+ for (i = 0; i < order; i++) {
+ tmp = fMultAddDiv2(tmp, pCoeff[i], filtState[i]);
+ }
+
+ stateIndex =
+ ((stateIndex - 1) < 0) ? (stateIndex - 1 + order) : (stateIndex - 1);
+ filtState[stateIndex] = signal[j];
+
+ signal[j] = tmp << shift;
+ }
+
+ if (filtStateIndex != NULL) {
+ *filtStateIndex = stateIndex;
+ }
+}
+
+/* For the LPC_SYNTHESIS_IIR version */
+INT CLpc_ParcorToLpc(const FIXP_LPC_TNS reflCoeff[], FIXP_LPC_TNS LpcCoeff[],
+ INT numOfCoeff, FIXP_DBL workBuffer[]) {
+ INT i, j;
+ INT shiftval,
+ par2LpcShiftVal = 6; /* 6 should be enough, bec. max(numOfCoeff) = 20 */
+ FIXP_DBL maxVal = (FIXP_DBL)0;
+
+ workBuffer[0] = FX_LPC_TNS2FX_DBL(reflCoeff[0]) >> par2LpcShiftVal;
+ for (i = 1; i < numOfCoeff; i++) {
+ for (j = 0; j < i / 2; j++) {
+ FIXP_DBL tmp1, tmp2;
+
+ tmp1 = workBuffer[j];
+ tmp2 = workBuffer[i - 1 - j];
+ workBuffer[j] += fMult(reflCoeff[i], tmp2);
+ workBuffer[i - 1 - j] += fMult(reflCoeff[i], tmp1);
+ }
+ if (i & 1) {
+ workBuffer[j] += fMult(reflCoeff[i], workBuffer[j]);
+ }
+
+ workBuffer[i] = FX_LPC_TNS2FX_DBL(reflCoeff[i]) >> par2LpcShiftVal;
+ }
+
+ /* calculate exponent */
+ for (i = 0; i < numOfCoeff; i++) {
+ maxVal = fMax(maxVal, fAbs(workBuffer[i]));
+ }
+
+ shiftval = fMin(fNorm(maxVal), par2LpcShiftVal);
+
+ for (i = 0; i < numOfCoeff; i++) {
+ LpcCoeff[i] = FX_DBL2FX_LPC_TNS(workBuffer[i] << shiftval);
+ }
+
+ return (par2LpcShiftVal - shiftval);
+}
+/* Default version */
+INT CLpc_ParcorToLpc(const FIXP_LPC reflCoeff[], FIXP_LPC LpcCoeff[],
+ INT numOfCoeff, FIXP_DBL workBuffer[]) {
+ INT i, j;
+ INT shiftval,
+ par2LpcShiftVal = 6; /* 6 should be enough, bec. max(numOfCoeff) = 20 */
+ FIXP_DBL maxVal = (FIXP_DBL)0;
+
+ workBuffer[0] = FX_LPC2FX_DBL(reflCoeff[0]) >> par2LpcShiftVal;
+ for (i = 1; i < numOfCoeff; i++) {
+ for (j = 0; j < i / 2; j++) {
+ FIXP_DBL tmp1, tmp2;
+
+ tmp1 = workBuffer[j];
+ tmp2 = workBuffer[i - 1 - j];
+ workBuffer[j] += fMult(reflCoeff[i], tmp2);
+ workBuffer[i - 1 - j] += fMult(reflCoeff[i], tmp1);
+ }
+ if (i & 1) {
+ workBuffer[j] += fMult(reflCoeff[i], workBuffer[j]);
+ }
+
+ workBuffer[i] = FX_LPC2FX_DBL(reflCoeff[i]) >> par2LpcShiftVal;
+ }
+
+ /* calculate exponent */
+ for (i = 0; i < numOfCoeff; i++) {
+ maxVal = fMax(maxVal, fAbs(workBuffer[i]));
+ }
+
+ shiftval = fMin(fNorm(maxVal), par2LpcShiftVal);
+
+ for (i = 0; i < numOfCoeff; i++) {
+ LpcCoeff[i] = FX_DBL2FX_LPC(workBuffer[i] << shiftval);
+ }
+
+ return (par2LpcShiftVal - shiftval);
+}
+
+void CLpc_AutoToParcor(FIXP_DBL acorr[], const int acorr_e,
+ FIXP_LPC reflCoeff[], const int numOfCoeff,
+ FIXP_DBL *pPredictionGain_m, INT *pPredictionGain_e) {
+ INT i, j, scale = 0;
+ FIXP_DBL parcorWorkBuffer[LPC_MAX_ORDER];
+
+ FIXP_DBL *workBuffer = parcorWorkBuffer;
+ FIXP_DBL autoCorr_0 = acorr[0];
+
+ FDKmemclear(reflCoeff, numOfCoeff * sizeof(FIXP_LPC));
+
+ if (autoCorr_0 == FL2FXCONST_DBL(0.0)) {
+ if (pPredictionGain_m != NULL) {
+ *pPredictionGain_m = FL2FXCONST_DBL(0.5f);
+ *pPredictionGain_e = 1;
+ }
+ return;
+ }
+
+ FDKmemcpy(workBuffer, acorr + 1, numOfCoeff * sizeof(FIXP_DBL));
+ for (i = 0; i < numOfCoeff; i++) {
+ LONG sign = ((LONG)workBuffer[0] >> (DFRACT_BITS - 1));
+ FIXP_DBL tmp = (FIXP_DBL)((LONG)workBuffer[0] ^ sign);
+
+ /* Check preconditions for division function: num<=denum */
+ /* For 1st iteration acorr[0] cannot be 0, it is checked before loop */
+ /* Due to exor operation with "sign", num(=tmp) is greater/equal 0 */
+ if (acorr[0] < tmp) break;
+
+ /* tmp = div(num, denum, 16) */
+ tmp = (FIXP_DBL)((LONG)schur_div(tmp, acorr[0], FRACT_BITS) ^ (~sign));
+
+ reflCoeff[i] = FX_DBL2FX_LPC(tmp);
+
+ for (j = numOfCoeff - i - 1; j >= 0; j--) {
+ FIXP_DBL accu1 = fMult(tmp, acorr[j]);
+ FIXP_DBL accu2 = fMult(tmp, workBuffer[j]);
+ workBuffer[j] += accu1;
+ acorr[j] += accu2;
+ }
+ /* Check preconditions for division function: denum (=acorr[0]) > 0 */
+ if (acorr[0] == (FIXP_DBL)0) break;
+
+ workBuffer++;
+ }
+
+ if (pPredictionGain_m != NULL) {
+ if (acorr[0] > (FIXP_DBL)0) {
+ /* prediction gain = signal power / error (residual) power */
+ *pPredictionGain_m = fDivNormSigned(autoCorr_0, acorr[0], &scale);
+ *pPredictionGain_e = scale;
+ } else {
+ *pPredictionGain_m = (FIXP_DBL)0;
+ *pPredictionGain_e = 0;
+ }
+ }
+}
diff --git a/fdk-aac/libFDK/src/FDK_matrixCalloc.cpp b/fdk-aac/libFDK/src/FDK_matrixCalloc.cpp
new file mode 100644
index 0000000..5d5c521
--- /dev/null
+++ b/fdk-aac/libFDK/src/FDK_matrixCalloc.cpp
@@ -0,0 +1,315 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: matrix memory allocation
+
+*******************************************************************************/
+
+#include "FDK_matrixCalloc.h"
+
+#include "genericStds.h"
+
+void *fdkCallocMatrix1D_aligned(UINT dim1, UINT size) {
+ return FDKaalloc(dim1 * size, ALIGNMENT_DEFAULT);
+}
+
+void *fdkCallocMatrix1D_int(UINT dim, UINT size, MEMORY_SECTION s) {
+ return FDKcalloc_L(dim, size, s);
+}
+
+void *fdkCallocMatrix1D_int_aligned(UINT dim, UINT size, MEMORY_SECTION s) {
+ return FDKaalloc_L(dim * size, ALIGNMENT_DEFAULT, s);
+}
+
+void fdkFreeMatrix1D(void *p) {
+ if (p != NULL) {
+ FDKfree_L(p);
+ }
+}
+
+void fdkFreeMatrix1D_aligned(void *p) {
+ if (p != NULL) {
+ FDKafree_L(p);
+ }
+}
+
+void *fdkCallocMatrix1D(UINT dim1, UINT size) { return FDKcalloc(dim1, size); }
+
+/* 2D */
+void **fdkCallocMatrix2D(UINT dim1, UINT dim2, UINT size) {
+ void **p1;
+ UINT i;
+ char *p2;
+ if (!dim1 || !dim2) return NULL;
+ if ((p1 = (void **)fdkCallocMatrix1D(dim1, sizeof(void *))) == NULL) {
+ goto bail;
+ }
+ if ((p2 = (char *)fdkCallocMatrix1D(dim1 * dim2, size)) == NULL) {
+ fdkFreeMatrix1D(p1);
+ p1 = NULL;
+ goto bail;
+ }
+ for (i = 0; i < dim1; i++) {
+ p1[i] = p2;
+ p2 += dim2 * size;
+ }
+bail:
+ return p1;
+}
+
+void **fdkCallocMatrix2D_aligned(UINT dim1, UINT dim2, UINT size) {
+ void **p1;
+ UINT i;
+ char *p2;
+ if (!dim1 || !dim2) return NULL;
+ if ((p1 = (void **)fdkCallocMatrix1D(dim1, sizeof(void *))) == NULL) {
+ goto bail;
+ }
+ if ((p2 = (char *)fdkCallocMatrix1D_aligned(dim1 * dim2, size)) == NULL) {
+ fdkFreeMatrix1D(p1);
+ p1 = NULL;
+ goto bail;
+ }
+ for (i = 0; i < dim1; i++) {
+ p1[i] = p2;
+ p2 += dim2 * size;
+ }
+bail:
+ return p1;
+}
+
+void fdkFreeMatrix2D(void **p) {
+ if (!p) return;
+ fdkFreeMatrix1D(p[0]);
+ fdkFreeMatrix1D(p);
+}
+
+void fdkFreeMatrix2D_aligned(void **p) {
+ if (!p) return;
+ fdkFreeMatrix1D_aligned(p[0]);
+ fdkFreeMatrix1D(p);
+}
+
+void **fdkCallocMatrix2D_int(UINT dim1, UINT dim2, UINT size,
+ MEMORY_SECTION s) {
+ void **p1;
+ UINT i;
+ char *p2;
+
+ if (!dim1 || !dim2) return NULL;
+ if ((p1 = (void **)fdkCallocMatrix1D_int(dim1, sizeof(void *), s)) == NULL) {
+ goto bail;
+ }
+ if ((p2 = (char *)fdkCallocMatrix1D_int(dim1 * dim2, size, s)) == NULL) {
+ fdkFreeMatrix1D(p1);
+ p1 = NULL;
+ goto bail;
+ }
+ for (i = 0; i < dim1; i++) {
+ p1[i] = p2;
+ p2 += dim2 * size;
+ }
+bail:
+ return p1;
+}
+
+void **fdkCallocMatrix2D_int_aligned(UINT dim1, UINT dim2, UINT size,
+ MEMORY_SECTION s) {
+ void **p1;
+ UINT i;
+ char *p2;
+
+ if (!dim1 || !dim2) return NULL;
+ if ((p1 = (void **)fdkCallocMatrix1D_int(dim1, sizeof(void *), s)) == NULL) {
+ goto bail;
+ }
+ if ((p2 = (char *)fdkCallocMatrix1D_int_aligned(dim1 * dim2, size, s)) ==
+ NULL) {
+ fdkFreeMatrix1D(p1);
+ p1 = NULL;
+ goto bail;
+ }
+ for (i = 0; i < dim1; i++) {
+ p1[i] = p2;
+ p2 += dim2 * size;
+ }
+bail:
+ return p1;
+}
+
+/* 3D */
+void ***fdkCallocMatrix3D(UINT dim1, UINT dim2, UINT dim3, UINT size) {
+ void ***p1;
+ UINT i, j;
+ void **p2;
+ char *p3;
+
+ if (!dim1 || !dim2 || !dim3) return NULL;
+ if ((p1 = (void ***)fdkCallocMatrix1D(dim1, sizeof(void **))) == NULL) {
+ goto bail;
+ }
+ if ((p2 = (void **)fdkCallocMatrix1D(dim1 * dim2, sizeof(void *))) == NULL) {
+ fdkFreeMatrix1D(p1);
+ p1 = NULL;
+ goto bail;
+ }
+ p1[0] = p2;
+ if ((p3 = (char *)fdkCallocMatrix1D(dim1 * dim2 * dim3, size)) == NULL) {
+ fdkFreeMatrix1D(p1);
+ fdkFreeMatrix1D(p2);
+ p1 = NULL;
+ p2 = NULL;
+ goto bail;
+ }
+ for (i = 0; i < dim1; i++) {
+ p1[i] = p2;
+ for (j = 0; j < dim2; j++) {
+ p2[j] = p3;
+ p3 += dim3 * size;
+ }
+ p2 += dim2;
+ }
+bail:
+ return p1;
+}
+
+void fdkFreeMatrix3D(void ***p) {
+ if (!p) return;
+ if (p[0] != NULL) fdkFreeMatrix1D(p[0][0]);
+ fdkFreeMatrix1D(p[0]);
+ fdkFreeMatrix1D(p);
+}
+
+void ***fdkCallocMatrix3D_int(UINT dim1, UINT dim2, UINT dim3, UINT size,
+ MEMORY_SECTION s) {
+ void ***p1;
+ UINT i, j;
+ void **p2;
+ char *p3;
+
+ if (!dim1 || !dim2 || !dim3) return NULL;
+ if ((p1 = (void ***)fdkCallocMatrix1D_int(dim1, sizeof(void **), s)) ==
+ NULL) {
+ goto bail;
+ }
+ if ((p2 = (void **)fdkCallocMatrix1D_int(dim1 * dim2, sizeof(void *), s)) ==
+ NULL) {
+ fdkFreeMatrix1D(p1);
+ p1 = NULL;
+ goto bail;
+ }
+ p1[0] = p2;
+ if ((p3 = (char *)fdkCallocMatrix1D_int(dim1 * dim2 * dim3, size, s)) ==
+ NULL) {
+ fdkFreeMatrix1D(p1);
+ fdkFreeMatrix1D(p2);
+ p1 = NULL;
+ p2 = NULL;
+ goto bail;
+ }
+ for (i = 0; i < dim1; i++) {
+ p1[i] = p2;
+ for (j = 0; j < dim2; j++) {
+ p2[j] = p3;
+ p3 += dim3 * size;
+ }
+ p2 += dim2;
+ }
+bail:
+ return p1;
+}
diff --git a/fdk-aac/libFDK/src/FDK_qmf_domain.cpp b/fdk-aac/libFDK/src/FDK_qmf_domain.cpp
new file mode 100644
index 0000000..3245deb
--- /dev/null
+++ b/fdk-aac/libFDK/src/FDK_qmf_domain.cpp
@@ -0,0 +1,1018 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: Module to efficiently handle QMF data for multiple channels and
+ to share the data between e.g. SBR and MPS
+
+*******************************************************************************/
+
+#include "FDK_qmf_domain.h"
+
+#include "common_fix.h"
+
+#define WORKBUFFER1_TAG 0
+#define WORKBUFFER2_TAG 1
+
+#define WORKBUFFER3_TAG 4
+#define WORKBUFFER4_TAG 5
+#define WORKBUFFER5_TAG 6
+#define WORKBUFFER6_TAG 7
+
+C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL, QMF_WB_SECTION_SIZE,
+ SECT_DATA_L1, WORKBUFFER1_TAG)
+C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL, QMF_WB_SECTION_SIZE,
+ SECT_DATA_L2, WORKBUFFER2_TAG)
+C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL, QMF_WB_SECTION_SIZE,
+ SECT_DATA_L2, WORKBUFFER3_TAG)
+C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL, QMF_WB_SECTION_SIZE,
+ SECT_DATA_L2, WORKBUFFER4_TAG)
+C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL, QMF_WB_SECTION_SIZE,
+ SECT_DATA_L2, WORKBUFFER5_TAG)
+C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL, QMF_WB_SECTION_SIZE,
+ SECT_DATA_L2, WORKBUFFER6_TAG)
+
+/*! Analysis states buffer. <br>
+ Dimension: #((8) + (1)) */
+C_ALLOC_MEM2(AnaQmfStates, FIXP_QAS, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS,
+ ((8) + (1)))
+
+/*! Synthesis states buffer. <br>
+ Dimension: #((8) + (1)) */
+C_ALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS,
+ ((8) + (1)))
+
+/*! Pointer to real qmf data for each time slot. <br>
+ Dimension: #((8) + (1)) */
+C_ALLOC_MEM2(QmfSlotsReal, FIXP_DBL *,
+ QMF_DOMAIN_MAX_TIMESLOTS + QMF_DOMAIN_MAX_OV_TIMESLOTS,
+ ((8) + (1)))
+
+/*! Pointer to imaginary qmf data for each time slot. <br>
+ Dimension: #((8) + (1)) */
+C_ALLOC_MEM2(QmfSlotsImag, FIXP_DBL *,
+ QMF_DOMAIN_MAX_TIMESLOTS + QMF_DOMAIN_MAX_OV_TIMESLOTS,
+ ((8) + (1)))
+
+/*! QMF overlap buffer. <br>
+ Dimension: #((8) + (1)) */
+C_AALLOC_MEM2(QmfOverlapBuffer, FIXP_DBL,
+ 2 * QMF_DOMAIN_MAX_OV_TIMESLOTS * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
+ ((8) + (1)))
+
+/*! Analysis states buffer. <br>
+ Dimension: #((8) + (1)) */
+C_ALLOC_MEM2(AnaQmfStates16, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16,
+ ((8) + (1)))
+
+/*! Analysis states buffer. <br>
+ Dimension: #((8) + (1)) */
+C_ALLOC_MEM2(AnaQmfStates24, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24,
+ ((8) + (1)))
+
+/*! Analysis states buffer. <br>
+ Dimension: #((8) + (1)) */
+C_ALLOC_MEM2(AnaQmfStates32, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
+ ((8) + (1)))
+
+/*! Pointer to real qmf data for each time slot. <br>
+ Dimension: #((8) + (1)) */
+C_ALLOC_MEM2(QmfSlotsReal16, FIXP_DBL *,
+ QMF_DOMAIN_TIMESLOTS_16 + QMF_DOMAIN_OV_TIMESLOTS_16, ((8) + (1)))
+
+/*! Pointer to real qmf data for each time slot. <br>
+ Dimension: #((8) + (1)) */
+C_ALLOC_MEM2(QmfSlotsReal32, FIXP_DBL *,
+ QMF_DOMAIN_TIMESLOTS_32 + QMF_DOMAIN_OV_TIMESLOTS_32, ((8) + (1)))
+
+/*! Pointer to imaginary qmf data for each time slot. <br>
+ Dimension: #((8) + (1)) */
+C_ALLOC_MEM2(QmfSlotsImag16, FIXP_DBL *,
+ QMF_DOMAIN_TIMESLOTS_16 + QMF_DOMAIN_OV_TIMESLOTS_16, ((8) + (1)))
+
+/*! Pointer to imaginary qmf data for each time slot. <br>
+ Dimension: #((8) + (1)) */
+C_ALLOC_MEM2(QmfSlotsImag32, FIXP_DBL *,
+ QMF_DOMAIN_TIMESLOTS_32 + QMF_DOMAIN_OV_TIMESLOTS_32, ((8) + (1)))
+
+/*! QMF overlap buffer. <br>
+ Dimension: #((8) + (1)) */
+C_AALLOC_MEM2(QmfOverlapBuffer16, FIXP_DBL,
+ 2 * QMF_DOMAIN_OV_TIMESLOTS_16 * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
+ ((8) + (1)))
+
+/*! QMF overlap buffer. <br>
+ Dimension: #((8) + (1)) */
+C_AALLOC_MEM2(QmfOverlapBuffer32, FIXP_DBL,
+ 2 * QMF_DOMAIN_OV_TIMESLOTS_32 * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
+ ((8) + (1)))
+
+static int FDK_QmfDomain_FreePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) {
+ int err = 0;
+ int ch;
+
+ for (ch = 0; ch < ((8) + (1)); ch++) {
+ if (qd->QmfDomainIn[ch].pAnaQmfStates) {
+ if (qd->globalConf.nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_16) {
+ FreeAnaQmfStates16(&qd->QmfDomainIn[ch].pAnaQmfStates);
+ } else if (qd->globalConf.nBandsAnalysis ==
+ QMF_DOMAIN_ANALYSIS_QMF_BANDS_24) {
+ FreeAnaQmfStates24(&qd->QmfDomainIn[ch].pAnaQmfStates);
+ } else if (qd->globalConf.nBandsAnalysis ==
+ QMF_DOMAIN_ANALYSIS_QMF_BANDS_32) {
+ FreeAnaQmfStates32(&qd->QmfDomainIn[ch].pAnaQmfStates);
+ } else {
+ FreeAnaQmfStates(&qd->QmfDomainIn[ch].pAnaQmfStates);
+ }
+ }
+
+ if (qd->QmfDomainIn[ch].pOverlapBuffer) {
+ if (qd->globalConf.nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_16) {
+ FreeQmfOverlapBuffer16(&qd->QmfDomainIn[ch].pOverlapBuffer);
+ } else if (qd->globalConf.nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_32) {
+ FreeQmfOverlapBuffer32(&qd->QmfDomainIn[ch].pOverlapBuffer);
+ } else {
+ FreeQmfOverlapBuffer(&qd->QmfDomainIn[ch].pOverlapBuffer);
+ }
+ }
+
+ if (qd->QmfDomainIn[ch].hQmfSlotsReal) {
+ if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
+ FreeQmfSlotsReal16(&qd->QmfDomainIn[ch].hQmfSlotsReal);
+ } else if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
+ FreeQmfSlotsReal32(&qd->QmfDomainIn[ch].hQmfSlotsReal);
+ } else {
+ FreeQmfSlotsReal(&qd->QmfDomainIn[ch].hQmfSlotsReal);
+ }
+ }
+
+ if (qd->QmfDomainIn[ch].hQmfSlotsImag) {
+ if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
+ FreeQmfSlotsImag16(&qd->QmfDomainIn[ch].hQmfSlotsImag);
+ }
+ if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
+ FreeQmfSlotsImag32(&qd->QmfDomainIn[ch].hQmfSlotsImag);
+ } else {
+ FreeQmfSlotsImag(&qd->QmfDomainIn[ch].hQmfSlotsImag);
+ }
+ }
+ }
+
+ for (ch = 0; ch < ((8) + (1)); ch++) {
+ if (qd->QmfDomainOut[ch].pSynQmfStates) {
+ FreeSynQmfStates(&qd->QmfDomainOut[ch].pSynQmfStates);
+ }
+ }
+
+ return err;
+}
+
+static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) {
+ int err = 0;
+ int ch;
+ HANDLE_FDK_QMF_DOMAIN_GC gc = &qd->globalConf;
+
+ if ((gc->nInputChannels > ((8) + (1))) || (gc->nOutputChannels > ((8) + (1))))
+ return err = 1;
+ for (ch = 0; ch < gc->nInputChannels; ch++) {
+ int size;
+
+ size = gc->nBandsAnalysis * 10;
+ if (size > 0) {
+ if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_16) {
+ if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
+ if (NULL ==
+ (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates16(ch)))
+ goto bail;
+ }
+ } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_24) {
+ if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
+ if (NULL ==
+ (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates24(ch)))
+ goto bail;
+ }
+ } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_32) {
+ if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
+ if (NULL ==
+ (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates32(ch)))
+ goto bail;
+ }
+ } else {
+ if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
+ if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates(ch)))
+ goto bail;
+ }
+ }
+ } else {
+ qd->QmfDomainIn[ch].pAnaQmfStates = NULL;
+ }
+
+ size = gc->nQmfOvTimeSlots + gc->nQmfTimeSlots;
+ if (size > 0) {
+ if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
+ if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
+ if (NULL ==
+ (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal16(ch)))
+ goto bail;
+ }
+ if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
+ if (NULL ==
+ (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag16(ch)))
+ goto bail;
+ }
+ } else if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
+ if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
+ if (NULL ==
+ (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal32(ch)))
+ goto bail;
+ }
+ if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
+ if (NULL ==
+ (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag32(ch)))
+ goto bail;
+ }
+ } else {
+ if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
+ if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal(ch)))
+ goto bail;
+ }
+ if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
+ if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag(ch)))
+ goto bail;
+ }
+ }
+ } else {
+ qd->QmfDomainIn[ch].hQmfSlotsReal = NULL;
+ qd->QmfDomainIn[ch].hQmfSlotsImag = NULL;
+ }
+
+ size = gc->nQmfOvTimeSlots * gc->nQmfProcBands * CMPLX_MOD;
+ if (size > 0) {
+ if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_16) {
+ if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
+ if (NULL ==
+ (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer16(ch)))
+ goto bail;
+ }
+ } else if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_32) {
+ if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
+ if (NULL ==
+ (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer32(ch)))
+ goto bail;
+ }
+ } else {
+ if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
+ if (NULL ==
+ (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer(ch)))
+ goto bail;
+ }
+ }
+ } else {
+ qd->QmfDomainIn[ch].pOverlapBuffer = NULL;
+ }
+ }
+
+ for (ch = 0; ch < gc->nOutputChannels; ch++) {
+ int size = gc->nBandsSynthesis * 9;
+ if (size > 0) {
+ if (qd->QmfDomainOut[ch].pSynQmfStates == NULL) {
+ if (NULL == (qd->QmfDomainOut[ch].pSynQmfStates = GetSynQmfStates(ch)))
+ goto bail;
+ }
+ } else {
+ qd->QmfDomainOut[ch].pSynQmfStates = NULL;
+ }
+ }
+
+ return err;
+
+bail:
+ FDK_QmfDomain_FreePersistentMemory(qd);
+ return -1;
+}
+
+QMF_DOMAIN_ERROR FDK_QmfDomain_ClearPersistentMemory(
+ HANDLE_FDK_QMF_DOMAIN hqd) {
+ QMF_DOMAIN_ERROR err = QMF_DOMAIN_OK;
+ int ch, size;
+ if (hqd) {
+ HANDLE_FDK_QMF_DOMAIN_GC gc = &hqd->globalConf;
+
+ size = gc->nQmfOvTimeSlots * gc->nQmfProcBands * CMPLX_MOD;
+ for (ch = 0; ch < gc->nInputChannels; ch++) {
+ if (hqd->QmfDomainIn[ch].pOverlapBuffer) {
+ FDKmemclear(hqd->QmfDomainIn[ch].pOverlapBuffer,
+ size * sizeof(FIXP_DBL));
+ }
+ }
+ if (FDK_QmfDomain_InitFilterBank(hqd, 0)) {
+ err = QMF_DOMAIN_INIT_ERROR;
+ }
+ } else {
+ err = QMF_DOMAIN_INIT_ERROR;
+ }
+ return err;
+}
+
+/*
+ FDK_getWorkBuffer
+
+ Parameters:
+
+ pWorkBuffer i: array of pointers which point to different workbuffer
+ sections workBufferOffset i: offset in the workbuffer to the requested
+ memory memSize i: size of requested memory
+
+ Function:
+
+ The functions returns the address to the requested memory in the workbuffer.
+
+ The overall workbuffer is divided into several sections. There are
+ QMF_MAX_WB_SECTIONS sections of size QMF_WB_SECTION_SIZE. The function
+ selects the workbuffer section with the help of the workBufferOffset and than
+ it verifies whether the requested amount of memory fits into the selected
+ workbuffer section.
+
+ Returns:
+
+ address to workbuffer
+*/
+static FIXP_DBL *FDK_getWorkBuffer(FIXP_DBL **pWorkBuffer,
+ USHORT workBufferOffset,
+ USHORT workBufferSectSize, USHORT memSize) {
+ int idx1;
+ int idx2;
+ FIXP_DBL *pwb;
+
+ /* a section must be a multiple of the number of processing bands (currently
+ * always 64) */
+ FDK_ASSERT((workBufferSectSize % 64) == 0);
+
+ /* calculate offset within the section */
+ idx2 = workBufferOffset % workBufferSectSize;
+ /* calculate section number */
+ idx1 = (workBufferOffset - idx2) / workBufferSectSize;
+ /* maximum sectionnumber is QMF_MAX_WB_SECTIONS */
+ FDK_ASSERT(idx1 < QMF_MAX_WB_SECTIONS);
+
+ /* check, whether workbuffer is available */
+ FDK_ASSERT(pWorkBuffer[idx1] != NULL);
+
+ /* check, whether buffer fits into selected section */
+ FDK_ASSERT((idx2 + memSize) <= workBufferSectSize);
+
+ /* get requested address to workbuffer */
+ pwb = &pWorkBuffer[idx1][idx2];
+
+ return pwb;
+}
+
+static int FDK_QmfDomain_FeedWorkBuffer(HANDLE_FDK_QMF_DOMAIN qd, int ch,
+ FIXP_DBL **pWorkBuffer,
+ USHORT workBufferOffset,
+ USHORT workBufferSectSize, int size) {
+ int err = 0;
+ int mem_needed;
+
+ mem_needed = qd->QmfDomainIn[ch].workBuf_nBands *
+ qd->QmfDomainIn[ch].workBuf_nTimeSlots * CMPLX_MOD;
+ if (mem_needed > size) {
+ return (err = 1);
+ }
+ qd->QmfDomainIn[ch].pWorkBuffer = pWorkBuffer;
+ qd->QmfDomainIn[ch].workBufferOffset = workBufferOffset;
+ qd->QmfDomainIn[ch].workBufferSectSize = workBufferSectSize;
+
+ return err;
+}
+
+int FDK_QmfDomain_IsInitialized(const HANDLE_FDK_QMF_DOMAIN qd) {
+ FDK_ASSERT(qd != NULL);
+ return ((qd->QmfDomainIn[0].pAnaQmfStates == NULL) &&
+ (qd->QmfDomainOut[0].pSynQmfStates == NULL))
+ ? 0
+ : 1;
+}
+
+int FDK_QmfDomain_InitFilterBank(HANDLE_FDK_QMF_DOMAIN qd, UINT extra_flags) {
+ FDK_ASSERT(qd != NULL);
+ int err = 0;
+ int ch, ts;
+ HANDLE_FDK_QMF_DOMAIN_GC gc = &qd->globalConf;
+ int noCols = gc->nQmfTimeSlots;
+ int lsb = gc->nBandsAnalysis;
+ int usb = fMin((INT)gc->nBandsSynthesis, 64);
+ int nProcBands = gc->nQmfProcBands;
+ FDK_ASSERT(nProcBands % ALIGNMENT_DEFAULT == 0);
+
+ if (extra_flags & QMF_FLAG_MPSLDFB) {
+ gc->flags &= ~QMF_FLAG_CLDFB;
+ gc->flags |= QMF_FLAG_MPSLDFB;
+ }
+ for (ch = 0; ch < gc->nInputChannels; ch++) {
+ /* distribute memory to slots array */
+ FIXP_DBL *ptrOv =
+ qd->QmfDomainIn[ch].pOverlapBuffer; /* persistent memory for overlap */
+ if ((ptrOv == NULL) && (gc->nQmfOvTimeSlots != 0)) {
+ err = 1;
+ return err;
+ }
+ /* This assumes the workbuffer defined for ch0 is the big one being used to
+ * hold one full frame of QMF data. */
+ FIXP_DBL **ptr =
+ qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
+ .pWorkBuffer; /* non-persistent workbuffer */
+ USHORT workBufferOffset =
+ qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
+ .workBufferOffset;
+ USHORT workBufferSectSize =
+ qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
+ .workBufferSectSize;
+
+ if ((ptr == NULL) && (gc->nQmfTimeSlots != 0)) {
+ err = 1;
+ return err;
+ }
+
+ qd->QmfDomainIn[ch].pGlobalConf = gc;
+ for (ts = 0; ts < gc->nQmfOvTimeSlots; ts++) {
+ qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = ptrOv;
+ ptrOv += nProcBands;
+ qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = ptrOv;
+ ptrOv += nProcBands;
+ }
+ for (; ts < (gc->nQmfOvTimeSlots + gc->nQmfTimeSlots); ts++) {
+ qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = FDK_getWorkBuffer(
+ ptr, workBufferOffset, workBufferSectSize, nProcBands);
+ workBufferOffset += nProcBands;
+ qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = FDK_getWorkBuffer(
+ ptr, workBufferOffset, workBufferSectSize, nProcBands);
+ workBufferOffset += nProcBands;
+ }
+ err |= qmfInitAnalysisFilterBank(
+ &qd->QmfDomainIn[ch].fb, qd->QmfDomainIn[ch].pAnaQmfStates, noCols,
+ (qd->QmfDomainIn[ch].fb.lsb == 0) ? lsb : qd->QmfDomainIn[ch].fb.lsb,
+ (qd->QmfDomainIn[ch].fb.usb == 0) ? usb : qd->QmfDomainIn[ch].fb.usb,
+ gc->nBandsAnalysis, gc->flags | extra_flags);
+ }
+
+ for (ch = 0; ch < gc->nOutputChannels; ch++) {
+ FIXP_DBL outGain_m = qd->QmfDomainOut[ch].fb.outGain_m;
+ int outGain_e = qd->QmfDomainOut[ch].fb.outGain_e;
+ int outScale = qmfGetOutScalefactor(&qd->QmfDomainOut[ch].fb);
+ err |= qmfInitSynthesisFilterBank(
+ &qd->QmfDomainOut[ch].fb, qd->QmfDomainOut[ch].pSynQmfStates, noCols,
+ (qd->QmfDomainOut[ch].fb.lsb == 0) ? lsb : qd->QmfDomainOut[ch].fb.lsb,
+ (qd->QmfDomainOut[ch].fb.usb == 0) ? usb : qd->QmfDomainOut[ch].fb.usb,
+ gc->nBandsSynthesis, gc->flags | extra_flags);
+ if (outGain_m != (FIXP_DBL)0) {
+ qmfChangeOutGain(&qd->QmfDomainOut[ch].fb, outGain_m, outGain_e);
+ }
+ if (outScale) {
+ qmfChangeOutScalefactor(&qd->QmfDomainOut[ch].fb, outScale);
+ }
+ }
+
+ return err;
+}
+
+void FDK_QmfDomain_SaveOverlap(HANDLE_FDK_QMF_DOMAIN_IN qd_ch, int offset) {
+ FDK_ASSERT(qd_ch != NULL);
+ int ts;
+ HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
+ int ovSlots = gc->nQmfOvTimeSlots;
+ int nCols = gc->nQmfTimeSlots;
+ int nProcBands = gc->nQmfProcBands;
+ FIXP_DBL **qmfReal = qd_ch->hQmfSlotsReal;
+ FIXP_DBL **qmfImag = qd_ch->hQmfSlotsImag;
+ QMF_SCALE_FACTOR *pScaling = &qd_ch->scaling;
+
+ /* for high part it would be enough to save only used part of overlap area */
+ if (qmfImag != NULL) {
+ for (ts = offset; ts < ovSlots; ts++) {
+ FDKmemcpy(qmfReal[ts], qmfReal[nCols + ts],
+ sizeof(FIXP_DBL) * nProcBands);
+ FDKmemcpy(qmfImag[ts], qmfImag[nCols + ts],
+ sizeof(FIXP_DBL) * nProcBands);
+ }
+ } else {
+ for (ts = 0; ts < ovSlots; ts++) {
+ FDKmemcpy(qmfReal[ts], qmfReal[nCols + ts],
+ sizeof(FIXP_DBL) * nProcBands);
+ }
+ }
+ pScaling->ov_lb_scale = pScaling->lb_scale;
+}
+
+ /* Convert headroom bits to exponent */
+#define SCALE2EXP(s) (15 - (s))
+#define EXP2SCALE(e) (15 - (e))
+
+void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
+ const int start_band, const int stop_band,
+ FIXP_DBL *pQmfOutReal, FIXP_DBL *pQmfOutImag,
+ const int exp_out) {
+ FDK_ASSERT(qd_ch != NULL);
+ FDK_ASSERT(pQmfOutReal != NULL);
+ HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
+ const FIXP_DBL *real = qd_ch->hQmfSlotsReal[ts];
+ const FIXP_DBL *imag = qd_ch->hQmfSlotsImag[ts];
+ const int ovSlots = gc->nQmfOvTimeSlots;
+ const int exp_lb = SCALE2EXP((ts < ovSlots) ? qd_ch->scaling.ov_lb_scale
+ : qd_ch->scaling.lb_scale);
+ const int exp_hb = SCALE2EXP(qd_ch->scaling.hb_scale);
+ const int lsb = qd_ch->fb.lsb;
+ const int usb = qd_ch->fb.usb;
+ int b = start_band;
+ int lb_sf, hb_sf;
+
+ int target_exp =
+ ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + qd_ch->fb.filterScale;
+
+ FDK_ASSERT(ts < (gc->nQmfTimeSlots + gc->nQmfOvTimeSlots));
+ FDK_ASSERT(start_band >= 0);
+ FDK_ASSERT(stop_band <= gc->nQmfProcBands);
+
+ if (qd_ch->fb.no_channels == 24) {
+ target_exp -= 1;
+ }
+
+ /* Limit scaling factors to maximum negative value to avoid faulty behaviour
+ due to right-shifts. Corresponding asserts were observed during robustness
+ testing.
+ */
+ lb_sf = fMax(exp_lb - target_exp - exp_out, -31);
+ FDK_ASSERT(lb_sf < 32);
+ hb_sf = fMax(exp_hb - target_exp - exp_out, -31);
+ FDK_ASSERT(hb_sf < 32);
+
+ if (pQmfOutImag == NULL) {
+ for (; b < fMin(lsb, stop_band); b++) {
+ pQmfOutReal[b] = scaleValue(real[b], lb_sf);
+ }
+ for (; b < fMin(usb, stop_band); b++) {
+ pQmfOutReal[b] = scaleValue(real[b], hb_sf);
+ }
+ for (; b < stop_band; b++) {
+ pQmfOutReal[b] = (FIXP_DBL)0;
+ }
+ } else {
+ FDK_ASSERT(imag != NULL);
+ for (; b < fMin(lsb, stop_band); b++) {
+ pQmfOutReal[b] = scaleValue(real[b], lb_sf);
+ pQmfOutImag[b] = scaleValue(imag[b], lb_sf);
+ }
+ for (; b < fMin(usb, stop_band); b++) {
+ pQmfOutReal[b] = scaleValue(real[b], hb_sf);
+ pQmfOutImag[b] = scaleValue(imag[b], hb_sf);
+ }
+ for (; b < stop_band; b++) {
+ pQmfOutReal[b] = (FIXP_DBL)0;
+ pQmfOutImag[b] = (FIXP_DBL)0;
+ }
+ }
+}
+
+void FDK_QmfDomain_GetWorkBuffer(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch,
+ const int ts, FIXP_DBL **ppQmfReal,
+ FIXP_DBL **ppQmfImag) {
+ FDK_ASSERT(qd_ch != NULL);
+ FDK_ASSERT(ppQmfReal != NULL);
+ FDK_ASSERT(ppQmfImag != NULL);
+ const int bands = qd_ch->workBuf_nBands;
+ FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
+ USHORT workBufferOffset = qd_ch->workBufferOffset;
+ USHORT workBufferSectSize = qd_ch->workBufferSectSize;
+
+ FDK_ASSERT(bands > 0);
+ FDK_ASSERT(ts < qd_ch->workBuf_nTimeSlots);
+
+ *ppQmfReal = FDK_getWorkBuffer(
+ pWorkBuf, workBufferOffset + (ts * CMPLX_MOD + 0) * bands,
+ workBufferSectSize, bands);
+ *ppQmfImag = FDK_getWorkBuffer(
+ pWorkBuf, workBufferOffset + (ts * CMPLX_MOD + 1) * bands,
+ workBufferSectSize, bands);
+}
+
+void FDK_QmfDomain_WorkBuffer2ProcChannel(
+ const HANDLE_FDK_QMF_DOMAIN_IN qd_ch) {
+ FDK_ASSERT(qd_ch != NULL);
+ HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
+ FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
+ USHORT workBufferOffset = qd_ch->workBufferOffset;
+ USHORT workBufferSectSize = qd_ch->workBufferSectSize;
+
+ if (FDK_getWorkBuffer(pWorkBuf, workBufferOffset, workBufferSectSize,
+ qd_ch->workBuf_nBands) ==
+ qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots]) {
+ /* work buffer is part of processing channel => nothing to do */
+ return;
+ } else {
+ /* copy parked new QMF data to processing channel */
+ const int bands = qd_ch->workBuf_nBands;
+ const int slots = qd_ch->workBuf_nTimeSlots;
+ int ts;
+ for (ts = 0; ts < slots; ts++) {
+ FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts],
+ FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
+ workBufferSectSize, bands),
+ sizeof(FIXP_DBL) * bands); // parkBuf_to_anaMatrix
+ workBufferOffset += bands;
+ FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts],
+ FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
+ workBufferSectSize, bands),
+ sizeof(FIXP_DBL) * bands);
+ workBufferOffset += bands;
+ }
+ }
+}
+
+void FDK_QmfDomain_QmfData2HBE(HANDLE_FDK_QMF_DOMAIN_IN qd_ch,
+ FIXP_DBL **ppQmfReal, FIXP_DBL **ppQmfImag) {
+ FDK_ASSERT(qd_ch != NULL);
+ FDK_ASSERT(ppQmfReal != NULL);
+ FDK_ASSERT(ppQmfImag != NULL);
+ HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
+ FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
+ USHORT workBufferOffset = qd_ch->workBufferOffset;
+ USHORT workBufferSectSize = qd_ch->workBufferSectSize;
+
+ if (FDK_getWorkBuffer(pWorkBuf, workBufferOffset, workBufferSectSize,
+ qd_ch->workBuf_nBands) ==
+ qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots]) { // left channel (anaMatrix)
+ int ts;
+ const int bands = gc->nBandsAnalysis;
+ const int slots = qd_ch->workBuf_nTimeSlots;
+ FDK_ASSERT(bands <= 64);
+ for (ts = 0; ts < slots; ts++) {
+ /* copy current data of processing channel */
+ FIXP_DBL tmp[64]; // one slot
+ /* real */
+ FDKmemcpy(tmp, qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts],
+ sizeof(FIXP_DBL) * bands); // anaMatrix_to_tmp
+ FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts], ppQmfReal[ts],
+ sizeof(FIXP_DBL) * bands); // HBE_to_anaMatrix
+ FDKmemcpy(ppQmfReal[ts], tmp, sizeof(FIXP_DBL) * bands); // tmp_to_HBE
+ /* imag */
+ FDKmemcpy(tmp, qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts],
+ sizeof(FIXP_DBL) * bands);
+ FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts], ppQmfImag[ts],
+ sizeof(FIXP_DBL) * bands);
+ FDKmemcpy(ppQmfImag[ts], tmp, sizeof(FIXP_DBL) * bands);
+ }
+ } else { // right channel (parkBuf)
+ const int bands = qd_ch->workBuf_nBands;
+ const int slots = qd_ch->workBuf_nTimeSlots;
+ int ts;
+ FDK_ASSERT(qd_ch->workBuf_nBands == gc->nBandsAnalysis);
+ for (ts = 0; ts < slots; ts++) {
+ /* copy HBE QMF data buffer to processing channel */
+ FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts], ppQmfReal[ts],
+ sizeof(FIXP_DBL) * bands); // HBE_to_anaMatrix
+ FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts], ppQmfImag[ts],
+ sizeof(FIXP_DBL) * bands);
+ /* copy parked new QMF data to HBE QMF data buffer */
+ FDKmemcpy(ppQmfReal[ts],
+ FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
+ workBufferSectSize, bands),
+ sizeof(FIXP_DBL) * bands); // parkBuf_to_HBE
+ workBufferOffset += bands;
+ FDKmemcpy(ppQmfImag[ts],
+ FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
+ workBufferSectSize, bands),
+ sizeof(FIXP_DBL) * bands);
+ workBufferOffset += bands;
+ }
+ }
+}
+
+void FDK_QmfDomain_ClearRequested(HANDLE_FDK_QMF_DOMAIN_GC hgc) {
+ hgc->qmfDomainExplicitConfig = 0;
+ hgc->flags_requested = 0;
+ hgc->nInputChannels_requested = 0;
+ hgc->nOutputChannels_requested = 0;
+ hgc->parkChannel_requested = 0;
+ hgc->nBandsAnalysis_requested = 0;
+ hgc->nBandsSynthesis_requested = 0;
+ hgc->nQmfTimeSlots_requested = 0;
+ hgc->nQmfOvTimeSlots_requested = 0;
+ hgc->nQmfProcBands_requested = 0;
+ hgc->nQmfProcChannels_requested = 0;
+}
+
+static void FDK_QmfDomain_ClearConfigured(HANDLE_FDK_QMF_DOMAIN_GC hgc) {
+ hgc->flags = 0;
+ hgc->nInputChannels = 0;
+ hgc->nOutputChannels = 0;
+ hgc->parkChannel = 0;
+ hgc->nBandsAnalysis = 0;
+ hgc->nBandsSynthesis = 0;
+ hgc->nQmfTimeSlots = 0;
+ hgc->nQmfOvTimeSlots = 0;
+ hgc->nQmfProcBands = 0;
+ hgc->nQmfProcChannels = 0;
+}
+
+static void FDK_QmfDomain_ClearFilterBank(HANDLE_FDK_QMF_DOMAIN hqd) {
+ int ch;
+
+ for (ch = 0; ch < ((8) + (1)); ch++) {
+ FDKmemclear(&hqd->QmfDomainIn[ch].fb, sizeof(hqd->QmfDomainIn[ch].fb));
+ }
+
+ for (ch = 0; ch < ((8) + (1)); ch++) {
+ FDKmemclear(&hqd->QmfDomainOut[ch].fb, sizeof(hqd->QmfDomainIn[ch].fb));
+ }
+}
+
+QMF_DOMAIN_ERROR FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd) {
+ FDK_ASSERT(hqd != NULL);
+ QMF_DOMAIN_ERROR err = QMF_DOMAIN_OK;
+ int i, size_main, size, size_temp = 0;
+
+ HANDLE_FDK_QMF_DOMAIN_GC hgc = &hqd->globalConf;
+ FIXP_DBL **pWorkBuffer = hgc->pWorkBuffer;
+
+ int hasChanged = 0;
+
+ if ((hgc->nQmfProcChannels_requested > 0) &&
+ (hgc->nQmfProcBands_requested != 64)) {
+ return QMF_DOMAIN_INIT_ERROR;
+ }
+ if (hgc->nBandsAnalysis_requested > hgc->nQmfProcBands_requested) {
+ /* In general the output of the qmf analysis is written to QMF memory slots
+ which size is defined by nQmfProcBands. nBandsSynthesis may be larger
+ than nQmfProcBands. This is e.g. the case if the QMF based resampler is
+ used.
+ */
+ return QMF_DOMAIN_INIT_ERROR;
+ }
+
+ /* 1. adjust change of processing channels by comparison of current and
+ * requested parameters */
+ if ((hgc->nQmfProcChannels != hgc->nQmfProcChannels_requested) ||
+ (hgc->nQmfProcBands != hgc->nQmfProcBands_requested) ||
+ (hgc->nQmfTimeSlots != hgc->nQmfTimeSlots_requested)) {
+ for (i = 0; i < hgc->nQmfProcChannels_requested; i++) {
+ hqd->QmfDomainIn[i].workBuf_nBands = hgc->nQmfProcBands_requested;
+ hgc->nQmfProcBands = hgc->nQmfProcBands_requested;
+
+ hqd->QmfDomainIn[i].workBuf_nTimeSlots = hgc->nQmfTimeSlots_requested;
+ }
+
+ hgc->nQmfProcChannels =
+ hgc->nQmfProcChannels_requested; /* keep highest value encountered so
+ far as allocated */
+
+ hasChanged = 1;
+ }
+
+ /* 2. reallocate persistent memory if necessary (analysis state-buffers,
+ * timeslot-pointer-array, overlap-buffers, synthesis state-buffers) */
+ if ((hgc->nInputChannels != hgc->nInputChannels_requested) ||
+ (hgc->nBandsAnalysis != hgc->nBandsAnalysis_requested) ||
+ (hgc->nQmfTimeSlots != hgc->nQmfTimeSlots_requested) ||
+ (hgc->nQmfOvTimeSlots != hgc->nQmfOvTimeSlots_requested) ||
+ (hgc->nOutputChannels != hgc->nOutputChannels_requested) ||
+ (hgc->nBandsSynthesis != hgc->nBandsSynthesis_requested) ||
+ (hgc->parkChannel != hgc->parkChannel_requested)) {
+ hgc->nInputChannels = hgc->nInputChannels_requested;
+ hgc->nBandsAnalysis = hgc->nBandsAnalysis_requested;
+ hgc->nQmfTimeSlots = hgc->nQmfTimeSlots_requested;
+ hgc->nQmfOvTimeSlots = hgc->nQmfOvTimeSlots_requested;
+ hgc->nOutputChannels = hgc->nOutputChannels_requested;
+ hgc->nBandsSynthesis = hgc->nBandsSynthesis_requested;
+ hgc->parkChannel = hgc->parkChannel_requested;
+
+ if (FDK_QmfDomain_AllocatePersistentMemory(hqd)) {
+ err = QMF_DOMAIN_OUT_OF_MEMORY;
+ goto bail;
+ }
+
+ /* 3. set request-flag for downsampled SBR */
+ if ((hgc->nBandsAnalysis == 32) && (hgc->nBandsSynthesis == 32) &&
+ !(hgc->flags & (QMF_FLAG_CLDFB | QMF_FLAG_MPSLDFB))) {
+ hgc->flags_requested |= QMF_FLAG_DOWNSAMPLED;
+ }
+
+ hasChanged = 1;
+ }
+
+ /* 4. initialize tables and buffer for QMF-resampler */
+
+ /* 5. set requested flags */
+ if (hgc->flags != hgc->flags_requested) {
+ if ((hgc->flags_requested & QMF_FLAG_MPSLDFB) &&
+ (hgc->flags_requested & QMF_FLAG_CLDFB)) {
+ hgc->flags_requested &= ~QMF_FLAG_CLDFB;
+ }
+ hgc->flags = hgc->flags_requested;
+ hasChanged = 1;
+ }
+
+ if (hasChanged) {
+ /* 6. recalculate and check size of required workbuffer-space */
+
+ if (hgc->parkChannel && (hqd->globalConf.nQmfProcChannels == 1)) {
+ /* configure temp QMF buffer for parking right channel MPS212 output,
+ * (USAC stereoConfigIndex 3 only) */
+ hqd->QmfDomainIn[1].workBuf_nBands = hqd->globalConf.nBandsAnalysis;
+ hqd->QmfDomainIn[1].workBuf_nTimeSlots = hqd->globalConf.nQmfTimeSlots;
+ size_temp = hqd->QmfDomainIn[1].workBuf_nBands *
+ hqd->QmfDomainIn[1].workBuf_nTimeSlots * CMPLX_MOD;
+ }
+
+ size_main = hqd->QmfDomainIn[0].workBuf_nBands *
+ hqd->QmfDomainIn[0].workBuf_nTimeSlots * CMPLX_MOD;
+
+ size = size_main * hgc->nQmfProcChannels + size_temp;
+
+ if (size > (QMF_MAX_WB_SECTIONS * QMF_WB_SECTION_SIZE)) {
+ err = QMF_DOMAIN_OUT_OF_MEMORY;
+ goto bail;
+ }
+
+ /* 7. allocate additional workbuffer if necessary */
+ if ((size > 0 /* *QMF_WB_SECTION_SIZE */) && (pWorkBuffer[0] == NULL)) {
+ /* get work buffer of size QMF_WB_SECTION_SIZE */
+ pWorkBuffer[0] = GetQmfWorkBufferCore6();
+ }
+
+ if ((size > 1 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[1] == NULL)) {
+ /* get work buffer of size QMF_WB_SECTION_SIZE */
+ pWorkBuffer[1] = GetQmfWorkBufferCore1();
+ }
+
+ if ((size > 2 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[2] == NULL)) {
+ /* get work buffer of size QMF_WB_SECTION_SIZE */
+ pWorkBuffer[2] = GetQmfWorkBufferCore3();
+ }
+
+ if ((size > 3 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[3] == NULL)) {
+ /* get work buffer of size QMF_WB_SECTION_SIZE */
+ pWorkBuffer[3] = GetQmfWorkBufferCore4();
+ }
+
+ if ((size > 4 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[4] == NULL)) {
+ /* get work buffer of size QMF_WB_SECTION_SIZE */
+ pWorkBuffer[4] = GetQmfWorkBufferCore5();
+ }
+
+ /* 8. distribute workbuffer over processing channels */
+ for (i = 0; i < hgc->nQmfProcChannels; i++) {
+ FDK_QmfDomain_FeedWorkBuffer(hqd, i, pWorkBuffer, size_main * i,
+ QMF_WB_SECTION_SIZE, size_main);
+ }
+ if (hgc->parkChannel) {
+ for (; i < hgc->nInputChannels; i++) {
+ FDK_QmfDomain_FeedWorkBuffer(hqd, 1, pWorkBuffer,
+ size_main * hgc->nQmfProcChannels,
+ QMF_WB_SECTION_SIZE, size_temp);
+ }
+ }
+
+ /* 9. (re-)init filterbank */
+ for (i = 0; i < hgc->nOutputChannels; i++) {
+ if ((hqd->QmfDomainOut[i].fb.lsb == 0) &&
+ (hqd->QmfDomainOut[i].fb.usb == 0)) {
+ /* Although lsb and usb are set in the SBR module, they are initialized
+ * at this point due to the case of using MPS without SBR. */
+ hqd->QmfDomainOut[i].fb.lsb = hgc->nBandsAnalysis_requested;
+ hqd->QmfDomainOut[i].fb.usb =
+ fMin((INT)hgc->nBandsSynthesis_requested, 64);
+ }
+ }
+ if (FDK_QmfDomain_InitFilterBank(hqd, 0)) {
+ err = QMF_DOMAIN_INIT_ERROR;
+ }
+ }
+
+bail:
+ if (err) {
+ FDK_QmfDomain_FreeMem(hqd);
+ }
+ return err;
+}
+
+static void FDK_QmfDomain_FreeWorkBuffer(HANDLE_FDK_QMF_DOMAIN hqd) {
+ FIXP_DBL **pWorkBuffer = hqd->globalConf.pWorkBuffer;
+
+ if (pWorkBuffer[0]) FreeQmfWorkBufferCore6(&pWorkBuffer[0]);
+ if (pWorkBuffer[1]) FreeQmfWorkBufferCore1(&pWorkBuffer[1]);
+ if (pWorkBuffer[2]) FreeQmfWorkBufferCore3(&pWorkBuffer[2]);
+ if (pWorkBuffer[3]) FreeQmfWorkBufferCore4(&pWorkBuffer[3]);
+ if (pWorkBuffer[4]) FreeQmfWorkBufferCore5(&pWorkBuffer[4]);
+}
+
+void FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd) {
+ FDK_QmfDomain_FreeWorkBuffer(hqd);
+
+ FDK_QmfDomain_FreePersistentMemory(hqd);
+
+ FDK_QmfDomain_ClearFilterBank(hqd);
+
+ FDK_QmfDomain_ClearConfigured(&hqd->globalConf);
+
+ FDK_QmfDomain_ClearRequested(&hqd->globalConf);
+}
+
+void FDK_QmfDomain_Close(HANDLE_FDK_QMF_DOMAIN hqd) {
+ FDK_QmfDomain_FreeWorkBuffer(hqd);
+
+ FDK_QmfDomain_FreePersistentMemory(hqd);
+}
diff --git a/fdk-aac/libFDK/src/FDK_tools_rom.cpp b/fdk-aac/libFDK/src/FDK_tools_rom.cpp
new file mode 100644
index 0000000..e9e1206
--- /dev/null
+++ b/fdk-aac/libFDK/src/FDK_tools_rom.cpp
@@ -0,0 +1,7274 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Oliver Moser
+
+ Description: ROM tables used by FDK tools
+
+*******************************************************************************/
+
+#include "FDK_tools_rom.h"
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STP SineTable80[] = {
+ STCP(0x7fffffff, 0x00000000), STCP(0x7ff9af04, 0x02835b5a),
+ STCP(0x7fe6bcb0, 0x05067734), STCP(0x7fc72ae2, 0x07891418),
+ STCP(0x7f9afcb9, 0x0a0af299), STCP(0x7f62368f, 0x0c8bd35e),
+ STCP(0x7f1cde01, 0x0f0b7727), STCP(0x7ecaf9e5, 0x11899ed3),
+ STCP(0x7e6c9251, 0x14060b68), STCP(0x7e01b096, 0x16807e15),
+ STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d06aa16, 0x1b6e7b7a),
+ STCP(0x7c769e18, 0x1de189a6), STCP(0x7bda497d, 0x2051a4dd),
+ STCP(0x7b31bbb2, 0x22be8f87), STCP(0x7a7d055b, 0x25280c5e),
+ STCP(0x79bc384d, 0x278dde6e), STCP(0x78ef678f, 0x29efc925),
+ STCP(0x7816a759, 0x2c4d9050), STCP(0x77320d0d, 0x2ea6f827),
+ STCP(0x7641af3d, 0x30fbc54d), STCP(0x7545a5a0, 0x334bbcde),
+ STCP(0x743e0918, 0x3596a46c), STCP(0x732af3a7, 0x37dc420c),
+ STCP(0x720c8075, 0x3a1c5c57), STCP(0x70e2cbc6, 0x3c56ba70),
+ STCP(0x6fadf2fc, 0x3e8b240e), STCP(0x6e6e1492, 0x40b9617d),
+ STCP(0x6d23501b, 0x42e13ba4), STCP(0x6bcdc639, 0x45027c0c),
+ STCP(0x6a6d98a4, 0x471cece7), STCP(0x6902ea1d, 0x4930590f),
+ STCP(0x678dde6e, 0x4b3c8c12), STCP(0x660e9a6a, 0x4d415234),
+ STCP(0x648543e4, 0x4f3e7875), STCP(0x62f201ac, 0x5133cc94),
+ STCP(0x6154fb91, 0x53211d18), STCP(0x5fae5a55, 0x55063951),
+ STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5c44ee40, 0x58b71632),
+ STCP(0x5a82799a, 0x5a82799a),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STP SineTable384[] = {
+ STCP(0x7fffffff, 0x00000000), STCP(0x7fffb9d1, 0x00860a79),
+ STCP(0x7ffee744, 0x010c1460), STCP(0x7ffd885a, 0x01921d20),
+ STCP(0x7ffb9d15, 0x02182427), STCP(0x7ff92577, 0x029e28e2),
+ STCP(0x7ff62182, 0x03242abf), STCP(0x7ff2913a, 0x03aa292a),
+ STCP(0x7fee74a2, 0x0430238f), STCP(0x7fe9cbc0, 0x04b6195d),
+ STCP(0x7fe49698, 0x053c0a01), STCP(0x7fded530, 0x05c1f4e7),
+ STCP(0x7fd8878e, 0x0647d97c), STCP(0x7fd1adb9, 0x06cdb72f),
+ STCP(0x7fca47b9, 0x07538d6b), STCP(0x7fc25596, 0x07d95b9e),
+ STCP(0x7fb9d759, 0x085f2137), STCP(0x7fb0cd0a, 0x08e4dda0),
+ STCP(0x7fa736b4, 0x096a9049), STCP(0x7f9d1461, 0x09f0389f),
+ STCP(0x7f92661d, 0x0a75d60e), STCP(0x7f872bf3, 0x0afb6805),
+ STCP(0x7f7b65ef, 0x0b80edf1), STCP(0x7f6f141f, 0x0c066740),
+ STCP(0x7f62368f, 0x0c8bd35e), STCP(0x7f54cd4f, 0x0d1131ba),
+ STCP(0x7f46d86c, 0x0d9681c2), STCP(0x7f3857f6, 0x0e1bc2e4),
+ STCP(0x7f294bfd, 0x0ea0f48c), STCP(0x7f19b491, 0x0f26162a),
+ STCP(0x7f0991c4, 0x0fab272b), STCP(0x7ef8e3a6, 0x103026fe),
+ STCP(0x7ee7aa4c, 0x10b5150f), STCP(0x7ed5e5c6, 0x1139f0cf),
+ STCP(0x7ec3962a, 0x11beb9aa), STCP(0x7eb0bb8a, 0x12436f10),
+ STCP(0x7e9d55fc, 0x12c8106f), STCP(0x7e896595, 0x134c9d34),
+ STCP(0x7e74ea6a, 0x13d114d0), STCP(0x7e5fe493, 0x145576b1),
+ STCP(0x7e4a5426, 0x14d9c245), STCP(0x7e34393b, 0x155df6fc),
+ STCP(0x7e1d93ea, 0x15e21445), STCP(0x7e06644c, 0x1666198d),
+ STCP(0x7deeaa7a, 0x16ea0646), STCP(0x7dd6668f, 0x176dd9de),
+ STCP(0x7dbd98a4, 0x17f193c5), STCP(0x7da440d6, 0x1875336a),
+ STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d6ff3fe, 0x197c21ad),
+ STCP(0x7d54ff2e, 0x19ff6f2a), STCP(0x7d3980ec, 0x1a82a026),
+ STCP(0x7d1d7958, 0x1b05b40f), STCP(0x7d00e88f, 0x1b88aa55),
+ STCP(0x7ce3ceb2, 0x1c0b826a), STCP(0x7cc62bdf, 0x1c8e3bbe),
+ STCP(0x7ca80038, 0x1d10d5c2), STCP(0x7c894bde, 0x1d934fe5),
+ STCP(0x7c6a0ef2, 0x1e15a99a), STCP(0x7c4a4996, 0x1e97e251),
+ STCP(0x7c29fbee, 0x1f19f97b), STCP(0x7c09261d, 0x1f9bee8a),
+ STCP(0x7be7c847, 0x201dc0ef), STCP(0x7bc5e290, 0x209f701c),
+ STCP(0x7ba3751d, 0x2120fb83), STCP(0x7b808015, 0x21a26295),
+ STCP(0x7b5d039e, 0x2223a4c5), STCP(0x7b38ffde, 0x22a4c185),
+ STCP(0x7b1474fd, 0x2325b847), STCP(0x7aef6323, 0x23a6887f),
+ STCP(0x7ac9ca7a, 0x2427319d), STCP(0x7aa3ab29, 0x24a7b317),
+ STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a55d93a, 0x25a83ce6),
+ STCP(0x7a2e26f2, 0x26284422), STCP(0x7a05eead, 0x26a82186),
+ STCP(0x79dd3098, 0x2727d486), STCP(0x79b3ece0, 0x27a75c95),
+ STCP(0x798a23b1, 0x2826b928), STCP(0x795fd53a, 0x28a5e9b4),
+ STCP(0x793501a9, 0x2924edac), STCP(0x7909a92d, 0x29a3c485),
+ STCP(0x78ddcbf5, 0x2a226db5), STCP(0x78b16a32, 0x2aa0e8b0),
+ STCP(0x78848414, 0x2b1f34eb), STCP(0x785719cc, 0x2b9d51dd),
+ STCP(0x78292b8d, 0x2c1b3efb), STCP(0x77fab989, 0x2c98fbba),
+ STCP(0x77cbc3f2, 0x2d168792), STCP(0x779c4afc, 0x2d93e1f8),
+ STCP(0x776c4edb, 0x2e110a62), STCP(0x773bcfc4, 0x2e8e0048),
+ STCP(0x770acdec, 0x2f0ac320), STCP(0x76d94989, 0x2f875262),
+ STCP(0x76a742d1, 0x3003ad85), STCP(0x7674b9fa, 0x307fd401),
+ STCP(0x7641af3d, 0x30fbc54d), STCP(0x760e22d1, 0x317780e2),
+ STCP(0x75da14ef, 0x31f30638), STCP(0x75a585cf, 0x326e54c7),
+ STCP(0x757075ac, 0x32e96c09), STCP(0x753ae4c0, 0x33644b76),
+ STCP(0x7504d345, 0x33def287), STCP(0x74ce4177, 0x345960b7),
+ STCP(0x74972f92, 0x34d3957e), STCP(0x745f9dd1, 0x354d9057),
+ STCP(0x74278c72, 0x35c750bc), STCP(0x73eefbb3, 0x3640d627),
+ STCP(0x73b5ebd1, 0x36ba2014), STCP(0x737c5d0b, 0x37332dfd),
+ STCP(0x73424fa0, 0x37abff5d), STCP(0x7307c3d0, 0x382493b0),
+ STCP(0x72ccb9db, 0x389cea72), STCP(0x72913201, 0x3915031f),
+ STCP(0x72552c85, 0x398cdd32), STCP(0x7218a9a7, 0x3a04782a),
+ STCP(0x71dba9ab, 0x3a7bd382), STCP(0x719e2cd2, 0x3af2eeb7),
+ STCP(0x71603361, 0x3b69c947), STCP(0x7121bd9c, 0x3be062b0),
+ STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70a35e25, 0x3cccd004),
+ STCP(0x706374ff, 0x3d42a2ec), STCP(0x7023109a, 0x3db832a6),
+ STCP(0x6fe2313c, 0x3e2d7eb1), STCP(0x6fa0d72c, 0x3ea2868c),
+ STCP(0x6f5f02b2, 0x3f1749b8), STCP(0x6f1cb416, 0x3f8bc7b4),
+ STCP(0x6ed9eba1, 0x40000000), STCP(0x6e96a99d, 0x4073f21d),
+ STCP(0x6e52ee52, 0x40e79d8c), STCP(0x6e0eba0c, 0x415b01ce),
+ STCP(0x6dca0d14, 0x41ce1e65), STCP(0x6d84e7b7, 0x4240f2d1),
+ STCP(0x6d3f4a40, 0x42b37e96), STCP(0x6cf934fc, 0x4325c135),
+ STCP(0x6cb2a837, 0x4397ba32), STCP(0x6c6ba43e, 0x44096910),
+ STCP(0x6c242960, 0x447acd50), STCP(0x6bdc37eb, 0x44ebe679),
+ STCP(0x6b93d02e, 0x455cb40c), STCP(0x6b4af279, 0x45cd358f),
+ STCP(0x6b019f1a, 0x463d6a87), STCP(0x6ab7d663, 0x46ad5278),
+ STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a22e630, 0x478c395a),
+ STCP(0x69d7bf57, 0x47fb3757), STCP(0x698c246c, 0x4869e665),
+ STCP(0x694015c3, 0x48d84609), STCP(0x68f393ae, 0x494655cc),
+ STCP(0x68a69e81, 0x49b41533), STCP(0x68593691, 0x4a2183c8),
+ STCP(0x680b5c33, 0x4a8ea111), STCP(0x67bd0fbd, 0x4afb6c98),
+ STCP(0x676e5183, 0x4b67e5e4), STCP(0x671f21dc, 0x4bd40c80),
+ STCP(0x66cf8120, 0x4c3fdff4), STCP(0x667f6fa5, 0x4cab5fc9),
+ STCP(0x662eedc3, 0x4d168b8b), STCP(0x65ddfbd3, 0x4d8162c4),
+ STCP(0x658c9a2d, 0x4debe4fe), STCP(0x653ac92b, 0x4e5611c5),
+ STCP(0x64e88926, 0x4ebfe8a5), STCP(0x6495da79, 0x4f296928),
+ STCP(0x6442bd7e, 0x4f9292dc), STCP(0x63ef3290, 0x4ffb654d),
+ STCP(0x639b3a0b, 0x5063e008), STCP(0x6346d44b, 0x50cc029c),
+ STCP(0x62f201ac, 0x5133cc94), STCP(0x629cc28c, 0x519b3d80),
+ STCP(0x62471749, 0x520254ef), STCP(0x61f1003f, 0x5269126e),
+ STCP(0x619a7dce, 0x52cf758f), STCP(0x61439053, 0x53357ddf),
+ STCP(0x60ec3830, 0x539b2af0), STCP(0x609475c3, 0x54007c51),
+ STCP(0x603c496c, 0x54657194), STCP(0x5fe3b38d, 0x54ca0a4b),
+ STCP(0x5f8ab487, 0x552e4605), STCP(0x5f314cba, 0x55922457),
+ STCP(0x5ed77c8a, 0x55f5a4d2), STCP(0x5e7d4458, 0x5658c709),
+ STCP(0x5e22a487, 0x56bb8a90), STCP(0x5dc79d7c, 0x571deefa),
+ STCP(0x5d6c2f99, 0x577ff3da), STCP(0x5d105b44, 0x57e198c7),
+ STCP(0x5cb420e0, 0x5842dd54), STCP(0x5c5780d3, 0x58a3c118),
+ STCP(0x5bfa7b82, 0x590443a7), STCP(0x5b9d1154, 0x59646498),
+ STCP(0x5b3f42ae, 0x59c42381), STCP(0x5ae10ff9, 0x5a237ffa),
+ STCP(0x5a82799a, 0x5a82799a),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STP SineTable480[] = {
+ STCP(0x7fffffff, 0x00000000), STCP(0x7fffd315, 0x006b3b9b),
+ STCP(0x7fff4c54, 0x00d676eb), STCP(0x7ffe6bbf, 0x0141b1a5),
+ STCP(0x7ffd3154, 0x01aceb7c), STCP(0x7ffb9d15, 0x02182427),
+ STCP(0x7ff9af04, 0x02835b5a), STCP(0x7ff76721, 0x02ee90c8),
+ STCP(0x7ff4c56f, 0x0359c428), STCP(0x7ff1c9ef, 0x03c4f52f),
+ STCP(0x7fee74a2, 0x0430238f), STCP(0x7feac58d, 0x049b4f00),
+ STCP(0x7fe6bcb0, 0x05067734), STCP(0x7fe25a0f, 0x05719be2),
+ STCP(0x7fdd9dad, 0x05dcbcbe), STCP(0x7fd8878e, 0x0647d97c),
+ STCP(0x7fd317b4, 0x06b2f1d2), STCP(0x7fcd4e24, 0x071e0575),
+ STCP(0x7fc72ae2, 0x07891418), STCP(0x7fc0adf2, 0x07f41d72),
+ STCP(0x7fb9d759, 0x085f2137), STCP(0x7fb2a71b, 0x08ca1f1b),
+ STCP(0x7fab1d3d, 0x093516d4), STCP(0x7fa339c5, 0x09a00817),
+ STCP(0x7f9afcb9, 0x0a0af299), STCP(0x7f92661d, 0x0a75d60e),
+ STCP(0x7f8975f9, 0x0ae0b22c), STCP(0x7f802c52, 0x0b4b86a8),
+ STCP(0x7f76892f, 0x0bb65336), STCP(0x7f6c8c96, 0x0c21178c),
+ STCP(0x7f62368f, 0x0c8bd35e), STCP(0x7f578721, 0x0cf68662),
+ STCP(0x7f4c7e54, 0x0d61304e), STCP(0x7f411c2f, 0x0dcbd0d5),
+ STCP(0x7f3560b9, 0x0e3667ad), STCP(0x7f294bfd, 0x0ea0f48c),
+ STCP(0x7f1cde01, 0x0f0b7727), STCP(0x7f1016ce, 0x0f75ef33),
+ STCP(0x7f02f66f, 0x0fe05c64), STCP(0x7ef57cea, 0x104abe71),
+ STCP(0x7ee7aa4c, 0x10b5150f), STCP(0x7ed97e9c, 0x111f5ff4),
+ STCP(0x7ecaf9e5, 0x11899ed3), STCP(0x7ebc1c31, 0x11f3d164),
+ STCP(0x7eace58a, 0x125df75b), STCP(0x7e9d55fc, 0x12c8106f),
+ STCP(0x7e8d6d91, 0x13321c53), STCP(0x7e7d2c54, 0x139c1abf),
+ STCP(0x7e6c9251, 0x14060b68), STCP(0x7e5b9f93, 0x146fee03),
+ STCP(0x7e4a5426, 0x14d9c245), STCP(0x7e38b017, 0x154387e6),
+ STCP(0x7e26b371, 0x15ad3e9a), STCP(0x7e145e42, 0x1616e618),
+ STCP(0x7e01b096, 0x16807e15), STCP(0x7deeaa7a, 0x16ea0646),
+ STCP(0x7ddb4bfc, 0x17537e63), STCP(0x7dc79529, 0x17bce621),
+ STCP(0x7db3860f, 0x18263d36), STCP(0x7d9f1ebd, 0x188f8357),
+ STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d7547a7, 0x1961db9b),
+ STCP(0x7d5fd801, 0x19caed29), STCP(0x7d4a105d, 0x1a33ec9c),
+ STCP(0x7d33f0ca, 0x1a9cd9ac), STCP(0x7d1d7958, 0x1b05b40f),
+ STCP(0x7d06aa16, 0x1b6e7b7a), STCP(0x7cef8315, 0x1bd72fa4),
+ STCP(0x7cd80464, 0x1c3fd045), STCP(0x7cc02e15, 0x1ca85d12),
+ STCP(0x7ca80038, 0x1d10d5c2), STCP(0x7c8f7ade, 0x1d793a0b),
+ STCP(0x7c769e18, 0x1de189a6), STCP(0x7c5d69f7, 0x1e49c447),
+ STCP(0x7c43de8e, 0x1eb1e9a7), STCP(0x7c29fbee, 0x1f19f97b),
+ STCP(0x7c0fc22a, 0x1f81f37c), STCP(0x7bf53153, 0x1fe9d75f),
+ STCP(0x7bda497d, 0x2051a4dd), STCP(0x7bbf0aba, 0x20b95bac),
+ STCP(0x7ba3751d, 0x2120fb83), STCP(0x7b8788ba, 0x2188841a),
+ STCP(0x7b6b45a5, 0x21eff528), STCP(0x7b4eabf1, 0x22574e65),
+ STCP(0x7b31bbb2, 0x22be8f87), STCP(0x7b1474fd, 0x2325b847),
+ STCP(0x7af6d7e6, 0x238cc85d), STCP(0x7ad8e482, 0x23f3bf7e),
+ STCP(0x7aba9ae6, 0x245a9d65), STCP(0x7a9bfb27, 0x24c161c7),
+ STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a5db997, 0x258e9ce0),
+ STCP(0x7a3e17f2, 0x25f51307), STCP(0x7a1e2082, 0x265b6e8a),
+ STCP(0x79fdd35c, 0x26c1af22), STCP(0x79dd3098, 0x2727d486),
+ STCP(0x79bc384d, 0x278dde6e), STCP(0x799aea92, 0x27f3cc94),
+ STCP(0x7979477d, 0x28599eb0), STCP(0x79574f28, 0x28bf547b),
+ STCP(0x793501a9, 0x2924edac), STCP(0x79125f19, 0x298a69fc),
+ STCP(0x78ef678f, 0x29efc925), STCP(0x78cc1b26, 0x2a550adf),
+ STCP(0x78a879f4, 0x2aba2ee4), STCP(0x78848414, 0x2b1f34eb),
+ STCP(0x7860399e, 0x2b841caf), STCP(0x783b9aad, 0x2be8e5e8),
+ STCP(0x7816a759, 0x2c4d9050), STCP(0x77f15fbc, 0x2cb21ba0),
+ STCP(0x77cbc3f2, 0x2d168792), STCP(0x77a5d413, 0x2d7ad3de),
+ STCP(0x777f903c, 0x2ddf0040), STCP(0x7758f886, 0x2e430c6f),
+ STCP(0x77320d0d, 0x2ea6f827), STCP(0x770acdec, 0x2f0ac320),
+ STCP(0x76e33b3f, 0x2f6e6d16), STCP(0x76bb5521, 0x2fd1f5c1),
+ STCP(0x76931bae, 0x30355cdd), STCP(0x766a8f04, 0x3098a223),
+ STCP(0x7641af3d, 0x30fbc54d), STCP(0x76187c77, 0x315ec617),
+ STCP(0x75eef6ce, 0x31c1a43b), STCP(0x75c51e61, 0x32245f72),
+ STCP(0x759af34c, 0x3286f779), STCP(0x757075ac, 0x32e96c09),
+ STCP(0x7545a5a0, 0x334bbcde), STCP(0x751a8346, 0x33ade9b3),
+ STCP(0x74ef0ebc, 0x340ff242), STCP(0x74c34820, 0x3471d647),
+ STCP(0x74972f92, 0x34d3957e), STCP(0x746ac52f, 0x35352fa1),
+ STCP(0x743e0918, 0x3596a46c), STCP(0x7410fb6b, 0x35f7f39c),
+ STCP(0x73e39c49, 0x36591cea), STCP(0x73b5ebd1, 0x36ba2014),
+ STCP(0x7387ea23, 0x371afcd5), STCP(0x73599760, 0x377bb2e9),
+ STCP(0x732af3a7, 0x37dc420c), STCP(0x72fbff1b, 0x383ca9fb),
+ STCP(0x72ccb9db, 0x389cea72), STCP(0x729d2409, 0x38fd032d),
+ STCP(0x726d3dc6, 0x395cf3e9), STCP(0x723d0734, 0x39bcbc63),
+ STCP(0x720c8075, 0x3a1c5c57), STCP(0x71dba9ab, 0x3a7bd382),
+ STCP(0x71aa82f7, 0x3adb21a1), STCP(0x71790c7e, 0x3b3a4672),
+ STCP(0x71474660, 0x3b9941b1), STCP(0x711530c2, 0x3bf8131c),
+ STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70b01790, 0x3cb5376b),
+ STCP(0x707d1443, 0x3d1389cb), STCP(0x7049c203, 0x3d71b14d),
+ STCP(0x701620f5, 0x3dcfadb0), STCP(0x6fe2313c, 0x3e2d7eb1),
+ STCP(0x6fadf2fc, 0x3e8b240e), STCP(0x6f79665b, 0x3ee89d86),
+ STCP(0x6f448b7e, 0x3f45ead8), STCP(0x6f0f6289, 0x3fa30bc1),
+ STCP(0x6ed9eba1, 0x40000000), STCP(0x6ea426ed, 0x405cc754),
+ STCP(0x6e6e1492, 0x40b9617d), STCP(0x6e37b4b6, 0x4115ce38),
+ STCP(0x6e010780, 0x41720d46), STCP(0x6dca0d14, 0x41ce1e65),
+ STCP(0x6d92c59b, 0x422a0154), STCP(0x6d5b313b, 0x4285b5d4),
+ STCP(0x6d23501b, 0x42e13ba4), STCP(0x6ceb2261, 0x433c9283),
+ STCP(0x6cb2a837, 0x4397ba32), STCP(0x6c79e1c2, 0x43f2b271),
+ STCP(0x6c40cf2c, 0x444d7aff), STCP(0x6c07709b, 0x44a8139e),
+ STCP(0x6bcdc639, 0x45027c0c), STCP(0x6b93d02e, 0x455cb40c),
+ STCP(0x6b598ea3, 0x45b6bb5e), STCP(0x6b1f01c0, 0x461091c2),
+ STCP(0x6ae429ae, 0x466a36f9), STCP(0x6aa90697, 0x46c3aac5),
+ STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a31e000, 0x4775fd1f),
+ STCP(0x69f5dcd3, 0x47cedb31), STCP(0x69b98f48, 0x482786dc),
+ STCP(0x697cf78a, 0x487fffe4), STCP(0x694015c3, 0x48d84609),
+ STCP(0x6902ea1d, 0x4930590f), STCP(0x68c574c4, 0x498838b6),
+ STCP(0x6887b5e2, 0x49dfe4c2), STCP(0x6849ada3, 0x4a375cf5),
+ STCP(0x680b5c33, 0x4a8ea111), STCP(0x67ccc1be, 0x4ae5b0da),
+ STCP(0x678dde6e, 0x4b3c8c12), STCP(0x674eb271, 0x4b93327c),
+ STCP(0x670f3df3, 0x4be9a3db), STCP(0x66cf8120, 0x4c3fdff4),
+ STCP(0x668f7c25, 0x4c95e688), STCP(0x664f2f2e, 0x4cebb75c),
+ STCP(0x660e9a6a, 0x4d415234), STCP(0x65cdbe05, 0x4d96b6d3),
+ STCP(0x658c9a2d, 0x4debe4fe), STCP(0x654b2f10, 0x4e40dc79),
+ STCP(0x65097cdb, 0x4e959d08), STCP(0x64c783bd, 0x4eea2670),
+ STCP(0x648543e4, 0x4f3e7875), STCP(0x6442bd7e, 0x4f9292dc),
+ STCP(0x63fff0ba, 0x4fe6756a), STCP(0x63bcddc7, 0x503a1fe5),
+ STCP(0x637984d4, 0x508d9211), STCP(0x6335e611, 0x50e0cbb4),
+ STCP(0x62f201ac, 0x5133cc94), STCP(0x62add7d6, 0x51869476),
+ STCP(0x626968be, 0x51d92321), STCP(0x6224b495, 0x522b7859),
+ STCP(0x61dfbb8a, 0x527d93e6), STCP(0x619a7dce, 0x52cf758f),
+ STCP(0x6154fb91, 0x53211d18), STCP(0x610f3505, 0x53728a4a),
+ STCP(0x60c92a5a, 0x53c3bcea), STCP(0x6082dbc1, 0x5414b4c1),
+ STCP(0x603c496c, 0x54657194), STCP(0x5ff5738d, 0x54b5f32c),
+ STCP(0x5fae5a55, 0x55063951), STCP(0x5f66fdf5, 0x555643c8),
+ STCP(0x5f1f5ea1, 0x55a6125c), STCP(0x5ed77c8a, 0x55f5a4d2),
+ STCP(0x5e8f57e2, 0x5644faf4), STCP(0x5e46f0dd, 0x5694148b),
+ STCP(0x5dfe47ad, 0x56e2f15d), STCP(0x5db55c86, 0x57319135),
+ STCP(0x5d6c2f99, 0x577ff3da), STCP(0x5d22c11c, 0x57ce1917),
+ STCP(0x5cd91140, 0x581c00b3), STCP(0x5c8f203b, 0x5869aa79),
+ STCP(0x5c44ee40, 0x58b71632), STCP(0x5bfa7b82, 0x590443a7),
+ STCP(0x5bafc837, 0x595132a2), STCP(0x5b64d492, 0x599de2ee),
+ STCP(0x5b19a0c8, 0x59ea5454), STCP(0x5ace2d0f, 0x5a36869f),
+ STCP(0x5a82799a, 0x5a82799a),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STP SineTable512[] = {
+ STCP(0x7fffffff, 0x00000000), STCP(0x7fffd886, 0x006487e3),
+ STCP(0x7fff6216, 0x00c90f88), STCP(0x7ffe9cb2, 0x012d96b1),
+ STCP(0x7ffd885a, 0x01921d20), STCP(0x7ffc250f, 0x01f6a297),
+ STCP(0x7ffa72d1, 0x025b26d7), STCP(0x7ff871a2, 0x02bfa9a4),
+ STCP(0x7ff62182, 0x03242abf), STCP(0x7ff38274, 0x0388a9ea),
+ STCP(0x7ff09478, 0x03ed26e6), STCP(0x7fed5791, 0x0451a177),
+ STCP(0x7fe9cbc0, 0x04b6195d), STCP(0x7fe5f108, 0x051a8e5c),
+ STCP(0x7fe1c76b, 0x057f0035), STCP(0x7fdd4eec, 0x05e36ea9),
+ STCP(0x7fd8878e, 0x0647d97c), STCP(0x7fd37153, 0x06ac406f),
+ STCP(0x7fce0c3e, 0x0710a345), STCP(0x7fc85854, 0x077501be),
+ STCP(0x7fc25596, 0x07d95b9e), STCP(0x7fbc040a, 0x083db0a7),
+ STCP(0x7fb563b3, 0x08a2009a), STCP(0x7fae7495, 0x09064b3a),
+ STCP(0x7fa736b4, 0x096a9049), STCP(0x7f9faa15, 0x09cecf89),
+ STCP(0x7f97cebd, 0x0a3308bd), STCP(0x7f8fa4b0, 0x0a973ba5),
+ STCP(0x7f872bf3, 0x0afb6805), STCP(0x7f7e648c, 0x0b5f8d9f),
+ STCP(0x7f754e80, 0x0bc3ac35), STCP(0x7f6be9d4, 0x0c27c389),
+ STCP(0x7f62368f, 0x0c8bd35e), STCP(0x7f5834b7, 0x0cefdb76),
+ STCP(0x7f4de451, 0x0d53db92), STCP(0x7f434563, 0x0db7d376),
+ STCP(0x7f3857f6, 0x0e1bc2e4), STCP(0x7f2d1c0e, 0x0e7fa99e),
+ STCP(0x7f2191b4, 0x0ee38766), STCP(0x7f15b8ee, 0x0f475bff),
+ STCP(0x7f0991c4, 0x0fab272b), STCP(0x7efd1c3c, 0x100ee8ad),
+ STCP(0x7ef05860, 0x1072a048), STCP(0x7ee34636, 0x10d64dbd),
+ STCP(0x7ed5e5c6, 0x1139f0cf), STCP(0x7ec8371a, 0x119d8941),
+ STCP(0x7eba3a39, 0x120116d5), STCP(0x7eabef2c, 0x1264994e),
+ STCP(0x7e9d55fc, 0x12c8106f), STCP(0x7e8e6eb2, 0x132b7bf9),
+ STCP(0x7e7f3957, 0x138edbb1), STCP(0x7e6fb5f4, 0x13f22f58),
+ STCP(0x7e5fe493, 0x145576b1), STCP(0x7e4fc53e, 0x14b8b17f),
+ STCP(0x7e3f57ff, 0x151bdf86), STCP(0x7e2e9cdf, 0x157f0086),
+ STCP(0x7e1d93ea, 0x15e21445), STCP(0x7e0c3d29, 0x16451a83),
+ STCP(0x7dfa98a8, 0x16a81305), STCP(0x7de8a670, 0x170afd8d),
+ STCP(0x7dd6668f, 0x176dd9de), STCP(0x7dc3d90d, 0x17d0a7bc),
+ STCP(0x7db0fdf8, 0x183366e9), STCP(0x7d9dd55a, 0x18961728),
+ STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d769bb5, 0x195b49ea),
+ STCP(0x7d628ac6, 0x19bdcbf3), STCP(0x7d4e2c7f, 0x1a203e1b),
+ STCP(0x7d3980ec, 0x1a82a026), STCP(0x7d24881b, 0x1ae4f1d6),
+ STCP(0x7d0f4218, 0x1b4732ef), STCP(0x7cf9aef0, 0x1ba96335),
+ STCP(0x7ce3ceb2, 0x1c0b826a), STCP(0x7ccda169, 0x1c6d9053),
+ STCP(0x7cb72724, 0x1ccf8cb3), STCP(0x7ca05ff1, 0x1d31774d),
+ STCP(0x7c894bde, 0x1d934fe5), STCP(0x7c71eaf9, 0x1df5163f),
+ STCP(0x7c5a3d50, 0x1e56ca1e), STCP(0x7c4242f2, 0x1eb86b46),
+ STCP(0x7c29fbee, 0x1f19f97b), STCP(0x7c116853, 0x1f7b7481),
+ STCP(0x7bf88830, 0x1fdcdc1b), STCP(0x7bdf5b94, 0x203e300d),
+ STCP(0x7bc5e290, 0x209f701c), STCP(0x7bac1d31, 0x21009c0c),
+ STCP(0x7b920b89, 0x2161b3a0), STCP(0x7b77ada8, 0x21c2b69c),
+ STCP(0x7b5d039e, 0x2223a4c5), STCP(0x7b420d7a, 0x22847de0),
+ STCP(0x7b26cb4f, 0x22e541af), STCP(0x7b0b3d2c, 0x2345eff8),
+ STCP(0x7aef6323, 0x23a6887f), STCP(0x7ad33d45, 0x24070b08),
+ STCP(0x7ab6cba4, 0x24677758), STCP(0x7a9a0e50, 0x24c7cd33),
+ STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a5fb0d8, 0x2588349d),
+ STCP(0x7a4210d8, 0x25e845b6), STCP(0x7a24256f, 0x26483f6c),
+ STCP(0x7a05eead, 0x26a82186), STCP(0x79e76ca7, 0x2707ebc7),
+ STCP(0x79c89f6e, 0x27679df4), STCP(0x79a98715, 0x27c737d3),
+ STCP(0x798a23b1, 0x2826b928), STCP(0x796a7554, 0x288621b9),
+ STCP(0x794a7c12, 0x28e5714b), STCP(0x792a37fe, 0x2944a7a2),
+ STCP(0x7909a92d, 0x29a3c485), STCP(0x78e8cfb2, 0x2a02c7b8),
+ STCP(0x78c7aba2, 0x2a61b101), STCP(0x78a63d11, 0x2ac08026),
+ STCP(0x78848414, 0x2b1f34eb), STCP(0x786280bf, 0x2b7dcf17),
+ STCP(0x78403329, 0x2bdc4e6f), STCP(0x781d9b65, 0x2c3ab2b9),
+ STCP(0x77fab989, 0x2c98fbba), STCP(0x77d78daa, 0x2cf72939),
+ STCP(0x77b417df, 0x2d553afc), STCP(0x7790583e, 0x2db330c7),
+ STCP(0x776c4edb, 0x2e110a62), STCP(0x7747fbce, 0x2e6ec792),
+ STCP(0x77235f2d, 0x2ecc681e), STCP(0x76fe790e, 0x2f29ebcc),
+ STCP(0x76d94989, 0x2f875262), STCP(0x76b3d0b4, 0x2fe49ba7),
+ STCP(0x768e0ea6, 0x3041c761), STCP(0x76680376, 0x309ed556),
+ STCP(0x7641af3d, 0x30fbc54d), STCP(0x761b1211, 0x3158970e),
+ STCP(0x75f42c0b, 0x31b54a5e), STCP(0x75ccfd42, 0x3211df04),
+ STCP(0x75a585cf, 0x326e54c7), STCP(0x757dc5ca, 0x32caab6f),
+ STCP(0x7555bd4c, 0x3326e2c3), STCP(0x752d6c6c, 0x3382fa88),
+ STCP(0x7504d345, 0x33def287), STCP(0x74dbf1ef, 0x343aca87),
+ STCP(0x74b2c884, 0x34968250), STCP(0x7489571c, 0x34f219a8),
+ STCP(0x745f9dd1, 0x354d9057), STCP(0x74359cbd, 0x35a8e625),
+ STCP(0x740b53fb, 0x36041ad9), STCP(0x73e0c3a3, 0x365f2e3b),
+ STCP(0x73b5ebd1, 0x36ba2014), STCP(0x738acc9e, 0x3714f02a),
+ STCP(0x735f6626, 0x376f9e46), STCP(0x7333b883, 0x37ca2a30),
+ STCP(0x7307c3d0, 0x382493b0), STCP(0x72db8828, 0x387eda8e),
+ STCP(0x72af05a7, 0x38d8fe93), STCP(0x72823c67, 0x3932ff87),
+ STCP(0x72552c85, 0x398cdd32), STCP(0x7227d61c, 0x39e6975e),
+ STCP(0x71fa3949, 0x3a402dd2), STCP(0x71cc5626, 0x3a99a057),
+ STCP(0x719e2cd2, 0x3af2eeb7), STCP(0x716fbd68, 0x3b4c18ba),
+ STCP(0x71410805, 0x3ba51e29), STCP(0x71120cc5, 0x3bfdfecd),
+ STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70b34525, 0x3caf50da),
+ STCP(0x708378ff, 0x3d07c1d6), STCP(0x70536771, 0x3d600d2c),
+ STCP(0x7023109a, 0x3db832a6), STCP(0x6ff27497, 0x3e10320d),
+ STCP(0x6fc19385, 0x3e680b2c), STCP(0x6f906d84, 0x3ebfbdcd),
+ STCP(0x6f5f02b2, 0x3f1749b8), STCP(0x6f2d532c, 0x3f6eaeb8),
+ STCP(0x6efb5f12, 0x3fc5ec98), STCP(0x6ec92683, 0x401d0321),
+ STCP(0x6e96a99d, 0x4073f21d), STCP(0x6e63e87f, 0x40cab958),
+ STCP(0x6e30e34a, 0x4121589b), STCP(0x6dfd9a1c, 0x4177cfb1),
+ STCP(0x6dca0d14, 0x41ce1e65), STCP(0x6d963c54, 0x42244481),
+ STCP(0x6d6227fa, 0x427a41d0), STCP(0x6d2dd027, 0x42d0161e),
+ STCP(0x6cf934fc, 0x4325c135), STCP(0x6cc45698, 0x437b42e1),
+ STCP(0x6c8f351c, 0x43d09aed), STCP(0x6c59d0a9, 0x4425c923),
+ STCP(0x6c242960, 0x447acd50), STCP(0x6bee3f62, 0x44cfa740),
+ STCP(0x6bb812d1, 0x452456bd), STCP(0x6b81a3cd, 0x4578db93),
+ STCP(0x6b4af279, 0x45cd358f), STCP(0x6b13fef5, 0x4621647d),
+ STCP(0x6adcc964, 0x46756828), STCP(0x6aa551e9, 0x46c9405c),
+ STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a359db9, 0x47706d93),
+ STCP(0x69fd614a, 0x47c3c22f), STCP(0x69c4e37a, 0x4816ea86),
+ STCP(0x698c246c, 0x4869e665), STCP(0x69532442, 0x48bcb599),
+ STCP(0x6919e320, 0x490f57ee), STCP(0x68e06129, 0x4961cd33),
+ STCP(0x68a69e81, 0x49b41533), STCP(0x686c9b4b, 0x4a062fbd),
+ STCP(0x683257ab, 0x4a581c9e), STCP(0x67f7d3c5, 0x4aa9dba2),
+ STCP(0x67bd0fbd, 0x4afb6c98), STCP(0x67820bb7, 0x4b4ccf4d),
+ STCP(0x6746c7d8, 0x4b9e0390), STCP(0x670b4444, 0x4bef092d),
+ STCP(0x66cf8120, 0x4c3fdff4), STCP(0x66937e91, 0x4c9087b1),
+ STCP(0x66573cbb, 0x4ce10034), STCP(0x661abbc5, 0x4d31494b),
+ STCP(0x65ddfbd3, 0x4d8162c4), STCP(0x65a0fd0b, 0x4dd14c6e),
+ STCP(0x6563bf92, 0x4e210617), STCP(0x6526438f, 0x4e708f8f),
+ STCP(0x64e88926, 0x4ebfe8a5), STCP(0x64aa907f, 0x4f0f1126),
+ STCP(0x646c59bf, 0x4f5e08e3), STCP(0x642de50d, 0x4faccfab),
+ STCP(0x63ef3290, 0x4ffb654d), STCP(0x63b0426d, 0x5049c999),
+ STCP(0x637114cc, 0x5097fc5e), STCP(0x6331a9d4, 0x50e5fd6d),
+ STCP(0x62f201ac, 0x5133cc94), STCP(0x62b21c7b, 0x518169a5),
+ STCP(0x6271fa69, 0x51ced46e), STCP(0x62319b9d, 0x521c0cc2),
+ STCP(0x61f1003f, 0x5269126e), STCP(0x61b02876, 0x52b5e546),
+ STCP(0x616f146c, 0x53028518), STCP(0x612dc447, 0x534ef1b5),
+ STCP(0x60ec3830, 0x539b2af0), STCP(0x60aa7050, 0x53e73097),
+ STCP(0x60686ccf, 0x5433027d), STCP(0x60262dd6, 0x547ea073),
+ STCP(0x5fe3b38d, 0x54ca0a4b), STCP(0x5fa0fe1f, 0x55153fd4),
+ STCP(0x5f5e0db3, 0x556040e2), STCP(0x5f1ae274, 0x55ab0d46),
+ STCP(0x5ed77c8a, 0x55f5a4d2), STCP(0x5e93dc1f, 0x56400758),
+ STCP(0x5e50015d, 0x568a34a9), STCP(0x5e0bec6e, 0x56d42c99),
+ STCP(0x5dc79d7c, 0x571deefa), STCP(0x5d8314b1, 0x57677b9d),
+ STCP(0x5d3e5237, 0x57b0d256), STCP(0x5cf95638, 0x57f9f2f8),
+ STCP(0x5cb420e0, 0x5842dd54), STCP(0x5c6eb258, 0x588b9140),
+ STCP(0x5c290acc, 0x58d40e8c), STCP(0x5be32a67, 0x591c550e),
+ STCP(0x5b9d1154, 0x59646498), STCP(0x5b56bfbd, 0x59ac3cfd),
+ STCP(0x5b1035cf, 0x59f3de12), STCP(0x5ac973b5, 0x5a3b47ab),
+ STCP(0x5a82799a, 0x5a82799a),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STP SineTable1024[] = {
+ STCP(0x7fffffff, 0x00000000), STCP(0x7ffff621, 0x003243f5),
+ STCP(0x7fffd886, 0x006487e3), STCP(0x7fffa72c, 0x0096cbc1),
+ STCP(0x7fff6216, 0x00c90f88), STCP(0x7fff0943, 0x00fb5330),
+ STCP(0x7ffe9cb2, 0x012d96b1), STCP(0x7ffe1c65, 0x015fda03),
+ STCP(0x7ffd885a, 0x01921d20), STCP(0x7ffce093, 0x01c45ffe),
+ STCP(0x7ffc250f, 0x01f6a297), STCP(0x7ffb55ce, 0x0228e4e2),
+ STCP(0x7ffa72d1, 0x025b26d7), STCP(0x7ff97c18, 0x028d6870),
+ STCP(0x7ff871a2, 0x02bfa9a4), STCP(0x7ff75370, 0x02f1ea6c),
+ STCP(0x7ff62182, 0x03242abf), STCP(0x7ff4dbd9, 0x03566a96),
+ STCP(0x7ff38274, 0x0388a9ea), STCP(0x7ff21553, 0x03bae8b2),
+ STCP(0x7ff09478, 0x03ed26e6), STCP(0x7feeffe1, 0x041f6480),
+ STCP(0x7fed5791, 0x0451a177), STCP(0x7feb9b85, 0x0483ddc3),
+ STCP(0x7fe9cbc0, 0x04b6195d), STCP(0x7fe7e841, 0x04e8543e),
+ STCP(0x7fe5f108, 0x051a8e5c), STCP(0x7fe3e616, 0x054cc7b1),
+ STCP(0x7fe1c76b, 0x057f0035), STCP(0x7fdf9508, 0x05b137df),
+ STCP(0x7fdd4eec, 0x05e36ea9), STCP(0x7fdaf519, 0x0615a48b),
+ STCP(0x7fd8878e, 0x0647d97c), STCP(0x7fd6064c, 0x067a0d76),
+ STCP(0x7fd37153, 0x06ac406f), STCP(0x7fd0c8a3, 0x06de7262),
+ STCP(0x7fce0c3e, 0x0710a345), STCP(0x7fcb3c23, 0x0742d311),
+ STCP(0x7fc85854, 0x077501be), STCP(0x7fc560cf, 0x07a72f45),
+ STCP(0x7fc25596, 0x07d95b9e), STCP(0x7fbf36aa, 0x080b86c2),
+ STCP(0x7fbc040a, 0x083db0a7), STCP(0x7fb8bdb8, 0x086fd947),
+ STCP(0x7fb563b3, 0x08a2009a), STCP(0x7fb1f5fc, 0x08d42699),
+ STCP(0x7fae7495, 0x09064b3a), STCP(0x7faadf7c, 0x09386e78),
+ STCP(0x7fa736b4, 0x096a9049), STCP(0x7fa37a3c, 0x099cb0a7),
+ STCP(0x7f9faa15, 0x09cecf89), STCP(0x7f9bc640, 0x0a00ece8),
+ STCP(0x7f97cebd, 0x0a3308bd), STCP(0x7f93c38c, 0x0a6522fe),
+ STCP(0x7f8fa4b0, 0x0a973ba5), STCP(0x7f8b7227, 0x0ac952aa),
+ STCP(0x7f872bf3, 0x0afb6805), STCP(0x7f82d214, 0x0b2d7baf),
+ STCP(0x7f7e648c, 0x0b5f8d9f), STCP(0x7f79e35a, 0x0b919dcf),
+ STCP(0x7f754e80, 0x0bc3ac35), STCP(0x7f70a5fe, 0x0bf5b8cb),
+ STCP(0x7f6be9d4, 0x0c27c389), STCP(0x7f671a05, 0x0c59cc68),
+ STCP(0x7f62368f, 0x0c8bd35e), STCP(0x7f5d3f75, 0x0cbdd865),
+ STCP(0x7f5834b7, 0x0cefdb76), STCP(0x7f531655, 0x0d21dc87),
+ STCP(0x7f4de451, 0x0d53db92), STCP(0x7f489eaa, 0x0d85d88f),
+ STCP(0x7f434563, 0x0db7d376), STCP(0x7f3dd87c, 0x0de9cc40),
+ STCP(0x7f3857f6, 0x0e1bc2e4), STCP(0x7f32c3d1, 0x0e4db75b),
+ STCP(0x7f2d1c0e, 0x0e7fa99e), STCP(0x7f2760af, 0x0eb199a4),
+ STCP(0x7f2191b4, 0x0ee38766), STCP(0x7f1baf1e, 0x0f1572dc),
+ STCP(0x7f15b8ee, 0x0f475bff), STCP(0x7f0faf25, 0x0f7942c7),
+ STCP(0x7f0991c4, 0x0fab272b), STCP(0x7f0360cb, 0x0fdd0926),
+ STCP(0x7efd1c3c, 0x100ee8ad), STCP(0x7ef6c418, 0x1040c5bb),
+ STCP(0x7ef05860, 0x1072a048), STCP(0x7ee9d914, 0x10a4784b),
+ STCP(0x7ee34636, 0x10d64dbd), STCP(0x7edc9fc6, 0x11082096),
+ STCP(0x7ed5e5c6, 0x1139f0cf), STCP(0x7ecf1837, 0x116bbe60),
+ STCP(0x7ec8371a, 0x119d8941), STCP(0x7ec14270, 0x11cf516a),
+ STCP(0x7eba3a39, 0x120116d5), STCP(0x7eb31e78, 0x1232d979),
+ STCP(0x7eabef2c, 0x1264994e), STCP(0x7ea4ac58, 0x1296564d),
+ STCP(0x7e9d55fc, 0x12c8106f), STCP(0x7e95ec1a, 0x12f9c7aa),
+ STCP(0x7e8e6eb2, 0x132b7bf9), STCP(0x7e86ddc6, 0x135d2d53),
+ STCP(0x7e7f3957, 0x138edbb1), STCP(0x7e778166, 0x13c0870a),
+ STCP(0x7e6fb5f4, 0x13f22f58), STCP(0x7e67d703, 0x1423d492),
+ STCP(0x7e5fe493, 0x145576b1), STCP(0x7e57dea7, 0x148715ae),
+ STCP(0x7e4fc53e, 0x14b8b17f), STCP(0x7e47985b, 0x14ea4a1f),
+ STCP(0x7e3f57ff, 0x151bdf86), STCP(0x7e37042a, 0x154d71aa),
+ STCP(0x7e2e9cdf, 0x157f0086), STCP(0x7e26221f, 0x15b08c12),
+ STCP(0x7e1d93ea, 0x15e21445), STCP(0x7e14f242, 0x16139918),
+ STCP(0x7e0c3d29, 0x16451a83), STCP(0x7e0374a0, 0x1676987f),
+ STCP(0x7dfa98a8, 0x16a81305), STCP(0x7df1a942, 0x16d98a0c),
+ STCP(0x7de8a670, 0x170afd8d), STCP(0x7ddf9034, 0x173c6d80),
+ STCP(0x7dd6668f, 0x176dd9de), STCP(0x7dcd2981, 0x179f429f),
+ STCP(0x7dc3d90d, 0x17d0a7bc), STCP(0x7dba7534, 0x1802092c),
+ STCP(0x7db0fdf8, 0x183366e9), STCP(0x7da77359, 0x1864c0ea),
+ STCP(0x7d9dd55a, 0x18961728), STCP(0x7d9423fc, 0x18c7699b),
+ STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x7d808728, 0x192a0304),
+ STCP(0x7d769bb5, 0x195b49ea), STCP(0x7d6c9ce9, 0x198c8ce7),
+ STCP(0x7d628ac6, 0x19bdcbf3), STCP(0x7d58654d, 0x19ef0707),
+ STCP(0x7d4e2c7f, 0x1a203e1b), STCP(0x7d43e05e, 0x1a517128),
+ STCP(0x7d3980ec, 0x1a82a026), STCP(0x7d2f0e2b, 0x1ab3cb0d),
+ STCP(0x7d24881b, 0x1ae4f1d6), STCP(0x7d19eebf, 0x1b161479),
+ STCP(0x7d0f4218, 0x1b4732ef), STCP(0x7d048228, 0x1b784d30),
+ STCP(0x7cf9aef0, 0x1ba96335), STCP(0x7ceec873, 0x1bda74f6),
+ STCP(0x7ce3ceb2, 0x1c0b826a), STCP(0x7cd8c1ae, 0x1c3c8b8c),
+ STCP(0x7ccda169, 0x1c6d9053), STCP(0x7cc26de5, 0x1c9e90b8),
+ STCP(0x7cb72724, 0x1ccf8cb3), STCP(0x7cabcd28, 0x1d00843d),
+ STCP(0x7ca05ff1, 0x1d31774d), STCP(0x7c94df83, 0x1d6265dd),
+ STCP(0x7c894bde, 0x1d934fe5), STCP(0x7c7da505, 0x1dc4355e),
+ STCP(0x7c71eaf9, 0x1df5163f), STCP(0x7c661dbc, 0x1e25f282),
+ STCP(0x7c5a3d50, 0x1e56ca1e), STCP(0x7c4e49b7, 0x1e879d0d),
+ STCP(0x7c4242f2, 0x1eb86b46), STCP(0x7c362904, 0x1ee934c3),
+ STCP(0x7c29fbee, 0x1f19f97b), STCP(0x7c1dbbb3, 0x1f4ab968),
+ STCP(0x7c116853, 0x1f7b7481), STCP(0x7c0501d2, 0x1fac2abf),
+ STCP(0x7bf88830, 0x1fdcdc1b), STCP(0x7bebfb70, 0x200d888d),
+ STCP(0x7bdf5b94, 0x203e300d), STCP(0x7bd2a89e, 0x206ed295),
+ STCP(0x7bc5e290, 0x209f701c), STCP(0x7bb9096b, 0x20d0089c),
+ STCP(0x7bac1d31, 0x21009c0c), STCP(0x7b9f1de6, 0x21312a65),
+ STCP(0x7b920b89, 0x2161b3a0), STCP(0x7b84e61f, 0x219237b5),
+ STCP(0x7b77ada8, 0x21c2b69c), STCP(0x7b6a6227, 0x21f3304f),
+ STCP(0x7b5d039e, 0x2223a4c5), STCP(0x7b4f920e, 0x225413f8),
+ STCP(0x7b420d7a, 0x22847de0), STCP(0x7b3475e5, 0x22b4e274),
+ STCP(0x7b26cb4f, 0x22e541af), STCP(0x7b190dbc, 0x23159b88),
+ STCP(0x7b0b3d2c, 0x2345eff8), STCP(0x7afd59a4, 0x23763ef7),
+ STCP(0x7aef6323, 0x23a6887f), STCP(0x7ae159ae, 0x23d6cc87),
+ STCP(0x7ad33d45, 0x24070b08), STCP(0x7ac50dec, 0x243743fa),
+ STCP(0x7ab6cba4, 0x24677758), STCP(0x7aa8766f, 0x2497a517),
+ STCP(0x7a9a0e50, 0x24c7cd33), STCP(0x7a8b9348, 0x24f7efa2),
+ STCP(0x7a7d055b, 0x25280c5e), STCP(0x7a6e648a, 0x2558235f),
+ STCP(0x7a5fb0d8, 0x2588349d), STCP(0x7a50ea47, 0x25b84012),
+ STCP(0x7a4210d8, 0x25e845b6), STCP(0x7a332490, 0x26184581),
+ STCP(0x7a24256f, 0x26483f6c), STCP(0x7a151378, 0x26783370),
+ STCP(0x7a05eead, 0x26a82186), STCP(0x79f6b711, 0x26d809a5),
+ STCP(0x79e76ca7, 0x2707ebc7), STCP(0x79d80f6f, 0x2737c7e3),
+ STCP(0x79c89f6e, 0x27679df4), STCP(0x79b91ca4, 0x27976df1),
+ STCP(0x79a98715, 0x27c737d3), STCP(0x7999dec4, 0x27f6fb92),
+ STCP(0x798a23b1, 0x2826b928), STCP(0x797a55e0, 0x2856708d),
+ STCP(0x796a7554, 0x288621b9), STCP(0x795a820e, 0x28b5cca5),
+ STCP(0x794a7c12, 0x28e5714b), STCP(0x793a6361, 0x29150fa1),
+ STCP(0x792a37fe, 0x2944a7a2), STCP(0x7919f9ec, 0x29743946),
+ STCP(0x7909a92d, 0x29a3c485), STCP(0x78f945c3, 0x29d34958),
+ STCP(0x78e8cfb2, 0x2a02c7b8), STCP(0x78d846fb, 0x2a323f9e),
+ STCP(0x78c7aba2, 0x2a61b101), STCP(0x78b6fda8, 0x2a911bdc),
+ STCP(0x78a63d11, 0x2ac08026), STCP(0x789569df, 0x2aefddd8),
+ STCP(0x78848414, 0x2b1f34eb), STCP(0x78738bb3, 0x2b4e8558),
+ STCP(0x786280bf, 0x2b7dcf17), STCP(0x7851633b, 0x2bad1221),
+ STCP(0x78403329, 0x2bdc4e6f), STCP(0x782ef08b, 0x2c0b83fa),
+ STCP(0x781d9b65, 0x2c3ab2b9), STCP(0x780c33b8, 0x2c69daa6),
+ STCP(0x77fab989, 0x2c98fbba), STCP(0x77e92cd9, 0x2cc815ee),
+ STCP(0x77d78daa, 0x2cf72939), STCP(0x77c5dc01, 0x2d263596),
+ STCP(0x77b417df, 0x2d553afc), STCP(0x77a24148, 0x2d843964),
+ STCP(0x7790583e, 0x2db330c7), STCP(0x777e5cc3, 0x2de2211e),
+ STCP(0x776c4edb, 0x2e110a62), STCP(0x775a2e89, 0x2e3fec8b),
+ STCP(0x7747fbce, 0x2e6ec792), STCP(0x7735b6af, 0x2e9d9b70),
+ STCP(0x77235f2d, 0x2ecc681e), STCP(0x7710f54c, 0x2efb2d95),
+ STCP(0x76fe790e, 0x2f29ebcc), STCP(0x76ebea77, 0x2f58a2be),
+ STCP(0x76d94989, 0x2f875262), STCP(0x76c69647, 0x2fb5fab2),
+ STCP(0x76b3d0b4, 0x2fe49ba7), STCP(0x76a0f8d2, 0x30133539),
+ STCP(0x768e0ea6, 0x3041c761), STCP(0x767b1231, 0x30705217),
+ STCP(0x76680376, 0x309ed556), STCP(0x7654e279, 0x30cd5115),
+ STCP(0x7641af3d, 0x30fbc54d), STCP(0x762e69c4, 0x312a31f8),
+ STCP(0x761b1211, 0x3158970e), STCP(0x7607a828, 0x3186f487),
+ STCP(0x75f42c0b, 0x31b54a5e), STCP(0x75e09dbd, 0x31e39889),
+ STCP(0x75ccfd42, 0x3211df04), STCP(0x75b94a9c, 0x32401dc6),
+ STCP(0x75a585cf, 0x326e54c7), STCP(0x7591aedd, 0x329c8402),
+ STCP(0x757dc5ca, 0x32caab6f), STCP(0x7569ca99, 0x32f8cb07),
+ STCP(0x7555bd4c, 0x3326e2c3), STCP(0x75419de7, 0x3354f29b),
+ STCP(0x752d6c6c, 0x3382fa88), STCP(0x751928e0, 0x33b0fa84),
+ STCP(0x7504d345, 0x33def287), STCP(0x74f06b9e, 0x340ce28b),
+ STCP(0x74dbf1ef, 0x343aca87), STCP(0x74c7663a, 0x3468aa76),
+ STCP(0x74b2c884, 0x34968250), STCP(0x749e18cd, 0x34c4520d),
+ STCP(0x7489571c, 0x34f219a8), STCP(0x74748371, 0x351fd918),
+ STCP(0x745f9dd1, 0x354d9057), STCP(0x744aa63f, 0x357b3f5d),
+ STCP(0x74359cbd, 0x35a8e625), STCP(0x74208150, 0x35d684a6),
+ STCP(0x740b53fb, 0x36041ad9), STCP(0x73f614c0, 0x3631a8b8),
+ STCP(0x73e0c3a3, 0x365f2e3b), STCP(0x73cb60a8, 0x368cab5c),
+ STCP(0x73b5ebd1, 0x36ba2014), STCP(0x73a06522, 0x36e78c5b),
+ STCP(0x738acc9e, 0x3714f02a), STCP(0x73752249, 0x37424b7b),
+ STCP(0x735f6626, 0x376f9e46), STCP(0x73499838, 0x379ce885),
+ STCP(0x7333b883, 0x37ca2a30), STCP(0x731dc70a, 0x37f76341),
+ STCP(0x7307c3d0, 0x382493b0), STCP(0x72f1aed9, 0x3851bb77),
+ STCP(0x72db8828, 0x387eda8e), STCP(0x72c54fc1, 0x38abf0ef),
+ STCP(0x72af05a7, 0x38d8fe93), STCP(0x7298a9dd, 0x39060373),
+ STCP(0x72823c67, 0x3932ff87), STCP(0x726bbd48, 0x395ff2c9),
+ STCP(0x72552c85, 0x398cdd32), STCP(0x723e8a20, 0x39b9bebc),
+ STCP(0x7227d61c, 0x39e6975e), STCP(0x7211107e, 0x3a136712),
+ STCP(0x71fa3949, 0x3a402dd2), STCP(0x71e35080, 0x3a6ceb96),
+ STCP(0x71cc5626, 0x3a99a057), STCP(0x71b54a41, 0x3ac64c0f),
+ STCP(0x719e2cd2, 0x3af2eeb7), STCP(0x7186fdde, 0x3b1f8848),
+ STCP(0x716fbd68, 0x3b4c18ba), STCP(0x71586b74, 0x3b78a007),
+ STCP(0x71410805, 0x3ba51e29), STCP(0x7129931f, 0x3bd19318),
+ STCP(0x71120cc5, 0x3bfdfecd), STCP(0x70fa74fc, 0x3c2a6142),
+ STCP(0x70e2cbc6, 0x3c56ba70), STCP(0x70cb1128, 0x3c830a50),
+ STCP(0x70b34525, 0x3caf50da), STCP(0x709b67c0, 0x3cdb8e09),
+ STCP(0x708378ff, 0x3d07c1d6), STCP(0x706b78e3, 0x3d33ec39),
+ STCP(0x70536771, 0x3d600d2c), STCP(0x703b44ad, 0x3d8c24a8),
+ STCP(0x7023109a, 0x3db832a6), STCP(0x700acb3c, 0x3de4371f),
+ STCP(0x6ff27497, 0x3e10320d), STCP(0x6fda0cae, 0x3e3c2369),
+ STCP(0x6fc19385, 0x3e680b2c), STCP(0x6fa90921, 0x3e93e950),
+ STCP(0x6f906d84, 0x3ebfbdcd), STCP(0x6f77c0b3, 0x3eeb889c),
+ STCP(0x6f5f02b2, 0x3f1749b8), STCP(0x6f463383, 0x3f430119),
+ STCP(0x6f2d532c, 0x3f6eaeb8), STCP(0x6f1461b0, 0x3f9a5290),
+ STCP(0x6efb5f12, 0x3fc5ec98), STCP(0x6ee24b57, 0x3ff17cca),
+ STCP(0x6ec92683, 0x401d0321), STCP(0x6eaff099, 0x40487f94),
+ STCP(0x6e96a99d, 0x4073f21d), STCP(0x6e7d5193, 0x409f5ab6),
+ STCP(0x6e63e87f, 0x40cab958), STCP(0x6e4a6e66, 0x40f60dfb),
+ STCP(0x6e30e34a, 0x4121589b), STCP(0x6e174730, 0x414c992f),
+ STCP(0x6dfd9a1c, 0x4177cfb1), STCP(0x6de3dc11, 0x41a2fc1a),
+ STCP(0x6dca0d14, 0x41ce1e65), STCP(0x6db02d29, 0x41f93689),
+ STCP(0x6d963c54, 0x42244481), STCP(0x6d7c3a98, 0x424f4845),
+ STCP(0x6d6227fa, 0x427a41d0), STCP(0x6d48047e, 0x42a5311b),
+ STCP(0x6d2dd027, 0x42d0161e), STCP(0x6d138afb, 0x42faf0d4),
+ STCP(0x6cf934fc, 0x4325c135), STCP(0x6cdece2f, 0x4350873c),
+ STCP(0x6cc45698, 0x437b42e1), STCP(0x6ca9ce3b, 0x43a5f41e),
+ STCP(0x6c8f351c, 0x43d09aed), STCP(0x6c748b3f, 0x43fb3746),
+ STCP(0x6c59d0a9, 0x4425c923), STCP(0x6c3f055d, 0x4450507e),
+ STCP(0x6c242960, 0x447acd50), STCP(0x6c093cb6, 0x44a53f93),
+ STCP(0x6bee3f62, 0x44cfa740), STCP(0x6bd3316a, 0x44fa0450),
+ STCP(0x6bb812d1, 0x452456bd), STCP(0x6b9ce39b, 0x454e9e80),
+ STCP(0x6b81a3cd, 0x4578db93), STCP(0x6b66536b, 0x45a30df0),
+ STCP(0x6b4af279, 0x45cd358f), STCP(0x6b2f80fb, 0x45f7526b),
+ STCP(0x6b13fef5, 0x4621647d), STCP(0x6af86c6c, 0x464b6bbe),
+ STCP(0x6adcc964, 0x46756828), STCP(0x6ac115e2, 0x469f59b4),
+ STCP(0x6aa551e9, 0x46c9405c), STCP(0x6a897d7d, 0x46f31c1a),
+ STCP(0x6a6d98a4, 0x471cece7), STCP(0x6a51a361, 0x4746b2bc),
+ STCP(0x6a359db9, 0x47706d93), STCP(0x6a1987b0, 0x479a1d67),
+ STCP(0x69fd614a, 0x47c3c22f), STCP(0x69e12a8c, 0x47ed5be6),
+ STCP(0x69c4e37a, 0x4816ea86), STCP(0x69a88c19, 0x48406e08),
+ STCP(0x698c246c, 0x4869e665), STCP(0x696fac78, 0x48935397),
+ STCP(0x69532442, 0x48bcb599), STCP(0x69368bce, 0x48e60c62),
+ STCP(0x6919e320, 0x490f57ee), STCP(0x68fd2a3d, 0x49389836),
+ STCP(0x68e06129, 0x4961cd33), STCP(0x68c387e9, 0x498af6df),
+ STCP(0x68a69e81, 0x49b41533), STCP(0x6889a4f6, 0x49dd282a),
+ STCP(0x686c9b4b, 0x4a062fbd), STCP(0x684f8186, 0x4a2f2be6),
+ STCP(0x683257ab, 0x4a581c9e), STCP(0x68151dbe, 0x4a8101de),
+ STCP(0x67f7d3c5, 0x4aa9dba2), STCP(0x67da79c3, 0x4ad2a9e2),
+ STCP(0x67bd0fbd, 0x4afb6c98), STCP(0x679f95b7, 0x4b2423be),
+ STCP(0x67820bb7, 0x4b4ccf4d), STCP(0x676471c0, 0x4b756f40),
+ STCP(0x6746c7d8, 0x4b9e0390), STCP(0x67290e02, 0x4bc68c36),
+ STCP(0x670b4444, 0x4bef092d), STCP(0x66ed6aa1, 0x4c177a6e),
+ STCP(0x66cf8120, 0x4c3fdff4), STCP(0x66b187c3, 0x4c6839b7),
+ STCP(0x66937e91, 0x4c9087b1), STCP(0x6675658c, 0x4cb8c9dd),
+ STCP(0x66573cbb, 0x4ce10034), STCP(0x66390422, 0x4d092ab0),
+ STCP(0x661abbc5, 0x4d31494b), STCP(0x65fc63a9, 0x4d595bfe),
+ STCP(0x65ddfbd3, 0x4d8162c4), STCP(0x65bf8447, 0x4da95d96),
+ STCP(0x65a0fd0b, 0x4dd14c6e), STCP(0x65826622, 0x4df92f46),
+ STCP(0x6563bf92, 0x4e210617), STCP(0x6545095f, 0x4e48d0dd),
+ STCP(0x6526438f, 0x4e708f8f), STCP(0x65076e25, 0x4e984229),
+ STCP(0x64e88926, 0x4ebfe8a5), STCP(0x64c99498, 0x4ee782fb),
+ STCP(0x64aa907f, 0x4f0f1126), STCP(0x648b7ce0, 0x4f369320),
+ STCP(0x646c59bf, 0x4f5e08e3), STCP(0x644d2722, 0x4f857269),
+ STCP(0x642de50d, 0x4faccfab), STCP(0x640e9386, 0x4fd420a4),
+ STCP(0x63ef3290, 0x4ffb654d), STCP(0x63cfc231, 0x50229da1),
+ STCP(0x63b0426d, 0x5049c999), STCP(0x6390b34a, 0x5070e92f),
+ STCP(0x637114cc, 0x5097fc5e), STCP(0x635166f9, 0x50bf031f),
+ STCP(0x6331a9d4, 0x50e5fd6d), STCP(0x6311dd64, 0x510ceb40),
+ STCP(0x62f201ac, 0x5133cc94), STCP(0x62d216b3, 0x515aa162),
+ STCP(0x62b21c7b, 0x518169a5), STCP(0x6292130c, 0x51a82555),
+ STCP(0x6271fa69, 0x51ced46e), STCP(0x6251d298, 0x51f576ea),
+ STCP(0x62319b9d, 0x521c0cc2), STCP(0x6211557e, 0x524295f0),
+ STCP(0x61f1003f, 0x5269126e), STCP(0x61d09be5, 0x528f8238),
+ STCP(0x61b02876, 0x52b5e546), STCP(0x618fa5f7, 0x52dc3b92),
+ STCP(0x616f146c, 0x53028518), STCP(0x614e73da, 0x5328c1d0),
+ STCP(0x612dc447, 0x534ef1b5), STCP(0x610d05b7, 0x537514c2),
+ STCP(0x60ec3830, 0x539b2af0), STCP(0x60cb5bb7, 0x53c13439),
+ STCP(0x60aa7050, 0x53e73097), STCP(0x60897601, 0x540d2005),
+ STCP(0x60686ccf, 0x5433027d), STCP(0x604754bf, 0x5458d7f9),
+ STCP(0x60262dd6, 0x547ea073), STCP(0x6004f819, 0x54a45be6),
+ STCP(0x5fe3b38d, 0x54ca0a4b), STCP(0x5fc26038, 0x54efab9c),
+ STCP(0x5fa0fe1f, 0x55153fd4), STCP(0x5f7f8d46, 0x553ac6ee),
+ STCP(0x5f5e0db3, 0x556040e2), STCP(0x5f3c7f6b, 0x5585adad),
+ STCP(0x5f1ae274, 0x55ab0d46), STCP(0x5ef936d1, 0x55d05faa),
+ STCP(0x5ed77c8a, 0x55f5a4d2), STCP(0x5eb5b3a2, 0x561adcb9),
+ STCP(0x5e93dc1f, 0x56400758), STCP(0x5e71f606, 0x566524aa),
+ STCP(0x5e50015d, 0x568a34a9), STCP(0x5e2dfe29, 0x56af3750),
+ STCP(0x5e0bec6e, 0x56d42c99), STCP(0x5de9cc33, 0x56f9147e),
+ STCP(0x5dc79d7c, 0x571deefa), STCP(0x5da5604f, 0x5742bc06),
+ STCP(0x5d8314b1, 0x57677b9d), STCP(0x5d60baa7, 0x578c2dba),
+ STCP(0x5d3e5237, 0x57b0d256), STCP(0x5d1bdb65, 0x57d5696d),
+ STCP(0x5cf95638, 0x57f9f2f8), STCP(0x5cd6c2b5, 0x581e6ef1),
+ STCP(0x5cb420e0, 0x5842dd54), STCP(0x5c9170bf, 0x58673e1b),
+ STCP(0x5c6eb258, 0x588b9140), STCP(0x5c4be5b0, 0x58afd6bd),
+ STCP(0x5c290acc, 0x58d40e8c), STCP(0x5c0621b2, 0x58f838a9),
+ STCP(0x5be32a67, 0x591c550e), STCP(0x5bc024f0, 0x594063b5),
+ STCP(0x5b9d1154, 0x59646498), STCP(0x5b79ef96, 0x598857b2),
+ STCP(0x5b56bfbd, 0x59ac3cfd), STCP(0x5b3381ce, 0x59d01475),
+ STCP(0x5b1035cf, 0x59f3de12), STCP(0x5aecdbc5, 0x5a1799d1),
+ STCP(0x5ac973b5, 0x5a3b47ab), STCP(0x5aa5fda5, 0x5a5ee79a),
+ STCP(0x5a82799a, 0x5a82799a),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal6[] = {
+ STC(0x40000000),
+ STC(0xc0000000),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag6[] = {
+ STC(0x6ed9eba1),
+ STC(0x6ed9eba1),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal12[] = {
+ STC(0x6ed9eba1),
+ STC(0x40000000),
+ STC(0x40000000),
+ STC(0xc0000000),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag12[] = {
+ STC(0x40000000),
+ STC(0x6ed9eba1),
+ STC(0x6ed9eba1),
+ STC(0x6ed9eba1),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal24[] = {
+ STC(0x7ba3751d), STC(0x6ed9eba1), STC(0x5a82799a), STC(0x40000000),
+ STC(0x2120fb83), STC(0x00000000), STC(0xdedf047d), STC(0xc0000000),
+ STC(0xa57d8666), STC(0x9126145f), STC(0x845c8ae3),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag24[] = {
+ STC(0x2120fb83), STC(0x40000000), STC(0x5a82799a), STC(0x6ed9eba1),
+ STC(0x7ba3751d), STC(0x7fffffff), STC(0x7ba3751d), STC(0x6ed9eba1),
+ STC(0x5a82799a), STC(0x40000000), STC(0x2120fb83),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal48[] = {
+ STC(0x7ee7aa4c), STC(0x7ba3751d), STC(0x7641af3d), STC(0x7ba3751d),
+ STC(0x6ed9eba1), STC(0x5a82799a), STC(0x7641af3d), STC(0x5a82799a),
+ STC(0x30fbc54d), STC(0x6ed9eba1), STC(0x40000000), STC(0x00000000),
+ STC(0x658c9a2d), STC(0x2120fb83), STC(0xcf043ab3), STC(0x5a82799a),
+ STC(0x00000000), STC(0xa57d8666), STC(0x4debe4fe), STC(0xdedf047d),
+ STC(0x89be50c3), STC(0x40000000), STC(0xc0000000), STC(0x80000000),
+ STC(0x30fbc54d), STC(0xa57d8666), STC(0x89be50c3), STC(0x2120fb83),
+ STC(0x9126145f), STC(0xa57d8666), STC(0x10b5150f), STC(0x845c8ae3),
+ STC(0xcf043ab3),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag48[] = {
+ STC(0x10b5150f), STC(0x2120fb83), STC(0x30fbc54d), STC(0x2120fb83),
+ STC(0x40000000), STC(0x5a82799a), STC(0x30fbc54d), STC(0x5a82799a),
+ STC(0x7641af3d), STC(0x40000000), STC(0x6ed9eba1), STC(0x7fffffff),
+ STC(0x4debe4fe), STC(0x7ba3751d), STC(0x7641af3d), STC(0x5a82799a),
+ STC(0x7fffffff), STC(0x5a82799a), STC(0x658c9a2d), STC(0x7ba3751d),
+ STC(0x30fbc54d), STC(0x6ed9eba1), STC(0x6ed9eba1), STC(0x00000000),
+ STC(0x7641af3d), STC(0x5a82799a), STC(0xcf043ab3), STC(0x7ba3751d),
+ STC(0x40000000), STC(0xa57d8666), STC(0x7ee7aa4c), STC(0x2120fb83),
+ STC(0x89be50c3),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal80[] = {
+ STC(0x7f9afcb9), STC(0x7e6c9251), STC(0x7c769e18), STC(0x79bc384d),
+ STC(0x7e6c9251), STC(0x79bc384d), STC(0x720c8075), STC(0x678dde6e),
+ STC(0x7c769e18), STC(0x720c8075), STC(0x6154fb91), STC(0x4b3c8c12),
+ STC(0x79bc384d), STC(0x678dde6e), STC(0x4b3c8c12), STC(0x278dde6e),
+ STC(0x7641af3d), STC(0x5a82799a), STC(0x30fbc54d), STC(0x00000000),
+ STC(0x720c8075), STC(0x4b3c8c12), STC(0x14060b68), STC(0xd8722192),
+ STC(0x6d23501b), STC(0x3a1c5c57), STC(0xf5f50d67), STC(0xb4c373ee),
+ STC(0x678dde6e), STC(0x278dde6e), STC(0xd8722192), STC(0x98722192),
+ STC(0x6154fb91), STC(0x14060b68), STC(0xbd1ec45c), STC(0x8643c7b3),
+ STC(0x5a82799a), STC(0x00000000), STC(0xa57d8666), STC(0x80000000),
+ STC(0x53211d18), STC(0xebf9f498), STC(0x92dcafe5), STC(0x8643c7b3),
+ STC(0x4b3c8c12), STC(0xd8722192), STC(0x8643c7b3), STC(0x98722192),
+ STC(0x42e13ba4), STC(0xc5e3a3a9), STC(0x80650347), STC(0xb4c373ee),
+ STC(0x3a1c5c57), STC(0xb4c373ee), STC(0x81936daf), STC(0xd8722192),
+ STC(0x30fbc54d), STC(0xa57d8666), STC(0x89be50c3), STC(0x00000000),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag80[] = {
+ STC(0x0a0af299), STC(0x14060b68), STC(0x1de189a6), STC(0x278dde6e),
+ STC(0x14060b68), STC(0x278dde6e), STC(0x3a1c5c57), STC(0x4b3c8c12),
+ STC(0x1de189a6), STC(0x3a1c5c57), STC(0x53211d18), STC(0x678dde6e),
+ STC(0x278dde6e), STC(0x4b3c8c12), STC(0x678dde6e), STC(0x79bc384d),
+ STC(0x30fbc54d), STC(0x5a82799a), STC(0x7641af3d), STC(0x7fffffff),
+ STC(0x3a1c5c57), STC(0x678dde6e), STC(0x7e6c9251), STC(0x79bc384d),
+ STC(0x42e13ba4), STC(0x720c8075), STC(0x7f9afcb9), STC(0x678dde6e),
+ STC(0x4b3c8c12), STC(0x79bc384d), STC(0x79bc384d), STC(0x4b3c8c12),
+ STC(0x53211d18), STC(0x7e6c9251), STC(0x6d23501b), STC(0x278dde6e),
+ STC(0x5a82799a), STC(0x7fffffff), STC(0x5a82799a), STC(0x00000000),
+ STC(0x6154fb91), STC(0x7e6c9251), STC(0x42e13ba4), STC(0xd8722192),
+ STC(0x678dde6e), STC(0x79bc384d), STC(0x278dde6e), STC(0xb4c373ee),
+ STC(0x6d23501b), STC(0x720c8075), STC(0x0a0af299), STC(0x98722192),
+ STC(0x720c8075), STC(0x678dde6e), STC(0xebf9f498), STC(0x8643c7b3),
+ STC(0x7641af3d), STC(0x5a82799a), STC(0xcf043ab3), STC(0x80000000),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal96[] = {
+ STC(0x7fb9d759), STC(0x7ee7aa4c), STC(0x7ee7aa4c), STC(0x7ba3751d),
+ STC(0x7d8a5f40), STC(0x7641af3d), STC(0x7ba3751d), STC(0x6ed9eba1),
+ STC(0x793501a9), STC(0x658c9a2d), STC(0x7641af3d), STC(0x5a82799a),
+ STC(0x72ccb9db), STC(0x4debe4fe), STC(0x6ed9eba1), STC(0x40000000),
+ STC(0x6a6d98a4), STC(0x30fbc54d), STC(0x658c9a2d), STC(0x2120fb83),
+ STC(0x603c496c), STC(0x10b5150f), STC(0x5a82799a), STC(0x00000000),
+ STC(0x54657194), STC(0xef4aeaf1), STC(0x4debe4fe), STC(0xdedf047d),
+ STC(0x471cece7), STC(0xcf043ab3), STC(0x40000000), STC(0xc0000000),
+ STC(0x389cea72), STC(0xb2141b02), STC(0x30fbc54d), STC(0xa57d8666),
+ STC(0x2924edac), STC(0x9a7365d3), STC(0x2120fb83), STC(0x9126145f),
+ STC(0x18f8b83c), STC(0x89be50c3), STC(0x10b5150f), STC(0x845c8ae3),
+ STC(0x085f2137), STC(0x811855b4), STC(0x00000000), STC(0x80000000),
+ STC(0xf7a0dec9), STC(0x811855b4), STC(0xef4aeaf1), STC(0x845c8ae3),
+ STC(0xe70747c4), STC(0x89be50c3), STC(0xdedf047d), STC(0x9126145f),
+ STC(0xd6db1254), STC(0x9a7365d3), STC(0xcf043ab3), STC(0xa57d8666),
+ STC(0xc763158e), STC(0xb2141b02),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag96[] = {
+ STC(0x085f2137), STC(0x10b5150f), STC(0x10b5150f), STC(0x2120fb83),
+ STC(0x18f8b83c), STC(0x30fbc54d), STC(0x2120fb83), STC(0x40000000),
+ STC(0x2924edac), STC(0x4debe4fe), STC(0x30fbc54d), STC(0x5a82799a),
+ STC(0x389cea72), STC(0x658c9a2d), STC(0x40000000), STC(0x6ed9eba1),
+ STC(0x471cece7), STC(0x7641af3d), STC(0x4debe4fe), STC(0x7ba3751d),
+ STC(0x54657194), STC(0x7ee7aa4c), STC(0x5a82799a), STC(0x7fffffff),
+ STC(0x603c496c), STC(0x7ee7aa4c), STC(0x658c9a2d), STC(0x7ba3751d),
+ STC(0x6a6d98a4), STC(0x7641af3d), STC(0x6ed9eba1), STC(0x6ed9eba1),
+ STC(0x72ccb9db), STC(0x658c9a2d), STC(0x7641af3d), STC(0x5a82799a),
+ STC(0x793501a9), STC(0x4debe4fe), STC(0x7ba3751d), STC(0x40000000),
+ STC(0x7d8a5f40), STC(0x30fbc54d), STC(0x7ee7aa4c), STC(0x2120fb83),
+ STC(0x7fb9d759), STC(0x10b5150f), STC(0x7fffffff), STC(0x00000000),
+ STC(0x7fb9d759), STC(0xef4aeaf1), STC(0x7ee7aa4c), STC(0xdedf047d),
+ STC(0x7d8a5f40), STC(0xcf043ab3), STC(0x7ba3751d), STC(0xc0000000),
+ STC(0x793501a9), STC(0xb2141b02), STC(0x7641af3d), STC(0xa57d8666),
+ STC(0x72ccb9db), STC(0x9a7365d3),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal384[] = {
+ STC(0x7ffb9d15), STC(0x7fee74a2), STC(0x7fd8878e), STC(0x7fb9d759),
+ STC(0x7f92661d), STC(0x7f62368f), STC(0x7f294bfd), STC(0x7ee7aa4c),
+ STC(0x7e9d55fc), STC(0x7e4a5426), STC(0x7deeaa7a), STC(0x7fee74a2),
+ STC(0x7fb9d759), STC(0x7f62368f), STC(0x7ee7aa4c), STC(0x7e4a5426),
+ STC(0x7d8a5f40), STC(0x7ca80038), STC(0x7ba3751d), STC(0x7a7d055b),
+ STC(0x793501a9), STC(0x77cbc3f2), STC(0x7fd8878e), STC(0x7f62368f),
+ STC(0x7e9d55fc), STC(0x7d8a5f40), STC(0x7c29fbee), STC(0x7a7d055b),
+ STC(0x78848414), STC(0x7641af3d), STC(0x73b5ebd1), STC(0x70e2cbc6),
+ STC(0x6dca0d14), STC(0x7fb9d759), STC(0x7ee7aa4c), STC(0x7d8a5f40),
+ STC(0x7ba3751d), STC(0x793501a9), STC(0x7641af3d), STC(0x72ccb9db),
+ STC(0x6ed9eba1), STC(0x6a6d98a4), STC(0x658c9a2d), STC(0x603c496c),
+ STC(0x7f92661d), STC(0x7e4a5426), STC(0x7c29fbee), STC(0x793501a9),
+ STC(0x757075ac), STC(0x70e2cbc6), STC(0x6b93d02e), STC(0x658c9a2d),
+ STC(0x5ed77c8a), STC(0x577ff3da), STC(0x4f9292dc), STC(0x7f62368f),
+ STC(0x7d8a5f40), STC(0x7a7d055b), STC(0x7641af3d), STC(0x70e2cbc6),
+ STC(0x6a6d98a4), STC(0x62f201ac), STC(0x5a82799a), STC(0x5133cc94),
+ STC(0x471cece7), STC(0x3c56ba70), STC(0x7f294bfd), STC(0x7ca80038),
+ STC(0x78848414), STC(0x72ccb9db), STC(0x6b93d02e), STC(0x62f201ac),
+ STC(0x590443a7), STC(0x4debe4fe), STC(0x41ce1e65), STC(0x34d3957e),
+ STC(0x2727d486), STC(0x7ee7aa4c), STC(0x7ba3751d), STC(0x7641af3d),
+ STC(0x6ed9eba1), STC(0x658c9a2d), STC(0x5a82799a), STC(0x4debe4fe),
+ STC(0x40000000), STC(0x30fbc54d), STC(0x2120fb83), STC(0x10b5150f),
+ STC(0x7e9d55fc), STC(0x7a7d055b), STC(0x73b5ebd1), STC(0x6a6d98a4),
+ STC(0x5ed77c8a), STC(0x5133cc94), STC(0x41ce1e65), STC(0x30fbc54d),
+ STC(0x1f19f97b), STC(0x0c8bd35e), STC(0xf9b82684), STC(0x7e4a5426),
+ STC(0x793501a9), STC(0x70e2cbc6), STC(0x658c9a2d), STC(0x577ff3da),
+ STC(0x471cece7), STC(0x34d3957e), STC(0x2120fb83), STC(0x0c8bd35e),
+ STC(0xf7a0dec9), STC(0xe2ef2a3e), STC(0x7deeaa7a), STC(0x77cbc3f2),
+ STC(0x6dca0d14), STC(0x603c496c), STC(0x4f9292dc), STC(0x3c56ba70),
+ STC(0x2727d486), STC(0x10b5150f), STC(0xf9b82684), STC(0xe2ef2a3e),
+ STC(0xcd1693f7), STC(0x7d8a5f40), STC(0x7641af3d), STC(0x6a6d98a4),
+ STC(0x5a82799a), STC(0x471cece7), STC(0x30fbc54d), STC(0x18f8b83c),
+ STC(0x00000000), STC(0xe70747c4), STC(0xcf043ab3), STC(0xb8e31319),
+ STC(0x7d1d7958), STC(0x74972f92), STC(0x66cf8120), STC(0x54657194),
+ STC(0x3e2d7eb1), STC(0x25280c5e), STC(0x0a75d60e), STC(0xef4aeaf1),
+ STC(0xd4e0cb15), STC(0xbc6845ce), STC(0xa6fbbc59), STC(0x7ca80038),
+ STC(0x72ccb9db), STC(0x62f201ac), STC(0x4debe4fe), STC(0x34d3957e),
+ STC(0x18f8b83c), STC(0xfbcfdc71), STC(0xdedf047d), STC(0xc3a94590),
+ STC(0xab9a8e6c), STC(0x97f4a3cd), STC(0x7c29fbee), STC(0x70e2cbc6),
+ STC(0x5ed77c8a), STC(0x471cece7), STC(0x2b1f34eb), STC(0x0c8bd35e),
+ STC(0xed37ef91), STC(0xcf043ab3), STC(0xb3c0200c), STC(0x9d0dfe54),
+ STC(0x8c4a142f), STC(0x7ba3751d), STC(0x6ed9eba1), STC(0x5a82799a),
+ STC(0x40000000), STC(0x2120fb83), STC(0x00000000), STC(0xdedf047d),
+ STC(0xc0000000), STC(0xa57d8666), STC(0x9126145f), STC(0x845c8ae3),
+ STC(0x7b1474fd), STC(0x6cb2a837), STC(0x55f5a4d2), STC(0x389cea72),
+ STC(0x16ea0646), STC(0xf3742ca2), STC(0xd0f53ce0), STC(0xb2141b02),
+ STC(0x99307ee0), STC(0x88343c0e), STC(0x806d99e3), STC(0x7a7d055b),
+ STC(0x6a6d98a4), STC(0x5133cc94), STC(0x30fbc54d), STC(0x0c8bd35e),
+ STC(0xe70747c4), STC(0xc3a94590), STC(0xa57d8666), STC(0x8f1d343a),
+ STC(0x8275a0c0), STC(0x809dc971), STC(0x79dd3098), STC(0x680b5c33),
+ STC(0x4c3fdff4), STC(0x2924edac), STC(0x02182427), STC(0xdad7f3a2),
+ STC(0xb727b9f7), STC(0x9a7365d3), STC(0x877b7bec), STC(0x80118b5e),
+ STC(0x84eb8b03), STC(0x793501a9), STC(0x658c9a2d), STC(0x471cece7),
+ STC(0x2120fb83), STC(0xf7a0dec9), STC(0xcf043ab3), STC(0xab9a8e6c),
+ STC(0x9126145f), STC(0x8275a0c0), STC(0x811855b4), STC(0x8d334625),
+ STC(0x78848414), STC(0x62f201ac), STC(0x41ce1e65), STC(0x18f8b83c),
+ STC(0xed37ef91), STC(0xc3a94590), STC(0xa1288376), STC(0x89be50c3),
+ STC(0x80277872), STC(0x8582faa5), STC(0x99307ee0), STC(0x77cbc3f2),
+ STC(0x603c496c), STC(0x3c56ba70), STC(0x10b5150f), STC(0xe2ef2a3e),
+ STC(0xb8e31319), STC(0x97f4a3cd), STC(0x845c8ae3), STC(0x809dc971),
+ STC(0x8d334625), STC(0xa8800c26), STC(0x770acdec), STC(0x5d6c2f99),
+ STC(0x36ba2014), STC(0x085f2137), STC(0xd8d82b7a), STC(0xaecc336c),
+ STC(0x901dcec4), STC(0x811855b4), STC(0x83d60412), STC(0x97f4a3cd),
+ STC(0xbaa34bf4), STC(0x7641af3d), STC(0x5a82799a), STC(0x30fbc54d),
+ STC(0x00000000), STC(0xcf043ab3), STC(0xa57d8666), STC(0x89be50c3),
+ STC(0x80000000), STC(0x89be50c3), STC(0xa57d8666), STC(0xcf043ab3),
+ STC(0x757075ac), STC(0x577ff3da), STC(0x2b1f34eb), STC(0xf7a0dec9),
+ STC(0xc5842c7e), STC(0x9d0dfe54), STC(0x84eb8b03), STC(0x811855b4),
+ STC(0x9235f2ec), STC(0xb5715eef), STC(0xe4fa4bf1), STC(0x74972f92),
+ STC(0x54657194), STC(0x25280c5e), STC(0xef4aeaf1), STC(0xbc6845ce),
+ STC(0x9592675c), STC(0x81b5abda), STC(0x845c8ae3), STC(0x9d0dfe54),
+ STC(0xc763158e), STC(0xfbcfdc71), STC(0x73b5ebd1), STC(0x5133cc94),
+ STC(0x1f19f97b), STC(0xe70747c4), STC(0xb3c0200c), STC(0x8f1d343a),
+ STC(0x80277872), STC(0x89be50c3), STC(0xaa0a5b2e), STC(0xdad7f3a2),
+ STC(0x12c8106f), STC(0x72ccb9db), STC(0x4debe4fe), STC(0x18f8b83c),
+ STC(0xdedf047d), STC(0xab9a8e6c), STC(0x89be50c3), STC(0x804628a7),
+ STC(0x9126145f), STC(0xb8e31319), STC(0xef4aeaf1), STC(0x2924edac),
+ STC(0x71dba9ab), STC(0x4a8ea111), STC(0x12c8106f), STC(0xd6db1254),
+ STC(0xa405847e), STC(0x8582faa5), STC(0x82115586), STC(0x9a7365d3),
+ STC(0xc945dfec), STC(0x0430238f), STC(0x3e2d7eb1), STC(0x70e2cbc6),
+ STC(0x471cece7), STC(0x0c8bd35e), STC(0xcf043ab3), STC(0x9d0dfe54),
+ STC(0x8275a0c0), STC(0x8582faa5), STC(0xa57d8666), STC(0xdad7f3a2),
+ STC(0x18f8b83c), STC(0x5133cc94), STC(0x6fe2313c), STC(0x4397ba32),
+ STC(0x0647d97c), STC(0xc763158e), STC(0x96bfea3d), STC(0x809dc971),
+ STC(0x8a8f8a54), STC(0xb2141b02), STC(0xed37ef91), STC(0x2d168792),
+ STC(0x619a7dce),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag384[] = {
+ STC(0x02182427), STC(0x0430238f), STC(0x0647d97c), STC(0x085f2137),
+ STC(0x0a75d60e), STC(0x0c8bd35e), STC(0x0ea0f48c), STC(0x10b5150f),
+ STC(0x12c8106f), STC(0x14d9c245), STC(0x16ea0646), STC(0x0430238f),
+ STC(0x085f2137), STC(0x0c8bd35e), STC(0x10b5150f), STC(0x14d9c245),
+ STC(0x18f8b83c), STC(0x1d10d5c2), STC(0x2120fb83), STC(0x25280c5e),
+ STC(0x2924edac), STC(0x2d168792), STC(0x0647d97c), STC(0x0c8bd35e),
+ STC(0x12c8106f), STC(0x18f8b83c), STC(0x1f19f97b), STC(0x25280c5e),
+ STC(0x2b1f34eb), STC(0x30fbc54d), STC(0x36ba2014), STC(0x3c56ba70),
+ STC(0x41ce1e65), STC(0x085f2137), STC(0x10b5150f), STC(0x18f8b83c),
+ STC(0x2120fb83), STC(0x2924edac), STC(0x30fbc54d), STC(0x389cea72),
+ STC(0x40000000), STC(0x471cece7), STC(0x4debe4fe), STC(0x54657194),
+ STC(0x0a75d60e), STC(0x14d9c245), STC(0x1f19f97b), STC(0x2924edac),
+ STC(0x32e96c09), STC(0x3c56ba70), STC(0x455cb40c), STC(0x4debe4fe),
+ STC(0x55f5a4d2), STC(0x5d6c2f99), STC(0x6442bd7e), STC(0x0c8bd35e),
+ STC(0x18f8b83c), STC(0x25280c5e), STC(0x30fbc54d), STC(0x3c56ba70),
+ STC(0x471cece7), STC(0x5133cc94), STC(0x5a82799a), STC(0x62f201ac),
+ STC(0x6a6d98a4), STC(0x70e2cbc6), STC(0x0ea0f48c), STC(0x1d10d5c2),
+ STC(0x2b1f34eb), STC(0x389cea72), STC(0x455cb40c), STC(0x5133cc94),
+ STC(0x5bfa7b82), STC(0x658c9a2d), STC(0x6dca0d14), STC(0x74972f92),
+ STC(0x79dd3098), STC(0x10b5150f), STC(0x2120fb83), STC(0x30fbc54d),
+ STC(0x40000000), STC(0x4debe4fe), STC(0x5a82799a), STC(0x658c9a2d),
+ STC(0x6ed9eba1), STC(0x7641af3d), STC(0x7ba3751d), STC(0x7ee7aa4c),
+ STC(0x12c8106f), STC(0x25280c5e), STC(0x36ba2014), STC(0x471cece7),
+ STC(0x55f5a4d2), STC(0x62f201ac), STC(0x6dca0d14), STC(0x7641af3d),
+ STC(0x7c29fbee), STC(0x7f62368f), STC(0x7fd8878e), STC(0x14d9c245),
+ STC(0x2924edac), STC(0x3c56ba70), STC(0x4debe4fe), STC(0x5d6c2f99),
+ STC(0x6a6d98a4), STC(0x74972f92), STC(0x7ba3751d), STC(0x7f62368f),
+ STC(0x7fb9d759), STC(0x7ca80038), STC(0x16ea0646), STC(0x2d168792),
+ STC(0x41ce1e65), STC(0x54657194), STC(0x6442bd7e), STC(0x70e2cbc6),
+ STC(0x79dd3098), STC(0x7ee7aa4c), STC(0x7fd8878e), STC(0x7ca80038),
+ STC(0x757075ac), STC(0x18f8b83c), STC(0x30fbc54d), STC(0x471cece7),
+ STC(0x5a82799a), STC(0x6a6d98a4), STC(0x7641af3d), STC(0x7d8a5f40),
+ STC(0x7fffffff), STC(0x7d8a5f40), STC(0x7641af3d), STC(0x6a6d98a4),
+ STC(0x1b05b40f), STC(0x34d3957e), STC(0x4c3fdff4), STC(0x603c496c),
+ STC(0x6fe2313c), STC(0x7a7d055b), STC(0x7f92661d), STC(0x7ee7aa4c),
+ STC(0x78848414), STC(0x6cb2a837), STC(0x5bfa7b82), STC(0x1d10d5c2),
+ STC(0x389cea72), STC(0x5133cc94), STC(0x658c9a2d), STC(0x74972f92),
+ STC(0x7d8a5f40), STC(0x7fee74a2), STC(0x7ba3751d), STC(0x70e2cbc6),
+ STC(0x603c496c), STC(0x4a8ea111), STC(0x1f19f97b), STC(0x3c56ba70),
+ STC(0x55f5a4d2), STC(0x6a6d98a4), STC(0x78848414), STC(0x7f62368f),
+ STC(0x7e9d55fc), STC(0x7641af3d), STC(0x66cf8120), STC(0x5133cc94),
+ STC(0x36ba2014), STC(0x2120fb83), STC(0x40000000), STC(0x5a82799a),
+ STC(0x6ed9eba1), STC(0x7ba3751d), STC(0x7fffffff), STC(0x7ba3751d),
+ STC(0x6ed9eba1), STC(0x5a82799a), STC(0x40000000), STC(0x2120fb83),
+ STC(0x2325b847), STC(0x4397ba32), STC(0x5ed77c8a), STC(0x72ccb9db),
+ STC(0x7deeaa7a), STC(0x7f62368f), STC(0x770acdec), STC(0x658c9a2d),
+ STC(0x4c3fdff4), STC(0x2d168792), STC(0x0a75d60e), STC(0x25280c5e),
+ STC(0x471cece7), STC(0x62f201ac), STC(0x7641af3d), STC(0x7f62368f),
+ STC(0x7d8a5f40), STC(0x70e2cbc6), STC(0x5a82799a), STC(0x3c56ba70),
+ STC(0x18f8b83c), STC(0xf3742ca2), STC(0x2727d486), STC(0x4a8ea111),
+ STC(0x66cf8120), STC(0x793501a9), STC(0x7ffb9d15), STC(0x7a7d055b),
+ STC(0x694015c3), STC(0x4debe4fe), STC(0x2b1f34eb), STC(0x0430238f),
+ STC(0xdcda47b9), STC(0x2924edac), STC(0x4debe4fe), STC(0x6a6d98a4),
+ STC(0x7ba3751d), STC(0x7fb9d759), STC(0x7641af3d), STC(0x603c496c),
+ STC(0x40000000), STC(0x18f8b83c), STC(0xef4aeaf1), STC(0xc763158e),
+ STC(0x2b1f34eb), STC(0x5133cc94), STC(0x6dca0d14), STC(0x7d8a5f40),
+ STC(0x7e9d55fc), STC(0x70e2cbc6), STC(0x55f5a4d2), STC(0x30fbc54d),
+ STC(0x0647d97c), STC(0xdad7f3a2), STC(0xb3c0200c), STC(0x2d168792),
+ STC(0x54657194), STC(0x70e2cbc6), STC(0x7ee7aa4c), STC(0x7ca80038),
+ STC(0x6a6d98a4), STC(0x4a8ea111), STC(0x2120fb83), STC(0xf3742ca2),
+ STC(0xc763158e), STC(0xa293d067), STC(0x2f0ac320), STC(0x577ff3da),
+ STC(0x73b5ebd1), STC(0x7fb9d759), STC(0x79dd3098), STC(0x62f201ac),
+ STC(0x3e2d7eb1), STC(0x10b5150f), STC(0xe0e60685), STC(0xb5715eef),
+ STC(0x946c2fd2), STC(0x30fbc54d), STC(0x5a82799a), STC(0x7641af3d),
+ STC(0x7fffffff), STC(0x7641af3d), STC(0x5a82799a), STC(0x30fbc54d),
+ STC(0x00000000), STC(0xcf043ab3), STC(0xa57d8666), STC(0x89be50c3),
+ STC(0x32e96c09), STC(0x5d6c2f99), STC(0x78848414), STC(0x7fb9d759),
+ STC(0x71dba9ab), STC(0x5133cc94), STC(0x2325b847), STC(0xef4aeaf1),
+ STC(0xbe31e19b), STC(0x97f4a3cd), STC(0x82e286a8), STC(0x34d3957e),
+ STC(0x603c496c), STC(0x7a7d055b), STC(0x7ee7aa4c), STC(0x6cb2a837),
+ STC(0x471cece7), STC(0x14d9c245), STC(0xdedf047d), STC(0xaecc336c),
+ STC(0x8d334625), STC(0x80118b5e), STC(0x36ba2014), STC(0x62f201ac),
+ STC(0x7c29fbee), STC(0x7d8a5f40), STC(0x66cf8120), STC(0x3c56ba70),
+ STC(0x0647d97c), STC(0xcf043ab3), STC(0xa1288376), STC(0x8582faa5),
+ STC(0x8162aa04), STC(0x389cea72), STC(0x658c9a2d), STC(0x7d8a5f40),
+ STC(0x7ba3751d), STC(0x603c496c), STC(0x30fbc54d), STC(0xf7a0dec9),
+ STC(0xc0000000), STC(0x9592675c), STC(0x811855b4), STC(0x86cafe57),
+ STC(0x3a7bd382), STC(0x680b5c33), STC(0x7e9d55fc), STC(0x793501a9),
+ STC(0x590443a7), STC(0x25280c5e), STC(0xe915f9ba), STC(0xb2141b02),
+ STC(0x8c4a142f), STC(0x80118b5e), STC(0x901dcec4), STC(0x3c56ba70),
+ STC(0x6a6d98a4), STC(0x7f62368f), STC(0x7641af3d), STC(0x5133cc94),
+ STC(0x18f8b83c), STC(0xdad7f3a2), STC(0xa57d8666), STC(0x8582faa5),
+ STC(0x8275a0c0), STC(0x9d0dfe54), STC(0x3e2d7eb1), STC(0x6cb2a837),
+ STC(0x7fd8878e), STC(0x72ccb9db), STC(0x48d84609), STC(0x0c8bd35e),
+ STC(0xcd1693f7), STC(0x9a7365d3), STC(0x8162aa04), STC(0x88343c0e),
+ STC(0xad308a71),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal60[] = {
+ STC(0x7f4c7e54), STC(0x7d33f0ca), STC(0x79bc384d), STC(0x7d33f0ca),
+ STC(0x74ef0ebc), STC(0x678dde6e), STC(0x79bc384d), STC(0x678dde6e),
+ STC(0x4b3c8c12), STC(0x74ef0ebc), STC(0x55a6125c), STC(0x278dde6e),
+ STC(0x6ed9eba1), STC(0x40000000), STC(0x00000000), STC(0x678dde6e),
+ STC(0x278dde6e), STC(0xd8722192), STC(0x5f1f5ea1), STC(0x0d61304e),
+ STC(0xb4c373ee), STC(0x55a6125c), STC(0xf29ecfb2), STC(0x98722192),
+ STC(0x4b3c8c12), STC(0xd8722192), STC(0x8643c7b3), STC(0x40000000),
+ STC(0xc0000000), STC(0x80000000), STC(0x340ff242), STC(0xaa59eda4),
+ STC(0x8643c7b3), STC(0x278dde6e), STC(0x98722192), STC(0x98722192),
+ STC(0x1a9cd9ac), STC(0x8b10f144), STC(0xb4c373ee), STC(0x0d61304e),
+ STC(0x82cc0f36), STC(0xd8722192),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag60[] = {
+ STC(0x0d61304e), STC(0x1a9cd9ac), STC(0x278dde6e), STC(0x1a9cd9ac),
+ STC(0x340ff242), STC(0x4b3c8c12), STC(0x278dde6e), STC(0x4b3c8c12),
+ STC(0x678dde6e), STC(0x340ff242), STC(0x5f1f5ea1), STC(0x79bc384d),
+ STC(0x40000000), STC(0x6ed9eba1), STC(0x7fffffff), STC(0x4b3c8c12),
+ STC(0x79bc384d), STC(0x79bc384d), STC(0x55a6125c), STC(0x7f4c7e54),
+ STC(0x678dde6e), STC(0x5f1f5ea1), STC(0x7f4c7e54), STC(0x4b3c8c12),
+ STC(0x678dde6e), STC(0x79bc384d), STC(0x278dde6e), STC(0x6ed9eba1),
+ STC(0x6ed9eba1), STC(0x00000000), STC(0x74ef0ebc), STC(0x5f1f5ea1),
+ STC(0xd8722192), STC(0x79bc384d), STC(0x4b3c8c12), STC(0xb4c373ee),
+ STC(0x7d33f0ca), STC(0x340ff242), STC(0x98722192), STC(0x7f4c7e54),
+ STC(0x1a9cd9ac), STC(0x8643c7b3),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal120[] = {
+ STC(0x7fd317b4), STC(0x7f4c7e54), STC(0x7e6c9251), STC(0x7d33f0ca),
+ STC(0x7ba3751d), STC(0x79bc384d), STC(0x777f903c), STC(0x7f4c7e54),
+ STC(0x7d33f0ca), STC(0x79bc384d), STC(0x74ef0ebc), STC(0x6ed9eba1),
+ STC(0x678dde6e), STC(0x5f1f5ea1), STC(0x7e6c9251), STC(0x79bc384d),
+ STC(0x720c8075), STC(0x678dde6e), STC(0x5a82799a), STC(0x4b3c8c12),
+ STC(0x3a1c5c57), STC(0x7d33f0ca), STC(0x74ef0ebc), STC(0x678dde6e),
+ STC(0x55a6125c), STC(0x40000000), STC(0x278dde6e), STC(0x0d61304e),
+ STC(0x7ba3751d), STC(0x6ed9eba1), STC(0x5a82799a), STC(0x40000000),
+ STC(0x2120fb83), STC(0x00000000), STC(0xdedf047d), STC(0x79bc384d),
+ STC(0x678dde6e), STC(0x4b3c8c12), STC(0x278dde6e), STC(0x00000000),
+ STC(0xd8722192), STC(0xb4c373ee), STC(0x777f903c), STC(0x5f1f5ea1),
+ STC(0x3a1c5c57), STC(0x0d61304e), STC(0xdedf047d), STC(0xb4c373ee),
+ STC(0x94a6715d), STC(0x74ef0ebc), STC(0x55a6125c), STC(0x278dde6e),
+ STC(0xf29ecfb2), STC(0xc0000000), STC(0x98722192), STC(0x82cc0f36),
+ STC(0x720c8075), STC(0x4b3c8c12), STC(0x14060b68), STC(0xd8722192),
+ STC(0xa57d8666), STC(0x8643c7b3), STC(0x81936daf), STC(0x6ed9eba1),
+ STC(0x40000000), STC(0x00000000), STC(0xc0000000), STC(0x9126145f),
+ STC(0x80000000), STC(0x9126145f), STC(0x6b598ea3), STC(0x340ff242),
+ STC(0xebf9f498), STC(0xaa59eda4), STC(0x845c8ae3), STC(0x8643c7b3),
+ STC(0xaf726def), STC(0x678dde6e), STC(0x278dde6e), STC(0xd8722192),
+ STC(0x98722192), STC(0x80000000), STC(0x98722192), STC(0xd8722192),
+ STC(0x637984d4), STC(0x1a9cd9ac), STC(0xc5e3a3a9), STC(0x8b10f144),
+ STC(0x845c8ae3), STC(0xb4c373ee), STC(0x06b2f1d2), STC(0x5f1f5ea1),
+ STC(0x0d61304e), STC(0xb4c373ee), STC(0x82cc0f36), STC(0x9126145f),
+ STC(0xd8722192), STC(0x340ff242),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag120[] = {
+ STC(0x06b2f1d2), STC(0x0d61304e), STC(0x14060b68), STC(0x1a9cd9ac),
+ STC(0x2120fb83), STC(0x278dde6e), STC(0x2ddf0040), STC(0x0d61304e),
+ STC(0x1a9cd9ac), STC(0x278dde6e), STC(0x340ff242), STC(0x40000000),
+ STC(0x4b3c8c12), STC(0x55a6125c), STC(0x14060b68), STC(0x278dde6e),
+ STC(0x3a1c5c57), STC(0x4b3c8c12), STC(0x5a82799a), STC(0x678dde6e),
+ STC(0x720c8075), STC(0x1a9cd9ac), STC(0x340ff242), STC(0x4b3c8c12),
+ STC(0x5f1f5ea1), STC(0x6ed9eba1), STC(0x79bc384d), STC(0x7f4c7e54),
+ STC(0x2120fb83), STC(0x40000000), STC(0x5a82799a), STC(0x6ed9eba1),
+ STC(0x7ba3751d), STC(0x7fffffff), STC(0x7ba3751d), STC(0x278dde6e),
+ STC(0x4b3c8c12), STC(0x678dde6e), STC(0x79bc384d), STC(0x7fffffff),
+ STC(0x79bc384d), STC(0x678dde6e), STC(0x2ddf0040), STC(0x55a6125c),
+ STC(0x720c8075), STC(0x7f4c7e54), STC(0x7ba3751d), STC(0x678dde6e),
+ STC(0x45b6bb5e), STC(0x340ff242), STC(0x5f1f5ea1), STC(0x79bc384d),
+ STC(0x7f4c7e54), STC(0x6ed9eba1), STC(0x4b3c8c12), STC(0x1a9cd9ac),
+ STC(0x3a1c5c57), STC(0x678dde6e), STC(0x7e6c9251), STC(0x79bc384d),
+ STC(0x5a82799a), STC(0x278dde6e), STC(0xebf9f498), STC(0x40000000),
+ STC(0x6ed9eba1), STC(0x7fffffff), STC(0x6ed9eba1), STC(0x40000000),
+ STC(0x00000000), STC(0xc0000000), STC(0x45b6bb5e), STC(0x74ef0ebc),
+ STC(0x7e6c9251), STC(0x5f1f5ea1), STC(0x2120fb83), STC(0xd8722192),
+ STC(0x9c867b2c), STC(0x4b3c8c12), STC(0x79bc384d), STC(0x79bc384d),
+ STC(0x4b3c8c12), STC(0x00000000), STC(0xb4c373ee), STC(0x8643c7b3),
+ STC(0x508d9211), STC(0x7d33f0ca), STC(0x720c8075), STC(0x340ff242),
+ STC(0xdedf047d), STC(0x98722192), STC(0x802ce84c), STC(0x55a6125c),
+ STC(0x7f4c7e54), STC(0x678dde6e), STC(0x1a9cd9ac), STC(0xc0000000),
+ STC(0x8643c7b3), STC(0x8b10f144),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal192[] = {
+ STC(0x7fee74a2), STC(0x7fb9d759), STC(0x7f62368f), STC(0x7ee7aa4c),
+ STC(0x7e4a5426), STC(0x7d8a5f40), STC(0x7ca80038), STC(0x7ba3751d),
+ STC(0x7a7d055b), STC(0x793501a9), STC(0x77cbc3f2), STC(0x7641af3d),
+ STC(0x74972f92), STC(0x72ccb9db), STC(0x70e2cbc6), STC(0x7fb9d759),
+ STC(0x7ee7aa4c), STC(0x7d8a5f40), STC(0x7ba3751d), STC(0x793501a9),
+ STC(0x7641af3d), STC(0x72ccb9db), STC(0x6ed9eba1), STC(0x6a6d98a4),
+ STC(0x658c9a2d), STC(0x603c496c), STC(0x5a82799a), STC(0x54657194),
+ STC(0x4debe4fe), STC(0x471cece7), STC(0x7f62368f), STC(0x7d8a5f40),
+ STC(0x7a7d055b), STC(0x7641af3d), STC(0x70e2cbc6), STC(0x6a6d98a4),
+ STC(0x62f201ac), STC(0x5a82799a), STC(0x5133cc94), STC(0x471cece7),
+ STC(0x3c56ba70), STC(0x30fbc54d), STC(0x25280c5e), STC(0x18f8b83c),
+ STC(0x0c8bd35e), STC(0x7ee7aa4c), STC(0x7ba3751d), STC(0x7641af3d),
+ STC(0x6ed9eba1), STC(0x658c9a2d), STC(0x5a82799a), STC(0x4debe4fe),
+ STC(0x40000000), STC(0x30fbc54d), STC(0x2120fb83), STC(0x10b5150f),
+ STC(0x00000000), STC(0xef4aeaf1), STC(0xdedf047d), STC(0xcf043ab3),
+ STC(0x7e4a5426), STC(0x793501a9), STC(0x70e2cbc6), STC(0x658c9a2d),
+ STC(0x577ff3da), STC(0x471cece7), STC(0x34d3957e), STC(0x2120fb83),
+ STC(0x0c8bd35e), STC(0xf7a0dec9), STC(0xe2ef2a3e), STC(0xcf043ab3),
+ STC(0xbc6845ce), STC(0xab9a8e6c), STC(0x9d0dfe54), STC(0x7d8a5f40),
+ STC(0x7641af3d), STC(0x6a6d98a4), STC(0x5a82799a), STC(0x471cece7),
+ STC(0x30fbc54d), STC(0x18f8b83c), STC(0x00000000), STC(0xe70747c4),
+ STC(0xcf043ab3), STC(0xb8e31319), STC(0xa57d8666), STC(0x9592675c),
+ STC(0x89be50c3), STC(0x8275a0c0), STC(0x7ca80038), STC(0x72ccb9db),
+ STC(0x62f201ac), STC(0x4debe4fe), STC(0x34d3957e), STC(0x18f8b83c),
+ STC(0xfbcfdc71), STC(0xdedf047d), STC(0xc3a94590), STC(0xab9a8e6c),
+ STC(0x97f4a3cd), STC(0x89be50c3), STC(0x81b5abda), STC(0x804628a7),
+ STC(0x8582faa5), STC(0x7ba3751d), STC(0x6ed9eba1), STC(0x5a82799a),
+ STC(0x40000000), STC(0x2120fb83), STC(0x00000000), STC(0xdedf047d),
+ STC(0xc0000000), STC(0xa57d8666), STC(0x9126145f), STC(0x845c8ae3),
+ STC(0x80000000), STC(0x845c8ae3), STC(0x9126145f), STC(0xa57d8666),
+ STC(0x7a7d055b), STC(0x6a6d98a4), STC(0x5133cc94), STC(0x30fbc54d),
+ STC(0x0c8bd35e), STC(0xe70747c4), STC(0xc3a94590), STC(0xa57d8666),
+ STC(0x8f1d343a), STC(0x8275a0c0), STC(0x809dc971), STC(0x89be50c3),
+ STC(0x9d0dfe54), STC(0xb8e31319), STC(0xdad7f3a2), STC(0x793501a9),
+ STC(0x658c9a2d), STC(0x471cece7), STC(0x2120fb83), STC(0xf7a0dec9),
+ STC(0xcf043ab3), STC(0xab9a8e6c), STC(0x9126145f), STC(0x8275a0c0),
+ STC(0x811855b4), STC(0x8d334625), STC(0xa57d8666), STC(0xc763158e),
+ STC(0xef4aeaf1), STC(0x18f8b83c), STC(0x77cbc3f2), STC(0x603c496c),
+ STC(0x3c56ba70), STC(0x10b5150f), STC(0xe2ef2a3e), STC(0xb8e31319),
+ STC(0x97f4a3cd), STC(0x845c8ae3), STC(0x809dc971), STC(0x8d334625),
+ STC(0xa8800c26), STC(0xcf043ab3), STC(0xfbcfdc71), STC(0x2924edac),
+ STC(0x5133cc94),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag192[] = {
+ STC(0x0430238f), STC(0x085f2137), STC(0x0c8bd35e), STC(0x10b5150f),
+ STC(0x14d9c245), STC(0x18f8b83c), STC(0x1d10d5c2), STC(0x2120fb83),
+ STC(0x25280c5e), STC(0x2924edac), STC(0x2d168792), STC(0x30fbc54d),
+ STC(0x34d3957e), STC(0x389cea72), STC(0x3c56ba70), STC(0x085f2137),
+ STC(0x10b5150f), STC(0x18f8b83c), STC(0x2120fb83), STC(0x2924edac),
+ STC(0x30fbc54d), STC(0x389cea72), STC(0x40000000), STC(0x471cece7),
+ STC(0x4debe4fe), STC(0x54657194), STC(0x5a82799a), STC(0x603c496c),
+ STC(0x658c9a2d), STC(0x6a6d98a4), STC(0x0c8bd35e), STC(0x18f8b83c),
+ STC(0x25280c5e), STC(0x30fbc54d), STC(0x3c56ba70), STC(0x471cece7),
+ STC(0x5133cc94), STC(0x5a82799a), STC(0x62f201ac), STC(0x6a6d98a4),
+ STC(0x70e2cbc6), STC(0x7641af3d), STC(0x7a7d055b), STC(0x7d8a5f40),
+ STC(0x7f62368f), STC(0x10b5150f), STC(0x2120fb83), STC(0x30fbc54d),
+ STC(0x40000000), STC(0x4debe4fe), STC(0x5a82799a), STC(0x658c9a2d),
+ STC(0x6ed9eba1), STC(0x7641af3d), STC(0x7ba3751d), STC(0x7ee7aa4c),
+ STC(0x7fffffff), STC(0x7ee7aa4c), STC(0x7ba3751d), STC(0x7641af3d),
+ STC(0x14d9c245), STC(0x2924edac), STC(0x3c56ba70), STC(0x4debe4fe),
+ STC(0x5d6c2f99), STC(0x6a6d98a4), STC(0x74972f92), STC(0x7ba3751d),
+ STC(0x7f62368f), STC(0x7fb9d759), STC(0x7ca80038), STC(0x7641af3d),
+ STC(0x6cb2a837), STC(0x603c496c), STC(0x5133cc94), STC(0x18f8b83c),
+ STC(0x30fbc54d), STC(0x471cece7), STC(0x5a82799a), STC(0x6a6d98a4),
+ STC(0x7641af3d), STC(0x7d8a5f40), STC(0x7fffffff), STC(0x7d8a5f40),
+ STC(0x7641af3d), STC(0x6a6d98a4), STC(0x5a82799a), STC(0x471cece7),
+ STC(0x30fbc54d), STC(0x18f8b83c), STC(0x1d10d5c2), STC(0x389cea72),
+ STC(0x5133cc94), STC(0x658c9a2d), STC(0x74972f92), STC(0x7d8a5f40),
+ STC(0x7fee74a2), STC(0x7ba3751d), STC(0x70e2cbc6), STC(0x603c496c),
+ STC(0x4a8ea111), STC(0x30fbc54d), STC(0x14d9c245), STC(0xf7a0dec9),
+ STC(0xdad7f3a2), STC(0x2120fb83), STC(0x40000000), STC(0x5a82799a),
+ STC(0x6ed9eba1), STC(0x7ba3751d), STC(0x7fffffff), STC(0x7ba3751d),
+ STC(0x6ed9eba1), STC(0x5a82799a), STC(0x40000000), STC(0x2120fb83),
+ STC(0x00000000), STC(0xdedf047d), STC(0xc0000000), STC(0xa57d8666),
+ STC(0x25280c5e), STC(0x471cece7), STC(0x62f201ac), STC(0x7641af3d),
+ STC(0x7f62368f), STC(0x7d8a5f40), STC(0x70e2cbc6), STC(0x5a82799a),
+ STC(0x3c56ba70), STC(0x18f8b83c), STC(0xf3742ca2), STC(0xcf043ab3),
+ STC(0xaecc336c), STC(0x9592675c), STC(0x8582faa5), STC(0x2924edac),
+ STC(0x4debe4fe), STC(0x6a6d98a4), STC(0x7ba3751d), STC(0x7fb9d759),
+ STC(0x7641af3d), STC(0x603c496c), STC(0x40000000), STC(0x18f8b83c),
+ STC(0xef4aeaf1), STC(0xc763158e), STC(0xa57d8666), STC(0x8d334625),
+ STC(0x811855b4), STC(0x8275a0c0), STC(0x2d168792), STC(0x54657194),
+ STC(0x70e2cbc6), STC(0x7ee7aa4c), STC(0x7ca80038), STC(0x6a6d98a4),
+ STC(0x4a8ea111), STC(0x2120fb83), STC(0xf3742ca2), STC(0xc763158e),
+ STC(0xa293d067), STC(0x89be50c3), STC(0x80118b5e), STC(0x86cafe57),
+ STC(0x9d0dfe54),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal240[] = {
+ STC(0x7ff4c56f), STC(0x7fd317b4), STC(0x7f9afcb9), STC(0x7f4c7e54),
+ STC(0x7ee7aa4c), STC(0x7e6c9251), STC(0x7ddb4bfc), STC(0x7d33f0ca),
+ STC(0x7c769e18), STC(0x7ba3751d), STC(0x7aba9ae6), STC(0x79bc384d),
+ STC(0x78a879f4), STC(0x777f903c), STC(0x7641af3d), STC(0x7fd317b4),
+ STC(0x7f4c7e54), STC(0x7e6c9251), STC(0x7d33f0ca), STC(0x7ba3751d),
+ STC(0x79bc384d), STC(0x777f903c), STC(0x74ef0ebc), STC(0x720c8075),
+ STC(0x6ed9eba1), STC(0x6b598ea3), STC(0x678dde6e), STC(0x637984d4),
+ STC(0x5f1f5ea1), STC(0x5a82799a), STC(0x7f9afcb9), STC(0x7e6c9251),
+ STC(0x7c769e18), STC(0x79bc384d), STC(0x7641af3d), STC(0x720c8075),
+ STC(0x6d23501b), STC(0x678dde6e), STC(0x6154fb91), STC(0x5a82799a),
+ STC(0x53211d18), STC(0x4b3c8c12), STC(0x42e13ba4), STC(0x3a1c5c57),
+ STC(0x30fbc54d), STC(0x7f4c7e54), STC(0x7d33f0ca), STC(0x79bc384d),
+ STC(0x74ef0ebc), STC(0x6ed9eba1), STC(0x678dde6e), STC(0x5f1f5ea1),
+ STC(0x55a6125c), STC(0x4b3c8c12), STC(0x40000000), STC(0x340ff242),
+ STC(0x278dde6e), STC(0x1a9cd9ac), STC(0x0d61304e), STC(0x00000000),
+ STC(0x7ee7aa4c), STC(0x7ba3751d), STC(0x7641af3d), STC(0x6ed9eba1),
+ STC(0x658c9a2d), STC(0x5a82799a), STC(0x4debe4fe), STC(0x40000000),
+ STC(0x30fbc54d), STC(0x2120fb83), STC(0x10b5150f), STC(0x00000000),
+ STC(0xef4aeaf1), STC(0xdedf047d), STC(0xcf043ab3), STC(0x7e6c9251),
+ STC(0x79bc384d), STC(0x720c8075), STC(0x678dde6e), STC(0x5a82799a),
+ STC(0x4b3c8c12), STC(0x3a1c5c57), STC(0x278dde6e), STC(0x14060b68),
+ STC(0x00000000), STC(0xebf9f498), STC(0xd8722192), STC(0xc5e3a3a9),
+ STC(0xb4c373ee), STC(0xa57d8666), STC(0x7ddb4bfc), STC(0x777f903c),
+ STC(0x6d23501b), STC(0x5f1f5ea1), STC(0x4debe4fe), STC(0x3a1c5c57),
+ STC(0x245a9d65), STC(0x0d61304e), STC(0xf5f50d67), STC(0xdedf047d),
+ STC(0xc8e5032b), STC(0xb4c373ee), STC(0xa326eec0), STC(0x94a6715d),
+ STC(0x89be50c3), STC(0x7d33f0ca), STC(0x74ef0ebc), STC(0x678dde6e),
+ STC(0x55a6125c), STC(0x40000000), STC(0x278dde6e), STC(0x0d61304e),
+ STC(0xf29ecfb2), STC(0xd8722192), STC(0xc0000000), STC(0xaa59eda4),
+ STC(0x98722192), STC(0x8b10f144), STC(0x82cc0f36), STC(0x80000000),
+ STC(0x7c769e18), STC(0x720c8075), STC(0x6154fb91), STC(0x4b3c8c12),
+ STC(0x30fbc54d), STC(0x14060b68), STC(0xf5f50d67), STC(0xd8722192),
+ STC(0xbd1ec45c), STC(0xa57d8666), STC(0x92dcafe5), STC(0x8643c7b3),
+ STC(0x80650347), STC(0x81936daf), STC(0x89be50c3), STC(0x7ba3751d),
+ STC(0x6ed9eba1), STC(0x5a82799a), STC(0x40000000), STC(0x2120fb83),
+ STC(0x00000000), STC(0xdedf047d), STC(0xc0000000), STC(0xa57d8666),
+ STC(0x9126145f), STC(0x845c8ae3), STC(0x80000000), STC(0x845c8ae3),
+ STC(0x9126145f), STC(0xa57d8666), STC(0x7aba9ae6), STC(0x6b598ea3),
+ STC(0x53211d18), STC(0x340ff242), STC(0x10b5150f), STC(0xebf9f498),
+ STC(0xc8e5032b), STC(0xaa59eda4), STC(0x92dcafe5), STC(0x845c8ae3),
+ STC(0x800b3a91), STC(0x8643c7b3), STC(0x96830876), STC(0xaf726def),
+ STC(0xcf043ab3), STC(0x79bc384d), STC(0x678dde6e), STC(0x4b3c8c12),
+ STC(0x278dde6e), STC(0x00000000), STC(0xd8722192), STC(0xb4c373ee),
+ STC(0x98722192), STC(0x8643c7b3), STC(0x80000000), STC(0x8643c7b3),
+ STC(0x98722192), STC(0xb4c373ee), STC(0xd8722192), STC(0x00000000),
+ STC(0x78a879f4), STC(0x637984d4), STC(0x42e13ba4), STC(0x1a9cd9ac),
+ STC(0xef4aeaf1), STC(0xc5e3a3a9), STC(0xa326eec0), STC(0x8b10f144),
+ STC(0x80650347), STC(0x845c8ae3), STC(0x96830876), STC(0xb4c373ee),
+ STC(0xdba5629b), STC(0x06b2f1d2), STC(0x30fbc54d), STC(0x777f903c),
+ STC(0x5f1f5ea1), STC(0x3a1c5c57), STC(0x0d61304e), STC(0xdedf047d),
+ STC(0xb4c373ee), STC(0x94a6715d), STC(0x82cc0f36), STC(0x81936daf),
+ STC(0x9126145f), STC(0xaf726def), STC(0xd8722192), STC(0x06b2f1d2),
+ STC(0x340ff242), STC(0x5a82799a),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag240[] = {
+ STC(0x0359c428), STC(0x06b2f1d2), STC(0x0a0af299), STC(0x0d61304e),
+ STC(0x10b5150f), STC(0x14060b68), STC(0x17537e63), STC(0x1a9cd9ac),
+ STC(0x1de189a6), STC(0x2120fb83), STC(0x245a9d65), STC(0x278dde6e),
+ STC(0x2aba2ee4), STC(0x2ddf0040), STC(0x30fbc54d), STC(0x06b2f1d2),
+ STC(0x0d61304e), STC(0x14060b68), STC(0x1a9cd9ac), STC(0x2120fb83),
+ STC(0x278dde6e), STC(0x2ddf0040), STC(0x340ff242), STC(0x3a1c5c57),
+ STC(0x40000000), STC(0x45b6bb5e), STC(0x4b3c8c12), STC(0x508d9211),
+ STC(0x55a6125c), STC(0x5a82799a), STC(0x0a0af299), STC(0x14060b68),
+ STC(0x1de189a6), STC(0x278dde6e), STC(0x30fbc54d), STC(0x3a1c5c57),
+ STC(0x42e13ba4), STC(0x4b3c8c12), STC(0x53211d18), STC(0x5a82799a),
+ STC(0x6154fb91), STC(0x678dde6e), STC(0x6d23501b), STC(0x720c8075),
+ STC(0x7641af3d), STC(0x0d61304e), STC(0x1a9cd9ac), STC(0x278dde6e),
+ STC(0x340ff242), STC(0x40000000), STC(0x4b3c8c12), STC(0x55a6125c),
+ STC(0x5f1f5ea1), STC(0x678dde6e), STC(0x6ed9eba1), STC(0x74ef0ebc),
+ STC(0x79bc384d), STC(0x7d33f0ca), STC(0x7f4c7e54), STC(0x7fffffff),
+ STC(0x10b5150f), STC(0x2120fb83), STC(0x30fbc54d), STC(0x40000000),
+ STC(0x4debe4fe), STC(0x5a82799a), STC(0x658c9a2d), STC(0x6ed9eba1),
+ STC(0x7641af3d), STC(0x7ba3751d), STC(0x7ee7aa4c), STC(0x7fffffff),
+ STC(0x7ee7aa4c), STC(0x7ba3751d), STC(0x7641af3d), STC(0x14060b68),
+ STC(0x278dde6e), STC(0x3a1c5c57), STC(0x4b3c8c12), STC(0x5a82799a),
+ STC(0x678dde6e), STC(0x720c8075), STC(0x79bc384d), STC(0x7e6c9251),
+ STC(0x7fffffff), STC(0x7e6c9251), STC(0x79bc384d), STC(0x720c8075),
+ STC(0x678dde6e), STC(0x5a82799a), STC(0x17537e63), STC(0x2ddf0040),
+ STC(0x42e13ba4), STC(0x55a6125c), STC(0x658c9a2d), STC(0x720c8075),
+ STC(0x7aba9ae6), STC(0x7f4c7e54), STC(0x7f9afcb9), STC(0x7ba3751d),
+ STC(0x7387ea23), STC(0x678dde6e), STC(0x581c00b3), STC(0x45b6bb5e),
+ STC(0x30fbc54d), STC(0x1a9cd9ac), STC(0x340ff242), STC(0x4b3c8c12),
+ STC(0x5f1f5ea1), STC(0x6ed9eba1), STC(0x79bc384d), STC(0x7f4c7e54),
+ STC(0x7f4c7e54), STC(0x79bc384d), STC(0x6ed9eba1), STC(0x5f1f5ea1),
+ STC(0x4b3c8c12), STC(0x340ff242), STC(0x1a9cd9ac), STC(0x00000000),
+ STC(0x1de189a6), STC(0x3a1c5c57), STC(0x53211d18), STC(0x678dde6e),
+ STC(0x7641af3d), STC(0x7e6c9251), STC(0x7f9afcb9), STC(0x79bc384d),
+ STC(0x6d23501b), STC(0x5a82799a), STC(0x42e13ba4), STC(0x278dde6e),
+ STC(0x0a0af299), STC(0xebf9f498), STC(0xcf043ab3), STC(0x2120fb83),
+ STC(0x40000000), STC(0x5a82799a), STC(0x6ed9eba1), STC(0x7ba3751d),
+ STC(0x7fffffff), STC(0x7ba3751d), STC(0x6ed9eba1), STC(0x5a82799a),
+ STC(0x40000000), STC(0x2120fb83), STC(0x00000000), STC(0xdedf047d),
+ STC(0xc0000000), STC(0xa57d8666), STC(0x245a9d65), STC(0x45b6bb5e),
+ STC(0x6154fb91), STC(0x74ef0ebc), STC(0x7ee7aa4c), STC(0x7e6c9251),
+ STC(0x7387ea23), STC(0x5f1f5ea1), STC(0x42e13ba4), STC(0x2120fb83),
+ STC(0xfca63bd8), STC(0xd8722192), STC(0xb780001c), STC(0x9c867b2c),
+ STC(0x89be50c3), STC(0x278dde6e), STC(0x4b3c8c12), STC(0x678dde6e),
+ STC(0x79bc384d), STC(0x7fffffff), STC(0x79bc384d), STC(0x678dde6e),
+ STC(0x4b3c8c12), STC(0x278dde6e), STC(0x00000000), STC(0xd8722192),
+ STC(0xb4c373ee), STC(0x98722192), STC(0x8643c7b3), STC(0x80000000),
+ STC(0x2aba2ee4), STC(0x508d9211), STC(0x6d23501b), STC(0x7d33f0ca),
+ STC(0x7ee7aa4c), STC(0x720c8075), STC(0x581c00b3), STC(0x340ff242),
+ STC(0x0a0af299), STC(0xdedf047d), STC(0xb780001c), STC(0x98722192),
+ STC(0x8545651a), STC(0x802ce84c), STC(0x89be50c3), STC(0x2ddf0040),
+ STC(0x55a6125c), STC(0x720c8075), STC(0x7f4c7e54), STC(0x7ba3751d),
+ STC(0x678dde6e), STC(0x45b6bb5e), STC(0x1a9cd9ac), STC(0xebf9f498),
+ STC(0xc0000000), STC(0x9c867b2c), STC(0x8643c7b3), STC(0x802ce84c),
+ STC(0x8b10f144), STC(0xa57d8666),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal480[] = {
+ STC(0x7ffd3154), STC(0x7ff4c56f), STC(0x7fe6bcb0), STC(0x7fd317b4),
+ STC(0x7fb9d759), STC(0x7f9afcb9), STC(0x7f76892f), STC(0x7f4c7e54),
+ STC(0x7f1cde01), STC(0x7ee7aa4c), STC(0x7eace58a), STC(0x7e6c9251),
+ STC(0x7e26b371), STC(0x7ddb4bfc), STC(0x7d8a5f40), STC(0x7d33f0ca),
+ STC(0x7cd80464), STC(0x7c769e18), STC(0x7c0fc22a), STC(0x7ba3751d),
+ STC(0x7b31bbb2), STC(0x7aba9ae6), STC(0x7a3e17f2), STC(0x79bc384d),
+ STC(0x793501a9), STC(0x78a879f4), STC(0x7816a759), STC(0x777f903c),
+ STC(0x76e33b3f), STC(0x7641af3d), STC(0x759af34c), STC(0x7ff4c56f),
+ STC(0x7fd317b4), STC(0x7f9afcb9), STC(0x7f4c7e54), STC(0x7ee7aa4c),
+ STC(0x7e6c9251), STC(0x7ddb4bfc), STC(0x7d33f0ca), STC(0x7c769e18),
+ STC(0x7ba3751d), STC(0x7aba9ae6), STC(0x79bc384d), STC(0x78a879f4),
+ STC(0x777f903c), STC(0x7641af3d), STC(0x74ef0ebc), STC(0x7387ea23),
+ STC(0x720c8075), STC(0x707d1443), STC(0x6ed9eba1), STC(0x6d23501b),
+ STC(0x6b598ea3), STC(0x697cf78a), STC(0x678dde6e), STC(0x658c9a2d),
+ STC(0x637984d4), STC(0x6154fb91), STC(0x5f1f5ea1), STC(0x5cd91140),
+ STC(0x5a82799a), STC(0x581c00b3), STC(0x7fe6bcb0), STC(0x7f9afcb9),
+ STC(0x7f1cde01), STC(0x7e6c9251), STC(0x7d8a5f40), STC(0x7c769e18),
+ STC(0x7b31bbb2), STC(0x79bc384d), STC(0x7816a759), STC(0x7641af3d),
+ STC(0x743e0918), STC(0x720c8075), STC(0x6fadf2fc), STC(0x6d23501b),
+ STC(0x6a6d98a4), STC(0x678dde6e), STC(0x648543e4), STC(0x6154fb91),
+ STC(0x5dfe47ad), STC(0x5a82799a), STC(0x56e2f15d), STC(0x53211d18),
+ STC(0x4f3e7875), STC(0x4b3c8c12), STC(0x471cece7), STC(0x42e13ba4),
+ STC(0x3e8b240e), STC(0x3a1c5c57), STC(0x3596a46c), STC(0x30fbc54d),
+ STC(0x2c4d9050), STC(0x7fd317b4), STC(0x7f4c7e54), STC(0x7e6c9251),
+ STC(0x7d33f0ca), STC(0x7ba3751d), STC(0x79bc384d), STC(0x777f903c),
+ STC(0x74ef0ebc), STC(0x720c8075), STC(0x6ed9eba1), STC(0x6b598ea3),
+ STC(0x678dde6e), STC(0x637984d4), STC(0x5f1f5ea1), STC(0x5a82799a),
+ STC(0x55a6125c), STC(0x508d9211), STC(0x4b3c8c12), STC(0x45b6bb5e),
+ STC(0x40000000), STC(0x3a1c5c57), STC(0x340ff242), STC(0x2ddf0040),
+ STC(0x278dde6e), STC(0x2120fb83), STC(0x1a9cd9ac), STC(0x14060b68),
+ STC(0x0d61304e), STC(0x06b2f1d2), STC(0x00000000), STC(0xf94d0e2e),
+ STC(0x7fb9d759), STC(0x7ee7aa4c), STC(0x7d8a5f40), STC(0x7ba3751d),
+ STC(0x793501a9), STC(0x7641af3d), STC(0x72ccb9db), STC(0x6ed9eba1),
+ STC(0x6a6d98a4), STC(0x658c9a2d), STC(0x603c496c), STC(0x5a82799a),
+ STC(0x54657194), STC(0x4debe4fe), STC(0x471cece7), STC(0x40000000),
+ STC(0x389cea72), STC(0x30fbc54d), STC(0x2924edac), STC(0x2120fb83),
+ STC(0x18f8b83c), STC(0x10b5150f), STC(0x085f2137), STC(0x00000000),
+ STC(0xf7a0dec9), STC(0xef4aeaf1), STC(0xe70747c4), STC(0xdedf047d),
+ STC(0xd6db1254), STC(0xcf043ab3), STC(0xc763158e), STC(0x7f9afcb9),
+ STC(0x7e6c9251), STC(0x7c769e18), STC(0x79bc384d), STC(0x7641af3d),
+ STC(0x720c8075), STC(0x6d23501b), STC(0x678dde6e), STC(0x6154fb91),
+ STC(0x5a82799a), STC(0x53211d18), STC(0x4b3c8c12), STC(0x42e13ba4),
+ STC(0x3a1c5c57), STC(0x30fbc54d), STC(0x278dde6e), STC(0x1de189a6),
+ STC(0x14060b68), STC(0x0a0af299), STC(0x00000000), STC(0xf5f50d67),
+ STC(0xebf9f498), STC(0xe21e765a), STC(0xd8722192), STC(0xcf043ab3),
+ STC(0xc5e3a3a9), STC(0xbd1ec45c), STC(0xb4c373ee), STC(0xacdee2e8),
+ STC(0xa57d8666), STC(0x9eab046f), STC(0x7f76892f), STC(0x7ddb4bfc),
+ STC(0x7b31bbb2), STC(0x777f903c), STC(0x72ccb9db), STC(0x6d23501b),
+ STC(0x668f7c25), STC(0x5f1f5ea1), STC(0x56e2f15d), STC(0x4debe4fe),
+ STC(0x444d7aff), STC(0x3a1c5c57), STC(0x2f6e6d16), STC(0x245a9d65),
+ STC(0x18f8b83c), STC(0x0d61304e), STC(0x01aceb7c), STC(0xf5f50d67),
+ STC(0xea52c166), STC(0xdedf047d), STC(0xd3b26fb0), STC(0xc8e5032b),
+ STC(0xbe8df2ba), STC(0xb4c373ee), STC(0xab9a8e6c), STC(0xa326eec0),
+ STC(0x9b7abc1c), STC(0x94a6715d), STC(0x8eb8b9a0), STC(0x89be50c3),
+ STC(0x85c1e80e), STC(0x7f4c7e54), STC(0x7d33f0ca), STC(0x79bc384d),
+ STC(0x74ef0ebc), STC(0x6ed9eba1), STC(0x678dde6e), STC(0x5f1f5ea1),
+ STC(0x55a6125c), STC(0x4b3c8c12), STC(0x40000000), STC(0x340ff242),
+ STC(0x278dde6e), STC(0x1a9cd9ac), STC(0x0d61304e), STC(0x00000000),
+ STC(0xf29ecfb2), STC(0xe5632654), STC(0xd8722192), STC(0xcbf00dbe),
+ STC(0xc0000000), STC(0xb4c373ee), STC(0xaa59eda4), STC(0xa0e0a15f),
+ STC(0x98722192), STC(0x9126145f), STC(0x8b10f144), STC(0x8643c7b3),
+ STC(0x82cc0f36), STC(0x80b381ac), STC(0x80000000), STC(0x80b381ac),
+ STC(0x7f1cde01), STC(0x7c769e18), STC(0x7816a759), STC(0x720c8075),
+ STC(0x6a6d98a4), STC(0x6154fb91), STC(0x56e2f15d), STC(0x4b3c8c12),
+ STC(0x3e8b240e), STC(0x30fbc54d), STC(0x22be8f87), STC(0x14060b68),
+ STC(0x05067734), STC(0xf5f50d67), STC(0xe70747c4), STC(0xd8722192),
+ STC(0xca695b94), STC(0xbd1ec45c), STC(0xb0c1878b), STC(0xa57d8666),
+ STC(0x9b7abc1c), STC(0x92dcafe5), STC(0x8bc1f6e8), STC(0x8643c7b3),
+ STC(0x8275a0c0), STC(0x80650347), STC(0x80194350), STC(0x81936daf),
+ STC(0x84ce444e), STC(0x89be50c3), STC(0x90520d04), STC(0x7ee7aa4c),
+ STC(0x7ba3751d), STC(0x7641af3d), STC(0x6ed9eba1), STC(0x658c9a2d),
+ STC(0x5a82799a), STC(0x4debe4fe), STC(0x40000000), STC(0x30fbc54d),
+ STC(0x2120fb83), STC(0x10b5150f), STC(0x00000000), STC(0xef4aeaf1),
+ STC(0xdedf047d), STC(0xcf043ab3), STC(0xc0000000), STC(0xb2141b02),
+ STC(0xa57d8666), STC(0x9a7365d3), STC(0x9126145f), STC(0x89be50c3),
+ STC(0x845c8ae3), STC(0x811855b4), STC(0x80000000), STC(0x811855b4),
+ STC(0x845c8ae3), STC(0x89be50c3), STC(0x9126145f), STC(0x9a7365d3),
+ STC(0xa57d8666), STC(0xb2141b02), STC(0x7eace58a), STC(0x7aba9ae6),
+ STC(0x743e0918), STC(0x6b598ea3), STC(0x603c496c), STC(0x53211d18),
+ STC(0x444d7aff), STC(0x340ff242), STC(0x22be8f87), STC(0x10b5150f),
+ STC(0xfe531484), STC(0xebf9f498), STC(0xda0aecf9), STC(0xc8e5032b),
+ STC(0xb8e31319), STC(0xaa59eda4), STC(0x9d969742), STC(0x92dcafe5),
+ STC(0x8a650cb4), STC(0x845c8ae3), STC(0x80e321ff), STC(0x800b3a91),
+ STC(0x81d94c8f), STC(0x8643c7b3), STC(0x8d334625), STC(0x96830876),
+ STC(0xa201b853), STC(0xaf726def), STC(0xbe8df2ba), STC(0xcf043ab3),
+ STC(0xe07e0c84), STC(0x7e6c9251), STC(0x79bc384d), STC(0x720c8075),
+ STC(0x678dde6e), STC(0x5a82799a), STC(0x4b3c8c12), STC(0x3a1c5c57),
+ STC(0x278dde6e), STC(0x14060b68), STC(0x00000000), STC(0xebf9f498),
+ STC(0xd8722192), STC(0xc5e3a3a9), STC(0xb4c373ee), STC(0xa57d8666),
+ STC(0x98722192), STC(0x8df37f8b), STC(0x8643c7b3), STC(0x81936daf),
+ STC(0x80000000), STC(0x81936daf), STC(0x8643c7b3), STC(0x8df37f8b),
+ STC(0x98722192), STC(0xa57d8666), STC(0xb4c373ee), STC(0xc5e3a3a9),
+ STC(0xd8722192), STC(0xebf9f498), STC(0x00000000), STC(0x14060b68),
+ STC(0x7e26b371), STC(0x78a879f4), STC(0x6fadf2fc), STC(0x637984d4),
+ STC(0x54657194), STC(0x42e13ba4), STC(0x2f6e6d16), STC(0x1a9cd9ac),
+ STC(0x05067734), STC(0xef4aeaf1), STC(0xda0aecf9), STC(0xc5e3a3a9),
+ STC(0xb36a1978), STC(0xa326eec0), STC(0x9592675c), STC(0x8b10f144),
+ STC(0x83f03dd6), STC(0x80650347), STC(0x808976d1), STC(0x845c8ae3),
+ STC(0x8bc1f6e8), STC(0x96830876), STC(0xa45037c9), STC(0xb4c373ee),
+ STC(0xc763158e), STC(0xdba5629b), STC(0xf0f488d9), STC(0x06b2f1d2),
+ STC(0x1c3fd045), STC(0x30fbc54d), STC(0x444d7aff), STC(0x7ddb4bfc),
+ STC(0x777f903c), STC(0x6d23501b), STC(0x5f1f5ea1), STC(0x4debe4fe),
+ STC(0x3a1c5c57), STC(0x245a9d65), STC(0x0d61304e), STC(0xf5f50d67),
+ STC(0xdedf047d), STC(0xc8e5032b), STC(0xb4c373ee), STC(0xa326eec0),
+ STC(0x94a6715d), STC(0x89be50c3), STC(0x82cc0f36), STC(0x800b3a91),
+ STC(0x81936daf), STC(0x8757860c), STC(0x9126145f), STC(0x9eab046f),
+ STC(0xaf726def), STC(0xc2ec7635), STC(0xd8722192), STC(0xef4aeaf1),
+ STC(0x06b2f1d2), STC(0x1de189a6), STC(0x340ff242), STC(0x487fffe4),
+ STC(0x5a82799a), STC(0x697cf78a),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag480[] = {
+ STC(0x01aceb7c), STC(0x0359c428), STC(0x05067734), STC(0x06b2f1d2),
+ STC(0x085f2137), STC(0x0a0af299), STC(0x0bb65336), STC(0x0d61304e),
+ STC(0x0f0b7727), STC(0x10b5150f), STC(0x125df75b), STC(0x14060b68),
+ STC(0x15ad3e9a), STC(0x17537e63), STC(0x18f8b83c), STC(0x1a9cd9ac),
+ STC(0x1c3fd045), STC(0x1de189a6), STC(0x1f81f37c), STC(0x2120fb83),
+ STC(0x22be8f87), STC(0x245a9d65), STC(0x25f51307), STC(0x278dde6e),
+ STC(0x2924edac), STC(0x2aba2ee4), STC(0x2c4d9050), STC(0x2ddf0040),
+ STC(0x2f6e6d16), STC(0x30fbc54d), STC(0x3286f779), STC(0x0359c428),
+ STC(0x06b2f1d2), STC(0x0a0af299), STC(0x0d61304e), STC(0x10b5150f),
+ STC(0x14060b68), STC(0x17537e63), STC(0x1a9cd9ac), STC(0x1de189a6),
+ STC(0x2120fb83), STC(0x245a9d65), STC(0x278dde6e), STC(0x2aba2ee4),
+ STC(0x2ddf0040), STC(0x30fbc54d), STC(0x340ff242), STC(0x371afcd5),
+ STC(0x3a1c5c57), STC(0x3d1389cb), STC(0x40000000), STC(0x42e13ba4),
+ STC(0x45b6bb5e), STC(0x487fffe4), STC(0x4b3c8c12), STC(0x4debe4fe),
+ STC(0x508d9211), STC(0x53211d18), STC(0x55a6125c), STC(0x581c00b3),
+ STC(0x5a82799a), STC(0x5cd91140), STC(0x05067734), STC(0x0a0af299),
+ STC(0x0f0b7727), STC(0x14060b68), STC(0x18f8b83c), STC(0x1de189a6),
+ STC(0x22be8f87), STC(0x278dde6e), STC(0x2c4d9050), STC(0x30fbc54d),
+ STC(0x3596a46c), STC(0x3a1c5c57), STC(0x3e8b240e), STC(0x42e13ba4),
+ STC(0x471cece7), STC(0x4b3c8c12), STC(0x4f3e7875), STC(0x53211d18),
+ STC(0x56e2f15d), STC(0x5a82799a), STC(0x5dfe47ad), STC(0x6154fb91),
+ STC(0x648543e4), STC(0x678dde6e), STC(0x6a6d98a4), STC(0x6d23501b),
+ STC(0x6fadf2fc), STC(0x720c8075), STC(0x743e0918), STC(0x7641af3d),
+ STC(0x7816a759), STC(0x06b2f1d2), STC(0x0d61304e), STC(0x14060b68),
+ STC(0x1a9cd9ac), STC(0x2120fb83), STC(0x278dde6e), STC(0x2ddf0040),
+ STC(0x340ff242), STC(0x3a1c5c57), STC(0x40000000), STC(0x45b6bb5e),
+ STC(0x4b3c8c12), STC(0x508d9211), STC(0x55a6125c), STC(0x5a82799a),
+ STC(0x5f1f5ea1), STC(0x637984d4), STC(0x678dde6e), STC(0x6b598ea3),
+ STC(0x6ed9eba1), STC(0x720c8075), STC(0x74ef0ebc), STC(0x777f903c),
+ STC(0x79bc384d), STC(0x7ba3751d), STC(0x7d33f0ca), STC(0x7e6c9251),
+ STC(0x7f4c7e54), STC(0x7fd317b4), STC(0x7fffffff), STC(0x7fd317b4),
+ STC(0x085f2137), STC(0x10b5150f), STC(0x18f8b83c), STC(0x2120fb83),
+ STC(0x2924edac), STC(0x30fbc54d), STC(0x389cea72), STC(0x40000000),
+ STC(0x471cece7), STC(0x4debe4fe), STC(0x54657194), STC(0x5a82799a),
+ STC(0x603c496c), STC(0x658c9a2d), STC(0x6a6d98a4), STC(0x6ed9eba1),
+ STC(0x72ccb9db), STC(0x7641af3d), STC(0x793501a9), STC(0x7ba3751d),
+ STC(0x7d8a5f40), STC(0x7ee7aa4c), STC(0x7fb9d759), STC(0x7fffffff),
+ STC(0x7fb9d759), STC(0x7ee7aa4c), STC(0x7d8a5f40), STC(0x7ba3751d),
+ STC(0x793501a9), STC(0x7641af3d), STC(0x72ccb9db), STC(0x0a0af299),
+ STC(0x14060b68), STC(0x1de189a6), STC(0x278dde6e), STC(0x30fbc54d),
+ STC(0x3a1c5c57), STC(0x42e13ba4), STC(0x4b3c8c12), STC(0x53211d18),
+ STC(0x5a82799a), STC(0x6154fb91), STC(0x678dde6e), STC(0x6d23501b),
+ STC(0x720c8075), STC(0x7641af3d), STC(0x79bc384d), STC(0x7c769e18),
+ STC(0x7e6c9251), STC(0x7f9afcb9), STC(0x7fffffff), STC(0x7f9afcb9),
+ STC(0x7e6c9251), STC(0x7c769e18), STC(0x79bc384d), STC(0x7641af3d),
+ STC(0x720c8075), STC(0x6d23501b), STC(0x678dde6e), STC(0x6154fb91),
+ STC(0x5a82799a), STC(0x53211d18), STC(0x0bb65336), STC(0x17537e63),
+ STC(0x22be8f87), STC(0x2ddf0040), STC(0x389cea72), STC(0x42e13ba4),
+ STC(0x4c95e688), STC(0x55a6125c), STC(0x5dfe47ad), STC(0x658c9a2d),
+ STC(0x6c40cf2c), STC(0x720c8075), STC(0x76e33b3f), STC(0x7aba9ae6),
+ STC(0x7d8a5f40), STC(0x7f4c7e54), STC(0x7ffd3154), STC(0x7f9afcb9),
+ STC(0x7e26b371), STC(0x7ba3751d), STC(0x7816a759), STC(0x7387ea23),
+ STC(0x6e010780), STC(0x678dde6e), STC(0x603c496c), STC(0x581c00b3),
+ STC(0x4f3e7875), STC(0x45b6bb5e), STC(0x3b9941b1), STC(0x30fbc54d),
+ STC(0x25f51307), STC(0x0d61304e), STC(0x1a9cd9ac), STC(0x278dde6e),
+ STC(0x340ff242), STC(0x40000000), STC(0x4b3c8c12), STC(0x55a6125c),
+ STC(0x5f1f5ea1), STC(0x678dde6e), STC(0x6ed9eba1), STC(0x74ef0ebc),
+ STC(0x79bc384d), STC(0x7d33f0ca), STC(0x7f4c7e54), STC(0x7fffffff),
+ STC(0x7f4c7e54), STC(0x7d33f0ca), STC(0x79bc384d), STC(0x74ef0ebc),
+ STC(0x6ed9eba1), STC(0x678dde6e), STC(0x5f1f5ea1), STC(0x55a6125c),
+ STC(0x4b3c8c12), STC(0x40000000), STC(0x340ff242), STC(0x278dde6e),
+ STC(0x1a9cd9ac), STC(0x0d61304e), STC(0x00000000), STC(0xf29ecfb2),
+ STC(0x0f0b7727), STC(0x1de189a6), STC(0x2c4d9050), STC(0x3a1c5c57),
+ STC(0x471cece7), STC(0x53211d18), STC(0x5dfe47ad), STC(0x678dde6e),
+ STC(0x6fadf2fc), STC(0x7641af3d), STC(0x7b31bbb2), STC(0x7e6c9251),
+ STC(0x7fe6bcb0), STC(0x7f9afcb9), STC(0x7d8a5f40), STC(0x79bc384d),
+ STC(0x743e0918), STC(0x6d23501b), STC(0x648543e4), STC(0x5a82799a),
+ STC(0x4f3e7875), STC(0x42e13ba4), STC(0x3596a46c), STC(0x278dde6e),
+ STC(0x18f8b83c), STC(0x0a0af299), STC(0xfaf988cc), STC(0xebf9f498),
+ STC(0xdd417079), STC(0xcf043ab3), STC(0xc174dbf2), STC(0x10b5150f),
+ STC(0x2120fb83), STC(0x30fbc54d), STC(0x40000000), STC(0x4debe4fe),
+ STC(0x5a82799a), STC(0x658c9a2d), STC(0x6ed9eba1), STC(0x7641af3d),
+ STC(0x7ba3751d), STC(0x7ee7aa4c), STC(0x7fffffff), STC(0x7ee7aa4c),
+ STC(0x7ba3751d), STC(0x7641af3d), STC(0x6ed9eba1), STC(0x658c9a2d),
+ STC(0x5a82799a), STC(0x4debe4fe), STC(0x40000000), STC(0x30fbc54d),
+ STC(0x2120fb83), STC(0x10b5150f), STC(0x00000000), STC(0xef4aeaf1),
+ STC(0xdedf047d), STC(0xcf043ab3), STC(0xc0000000), STC(0xb2141b02),
+ STC(0xa57d8666), STC(0x9a7365d3), STC(0x125df75b), STC(0x245a9d65),
+ STC(0x3596a46c), STC(0x45b6bb5e), STC(0x54657194), STC(0x6154fb91),
+ STC(0x6c40cf2c), STC(0x74ef0ebc), STC(0x7b31bbb2), STC(0x7ee7aa4c),
+ STC(0x7ffd3154), STC(0x7e6c9251), STC(0x7a3e17f2), STC(0x7387ea23),
+ STC(0x6a6d98a4), STC(0x5f1f5ea1), STC(0x51d92321), STC(0x42e13ba4),
+ STC(0x3286f779), STC(0x2120fb83), STC(0x0f0b7727), STC(0xfca63bd8),
+ STC(0xea52c166), STC(0xd8722192), STC(0xc763158e), STC(0xb780001c),
+ STC(0xa91d0ea3), STC(0x9c867b2c), STC(0x91fef880), STC(0x89be50c3),
+ STC(0x83f03dd6), STC(0x14060b68), STC(0x278dde6e), STC(0x3a1c5c57),
+ STC(0x4b3c8c12), STC(0x5a82799a), STC(0x678dde6e), STC(0x720c8075),
+ STC(0x79bc384d), STC(0x7e6c9251), STC(0x7fffffff), STC(0x7e6c9251),
+ STC(0x79bc384d), STC(0x720c8075), STC(0x678dde6e), STC(0x5a82799a),
+ STC(0x4b3c8c12), STC(0x3a1c5c57), STC(0x278dde6e), STC(0x14060b68),
+ STC(0x00000000), STC(0xebf9f498), STC(0xd8722192), STC(0xc5e3a3a9),
+ STC(0xb4c373ee), STC(0xa57d8666), STC(0x98722192), STC(0x8df37f8b),
+ STC(0x8643c7b3), STC(0x81936daf), STC(0x80000000), STC(0x81936daf),
+ STC(0x15ad3e9a), STC(0x2aba2ee4), STC(0x3e8b240e), STC(0x508d9211),
+ STC(0x603c496c), STC(0x6d23501b), STC(0x76e33b3f), STC(0x7d33f0ca),
+ STC(0x7fe6bcb0), STC(0x7ee7aa4c), STC(0x7a3e17f2), STC(0x720c8075),
+ STC(0x668f7c25), STC(0x581c00b3), STC(0x471cece7), STC(0x340ff242),
+ STC(0x1f81f37c), STC(0x0a0af299), STC(0xf449acca), STC(0xdedf047d),
+ STC(0xca695b94), STC(0xb780001c), STC(0xa6aecd5e), STC(0x98722192),
+ STC(0x8d334625), STC(0x8545651a), STC(0x80e321ff), STC(0x802ce84c),
+ STC(0x8327fb9c), STC(0x89be50c3), STC(0x93bf30d4), STC(0x17537e63),
+ STC(0x2ddf0040), STC(0x42e13ba4), STC(0x55a6125c), STC(0x658c9a2d),
+ STC(0x720c8075), STC(0x7aba9ae6), STC(0x7f4c7e54), STC(0x7f9afcb9),
+ STC(0x7ba3751d), STC(0x7387ea23), STC(0x678dde6e), STC(0x581c00b3),
+ STC(0x45b6bb5e), STC(0x30fbc54d), STC(0x1a9cd9ac), STC(0x0359c428),
+ STC(0xebf9f498), STC(0xd545d11c), STC(0xc0000000), STC(0xacdee2e8),
+ STC(0x9c867b2c), STC(0x8f82ebbd), STC(0x8643c7b3), STC(0x811855b4),
+ STC(0x802ce84c), STC(0x838961e8), STC(0x8b10f144), STC(0x96830876),
+ STC(0xa57d8666), STC(0xb780001c),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorReal20[] = {
+ STC(0x79bc384d), STC(0x678dde6e), STC(0x4b3c8c12), STC(0x678dde6e),
+ STC(0x278dde6e), STC(0xd8722192), STC(0x4b3c8c12), STC(0xd8722192),
+ STC(0x8643c7b3), STC(0x278dde6e), STC(0x98722192), STC(0x98722192),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_STB RotVectorImag20[] = {
+ STC(0x278dde6e), STC(0x4b3c8c12), STC(0x678dde6e), STC(0x4b3c8c12),
+ STC(0x79bc384d), STC(0x79bc384d), STC(0x678dde6e), STC(0x79bc384d),
+ STC(0x278dde6e), STC(0x79bc384d), STC(0x4b3c8c12), STC(0xb4c373ee),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow8[] = {
+ WTCP(0x7f62368f, 0x0c8bd35e),
+ WTCP(0x7a7d055b, 0x25280c5e),
+ WTCP(0x70e2cbc6, 0x3c56ba70),
+ WTCP(0x62f201ac, 0x5133cc94),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow12[] = {
+ WTCP(0x7fb9d759, 0x085f2137), WTCP(0x7d8a5f40, 0x18f8b83c),
+ WTCP(0x793501a9, 0x2924edac), WTCP(0x72ccb9db, 0x389cea72),
+ WTCP(0x6a6d98a4, 0x471cece7), WTCP(0x603c496c, 0x54657194),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow16[] = {
+ WTCP(0x7fd8878e, 0x0647d97c), WTCP(0x7e9d55fc, 0x12c8106f),
+ WTCP(0x7c29fbee, 0x1f19f97b), WTCP(0x78848414, 0x2b1f34eb),
+ WTCP(0x73b5ebd1, 0x36ba2014), WTCP(0x6dca0d14, 0x41ce1e65),
+ WTCP(0x66cf8120, 0x4c3fdff4), WTCP(0x5ed77c8a, 0x55f5a4d2),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow20[] = {
+ WTCP(0x7fe6bcb0, 0x05067734), WTCP(0x7f1cde01, 0x0f0b7727),
+ WTCP(0x7d8a5f40, 0x18f8b83c), WTCP(0x7b31bbb2, 0x22be8f87),
+ WTCP(0x7816a759, 0x2c4d9050), WTCP(0x743e0918, 0x3596a46c),
+ WTCP(0x6fadf2fc, 0x3e8b240e), WTCP(0x6a6d98a4, 0x471cece7),
+ WTCP(0x648543e4, 0x4f3e7875), WTCP(0x5dfe47ad, 0x56e2f15d),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow24[] = {
+ WTCP(0x7fee74a2, 0x0430238f), WTCP(0x7f62368f, 0x0c8bd35e),
+ WTCP(0x7e4a5426, 0x14d9c245), WTCP(0x7ca80038, 0x1d10d5c2),
+ WTCP(0x7a7d055b, 0x25280c5e), WTCP(0x77cbc3f2, 0x2d168792),
+ WTCP(0x74972f92, 0x34d3957e), WTCP(0x70e2cbc6, 0x3c56ba70),
+ WTCP(0x6cb2a837, 0x4397ba32), WTCP(0x680b5c33, 0x4a8ea111),
+ WTCP(0x62f201ac, 0x5133cc94), WTCP(0x5d6c2f99, 0x577ff3da),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow32[] = {
+ WTCP(0x7ff62182, 0x03242abf), WTCP(0x7fa736b4, 0x096a9049),
+ WTCP(0x7f0991c4, 0x0fab272b), WTCP(0x7e1d93ea, 0x15e21445),
+ WTCP(0x7ce3ceb2, 0x1c0b826a), WTCP(0x7b5d039e, 0x2223a4c5),
+ WTCP(0x798a23b1, 0x2826b928), WTCP(0x776c4edb, 0x2e110a62),
+ WTCP(0x7504d345, 0x33def287), WTCP(0x72552c85, 0x398cdd32),
+ WTCP(0x6f5f02b2, 0x3f1749b8), WTCP(0x6c242960, 0x447acd50),
+ WTCP(0x68a69e81, 0x49b41533), WTCP(0x64e88926, 0x4ebfe8a5),
+ WTCP(0x60ec3830, 0x539b2af0), WTCP(0x5cb420e0, 0x5842dd54),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow40[] = {
+ WTCP(0x7ff9af04, 0x02835b5a), WTCP(0x7fc72ae2, 0x07891418),
+ WTCP(0x7f62368f, 0x0c8bd35e), WTCP(0x7ecaf9e5, 0x11899ed3),
+ WTCP(0x7e01b096, 0x16807e15), WTCP(0x7d06aa16, 0x1b6e7b7a),
+ WTCP(0x7bda497d, 0x2051a4dd), WTCP(0x7a7d055b, 0x25280c5e),
+ WTCP(0x78ef678f, 0x29efc925), WTCP(0x77320d0d, 0x2ea6f827),
+ WTCP(0x7545a5a0, 0x334bbcde), WTCP(0x732af3a7, 0x37dc420c),
+ WTCP(0x70e2cbc6, 0x3c56ba70), WTCP(0x6e6e1492, 0x40b9617d),
+ WTCP(0x6bcdc639, 0x45027c0c), WTCP(0x6902ea1d, 0x4930590f),
+ WTCP(0x660e9a6a, 0x4d415234), WTCP(0x62f201ac, 0x5133cc94),
+ WTCP(0x5fae5a55, 0x55063951), WTCP(0x5c44ee40, 0x58b71632),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow48[] = {
+ WTCP(0x7ffb9d15, 0x02182427), WTCP(0x7fd8878e, 0x0647d97c),
+ WTCP(0x7f92661d, 0x0a75d60e), WTCP(0x7f294bfd, 0x0ea0f48c),
+ WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7deeaa7a, 0x16ea0646),
+ WTCP(0x7d1d7958, 0x1b05b40f), WTCP(0x7c29fbee, 0x1f19f97b),
+ WTCP(0x7b1474fd, 0x2325b847), WTCP(0x79dd3098, 0x2727d486),
+ WTCP(0x78848414, 0x2b1f34eb), WTCP(0x770acdec, 0x2f0ac320),
+ WTCP(0x757075ac, 0x32e96c09), WTCP(0x73b5ebd1, 0x36ba2014),
+ WTCP(0x71dba9ab, 0x3a7bd382), WTCP(0x6fe2313c, 0x3e2d7eb1),
+ WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x6b93d02e, 0x455cb40c),
+ WTCP(0x694015c3, 0x48d84609), WTCP(0x66cf8120, 0x4c3fdff4),
+ WTCP(0x6442bd7e, 0x4f9292dc), WTCP(0x619a7dce, 0x52cf758f),
+ WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5bfa7b82, 0x590443a7),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow64[] = {
+ WTCP(0x7ffd885a, 0x01921d20), WTCP(0x7fe9cbc0, 0x04b6195d),
+ WTCP(0x7fc25596, 0x07d95b9e), WTCP(0x7f872bf3, 0x0afb6805),
+ WTCP(0x7f3857f6, 0x0e1bc2e4), WTCP(0x7ed5e5c6, 0x1139f0cf),
+ WTCP(0x7e5fe493, 0x145576b1), WTCP(0x7dd6668f, 0x176dd9de),
+ WTCP(0x7d3980ec, 0x1a82a026), WTCP(0x7c894bde, 0x1d934fe5),
+ WTCP(0x7bc5e290, 0x209f701c), WTCP(0x7aef6323, 0x23a6887f),
+ WTCP(0x7a05eead, 0x26a82186), WTCP(0x7909a92d, 0x29a3c485),
+ WTCP(0x77fab989, 0x2c98fbba), WTCP(0x76d94989, 0x2f875262),
+ WTCP(0x75a585cf, 0x326e54c7), WTCP(0x745f9dd1, 0x354d9057),
+ WTCP(0x7307c3d0, 0x382493b0), WTCP(0x719e2cd2, 0x3af2eeb7),
+ WTCP(0x7023109a, 0x3db832a6), WTCP(0x6e96a99d, 0x4073f21d),
+ WTCP(0x6cf934fc, 0x4325c135), WTCP(0x6b4af279, 0x45cd358f),
+ WTCP(0x698c246c, 0x4869e665), WTCP(0x67bd0fbd, 0x4afb6c98),
+ WTCP(0x65ddfbd3, 0x4d8162c4), WTCP(0x63ef3290, 0x4ffb654d),
+ WTCP(0x61f1003f, 0x5269126e), WTCP(0x5fe3b38d, 0x54ca0a4b),
+ WTCP(0x5dc79d7c, 0x571deefa), WTCP(0x5b9d1154, 0x59646498),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow96[] = {
+ WTCP(0x7ffee744, 0x010c1460), WTCP(0x7ff62182, 0x03242abf),
+ WTCP(0x7fe49698, 0x053c0a01), WTCP(0x7fca47b9, 0x07538d6b),
+ WTCP(0x7fa736b4, 0x096a9049), WTCP(0x7f7b65ef, 0x0b80edf1),
+ WTCP(0x7f46d86c, 0x0d9681c2), WTCP(0x7f0991c4, 0x0fab272b),
+ WTCP(0x7ec3962a, 0x11beb9aa), WTCP(0x7e74ea6a, 0x13d114d0),
+ WTCP(0x7e1d93ea, 0x15e21445), WTCP(0x7dbd98a4, 0x17f193c5),
+ WTCP(0x7d54ff2e, 0x19ff6f2a), WTCP(0x7ce3ceb2, 0x1c0b826a),
+ WTCP(0x7c6a0ef2, 0x1e15a99a), WTCP(0x7be7c847, 0x201dc0ef),
+ WTCP(0x7b5d039e, 0x2223a4c5), WTCP(0x7ac9ca7a, 0x2427319d),
+ WTCP(0x7a2e26f2, 0x26284422), WTCP(0x798a23b1, 0x2826b928),
+ WTCP(0x78ddcbf5, 0x2a226db5), WTCP(0x78292b8d, 0x2c1b3efb),
+ WTCP(0x776c4edb, 0x2e110a62), WTCP(0x76a742d1, 0x3003ad85),
+ WTCP(0x75da14ef, 0x31f30638), WTCP(0x7504d345, 0x33def287),
+ WTCP(0x74278c72, 0x35c750bc), WTCP(0x73424fa0, 0x37abff5d),
+ WTCP(0x72552c85, 0x398cdd32), WTCP(0x71603361, 0x3b69c947),
+ WTCP(0x706374ff, 0x3d42a2ec), WTCP(0x6f5f02b2, 0x3f1749b8),
+ WTCP(0x6e52ee52, 0x40e79d8c), WTCP(0x6d3f4a40, 0x42b37e96),
+ WTCP(0x6c242960, 0x447acd50), WTCP(0x6b019f1a, 0x463d6a87),
+ WTCP(0x69d7bf57, 0x47fb3757), WTCP(0x68a69e81, 0x49b41533),
+ WTCP(0x676e5183, 0x4b67e5e4), WTCP(0x662eedc3, 0x4d168b8b),
+ WTCP(0x64e88926, 0x4ebfe8a5), WTCP(0x639b3a0b, 0x5063e008),
+ WTCP(0x62471749, 0x520254ef), WTCP(0x60ec3830, 0x539b2af0),
+ WTCP(0x5f8ab487, 0x552e4605), WTCP(0x5e22a487, 0x56bb8a90),
+ WTCP(0x5cb420e0, 0x5842dd54), WTCP(0x5b3f42ae, 0x59c42381),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow120[] = {
+ WTCP(0x7fff4c54, 0x00d676eb), WTCP(0x7ff9af04, 0x02835b5a),
+ WTCP(0x7fee74a2, 0x0430238f), WTCP(0x7fdd9dad, 0x05dcbcbe),
+ WTCP(0x7fc72ae2, 0x07891418), WTCP(0x7fab1d3d, 0x093516d4),
+ WTCP(0x7f8975f9, 0x0ae0b22c), WTCP(0x7f62368f, 0x0c8bd35e),
+ WTCP(0x7f3560b9, 0x0e3667ad), WTCP(0x7f02f66f, 0x0fe05c64),
+ WTCP(0x7ecaf9e5, 0x11899ed3), WTCP(0x7e8d6d91, 0x13321c53),
+ WTCP(0x7e4a5426, 0x14d9c245), WTCP(0x7e01b096, 0x16807e15),
+ WTCP(0x7db3860f, 0x18263d36), WTCP(0x7d5fd801, 0x19caed29),
+ WTCP(0x7d06aa16, 0x1b6e7b7a), WTCP(0x7ca80038, 0x1d10d5c2),
+ WTCP(0x7c43de8e, 0x1eb1e9a7), WTCP(0x7bda497d, 0x2051a4dd),
+ WTCP(0x7b6b45a5, 0x21eff528), WTCP(0x7af6d7e6, 0x238cc85d),
+ WTCP(0x7a7d055b, 0x25280c5e), WTCP(0x79fdd35c, 0x26c1af22),
+ WTCP(0x7979477d, 0x28599eb0), WTCP(0x78ef678f, 0x29efc925),
+ WTCP(0x7860399e, 0x2b841caf), WTCP(0x77cbc3f2, 0x2d168792),
+ WTCP(0x77320d0d, 0x2ea6f827), WTCP(0x76931bae, 0x30355cdd),
+ WTCP(0x75eef6ce, 0x31c1a43b), WTCP(0x7545a5a0, 0x334bbcde),
+ WTCP(0x74972f92, 0x34d3957e), WTCP(0x73e39c49, 0x36591cea),
+ WTCP(0x732af3a7, 0x37dc420c), WTCP(0x726d3dc6, 0x395cf3e9),
+ WTCP(0x71aa82f7, 0x3adb21a1), WTCP(0x70e2cbc6, 0x3c56ba70),
+ WTCP(0x701620f5, 0x3dcfadb0), WTCP(0x6f448b7e, 0x3f45ead8),
+ WTCP(0x6e6e1492, 0x40b9617d), WTCP(0x6d92c59b, 0x422a0154),
+ WTCP(0x6cb2a837, 0x4397ba32), WTCP(0x6bcdc639, 0x45027c0c),
+ WTCP(0x6ae429ae, 0x466a36f9), WTCP(0x69f5dcd3, 0x47cedb31),
+ WTCP(0x6902ea1d, 0x4930590f), WTCP(0x680b5c33, 0x4a8ea111),
+ WTCP(0x670f3df3, 0x4be9a3db), WTCP(0x660e9a6a, 0x4d415234),
+ WTCP(0x65097cdb, 0x4e959d08), WTCP(0x63fff0ba, 0x4fe6756a),
+ WTCP(0x62f201ac, 0x5133cc94), WTCP(0x61dfbb8a, 0x527d93e6),
+ WTCP(0x60c92a5a, 0x53c3bcea), WTCP(0x5fae5a55, 0x55063951),
+ WTCP(0x5e8f57e2, 0x5644faf4), WTCP(0x5d6c2f99, 0x577ff3da),
+ WTCP(0x5c44ee40, 0x58b71632), WTCP(0x5b19a0c8, 0x59ea5454),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow128[] = {
+ WTCP(0x7fff6216, 0x00c90f88), WTCP(0x7ffa72d1, 0x025b26d7),
+ WTCP(0x7ff09478, 0x03ed26e6), WTCP(0x7fe1c76b, 0x057f0035),
+ WTCP(0x7fce0c3e, 0x0710a345), WTCP(0x7fb563b3, 0x08a2009a),
+ WTCP(0x7f97cebd, 0x0a3308bd), WTCP(0x7f754e80, 0x0bc3ac35),
+ WTCP(0x7f4de451, 0x0d53db92), WTCP(0x7f2191b4, 0x0ee38766),
+ WTCP(0x7ef05860, 0x1072a048), WTCP(0x7eba3a39, 0x120116d5),
+ WTCP(0x7e7f3957, 0x138edbb1), WTCP(0x7e3f57ff, 0x151bdf86),
+ WTCP(0x7dfa98a8, 0x16a81305), WTCP(0x7db0fdf8, 0x183366e9),
+ WTCP(0x7d628ac6, 0x19bdcbf3), WTCP(0x7d0f4218, 0x1b4732ef),
+ WTCP(0x7cb72724, 0x1ccf8cb3), WTCP(0x7c5a3d50, 0x1e56ca1e),
+ WTCP(0x7bf88830, 0x1fdcdc1b), WTCP(0x7b920b89, 0x2161b3a0),
+ WTCP(0x7b26cb4f, 0x22e541af), WTCP(0x7ab6cba4, 0x24677758),
+ WTCP(0x7a4210d8, 0x25e845b6), WTCP(0x79c89f6e, 0x27679df4),
+ WTCP(0x794a7c12, 0x28e5714b), WTCP(0x78c7aba2, 0x2a61b101),
+ WTCP(0x78403329, 0x2bdc4e6f), WTCP(0x77b417df, 0x2d553afc),
+ WTCP(0x77235f2d, 0x2ecc681e), WTCP(0x768e0ea6, 0x3041c761),
+ WTCP(0x75f42c0b, 0x31b54a5e), WTCP(0x7555bd4c, 0x3326e2c3),
+ WTCP(0x74b2c884, 0x34968250), WTCP(0x740b53fb, 0x36041ad9),
+ WTCP(0x735f6626, 0x376f9e46), WTCP(0x72af05a7, 0x38d8fe93),
+ WTCP(0x71fa3949, 0x3a402dd2), WTCP(0x71410805, 0x3ba51e29),
+ WTCP(0x708378ff, 0x3d07c1d6), WTCP(0x6fc19385, 0x3e680b2c),
+ WTCP(0x6efb5f12, 0x3fc5ec98), WTCP(0x6e30e34a, 0x4121589b),
+ WTCP(0x6d6227fa, 0x427a41d0), WTCP(0x6c8f351c, 0x43d09aed),
+ WTCP(0x6bb812d1, 0x452456bd), WTCP(0x6adcc964, 0x46756828),
+ WTCP(0x69fd614a, 0x47c3c22f), WTCP(0x6919e320, 0x490f57ee),
+ WTCP(0x683257ab, 0x4a581c9e), WTCP(0x6746c7d8, 0x4b9e0390),
+ WTCP(0x66573cbb, 0x4ce10034), WTCP(0x6563bf92, 0x4e210617),
+ WTCP(0x646c59bf, 0x4f5e08e3), WTCP(0x637114cc, 0x5097fc5e),
+ WTCP(0x6271fa69, 0x51ced46e), WTCP(0x616f146c, 0x53028518),
+ WTCP(0x60686ccf, 0x5433027d), WTCP(0x5f5e0db3, 0x556040e2),
+ WTCP(0x5e50015d, 0x568a34a9), WTCP(0x5d3e5237, 0x57b0d256),
+ WTCP(0x5c290acc, 0x58d40e8c), WTCP(0x5b1035cf, 0x59f3de12),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow160[] = {
+ WTCP(0x7fff9aef, 0x00a0d951), WTCP(0x7ffc726f, 0x01e287fc),
+ WTCP(0x7ff62182, 0x03242abf), WTCP(0x7feca851, 0x0465b9aa),
+ WTCP(0x7fe00716, 0x05a72ccf), WTCP(0x7fd03e23, 0x06e87c3f),
+ WTCP(0x7fbd4dda, 0x0829a00c), WTCP(0x7fa736b4, 0x096a9049),
+ WTCP(0x7f8df93c, 0x0aab450d), WTCP(0x7f719611, 0x0bebb66c),
+ WTCP(0x7f520de6, 0x0d2bdc80), WTCP(0x7f2f6183, 0x0e6baf61),
+ WTCP(0x7f0991c4, 0x0fab272b), WTCP(0x7ee09f95, 0x10ea3bfd),
+ WTCP(0x7eb48bfb, 0x1228e5f8), WTCP(0x7e85580c, 0x13671d3d),
+ WTCP(0x7e5304f2, 0x14a4d9f4), WTCP(0x7e1d93ea, 0x15e21445),
+ WTCP(0x7de50646, 0x171ec45c), WTCP(0x7da95d6c, 0x185ae269),
+ WTCP(0x7d6a9ad5, 0x199666a0), WTCP(0x7d28c00c, 0x1ad14938),
+ WTCP(0x7ce3ceb2, 0x1c0b826a), WTCP(0x7c9bc87a, 0x1d450a78),
+ WTCP(0x7c50af2b, 0x1e7dd9a4), WTCP(0x7c02849f, 0x1fb5e836),
+ WTCP(0x7bb14ac5, 0x20ed2e7b), WTCP(0x7b5d039e, 0x2223a4c5),
+ WTCP(0x7b05b13d, 0x2359436c), WTCP(0x7aab55ca, 0x248e02cb),
+ WTCP(0x7a4df380, 0x25c1db44), WTCP(0x79ed8cad, 0x26f4c53e),
+ WTCP(0x798a23b1, 0x2826b928), WTCP(0x7923bb01, 0x2957af74),
+ WTCP(0x78ba5524, 0x2a87a09d), WTCP(0x784df4b3, 0x2bb68522),
+ WTCP(0x77de9c5b, 0x2ce45589), WTCP(0x776c4edb, 0x2e110a62),
+ WTCP(0x76f70f05, 0x2f3c9c40), WTCP(0x767edfbe, 0x306703bf),
+ WTCP(0x7603c3fd, 0x31903982), WTCP(0x7585becb, 0x32b83634),
+ WTCP(0x7504d345, 0x33def287), WTCP(0x74810499, 0x35046736),
+ WTCP(0x73fa5607, 0x36288d03), WTCP(0x7370cae2, 0x374b5cb9),
+ WTCP(0x72e4668f, 0x386ccf2a), WTCP(0x72552c85, 0x398cdd32),
+ WTCP(0x71c3204c, 0x3aab7fb7), WTCP(0x712e457f, 0x3bc8afa5),
+ WTCP(0x70969fca, 0x3ce465f3), WTCP(0x6ffc32eb, 0x3dfe9ba1),
+ WTCP(0x6f5f02b2, 0x3f1749b8), WTCP(0x6ebf12ff, 0x402e694c),
+ WTCP(0x6e1c67c4, 0x4143f379), WTCP(0x6d770506, 0x4257e166),
+ WTCP(0x6cceeed8, 0x436a2c45), WTCP(0x6c242960, 0x447acd50),
+ WTCP(0x6b76b8d6, 0x4589bdcf), WTCP(0x6ac6a180, 0x4696f710),
+ WTCP(0x6a13e7b8, 0x47a27271), WTCP(0x695e8fe5, 0x48ac2957),
+ WTCP(0x68a69e81, 0x49b41533), WTCP(0x67ec1817, 0x4aba2f84),
+ WTCP(0x672f013f, 0x4bbe71d1), WTCP(0x666f5ea6, 0x4cc0d5ae),
+ WTCP(0x65ad3505, 0x4dc154bb), WTCP(0x64e88926, 0x4ebfe8a5),
+ WTCP(0x64215fe5, 0x4fbc8b22), WTCP(0x6357be2a, 0x50b735f8),
+ WTCP(0x628ba8ef, 0x51afe2f6), WTCP(0x61bd253f, 0x52a68bfb),
+ WTCP(0x60ec3830, 0x539b2af0), WTCP(0x6018e6eb, 0x548db9cb),
+ WTCP(0x5f4336a7, 0x557e3292), WTCP(0x5e6b2ca8, 0x566c8f55),
+ WTCP(0x5d90ce45, 0x5758ca31), WTCP(0x5cb420e0, 0x5842dd54),
+ WTCP(0x5bd529eb, 0x592ac2f7), WTCP(0x5af3eee6, 0x5a107561),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow192[] = {
+ WTCP(0x7fffb9d1, 0x00860a79), WTCP(0x7ffd885a, 0x01921d20),
+ WTCP(0x7ff92577, 0x029e28e2), WTCP(0x7ff2913a, 0x03aa292a),
+ WTCP(0x7fe9cbc0, 0x04b6195d), WTCP(0x7fded530, 0x05c1f4e7),
+ WTCP(0x7fd1adb9, 0x06cdb72f), WTCP(0x7fc25596, 0x07d95b9e),
+ WTCP(0x7fb0cd0a, 0x08e4dda0), WTCP(0x7f9d1461, 0x09f0389f),
+ WTCP(0x7f872bf3, 0x0afb6805), WTCP(0x7f6f141f, 0x0c066740),
+ WTCP(0x7f54cd4f, 0x0d1131ba), WTCP(0x7f3857f6, 0x0e1bc2e4),
+ WTCP(0x7f19b491, 0x0f26162a), WTCP(0x7ef8e3a6, 0x103026fe),
+ WTCP(0x7ed5e5c6, 0x1139f0cf), WTCP(0x7eb0bb8a, 0x12436f10),
+ WTCP(0x7e896595, 0x134c9d34), WTCP(0x7e5fe493, 0x145576b1),
+ WTCP(0x7e34393b, 0x155df6fc), WTCP(0x7e06644c, 0x1666198d),
+ WTCP(0x7dd6668f, 0x176dd9de), WTCP(0x7da440d6, 0x1875336a),
+ WTCP(0x7d6ff3fe, 0x197c21ad), WTCP(0x7d3980ec, 0x1a82a026),
+ WTCP(0x7d00e88f, 0x1b88aa55), WTCP(0x7cc62bdf, 0x1c8e3bbe),
+ WTCP(0x7c894bde, 0x1d934fe5), WTCP(0x7c4a4996, 0x1e97e251),
+ WTCP(0x7c09261d, 0x1f9bee8a), WTCP(0x7bc5e290, 0x209f701c),
+ WTCP(0x7b808015, 0x21a26295), WTCP(0x7b38ffde, 0x22a4c185),
+ WTCP(0x7aef6323, 0x23a6887f), WTCP(0x7aa3ab29, 0x24a7b317),
+ WTCP(0x7a55d93a, 0x25a83ce6), WTCP(0x7a05eead, 0x26a82186),
+ WTCP(0x79b3ece0, 0x27a75c95), WTCP(0x795fd53a, 0x28a5e9b4),
+ WTCP(0x7909a92d, 0x29a3c485), WTCP(0x78b16a32, 0x2aa0e8b0),
+ WTCP(0x785719cc, 0x2b9d51dd), WTCP(0x77fab989, 0x2c98fbba),
+ WTCP(0x779c4afc, 0x2d93e1f8), WTCP(0x773bcfc4, 0x2e8e0048),
+ WTCP(0x76d94989, 0x2f875262), WTCP(0x7674b9fa, 0x307fd401),
+ WTCP(0x760e22d1, 0x317780e2), WTCP(0x75a585cf, 0x326e54c7),
+ WTCP(0x753ae4c0, 0x33644b76), WTCP(0x74ce4177, 0x345960b7),
+ WTCP(0x745f9dd1, 0x354d9057), WTCP(0x73eefbb3, 0x3640d627),
+ WTCP(0x737c5d0b, 0x37332dfd), WTCP(0x7307c3d0, 0x382493b0),
+ WTCP(0x72913201, 0x3915031f), WTCP(0x7218a9a7, 0x3a04782a),
+ WTCP(0x719e2cd2, 0x3af2eeb7), WTCP(0x7121bd9c, 0x3be062b0),
+ WTCP(0x70a35e25, 0x3cccd004), WTCP(0x7023109a, 0x3db832a6),
+ WTCP(0x6fa0d72c, 0x3ea2868c), WTCP(0x6f1cb416, 0x3f8bc7b4),
+ WTCP(0x6e96a99d, 0x4073f21d), WTCP(0x6e0eba0c, 0x415b01ce),
+ WTCP(0x6d84e7b7, 0x4240f2d1), WTCP(0x6cf934fc, 0x4325c135),
+ WTCP(0x6c6ba43e, 0x44096910), WTCP(0x6bdc37eb, 0x44ebe679),
+ WTCP(0x6b4af279, 0x45cd358f), WTCP(0x6ab7d663, 0x46ad5278),
+ WTCP(0x6a22e630, 0x478c395a), WTCP(0x698c246c, 0x4869e665),
+ WTCP(0x68f393ae, 0x494655cc), WTCP(0x68593691, 0x4a2183c8),
+ WTCP(0x67bd0fbd, 0x4afb6c98), WTCP(0x671f21dc, 0x4bd40c80),
+ WTCP(0x667f6fa5, 0x4cab5fc9), WTCP(0x65ddfbd3, 0x4d8162c4),
+ WTCP(0x653ac92b, 0x4e5611c5), WTCP(0x6495da79, 0x4f296928),
+ WTCP(0x63ef3290, 0x4ffb654d), WTCP(0x6346d44b, 0x50cc029c),
+ WTCP(0x629cc28c, 0x519b3d80), WTCP(0x61f1003f, 0x5269126e),
+ WTCP(0x61439053, 0x53357ddf), WTCP(0x609475c3, 0x54007c51),
+ WTCP(0x5fe3b38d, 0x54ca0a4b), WTCP(0x5f314cba, 0x55922457),
+ WTCP(0x5e7d4458, 0x5658c709), WTCP(0x5dc79d7c, 0x571deefa),
+ WTCP(0x5d105b44, 0x57e198c7), WTCP(0x5c5780d3, 0x58a3c118),
+ WTCP(0x5b9d1154, 0x59646498), WTCP(0x5ae10ff9, 0x5a237ffa),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow240[] = {
+ WTCP(0x7fffd315, 0x006b3b9b), WTCP(0x7ffe6bbf, 0x0141b1a5),
+ WTCP(0x7ffb9d15, 0x02182427), WTCP(0x7ff76721, 0x02ee90c8),
+ WTCP(0x7ff1c9ef, 0x03c4f52f), WTCP(0x7feac58d, 0x049b4f00),
+ WTCP(0x7fe25a0f, 0x05719be2), WTCP(0x7fd8878e, 0x0647d97c),
+ WTCP(0x7fcd4e24, 0x071e0575), WTCP(0x7fc0adf2, 0x07f41d72),
+ WTCP(0x7fb2a71b, 0x08ca1f1b), WTCP(0x7fa339c5, 0x09a00817),
+ WTCP(0x7f92661d, 0x0a75d60e), WTCP(0x7f802c52, 0x0b4b86a8),
+ WTCP(0x7f6c8c96, 0x0c21178c), WTCP(0x7f578721, 0x0cf68662),
+ WTCP(0x7f411c2f, 0x0dcbd0d5), WTCP(0x7f294bfd, 0x0ea0f48c),
+ WTCP(0x7f1016ce, 0x0f75ef33), WTCP(0x7ef57cea, 0x104abe71),
+ WTCP(0x7ed97e9c, 0x111f5ff4), WTCP(0x7ebc1c31, 0x11f3d164),
+ WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7e7d2c54, 0x139c1abf),
+ WTCP(0x7e5b9f93, 0x146fee03), WTCP(0x7e38b017, 0x154387e6),
+ WTCP(0x7e145e42, 0x1616e618), WTCP(0x7deeaa7a, 0x16ea0646),
+ WTCP(0x7dc79529, 0x17bce621), WTCP(0x7d9f1ebd, 0x188f8357),
+ WTCP(0x7d7547a7, 0x1961db9b), WTCP(0x7d4a105d, 0x1a33ec9c),
+ WTCP(0x7d1d7958, 0x1b05b40f), WTCP(0x7cef8315, 0x1bd72fa4),
+ WTCP(0x7cc02e15, 0x1ca85d12), WTCP(0x7c8f7ade, 0x1d793a0b),
+ WTCP(0x7c5d69f7, 0x1e49c447), WTCP(0x7c29fbee, 0x1f19f97b),
+ WTCP(0x7bf53153, 0x1fe9d75f), WTCP(0x7bbf0aba, 0x20b95bac),
+ WTCP(0x7b8788ba, 0x2188841a), WTCP(0x7b4eabf1, 0x22574e65),
+ WTCP(0x7b1474fd, 0x2325b847), WTCP(0x7ad8e482, 0x23f3bf7e),
+ WTCP(0x7a9bfb27, 0x24c161c7), WTCP(0x7a5db997, 0x258e9ce0),
+ WTCP(0x7a1e2082, 0x265b6e8a), WTCP(0x79dd3098, 0x2727d486),
+ WTCP(0x799aea92, 0x27f3cc94), WTCP(0x79574f28, 0x28bf547b),
+ WTCP(0x79125f19, 0x298a69fc), WTCP(0x78cc1b26, 0x2a550adf),
+ WTCP(0x78848414, 0x2b1f34eb), WTCP(0x783b9aad, 0x2be8e5e8),
+ WTCP(0x77f15fbc, 0x2cb21ba0), WTCP(0x77a5d413, 0x2d7ad3de),
+ WTCP(0x7758f886, 0x2e430c6f), WTCP(0x770acdec, 0x2f0ac320),
+ WTCP(0x76bb5521, 0x2fd1f5c1), WTCP(0x766a8f04, 0x3098a223),
+ WTCP(0x76187c77, 0x315ec617), WTCP(0x75c51e61, 0x32245f72),
+ WTCP(0x757075ac, 0x32e96c09), WTCP(0x751a8346, 0x33ade9b3),
+ WTCP(0x74c34820, 0x3471d647), WTCP(0x746ac52f, 0x35352fa1),
+ WTCP(0x7410fb6b, 0x35f7f39c), WTCP(0x73b5ebd1, 0x36ba2014),
+ WTCP(0x73599760, 0x377bb2e9), WTCP(0x72fbff1b, 0x383ca9fb),
+ WTCP(0x729d2409, 0x38fd032d), WTCP(0x723d0734, 0x39bcbc63),
+ WTCP(0x71dba9ab, 0x3a7bd382), WTCP(0x71790c7e, 0x3b3a4672),
+ WTCP(0x711530c2, 0x3bf8131c), WTCP(0x70b01790, 0x3cb5376b),
+ WTCP(0x7049c203, 0x3d71b14d), WTCP(0x6fe2313c, 0x3e2d7eb1),
+ WTCP(0x6f79665b, 0x3ee89d86), WTCP(0x6f0f6289, 0x3fa30bc1),
+ WTCP(0x6ea426ed, 0x405cc754), WTCP(0x6e37b4b6, 0x4115ce38),
+ WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x6d5b313b, 0x4285b5d4),
+ WTCP(0x6ceb2261, 0x433c9283), WTCP(0x6c79e1c2, 0x43f2b271),
+ WTCP(0x6c07709b, 0x44a8139e), WTCP(0x6b93d02e, 0x455cb40c),
+ WTCP(0x6b1f01c0, 0x461091c2), WTCP(0x6aa90697, 0x46c3aac5),
+ WTCP(0x6a31e000, 0x4775fd1f), WTCP(0x69b98f48, 0x482786dc),
+ WTCP(0x694015c3, 0x48d84609), WTCP(0x68c574c4, 0x498838b6),
+ WTCP(0x6849ada3, 0x4a375cf5), WTCP(0x67ccc1be, 0x4ae5b0da),
+ WTCP(0x674eb271, 0x4b93327c), WTCP(0x66cf8120, 0x4c3fdff4),
+ WTCP(0x664f2f2e, 0x4cebb75c), WTCP(0x65cdbe05, 0x4d96b6d3),
+ WTCP(0x654b2f10, 0x4e40dc79), WTCP(0x64c783bd, 0x4eea2670),
+ WTCP(0x6442bd7e, 0x4f9292dc), WTCP(0x63bcddc7, 0x503a1fe5),
+ WTCP(0x6335e611, 0x50e0cbb4), WTCP(0x62add7d6, 0x51869476),
+ WTCP(0x6224b495, 0x522b7859), WTCP(0x619a7dce, 0x52cf758f),
+ WTCP(0x610f3505, 0x53728a4a), WTCP(0x6082dbc1, 0x5414b4c1),
+ WTCP(0x5ff5738d, 0x54b5f32c), WTCP(0x5f66fdf5, 0x555643c8),
+ WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5e46f0dd, 0x5694148b),
+ WTCP(0x5db55c86, 0x57319135), WTCP(0x5d22c11c, 0x57ce1917),
+ WTCP(0x5c8f203b, 0x5869aa79), WTCP(0x5bfa7b82, 0x590443a7),
+ WTCP(0x5b64d492, 0x599de2ee), WTCP(0x5ace2d0f, 0x5a36869f),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow256[] = {
+ WTCP(0x7fffd886, 0x006487e3), WTCP(0x7ffe9cb2, 0x012d96b1),
+ WTCP(0x7ffc250f, 0x01f6a297), WTCP(0x7ff871a2, 0x02bfa9a4),
+ WTCP(0x7ff38274, 0x0388a9ea), WTCP(0x7fed5791, 0x0451a177),
+ WTCP(0x7fe5f108, 0x051a8e5c), WTCP(0x7fdd4eec, 0x05e36ea9),
+ WTCP(0x7fd37153, 0x06ac406f), WTCP(0x7fc85854, 0x077501be),
+ WTCP(0x7fbc040a, 0x083db0a7), WTCP(0x7fae7495, 0x09064b3a),
+ WTCP(0x7f9faa15, 0x09cecf89), WTCP(0x7f8fa4b0, 0x0a973ba5),
+ WTCP(0x7f7e648c, 0x0b5f8d9f), WTCP(0x7f6be9d4, 0x0c27c389),
+ WTCP(0x7f5834b7, 0x0cefdb76), WTCP(0x7f434563, 0x0db7d376),
+ WTCP(0x7f2d1c0e, 0x0e7fa99e), WTCP(0x7f15b8ee, 0x0f475bff),
+ WTCP(0x7efd1c3c, 0x100ee8ad), WTCP(0x7ee34636, 0x10d64dbd),
+ WTCP(0x7ec8371a, 0x119d8941), WTCP(0x7eabef2c, 0x1264994e),
+ WTCP(0x7e8e6eb2, 0x132b7bf9), WTCP(0x7e6fb5f4, 0x13f22f58),
+ WTCP(0x7e4fc53e, 0x14b8b17f), WTCP(0x7e2e9cdf, 0x157f0086),
+ WTCP(0x7e0c3d29, 0x16451a83), WTCP(0x7de8a670, 0x170afd8d),
+ WTCP(0x7dc3d90d, 0x17d0a7bc), WTCP(0x7d9dd55a, 0x18961728),
+ WTCP(0x7d769bb5, 0x195b49ea), WTCP(0x7d4e2c7f, 0x1a203e1b),
+ WTCP(0x7d24881b, 0x1ae4f1d6), WTCP(0x7cf9aef0, 0x1ba96335),
+ WTCP(0x7ccda169, 0x1c6d9053), WTCP(0x7ca05ff1, 0x1d31774d),
+ WTCP(0x7c71eaf9, 0x1df5163f), WTCP(0x7c4242f2, 0x1eb86b46),
+ WTCP(0x7c116853, 0x1f7b7481), WTCP(0x7bdf5b94, 0x203e300d),
+ WTCP(0x7bac1d31, 0x21009c0c), WTCP(0x7b77ada8, 0x21c2b69c),
+ WTCP(0x7b420d7a, 0x22847de0), WTCP(0x7b0b3d2c, 0x2345eff8),
+ WTCP(0x7ad33d45, 0x24070b08), WTCP(0x7a9a0e50, 0x24c7cd33),
+ WTCP(0x7a5fb0d8, 0x2588349d), WTCP(0x7a24256f, 0x26483f6c),
+ WTCP(0x79e76ca7, 0x2707ebc7), WTCP(0x79a98715, 0x27c737d3),
+ WTCP(0x796a7554, 0x288621b9), WTCP(0x792a37fe, 0x2944a7a2),
+ WTCP(0x78e8cfb2, 0x2a02c7b8), WTCP(0x78a63d11, 0x2ac08026),
+ WTCP(0x786280bf, 0x2b7dcf17), WTCP(0x781d9b65, 0x2c3ab2b9),
+ WTCP(0x77d78daa, 0x2cf72939), WTCP(0x7790583e, 0x2db330c7),
+ WTCP(0x7747fbce, 0x2e6ec792), WTCP(0x76fe790e, 0x2f29ebcc),
+ WTCP(0x76b3d0b4, 0x2fe49ba7), WTCP(0x76680376, 0x309ed556),
+ WTCP(0x761b1211, 0x3158970e), WTCP(0x75ccfd42, 0x3211df04),
+ WTCP(0x757dc5ca, 0x32caab6f), WTCP(0x752d6c6c, 0x3382fa88),
+ WTCP(0x74dbf1ef, 0x343aca87), WTCP(0x7489571c, 0x34f219a8),
+ WTCP(0x74359cbd, 0x35a8e625), WTCP(0x73e0c3a3, 0x365f2e3b),
+ WTCP(0x738acc9e, 0x3714f02a), WTCP(0x7333b883, 0x37ca2a30),
+ WTCP(0x72db8828, 0x387eda8e), WTCP(0x72823c67, 0x3932ff87),
+ WTCP(0x7227d61c, 0x39e6975e), WTCP(0x71cc5626, 0x3a99a057),
+ WTCP(0x716fbd68, 0x3b4c18ba), WTCP(0x71120cc5, 0x3bfdfecd),
+ WTCP(0x70b34525, 0x3caf50da), WTCP(0x70536771, 0x3d600d2c),
+ WTCP(0x6ff27497, 0x3e10320d), WTCP(0x6f906d84, 0x3ebfbdcd),
+ WTCP(0x6f2d532c, 0x3f6eaeb8), WTCP(0x6ec92683, 0x401d0321),
+ WTCP(0x6e63e87f, 0x40cab958), WTCP(0x6dfd9a1c, 0x4177cfb1),
+ WTCP(0x6d963c54, 0x42244481), WTCP(0x6d2dd027, 0x42d0161e),
+ WTCP(0x6cc45698, 0x437b42e1), WTCP(0x6c59d0a9, 0x4425c923),
+ WTCP(0x6bee3f62, 0x44cfa740), WTCP(0x6b81a3cd, 0x4578db93),
+ WTCP(0x6b13fef5, 0x4621647d), WTCP(0x6aa551e9, 0x46c9405c),
+ WTCP(0x6a359db9, 0x47706d93), WTCP(0x69c4e37a, 0x4816ea86),
+ WTCP(0x69532442, 0x48bcb599), WTCP(0x68e06129, 0x4961cd33),
+ WTCP(0x686c9b4b, 0x4a062fbd), WTCP(0x67f7d3c5, 0x4aa9dba2),
+ WTCP(0x67820bb7, 0x4b4ccf4d), WTCP(0x670b4444, 0x4bef092d),
+ WTCP(0x66937e91, 0x4c9087b1), WTCP(0x661abbc5, 0x4d31494b),
+ WTCP(0x65a0fd0b, 0x4dd14c6e), WTCP(0x6526438f, 0x4e708f8f),
+ WTCP(0x64aa907f, 0x4f0f1126), WTCP(0x642de50d, 0x4faccfab),
+ WTCP(0x63b0426d, 0x5049c999), WTCP(0x6331a9d4, 0x50e5fd6d),
+ WTCP(0x62b21c7b, 0x518169a5), WTCP(0x62319b9d, 0x521c0cc2),
+ WTCP(0x61b02876, 0x52b5e546), WTCP(0x612dc447, 0x534ef1b5),
+ WTCP(0x60aa7050, 0x53e73097), WTCP(0x60262dd6, 0x547ea073),
+ WTCP(0x5fa0fe1f, 0x55153fd4), WTCP(0x5f1ae274, 0x55ab0d46),
+ WTCP(0x5e93dc1f, 0x56400758), WTCP(0x5e0bec6e, 0x56d42c99),
+ WTCP(0x5d8314b1, 0x57677b9d), WTCP(0x5cf95638, 0x57f9f2f8),
+ WTCP(0x5c6eb258, 0x588b9140), WTCP(0x5be32a67, 0x591c550e),
+ WTCP(0x5b56bfbd, 0x59ac3cfd), WTCP(0x5ac973b5, 0x5a3b47ab),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow384[] = {
+ WTCP(0x7fffee74, 0x00430546), WTCP(0x7fff6216, 0x00c90f88),
+ WTCP(0x7ffe495b, 0x014f18ee), WTCP(0x7ffca443, 0x01d520e4),
+ WTCP(0x7ffa72d1, 0x025b26d7), WTCP(0x7ff7b507, 0x02e12a36),
+ WTCP(0x7ff46ae8, 0x03672a6c), WTCP(0x7ff09478, 0x03ed26e6),
+ WTCP(0x7fec31ba, 0x04731f13), WTCP(0x7fe742b4, 0x04f9125e),
+ WTCP(0x7fe1c76b, 0x057f0035), WTCP(0x7fdbbfe6, 0x0604e805),
+ WTCP(0x7fd52c29, 0x068ac93b), WTCP(0x7fce0c3e, 0x0710a345),
+ WTCP(0x7fc6602c, 0x0796758f), WTCP(0x7fbe27fa, 0x081c3f87),
+ WTCP(0x7fb563b3, 0x08a2009a), WTCP(0x7fac135f, 0x0927b836),
+ WTCP(0x7fa2370a, 0x09ad65c8), WTCP(0x7f97cebd, 0x0a3308bd),
+ WTCP(0x7f8cda84, 0x0ab8a082), WTCP(0x7f815a6b, 0x0b3e2c86),
+ WTCP(0x7f754e80, 0x0bc3ac35), WTCP(0x7f68b6ce, 0x0c491efe),
+ WTCP(0x7f5b9364, 0x0cce844e), WTCP(0x7f4de451, 0x0d53db92),
+ WTCP(0x7f3fa9a2, 0x0dd92439), WTCP(0x7f30e369, 0x0e5e5db0),
+ WTCP(0x7f2191b4, 0x0ee38766), WTCP(0x7f11b495, 0x0f68a0c8),
+ WTCP(0x7f014c1e, 0x0feda943), WTCP(0x7ef05860, 0x1072a048),
+ WTCP(0x7eded96d, 0x10f78543), WTCP(0x7ecccf5a, 0x117c57a2),
+ WTCP(0x7eba3a39, 0x120116d5), WTCP(0x7ea71a20, 0x1285c249),
+ WTCP(0x7e936f22, 0x130a596e), WTCP(0x7e7f3957, 0x138edbb1),
+ WTCP(0x7e6a78d3, 0x14134881), WTCP(0x7e552dae, 0x14979f4e),
+ WTCP(0x7e3f57ff, 0x151bdf86), WTCP(0x7e28f7de, 0x15a00897),
+ WTCP(0x7e120d63, 0x162419f2), WTCP(0x7dfa98a8, 0x16a81305),
+ WTCP(0x7de299c6, 0x172bf33f), WTCP(0x7dca10d8, 0x17afba11),
+ WTCP(0x7db0fdf8, 0x183366e9), WTCP(0x7d976142, 0x18b6f936),
+ WTCP(0x7d7d3ad3, 0x193a706a), WTCP(0x7d628ac6, 0x19bdcbf3),
+ WTCP(0x7d475139, 0x1a410b41), WTCP(0x7d2b8e4a, 0x1ac42dc5),
+ WTCP(0x7d0f4218, 0x1b4732ef), WTCP(0x7cf26cc1, 0x1bca1a2f),
+ WTCP(0x7cd50e65, 0x1c4ce2f6), WTCP(0x7cb72724, 0x1ccf8cb3),
+ WTCP(0x7c98b71f, 0x1d5216d8), WTCP(0x7c79be78, 0x1dd480d6),
+ WTCP(0x7c5a3d50, 0x1e56ca1e), WTCP(0x7c3a33ca, 0x1ed8f220),
+ WTCP(0x7c19a209, 0x1f5af84f), WTCP(0x7bf88830, 0x1fdcdc1b),
+ WTCP(0x7bd6e665, 0x205e9cf6), WTCP(0x7bb4bccb, 0x20e03a51),
+ WTCP(0x7b920b89, 0x2161b3a0), WTCP(0x7b6ed2c5, 0x21e30853),
+ WTCP(0x7b4b12a4, 0x226437dc), WTCP(0x7b26cb4f, 0x22e541af),
+ WTCP(0x7b01fced, 0x2366253d), WTCP(0x7adca7a6, 0x23e6e1fa),
+ WTCP(0x7ab6cba4, 0x24677758), WTCP(0x7a90690f, 0x24e7e4c9),
+ WTCP(0x7a698012, 0x256829c2), WTCP(0x7a4210d8, 0x25e845b6),
+ WTCP(0x7a1a1b8c, 0x26683818), WTCP(0x79f1a05a, 0x26e8005b),
+ WTCP(0x79c89f6e, 0x27679df4), WTCP(0x799f18f4, 0x27e71057),
+ WTCP(0x79750d1c, 0x286656f8), WTCP(0x794a7c12, 0x28e5714b),
+ WTCP(0x791f6605, 0x29645ec5), WTCP(0x78f3cb25, 0x29e31edb),
+ WTCP(0x78c7aba2, 0x2a61b101), WTCP(0x789b07ab, 0x2ae014ae),
+ WTCP(0x786ddf72, 0x2b5e4956), WTCP(0x78403329, 0x2bdc4e6f),
+ WTCP(0x78120300, 0x2c5a236f), WTCP(0x77e34f2c, 0x2cd7c7cc),
+ WTCP(0x77b417df, 0x2d553afc), WTCP(0x77845d4e, 0x2dd27c75),
+ WTCP(0x77541fab, 0x2e4f8bae), WTCP(0x77235f2d, 0x2ecc681e),
+ WTCP(0x76f21c09, 0x2f49113d), WTCP(0x76c05674, 0x2fc58680),
+ WTCP(0x768e0ea6, 0x3041c761), WTCP(0x765b44d5, 0x30bdd356),
+ WTCP(0x7627f939, 0x3139a9d7), WTCP(0x75f42c0b, 0x31b54a5e),
+ WTCP(0x75bfdd83, 0x3230b461), WTCP(0x758b0ddb, 0x32abe75a),
+ WTCP(0x7555bd4c, 0x3326e2c3), WTCP(0x751fec11, 0x33a1a612),
+ WTCP(0x74e99a65, 0x341c30c4), WTCP(0x74b2c884, 0x34968250),
+ WTCP(0x747b76a9, 0x35109a31), WTCP(0x7443a512, 0x358a77e0),
+ WTCP(0x740b53fb, 0x36041ad9), WTCP(0x73d283a2, 0x367d8296),
+ WTCP(0x73993447, 0x36f6ae91), WTCP(0x735f6626, 0x376f9e46),
+ WTCP(0x73251981, 0x37e85130), WTCP(0x72ea4e96, 0x3860c6cb),
+ WTCP(0x72af05a7, 0x38d8fe93), WTCP(0x72733ef3, 0x3950f804),
+ WTCP(0x7236fabe, 0x39c8b29a), WTCP(0x71fa3949, 0x3a402dd2),
+ WTCP(0x71bcfad6, 0x3ab76929), WTCP(0x717f3fa8, 0x3b2e641c),
+ WTCP(0x71410805, 0x3ba51e29), WTCP(0x7102542f, 0x3c1b96ce),
+ WTCP(0x70c3246b, 0x3c91cd88), WTCP(0x708378ff, 0x3d07c1d6),
+ WTCP(0x70435230, 0x3d7d7337), WTCP(0x7002b045, 0x3df2e129),
+ WTCP(0x6fc19385, 0x3e680b2c), WTCP(0x6f7ffc37, 0x3edcf0c0),
+ WTCP(0x6f3deaa4, 0x3f519164), WTCP(0x6efb5f12, 0x3fc5ec98),
+ WTCP(0x6eb859cc, 0x403a01dc), WTCP(0x6e74db1c, 0x40add0b2),
+ WTCP(0x6e30e34a, 0x4121589b), WTCP(0x6dec72a2, 0x41949917),
+ WTCP(0x6da7896e, 0x420791a8), WTCP(0x6d6227fa, 0x427a41d0),
+ WTCP(0x6d1c4e93, 0x42eca912), WTCP(0x6cd5fd85, 0x435ec6f0),
+ WTCP(0x6c8f351c, 0x43d09aed), WTCP(0x6c47f5a7, 0x4442248b),
+ WTCP(0x6c003f74, 0x44b3634f), WTCP(0x6bb812d1, 0x452456bd),
+ WTCP(0x6b6f700e, 0x4594fe58), WTCP(0x6b265779, 0x460559a4),
+ WTCP(0x6adcc964, 0x46756828), WTCP(0x6a92c61f, 0x46e52967),
+ WTCP(0x6a484dfc, 0x47549ce7), WTCP(0x69fd614a, 0x47c3c22f),
+ WTCP(0x69b2005e, 0x483298c4), WTCP(0x69662b8a, 0x48a1202c),
+ WTCP(0x6919e320, 0x490f57ee), WTCP(0x68cd2775, 0x497d3f93),
+ WTCP(0x687ff8dc, 0x49ead6a0), WTCP(0x683257ab, 0x4a581c9e),
+ WTCP(0x67e44436, 0x4ac51114), WTCP(0x6795bed3, 0x4b31b38d),
+ WTCP(0x6746c7d8, 0x4b9e0390), WTCP(0x66f75f9b, 0x4c0a00a6),
+ WTCP(0x66a78675, 0x4c75aa5a), WTCP(0x66573cbb, 0x4ce10034),
+ WTCP(0x660682c7, 0x4d4c01c0), WTCP(0x65b558f1, 0x4db6ae88),
+ WTCP(0x6563bf92, 0x4e210617), WTCP(0x6511b703, 0x4e8b07f9),
+ WTCP(0x64bf3f9f, 0x4ef4b3b9), WTCP(0x646c59bf, 0x4f5e08e3),
+ WTCP(0x641905bf, 0x4fc70704), WTCP(0x63c543fa, 0x502fada9),
+ WTCP(0x637114cc, 0x5097fc5e), WTCP(0x631c7892, 0x50fff2b2),
+ WTCP(0x62c76fa7, 0x51679033), WTCP(0x6271fa69, 0x51ced46e),
+ WTCP(0x621c1937, 0x5235bef4), WTCP(0x61c5cc6d, 0x529c4f51),
+ WTCP(0x616f146c, 0x53028518), WTCP(0x6117f191, 0x53685fd6),
+ WTCP(0x60c0643d, 0x53cddf1d), WTCP(0x60686ccf, 0x5433027d),
+ WTCP(0x60100ba8, 0x5497c988), WTCP(0x5fb74129, 0x54fc33ce),
+ WTCP(0x5f5e0db3, 0x556040e2), WTCP(0x5f0471a8, 0x55c3f056),
+ WTCP(0x5eaa6d6b, 0x562741bd), WTCP(0x5e50015d, 0x568a34a9),
+ WTCP(0x5df52de3, 0x56ecc8af), WTCP(0x5d99f35f, 0x574efd62),
+ WTCP(0x5d3e5237, 0x57b0d256), WTCP(0x5ce24acd, 0x58124720),
+ WTCP(0x5c85dd88, 0x58735b56), WTCP(0x5c290acc, 0x58d40e8c),
+ WTCP(0x5bcbd300, 0x5934605a), WTCP(0x5b6e3689, 0x59945054),
+ WTCP(0x5b1035cf, 0x59f3de12), WTCP(0x5ab1d138, 0x5a53092c),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow480[] = {
+ WTCP(0x7ffff4c5, 0x00359dd2), WTCP(0x7fff9aef, 0x00a0d951),
+ WTCP(0x7ffee744, 0x010c1460), WTCP(0x7ffdd9c4, 0x01774eb2),
+ WTCP(0x7ffc726f, 0x01e287fc), WTCP(0x7ffab147, 0x024dbff4),
+ WTCP(0x7ff8964d, 0x02b8f64e), WTCP(0x7ff62182, 0x03242abf),
+ WTCP(0x7ff352e8, 0x038f5cfb), WTCP(0x7ff02a82, 0x03fa8cb8),
+ WTCP(0x7feca851, 0x0465b9aa), WTCP(0x7fe8cc57, 0x04d0e386),
+ WTCP(0x7fe49698, 0x053c0a01), WTCP(0x7fe00716, 0x05a72ccf),
+ WTCP(0x7fdb1dd5, 0x06124ba5), WTCP(0x7fd5dad8, 0x067d6639),
+ WTCP(0x7fd03e23, 0x06e87c3f), WTCP(0x7fca47b9, 0x07538d6b),
+ WTCP(0x7fc3f7a0, 0x07be9973), WTCP(0x7fbd4dda, 0x0829a00c),
+ WTCP(0x7fb64a6e, 0x0894a0ea), WTCP(0x7faeed5f, 0x08ff9bc2),
+ WTCP(0x7fa736b4, 0x096a9049), WTCP(0x7f9f2671, 0x09d57e35),
+ WTCP(0x7f96bc9c, 0x0a40653a), WTCP(0x7f8df93c, 0x0aab450d),
+ WTCP(0x7f84dc55, 0x0b161d63), WTCP(0x7f7b65ef, 0x0b80edf1),
+ WTCP(0x7f719611, 0x0bebb66c), WTCP(0x7f676cc0, 0x0c56768a),
+ WTCP(0x7f5cea05, 0x0cc12dff), WTCP(0x7f520de6, 0x0d2bdc80),
+ WTCP(0x7f46d86c, 0x0d9681c2), WTCP(0x7f3b499d, 0x0e011d7c),
+ WTCP(0x7f2f6183, 0x0e6baf61), WTCP(0x7f232026, 0x0ed63727),
+ WTCP(0x7f16858e, 0x0f40b483), WTCP(0x7f0991c4, 0x0fab272b),
+ WTCP(0x7efc44d0, 0x10158ed4), WTCP(0x7eee9ebe, 0x107feb33),
+ WTCP(0x7ee09f95, 0x10ea3bfd), WTCP(0x7ed24761, 0x115480e9),
+ WTCP(0x7ec3962a, 0x11beb9aa), WTCP(0x7eb48bfb, 0x1228e5f8),
+ WTCP(0x7ea528e0, 0x12930586), WTCP(0x7e956ce1, 0x12fd180b),
+ WTCP(0x7e85580c, 0x13671d3d), WTCP(0x7e74ea6a, 0x13d114d0),
+ WTCP(0x7e642408, 0x143afe7b), WTCP(0x7e5304f2, 0x14a4d9f4),
+ WTCP(0x7e418d32, 0x150ea6ef), WTCP(0x7e2fbcd6, 0x15786522),
+ WTCP(0x7e1d93ea, 0x15e21445), WTCP(0x7e0b127a, 0x164bb40b),
+ WTCP(0x7df83895, 0x16b5442b), WTCP(0x7de50646, 0x171ec45c),
+ WTCP(0x7dd17b9c, 0x17883452), WTCP(0x7dbd98a4, 0x17f193c5),
+ WTCP(0x7da95d6c, 0x185ae269), WTCP(0x7d94ca03, 0x18c41ff6),
+ WTCP(0x7d7fde76, 0x192d4c21), WTCP(0x7d6a9ad5, 0x199666a0),
+ WTCP(0x7d54ff2e, 0x19ff6f2a), WTCP(0x7d3f0b90, 0x1a686575),
+ WTCP(0x7d28c00c, 0x1ad14938), WTCP(0x7d121cb0, 0x1b3a1a28),
+ WTCP(0x7cfb218c, 0x1ba2d7fc), WTCP(0x7ce3ceb2, 0x1c0b826a),
+ WTCP(0x7ccc2430, 0x1c74192a), WTCP(0x7cb42217, 0x1cdc9bf2),
+ WTCP(0x7c9bc87a, 0x1d450a78), WTCP(0x7c831767, 0x1dad6473),
+ WTCP(0x7c6a0ef2, 0x1e15a99a), WTCP(0x7c50af2b, 0x1e7dd9a4),
+ WTCP(0x7c36f824, 0x1ee5f447), WTCP(0x7c1ce9ef, 0x1f4df93a),
+ WTCP(0x7c02849f, 0x1fb5e836), WTCP(0x7be7c847, 0x201dc0ef),
+ WTCP(0x7bccb4f8, 0x2085831f), WTCP(0x7bb14ac5, 0x20ed2e7b),
+ WTCP(0x7b9589c3, 0x2154c2bb), WTCP(0x7b797205, 0x21bc3f97),
+ WTCP(0x7b5d039e, 0x2223a4c5), WTCP(0x7b403ea2, 0x228af1fe),
+ WTCP(0x7b232325, 0x22f226f8), WTCP(0x7b05b13d, 0x2359436c),
+ WTCP(0x7ae7e8fc, 0x23c04710), WTCP(0x7ac9ca7a, 0x2427319d),
+ WTCP(0x7aab55ca, 0x248e02cb), WTCP(0x7a8c8b01, 0x24f4ba50),
+ WTCP(0x7a6d6a37, 0x255b57e6), WTCP(0x7a4df380, 0x25c1db44),
+ WTCP(0x7a2e26f2, 0x26284422), WTCP(0x7a0e04a4, 0x268e9238),
+ WTCP(0x79ed8cad, 0x26f4c53e), WTCP(0x79ccbf22, 0x275adcee),
+ WTCP(0x79ab9c1c, 0x27c0d8fe), WTCP(0x798a23b1, 0x2826b928),
+ WTCP(0x796855f9, 0x288c7d24), WTCP(0x7946330c, 0x28f224ab),
+ WTCP(0x7923bb01, 0x2957af74), WTCP(0x7900edf2, 0x29bd1d3a),
+ WTCP(0x78ddcbf5, 0x2a226db5), WTCP(0x78ba5524, 0x2a87a09d),
+ WTCP(0x78968998, 0x2aecb5ac), WTCP(0x7872696a, 0x2b51ac9a),
+ WTCP(0x784df4b3, 0x2bb68522), WTCP(0x78292b8d, 0x2c1b3efb),
+ WTCP(0x78040e12, 0x2c7fd9e0), WTCP(0x77de9c5b, 0x2ce45589),
+ WTCP(0x77b8d683, 0x2d48b1b1), WTCP(0x7792bca5, 0x2dacee11),
+ WTCP(0x776c4edb, 0x2e110a62), WTCP(0x77458d40, 0x2e75065e),
+ WTCP(0x771e77f0, 0x2ed8e1c0), WTCP(0x76f70f05, 0x2f3c9c40),
+ WTCP(0x76cf529c, 0x2fa03599), WTCP(0x76a742d1, 0x3003ad85),
+ WTCP(0x767edfbe, 0x306703bf), WTCP(0x76562982, 0x30ca3800),
+ WTCP(0x762d2038, 0x312d4a03), WTCP(0x7603c3fd, 0x31903982),
+ WTCP(0x75da14ef, 0x31f30638), WTCP(0x75b01329, 0x3255afe0),
+ WTCP(0x7585becb, 0x32b83634), WTCP(0x755b17f2, 0x331a98ef),
+ WTCP(0x75301ebb, 0x337cd7cd), WTCP(0x7504d345, 0x33def287),
+ WTCP(0x74d935ae, 0x3440e8da), WTCP(0x74ad4615, 0x34a2ba81),
+ WTCP(0x74810499, 0x35046736), WTCP(0x74547158, 0x3565eeb6),
+ WTCP(0x74278c72, 0x35c750bc), WTCP(0x73fa5607, 0x36288d03),
+ WTCP(0x73ccce36, 0x3689a348), WTCP(0x739ef51f, 0x36ea9346),
+ WTCP(0x7370cae2, 0x374b5cb9), WTCP(0x73424fa0, 0x37abff5d),
+ WTCP(0x73138379, 0x380c7aee), WTCP(0x72e4668f, 0x386ccf2a),
+ WTCP(0x72b4f902, 0x38ccfbcb), WTCP(0x72853af3, 0x392d008f),
+ WTCP(0x72552c85, 0x398cdd32), WTCP(0x7224cdd8, 0x39ec9172),
+ WTCP(0x71f41f0f, 0x3a4c1d09), WTCP(0x71c3204c, 0x3aab7fb7),
+ WTCP(0x7191d1b1, 0x3b0ab937), WTCP(0x71603361, 0x3b69c947),
+ WTCP(0x712e457f, 0x3bc8afa5), WTCP(0x70fc082d, 0x3c276c0d),
+ WTCP(0x70c97b90, 0x3c85fe3d), WTCP(0x70969fca, 0x3ce465f3),
+ WTCP(0x706374ff, 0x3d42a2ec), WTCP(0x702ffb54, 0x3da0b4e7),
+ WTCP(0x6ffc32eb, 0x3dfe9ba1), WTCP(0x6fc81bea, 0x3e5c56d8),
+ WTCP(0x6f93b676, 0x3eb9e64b), WTCP(0x6f5f02b2, 0x3f1749b8),
+ WTCP(0x6f2a00c4, 0x3f7480dd), WTCP(0x6ef4b0d1, 0x3fd18b7a),
+ WTCP(0x6ebf12ff, 0x402e694c), WTCP(0x6e892772, 0x408b1a12),
+ WTCP(0x6e52ee52, 0x40e79d8c), WTCP(0x6e1c67c4, 0x4143f379),
+ WTCP(0x6de593ee, 0x41a01b97), WTCP(0x6dae72f7, 0x41fc15a6),
+ WTCP(0x6d770506, 0x4257e166), WTCP(0x6d3f4a40, 0x42b37e96),
+ WTCP(0x6d0742cf, 0x430eecf6), WTCP(0x6cceeed8, 0x436a2c45),
+ WTCP(0x6c964e83, 0x43c53c44), WTCP(0x6c5d61f9, 0x44201cb2),
+ WTCP(0x6c242960, 0x447acd50), WTCP(0x6beaa4e2, 0x44d54ddf),
+ WTCP(0x6bb0d4a7, 0x452f9e1e), WTCP(0x6b76b8d6, 0x4589bdcf),
+ WTCP(0x6b3c519a, 0x45e3acb1), WTCP(0x6b019f1a, 0x463d6a87),
+ WTCP(0x6ac6a180, 0x4696f710), WTCP(0x6a8b58f6, 0x46f0520f),
+ WTCP(0x6a4fc5a6, 0x47497b44), WTCP(0x6a13e7b8, 0x47a27271),
+ WTCP(0x69d7bf57, 0x47fb3757), WTCP(0x699b4cad, 0x4853c9b9),
+ WTCP(0x695e8fe5, 0x48ac2957), WTCP(0x69218929, 0x490455f4),
+ WTCP(0x68e438a4, 0x495c4f52), WTCP(0x68a69e81, 0x49b41533),
+ WTCP(0x6868baec, 0x4a0ba75b), WTCP(0x682a8e0f, 0x4a63058a),
+ WTCP(0x67ec1817, 0x4aba2f84), WTCP(0x67ad592f, 0x4b11250c),
+ WTCP(0x676e5183, 0x4b67e5e4), WTCP(0x672f013f, 0x4bbe71d1),
+ WTCP(0x66ef6891, 0x4c14c894), WTCP(0x66af87a4, 0x4c6ae9f2),
+ WTCP(0x666f5ea6, 0x4cc0d5ae), WTCP(0x662eedc3, 0x4d168b8b),
+ WTCP(0x65ee3529, 0x4d6c0b4e), WTCP(0x65ad3505, 0x4dc154bb),
+ WTCP(0x656bed84, 0x4e166795), WTCP(0x652a5ed6, 0x4e6b43a2),
+ WTCP(0x64e88926, 0x4ebfe8a5), WTCP(0x64a66ca5, 0x4f145662),
+ WTCP(0x6464097f, 0x4f688ca0), WTCP(0x64215fe5, 0x4fbc8b22),
+ WTCP(0x63de7003, 0x501051ae), WTCP(0x639b3a0b, 0x5063e008),
+ WTCP(0x6357be2a, 0x50b735f8), WTCP(0x6313fc90, 0x510a5340),
+ WTCP(0x62cff56c, 0x515d37a9), WTCP(0x628ba8ef, 0x51afe2f6),
+ WTCP(0x62471749, 0x520254ef), WTCP(0x620240a8, 0x52548d59),
+ WTCP(0x61bd253f, 0x52a68bfb), WTCP(0x6177c53c, 0x52f8509b),
+ WTCP(0x613220d2, 0x5349daff), WTCP(0x60ec3830, 0x539b2af0),
+ WTCP(0x60a60b88, 0x53ec4032), WTCP(0x605f9b0b, 0x543d1a8e),
+ WTCP(0x6018e6eb, 0x548db9cb), WTCP(0x5fd1ef59, 0x54de1db1),
+ WTCP(0x5f8ab487, 0x552e4605), WTCP(0x5f4336a7, 0x557e3292),
+ WTCP(0x5efb75ea, 0x55cde31e), WTCP(0x5eb37285, 0x561d5771),
+ WTCP(0x5e6b2ca8, 0x566c8f55), WTCP(0x5e22a487, 0x56bb8a90),
+ WTCP(0x5dd9da55, 0x570a48ec), WTCP(0x5d90ce45, 0x5758ca31),
+ WTCP(0x5d47808a, 0x57a70e29), WTCP(0x5cfdf157, 0x57f5149d),
+ WTCP(0x5cb420e0, 0x5842dd54), WTCP(0x5c6a0f59, 0x5890681a),
+ WTCP(0x5c1fbcf6, 0x58ddb4b8), WTCP(0x5bd529eb, 0x592ac2f7),
+ WTCP(0x5b8a566c, 0x597792a1), WTCP(0x5b3f42ae, 0x59c42381),
+ WTCP(0x5af3eee6, 0x5a107561), WTCP(0x5aa85b48, 0x5a5c880a),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow512[] = {
+ WTCP(0x7ffff621, 0x003243f5), WTCP(0x7fffa72c, 0x0096cbc1),
+ WTCP(0x7fff0943, 0x00fb5330), WTCP(0x7ffe1c65, 0x015fda03),
+ WTCP(0x7ffce093, 0x01c45ffe), WTCP(0x7ffb55ce, 0x0228e4e2),
+ WTCP(0x7ff97c18, 0x028d6870), WTCP(0x7ff75370, 0x02f1ea6c),
+ WTCP(0x7ff4dbd9, 0x03566a96), WTCP(0x7ff21553, 0x03bae8b2),
+ WTCP(0x7feeffe1, 0x041f6480), WTCP(0x7feb9b85, 0x0483ddc3),
+ WTCP(0x7fe7e841, 0x04e8543e), WTCP(0x7fe3e616, 0x054cc7b1),
+ WTCP(0x7fdf9508, 0x05b137df), WTCP(0x7fdaf519, 0x0615a48b),
+ WTCP(0x7fd6064c, 0x067a0d76), WTCP(0x7fd0c8a3, 0x06de7262),
+ WTCP(0x7fcb3c23, 0x0742d311), WTCP(0x7fc560cf, 0x07a72f45),
+ WTCP(0x7fbf36aa, 0x080b86c2), WTCP(0x7fb8bdb8, 0x086fd947),
+ WTCP(0x7fb1f5fc, 0x08d42699), WTCP(0x7faadf7c, 0x09386e78),
+ WTCP(0x7fa37a3c, 0x099cb0a7), WTCP(0x7f9bc640, 0x0a00ece8),
+ WTCP(0x7f93c38c, 0x0a6522fe), WTCP(0x7f8b7227, 0x0ac952aa),
+ WTCP(0x7f82d214, 0x0b2d7baf), WTCP(0x7f79e35a, 0x0b919dcf),
+ WTCP(0x7f70a5fe, 0x0bf5b8cb), WTCP(0x7f671a05, 0x0c59cc68),
+ WTCP(0x7f5d3f75, 0x0cbdd865), WTCP(0x7f531655, 0x0d21dc87),
+ WTCP(0x7f489eaa, 0x0d85d88f), WTCP(0x7f3dd87c, 0x0de9cc40),
+ WTCP(0x7f32c3d1, 0x0e4db75b), WTCP(0x7f2760af, 0x0eb199a4),
+ WTCP(0x7f1baf1e, 0x0f1572dc), WTCP(0x7f0faf25, 0x0f7942c7),
+ WTCP(0x7f0360cb, 0x0fdd0926), WTCP(0x7ef6c418, 0x1040c5bb),
+ WTCP(0x7ee9d914, 0x10a4784b), WTCP(0x7edc9fc6, 0x11082096),
+ WTCP(0x7ecf1837, 0x116bbe60), WTCP(0x7ec14270, 0x11cf516a),
+ WTCP(0x7eb31e78, 0x1232d979), WTCP(0x7ea4ac58, 0x1296564d),
+ WTCP(0x7e95ec1a, 0x12f9c7aa), WTCP(0x7e86ddc6, 0x135d2d53),
+ WTCP(0x7e778166, 0x13c0870a), WTCP(0x7e67d703, 0x1423d492),
+ WTCP(0x7e57dea7, 0x148715ae), WTCP(0x7e47985b, 0x14ea4a1f),
+ WTCP(0x7e37042a, 0x154d71aa), WTCP(0x7e26221f, 0x15b08c12),
+ WTCP(0x7e14f242, 0x16139918), WTCP(0x7e0374a0, 0x1676987f),
+ WTCP(0x7df1a942, 0x16d98a0c), WTCP(0x7ddf9034, 0x173c6d80),
+ WTCP(0x7dcd2981, 0x179f429f), WTCP(0x7dba7534, 0x1802092c),
+ WTCP(0x7da77359, 0x1864c0ea), WTCP(0x7d9423fc, 0x18c7699b),
+ WTCP(0x7d808728, 0x192a0304), WTCP(0x7d6c9ce9, 0x198c8ce7),
+ WTCP(0x7d58654d, 0x19ef0707), WTCP(0x7d43e05e, 0x1a517128),
+ WTCP(0x7d2f0e2b, 0x1ab3cb0d), WTCP(0x7d19eebf, 0x1b161479),
+ WTCP(0x7d048228, 0x1b784d30), WTCP(0x7ceec873, 0x1bda74f6),
+ WTCP(0x7cd8c1ae, 0x1c3c8b8c), WTCP(0x7cc26de5, 0x1c9e90b8),
+ WTCP(0x7cabcd28, 0x1d00843d), WTCP(0x7c94df83, 0x1d6265dd),
+ WTCP(0x7c7da505, 0x1dc4355e), WTCP(0x7c661dbc, 0x1e25f282),
+ WTCP(0x7c4e49b7, 0x1e879d0d), WTCP(0x7c362904, 0x1ee934c3),
+ WTCP(0x7c1dbbb3, 0x1f4ab968), WTCP(0x7c0501d2, 0x1fac2abf),
+ WTCP(0x7bebfb70, 0x200d888d), WTCP(0x7bd2a89e, 0x206ed295),
+ WTCP(0x7bb9096b, 0x20d0089c), WTCP(0x7b9f1de6, 0x21312a65),
+ WTCP(0x7b84e61f, 0x219237b5), WTCP(0x7b6a6227, 0x21f3304f),
+ WTCP(0x7b4f920e, 0x225413f8), WTCP(0x7b3475e5, 0x22b4e274),
+ WTCP(0x7b190dbc, 0x23159b88), WTCP(0x7afd59a4, 0x23763ef7),
+ WTCP(0x7ae159ae, 0x23d6cc87), WTCP(0x7ac50dec, 0x243743fa),
+ WTCP(0x7aa8766f, 0x2497a517), WTCP(0x7a8b9348, 0x24f7efa2),
+ WTCP(0x7a6e648a, 0x2558235f), WTCP(0x7a50ea47, 0x25b84012),
+ WTCP(0x7a332490, 0x26184581), WTCP(0x7a151378, 0x26783370),
+ WTCP(0x79f6b711, 0x26d809a5), WTCP(0x79d80f6f, 0x2737c7e3),
+ WTCP(0x79b91ca4, 0x27976df1), WTCP(0x7999dec4, 0x27f6fb92),
+ WTCP(0x797a55e0, 0x2856708d), WTCP(0x795a820e, 0x28b5cca5),
+ WTCP(0x793a6361, 0x29150fa1), WTCP(0x7919f9ec, 0x29743946),
+ WTCP(0x78f945c3, 0x29d34958), WTCP(0x78d846fb, 0x2a323f9e),
+ WTCP(0x78b6fda8, 0x2a911bdc), WTCP(0x789569df, 0x2aefddd8),
+ WTCP(0x78738bb3, 0x2b4e8558), WTCP(0x7851633b, 0x2bad1221),
+ WTCP(0x782ef08b, 0x2c0b83fa), WTCP(0x780c33b8, 0x2c69daa6),
+ WTCP(0x77e92cd9, 0x2cc815ee), WTCP(0x77c5dc01, 0x2d263596),
+ WTCP(0x77a24148, 0x2d843964), WTCP(0x777e5cc3, 0x2de2211e),
+ WTCP(0x775a2e89, 0x2e3fec8b), WTCP(0x7735b6af, 0x2e9d9b70),
+ WTCP(0x7710f54c, 0x2efb2d95), WTCP(0x76ebea77, 0x2f58a2be),
+ WTCP(0x76c69647, 0x2fb5fab2), WTCP(0x76a0f8d2, 0x30133539),
+ WTCP(0x767b1231, 0x30705217), WTCP(0x7654e279, 0x30cd5115),
+ WTCP(0x762e69c4, 0x312a31f8), WTCP(0x7607a828, 0x3186f487),
+ WTCP(0x75e09dbd, 0x31e39889), WTCP(0x75b94a9c, 0x32401dc6),
+ WTCP(0x7591aedd, 0x329c8402), WTCP(0x7569ca99, 0x32f8cb07),
+ WTCP(0x75419de7, 0x3354f29b), WTCP(0x751928e0, 0x33b0fa84),
+ WTCP(0x74f06b9e, 0x340ce28b), WTCP(0x74c7663a, 0x3468aa76),
+ WTCP(0x749e18cd, 0x34c4520d), WTCP(0x74748371, 0x351fd918),
+ WTCP(0x744aa63f, 0x357b3f5d), WTCP(0x74208150, 0x35d684a6),
+ WTCP(0x73f614c0, 0x3631a8b8), WTCP(0x73cb60a8, 0x368cab5c),
+ WTCP(0x73a06522, 0x36e78c5b), WTCP(0x73752249, 0x37424b7b),
+ WTCP(0x73499838, 0x379ce885), WTCP(0x731dc70a, 0x37f76341),
+ WTCP(0x72f1aed9, 0x3851bb77), WTCP(0x72c54fc1, 0x38abf0ef),
+ WTCP(0x7298a9dd, 0x39060373), WTCP(0x726bbd48, 0x395ff2c9),
+ WTCP(0x723e8a20, 0x39b9bebc), WTCP(0x7211107e, 0x3a136712),
+ WTCP(0x71e35080, 0x3a6ceb96), WTCP(0x71b54a41, 0x3ac64c0f),
+ WTCP(0x7186fdde, 0x3b1f8848), WTCP(0x71586b74, 0x3b78a007),
+ WTCP(0x7129931f, 0x3bd19318), WTCP(0x70fa74fc, 0x3c2a6142),
+ WTCP(0x70cb1128, 0x3c830a50), WTCP(0x709b67c0, 0x3cdb8e09),
+ WTCP(0x706b78e3, 0x3d33ec39), WTCP(0x703b44ad, 0x3d8c24a8),
+ WTCP(0x700acb3c, 0x3de4371f), WTCP(0x6fda0cae, 0x3e3c2369),
+ WTCP(0x6fa90921, 0x3e93e950), WTCP(0x6f77c0b3, 0x3eeb889c),
+ WTCP(0x6f463383, 0x3f430119), WTCP(0x6f1461b0, 0x3f9a5290),
+ WTCP(0x6ee24b57, 0x3ff17cca), WTCP(0x6eaff099, 0x40487f94),
+ WTCP(0x6e7d5193, 0x409f5ab6), WTCP(0x6e4a6e66, 0x40f60dfb),
+ WTCP(0x6e174730, 0x414c992f), WTCP(0x6de3dc11, 0x41a2fc1a),
+ WTCP(0x6db02d29, 0x41f93689), WTCP(0x6d7c3a98, 0x424f4845),
+ WTCP(0x6d48047e, 0x42a5311b), WTCP(0x6d138afb, 0x42faf0d4),
+ WTCP(0x6cdece2f, 0x4350873c), WTCP(0x6ca9ce3b, 0x43a5f41e),
+ WTCP(0x6c748b3f, 0x43fb3746), WTCP(0x6c3f055d, 0x4450507e),
+ WTCP(0x6c093cb6, 0x44a53f93), WTCP(0x6bd3316a, 0x44fa0450),
+ WTCP(0x6b9ce39b, 0x454e9e80), WTCP(0x6b66536b, 0x45a30df0),
+ WTCP(0x6b2f80fb, 0x45f7526b), WTCP(0x6af86c6c, 0x464b6bbe),
+ WTCP(0x6ac115e2, 0x469f59b4), WTCP(0x6a897d7d, 0x46f31c1a),
+ WTCP(0x6a51a361, 0x4746b2bc), WTCP(0x6a1987b0, 0x479a1d67),
+ WTCP(0x69e12a8c, 0x47ed5be6), WTCP(0x69a88c19, 0x48406e08),
+ WTCP(0x696fac78, 0x48935397), WTCP(0x69368bce, 0x48e60c62),
+ WTCP(0x68fd2a3d, 0x49389836), WTCP(0x68c387e9, 0x498af6df),
+ WTCP(0x6889a4f6, 0x49dd282a), WTCP(0x684f8186, 0x4a2f2be6),
+ WTCP(0x68151dbe, 0x4a8101de), WTCP(0x67da79c3, 0x4ad2a9e2),
+ WTCP(0x679f95b7, 0x4b2423be), WTCP(0x676471c0, 0x4b756f40),
+ WTCP(0x67290e02, 0x4bc68c36), WTCP(0x66ed6aa1, 0x4c177a6e),
+ WTCP(0x66b187c3, 0x4c6839b7), WTCP(0x6675658c, 0x4cb8c9dd),
+ WTCP(0x66390422, 0x4d092ab0), WTCP(0x65fc63a9, 0x4d595bfe),
+ WTCP(0x65bf8447, 0x4da95d96), WTCP(0x65826622, 0x4df92f46),
+ WTCP(0x6545095f, 0x4e48d0dd), WTCP(0x65076e25, 0x4e984229),
+ WTCP(0x64c99498, 0x4ee782fb), WTCP(0x648b7ce0, 0x4f369320),
+ WTCP(0x644d2722, 0x4f857269), WTCP(0x640e9386, 0x4fd420a4),
+ WTCP(0x63cfc231, 0x50229da1), WTCP(0x6390b34a, 0x5070e92f),
+ WTCP(0x635166f9, 0x50bf031f), WTCP(0x6311dd64, 0x510ceb40),
+ WTCP(0x62d216b3, 0x515aa162), WTCP(0x6292130c, 0x51a82555),
+ WTCP(0x6251d298, 0x51f576ea), WTCP(0x6211557e, 0x524295f0),
+ WTCP(0x61d09be5, 0x528f8238), WTCP(0x618fa5f7, 0x52dc3b92),
+ WTCP(0x614e73da, 0x5328c1d0), WTCP(0x610d05b7, 0x537514c2),
+ WTCP(0x60cb5bb7, 0x53c13439), WTCP(0x60897601, 0x540d2005),
+ WTCP(0x604754bf, 0x5458d7f9), WTCP(0x6004f819, 0x54a45be6),
+ WTCP(0x5fc26038, 0x54efab9c), WTCP(0x5f7f8d46, 0x553ac6ee),
+ WTCP(0x5f3c7f6b, 0x5585adad), WTCP(0x5ef936d1, 0x55d05faa),
+ WTCP(0x5eb5b3a2, 0x561adcb9), WTCP(0x5e71f606, 0x566524aa),
+ WTCP(0x5e2dfe29, 0x56af3750), WTCP(0x5de9cc33, 0x56f9147e),
+ WTCP(0x5da5604f, 0x5742bc06), WTCP(0x5d60baa7, 0x578c2dba),
+ WTCP(0x5d1bdb65, 0x57d5696d), WTCP(0x5cd6c2b5, 0x581e6ef1),
+ WTCP(0x5c9170bf, 0x58673e1b), WTCP(0x5c4be5b0, 0x58afd6bd),
+ WTCP(0x5c0621b2, 0x58f838a9), WTCP(0x5bc024f0, 0x594063b5),
+ WTCP(0x5b79ef96, 0x598857b2), WTCP(0x5b3381ce, 0x59d01475),
+ WTCP(0x5aecdbc5, 0x5a1799d1), WTCP(0x5aa5fda5, 0x5a5ee79a),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow768[] = {
+ WTCP(0x7ffffb9d, 0x002182a4), WTCP(0x7fffd886, 0x006487e3),
+ WTCP(0x7fff9257, 0x00a78d06), WTCP(0x7fff2910, 0x00ea91fc),
+ WTCP(0x7ffe9cb2, 0x012d96b1), WTCP(0x7ffded3d, 0x01709b13),
+ WTCP(0x7ffd1ab2, 0x01b39f11), WTCP(0x7ffc250f, 0x01f6a297),
+ WTCP(0x7ffb0c56, 0x0239a593), WTCP(0x7ff9d087, 0x027ca7f3),
+ WTCP(0x7ff871a2, 0x02bfa9a4), WTCP(0x7ff6efa7, 0x0302aa95),
+ WTCP(0x7ff54a98, 0x0345aab2), WTCP(0x7ff38274, 0x0388a9ea),
+ WTCP(0x7ff1973b, 0x03cba829), WTCP(0x7fef88ef, 0x040ea55e),
+ WTCP(0x7fed5791, 0x0451a177), WTCP(0x7feb031f, 0x04949c60),
+ WTCP(0x7fe88b9c, 0x04d79608), WTCP(0x7fe5f108, 0x051a8e5c),
+ WTCP(0x7fe33364, 0x055d854a), WTCP(0x7fe052af, 0x05a07abf),
+ WTCP(0x7fdd4eec, 0x05e36ea9), WTCP(0x7fda281b, 0x062660f6),
+ WTCP(0x7fd6de3d, 0x06695194), WTCP(0x7fd37153, 0x06ac406f),
+ WTCP(0x7fcfe15d, 0x06ef2d76), WTCP(0x7fcc2e5d, 0x07321897),
+ WTCP(0x7fc85854, 0x077501be), WTCP(0x7fc45f42, 0x07b7e8da),
+ WTCP(0x7fc04329, 0x07facdd9), WTCP(0x7fbc040a, 0x083db0a7),
+ WTCP(0x7fb7a1e6, 0x08809133), WTCP(0x7fb31cbf, 0x08c36f6a),
+ WTCP(0x7fae7495, 0x09064b3a), WTCP(0x7fa9a96a, 0x09492491),
+ WTCP(0x7fa4bb3f, 0x098bfb5c), WTCP(0x7f9faa15, 0x09cecf89),
+ WTCP(0x7f9a75ef, 0x0a11a106), WTCP(0x7f951ecc, 0x0a546fc0),
+ WTCP(0x7f8fa4b0, 0x0a973ba5), WTCP(0x7f8a079a, 0x0ada04a3),
+ WTCP(0x7f84478e, 0x0b1ccaa7), WTCP(0x7f7e648c, 0x0b5f8d9f),
+ WTCP(0x7f785e96, 0x0ba24d79), WTCP(0x7f7235ad, 0x0be50a23),
+ WTCP(0x7f6be9d4, 0x0c27c389), WTCP(0x7f657b0c, 0x0c6a799b),
+ WTCP(0x7f5ee957, 0x0cad2c45), WTCP(0x7f5834b7, 0x0cefdb76),
+ WTCP(0x7f515d2d, 0x0d32871a), WTCP(0x7f4a62bb, 0x0d752f20),
+ WTCP(0x7f434563, 0x0db7d376), WTCP(0x7f3c0528, 0x0dfa7409),
+ WTCP(0x7f34a20b, 0x0e3d10c7), WTCP(0x7f2d1c0e, 0x0e7fa99e),
+ WTCP(0x7f257334, 0x0ec23e7b), WTCP(0x7f1da77e, 0x0f04cf4c),
+ WTCP(0x7f15b8ee, 0x0f475bff), WTCP(0x7f0da787, 0x0f89e482),
+ WTCP(0x7f05734b, 0x0fcc68c2), WTCP(0x7efd1c3c, 0x100ee8ad),
+ WTCP(0x7ef4a25d, 0x10516432), WTCP(0x7eec05af, 0x1093db3d),
+ WTCP(0x7ee34636, 0x10d64dbd), WTCP(0x7eda63f3, 0x1118bb9f),
+ WTCP(0x7ed15ee9, 0x115b24d1), WTCP(0x7ec8371a, 0x119d8941),
+ WTCP(0x7ebeec89, 0x11dfe8dc), WTCP(0x7eb57f39, 0x12224392),
+ WTCP(0x7eabef2c, 0x1264994e), WTCP(0x7ea23c65, 0x12a6ea00),
+ WTCP(0x7e9866e6, 0x12e93594), WTCP(0x7e8e6eb2, 0x132b7bf9),
+ WTCP(0x7e8453cc, 0x136dbd1d), WTCP(0x7e7a1636, 0x13aff8ed),
+ WTCP(0x7e6fb5f4, 0x13f22f58), WTCP(0x7e653308, 0x1434604a),
+ WTCP(0x7e5a8d75, 0x14768bb3), WTCP(0x7e4fc53e, 0x14b8b17f),
+ WTCP(0x7e44da66, 0x14fad19e), WTCP(0x7e39ccf0, 0x153cebfb),
+ WTCP(0x7e2e9cdf, 0x157f0086), WTCP(0x7e234a36, 0x15c10f2d),
+ WTCP(0x7e17d4f8, 0x160317dc), WTCP(0x7e0c3d29, 0x16451a83),
+ WTCP(0x7e0082cb, 0x1687170f), WTCP(0x7df4a5e2, 0x16c90d6e),
+ WTCP(0x7de8a670, 0x170afd8d), WTCP(0x7ddc847a, 0x174ce75b),
+ WTCP(0x7dd04003, 0x178ecac6), WTCP(0x7dc3d90d, 0x17d0a7bc),
+ WTCP(0x7db74f9d, 0x18127e2a), WTCP(0x7daaa3b5, 0x18544dff),
+ WTCP(0x7d9dd55a, 0x18961728), WTCP(0x7d90e48f, 0x18d7d993),
+ WTCP(0x7d83d156, 0x1919952f), WTCP(0x7d769bb5, 0x195b49ea),
+ WTCP(0x7d6943ae, 0x199cf7b0), WTCP(0x7d5bc946, 0x19de9e72),
+ WTCP(0x7d4e2c7f, 0x1a203e1b), WTCP(0x7d406d5e, 0x1a61d69b),
+ WTCP(0x7d328be6, 0x1aa367df), WTCP(0x7d24881b, 0x1ae4f1d6),
+ WTCP(0x7d166201, 0x1b26746d), WTCP(0x7d08199c, 0x1b67ef93),
+ WTCP(0x7cf9aef0, 0x1ba96335), WTCP(0x7ceb2201, 0x1beacf42),
+ WTCP(0x7cdc72d3, 0x1c2c33a7), WTCP(0x7ccda169, 0x1c6d9053),
+ WTCP(0x7cbeadc8, 0x1caee534), WTCP(0x7caf97f4, 0x1cf03238),
+ WTCP(0x7ca05ff1, 0x1d31774d), WTCP(0x7c9105c3, 0x1d72b461),
+ WTCP(0x7c81896f, 0x1db3e962), WTCP(0x7c71eaf9, 0x1df5163f),
+ WTCP(0x7c622a64, 0x1e363ae5), WTCP(0x7c5247b6, 0x1e775743),
+ WTCP(0x7c4242f2, 0x1eb86b46), WTCP(0x7c321c1e, 0x1ef976de),
+ WTCP(0x7c21d33c, 0x1f3a79f7), WTCP(0x7c116853, 0x1f7b7481),
+ WTCP(0x7c00db66, 0x1fbc6669), WTCP(0x7bf02c7b, 0x1ffd4f9e),
+ WTCP(0x7bdf5b94, 0x203e300d), WTCP(0x7bce68b8, 0x207f07a6),
+ WTCP(0x7bbd53eb, 0x20bfd656), WTCP(0x7bac1d31, 0x21009c0c),
+ WTCP(0x7b9ac490, 0x214158b5), WTCP(0x7b894a0b, 0x21820c41),
+ WTCP(0x7b77ada8, 0x21c2b69c), WTCP(0x7b65ef6c, 0x220357b6),
+ WTCP(0x7b540f5b, 0x2243ef7d), WTCP(0x7b420d7a, 0x22847de0),
+ WTCP(0x7b2fe9cf, 0x22c502cb), WTCP(0x7b1da45e, 0x23057e2e),
+ WTCP(0x7b0b3d2c, 0x2345eff8), WTCP(0x7af8b43f, 0x23865816),
+ WTCP(0x7ae6099b, 0x23c6b676), WTCP(0x7ad33d45, 0x24070b08),
+ WTCP(0x7ac04f44, 0x244755b9), WTCP(0x7aad3f9b, 0x24879678),
+ WTCP(0x7a9a0e50, 0x24c7cd33), WTCP(0x7a86bb68, 0x2507f9d8),
+ WTCP(0x7a7346e9, 0x25481c57), WTCP(0x7a5fb0d8, 0x2588349d),
+ WTCP(0x7a4bf93a, 0x25c84299), WTCP(0x7a382015, 0x26084639),
+ WTCP(0x7a24256f, 0x26483f6c), WTCP(0x7a10094c, 0x26882e21),
+ WTCP(0x79fbcbb2, 0x26c81245), WTCP(0x79e76ca7, 0x2707ebc7),
+ WTCP(0x79d2ec30, 0x2747ba95), WTCP(0x79be4a53, 0x27877e9f),
+ WTCP(0x79a98715, 0x27c737d3), WTCP(0x7994a27d, 0x2806e61f),
+ WTCP(0x797f9c90, 0x28468971), WTCP(0x796a7554, 0x288621b9),
+ WTCP(0x79552cce, 0x28c5aee5), WTCP(0x793fc305, 0x290530e3),
+ WTCP(0x792a37fe, 0x2944a7a2), WTCP(0x79148bbf, 0x29841311),
+ WTCP(0x78febe4e, 0x29c3731e), WTCP(0x78e8cfb2, 0x2a02c7b8),
+ WTCP(0x78d2bfef, 0x2a4210ce), WTCP(0x78bc8f0d, 0x2a814e4d),
+ WTCP(0x78a63d11, 0x2ac08026), WTCP(0x788fca01, 0x2affa646),
+ WTCP(0x787935e4, 0x2b3ec09c), WTCP(0x786280bf, 0x2b7dcf17),
+ WTCP(0x784baa9a, 0x2bbcd1a6), WTCP(0x7834b37a, 0x2bfbc837),
+ WTCP(0x781d9b65, 0x2c3ab2b9), WTCP(0x78066262, 0x2c79911b),
+ WTCP(0x77ef0877, 0x2cb8634b), WTCP(0x77d78daa, 0x2cf72939),
+ WTCP(0x77bff203, 0x2d35e2d3), WTCP(0x77a83587, 0x2d749008),
+ WTCP(0x7790583e, 0x2db330c7), WTCP(0x77785a2d, 0x2df1c4fe),
+ WTCP(0x77603b5a, 0x2e304c9d), WTCP(0x7747fbce, 0x2e6ec792),
+ WTCP(0x772f9b8e, 0x2ead35cd), WTCP(0x77171aa1, 0x2eeb973b),
+ WTCP(0x76fe790e, 0x2f29ebcc), WTCP(0x76e5b6dc, 0x2f68336f),
+ WTCP(0x76ccd411, 0x2fa66e13), WTCP(0x76b3d0b4, 0x2fe49ba7),
+ WTCP(0x769aaccc, 0x3022bc19), WTCP(0x7681685f, 0x3060cf59),
+ WTCP(0x76680376, 0x309ed556), WTCP(0x764e7e17, 0x30dccdfe),
+ WTCP(0x7634d848, 0x311ab941), WTCP(0x761b1211, 0x3158970e),
+ WTCP(0x76012b79, 0x31966753), WTCP(0x75e72487, 0x31d42a00),
+ WTCP(0x75ccfd42, 0x3211df04), WTCP(0x75b2b5b2, 0x324f864e),
+ WTCP(0x75984ddc, 0x328d1fcc), WTCP(0x757dc5ca, 0x32caab6f),
+ WTCP(0x75631d82, 0x33082925), WTCP(0x7548550b, 0x334598de),
+ WTCP(0x752d6c6c, 0x3382fa88), WTCP(0x751263ae, 0x33c04e13),
+ WTCP(0x74f73ad7, 0x33fd936e), WTCP(0x74dbf1ef, 0x343aca87),
+ WTCP(0x74c088fe, 0x3477f350), WTCP(0x74a5000a, 0x34b50db5),
+ WTCP(0x7489571c, 0x34f219a8), WTCP(0x746d8e3a, 0x352f1716),
+ WTCP(0x7451a56e, 0x356c05f0), WTCP(0x74359cbd, 0x35a8e625),
+ WTCP(0x74197431, 0x35e5b7a3), WTCP(0x73fd2bd0, 0x36227a5b),
+ WTCP(0x73e0c3a3, 0x365f2e3b), WTCP(0x73c43bb1, 0x369bd334),
+ WTCP(0x73a79402, 0x36d86934), WTCP(0x738acc9e, 0x3714f02a),
+ WTCP(0x736de58d, 0x37516807), WTCP(0x7350ded7, 0x378dd0b9),
+ WTCP(0x7333b883, 0x37ca2a30), WTCP(0x7316729a, 0x3806745c),
+ WTCP(0x72f90d24, 0x3842af2b), WTCP(0x72db8828, 0x387eda8e),
+ WTCP(0x72bde3af, 0x38baf674), WTCP(0x72a01fc2, 0x38f702cd),
+ WTCP(0x72823c67, 0x3932ff87), WTCP(0x726439a8, 0x396eec93),
+ WTCP(0x7246178c, 0x39aac9e0), WTCP(0x7227d61c, 0x39e6975e),
+ WTCP(0x72097560, 0x3a2254fc), WTCP(0x71eaf561, 0x3a5e02aa),
+ WTCP(0x71cc5626, 0x3a99a057), WTCP(0x71ad97b9, 0x3ad52df4),
+ WTCP(0x718eba22, 0x3b10ab70), WTCP(0x716fbd68, 0x3b4c18ba),
+ WTCP(0x7150a195, 0x3b8775c2), WTCP(0x713166b1, 0x3bc2c279),
+ WTCP(0x71120cc5, 0x3bfdfecd), WTCP(0x70f293d9, 0x3c392aaf),
+ WTCP(0x70d2fbf6, 0x3c74460e), WTCP(0x70b34525, 0x3caf50da),
+ WTCP(0x70936f6e, 0x3cea4b04), WTCP(0x70737ad9, 0x3d253479),
+ WTCP(0x70536771, 0x3d600d2c), WTCP(0x7033353d, 0x3d9ad50b),
+ WTCP(0x7012e447, 0x3dd58c06), WTCP(0x6ff27497, 0x3e10320d),
+ WTCP(0x6fd1e635, 0x3e4ac711), WTCP(0x6fb1392c, 0x3e854b01),
+ WTCP(0x6f906d84, 0x3ebfbdcd), WTCP(0x6f6f8346, 0x3efa1f65),
+ WTCP(0x6f4e7a7b, 0x3f346fb8), WTCP(0x6f2d532c, 0x3f6eaeb8),
+ WTCP(0x6f0c0d62, 0x3fa8dc54), WTCP(0x6eeaa927, 0x3fe2f87c),
+ WTCP(0x6ec92683, 0x401d0321), WTCP(0x6ea7857f, 0x4056fc31),
+ WTCP(0x6e85c626, 0x4090e39e), WTCP(0x6e63e87f, 0x40cab958),
+ WTCP(0x6e41ec95, 0x41047d4e), WTCP(0x6e1fd271, 0x413e2f71),
+ WTCP(0x6dfd9a1c, 0x4177cfb1), WTCP(0x6ddb439f, 0x41b15dfe),
+ WTCP(0x6db8cf04, 0x41eada49), WTCP(0x6d963c54, 0x42244481),
+ WTCP(0x6d738b99, 0x425d9c97), WTCP(0x6d50bcdc, 0x4296e27b),
+ WTCP(0x6d2dd027, 0x42d0161e), WTCP(0x6d0ac584, 0x43093770),
+ WTCP(0x6ce79cfc, 0x43424661), WTCP(0x6cc45698, 0x437b42e1),
+ WTCP(0x6ca0f262, 0x43b42ce1), WTCP(0x6c7d7065, 0x43ed0452),
+ WTCP(0x6c59d0a9, 0x4425c923), WTCP(0x6c361339, 0x445e7b46),
+ WTCP(0x6c12381e, 0x44971aaa), WTCP(0x6bee3f62, 0x44cfa740),
+ WTCP(0x6bca2910, 0x450820f8), WTCP(0x6ba5f530, 0x454087c4),
+ WTCP(0x6b81a3cd, 0x4578db93), WTCP(0x6b5d34f1, 0x45b11c57),
+ WTCP(0x6b38a8a6, 0x45e949ff), WTCP(0x6b13fef5, 0x4621647d),
+ WTCP(0x6aef37e9, 0x46596bc1), WTCP(0x6aca538c, 0x46915fbb),
+ WTCP(0x6aa551e9, 0x46c9405c), WTCP(0x6a803308, 0x47010d96),
+ WTCP(0x6a5af6f5, 0x4738c758), WTCP(0x6a359db9, 0x47706d93),
+ WTCP(0x6a102760, 0x47a80039), WTCP(0x69ea93f2, 0x47df7f3a),
+ WTCP(0x69c4e37a, 0x4816ea86), WTCP(0x699f1604, 0x484e420f),
+ WTCP(0x69792b98, 0x488585c5), WTCP(0x69532442, 0x48bcb599),
+ WTCP(0x692d000c, 0x48f3d17c), WTCP(0x6906bf00, 0x492ad95f),
+ WTCP(0x68e06129, 0x4961cd33), WTCP(0x68b9e692, 0x4998ace9),
+ WTCP(0x68934f44, 0x49cf7871), WTCP(0x686c9b4b, 0x4a062fbd),
+ WTCP(0x6845cab1, 0x4a3cd2be), WTCP(0x681edd81, 0x4a736165),
+ WTCP(0x67f7d3c5, 0x4aa9dba2), WTCP(0x67d0ad88, 0x4ae04167),
+ WTCP(0x67a96ad5, 0x4b1692a5), WTCP(0x67820bb7, 0x4b4ccf4d),
+ WTCP(0x675a9038, 0x4b82f750), WTCP(0x6732f863, 0x4bb90aa0),
+ WTCP(0x670b4444, 0x4bef092d), WTCP(0x66e373e4, 0x4c24f2e9),
+ WTCP(0x66bb8750, 0x4c5ac7c4), WTCP(0x66937e91, 0x4c9087b1),
+ WTCP(0x666b59b3, 0x4cc632a0), WTCP(0x664318c0, 0x4cfbc883),
+ WTCP(0x661abbc5, 0x4d31494b), WTCP(0x65f242cc, 0x4d66b4e9),
+ WTCP(0x65c9addf, 0x4d9c0b4f), WTCP(0x65a0fd0b, 0x4dd14c6e),
+ WTCP(0x6578305a, 0x4e067837), WTCP(0x654f47d7, 0x4e3b8e9d),
+ WTCP(0x6526438f, 0x4e708f8f), WTCP(0x64fd238b, 0x4ea57b01),
+ WTCP(0x64d3e7d7, 0x4eda50e2), WTCP(0x64aa907f, 0x4f0f1126),
+ WTCP(0x64811d8e, 0x4f43bbbd), WTCP(0x64578f0f, 0x4f785099),
+ WTCP(0x642de50d, 0x4faccfab), WTCP(0x64041f95, 0x4fe138e5),
+ WTCP(0x63da3eb1, 0x50158c39), WTCP(0x63b0426d, 0x5049c999),
+ WTCP(0x63862ad5, 0x507df0f6), WTCP(0x635bf7f3, 0x50b20241),
+ WTCP(0x6331a9d4, 0x50e5fd6d), WTCP(0x63074084, 0x5119e26b),
+ WTCP(0x62dcbc0d, 0x514db12d), WTCP(0x62b21c7b, 0x518169a5),
+ WTCP(0x628761db, 0x51b50bc4), WTCP(0x625c8c38, 0x51e8977d),
+ WTCP(0x62319b9d, 0x521c0cc2), WTCP(0x62069017, 0x524f6b83),
+ WTCP(0x61db69b1, 0x5282b3b4), WTCP(0x61b02876, 0x52b5e546),
+ WTCP(0x6184cc74, 0x52e9002a), WTCP(0x615955b6, 0x531c0454),
+ WTCP(0x612dc447, 0x534ef1b5), WTCP(0x61021834, 0x5381c83f),
+ WTCP(0x60d65188, 0x53b487e5), WTCP(0x60aa7050, 0x53e73097),
+ WTCP(0x607e7497, 0x5419c249), WTCP(0x60525e6b, 0x544c3cec),
+ WTCP(0x60262dd6, 0x547ea073), WTCP(0x5ff9e2e5, 0x54b0ecd0),
+ WTCP(0x5fcd7da4, 0x54e321f5), WTCP(0x5fa0fe1f, 0x55153fd4),
+ WTCP(0x5f746462, 0x55474660), WTCP(0x5f47b07a, 0x5579358b),
+ WTCP(0x5f1ae274, 0x55ab0d46), WTCP(0x5eedfa5a, 0x55dccd86),
+ WTCP(0x5ec0f839, 0x560e763b), WTCP(0x5e93dc1f, 0x56400758),
+ WTCP(0x5e66a617, 0x567180d0), WTCP(0x5e39562d, 0x56a2e295),
+ WTCP(0x5e0bec6e, 0x56d42c99), WTCP(0x5dde68e7, 0x57055ed0),
+ WTCP(0x5db0cba4, 0x5736792b), WTCP(0x5d8314b1, 0x57677b9d),
+ WTCP(0x5d55441b, 0x57986619), WTCP(0x5d2759ee, 0x57c93891),
+ WTCP(0x5cf95638, 0x57f9f2f8), WTCP(0x5ccb3905, 0x582a9540),
+ WTCP(0x5c9d0260, 0x585b1f5c), WTCP(0x5c6eb258, 0x588b9140),
+ WTCP(0x5c4048f9, 0x58bbeadd), WTCP(0x5c11c64f, 0x58ec2c26),
+ WTCP(0x5be32a67, 0x591c550e), WTCP(0x5bb4754e, 0x594c6588),
+ WTCP(0x5b85a711, 0x597c5d87), WTCP(0x5b56bfbd, 0x59ac3cfd),
+ WTCP(0x5b27bf5e, 0x59dc03de), WTCP(0x5af8a602, 0x5a0bb21c),
+ WTCP(0x5ac973b5, 0x5a3b47ab), WTCP(0x5a9a2884, 0x5a6ac47c),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow960[] = {
+ WTCP(0x7ffffd31, 0x001aceea), WTCP(0x7fffe6bc, 0x00506cb9),
+ WTCP(0x7fffb9d1, 0x00860a79), WTCP(0x7fff7671, 0x00bba822),
+ WTCP(0x7fff1c9b, 0x00f145ab), WTCP(0x7ffeac50, 0x0126e309),
+ WTCP(0x7ffe2590, 0x015c8033), WTCP(0x7ffd885a, 0x01921d20),
+ WTCP(0x7ffcd4b0, 0x01c7b9c6), WTCP(0x7ffc0a91, 0x01fd561d),
+ WTCP(0x7ffb29fd, 0x0232f21a), WTCP(0x7ffa32f4, 0x02688db4),
+ WTCP(0x7ff92577, 0x029e28e2), WTCP(0x7ff80186, 0x02d3c39b),
+ WTCP(0x7ff6c720, 0x03095dd5), WTCP(0x7ff57647, 0x033ef786),
+ WTCP(0x7ff40efa, 0x037490a5), WTCP(0x7ff2913a, 0x03aa292a),
+ WTCP(0x7ff0fd07, 0x03dfc109), WTCP(0x7fef5260, 0x0415583b),
+ WTCP(0x7fed9148, 0x044aeeb5), WTCP(0x7febb9bd, 0x0480846e),
+ WTCP(0x7fe9cbc0, 0x04b6195d), WTCP(0x7fe7c752, 0x04ebad79),
+ WTCP(0x7fe5ac72, 0x052140b7), WTCP(0x7fe37b22, 0x0556d30f),
+ WTCP(0x7fe13361, 0x058c6478), WTCP(0x7fded530, 0x05c1f4e7),
+ WTCP(0x7fdc608f, 0x05f78453), WTCP(0x7fd9d57f, 0x062d12b4),
+ WTCP(0x7fd73401, 0x06629ffe), WTCP(0x7fd47c14, 0x06982c2b),
+ WTCP(0x7fd1adb9, 0x06cdb72f), WTCP(0x7fcec8f1, 0x07034101),
+ WTCP(0x7fcbcdbc, 0x0738c998), WTCP(0x7fc8bc1b, 0x076e50eb),
+ WTCP(0x7fc5940e, 0x07a3d6f0), WTCP(0x7fc25596, 0x07d95b9e),
+ WTCP(0x7fbf00b3, 0x080edeec), WTCP(0x7fbb9567, 0x084460cf),
+ WTCP(0x7fb813b0, 0x0879e140), WTCP(0x7fb47b91, 0x08af6033),
+ WTCP(0x7fb0cd0a, 0x08e4dda0), WTCP(0x7fad081b, 0x091a597e),
+ WTCP(0x7fa92cc5, 0x094fd3c3), WTCP(0x7fa53b09, 0x09854c66),
+ WTCP(0x7fa132e8, 0x09bac35d), WTCP(0x7f9d1461, 0x09f0389f),
+ WTCP(0x7f98df77, 0x0a25ac23), WTCP(0x7f949429, 0x0a5b1dde),
+ WTCP(0x7f903279, 0x0a908dc9), WTCP(0x7f8bba66, 0x0ac5fbd9),
+ WTCP(0x7f872bf3, 0x0afb6805), WTCP(0x7f82871f, 0x0b30d244),
+ WTCP(0x7f7dcbec, 0x0b663a8c), WTCP(0x7f78fa5b, 0x0b9ba0d5),
+ WTCP(0x7f74126b, 0x0bd10513), WTCP(0x7f6f141f, 0x0c066740),
+ WTCP(0x7f69ff76, 0x0c3bc74f), WTCP(0x7f64d473, 0x0c71253a),
+ WTCP(0x7f5f9315, 0x0ca680f5), WTCP(0x7f5a3b5e, 0x0cdbda79),
+ WTCP(0x7f54cd4f, 0x0d1131ba), WTCP(0x7f4f48e8, 0x0d4686b1),
+ WTCP(0x7f49ae2a, 0x0d7bd954), WTCP(0x7f43fd18, 0x0db12999),
+ WTCP(0x7f3e35b0, 0x0de67776), WTCP(0x7f3857f6, 0x0e1bc2e4),
+ WTCP(0x7f3263e9, 0x0e510bd8), WTCP(0x7f2c598a, 0x0e865248),
+ WTCP(0x7f2638db, 0x0ebb962c), WTCP(0x7f2001dd, 0x0ef0d77b),
+ WTCP(0x7f19b491, 0x0f26162a), WTCP(0x7f1350f8, 0x0f5b5231),
+ WTCP(0x7f0cd712, 0x0f908b86), WTCP(0x7f0646e2, 0x0fc5c220),
+ WTCP(0x7effa069, 0x0ffaf5f6), WTCP(0x7ef8e3a6, 0x103026fe),
+ WTCP(0x7ef2109d, 0x1065552e), WTCP(0x7eeb274d, 0x109a807e),
+ WTCP(0x7ee427b9, 0x10cfa8e5), WTCP(0x7edd11e1, 0x1104ce58),
+ WTCP(0x7ed5e5c6, 0x1139f0cf), WTCP(0x7ecea36b, 0x116f1040),
+ WTCP(0x7ec74acf, 0x11a42ca2), WTCP(0x7ebfdbf5, 0x11d945eb),
+ WTCP(0x7eb856de, 0x120e5c13), WTCP(0x7eb0bb8a, 0x12436f10),
+ WTCP(0x7ea909fc, 0x12787ed8), WTCP(0x7ea14235, 0x12ad8b63),
+ WTCP(0x7e996436, 0x12e294a7), WTCP(0x7e917000, 0x13179a9b),
+ WTCP(0x7e896595, 0x134c9d34), WTCP(0x7e8144f6, 0x13819c6c),
+ WTCP(0x7e790e25, 0x13b69836), WTCP(0x7e70c124, 0x13eb908c),
+ WTCP(0x7e685df2, 0x14208563), WTCP(0x7e5fe493, 0x145576b1),
+ WTCP(0x7e575508, 0x148a646e), WTCP(0x7e4eaf51, 0x14bf4e91),
+ WTCP(0x7e45f371, 0x14f43510), WTCP(0x7e3d2169, 0x152917e1),
+ WTCP(0x7e34393b, 0x155df6fc), WTCP(0x7e2b3ae8, 0x1592d257),
+ WTCP(0x7e222672, 0x15c7a9ea), WTCP(0x7e18fbda, 0x15fc7daa),
+ WTCP(0x7e0fbb22, 0x16314d8e), WTCP(0x7e06644c, 0x1666198d),
+ WTCP(0x7dfcf759, 0x169ae19f), WTCP(0x7df3744b, 0x16cfa5b9),
+ WTCP(0x7de9db23, 0x170465d2), WTCP(0x7de02be4, 0x173921e2),
+ WTCP(0x7dd6668f, 0x176dd9de), WTCP(0x7dcc8b25, 0x17a28dbe),
+ WTCP(0x7dc299a9, 0x17d73d79), WTCP(0x7db8921c, 0x180be904),
+ WTCP(0x7dae747f, 0x18409058), WTCP(0x7da440d6, 0x1875336a),
+ WTCP(0x7d99f721, 0x18a9d231), WTCP(0x7d8f9762, 0x18de6ca5),
+ WTCP(0x7d85219c, 0x191302bc), WTCP(0x7d7a95cf, 0x1947946c),
+ WTCP(0x7d6ff3fe, 0x197c21ad), WTCP(0x7d653c2b, 0x19b0aa75),
+ WTCP(0x7d5a6e57, 0x19e52ebb), WTCP(0x7d4f8a85, 0x1a19ae76),
+ WTCP(0x7d4490b6, 0x1a4e299d), WTCP(0x7d3980ec, 0x1a82a026),
+ WTCP(0x7d2e5b2a, 0x1ab71208), WTCP(0x7d231f70, 0x1aeb7f3a),
+ WTCP(0x7d17cdc2, 0x1b1fe7b3), WTCP(0x7d0c6621, 0x1b544b6a),
+ WTCP(0x7d00e88f, 0x1b88aa55), WTCP(0x7cf5550e, 0x1bbd046c),
+ WTCP(0x7ce9aba1, 0x1bf159a4), WTCP(0x7cddec48, 0x1c25a9f6),
+ WTCP(0x7cd21707, 0x1c59f557), WTCP(0x7cc62bdf, 0x1c8e3bbe),
+ WTCP(0x7cba2ad3, 0x1cc27d23), WTCP(0x7cae13e4, 0x1cf6b97c),
+ WTCP(0x7ca1e715, 0x1d2af0c1), WTCP(0x7c95a467, 0x1d5f22e7),
+ WTCP(0x7c894bde, 0x1d934fe5), WTCP(0x7c7cdd7b, 0x1dc777b3),
+ WTCP(0x7c705940, 0x1dfb9a48), WTCP(0x7c63bf2f, 0x1e2fb79a),
+ WTCP(0x7c570f4b, 0x1e63cfa0), WTCP(0x7c4a4996, 0x1e97e251),
+ WTCP(0x7c3d6e13, 0x1ecbefa4), WTCP(0x7c307cc2, 0x1efff78f),
+ WTCP(0x7c2375a8, 0x1f33fa0a), WTCP(0x7c1658c5, 0x1f67f70b),
+ WTCP(0x7c09261d, 0x1f9bee8a), WTCP(0x7bfbddb1, 0x1fcfe07d),
+ WTCP(0x7bee7f85, 0x2003ccdb), WTCP(0x7be10b99, 0x2037b39b),
+ WTCP(0x7bd381f1, 0x206b94b4), WTCP(0x7bc5e290, 0x209f701c),
+ WTCP(0x7bb82d76, 0x20d345cc), WTCP(0x7baa62a8, 0x210715b8),
+ WTCP(0x7b9c8226, 0x213adfda), WTCP(0x7b8e8bf5, 0x216ea426),
+ WTCP(0x7b808015, 0x21a26295), WTCP(0x7b725e8a, 0x21d61b1e),
+ WTCP(0x7b642756, 0x2209cdb6), WTCP(0x7b55da7c, 0x223d7a55),
+ WTCP(0x7b4777fe, 0x227120f3), WTCP(0x7b38ffde, 0x22a4c185),
+ WTCP(0x7b2a721f, 0x22d85c04), WTCP(0x7b1bcec4, 0x230bf065),
+ WTCP(0x7b0d15d0, 0x233f7ea0), WTCP(0x7afe4744, 0x237306ab),
+ WTCP(0x7aef6323, 0x23a6887f), WTCP(0x7ae06971, 0x23da0411),
+ WTCP(0x7ad15a2f, 0x240d7958), WTCP(0x7ac23561, 0x2440e84d),
+ WTCP(0x7ab2fb09, 0x247450e4), WTCP(0x7aa3ab29, 0x24a7b317),
+ WTCP(0x7a9445c5, 0x24db0edb), WTCP(0x7a84cade, 0x250e6427),
+ WTCP(0x7a753a79, 0x2541b2f3), WTCP(0x7a659496, 0x2574fb36),
+ WTCP(0x7a55d93a, 0x25a83ce6), WTCP(0x7a460867, 0x25db77fa),
+ WTCP(0x7a362220, 0x260eac6a), WTCP(0x7a262668, 0x2641da2d),
+ WTCP(0x7a161540, 0x26750139), WTCP(0x7a05eead, 0x26a82186),
+ WTCP(0x79f5b2b1, 0x26db3b0a), WTCP(0x79e5614f, 0x270e4dbd),
+ WTCP(0x79d4fa89, 0x27415996), WTCP(0x79c47e63, 0x27745e8c),
+ WTCP(0x79b3ece0, 0x27a75c95), WTCP(0x79a34602, 0x27da53a9),
+ WTCP(0x799289cc, 0x280d43bf), WTCP(0x7981b841, 0x28402cce),
+ WTCP(0x7970d165, 0x28730ecd), WTCP(0x795fd53a, 0x28a5e9b4),
+ WTCP(0x794ec3c3, 0x28d8bd78), WTCP(0x793d9d03, 0x290b8a12),
+ WTCP(0x792c60fe, 0x293e4f78), WTCP(0x791b0fb5, 0x29710da1),
+ WTCP(0x7909a92d, 0x29a3c485), WTCP(0x78f82d68, 0x29d6741b),
+ WTCP(0x78e69c69, 0x2a091c59), WTCP(0x78d4f634, 0x2a3bbd37),
+ WTCP(0x78c33acb, 0x2a6e56ac), WTCP(0x78b16a32, 0x2aa0e8b0),
+ WTCP(0x789f846b, 0x2ad37338), WTCP(0x788d897b, 0x2b05f63d),
+ WTCP(0x787b7963, 0x2b3871b5), WTCP(0x78695428, 0x2b6ae598),
+ WTCP(0x785719cc, 0x2b9d51dd), WTCP(0x7844ca53, 0x2bcfb67b),
+ WTCP(0x783265c0, 0x2c021369), WTCP(0x781fec15, 0x2c34689e),
+ WTCP(0x780d5d57, 0x2c66b611), WTCP(0x77fab989, 0x2c98fbba),
+ WTCP(0x77e800ad, 0x2ccb3990), WTCP(0x77d532c7, 0x2cfd6f8a),
+ WTCP(0x77c24fdb, 0x2d2f9d9f), WTCP(0x77af57eb, 0x2d61c3c7),
+ WTCP(0x779c4afc, 0x2d93e1f8), WTCP(0x77892910, 0x2dc5f829),
+ WTCP(0x7775f22a, 0x2df80653), WTCP(0x7762a64f, 0x2e2a0c6c),
+ WTCP(0x774f4581, 0x2e5c0a6b), WTCP(0x773bcfc4, 0x2e8e0048),
+ WTCP(0x7728451c, 0x2ebfedfa), WTCP(0x7714a58b, 0x2ef1d377),
+ WTCP(0x7700f115, 0x2f23b0b9), WTCP(0x76ed27be, 0x2f5585b5),
+ WTCP(0x76d94989, 0x2f875262), WTCP(0x76c55679, 0x2fb916b9),
+ WTCP(0x76b14e93, 0x2fead2b0), WTCP(0x769d31d9, 0x301c863f),
+ WTCP(0x76890050, 0x304e315d), WTCP(0x7674b9fa, 0x307fd401),
+ WTCP(0x76605edb, 0x30b16e23), WTCP(0x764beef8, 0x30e2ffb9),
+ WTCP(0x76376a52, 0x311488bc), WTCP(0x7622d0ef, 0x31460922),
+ WTCP(0x760e22d1, 0x317780e2), WTCP(0x75f95ffc, 0x31a8eff5),
+ WTCP(0x75e48874, 0x31da5651), WTCP(0x75cf9c3d, 0x320bb3ee),
+ WTCP(0x75ba9b5a, 0x323d08c3), WTCP(0x75a585cf, 0x326e54c7),
+ WTCP(0x75905ba0, 0x329f97f3), WTCP(0x757b1ccf, 0x32d0d23c),
+ WTCP(0x7565c962, 0x3302039b), WTCP(0x7550615c, 0x33332c06),
+ WTCP(0x753ae4c0, 0x33644b76), WTCP(0x75255392, 0x339561e1),
+ WTCP(0x750fadd7, 0x33c66f40), WTCP(0x74f9f391, 0x33f77388),
+ WTCP(0x74e424c5, 0x34286eb3), WTCP(0x74ce4177, 0x345960b7),
+ WTCP(0x74b849aa, 0x348a498b), WTCP(0x74a23d62, 0x34bb2927),
+ WTCP(0x748c1ca4, 0x34ebff83), WTCP(0x7475e772, 0x351ccc96),
+ WTCP(0x745f9dd1, 0x354d9057), WTCP(0x74493fc5, 0x357e4abe),
+ WTCP(0x7432cd51, 0x35aefbc2), WTCP(0x741c467b, 0x35dfa35a),
+ WTCP(0x7405ab45, 0x3610417f), WTCP(0x73eefbb3, 0x3640d627),
+ WTCP(0x73d837ca, 0x3671614b), WTCP(0x73c15f8d, 0x36a1e2e0),
+ WTCP(0x73aa7301, 0x36d25ae0), WTCP(0x7393722a, 0x3702c942),
+ WTCP(0x737c5d0b, 0x37332dfd), WTCP(0x736533a9, 0x37638908),
+ WTCP(0x734df607, 0x3793da5b), WTCP(0x7336a42b, 0x37c421ee),
+ WTCP(0x731f3e17, 0x37f45fb7), WTCP(0x7307c3d0, 0x382493b0),
+ WTCP(0x72f0355a, 0x3854bdcf), WTCP(0x72d892ba, 0x3884de0b),
+ WTCP(0x72c0dbf3, 0x38b4f45d), WTCP(0x72a91109, 0x38e500bc),
+ WTCP(0x72913201, 0x3915031f), WTCP(0x72793edf, 0x3944fb7e),
+ WTCP(0x726137a8, 0x3974e9d0), WTCP(0x72491c5e, 0x39a4ce0e),
+ WTCP(0x7230ed07, 0x39d4a82f), WTCP(0x7218a9a7, 0x3a04782a),
+ WTCP(0x72005242, 0x3a343df7), WTCP(0x71e7e6dc, 0x3a63f98d),
+ WTCP(0x71cf677a, 0x3a93aae5), WTCP(0x71b6d420, 0x3ac351f6),
+ WTCP(0x719e2cd2, 0x3af2eeb7), WTCP(0x71857195, 0x3b228120),
+ WTCP(0x716ca26c, 0x3b52092a), WTCP(0x7153bf5d, 0x3b8186ca),
+ WTCP(0x713ac86b, 0x3bb0f9fa), WTCP(0x7121bd9c, 0x3be062b0),
+ WTCP(0x71089ef2, 0x3c0fc0e6), WTCP(0x70ef6c74, 0x3c3f1491),
+ WTCP(0x70d62625, 0x3c6e5daa), WTCP(0x70bccc09, 0x3c9d9c28),
+ WTCP(0x70a35e25, 0x3cccd004), WTCP(0x7089dc7e, 0x3cfbf935),
+ WTCP(0x70704718, 0x3d2b17b3), WTCP(0x70569df8, 0x3d5a2b75),
+ WTCP(0x703ce122, 0x3d893474), WTCP(0x7023109a, 0x3db832a6),
+ WTCP(0x70092c65, 0x3de72604), WTCP(0x6fef3488, 0x3e160e85),
+ WTCP(0x6fd52907, 0x3e44ec22), WTCP(0x6fbb09e7, 0x3e73bed2),
+ WTCP(0x6fa0d72c, 0x3ea2868c), WTCP(0x6f8690db, 0x3ed14349),
+ WTCP(0x6f6c36f8, 0x3efff501), WTCP(0x6f51c989, 0x3f2e9bab),
+ WTCP(0x6f374891, 0x3f5d373e), WTCP(0x6f1cb416, 0x3f8bc7b4),
+ WTCP(0x6f020c1c, 0x3fba4d03), WTCP(0x6ee750a8, 0x3fe8c724),
+ WTCP(0x6ecc81be, 0x4017360e), WTCP(0x6eb19f64, 0x404599b9),
+ WTCP(0x6e96a99d, 0x4073f21d), WTCP(0x6e7ba06f, 0x40a23f32),
+ WTCP(0x6e6083de, 0x40d080f0), WTCP(0x6e4553ef, 0x40feb74f),
+ WTCP(0x6e2a10a8, 0x412ce246), WTCP(0x6e0eba0c, 0x415b01ce),
+ WTCP(0x6df35020, 0x418915de), WTCP(0x6dd7d2ea, 0x41b71e6f),
+ WTCP(0x6dbc426e, 0x41e51b77), WTCP(0x6da09eb1, 0x42130cf0),
+ WTCP(0x6d84e7b7, 0x4240f2d1), WTCP(0x6d691d87, 0x426ecd12),
+ WTCP(0x6d4d4023, 0x429c9bab), WTCP(0x6d314f93, 0x42ca5e94),
+ WTCP(0x6d154bd9, 0x42f815c5), WTCP(0x6cf934fc, 0x4325c135),
+ WTCP(0x6cdd0b00, 0x435360de), WTCP(0x6cc0cdea, 0x4380f4b7),
+ WTCP(0x6ca47dbf, 0x43ae7cb7), WTCP(0x6c881a84, 0x43dbf8d7),
+ WTCP(0x6c6ba43e, 0x44096910), WTCP(0x6c4f1af2, 0x4436cd58),
+ WTCP(0x6c327ea6, 0x446425a8), WTCP(0x6c15cf5d, 0x449171f8),
+ WTCP(0x6bf90d1d, 0x44beb240), WTCP(0x6bdc37eb, 0x44ebe679),
+ WTCP(0x6bbf4fcd, 0x45190e99), WTCP(0x6ba254c7, 0x45462a9a),
+ WTCP(0x6b8546de, 0x45733a73), WTCP(0x6b682617, 0x45a03e1d),
+ WTCP(0x6b4af279, 0x45cd358f), WTCP(0x6b2dac06, 0x45fa20c2),
+ WTCP(0x6b1052c6, 0x4626ffae), WTCP(0x6af2e6bc, 0x4653d24b),
+ WTCP(0x6ad567ef, 0x46809891), WTCP(0x6ab7d663, 0x46ad5278),
+ WTCP(0x6a9a321d, 0x46d9fff8), WTCP(0x6a7c7b23, 0x4706a10a),
+ WTCP(0x6a5eb17a, 0x473335a5), WTCP(0x6a40d527, 0x475fbdc3),
+ WTCP(0x6a22e630, 0x478c395a), WTCP(0x6a04e499, 0x47b8a864),
+ WTCP(0x69e6d067, 0x47e50ad8), WTCP(0x69c8a9a1, 0x481160ae),
+ WTCP(0x69aa704c, 0x483da9e0), WTCP(0x698c246c, 0x4869e665),
+ WTCP(0x696dc607, 0x48961635), WTCP(0x694f5523, 0x48c23949),
+ WTCP(0x6930d1c4, 0x48ee4f98), WTCP(0x69123bf1, 0x491a591c),
+ WTCP(0x68f393ae, 0x494655cc), WTCP(0x68d4d900, 0x497245a1),
+ WTCP(0x68b60bee, 0x499e2892), WTCP(0x68972c7d, 0x49c9fe99),
+ WTCP(0x68783ab1, 0x49f5c7ae), WTCP(0x68593691, 0x4a2183c8),
+ WTCP(0x683a2022, 0x4a4d32e1), WTCP(0x681af76a, 0x4a78d4f0),
+ WTCP(0x67fbbc6d, 0x4aa469ee), WTCP(0x67dc6f31, 0x4acff1d3),
+ WTCP(0x67bd0fbd, 0x4afb6c98), WTCP(0x679d9e14, 0x4b26da35),
+ WTCP(0x677e1a3e, 0x4b523aa2), WTCP(0x675e843e, 0x4b7d8dd8),
+ WTCP(0x673edc1c, 0x4ba8d3cf), WTCP(0x671f21dc, 0x4bd40c80),
+ WTCP(0x66ff5584, 0x4bff37e2), WTCP(0x66df771a, 0x4c2a55ef),
+ WTCP(0x66bf86a3, 0x4c55669f), WTCP(0x669f8425, 0x4c8069ea),
+ WTCP(0x667f6fa5, 0x4cab5fc9), WTCP(0x665f4929, 0x4cd64834),
+ WTCP(0x663f10b7, 0x4d012324), WTCP(0x661ec654, 0x4d2bf091),
+ WTCP(0x65fe6a06, 0x4d56b073), WTCP(0x65ddfbd3, 0x4d8162c4),
+ WTCP(0x65bd7bc0, 0x4dac077b), WTCP(0x659ce9d4, 0x4dd69e92),
+ WTCP(0x657c4613, 0x4e012800), WTCP(0x655b9083, 0x4e2ba3be),
+ WTCP(0x653ac92b, 0x4e5611c5), WTCP(0x6519f010, 0x4e80720e),
+ WTCP(0x64f90538, 0x4eaac490), WTCP(0x64d808a8, 0x4ed50945),
+ WTCP(0x64b6fa66, 0x4eff4025), WTCP(0x6495da79, 0x4f296928),
+ WTCP(0x6474a8e5, 0x4f538448), WTCP(0x645365b2, 0x4f7d917c),
+ WTCP(0x643210e4, 0x4fa790be), WTCP(0x6410aa81, 0x4fd18206),
+ WTCP(0x63ef3290, 0x4ffb654d), WTCP(0x63cda916, 0x50253a8b),
+ WTCP(0x63ac0e19, 0x504f01ba), WTCP(0x638a619e, 0x5078bad1),
+ WTCP(0x6368a3ad, 0x50a265c9), WTCP(0x6346d44b, 0x50cc029c),
+ WTCP(0x6324f37d, 0x50f59141), WTCP(0x6303014a, 0x511f11b2),
+ WTCP(0x62e0fdb8, 0x514883e7), WTCP(0x62bee8cc, 0x5171e7d9),
+ WTCP(0x629cc28c, 0x519b3d80), WTCP(0x627a8b00, 0x51c484d6),
+ WTCP(0x6258422c, 0x51edbdd4), WTCP(0x6235e816, 0x5216e871),
+ WTCP(0x62137cc5, 0x524004a7), WTCP(0x61f1003f, 0x5269126e),
+ WTCP(0x61ce7289, 0x529211c0), WTCP(0x61abd3ab, 0x52bb0295),
+ WTCP(0x618923a9, 0x52e3e4e6), WTCP(0x61666289, 0x530cb8ac),
+ WTCP(0x61439053, 0x53357ddf), WTCP(0x6120ad0d, 0x535e3479),
+ WTCP(0x60fdb8bb, 0x5386dc72), WTCP(0x60dab365, 0x53af75c3),
+ WTCP(0x60b79d10, 0x53d80065), WTCP(0x609475c3, 0x54007c51),
+ WTCP(0x60713d84, 0x5428e980), WTCP(0x604df459, 0x545147eb),
+ WTCP(0x602a9a48, 0x5479978a), WTCP(0x60072f57, 0x54a1d857),
+ WTCP(0x5fe3b38d, 0x54ca0a4b), WTCP(0x5fc026f0, 0x54f22d5d),
+ WTCP(0x5f9c8987, 0x551a4189), WTCP(0x5f78db56, 0x554246c6),
+ WTCP(0x5f551c65, 0x556a3d0d), WTCP(0x5f314cba, 0x55922457),
+ WTCP(0x5f0d6c5b, 0x55b9fc9e), WTCP(0x5ee97b4f, 0x55e1c5da),
+ WTCP(0x5ec5799b, 0x56098005), WTCP(0x5ea16747, 0x56312b17),
+ WTCP(0x5e7d4458, 0x5658c709), WTCP(0x5e5910d4, 0x568053d5),
+ WTCP(0x5e34ccc3, 0x56a7d174), WTCP(0x5e10782b, 0x56cf3fde),
+ WTCP(0x5dec1311, 0x56f69f0d), WTCP(0x5dc79d7c, 0x571deefa),
+ WTCP(0x5da31773, 0x57452f9d), WTCP(0x5d7e80fc, 0x576c60f1),
+ WTCP(0x5d59da1e, 0x579382ee), WTCP(0x5d3522de, 0x57ba958d),
+ WTCP(0x5d105b44, 0x57e198c7), WTCP(0x5ceb8355, 0x58088c96),
+ WTCP(0x5cc69b19, 0x582f70f3), WTCP(0x5ca1a295, 0x585645d7),
+ WTCP(0x5c7c99d1, 0x587d0b3b), WTCP(0x5c5780d3, 0x58a3c118),
+ WTCP(0x5c3257a0, 0x58ca6767), WTCP(0x5c0d1e41, 0x58f0fe23),
+ WTCP(0x5be7d4ba, 0x59178543), WTCP(0x5bc27b14, 0x593dfcc2),
+ WTCP(0x5b9d1154, 0x59646498), WTCP(0x5b779780, 0x598abcbe),
+ WTCP(0x5b520da1, 0x59b1052f), WTCP(0x5b2c73bb, 0x59d73de3),
+ WTCP(0x5b06c9d6, 0x59fd66d4), WTCP(0x5ae10ff9, 0x5a237ffa),
+ WTCP(0x5abb4629, 0x5a498950), WTCP(0x5a956c6e, 0x5a6f82ce),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP SineWindow1024[] = {
+ WTCP(0x7ffffd88, 0x001921fb), WTCP(0x7fffe9cb, 0x004b65ee),
+ WTCP(0x7fffc251, 0x007da9d4), WTCP(0x7fff8719, 0x00afeda8),
+ WTCP(0x7fff3824, 0x00e23160), WTCP(0x7ffed572, 0x011474f6),
+ WTCP(0x7ffe5f03, 0x0146b860), WTCP(0x7ffdd4d7, 0x0178fb99),
+ WTCP(0x7ffd36ee, 0x01ab3e97), WTCP(0x7ffc8549, 0x01dd8154),
+ WTCP(0x7ffbbfe6, 0x020fc3c6), WTCP(0x7ffae6c7, 0x024205e8),
+ WTCP(0x7ff9f9ec, 0x027447b0), WTCP(0x7ff8f954, 0x02a68917),
+ WTCP(0x7ff7e500, 0x02d8ca16), WTCP(0x7ff6bcf0, 0x030b0aa4),
+ WTCP(0x7ff58125, 0x033d4abb), WTCP(0x7ff4319d, 0x036f8a51),
+ WTCP(0x7ff2ce5b, 0x03a1c960), WTCP(0x7ff1575d, 0x03d407df),
+ WTCP(0x7fefcca4, 0x040645c7), WTCP(0x7fee2e30, 0x04388310),
+ WTCP(0x7fec7c02, 0x046abfb3), WTCP(0x7feab61a, 0x049cfba7),
+ WTCP(0x7fe8dc78, 0x04cf36e5), WTCP(0x7fe6ef1c, 0x05017165),
+ WTCP(0x7fe4ee06, 0x0533ab20), WTCP(0x7fe2d938, 0x0565e40d),
+ WTCP(0x7fe0b0b1, 0x05981c26), WTCP(0x7fde7471, 0x05ca5361),
+ WTCP(0x7fdc247a, 0x05fc89b8), WTCP(0x7fd9c0ca, 0x062ebf22),
+ WTCP(0x7fd74964, 0x0660f398), WTCP(0x7fd4be46, 0x06932713),
+ WTCP(0x7fd21f72, 0x06c5598a), WTCP(0x7fcf6ce8, 0x06f78af6),
+ WTCP(0x7fcca6a7, 0x0729bb4e), WTCP(0x7fc9ccb2, 0x075bea8c),
+ WTCP(0x7fc6df08, 0x078e18a7), WTCP(0x7fc3dda9, 0x07c04598),
+ WTCP(0x7fc0c896, 0x07f27157), WTCP(0x7fbd9fd0, 0x08249bdd),
+ WTCP(0x7fba6357, 0x0856c520), WTCP(0x7fb7132b, 0x0888ed1b),
+ WTCP(0x7fb3af4e, 0x08bb13c5), WTCP(0x7fb037bf, 0x08ed3916),
+ WTCP(0x7facac7f, 0x091f5d06), WTCP(0x7fa90d8e, 0x09517f8f),
+ WTCP(0x7fa55aee, 0x0983a0a7), WTCP(0x7fa1949e, 0x09b5c048),
+ WTCP(0x7f9dbaa0, 0x09e7de6a), WTCP(0x7f99ccf4, 0x0a19fb04),
+ WTCP(0x7f95cb9a, 0x0a4c1610), WTCP(0x7f91b694, 0x0a7e2f85),
+ WTCP(0x7f8d8de1, 0x0ab0475c), WTCP(0x7f895182, 0x0ae25d8d),
+ WTCP(0x7f850179, 0x0b147211), WTCP(0x7f809dc5, 0x0b4684df),
+ WTCP(0x7f7c2668, 0x0b7895f0), WTCP(0x7f779b62, 0x0baaa53b),
+ WTCP(0x7f72fcb4, 0x0bdcb2bb), WTCP(0x7f6e4a5e, 0x0c0ebe66),
+ WTCP(0x7f698461, 0x0c40c835), WTCP(0x7f64aabf, 0x0c72d020),
+ WTCP(0x7f5fbd77, 0x0ca4d620), WTCP(0x7f5abc8a, 0x0cd6da2d),
+ WTCP(0x7f55a7fa, 0x0d08dc3f), WTCP(0x7f507fc7, 0x0d3adc4e),
+ WTCP(0x7f4b43f2, 0x0d6cda53), WTCP(0x7f45f47b, 0x0d9ed646),
+ WTCP(0x7f409164, 0x0dd0d01f), WTCP(0x7f3b1aad, 0x0e02c7d7),
+ WTCP(0x7f359057, 0x0e34bd66), WTCP(0x7f2ff263, 0x0e66b0c3),
+ WTCP(0x7f2a40d2, 0x0e98a1e9), WTCP(0x7f247ba5, 0x0eca90ce),
+ WTCP(0x7f1ea2dc, 0x0efc7d6b), WTCP(0x7f18b679, 0x0f2e67b8),
+ WTCP(0x7f12b67c, 0x0f604faf), WTCP(0x7f0ca2e7, 0x0f923546),
+ WTCP(0x7f067bba, 0x0fc41876), WTCP(0x7f0040f6, 0x0ff5f938),
+ WTCP(0x7ef9f29d, 0x1027d784), WTCP(0x7ef390ae, 0x1059b352),
+ WTCP(0x7eed1b2c, 0x108b8c9b), WTCP(0x7ee69217, 0x10bd6356),
+ WTCP(0x7edff570, 0x10ef377d), WTCP(0x7ed94538, 0x11210907),
+ WTCP(0x7ed28171, 0x1152d7ed), WTCP(0x7ecbaa1a, 0x1184a427),
+ WTCP(0x7ec4bf36, 0x11b66dad), WTCP(0x7ebdc0c6, 0x11e83478),
+ WTCP(0x7eb6aeca, 0x1219f880), WTCP(0x7eaf8943, 0x124bb9be),
+ WTCP(0x7ea85033, 0x127d7829), WTCP(0x7ea1039b, 0x12af33ba),
+ WTCP(0x7e99a37c, 0x12e0ec6a), WTCP(0x7e922fd6, 0x1312a230),
+ WTCP(0x7e8aa8ac, 0x13445505), WTCP(0x7e830dff, 0x137604e2),
+ WTCP(0x7e7b5fce, 0x13a7b1bf), WTCP(0x7e739e1d, 0x13d95b93),
+ WTCP(0x7e6bc8eb, 0x140b0258), WTCP(0x7e63e03b, 0x143ca605),
+ WTCP(0x7e5be40c, 0x146e4694), WTCP(0x7e53d462, 0x149fe3fc),
+ WTCP(0x7e4bb13c, 0x14d17e36), WTCP(0x7e437a9c, 0x1503153a),
+ WTCP(0x7e3b3083, 0x1534a901), WTCP(0x7e32d2f4, 0x15663982),
+ WTCP(0x7e2a61ed, 0x1597c6b7), WTCP(0x7e21dd73, 0x15c95097),
+ WTCP(0x7e194584, 0x15fad71b), WTCP(0x7e109a24, 0x162c5a3b),
+ WTCP(0x7e07db52, 0x165dd9f0), WTCP(0x7dff0911, 0x168f5632),
+ WTCP(0x7df62362, 0x16c0cef9), WTCP(0x7ded2a47, 0x16f2443e),
+ WTCP(0x7de41dc0, 0x1723b5f9), WTCP(0x7ddafdce, 0x17552422),
+ WTCP(0x7dd1ca75, 0x17868eb3), WTCP(0x7dc883b4, 0x17b7f5a3),
+ WTCP(0x7dbf298d, 0x17e958ea), WTCP(0x7db5bc02, 0x181ab881),
+ WTCP(0x7dac3b15, 0x184c1461), WTCP(0x7da2a6c6, 0x187d6c82),
+ WTCP(0x7d98ff17, 0x18aec0db), WTCP(0x7d8f4409, 0x18e01167),
+ WTCP(0x7d85759f, 0x19115e1c), WTCP(0x7d7b93da, 0x1942a6f3),
+ WTCP(0x7d719eba, 0x1973ebe6), WTCP(0x7d679642, 0x19a52ceb),
+ WTCP(0x7d5d7a74, 0x19d669fc), WTCP(0x7d534b50, 0x1a07a311),
+ WTCP(0x7d4908d9, 0x1a38d823), WTCP(0x7d3eb30f, 0x1a6a0929),
+ WTCP(0x7d3449f5, 0x1a9b361d), WTCP(0x7d29cd8c, 0x1acc5ef6),
+ WTCP(0x7d1f3dd6, 0x1afd83ad), WTCP(0x7d149ad5, 0x1b2ea43a),
+ WTCP(0x7d09e489, 0x1b5fc097), WTCP(0x7cff1af5, 0x1b90d8bb),
+ WTCP(0x7cf43e1a, 0x1bc1ec9e), WTCP(0x7ce94dfb, 0x1bf2fc3a),
+ WTCP(0x7cde4a98, 0x1c240786), WTCP(0x7cd333f3, 0x1c550e7c),
+ WTCP(0x7cc80a0f, 0x1c861113), WTCP(0x7cbcccec, 0x1cb70f43),
+ WTCP(0x7cb17c8d, 0x1ce80906), WTCP(0x7ca618f3, 0x1d18fe54),
+ WTCP(0x7c9aa221, 0x1d49ef26), WTCP(0x7c8f1817, 0x1d7adb73),
+ WTCP(0x7c837ad8, 0x1dabc334), WTCP(0x7c77ca65, 0x1ddca662),
+ WTCP(0x7c6c06c0, 0x1e0d84f5), WTCP(0x7c602fec, 0x1e3e5ee5),
+ WTCP(0x7c5445e9, 0x1e6f342c), WTCP(0x7c4848ba, 0x1ea004c1),
+ WTCP(0x7c3c3860, 0x1ed0d09d), WTCP(0x7c3014de, 0x1f0197b8),
+ WTCP(0x7c23de35, 0x1f325a0b), WTCP(0x7c179467, 0x1f63178f),
+ WTCP(0x7c0b3777, 0x1f93d03c), WTCP(0x7bfec765, 0x1fc4840a),
+ WTCP(0x7bf24434, 0x1ff532f2), WTCP(0x7be5ade6, 0x2025dcec),
+ WTCP(0x7bd9047c, 0x205681f1), WTCP(0x7bcc47fa, 0x208721f9),
+ WTCP(0x7bbf7860, 0x20b7bcfe), WTCP(0x7bb295b0, 0x20e852f6),
+ WTCP(0x7ba59fee, 0x2118e3dc), WTCP(0x7b989719, 0x21496fa7),
+ WTCP(0x7b8b7b36, 0x2179f64f), WTCP(0x7b7e4c45, 0x21aa77cf),
+ WTCP(0x7b710a49, 0x21daf41d), WTCP(0x7b63b543, 0x220b6b32),
+ WTCP(0x7b564d36, 0x223bdd08), WTCP(0x7b48d225, 0x226c4996),
+ WTCP(0x7b3b4410, 0x229cb0d5), WTCP(0x7b2da2fa, 0x22cd12bd),
+ WTCP(0x7b1feee5, 0x22fd6f48), WTCP(0x7b1227d3, 0x232dc66d),
+ WTCP(0x7b044dc7, 0x235e1826), WTCP(0x7af660c2, 0x238e646a),
+ WTCP(0x7ae860c7, 0x23beab33), WTCP(0x7ada4dd8, 0x23eeec78),
+ WTCP(0x7acc27f7, 0x241f2833), WTCP(0x7abdef25, 0x244f5e5c),
+ WTCP(0x7aafa367, 0x247f8eec), WTCP(0x7aa144bc, 0x24afb9da),
+ WTCP(0x7a92d329, 0x24dfdf20), WTCP(0x7a844eae, 0x250ffeb7),
+ WTCP(0x7a75b74f, 0x25401896), WTCP(0x7a670d0d, 0x25702cb7),
+ WTCP(0x7a584feb, 0x25a03b11), WTCP(0x7a497feb, 0x25d0439f),
+ WTCP(0x7a3a9d0f, 0x26004657), WTCP(0x7a2ba75a, 0x26304333),
+ WTCP(0x7a1c9ece, 0x26603a2c), WTCP(0x7a0d836d, 0x26902b39),
+ WTCP(0x79fe5539, 0x26c01655), WTCP(0x79ef1436, 0x26effb76),
+ WTCP(0x79dfc064, 0x271fda96), WTCP(0x79d059c8, 0x274fb3ae),
+ WTCP(0x79c0e062, 0x277f86b5), WTCP(0x79b15435, 0x27af53a6),
+ WTCP(0x79a1b545, 0x27df1a77), WTCP(0x79920392, 0x280edb23),
+ WTCP(0x79823f20, 0x283e95a1), WTCP(0x797267f2, 0x286e49ea),
+ WTCP(0x79627e08, 0x289df7f8), WTCP(0x79528167, 0x28cd9fc1),
+ WTCP(0x79427210, 0x28fd4140), WTCP(0x79325006, 0x292cdc6d),
+ WTCP(0x79221b4b, 0x295c7140), WTCP(0x7911d3e2, 0x298bffb2),
+ WTCP(0x790179cd, 0x29bb87bc), WTCP(0x78f10d0f, 0x29eb0957),
+ WTCP(0x78e08dab, 0x2a1a847b), WTCP(0x78cffba3, 0x2a49f920),
+ WTCP(0x78bf56f9, 0x2a796740), WTCP(0x78ae9fb0, 0x2aa8ced3),
+ WTCP(0x789dd5cb, 0x2ad82fd2), WTCP(0x788cf94c, 0x2b078a36),
+ WTCP(0x787c0a36, 0x2b36ddf7), WTCP(0x786b088c, 0x2b662b0e),
+ WTCP(0x7859f44f, 0x2b957173), WTCP(0x7848cd83, 0x2bc4b120),
+ WTCP(0x7837942b, 0x2bf3ea0d), WTCP(0x78264849, 0x2c231c33),
+ WTCP(0x7814e9df, 0x2c52478a), WTCP(0x780378f1, 0x2c816c0c),
+ WTCP(0x77f1f581, 0x2cb089b1), WTCP(0x77e05f91, 0x2cdfa071),
+ WTCP(0x77ceb725, 0x2d0eb046), WTCP(0x77bcfc3f, 0x2d3db928),
+ WTCP(0x77ab2ee2, 0x2d6cbb10), WTCP(0x77994f11, 0x2d9bb5f6),
+ WTCP(0x77875cce, 0x2dcaa9d5), WTCP(0x7775581d, 0x2df996a3),
+ WTCP(0x776340ff, 0x2e287c5a), WTCP(0x77511778, 0x2e575af3),
+ WTCP(0x773edb8b, 0x2e863267), WTCP(0x772c8d3a, 0x2eb502ae),
+ WTCP(0x771a2c88, 0x2ee3cbc1), WTCP(0x7707b979, 0x2f128d99),
+ WTCP(0x76f5340e, 0x2f41482e), WTCP(0x76e29c4b, 0x2f6ffb7a),
+ WTCP(0x76cff232, 0x2f9ea775), WTCP(0x76bd35c7, 0x2fcd4c19),
+ WTCP(0x76aa670d, 0x2ffbe95d), WTCP(0x76978605, 0x302a7f3a),
+ WTCP(0x768492b4, 0x30590dab), WTCP(0x76718d1c, 0x308794a6),
+ WTCP(0x765e7540, 0x30b61426), WTCP(0x764b4b23, 0x30e48c22),
+ WTCP(0x76380ec8, 0x3112fc95), WTCP(0x7624c031, 0x31416576),
+ WTCP(0x76115f63, 0x316fc6be), WTCP(0x75fdec60, 0x319e2067),
+ WTCP(0x75ea672a, 0x31cc7269), WTCP(0x75d6cfc5, 0x31fabcbd),
+ WTCP(0x75c32634, 0x3228ff5c), WTCP(0x75af6a7b, 0x32573a3f),
+ WTCP(0x759b9c9b, 0x32856d5e), WTCP(0x7587bc98, 0x32b398b3),
+ WTCP(0x7573ca75, 0x32e1bc36), WTCP(0x755fc635, 0x330fd7e1),
+ WTCP(0x754bafdc, 0x333debab), WTCP(0x7537876c, 0x336bf78f),
+ WTCP(0x75234ce8, 0x3399fb85), WTCP(0x750f0054, 0x33c7f785),
+ WTCP(0x74faa1b3, 0x33f5eb89), WTCP(0x74e63108, 0x3423d78a),
+ WTCP(0x74d1ae55, 0x3451bb81), WTCP(0x74bd199f, 0x347f9766),
+ WTCP(0x74a872e8, 0x34ad6b32), WTCP(0x7493ba34, 0x34db36df),
+ WTCP(0x747eef85, 0x3508fa66), WTCP(0x746a12df, 0x3536b5be),
+ WTCP(0x74552446, 0x356468e2), WTCP(0x744023bc, 0x359213c9),
+ WTCP(0x742b1144, 0x35bfb66e), WTCP(0x7415ece2, 0x35ed50c9),
+ WTCP(0x7400b69a, 0x361ae2d3), WTCP(0x73eb6e6e, 0x36486c86),
+ WTCP(0x73d61461, 0x3675edd9), WTCP(0x73c0a878, 0x36a366c6),
+ WTCP(0x73ab2ab4, 0x36d0d746), WTCP(0x73959b1b, 0x36fe3f52),
+ WTCP(0x737ff9ae, 0x372b9ee3), WTCP(0x736a4671, 0x3758f5f2),
+ WTCP(0x73548168, 0x37864477), WTCP(0x733eaa96, 0x37b38a6d),
+ WTCP(0x7328c1ff, 0x37e0c7cc), WTCP(0x7312c7a5, 0x380dfc8d),
+ WTCP(0x72fcbb8c, 0x383b28a9), WTCP(0x72e69db7, 0x38684c19),
+ WTCP(0x72d06e2b, 0x389566d6), WTCP(0x72ba2cea, 0x38c278d9),
+ WTCP(0x72a3d9f7, 0x38ef821c), WTCP(0x728d7557, 0x391c8297),
+ WTCP(0x7276ff0d, 0x39497a43), WTCP(0x7260771b, 0x39766919),
+ WTCP(0x7249dd86, 0x39a34f13), WTCP(0x72333251, 0x39d02c2a),
+ WTCP(0x721c7580, 0x39fd0056), WTCP(0x7205a716, 0x3a29cb91),
+ WTCP(0x71eec716, 0x3a568dd4), WTCP(0x71d7d585, 0x3a834717),
+ WTCP(0x71c0d265, 0x3aaff755), WTCP(0x71a9bdba, 0x3adc9e86),
+ WTCP(0x71929789, 0x3b093ca3), WTCP(0x717b5fd3, 0x3b35d1a5),
+ WTCP(0x7164169d, 0x3b625d86), WTCP(0x714cbbeb, 0x3b8ee03e),
+ WTCP(0x71354fc0, 0x3bbb59c7), WTCP(0x711dd220, 0x3be7ca1a),
+ WTCP(0x7106430e, 0x3c143130), WTCP(0x70eea28e, 0x3c408f03),
+ WTCP(0x70d6f0a4, 0x3c6ce38a), WTCP(0x70bf2d53, 0x3c992ec0),
+ WTCP(0x70a7589f, 0x3cc5709e), WTCP(0x708f728b, 0x3cf1a91c),
+ WTCP(0x70777b1c, 0x3d1dd835), WTCP(0x705f7255, 0x3d49fde1),
+ WTCP(0x70475839, 0x3d761a19), WTCP(0x702f2ccd, 0x3da22cd7),
+ WTCP(0x7016f014, 0x3dce3614), WTCP(0x6ffea212, 0x3dfa35c8),
+ WTCP(0x6fe642ca, 0x3e262bee), WTCP(0x6fcdd241, 0x3e52187f),
+ WTCP(0x6fb5507a, 0x3e7dfb73), WTCP(0x6f9cbd79, 0x3ea9d4c3),
+ WTCP(0x6f841942, 0x3ed5a46b), WTCP(0x6f6b63d8, 0x3f016a61),
+ WTCP(0x6f529d40, 0x3f2d26a0), WTCP(0x6f39c57d, 0x3f58d921),
+ WTCP(0x6f20dc92, 0x3f8481dd), WTCP(0x6f07e285, 0x3fb020ce),
+ WTCP(0x6eeed758, 0x3fdbb5ec), WTCP(0x6ed5bb10, 0x40074132),
+ WTCP(0x6ebc8db0, 0x4032c297), WTCP(0x6ea34f3d, 0x405e3a16),
+ WTCP(0x6e89ffb9, 0x4089a7a8), WTCP(0x6e709f2a, 0x40b50b46),
+ WTCP(0x6e572d93, 0x40e064ea), WTCP(0x6e3daaf8, 0x410bb48c),
+ WTCP(0x6e24175c, 0x4136fa27), WTCP(0x6e0a72c5, 0x416235b2),
+ WTCP(0x6df0bd35, 0x418d6729), WTCP(0x6dd6f6b1, 0x41b88e84),
+ WTCP(0x6dbd1f3c, 0x41e3abbc), WTCP(0x6da336dc, 0x420ebecb),
+ WTCP(0x6d893d93, 0x4239c7aa), WTCP(0x6d6f3365, 0x4264c653),
+ WTCP(0x6d551858, 0x428fbabe), WTCP(0x6d3aec6e, 0x42baa4e6),
+ WTCP(0x6d20afac, 0x42e584c3), WTCP(0x6d066215, 0x43105a50),
+ WTCP(0x6cec03af, 0x433b2585), WTCP(0x6cd1947c, 0x4365e65b),
+ WTCP(0x6cb71482, 0x43909ccd), WTCP(0x6c9c83c3, 0x43bb48d4),
+ WTCP(0x6c81e245, 0x43e5ea68), WTCP(0x6c67300b, 0x44108184),
+ WTCP(0x6c4c6d1a, 0x443b0e21), WTCP(0x6c319975, 0x44659039),
+ WTCP(0x6c16b521, 0x449007c4), WTCP(0x6bfbc021, 0x44ba74bd),
+ WTCP(0x6be0ba7b, 0x44e4d71c), WTCP(0x6bc5a431, 0x450f2edb),
+ WTCP(0x6baa7d49, 0x45397bf4), WTCP(0x6b8f45c7, 0x4563be60),
+ WTCP(0x6b73fdae, 0x458df619), WTCP(0x6b58a503, 0x45b82318),
+ WTCP(0x6b3d3bcb, 0x45e24556), WTCP(0x6b21c208, 0x460c5cce),
+ WTCP(0x6b0637c1, 0x46366978), WTCP(0x6aea9cf8, 0x46606b4e),
+ WTCP(0x6acef1b2, 0x468a624a), WTCP(0x6ab335f4, 0x46b44e65),
+ WTCP(0x6a9769c1, 0x46de2f99), WTCP(0x6a7b8d1e, 0x470805df),
+ WTCP(0x6a5fa010, 0x4731d131), WTCP(0x6a43a29a, 0x475b9188),
+ WTCP(0x6a2794c1, 0x478546de), WTCP(0x6a0b7689, 0x47aef12c),
+ WTCP(0x69ef47f6, 0x47d8906d), WTCP(0x69d3090e, 0x48022499),
+ WTCP(0x69b6b9d3, 0x482badab), WTCP(0x699a5a4c, 0x48552b9b),
+ WTCP(0x697dea7b, 0x487e9e64), WTCP(0x69616a65, 0x48a805ff),
+ WTCP(0x6944da10, 0x48d16265), WTCP(0x6928397e, 0x48fab391),
+ WTCP(0x690b88b5, 0x4923f97b), WTCP(0x68eec7b9, 0x494d341e),
+ WTCP(0x68d1f68f, 0x49766373), WTCP(0x68b5153a, 0x499f8774),
+ WTCP(0x689823bf, 0x49c8a01b), WTCP(0x687b2224, 0x49f1ad61),
+ WTCP(0x685e106c, 0x4a1aaf3f), WTCP(0x6840ee9b, 0x4a43a5b0),
+ WTCP(0x6823bcb7, 0x4a6c90ad), WTCP(0x68067ac3, 0x4a957030),
+ WTCP(0x67e928c5, 0x4abe4433), WTCP(0x67cbc6c0, 0x4ae70caf),
+ WTCP(0x67ae54ba, 0x4b0fc99d), WTCP(0x6790d2b6, 0x4b387af9),
+ WTCP(0x677340ba, 0x4b6120bb), WTCP(0x67559eca, 0x4b89badd),
+ WTCP(0x6737ecea, 0x4bb24958), WTCP(0x671a2b20, 0x4bdacc28),
+ WTCP(0x66fc596f, 0x4c034345), WTCP(0x66de77dc, 0x4c2baea9),
+ WTCP(0x66c0866d, 0x4c540e4e), WTCP(0x66a28524, 0x4c7c622d),
+ WTCP(0x66847408, 0x4ca4aa41), WTCP(0x6666531d, 0x4ccce684),
+ WTCP(0x66482267, 0x4cf516ee), WTCP(0x6629e1ec, 0x4d1d3b7a),
+ WTCP(0x660b91af, 0x4d455422), WTCP(0x65ed31b5, 0x4d6d60df),
+ WTCP(0x65cec204, 0x4d9561ac), WTCP(0x65b0429f, 0x4dbd5682),
+ WTCP(0x6591b38c, 0x4de53f5a), WTCP(0x657314cf, 0x4e0d1c30),
+ WTCP(0x6554666d, 0x4e34ecfc), WTCP(0x6535a86b, 0x4e5cb1b9),
+ WTCP(0x6516dacd, 0x4e846a60), WTCP(0x64f7fd98, 0x4eac16eb),
+ WTCP(0x64d910d1, 0x4ed3b755), WTCP(0x64ba147d, 0x4efb4b96),
+ WTCP(0x649b08a0, 0x4f22d3aa), WTCP(0x647bed3f, 0x4f4a4f89),
+ WTCP(0x645cc260, 0x4f71bf2e), WTCP(0x643d8806, 0x4f992293),
+ WTCP(0x641e3e38, 0x4fc079b1), WTCP(0x63fee4f8, 0x4fe7c483),
+ WTCP(0x63df7c4d, 0x500f0302), WTCP(0x63c0043b, 0x50363529),
+ WTCP(0x63a07cc7, 0x505d5af1), WTCP(0x6380e5f6, 0x50847454),
+ WTCP(0x63613fcd, 0x50ab814d), WTCP(0x63418a50, 0x50d281d5),
+ WTCP(0x6321c585, 0x50f975e6), WTCP(0x6301f171, 0x51205d7b),
+ WTCP(0x62e20e17, 0x5147388c), WTCP(0x62c21b7e, 0x516e0715),
+ WTCP(0x62a219aa, 0x5194c910), WTCP(0x628208a1, 0x51bb7e75),
+ WTCP(0x6261e866, 0x51e22740), WTCP(0x6241b8ff, 0x5208c36a),
+ WTCP(0x62217a72, 0x522f52ee), WTCP(0x62012cc2, 0x5255d5c5),
+ WTCP(0x61e0cff5, 0x527c4bea), WTCP(0x61c06410, 0x52a2b556),
+ WTCP(0x619fe918, 0x52c91204), WTCP(0x617f5f12, 0x52ef61ee),
+ WTCP(0x615ec603, 0x5315a50e), WTCP(0x613e1df0, 0x533bdb5d),
+ WTCP(0x611d66de, 0x536204d7), WTCP(0x60fca0d2, 0x53882175),
+ WTCP(0x60dbcbd1, 0x53ae3131), WTCP(0x60bae7e1, 0x53d43406),
+ WTCP(0x6099f505, 0x53fa29ed), WTCP(0x6078f344, 0x542012e1),
+ WTCP(0x6057e2a2, 0x5445eedb), WTCP(0x6036c325, 0x546bbdd7),
+ WTCP(0x601594d1, 0x54917fce), WTCP(0x5ff457ad, 0x54b734ba),
+ WTCP(0x5fd30bbc, 0x54dcdc96), WTCP(0x5fb1b104, 0x5502775c),
+ WTCP(0x5f90478a, 0x55280505), WTCP(0x5f6ecf53, 0x554d858d),
+ WTCP(0x5f4d4865, 0x5572f8ed), WTCP(0x5f2bb2c5, 0x55985f20),
+ WTCP(0x5f0a0e77, 0x55bdb81f), WTCP(0x5ee85b82, 0x55e303e6),
+ WTCP(0x5ec699e9, 0x5608426e), WTCP(0x5ea4c9b3, 0x562d73b2),
+ WTCP(0x5e82eae5, 0x565297ab), WTCP(0x5e60fd84, 0x5677ae54),
+ WTCP(0x5e3f0194, 0x569cb7a8), WTCP(0x5e1cf71c, 0x56c1b3a1),
+ WTCP(0x5dfade20, 0x56e6a239), WTCP(0x5dd8b6a7, 0x570b8369),
+ WTCP(0x5db680b4, 0x5730572e), WTCP(0x5d943c4e, 0x57551d80),
+ WTCP(0x5d71e979, 0x5779d65b), WTCP(0x5d4f883b, 0x579e81b8),
+ WTCP(0x5d2d189a, 0x57c31f92), WTCP(0x5d0a9a9a, 0x57e7afe4),
+ WTCP(0x5ce80e41, 0x580c32a7), WTCP(0x5cc57394, 0x5830a7d6),
+ WTCP(0x5ca2ca99, 0x58550f6c), WTCP(0x5c801354, 0x58796962),
+ WTCP(0x5c5d4dcc, 0x589db5b3), WTCP(0x5c3a7a05, 0x58c1f45b),
+ WTCP(0x5c179806, 0x58e62552), WTCP(0x5bf4a7d2, 0x590a4893),
+ WTCP(0x5bd1a971, 0x592e5e19), WTCP(0x5bae9ce7, 0x595265df),
+ WTCP(0x5b8b8239, 0x59765fde), WTCP(0x5b68596d, 0x599a4c12),
+ WTCP(0x5b452288, 0x59be2a74), WTCP(0x5b21dd90, 0x59e1faff),
+ WTCP(0x5afe8a8b, 0x5a05bdae), WTCP(0x5adb297d, 0x5a29727b),
+ WTCP(0x5ab7ba6c, 0x5a4d1960), WTCP(0x5a943d5e, 0x5a70b258),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP KBDWindow96[] = {
+ WTCP(0x7ffffffd, 0x0001a838), WTCP(0x7fffffe2, 0x00056e83),
+ WTCP(0x7fffff79, 0x000b9fda), WTCP(0x7ffffe45, 0x00150e8e),
+ WTCP(0x7ffffb4d, 0x0022aeeb), WTCP(0x7ffff4c6, 0x00359b36),
+ WTCP(0x7fffe792, 0x004f14ff), WTCP(0x7fffce8b, 0x0070858c),
+ WTCP(0x7fffa18f, 0x009b7d75), WTCP(0x7fff5439, 0x00d1b353),
+ WTCP(0x7ffed442, 0x0115018f), WTCP(0x7ffe0775, 0x01676335),
+ WTCP(0x7ffcc937, 0x01caefcb), WTCP(0x7ffae79f, 0x0241d62e),
+ WTCP(0x7ff82019, 0x02ce567f), WTCP(0x7ff41ba4, 0x0372bb25),
+ WTCP(0x7fee6ac3, 0x043150fc), WTCP(0x7fe68129, 0x050c5ec8),
+ WTCP(0x7fdbb164, 0x06061c0f), WTCP(0x7fcd2894, 0x0720a779),
+ WTCP(0x7fb9ea80, 0x085dfce2), WTCP(0x7fa0ce2e, 0x09bfeb4d),
+ WTCP(0x7f807b45, 0x0b480ae2), WTCP(0x7f576880, 0x0cf7b339),
+ WTCP(0x7f23db4e, 0x0ecff212), WTCP(0x7ee3e8ee, 0x10d182c0),
+ WTCP(0x7e95791f, 0x12fcc670), WTCP(0x7e364a74, 0x1551bd88),
+ WTCP(0x7dc3f864, 0x17d00238), WTCP(0x7d3c02fd, 0x1a76c47e),
+ WTCP(0x7c9bd82a, 0x1d44c7ad), WTCP(0x7be0de56, 0x203861a1),
+ WTCP(0x7b08803d, 0x234f7ba6), WTCP(0x7a103993, 0x26879530),
+ WTCP(0x78f5a442, 0x29ddc854), WTCP(0x77b685de, 0x2d4ed00f),
+ WTCP(0x7650dcf5, 0x30d7103d), WTCP(0x74c2ede4, 0x34729f2d),
+ WTCP(0x730b4edb, 0x381d50ad), WTCP(0x7128f2c1, 0x3bd2c273),
+ WTCP(0x6f1b32a9, 0x3f8e698f), WTCP(0x6ce1d5a0, 0x434ba0d6),
+ WTCP(0x6a7d16a3, 0x4705b7e5), WTCP(0x67eda890, 0x4ab80288),
+ WTCP(0x6534b7f8, 0x4e5de842), WTCP(0x6253eacd, 0x51f2f39a),
+ WTCP(0x5f4d5de1, 0x5572e0f7), WTCP(0x5c23a04a, 0x58d9acb9),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP KBDWindow120[] = {
+ WTCP(0x7ffffffe, 0x00017b6f), WTCP(0x7fffffef, 0x00042d2f),
+ WTCP(0x7fffffbb, 0x000849d0), WTCP(0x7fffff36, 0x000e3494),
+ WTCP(0x7ffffe0c, 0x00165efd), WTCP(0x7ffffbac, 0x002149be),
+ WTCP(0x7ffff72e, 0x002f854c), WTCP(0x7fffef24, 0x0041b235),
+ WTCP(0x7fffe167, 0x0058814f), WTCP(0x7fffcacd, 0x0074b3af),
+ WTCP(0x7fffa6d0, 0x00971a67), WTCP(0x7fff6f1e, 0x00c0960e),
+ WTCP(0x7fff1b12, 0x00f21602), WTCP(0x7ffe9f0b, 0x012c9775),
+ WTCP(0x7ffdebb2, 0x01712428), WTCP(0x7ffced1b, 0x01c0d0f7),
+ WTCP(0x7ffb89c2, 0x021cbc12), WTCP(0x7ff9a17c, 0x02860b05),
+ WTCP(0x7ff70c39, 0x02fde875), WTCP(0x7ff398bc, 0x038581b3),
+ WTCP(0x7fef0b3b, 0x041e040c), WTCP(0x7fe91bf3, 0x04c899f4),
+ WTCP(0x7fe175ba, 0x05866803), WTCP(0x7fd7b493, 0x065889d5),
+ WTCP(0x7fcb6459, 0x07400ed4), WTCP(0x7fbbff82, 0x083df6e9),
+ WTCP(0x7fa8ee09, 0x09532f37), WTCP(0x7f91849a, 0x0a808ed1),
+ WTCP(0x7f7503f2, 0x0bc6d381), WTCP(0x7f52989a, 0x0d269eb0),
+ WTCP(0x7f295af4, 0x0ea07270), WTCP(0x7ef84fb6, 0x1034aeb6),
+ WTCP(0x7ebe68c5, 0x11e38ed2), WTCP(0x7e7a8686, 0x13ad2733),
+ WTCP(0x7e2b79a3, 0x1591636d), WTCP(0x7dd0053c, 0x179004a7),
+ WTCP(0x7d66e18b, 0x19a8a05f), WTCP(0x7ceebef0, 0x1bda9fa2),
+ WTCP(0x7c664953, 0x1e253ea1), WTCP(0x7bcc2be8, 0x20878cce),
+ WTCP(0x7b1f1526, 0x23006d5d), WTCP(0x7a5dbb01, 0x258e9848),
+ WTCP(0x7986df3e, 0x28309bc6), WTCP(0x789953e0, 0x2ae4de3e),
+ WTCP(0x7793ff88, 0x2da9a0a8), WTCP(0x7675e1cc, 0x307d0163),
+ WTCP(0x753e1763, 0x335cff72), WTCP(0x73ebde10, 0x36477e1f),
+ WTCP(0x727e984e, 0x393a48f1), WTCP(0x70f5d09b, 0x3c3317f9),
+ WTCP(0x6f513c60, 0x3f2f945c), WTCP(0x6d90be61, 0x422d5d18),
+ WTCP(0x6bb468b1, 0x452a0bf3), WTCP(0x69bc7e1e, 0x48233a81),
+ WTCP(0x67a97317, 0x4b16873e), WTCP(0x657bedfa, 0x4e019a9d),
+ WTCP(0x6334c6d2, 0x50e22c0b), WTCP(0x60d50689, 0x53b606cb),
+ WTCP(0x5e5de588, 0x567b0ea7), WTCP(0x5bd0c9c6, 0x592f4460),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP KBDWindow128[] = {
+ WTCP(0x7ffffffe, 0x00016f63), WTCP(0x7ffffff1, 0x0003e382),
+ WTCP(0x7fffffc7, 0x00078f64), WTCP(0x7fffff5d, 0x000cc323),
+ WTCP(0x7ffffe76, 0x0013d9ed), WTCP(0x7ffffcaa, 0x001d3a9d),
+ WTCP(0x7ffff953, 0x0029581f), WTCP(0x7ffff372, 0x0038b1bd),
+ WTCP(0x7fffe98b, 0x004bd34d), WTCP(0x7fffd975, 0x00635538),
+ WTCP(0x7fffc024, 0x007fdc64), WTCP(0x7fff995b, 0x00a219f1),
+ WTCP(0x7fff5f5b, 0x00cacad0), WTCP(0x7fff0a75, 0x00fab72d),
+ WTCP(0x7ffe9091, 0x0132b1af), WTCP(0x7ffde49e, 0x01739689),
+ WTCP(0x7ffcf5ef, 0x01be4a63), WTCP(0x7ffbaf84, 0x0213b910),
+ WTCP(0x7ff9f73a, 0x0274d41e), WTCP(0x7ff7acf1, 0x02e2913a),
+ WTCP(0x7ff4a99a, 0x035de86c), WTCP(0x7ff0be3d, 0x03e7d233),
+ WTCP(0x7febb2f1, 0x0481457c), WTCP(0x7fe545d4, 0x052b357c),
+ WTCP(0x7fdd2a02, 0x05e68f77), WTCP(0x7fd30695, 0x06b4386f),
+ WTCP(0x7fc675b4, 0x07950acb), WTCP(0x7fb703be, 0x0889d3ef),
+ WTCP(0x7fa42e89, 0x099351e0), WTCP(0x7f8d64d8, 0x0ab230e0),
+ WTCP(0x7f7205f8, 0x0be70923), WTCP(0x7f516195, 0x0d325c93),
+ WTCP(0x7f2ab7d0, 0x0e9494ae), WTCP(0x7efd3997, 0x100e0085),
+ WTCP(0x7ec8094a, 0x119ed2ef), WTCP(0x7e8a3ba7, 0x134720d8),
+ WTCP(0x7e42d906, 0x1506dfdc), WTCP(0x7df0dee4, 0x16dde50b),
+ WTCP(0x7d9341b4, 0x18cbe3f7), WTCP(0x7d28ef02, 0x1ad06e07),
+ WTCP(0x7cb0cfcc, 0x1ceaf215), WTCP(0x7c29cb20, 0x1f1abc4f),
+ WTCP(0x7b92c8eb, 0x215ef677), WTCP(0x7aeab4ec, 0x23b6a867),
+ WTCP(0x7a3081d0, 0x2620b8ec), WTCP(0x79632c5a, 0x289beef5),
+ WTCP(0x7881be95, 0x2b26f30b), WTCP(0x778b5304, 0x2dc0511f),
+ WTCP(0x767f17c0, 0x30667aa2), WTCP(0x755c5178, 0x3317c8dd),
+ WTCP(0x74225e50, 0x35d27f98), WTCP(0x72d0b887, 0x3894cff3),
+ WTCP(0x7166f8e7, 0x3b5cdb7b), WTCP(0x6fe4d8e8, 0x3e28b770),
+ WTCP(0x6e4a3491, 0x40f6702a), WTCP(0x6c970bfc, 0x43c40caa),
+ WTCP(0x6acb8483, 0x468f9231), WTCP(0x68e7e994, 0x495707f5),
+ WTCP(0x66ecad1c, 0x4c187ac7), WTCP(0x64da6797, 0x4ed200c5),
+ WTCP(0x62b1d7b7, 0x5181bcea), WTCP(0x6073e1ae, 0x5425e28e),
+ WTCP(0x5e218e16, 0x56bcb8c2), WTCP(0x5bbc0875, 0x59449d76),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP KBDWindow256[] = {
+ WTCP(0x7fffffff, 0x000103c8), WTCP(0x7ffffffc, 0x000203ad),
+ WTCP(0x7ffffff5, 0x0003410a), WTCP(0x7fffffe9, 0x0004c6ce),
+ WTCP(0x7fffffd4, 0x00069ee0), WTCP(0x7fffffb2, 0x0008d376),
+ WTCP(0x7fffff7d, 0x000b6f5a), WTCP(0x7fffff2e, 0x000e7dfd),
+ WTCP(0x7ffffeba, 0x00120b83), WTCP(0x7ffffe16, 0x001624cd),
+ WTCP(0x7ffffd30, 0x001ad778), WTCP(0x7ffffbf3, 0x002031e2),
+ WTCP(0x7ffffa48, 0x00264330), WTCP(0x7ffff80d, 0x002d1b4b),
+ WTCP(0x7ffff51d, 0x0034cae6), WTCP(0x7ffff147, 0x003d637c),
+ WTCP(0x7fffec54, 0x0046f751), WTCP(0x7fffe5fe, 0x00519974),
+ WTCP(0x7fffddf3, 0x005d5dba), WTCP(0x7fffd3d2, 0x006a58c1),
+ WTCP(0x7fffc72a, 0x00789feb), WTCP(0x7fffb772, 0x0088495d),
+ WTCP(0x7fffa40e, 0x00996bfb), WTCP(0x7fff8c46, 0x00ac1f63),
+ WTCP(0x7fff6f46, 0x00c07bec), WTCP(0x7fff4c19, 0x00d69a9b),
+ WTCP(0x7fff21a6, 0x00ee9523), WTCP(0x7ffeeeab, 0x010885d9),
+ WTCP(0x7ffeb1b8, 0x012487b1), WTCP(0x7ffe692f, 0x0142b631),
+ WTCP(0x7ffe1335, 0x01632d6f), WTCP(0x7ffdadb8, 0x01860a00),
+ WTCP(0x7ffd3661, 0x01ab68f3), WTCP(0x7ffcaa91, 0x01d367c5),
+ WTCP(0x7ffc075b, 0x01fe2453), WTCP(0x7ffb497e, 0x022bbcd0),
+ WTCP(0x7ffa6d59, 0x025c4fba), WTCP(0x7ff96eeb, 0x028ffbc7),
+ WTCP(0x7ff849c6, 0x02c6dfdb), WTCP(0x7ff6f90b, 0x03011afc),
+ WTCP(0x7ff57760, 0x033ecc3a), WTCP(0x7ff3bee7, 0x038012a8),
+ WTCP(0x7ff1c939, 0x03c50d47), WTCP(0x7fef8f5a, 0x040ddaf6),
+ WTCP(0x7fed09b4, 0x045a9a64), WTCP(0x7fea300e, 0x04ab69f9),
+ WTCP(0x7fe6f980, 0x050067c7), WTCP(0x7fe35c70, 0x0559b17b),
+ WTCP(0x7fdf4e88, 0x05b76443), WTCP(0x7fdac4ad, 0x06199cc4),
+ WTCP(0x7fd5b2f8, 0x068076fe), WTCP(0x7fd00caf, 0x06ec0e41),
+ WTCP(0x7fc9c441, 0x075c7d16), WTCP(0x7fc2cb3b, 0x07d1dd2c),
+ WTCP(0x7fbb1242, 0x084c4745), WTCP(0x7fb28915, 0x08cbd323),
+ WTCP(0x7fa91e7e, 0x09509778), WTCP(0x7f9ec059, 0x09daa9cc),
+ WTCP(0x7f935b87, 0x0a6a1e74), WTCP(0x7f86dbf2, 0x0aff0877),
+ WTCP(0x7f792c8a, 0x0b997983), WTCP(0x7f6a3746, 0x0c3981d6),
+ WTCP(0x7f59e520, 0x0cdf3030), WTCP(0x7f481e1c, 0x0d8a91c3),
+ WTCP(0x7f34c949, 0x0e3bb222), WTCP(0x7f1fccc3, 0x0ef29b30),
+ WTCP(0x7f090dbc, 0x0faf5513), WTCP(0x7ef0707d, 0x1071e629),
+ WTCP(0x7ed5d872, 0x113a52f4), WTCP(0x7eb92831, 0x12089e14),
+ WTCP(0x7e9a4183, 0x12dcc836), WTCP(0x7e790571, 0x13b6d010),
+ WTCP(0x7e55544e, 0x1496b24f), WTCP(0x7e2f0dc8, 0x157c6998),
+ WTCP(0x7e0610f1, 0x1667ee77), WTCP(0x7dda3c54, 0x17593760),
+ WTCP(0x7dab6e06, 0x185038a3), WTCP(0x7d7983b3, 0x194ce46e),
+ WTCP(0x7d445ab5, 0x1a4f2ac4), WTCP(0x7d0bd028, 0x1b56f981),
+ WTCP(0x7ccfc0fd, 0x1c643c54), WTCP(0x7c900a11, 0x1d76dcc2),
+ WTCP(0x7c4c8844, 0x1e8ec227), WTCP(0x7c05188d, 0x1fabd1bb),
+ WTCP(0x7bb99817, 0x20cdee92), WTCP(0x7b69e455, 0x21f4f9a6),
+ WTCP(0x7b15db1a, 0x2320d1dc), WTCP(0x7abd5ab8, 0x2451540c),
+ WTCP(0x7a604213, 0x25865b09), WTCP(0x79fe70bf, 0x26bfbfaf),
+ WTCP(0x7997c716, 0x27fd58ed), WTCP(0x792c2654, 0x293efbd0),
+ WTCP(0x78bb70b0, 0x2a847b97), WTCP(0x78458976, 0x2bcda9bb),
+ WTCP(0x77ca551d, 0x2d1a5608), WTCP(0x7749b965, 0x2e6a4ea6),
+ WTCP(0x76c39d68, 0x2fbd6036), WTCP(0x7637e9b8, 0x311355dc),
+ WTCP(0x75a68873, 0x326bf95a), WTCP(0x750f6559, 0x33c71326),
+ WTCP(0x74726de1, 0x35246a7e), WTCP(0x73cf914f, 0x3683c582),
+ WTCP(0x7326c0c8, 0x37e4e94b), WTCP(0x7277ef5f, 0x39479a08),
+ WTCP(0x71c3122f, 0x3aab9b14), WTCP(0x71082063, 0x3c10af11),
+ WTCP(0x7047134a, 0x3d769807), WTCP(0x6f7fe661, 0x3edd177c),
+ WTCP(0x6eb29763, 0x4043ee92), WTCP(0x6ddf2651, 0x41aade26),
+ WTCP(0x6d05957c, 0x4311a6e8), WTCP(0x6c25e98f, 0x4478097b),
+ WTCP(0x6b402991, 0x45ddc693), WTCP(0x6a545ef0, 0x47429f13),
+ WTCP(0x6962957f, 0x48a65427), WTCP(0x686adb7c, 0x4a08a764),
+ WTCP(0x676d418d, 0x4b695ae8), WTCP(0x6669dac2, 0x4cc83171),
+ WTCP(0x6560bc90, 0x4e24ee7d), WTCP(0x6451fecf, 0x4f7f5668),
+ WTCP(0x633dbbb1, 0x50d72e85), WTCP(0x62240fbd, 0x522c3d3b),
+ WTCP(0x610519c7, 0x537e4a1f), WTCP(0x5fe0fae3, 0x54cd1e10),
+ WTCP(0x5eb7d65c, 0x5618834c), WTCP(0x5d89d1a5, 0x57604590),
+ WTCP(0x5c57144b, 0x58a43227), WTCP(0x5b1fc7e6, 0x59e41808),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP KBDWindow768[] = {
+ WTCP(0x7fffff85, 0x000b11d9), WTCP(0x7ffffef0, 0x00107aa9),
+ WTCP(0x7ffffe3e, 0x0015351c), WTCP(0x7ffffd6c, 0x0019b0a1),
+ WTCP(0x7ffffc77, 0x001e1656), WTCP(0x7ffffb5b, 0x00227a80),
+ WTCP(0x7ffffa16, 0x0026e8d3), WTCP(0x7ffff8a4, 0x002b68c9),
+ WTCP(0x7ffff700, 0x002fff8a), WTCP(0x7ffff528, 0x0034b0d9),
+ WTCP(0x7ffff316, 0x00397f9c), WTCP(0x7ffff0c6, 0x003e6e22),
+ WTCP(0x7fffee35, 0x00437e53), WTCP(0x7fffeb5b, 0x0048b1d0),
+ WTCP(0x7fffe836, 0x004e0a05), WTCP(0x7fffe4be, 0x00538837),
+ WTCP(0x7fffe0ef, 0x00592d8e), WTCP(0x7fffdcc3, 0x005efb1a),
+ WTCP(0x7fffd832, 0x0064f1da), WTCP(0x7fffd337, 0x006b12c1),
+ WTCP(0x7fffcdcb, 0x00715eb4), WTCP(0x7fffc7e7, 0x0077d692),
+ WTCP(0x7fffc182, 0x007e7b30), WTCP(0x7fffba96, 0x00854d61),
+ WTCP(0x7fffb31b, 0x008c4df0), WTCP(0x7fffab06, 0x00937da6),
+ WTCP(0x7fffa251, 0x009add48), WTCP(0x7fff98f1, 0x00a26d98),
+ WTCP(0x7fff8edd, 0x00aa2f57), WTCP(0x7fff840b, 0x00b22343),
+ WTCP(0x7fff7870, 0x00ba4a19), WTCP(0x7fff6c02, 0x00c2a495),
+ WTCP(0x7fff5eb5, 0x00cb3371), WTCP(0x7fff507e, 0x00d3f767),
+ WTCP(0x7fff4150, 0x00dcf130), WTCP(0x7fff311f, 0x00e62183),
+ WTCP(0x7fff1fde, 0x00ef8919), WTCP(0x7fff0d7f, 0x00f928a7),
+ WTCP(0x7ffef9f4, 0x010300e5), WTCP(0x7ffee52f, 0x010d1288),
+ WTCP(0x7ffecf20, 0x01175e47), WTCP(0x7ffeb7b8, 0x0121e4d6),
+ WTCP(0x7ffe9ee6, 0x012ca6eb), WTCP(0x7ffe849b, 0x0137a53b),
+ WTCP(0x7ffe68c4, 0x0142e07a), WTCP(0x7ffe4b50, 0x014e595c),
+ WTCP(0x7ffe2c2c, 0x015a1095), WTCP(0x7ffe0b45, 0x016606da),
+ WTCP(0x7ffde888, 0x01723cde), WTCP(0x7ffdc3df, 0x017eb353),
+ WTCP(0x7ffd9d37, 0x018b6aed), WTCP(0x7ffd7479, 0x0198645f),
+ WTCP(0x7ffd4990, 0x01a5a05b), WTCP(0x7ffd1c63, 0x01b31f92),
+ WTCP(0x7ffcecdc, 0x01c0e2b8), WTCP(0x7ffcbae2, 0x01ceea7d),
+ WTCP(0x7ffc865c, 0x01dd3793), WTCP(0x7ffc4f2f, 0x01ebcaaa),
+ WTCP(0x7ffc1542, 0x01faa472), WTCP(0x7ffbd879, 0x0209c59c),
+ WTCP(0x7ffb98b7, 0x02192ed7), WTCP(0x7ffb55e0, 0x0228e0d2),
+ WTCP(0x7ffb0fd6, 0x0238dc3c), WTCP(0x7ffac679, 0x024921c3),
+ WTCP(0x7ffa79ac, 0x0259b215), WTCP(0x7ffa294d, 0x026a8dde),
+ WTCP(0x7ff9d53b, 0x027bb5cc), WTCP(0x7ff97d54, 0x028d2a8a),
+ WTCP(0x7ff92175, 0x029eecc3), WTCP(0x7ff8c17a, 0x02b0fd23),
+ WTCP(0x7ff85d3f, 0x02c35c53), WTCP(0x7ff7f49d, 0x02d60afd),
+ WTCP(0x7ff7876e, 0x02e909ca), WTCP(0x7ff7158b, 0x02fc5960),
+ WTCP(0x7ff69eca, 0x030ffa69), WTCP(0x7ff62303, 0x0323ed89),
+ WTCP(0x7ff5a20a, 0x03383367), WTCP(0x7ff51bb3, 0x034ccca7),
+ WTCP(0x7ff48fd3, 0x0361b9ed), WTCP(0x7ff3fe3c, 0x0376fbdd),
+ WTCP(0x7ff366be, 0x038c9317), WTCP(0x7ff2c929, 0x03a2803e),
+ WTCP(0x7ff2254e, 0x03b8c3f2), WTCP(0x7ff17afa, 0x03cf5ed1),
+ WTCP(0x7ff0c9f9, 0x03e6517a), WTCP(0x7ff01218, 0x03fd9c8a),
+ WTCP(0x7fef5321, 0x0415409c), WTCP(0x7fee8cde, 0x042d3e4d),
+ WTCP(0x7fedbf17, 0x04459634), WTCP(0x7fece993, 0x045e48ec),
+ WTCP(0x7fec0c18, 0x0477570a), WTCP(0x7feb266a, 0x0490c127),
+ WTCP(0x7fea384e, 0x04aa87d5), WTCP(0x7fe94186, 0x04c4abaa),
+ WTCP(0x7fe841d3, 0x04df2d37), WTCP(0x7fe738f4, 0x04fa0d0d),
+ WTCP(0x7fe626a9, 0x05154bbc), WTCP(0x7fe50aaf, 0x0530e9d3),
+ WTCP(0x7fe3e4c1, 0x054ce7dd), WTCP(0x7fe2b49b, 0x05694667),
+ WTCP(0x7fe179f6, 0x058605fa), WTCP(0x7fe0348b, 0x05a3271e),
+ WTCP(0x7fdee410, 0x05c0aa5c), WTCP(0x7fdd883b, 0x05de9038),
+ WTCP(0x7fdc20c1, 0x05fcd935), WTCP(0x7fdaad53, 0x061b85d6),
+ WTCP(0x7fd92da5, 0x063a969c), WTCP(0x7fd7a166, 0x065a0c06),
+ WTCP(0x7fd60844, 0x0679e690), WTCP(0x7fd461ee, 0x069a26b6),
+ WTCP(0x7fd2ae10, 0x06baccf2), WTCP(0x7fd0ec55, 0x06dbd9bd),
+ WTCP(0x7fcf1c65, 0x06fd4d8c), WTCP(0x7fcd3de9, 0x071f28d3),
+ WTCP(0x7fcb5088, 0x07416c06), WTCP(0x7fc953e6, 0x07641794),
+ WTCP(0x7fc747a8, 0x07872bee), WTCP(0x7fc52b70, 0x07aaa97f),
+ WTCP(0x7fc2fedf, 0x07ce90b4), WTCP(0x7fc0c195, 0x07f2e1f4),
+ WTCP(0x7fbe732f, 0x08179da7), WTCP(0x7fbc134b, 0x083cc431),
+ WTCP(0x7fb9a183, 0x086255f7), WTCP(0x7fb71d72, 0x08885359),
+ WTCP(0x7fb486af, 0x08aebcb5), WTCP(0x7fb1dcd3, 0x08d59269),
+ WTCP(0x7faf1f72, 0x08fcd4cf), WTCP(0x7fac4e21, 0x09248440),
+ WTCP(0x7fa96873, 0x094ca111), WTCP(0x7fa66df8, 0x09752b98),
+ WTCP(0x7fa35e40, 0x099e2425), WTCP(0x7fa038db, 0x09c78b09),
+ WTCP(0x7f9cfd54, 0x09f16090), WTCP(0x7f99ab38, 0x0a1ba507),
+ WTCP(0x7f964210, 0x0a4658b6), WTCP(0x7f92c165, 0x0a717be2),
+ WTCP(0x7f8f28bf, 0x0a9d0ed1), WTCP(0x7f8b77a4, 0x0ac911c4),
+ WTCP(0x7f87ad97, 0x0af584fb), WTCP(0x7f83ca1d, 0x0b2268b2),
+ WTCP(0x7f7fccb5, 0x0b4fbd23), WTCP(0x7f7bb4e2, 0x0b7d8288),
+ WTCP(0x7f778221, 0x0babb915), WTCP(0x7f7333f1, 0x0bda60fd),
+ WTCP(0x7f6ec9cd, 0x0c097a72), WTCP(0x7f6a4330, 0x0c3905a1),
+ WTCP(0x7f659f94, 0x0c6902b6), WTCP(0x7f60de70, 0x0c9971d9),
+ WTCP(0x7f5bff3b, 0x0cca5331), WTCP(0x7f57016b, 0x0cfba6e3),
+ WTCP(0x7f51e474, 0x0d2d6d0e), WTCP(0x7f4ca7c8, 0x0d5fa5d2),
+ WTCP(0x7f474ad9, 0x0d92514a), WTCP(0x7f41cd17, 0x0dc56f90),
+ WTCP(0x7f3c2df1, 0x0df900bb), WTCP(0x7f366cd5, 0x0e2d04de),
+ WTCP(0x7f30892e, 0x0e617c0a), WTCP(0x7f2a8269, 0x0e96664e),
+ WTCP(0x7f2457ef, 0x0ecbc3b5), WTCP(0x7f1e0929, 0x0f019449),
+ WTCP(0x7f17957e, 0x0f37d80f), WTCP(0x7f10fc55, 0x0f6e8f0c),
+ WTCP(0x7f0a3d14, 0x0fa5b940), WTCP(0x7f03571d, 0x0fdd56a8),
+ WTCP(0x7efc49d4, 0x10156740), WTCP(0x7ef5149b, 0x104deb00),
+ WTCP(0x7eedb6d2, 0x1086e1dd), WTCP(0x7ee62fda, 0x10c04bca),
+ WTCP(0x7ede7f11, 0x10fa28b7), WTCP(0x7ed6a3d5, 0x11347890),
+ WTCP(0x7ece9d81, 0x116f3b3f), WTCP(0x7ec66b73, 0x11aa70ac),
+ WTCP(0x7ebe0d04, 0x11e618ba), WTCP(0x7eb5818d, 0x1222334c),
+ WTCP(0x7eacc869, 0x125ec03e), WTCP(0x7ea3e0ef, 0x129bbf6e),
+ WTCP(0x7e9aca75, 0x12d930b2), WTCP(0x7e918452, 0x131713e2),
+ WTCP(0x7e880ddb, 0x135568cf), WTCP(0x7e7e6665, 0x13942f49),
+ WTCP(0x7e748d43, 0x13d3671e), WTCP(0x7e6a81c8, 0x14131017),
+ WTCP(0x7e604347, 0x145329fa), WTCP(0x7e55d111, 0x1493b48c),
+ WTCP(0x7e4b2a76, 0x14d4af8e), WTCP(0x7e404ec8, 0x15161abe),
+ WTCP(0x7e353d55, 0x1557f5d7), WTCP(0x7e29f56c, 0x159a4090),
+ WTCP(0x7e1e765c, 0x15dcfaa0), WTCP(0x7e12bf72, 0x162023b7),
+ WTCP(0x7e06cffc, 0x1663bb86), WTCP(0x7dfaa746, 0x16a7c1b9),
+ WTCP(0x7dee449e, 0x16ec35f7), WTCP(0x7de1a74e, 0x173117e9),
+ WTCP(0x7dd4cea3, 0x17766731), WTCP(0x7dc7b9e7, 0x17bc236f),
+ WTCP(0x7dba6865, 0x18024c40), WTCP(0x7dacd968, 0x1848e13f),
+ WTCP(0x7d9f0c3a, 0x188fe204), WTCP(0x7d910025, 0x18d74e22),
+ WTCP(0x7d82b472, 0x191f252c), WTCP(0x7d74286c, 0x196766ae),
+ WTCP(0x7d655b5b, 0x19b01236), WTCP(0x7d564c8a, 0x19f9274b),
+ WTCP(0x7d46fb40, 0x1a42a574), WTCP(0x7d3766c8, 0x1a8c8c32),
+ WTCP(0x7d278e6a, 0x1ad6db06), WTCP(0x7d17716f, 0x1b21916c),
+ WTCP(0x7d070f22, 0x1b6caedf), WTCP(0x7cf666cb, 0x1bb832d5),
+ WTCP(0x7ce577b3, 0x1c041cc2), WTCP(0x7cd44124, 0x1c506c17),
+ WTCP(0x7cc2c269, 0x1c9d2044), WTCP(0x7cb0faca, 0x1cea38b2),
+ WTCP(0x7c9ee992, 0x1d37b4cc), WTCP(0x7c8c8e0c, 0x1d8593f5),
+ WTCP(0x7c79e782, 0x1dd3d592), WTCP(0x7c66f541, 0x1e227903),
+ WTCP(0x7c53b692, 0x1e717da3), WTCP(0x7c402ac3, 0x1ec0e2cf),
+ WTCP(0x7c2c5120, 0x1f10a7dc), WTCP(0x7c1828f6, 0x1f60cc21),
+ WTCP(0x7c03b193, 0x1fb14eef), WTCP(0x7beeea44, 0x20022f96),
+ WTCP(0x7bd9d259, 0x20536d61), WTCP(0x7bc46921, 0x20a5079a),
+ WTCP(0x7baeadec, 0x20f6fd8a), WTCP(0x7b98a00b, 0x21494e73),
+ WTCP(0x7b823ecf, 0x219bf998), WTCP(0x7b6b898b, 0x21eefe37),
+ WTCP(0x7b547f93, 0x22425b8d), WTCP(0x7b3d203a, 0x229610d4),
+ WTCP(0x7b256ad5, 0x22ea1d42), WTCP(0x7b0d5ebb, 0x233e800c),
+ WTCP(0x7af4fb42, 0x23933864), WTCP(0x7adc3fc2, 0x23e8457a),
+ WTCP(0x7ac32b95, 0x243da679), WTCP(0x7aa9be14, 0x24935a8d),
+ WTCP(0x7a8ff69a, 0x24e960dd), WTCP(0x7a75d485, 0x253fb88e),
+ WTCP(0x7a5b5731, 0x259660c3), WTCP(0x7a407dfe, 0x25ed589c),
+ WTCP(0x7a25484c, 0x26449f38), WTCP(0x7a09b57c, 0x269c33b1),
+ WTCP(0x79edc4f1, 0x26f41522), WTCP(0x79d1760e, 0x274c42a0),
+ WTCP(0x79b4c83b, 0x27a4bb40), WTCP(0x7997badd, 0x27fd7e15),
+ WTCP(0x797a4d5e, 0x28568a2f), WTCP(0x795c7f26, 0x28afde9a),
+ WTCP(0x793e4fa3, 0x29097a63), WTCP(0x791fbe40, 0x29635c92),
+ WTCP(0x7900ca6e, 0x29bd842e), WTCP(0x78e1739c, 0x2a17f03e),
+ WTCP(0x78c1b93d, 0x2a729fc2), WTCP(0x78a19ac4, 0x2acd91bc),
+ WTCP(0x788117a7, 0x2b28c52a), WTCP(0x78602f5e, 0x2b843909),
+ WTCP(0x783ee163, 0x2bdfec54), WTCP(0x781d2d2f, 0x2c3bde02),
+ WTCP(0x77fb1241, 0x2c980d0a), WTCP(0x77d89017, 0x2cf47862),
+ WTCP(0x77b5a632, 0x2d511efb), WTCP(0x77925416, 0x2dadffc6),
+ WTCP(0x776e9947, 0x2e0b19b3), WTCP(0x774a754d, 0x2e686bae),
+ WTCP(0x7725e7b0, 0x2ec5f4a4), WTCP(0x7700effd, 0x2f23b37d),
+ WTCP(0x76db8dbf, 0x2f81a721), WTCP(0x76b5c088, 0x2fdfce77),
+ WTCP(0x768f87e8, 0x303e2863), WTCP(0x7668e375, 0x309cb3c8),
+ WTCP(0x7641d2c4, 0x30fb6f88), WTCP(0x761a556e, 0x315a5a82),
+ WTCP(0x75f26b0e, 0x31b97394), WTCP(0x75ca1341, 0x3218b99c),
+ WTCP(0x75a14da8, 0x32782b74), WTCP(0x757819e4, 0x32d7c7f6),
+ WTCP(0x754e779a, 0x33378dfc), WTCP(0x75246671, 0x33977c5b),
+ WTCP(0x74f9e613, 0x33f791e9), WTCP(0x74cef62b, 0x3457cd7c),
+ WTCP(0x74a3966a, 0x34b82de6), WTCP(0x7477c67f, 0x3518b1f9),
+ WTCP(0x744b861e, 0x35795887), WTCP(0x741ed4ff, 0x35da205e),
+ WTCP(0x73f1b2da, 0x363b084e), WTCP(0x73c41f6b, 0x369c0f24),
+ WTCP(0x73961a71, 0x36fd33ac), WTCP(0x7367a3ac, 0x375e74b1),
+ WTCP(0x7338bae1, 0x37bfd0ff), WTCP(0x73095fd7, 0x3821475f),
+ WTCP(0x72d99257, 0x3882d699), WTCP(0x72a9522d, 0x38e47d75),
+ WTCP(0x72789f28, 0x39463aba), WTCP(0x7247791b, 0x39a80d2e),
+ WTCP(0x7215dfda, 0x3a09f397), WTCP(0x71e3d33d, 0x3a6becba),
+ WTCP(0x71b1531f, 0x3acdf75a), WTCP(0x717e5f5d, 0x3b30123b),
+ WTCP(0x714af7d7, 0x3b923c20), WTCP(0x71171c72, 0x3bf473cc),
+ WTCP(0x70e2cd14, 0x3c56b7ff), WTCP(0x70ae09a6, 0x3cb9077b),
+ WTCP(0x7078d215, 0x3d1b6101), WTCP(0x7043264f, 0x3d7dc353),
+ WTCP(0x700d0648, 0x3de02d2e), WTCP(0x6fd671f5, 0x3e429d55),
+ WTCP(0x6f9f694f, 0x3ea51285), WTCP(0x6f67ec52, 0x3f078b7f),
+ WTCP(0x6f2ffafb, 0x3f6a0701), WTCP(0x6ef7954e, 0x3fcc83ca),
+ WTCP(0x6ebebb4e, 0x402f009a), WTCP(0x6e856d05, 0x40917c2e),
+ WTCP(0x6e4baa7e, 0x40f3f546), WTCP(0x6e1173c6, 0x41566aa1),
+ WTCP(0x6dd6c8ef, 0x41b8dafc), WTCP(0x6d9baa0f, 0x421b4518),
+ WTCP(0x6d60173d, 0x427da7b1), WTCP(0x6d241094, 0x42e00189),
+ WTCP(0x6ce79632, 0x4342515e), WTCP(0x6caaa839, 0x43a495ef),
+ WTCP(0x6c6d46ce, 0x4406cdfd), WTCP(0x6c2f7218, 0x4468f848),
+ WTCP(0x6bf12a42, 0x44cb138f), WTCP(0x6bb26f7b, 0x452d1e94),
+ WTCP(0x6b7341f5, 0x458f1818), WTCP(0x6b33a1e3, 0x45f0fede),
+ WTCP(0x6af38f7e, 0x4652d1a6), WTCP(0x6ab30b01, 0x46b48f34),
+ WTCP(0x6a7214ab, 0x4716364c), WTCP(0x6a30acbd, 0x4777c5b2),
+ WTCP(0x69eed37c, 0x47d93c2a), WTCP(0x69ac8930, 0x483a987a),
+ WTCP(0x6969ce24, 0x489bd968), WTCP(0x6926a2a8, 0x48fcfdbb),
+ WTCP(0x68e3070c, 0x495e043b), WTCP(0x689efba7, 0x49beebb0),
+ WTCP(0x685a80cf, 0x4a1fb2e5), WTCP(0x681596e1, 0x4a8058a4),
+ WTCP(0x67d03e3b, 0x4ae0dbb8), WTCP(0x678a773f, 0x4b413aee),
+ WTCP(0x67444253, 0x4ba17514), WTCP(0x66fd9fde, 0x4c0188f8),
+ WTCP(0x66b6904c, 0x4c61756b), WTCP(0x666f140d, 0x4cc1393d),
+ WTCP(0x66272b91, 0x4d20d341), WTCP(0x65ded74d, 0x4d80424a),
+ WTCP(0x659617bb, 0x4ddf852d), WTCP(0x654ced55, 0x4e3e9ac1),
+ WTCP(0x6503589b, 0x4e9d81dc), WTCP(0x64b95a0d, 0x4efc3959),
+ WTCP(0x646ef230, 0x4f5ac010), WTCP(0x6424218d, 0x4fb914df),
+ WTCP(0x63d8e8ae, 0x501736a1), WTCP(0x638d4822, 0x50752438),
+ WTCP(0x6341407a, 0x50d2dc82), WTCP(0x62f4d24b, 0x51305e61),
+ WTCP(0x62a7fe2b, 0x518da8bb), WTCP(0x625ac4b5, 0x51eaba74),
+ WTCP(0x620d2686, 0x52479273), WTCP(0x61bf2440, 0x52a42fa2),
+ WTCP(0x6170be85, 0x530090ea), WTCP(0x6121f5fb, 0x535cb53a),
+ WTCP(0x60d2cb4e, 0x53b89b7e), WTCP(0x60833f28, 0x541442a8),
+ WTCP(0x60335239, 0x546fa9a9), WTCP(0x5fe30533, 0x54cacf77),
+ WTCP(0x5f9258cc, 0x5525b306), WTCP(0x5f414dbb, 0x55805350),
+ WTCP(0x5eefe4bc, 0x55daaf4e), WTCP(0x5e9e1e8c, 0x5634c5fe),
+ WTCP(0x5e4bfbec, 0x568e965c), WTCP(0x5df97d9e, 0x56e81f6c),
+ WTCP(0x5da6a46a, 0x5741602e), WTCP(0x5d537118, 0x579a57a8),
+ WTCP(0x5cffe474, 0x57f304e2), WTCP(0x5cabff4c, 0x584b66e4),
+ WTCP(0x5c57c271, 0x58a37cbb), WTCP(0x5c032eb7, 0x58fb4576),
+ WTCP(0x5bae44f4, 0x5952c024), WTCP(0x5b590602, 0x59a9ebd8),
+ WTCP(0x5b0372bb, 0x5a00c7a8), WTCP(0x5aad8bfe, 0x5a5752ac),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP KBDWindow960[] = {
+ WTCP(0x7fffff9e, 0x0009e6ac), WTCP(0x7fffff2b, 0x000e96d5),
+ WTCP(0x7ffffea6, 0x0012987e), WTCP(0x7ffffe0e, 0x001652b6),
+ WTCP(0x7ffffd60, 0x0019ebce), WTCP(0x7ffffc9c, 0x001d76bf),
+ WTCP(0x7ffffbbf, 0x0020fe79), WTCP(0x7ffffac9, 0x002489ef),
+ WTCP(0x7ffff9b7, 0x00281de2), WTCP(0x7ffff887, 0x002bbdbb),
+ WTCP(0x7ffff737, 0x002f6c0d), WTCP(0x7ffff5c6, 0x00332ad8),
+ WTCP(0x7ffff431, 0x0036fbb9), WTCP(0x7ffff276, 0x003ae004),
+ WTCP(0x7ffff092, 0x003ed8d8), WTCP(0x7fffee84, 0x0042e72f),
+ WTCP(0x7fffec48, 0x00470be3), WTCP(0x7fffe9dd, 0x004b47b8),
+ WTCP(0x7fffe73f, 0x004f9b5f), WTCP(0x7fffe46b, 0x0054077a),
+ WTCP(0x7fffe15f, 0x00588ca1), WTCP(0x7fffde17, 0x005d2b61),
+ WTCP(0x7fffda91, 0x0061e442), WTCP(0x7fffd6c9, 0x0066b7c2),
+ WTCP(0x7fffd2bb, 0x006ba65c), WTCP(0x7fffce65, 0x0070b087),
+ WTCP(0x7fffc9c2, 0x0075d6b5), WTCP(0x7fffc4cf, 0x007b1955),
+ WTCP(0x7fffbf87, 0x008078d5), WTCP(0x7fffb9e7, 0x0085f5a0),
+ WTCP(0x7fffb3ea, 0x008b901d), WTCP(0x7fffad8c, 0x009148b4),
+ WTCP(0x7fffa6c9, 0x00971fcb), WTCP(0x7fff9f9c, 0x009d15c7),
+ WTCP(0x7fff9800, 0x00a32b0b), WTCP(0x7fff8ff0, 0x00a95ff9),
+ WTCP(0x7fff8767, 0x00afb4f4), WTCP(0x7fff7e5f, 0x00b62a5c),
+ WTCP(0x7fff74d4, 0x00bcc093), WTCP(0x7fff6ac0, 0x00c377f8),
+ WTCP(0x7fff601c, 0x00ca50eb), WTCP(0x7fff54e3, 0x00d14bcb),
+ WTCP(0x7fff490e, 0x00d868f7), WTCP(0x7fff3c98, 0x00dfa8ce),
+ WTCP(0x7fff2f79, 0x00e70bad), WTCP(0x7fff21ac, 0x00ee91f3),
+ WTCP(0x7fff1328, 0x00f63bfe), WTCP(0x7fff03e7, 0x00fe0a2c),
+ WTCP(0x7ffef3e1, 0x0105fcd9), WTCP(0x7ffee310, 0x010e1462),
+ WTCP(0x7ffed16a, 0x01165126), WTCP(0x7ffebee9, 0x011eb381),
+ WTCP(0x7ffeab83, 0x01273bd0), WTCP(0x7ffe9731, 0x012fea6f),
+ WTCP(0x7ffe81ea, 0x0138bfbc), WTCP(0x7ffe6ba4, 0x0141bc12),
+ WTCP(0x7ffe5457, 0x014adfce), WTCP(0x7ffe3bfa, 0x01542b4d),
+ WTCP(0x7ffe2282, 0x015d9ee9), WTCP(0x7ffe07e6, 0x01673b01),
+ WTCP(0x7ffdec1b, 0x0170ffee), WTCP(0x7ffdcf17, 0x017aee0e),
+ WTCP(0x7ffdb0d0, 0x018505bc), WTCP(0x7ffd913b, 0x018f4754),
+ WTCP(0x7ffd704b, 0x0199b330), WTCP(0x7ffd4df7, 0x01a449ad),
+ WTCP(0x7ffd2a31, 0x01af0b25), WTCP(0x7ffd04ef, 0x01b9f7f4),
+ WTCP(0x7ffcde23, 0x01c51074), WTCP(0x7ffcb5c1, 0x01d05501),
+ WTCP(0x7ffc8bbc, 0x01dbc5f5), WTCP(0x7ffc6006, 0x01e763ab),
+ WTCP(0x7ffc3293, 0x01f32e7d), WTCP(0x7ffc0354, 0x01ff26c5),
+ WTCP(0x7ffbd23b, 0x020b4cde), WTCP(0x7ffb9f3a, 0x0217a120),
+ WTCP(0x7ffb6a41, 0x022423e6), WTCP(0x7ffb3342, 0x0230d58a),
+ WTCP(0x7ffafa2d, 0x023db664), WTCP(0x7ffabef2, 0x024ac6ce),
+ WTCP(0x7ffa8180, 0x02580720), WTCP(0x7ffa41c9, 0x026577b3),
+ WTCP(0x7ff9ffb9, 0x027318e0), WTCP(0x7ff9bb41, 0x0280eaff),
+ WTCP(0x7ff9744e, 0x028eee68), WTCP(0x7ff92acf, 0x029d2371),
+ WTCP(0x7ff8deb1, 0x02ab8a74), WTCP(0x7ff88fe2, 0x02ba23c7),
+ WTCP(0x7ff83e4d, 0x02c8efc0), WTCP(0x7ff7e9e1, 0x02d7eeb7),
+ WTCP(0x7ff79288, 0x02e72101), WTCP(0x7ff7382f, 0x02f686f5),
+ WTCP(0x7ff6dac1, 0x030620e9), WTCP(0x7ff67a29, 0x0315ef31),
+ WTCP(0x7ff61651, 0x0325f224), WTCP(0x7ff5af23, 0x03362a14),
+ WTCP(0x7ff5448a, 0x03469758), WTCP(0x7ff4d66d, 0x03573a42),
+ WTCP(0x7ff464b7, 0x03681327), WTCP(0x7ff3ef4f, 0x0379225a),
+ WTCP(0x7ff3761d, 0x038a682e), WTCP(0x7ff2f90a, 0x039be4f4),
+ WTCP(0x7ff277fb, 0x03ad9900), WTCP(0x7ff1f2d8, 0x03bf84a3),
+ WTCP(0x7ff16986, 0x03d1a82e), WTCP(0x7ff0dbec, 0x03e403f3),
+ WTCP(0x7ff049ef, 0x03f69840), WTCP(0x7fefb373, 0x04096568),
+ WTCP(0x7fef185d, 0x041c6bb8), WTCP(0x7fee7890, 0x042fab81),
+ WTCP(0x7fedd3f1, 0x04432510), WTCP(0x7fed2a61, 0x0456d8b4),
+ WTCP(0x7fec7bc4, 0x046ac6ba), WTCP(0x7febc7fb, 0x047eef70),
+ WTCP(0x7feb0ee8, 0x04935322), WTCP(0x7fea506b, 0x04a7f21d),
+ WTCP(0x7fe98c65, 0x04bcccab), WTCP(0x7fe8c2b7, 0x04d1e318),
+ WTCP(0x7fe7f33e, 0x04e735af), WTCP(0x7fe71ddb, 0x04fcc4ba),
+ WTCP(0x7fe6426c, 0x05129081), WTCP(0x7fe560ce, 0x0528994d),
+ WTCP(0x7fe478df, 0x053edf68), WTCP(0x7fe38a7c, 0x05556318),
+ WTCP(0x7fe29581, 0x056c24a5), WTCP(0x7fe199ca, 0x05832455),
+ WTCP(0x7fe09733, 0x059a626e), WTCP(0x7fdf8d95, 0x05b1df35),
+ WTCP(0x7fde7ccb, 0x05c99aef), WTCP(0x7fdd64af, 0x05e195e0),
+ WTCP(0x7fdc451a, 0x05f9d04b), WTCP(0x7fdb1de4, 0x06124a73),
+ WTCP(0x7fd9eee5, 0x062b0499), WTCP(0x7fd8b7f5, 0x0643ff00),
+ WTCP(0x7fd778ec, 0x065d39e7), WTCP(0x7fd6319e, 0x0676b58f),
+ WTCP(0x7fd4e1e2, 0x06907237), WTCP(0x7fd3898d, 0x06aa701d),
+ WTCP(0x7fd22873, 0x06c4af80), WTCP(0x7fd0be6a, 0x06df309c),
+ WTCP(0x7fcf4b44, 0x06f9f3ad), WTCP(0x7fcdced4, 0x0714f8f0),
+ WTCP(0x7fcc48ed, 0x0730409f), WTCP(0x7fcab960, 0x074bcaf5),
+ WTCP(0x7fc91fff, 0x0767982a), WTCP(0x7fc77c9a, 0x0783a877),
+ WTCP(0x7fc5cf02, 0x079ffc14), WTCP(0x7fc41705, 0x07bc9338),
+ WTCP(0x7fc25474, 0x07d96e19), WTCP(0x7fc0871b, 0x07f68ced),
+ WTCP(0x7fbeaeca, 0x0813efe7), WTCP(0x7fbccb4c, 0x0831973d),
+ WTCP(0x7fbadc70, 0x084f8320), WTCP(0x7fb8e200, 0x086db3c3),
+ WTCP(0x7fb6dbc8, 0x088c2957), WTCP(0x7fb4c993, 0x08aae40c),
+ WTCP(0x7fb2ab2b, 0x08c9e412), WTCP(0x7fb0805a, 0x08e92997),
+ WTCP(0x7fae48e9, 0x0908b4c9), WTCP(0x7fac04a0, 0x092885d6),
+ WTCP(0x7fa9b347, 0x09489ce8), WTCP(0x7fa754a6, 0x0968fa2c),
+ WTCP(0x7fa4e884, 0x09899dcb), WTCP(0x7fa26ea6, 0x09aa87ee),
+ WTCP(0x7f9fe6d1, 0x09cbb8be), WTCP(0x7f9d50cc, 0x09ed3062),
+ WTCP(0x7f9aac5a, 0x0a0eef00), WTCP(0x7f97f93f, 0x0a30f4bf),
+ WTCP(0x7f95373e, 0x0a5341c2), WTCP(0x7f92661b, 0x0a75d62e),
+ WTCP(0x7f8f8596, 0x0a98b224), WTCP(0x7f8c9572, 0x0abbd5c7),
+ WTCP(0x7f89956f, 0x0adf4137), WTCP(0x7f86854d, 0x0b02f494),
+ WTCP(0x7f8364cd, 0x0b26effd), WTCP(0x7f8033ae, 0x0b4b338f),
+ WTCP(0x7f7cf1ae, 0x0b6fbf67), WTCP(0x7f799e8b, 0x0b9493a0),
+ WTCP(0x7f763a03, 0x0bb9b056), WTCP(0x7f72c3d2, 0x0bdf15a2),
+ WTCP(0x7f6f3bb5, 0x0c04c39c), WTCP(0x7f6ba168, 0x0c2aba5d),
+ WTCP(0x7f67f4a6, 0x0c50f9fa), WTCP(0x7f643529, 0x0c77828a),
+ WTCP(0x7f6062ac, 0x0c9e5420), WTCP(0x7f5c7ce8, 0x0cc56ed1),
+ WTCP(0x7f588397, 0x0cecd2ae), WTCP(0x7f547670, 0x0d147fc8),
+ WTCP(0x7f50552c, 0x0d3c7630), WTCP(0x7f4c1f83, 0x0d64b5f6),
+ WTCP(0x7f47d52a, 0x0d8d3f26), WTCP(0x7f4375d9, 0x0db611ce),
+ WTCP(0x7f3f0144, 0x0ddf2dfa), WTCP(0x7f3a7723, 0x0e0893b4),
+ WTCP(0x7f35d729, 0x0e324306), WTCP(0x7f31210a, 0x0e5c3bf9),
+ WTCP(0x7f2c547b, 0x0e867e94), WTCP(0x7f27712e, 0x0eb10add),
+ WTCP(0x7f2276d8, 0x0edbe0da), WTCP(0x7f1d6529, 0x0f07008e),
+ WTCP(0x7f183bd3, 0x0f3269fc), WTCP(0x7f12fa89, 0x0f5e1d27),
+ WTCP(0x7f0da0fb, 0x0f8a1a0e), WTCP(0x7f082ed8, 0x0fb660b1),
+ WTCP(0x7f02a3d2, 0x0fe2f10f), WTCP(0x7efcff98, 0x100fcb25),
+ WTCP(0x7ef741d9, 0x103ceeee), WTCP(0x7ef16a42, 0x106a5c66),
+ WTCP(0x7eeb7884, 0x10981386), WTCP(0x7ee56c4a, 0x10c61447),
+ WTCP(0x7edf4543, 0x10f45ea0), WTCP(0x7ed9031b, 0x1122f288),
+ WTCP(0x7ed2a57f, 0x1151cff3), WTCP(0x7ecc2c1a, 0x1180f6d5),
+ WTCP(0x7ec59699, 0x11b06720), WTCP(0x7ebee4a6, 0x11e020c8),
+ WTCP(0x7eb815ed, 0x121023ba), WTCP(0x7eb12a18, 0x12406fe8),
+ WTCP(0x7eaa20d1, 0x1271053e), WTCP(0x7ea2f9c2, 0x12a1e3a9),
+ WTCP(0x7e9bb494, 0x12d30b15), WTCP(0x7e9450f0, 0x13047b6c),
+ WTCP(0x7e8cce7f, 0x13363497), WTCP(0x7e852ce9, 0x1368367f),
+ WTCP(0x7e7d6bd6, 0x139a8109), WTCP(0x7e758aee, 0x13cd141b),
+ WTCP(0x7e6d89d9, 0x13ffef99), WTCP(0x7e65683d, 0x14331368),
+ WTCP(0x7e5d25c1, 0x14667f67), WTCP(0x7e54c20b, 0x149a3379),
+ WTCP(0x7e4c3cc3, 0x14ce2f7c), WTCP(0x7e43958e, 0x1502734f),
+ WTCP(0x7e3acc11, 0x1536fece), WTCP(0x7e31dff2, 0x156bd1d6),
+ WTCP(0x7e28d0d7, 0x15a0ec41), WTCP(0x7e1f9e63, 0x15d64de9),
+ WTCP(0x7e16483d, 0x160bf6a5), WTCP(0x7e0cce08, 0x1641e64c),
+ WTCP(0x7e032f6a, 0x16781cb4), WTCP(0x7df96c05, 0x16ae99b2),
+ WTCP(0x7def837e, 0x16e55d18), WTCP(0x7de57579, 0x171c66ba),
+ WTCP(0x7ddb419a, 0x1753b667), WTCP(0x7dd0e784, 0x178b4bef),
+ WTCP(0x7dc666d9, 0x17c32721), WTCP(0x7dbbbf3e, 0x17fb47ca),
+ WTCP(0x7db0f056, 0x1833adb5), WTCP(0x7da5f9c3, 0x186c58ae),
+ WTCP(0x7d9adb29, 0x18a5487d), WTCP(0x7d8f9429, 0x18de7cec),
+ WTCP(0x7d842467, 0x1917f5c1), WTCP(0x7d788b86, 0x1951b2c2),
+ WTCP(0x7d6cc927, 0x198bb3b4), WTCP(0x7d60dced, 0x19c5f85a),
+ WTCP(0x7d54c67c, 0x1a008077), WTCP(0x7d488574, 0x1a3b4bcb),
+ WTCP(0x7d3c1979, 0x1a765a17), WTCP(0x7d2f822d, 0x1ab1ab18),
+ WTCP(0x7d22bf32, 0x1aed3e8d), WTCP(0x7d15d02b, 0x1b291432),
+ WTCP(0x7d08b4ba, 0x1b652bc1), WTCP(0x7cfb6c82, 0x1ba184f5),
+ WTCP(0x7cedf725, 0x1bde1f86), WTCP(0x7ce05445, 0x1c1afb2c),
+ WTCP(0x7cd28386, 0x1c58179c), WTCP(0x7cc48489, 0x1c95748d),
+ WTCP(0x7cb656f3, 0x1cd311b1), WTCP(0x7ca7fa65, 0x1d10eebd),
+ WTCP(0x7c996e83, 0x1d4f0b60), WTCP(0x7c8ab2f0, 0x1d8d674c),
+ WTCP(0x7c7bc74f, 0x1dcc0230), WTCP(0x7c6cab44, 0x1e0adbbb),
+ WTCP(0x7c5d5e71, 0x1e49f398), WTCP(0x7c4de07c, 0x1e894973),
+ WTCP(0x7c3e3108, 0x1ec8dcf8), WTCP(0x7c2e4fb9, 0x1f08add0),
+ WTCP(0x7c1e3c34, 0x1f48bba3), WTCP(0x7c0df61d, 0x1f890618),
+ WTCP(0x7bfd7d18, 0x1fc98cd6), WTCP(0x7becd0cc, 0x200a4f80),
+ WTCP(0x7bdbf0dd, 0x204b4dbc), WTCP(0x7bcadcf1, 0x208c872c),
+ WTCP(0x7bb994ae, 0x20cdfb71), WTCP(0x7ba817b9, 0x210faa2c),
+ WTCP(0x7b9665bb, 0x215192fc), WTCP(0x7b847e58, 0x2193b57f),
+ WTCP(0x7b726139, 0x21d61153), WTCP(0x7b600e05, 0x2218a614),
+ WTCP(0x7b4d8463, 0x225b735d), WTCP(0x7b3ac3fc, 0x229e78c7),
+ WTCP(0x7b27cc79, 0x22e1b5eb), WTCP(0x7b149d82, 0x23252a62),
+ WTCP(0x7b0136c1, 0x2368d5c2), WTCP(0x7aed97df, 0x23acb7a0),
+ WTCP(0x7ad9c087, 0x23f0cf92), WTCP(0x7ac5b063, 0x24351d2a),
+ WTCP(0x7ab1671e, 0x24799ffc), WTCP(0x7a9ce464, 0x24be5799),
+ WTCP(0x7a8827e1, 0x25034391), WTCP(0x7a733142, 0x25486375),
+ WTCP(0x7a5e0033, 0x258db6d2), WTCP(0x7a489461, 0x25d33d35),
+ WTCP(0x7a32ed7c, 0x2618f62c), WTCP(0x7a1d0b31, 0x265ee143),
+ WTCP(0x7a06ed2f, 0x26a4fe02), WTCP(0x79f09327, 0x26eb4bf5),
+ WTCP(0x79d9fcc8, 0x2731caa3), WTCP(0x79c329c2, 0x27787995),
+ WTCP(0x79ac19c9, 0x27bf5850), WTCP(0x7994cc8d, 0x2806665c),
+ WTCP(0x797d41c1, 0x284da33c), WTCP(0x79657918, 0x28950e74),
+ WTCP(0x794d7247, 0x28dca788), WTCP(0x79352d01, 0x29246dfa),
+ WTCP(0x791ca8fc, 0x296c614a), WTCP(0x7903e5ee, 0x29b480f9),
+ WTCP(0x78eae38d, 0x29fccc87), WTCP(0x78d1a191, 0x2a454372),
+ WTCP(0x78b81fb1, 0x2a8de537), WTCP(0x789e5da6, 0x2ad6b155),
+ WTCP(0x78845b29, 0x2b1fa745), WTCP(0x786a17f5, 0x2b68c684),
+ WTCP(0x784f93c4, 0x2bb20e8c), WTCP(0x7834ce53, 0x2bfb7ed7),
+ WTCP(0x7819c75c, 0x2c4516dc), WTCP(0x77fe7e9e, 0x2c8ed615),
+ WTCP(0x77e2f3d7, 0x2cd8bbf7), WTCP(0x77c726c5, 0x2d22c7fa),
+ WTCP(0x77ab1728, 0x2d6cf993), WTCP(0x778ec4c0, 0x2db75037),
+ WTCP(0x77722f4e, 0x2e01cb59), WTCP(0x77555695, 0x2e4c6a6d),
+ WTCP(0x77383a58, 0x2e972ce6), WTCP(0x771ada5a, 0x2ee21235),
+ WTCP(0x76fd3660, 0x2f2d19cc), WTCP(0x76df4e30, 0x2f78431a),
+ WTCP(0x76c12190, 0x2fc38d91), WTCP(0x76a2b047, 0x300ef89d),
+ WTCP(0x7683fa1e, 0x305a83af), WTCP(0x7664fede, 0x30a62e34),
+ WTCP(0x7645be51, 0x30f1f798), WTCP(0x76263842, 0x313ddf49),
+ WTCP(0x76066c7e, 0x3189e4b1), WTCP(0x75e65ad1, 0x31d6073d),
+ WTCP(0x75c60309, 0x32224657), WTCP(0x75a564f6, 0x326ea168),
+ WTCP(0x75848067, 0x32bb17da), WTCP(0x7563552d, 0x3307a917),
+ WTCP(0x7541e31a, 0x33545486), WTCP(0x75202a02, 0x33a1198e),
+ WTCP(0x74fe29b8, 0x33edf798), WTCP(0x74dbe211, 0x343aee09),
+ WTCP(0x74b952e3, 0x3487fc48), WTCP(0x74967c06, 0x34d521bb),
+ WTCP(0x74735d51, 0x35225dc7), WTCP(0x744ff69f, 0x356fafcf),
+ WTCP(0x742c47c9, 0x35bd173a), WTCP(0x740850ab, 0x360a9369),
+ WTCP(0x73e41121, 0x365823c1), WTCP(0x73bf8909, 0x36a5c7a4),
+ WTCP(0x739ab842, 0x36f37e75), WTCP(0x73759eab, 0x37414796),
+ WTCP(0x73503c26, 0x378f2268), WTCP(0x732a9095, 0x37dd0e4c),
+ WTCP(0x73049bda, 0x382b0aa4), WTCP(0x72de5ddb, 0x387916d0),
+ WTCP(0x72b7d67d, 0x38c73230), WTCP(0x729105a6, 0x39155c24),
+ WTCP(0x7269eb3f, 0x3963940c), WTCP(0x72428730, 0x39b1d946),
+ WTCP(0x721ad964, 0x3a002b31), WTCP(0x71f2e1c5, 0x3a4e892c),
+ WTCP(0x71caa042, 0x3a9cf296), WTCP(0x71a214c7, 0x3aeb66cc),
+ WTCP(0x71793f43, 0x3b39e52c), WTCP(0x71501fa6, 0x3b886d14),
+ WTCP(0x7126b5e3, 0x3bd6fde1), WTCP(0x70fd01eb, 0x3c2596f1),
+ WTCP(0x70d303b2, 0x3c74379f), WTCP(0x70a8bb2e, 0x3cc2df49),
+ WTCP(0x707e2855, 0x3d118d4c), WTCP(0x70534b1e, 0x3d604103),
+ WTCP(0x70282381, 0x3daef9cc), WTCP(0x6ffcb17a, 0x3dfdb702),
+ WTCP(0x6fd0f504, 0x3e4c7800), WTCP(0x6fa4ee1a, 0x3e9b3c25),
+ WTCP(0x6f789cbb, 0x3eea02ca), WTCP(0x6f4c00e5, 0x3f38cb4b),
+ WTCP(0x6f1f1a9a, 0x3f879505), WTCP(0x6ef1e9da, 0x3fd65f53),
+ WTCP(0x6ec46ea9, 0x40252990), WTCP(0x6e96a90b, 0x4073f318),
+ WTCP(0x6e689905, 0x40c2bb46), WTCP(0x6e3a3e9d, 0x41118176),
+ WTCP(0x6e0b99dd, 0x41604504), WTCP(0x6ddcaacc, 0x41af054a),
+ WTCP(0x6dad7177, 0x41fdc1a5), WTCP(0x6d7dede8, 0x424c7970),
+ WTCP(0x6d4e202e, 0x429b2c06), WTCP(0x6d1e0855, 0x42e9d8c4),
+ WTCP(0x6ceda66f, 0x43387f05), WTCP(0x6cbcfa8d, 0x43871e26),
+ WTCP(0x6c8c04c0, 0x43d5b581), WTCP(0x6c5ac51d, 0x44244474),
+ WTCP(0x6c293bb8, 0x4472ca5a), WTCP(0x6bf768a8, 0x44c14690),
+ WTCP(0x6bc54c06, 0x450fb873), WTCP(0x6b92e5e9, 0x455e1f5f),
+ WTCP(0x6b60366c, 0x45ac7ab2), WTCP(0x6b2d3dab, 0x45fac9c8),
+ WTCP(0x6af9fbc2, 0x46490bff), WTCP(0x6ac670d1, 0x469740b5),
+ WTCP(0x6a929cf6, 0x46e56747), WTCP(0x6a5e8053, 0x47337f13),
+ WTCP(0x6a2a1b0a, 0x47818779), WTCP(0x69f56d3e, 0x47cf7fd6),
+ WTCP(0x69c07715, 0x481d678a), WTCP(0x698b38b4, 0x486b3df3),
+ WTCP(0x6955b243, 0x48b90272), WTCP(0x691fe3ec, 0x4906b466),
+ WTCP(0x68e9cdd8, 0x49545330), WTCP(0x68b37033, 0x49a1de30),
+ WTCP(0x687ccb29, 0x49ef54c8), WTCP(0x6845dee9, 0x4a3cb657),
+ WTCP(0x680eaba3, 0x4a8a0242), WTCP(0x67d73187, 0x4ad737e9),
+ WTCP(0x679f70c7, 0x4b2456af), WTCP(0x67676997, 0x4b715df7),
+ WTCP(0x672f1c2b, 0x4bbe4d25), WTCP(0x66f688ba, 0x4c0b239c),
+ WTCP(0x66bdaf7b, 0x4c57e0c2), WTCP(0x668490a6, 0x4ca483fa),
+ WTCP(0x664b2c76, 0x4cf10cac), WTCP(0x66118326, 0x4d3d7a3b),
+ WTCP(0x65d794f3, 0x4d89cc0f), WTCP(0x659d621a, 0x4dd6018f),
+ WTCP(0x6562eada, 0x4e221a22), WTCP(0x65282f74, 0x4e6e1530),
+ WTCP(0x64ed302b, 0x4eb9f222), WTCP(0x64b1ed40, 0x4f05b061),
+ WTCP(0x647666f8, 0x4f514f57), WTCP(0x643a9d99, 0x4f9cce6f),
+ WTCP(0x63fe916a, 0x4fe82d13), WTCP(0x63c242b2, 0x50336aaf),
+ WTCP(0x6385b1bc, 0x507e86b0), WTCP(0x6348ded1, 0x50c98082),
+ WTCP(0x630bca3f, 0x51145793), WTCP(0x62ce7451, 0x515f0b51),
+ WTCP(0x6290dd57, 0x51a99b2b), WTCP(0x625305a0, 0x51f40692),
+ WTCP(0x6214ed7d, 0x523e4cf5), WTCP(0x61d69541, 0x52886dc5),
+ WTCP(0x6197fd3e, 0x52d26875), WTCP(0x615925c9, 0x531c3c77),
+ WTCP(0x611a0f39, 0x5365e93e), WTCP(0x60dab9e3, 0x53af6e3e),
+ WTCP(0x609b2621, 0x53f8caed), WTCP(0x605b544c, 0x5441fec0),
+ WTCP(0x601b44bf, 0x548b092e), WTCP(0x5fdaf7d5, 0x54d3e9ae),
+ WTCP(0x5f9a6deb, 0x551c9fb7), WTCP(0x5f59a761, 0x55652ac3),
+ WTCP(0x5f18a494, 0x55ad8a4d), WTCP(0x5ed765e6, 0x55f5bdcd),
+ WTCP(0x5e95ebb8, 0x563dc4c1), WTCP(0x5e54366d, 0x56859ea3),
+ WTCP(0x5e12466a, 0x56cd4af3), WTCP(0x5dd01c13, 0x5714c92d),
+ WTCP(0x5d8db7cf, 0x575c18d0), WTCP(0x5d4b1a05, 0x57a3395e),
+ WTCP(0x5d08431e, 0x57ea2a56), WTCP(0x5cc53384, 0x5830eb3a),
+ WTCP(0x5c81eba0, 0x58777b8e), WTCP(0x5c3e6bdf, 0x58bddad5),
+ WTCP(0x5bfab4af, 0x59040893), WTCP(0x5bb6c67c, 0x594a044f),
+ WTCP(0x5b72a1b6, 0x598fcd8e), WTCP(0x5b2e46ce, 0x59d563d9),
+ WTCP(0x5ae9b634, 0x5a1ac6b8), WTCP(0x5aa4f05a, 0x5a5ff5b5),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_WTP KBDWindow1024[] = {
+ WTCP(0x7fffffa4, 0x0009962f), WTCP(0x7fffff39, 0x000e16fb),
+ WTCP(0x7ffffebf, 0x0011ea65), WTCP(0x7ffffe34, 0x0015750e),
+ WTCP(0x7ffffd96, 0x0018dc74), WTCP(0x7ffffce5, 0x001c332e),
+ WTCP(0x7ffffc1f, 0x001f83f5), WTCP(0x7ffffb43, 0x0022d59a),
+ WTCP(0x7ffffa4f, 0x00262cc2), WTCP(0x7ffff942, 0x00298cc4),
+ WTCP(0x7ffff81a, 0x002cf81f), WTCP(0x7ffff6d6, 0x003070c4),
+ WTCP(0x7ffff573, 0x0033f840), WTCP(0x7ffff3f1, 0x00378fd9),
+ WTCP(0x7ffff24d, 0x003b38a1), WTCP(0x7ffff085, 0x003ef381),
+ WTCP(0x7fffee98, 0x0042c147), WTCP(0x7fffec83, 0x0046a2a8),
+ WTCP(0x7fffea44, 0x004a9847), WTCP(0x7fffe7d8, 0x004ea2b7),
+ WTCP(0x7fffe53f, 0x0052c283), WTCP(0x7fffe274, 0x0056f829),
+ WTCP(0x7fffdf76, 0x005b4422), WTCP(0x7fffdc43, 0x005fa6dd),
+ WTCP(0x7fffd8d6, 0x006420c8), WTCP(0x7fffd52f, 0x0068b249),
+ WTCP(0x7fffd149, 0x006d5bc4), WTCP(0x7fffcd22, 0x00721d9a),
+ WTCP(0x7fffc8b6, 0x0076f828), WTCP(0x7fffc404, 0x007bebca),
+ WTCP(0x7fffbf06, 0x0080f8d9), WTCP(0x7fffb9bb, 0x00861fae),
+ WTCP(0x7fffb41e, 0x008b609e), WTCP(0x7fffae2c, 0x0090bbff),
+ WTCP(0x7fffa7e1, 0x00963224), WTCP(0x7fffa13a, 0x009bc362),
+ WTCP(0x7fff9a32, 0x00a17009), WTCP(0x7fff92c5, 0x00a7386c),
+ WTCP(0x7fff8af0, 0x00ad1cdc), WTCP(0x7fff82ad, 0x00b31da8),
+ WTCP(0x7fff79f9, 0x00b93b21), WTCP(0x7fff70cf, 0x00bf7596),
+ WTCP(0x7fff672a, 0x00c5cd57), WTCP(0x7fff5d05, 0x00cc42b1),
+ WTCP(0x7fff525c, 0x00d2d5f3), WTCP(0x7fff4729, 0x00d9876c),
+ WTCP(0x7fff3b66, 0x00e05769), WTCP(0x7fff2f10, 0x00e74638),
+ WTCP(0x7fff221f, 0x00ee5426), WTCP(0x7fff148e, 0x00f58182),
+ WTCP(0x7fff0658, 0x00fcce97), WTCP(0x7ffef776, 0x01043bb3),
+ WTCP(0x7ffee7e2, 0x010bc923), WTCP(0x7ffed795, 0x01137733),
+ WTCP(0x7ffec68a, 0x011b4631), WTCP(0x7ffeb4ba, 0x01233669),
+ WTCP(0x7ffea21d, 0x012b4827), WTCP(0x7ffe8eac, 0x01337bb8),
+ WTCP(0x7ffe7a61, 0x013bd167), WTCP(0x7ffe6533, 0x01444982),
+ WTCP(0x7ffe4f1c, 0x014ce454), WTCP(0x7ffe3813, 0x0155a229),
+ WTCP(0x7ffe2011, 0x015e834d), WTCP(0x7ffe070d, 0x0167880c),
+ WTCP(0x7ffdecff, 0x0170b0b2), WTCP(0x7ffdd1df, 0x0179fd8b),
+ WTCP(0x7ffdb5a2, 0x01836ee1), WTCP(0x7ffd9842, 0x018d0500),
+ WTCP(0x7ffd79b3, 0x0196c035), WTCP(0x7ffd59ee, 0x01a0a0ca),
+ WTCP(0x7ffd38e8, 0x01aaa70a), WTCP(0x7ffd1697, 0x01b4d341),
+ WTCP(0x7ffcf2f2, 0x01bf25b9), WTCP(0x7ffccdee, 0x01c99ebd),
+ WTCP(0x7ffca780, 0x01d43e99), WTCP(0x7ffc7f9e, 0x01df0597),
+ WTCP(0x7ffc563d, 0x01e9f401), WTCP(0x7ffc2b51, 0x01f50a22),
+ WTCP(0x7ffbfecf, 0x02004844), WTCP(0x7ffbd0ab, 0x020baeb1),
+ WTCP(0x7ffba0da, 0x02173db4), WTCP(0x7ffb6f4f, 0x0222f596),
+ WTCP(0x7ffb3bfd, 0x022ed6a1), WTCP(0x7ffb06d8, 0x023ae11f),
+ WTCP(0x7ffacfd3, 0x02471558), WTCP(0x7ffa96e0, 0x02537397),
+ WTCP(0x7ffa5bf2, 0x025ffc25), WTCP(0x7ffa1efc, 0x026caf4a),
+ WTCP(0x7ff9dfee, 0x02798d4f), WTCP(0x7ff99ebb, 0x0286967c),
+ WTCP(0x7ff95b55, 0x0293cb1b), WTCP(0x7ff915ab, 0x02a12b72),
+ WTCP(0x7ff8cdaf, 0x02aeb7cb), WTCP(0x7ff88351, 0x02bc706d),
+ WTCP(0x7ff83682, 0x02ca559f), WTCP(0x7ff7e731, 0x02d867a9),
+ WTCP(0x7ff7954e, 0x02e6a6d2), WTCP(0x7ff740c8, 0x02f51361),
+ WTCP(0x7ff6e98e, 0x0303ad9c), WTCP(0x7ff68f8f, 0x031275ca),
+ WTCP(0x7ff632ba, 0x03216c30), WTCP(0x7ff5d2fb, 0x03309116),
+ WTCP(0x7ff57042, 0x033fe4bf), WTCP(0x7ff50a7a, 0x034f6773),
+ WTCP(0x7ff4a192, 0x035f1975), WTCP(0x7ff43576, 0x036efb0a),
+ WTCP(0x7ff3c612, 0x037f0c78), WTCP(0x7ff35353, 0x038f4e02),
+ WTCP(0x7ff2dd24, 0x039fbfeb), WTCP(0x7ff26370, 0x03b06279),
+ WTCP(0x7ff1e623, 0x03c135ed), WTCP(0x7ff16527, 0x03d23a8b),
+ WTCP(0x7ff0e067, 0x03e37095), WTCP(0x7ff057cc, 0x03f4d84e),
+ WTCP(0x7fefcb40, 0x040671f7), WTCP(0x7fef3aad, 0x04183dd3),
+ WTCP(0x7feea5fa, 0x042a3c22), WTCP(0x7fee0d11, 0x043c6d25),
+ WTCP(0x7fed6fda, 0x044ed11d), WTCP(0x7fecce3d, 0x04616849),
+ WTCP(0x7fec2821, 0x047432eb), WTCP(0x7feb7d6c, 0x04873140),
+ WTCP(0x7feace07, 0x049a6388), WTCP(0x7fea19d6, 0x04adca01),
+ WTCP(0x7fe960c0, 0x04c164ea), WTCP(0x7fe8a2aa, 0x04d53481),
+ WTCP(0x7fe7df79, 0x04e93902), WTCP(0x7fe71712, 0x04fd72aa),
+ WTCP(0x7fe6495a, 0x0511e1b6), WTCP(0x7fe57634, 0x05268663),
+ WTCP(0x7fe49d83, 0x053b60eb), WTCP(0x7fe3bf2b, 0x05507189),
+ WTCP(0x7fe2db0f, 0x0565b879), WTCP(0x7fe1f110, 0x057b35f4),
+ WTCP(0x7fe10111, 0x0590ea35), WTCP(0x7fe00af3, 0x05a6d574),
+ WTCP(0x7fdf0e97, 0x05bcf7ea), WTCP(0x7fde0bdd, 0x05d351cf),
+ WTCP(0x7fdd02a6, 0x05e9e35c), WTCP(0x7fdbf2d2, 0x0600acc8),
+ WTCP(0x7fdadc40, 0x0617ae48), WTCP(0x7fd9becf, 0x062ee814),
+ WTCP(0x7fd89a5e, 0x06465a62), WTCP(0x7fd76eca, 0x065e0565),
+ WTCP(0x7fd63bf1, 0x0675e954), WTCP(0x7fd501b0, 0x068e0662),
+ WTCP(0x7fd3bfe4, 0x06a65cc3), WTCP(0x7fd2766a, 0x06beecaa),
+ WTCP(0x7fd1251e, 0x06d7b648), WTCP(0x7fcfcbda, 0x06f0b9d1),
+ WTCP(0x7fce6a7a, 0x0709f775), WTCP(0x7fcd00d8, 0x07236f65),
+ WTCP(0x7fcb8ecf, 0x073d21d2), WTCP(0x7fca1439, 0x07570eea),
+ WTCP(0x7fc890ed, 0x077136dd), WTCP(0x7fc704c7, 0x078b99da),
+ WTCP(0x7fc56f9d, 0x07a6380d), WTCP(0x7fc3d147, 0x07c111a4),
+ WTCP(0x7fc2299e, 0x07dc26cc), WTCP(0x7fc07878, 0x07f777b1),
+ WTCP(0x7fbebdac, 0x0813047d), WTCP(0x7fbcf90f, 0x082ecd5b),
+ WTCP(0x7fbb2a78, 0x084ad276), WTCP(0x7fb951bc, 0x086713f7),
+ WTCP(0x7fb76eaf, 0x08839206), WTCP(0x7fb58126, 0x08a04ccb),
+ WTCP(0x7fb388f4, 0x08bd446e), WTCP(0x7fb185ee, 0x08da7915),
+ WTCP(0x7faf77e5, 0x08f7eae7), WTCP(0x7fad5ead, 0x09159a09),
+ WTCP(0x7fab3a17, 0x0933869f), WTCP(0x7fa909f6, 0x0951b0cd),
+ WTCP(0x7fa6ce1a, 0x097018b7), WTCP(0x7fa48653, 0x098ebe7f),
+ WTCP(0x7fa23273, 0x09ada248), WTCP(0x7f9fd249, 0x09ccc431),
+ WTCP(0x7f9d65a4, 0x09ec245b), WTCP(0x7f9aec53, 0x0a0bc2e7),
+ WTCP(0x7f986625, 0x0a2b9ff3), WTCP(0x7f95d2e7, 0x0a4bbb9e),
+ WTCP(0x7f933267, 0x0a6c1604), WTCP(0x7f908472, 0x0a8caf43),
+ WTCP(0x7f8dc8d5, 0x0aad8776), WTCP(0x7f8aff5c, 0x0ace9eb9),
+ WTCP(0x7f8827d3, 0x0aeff526), WTCP(0x7f854204, 0x0b118ad8),
+ WTCP(0x7f824dbb, 0x0b335fe6), WTCP(0x7f7f4ac3, 0x0b557469),
+ WTCP(0x7f7c38e4, 0x0b77c879), WTCP(0x7f7917e9, 0x0b9a5c2b),
+ WTCP(0x7f75e79b, 0x0bbd2f97), WTCP(0x7f72a7c3, 0x0be042d0),
+ WTCP(0x7f6f5828, 0x0c0395ec), WTCP(0x7f6bf892, 0x0c2728fd),
+ WTCP(0x7f6888c9, 0x0c4afc16), WTCP(0x7f650894, 0x0c6f0f4a),
+ WTCP(0x7f6177b9, 0x0c9362a8), WTCP(0x7f5dd5ff, 0x0cb7f642),
+ WTCP(0x7f5a232a, 0x0cdcca26), WTCP(0x7f565f00, 0x0d01de63),
+ WTCP(0x7f528947, 0x0d273307), WTCP(0x7f4ea1c2, 0x0d4cc81f),
+ WTCP(0x7f4aa835, 0x0d729db7), WTCP(0x7f469c65, 0x0d98b3da),
+ WTCP(0x7f427e13, 0x0dbf0a92), WTCP(0x7f3e4d04, 0x0de5a1e9),
+ WTCP(0x7f3a08f9, 0x0e0c79e7), WTCP(0x7f35b1b4, 0x0e339295),
+ WTCP(0x7f3146f8, 0x0e5aebfa), WTCP(0x7f2cc884, 0x0e82861a),
+ WTCP(0x7f28361b, 0x0eaa60fd), WTCP(0x7f238f7c, 0x0ed27ca5),
+ WTCP(0x7f1ed467, 0x0efad917), WTCP(0x7f1a049d, 0x0f237656),
+ WTCP(0x7f151fdc, 0x0f4c5462), WTCP(0x7f1025e3, 0x0f75733d),
+ WTCP(0x7f0b1672, 0x0f9ed2e6), WTCP(0x7f05f146, 0x0fc8735e),
+ WTCP(0x7f00b61d, 0x0ff254a1), WTCP(0x7efb64b4, 0x101c76ae),
+ WTCP(0x7ef5fcca, 0x1046d981), WTCP(0x7ef07e19, 0x10717d15),
+ WTCP(0x7eeae860, 0x109c6165), WTCP(0x7ee53b5b, 0x10c7866a),
+ WTCP(0x7edf76c4, 0x10f2ec1e), WTCP(0x7ed99a58, 0x111e9279),
+ WTCP(0x7ed3a5d1, 0x114a7971), WTCP(0x7ecd98eb, 0x1176a0fc),
+ WTCP(0x7ec77360, 0x11a30910), WTCP(0x7ec134eb, 0x11cfb1a1),
+ WTCP(0x7ebadd44, 0x11fc9aa2), WTCP(0x7eb46c27, 0x1229c406),
+ WTCP(0x7eade14c, 0x12572dbf), WTCP(0x7ea73c6c, 0x1284d7bc),
+ WTCP(0x7ea07d41, 0x12b2c1ed), WTCP(0x7e99a382, 0x12e0ec42),
+ WTCP(0x7e92aee7, 0x130f56a8), WTCP(0x7e8b9f2a, 0x133e010b),
+ WTCP(0x7e847402, 0x136ceb59), WTCP(0x7e7d2d25, 0x139c157b),
+ WTCP(0x7e75ca4c, 0x13cb7f5d), WTCP(0x7e6e4b2d, 0x13fb28e6),
+ WTCP(0x7e66af7f, 0x142b1200), WTCP(0x7e5ef6f8, 0x145b3a92),
+ WTCP(0x7e572150, 0x148ba281), WTCP(0x7e4f2e3b, 0x14bc49b4),
+ WTCP(0x7e471d70, 0x14ed300f), WTCP(0x7e3eeea5, 0x151e5575),
+ WTCP(0x7e36a18e, 0x154fb9c9), WTCP(0x7e2e35e2, 0x15815ced),
+ WTCP(0x7e25ab56, 0x15b33ec1), WTCP(0x7e1d019e, 0x15e55f25),
+ WTCP(0x7e14386e, 0x1617bdf9), WTCP(0x7e0b4f7d, 0x164a5b19),
+ WTCP(0x7e02467e, 0x167d3662), WTCP(0x7df91d25, 0x16b04fb2),
+ WTCP(0x7defd327, 0x16e3a6e2), WTCP(0x7de66837, 0x17173bce),
+ WTCP(0x7ddcdc0a, 0x174b0e4d), WTCP(0x7dd32e53, 0x177f1e39),
+ WTCP(0x7dc95ec6, 0x17b36b69), WTCP(0x7dbf6d17, 0x17e7f5b3),
+ WTCP(0x7db558f9, 0x181cbcec), WTCP(0x7dab221f, 0x1851c0e9),
+ WTCP(0x7da0c83c, 0x1887017d), WTCP(0x7d964b05, 0x18bc7e7c),
+ WTCP(0x7d8baa2b, 0x18f237b6), WTCP(0x7d80e563, 0x19282cfd),
+ WTCP(0x7d75fc5e, 0x195e5e20), WTCP(0x7d6aeed0, 0x1994caee),
+ WTCP(0x7d5fbc6d, 0x19cb7335), WTCP(0x7d5464e6, 0x1a0256c2),
+ WTCP(0x7d48e7ef, 0x1a397561), WTCP(0x7d3d453b, 0x1a70cede),
+ WTCP(0x7d317c7c, 0x1aa86301), WTCP(0x7d258d65, 0x1ae03195),
+ WTCP(0x7d1977aa, 0x1b183a63), WTCP(0x7d0d3afc, 0x1b507d30),
+ WTCP(0x7d00d710, 0x1b88f9c5), WTCP(0x7cf44b97, 0x1bc1afe6),
+ WTCP(0x7ce79846, 0x1bfa9f58), WTCP(0x7cdabcce, 0x1c33c7e0),
+ WTCP(0x7ccdb8e4, 0x1c6d293f), WTCP(0x7cc08c39, 0x1ca6c337),
+ WTCP(0x7cb33682, 0x1ce0958a), WTCP(0x7ca5b772, 0x1d1a9ff8),
+ WTCP(0x7c980ebd, 0x1d54e240), WTCP(0x7c8a3c14, 0x1d8f5c21),
+ WTCP(0x7c7c3f2e, 0x1dca0d56), WTCP(0x7c6e17bc, 0x1e04f59f),
+ WTCP(0x7c5fc573, 0x1e4014b4), WTCP(0x7c514807, 0x1e7b6a53),
+ WTCP(0x7c429f2c, 0x1eb6f633), WTCP(0x7c33ca96, 0x1ef2b80f),
+ WTCP(0x7c24c9fa, 0x1f2eaf9e), WTCP(0x7c159d0d, 0x1f6adc98),
+ WTCP(0x7c064383, 0x1fa73eb2), WTCP(0x7bf6bd11, 0x1fe3d5a3),
+ WTCP(0x7be7096c, 0x2020a11e), WTCP(0x7bd7284a, 0x205da0d8),
+ WTCP(0x7bc71960, 0x209ad483), WTCP(0x7bb6dc65, 0x20d83bd1),
+ WTCP(0x7ba6710d, 0x2115d674), WTCP(0x7b95d710, 0x2153a41b),
+ WTCP(0x7b850e24, 0x2191a476), WTCP(0x7b7415ff, 0x21cfd734),
+ WTCP(0x7b62ee59, 0x220e3c02), WTCP(0x7b5196e9, 0x224cd28d),
+ WTCP(0x7b400f67, 0x228b9a82), WTCP(0x7b2e578a, 0x22ca938a),
+ WTCP(0x7b1c6f0b, 0x2309bd52), WTCP(0x7b0a55a1, 0x23491783),
+ WTCP(0x7af80b07, 0x2388a1c4), WTCP(0x7ae58ef5, 0x23c85bbf),
+ WTCP(0x7ad2e124, 0x2408451a), WTCP(0x7ac0014e, 0x24485d7c),
+ WTCP(0x7aacef2e, 0x2488a48a), WTCP(0x7a99aa7e, 0x24c919e9),
+ WTCP(0x7a8632f8, 0x2509bd3d), WTCP(0x7a728858, 0x254a8e29),
+ WTCP(0x7a5eaa5a, 0x258b8c50), WTCP(0x7a4a98b9, 0x25ccb753),
+ WTCP(0x7a365333, 0x260e0ed3), WTCP(0x7a21d983, 0x264f9271),
+ WTCP(0x7a0d2b68, 0x269141cb), WTCP(0x79f8489e, 0x26d31c80),
+ WTCP(0x79e330e4, 0x2715222f), WTCP(0x79cde3f8, 0x27575273),
+ WTCP(0x79b8619a, 0x2799acea), WTCP(0x79a2a989, 0x27dc3130),
+ WTCP(0x798cbb85, 0x281ededf), WTCP(0x7976974e, 0x2861b591),
+ WTCP(0x79603ca5, 0x28a4b4e0), WTCP(0x7949ab4c, 0x28e7dc65),
+ WTCP(0x7932e304, 0x292b2bb8), WTCP(0x791be390, 0x296ea270),
+ WTCP(0x7904acb3, 0x29b24024), WTCP(0x78ed3e30, 0x29f6046b),
+ WTCP(0x78d597cc, 0x2a39eed8), WTCP(0x78bdb94a, 0x2a7dff02),
+ WTCP(0x78a5a270, 0x2ac2347c), WTCP(0x788d5304, 0x2b068eda),
+ WTCP(0x7874cacb, 0x2b4b0dae), WTCP(0x785c098d, 0x2b8fb08a),
+ WTCP(0x78430f11, 0x2bd47700), WTCP(0x7829db1f, 0x2c1960a1),
+ WTCP(0x78106d7f, 0x2c5e6cfd), WTCP(0x77f6c5fb, 0x2ca39ba3),
+ WTCP(0x77dce45c, 0x2ce8ec23), WTCP(0x77c2c86e, 0x2d2e5e0b),
+ WTCP(0x77a871fa, 0x2d73f0e8), WTCP(0x778de0cd, 0x2db9a449),
+ WTCP(0x777314b2, 0x2dff77b8), WTCP(0x77580d78, 0x2e456ac4),
+ WTCP(0x773ccaeb, 0x2e8b7cf6), WTCP(0x77214cdb, 0x2ed1addb),
+ WTCP(0x77059315, 0x2f17fcfb), WTCP(0x76e99d69, 0x2f5e69e2),
+ WTCP(0x76cd6ba9, 0x2fa4f419), WTCP(0x76b0fda4, 0x2feb9b27),
+ WTCP(0x7694532e, 0x30325e96), WTCP(0x76776c17, 0x30793dee),
+ WTCP(0x765a4834, 0x30c038b5), WTCP(0x763ce759, 0x31074e72),
+ WTCP(0x761f4959, 0x314e7eab), WTCP(0x76016e0b, 0x3195c8e6),
+ WTCP(0x75e35545, 0x31dd2ca9), WTCP(0x75c4fedc, 0x3224a979),
+ WTCP(0x75a66aab, 0x326c3ed8), WTCP(0x75879887, 0x32b3ec4d),
+ WTCP(0x7568884b, 0x32fbb159), WTCP(0x754939d1, 0x33438d81),
+ WTCP(0x7529acf4, 0x338b8045), WTCP(0x7509e18e, 0x33d3892a),
+ WTCP(0x74e9d77d, 0x341ba7b1), WTCP(0x74c98e9e, 0x3463db5a),
+ WTCP(0x74a906cd, 0x34ac23a7), WTCP(0x74883fec, 0x34f48019),
+ WTCP(0x746739d8, 0x353cf02f), WTCP(0x7445f472, 0x3585736a),
+ WTCP(0x74246f9c, 0x35ce0949), WTCP(0x7402ab37, 0x3616b14c),
+ WTCP(0x73e0a727, 0x365f6af0), WTCP(0x73be6350, 0x36a835b5),
+ WTCP(0x739bdf95, 0x36f11118), WTCP(0x73791bdd, 0x3739fc98),
+ WTCP(0x7356180e, 0x3782f7b2), WTCP(0x7332d410, 0x37cc01e3),
+ WTCP(0x730f4fc9, 0x38151aa8), WTCP(0x72eb8b24, 0x385e417e),
+ WTCP(0x72c7860a, 0x38a775e1), WTCP(0x72a34066, 0x38f0b74d),
+ WTCP(0x727eba24, 0x393a053e), WTCP(0x7259f331, 0x39835f30),
+ WTCP(0x7234eb79, 0x39ccc49e), WTCP(0x720fa2eb, 0x3a163503),
+ WTCP(0x71ea1977, 0x3a5fafda), WTCP(0x71c44f0c, 0x3aa9349e),
+ WTCP(0x719e439d, 0x3af2c2ca), WTCP(0x7177f71a, 0x3b3c59d7),
+ WTCP(0x71516978, 0x3b85f940), WTCP(0x712a9aaa, 0x3bcfa07e),
+ WTCP(0x71038aa4, 0x3c194f0d), WTCP(0x70dc395e, 0x3c630464),
+ WTCP(0x70b4a6cd, 0x3cacbfff), WTCP(0x708cd2e9, 0x3cf68155),
+ WTCP(0x7064bdab, 0x3d4047e1), WTCP(0x703c670d, 0x3d8a131c),
+ WTCP(0x7013cf0a, 0x3dd3e27e), WTCP(0x6feaf59c, 0x3e1db580),
+ WTCP(0x6fc1dac1, 0x3e678b9b), WTCP(0x6f987e76, 0x3eb16449),
+ WTCP(0x6f6ee0b9, 0x3efb3f01), WTCP(0x6f45018b, 0x3f451b3d),
+ WTCP(0x6f1ae0eb, 0x3f8ef874), WTCP(0x6ef07edb, 0x3fd8d620),
+ WTCP(0x6ec5db5d, 0x4022b3b9), WTCP(0x6e9af675, 0x406c90b7),
+ WTCP(0x6e6fd027, 0x40b66c93), WTCP(0x6e446879, 0x410046c5),
+ WTCP(0x6e18bf71, 0x414a1ec6), WTCP(0x6decd517, 0x4193f40d),
+ WTCP(0x6dc0a972, 0x41ddc615), WTCP(0x6d943c8d, 0x42279455),
+ WTCP(0x6d678e71, 0x42715e45), WTCP(0x6d3a9f2a, 0x42bb235f),
+ WTCP(0x6d0d6ec5, 0x4304e31a), WTCP(0x6cdffd4f, 0x434e9cf1),
+ WTCP(0x6cb24ad6, 0x4398505b), WTCP(0x6c84576b, 0x43e1fcd1),
+ WTCP(0x6c56231c, 0x442ba1cd), WTCP(0x6c27adfd, 0x44753ec7),
+ WTCP(0x6bf8f81e, 0x44bed33a), WTCP(0x6bca0195, 0x45085e9d),
+ WTCP(0x6b9aca75, 0x4551e06b), WTCP(0x6b6b52d5, 0x459b581e),
+ WTCP(0x6b3b9ac9, 0x45e4c52f), WTCP(0x6b0ba26b, 0x462e2717),
+ WTCP(0x6adb69d3, 0x46777d52), WTCP(0x6aaaf11b, 0x46c0c75a),
+ WTCP(0x6a7a385c, 0x470a04a9), WTCP(0x6a493fb3, 0x475334b9),
+ WTCP(0x6a18073d, 0x479c5707), WTCP(0x69e68f17, 0x47e56b0c),
+ WTCP(0x69b4d761, 0x482e7045), WTCP(0x6982e039, 0x4877662c),
+ WTCP(0x6950a9c0, 0x48c04c3f), WTCP(0x691e341a, 0x490921f8),
+ WTCP(0x68eb7f67, 0x4951e6d5), WTCP(0x68b88bcd, 0x499a9a51),
+ WTCP(0x68855970, 0x49e33beb), WTCP(0x6851e875, 0x4a2bcb1f),
+ WTCP(0x681e3905, 0x4a74476b), WTCP(0x67ea4b47, 0x4abcb04c),
+ WTCP(0x67b61f63, 0x4b050541), WTCP(0x6781b585, 0x4b4d45c9),
+ WTCP(0x674d0dd6, 0x4b957162), WTCP(0x67182883, 0x4bdd878c),
+ WTCP(0x66e305b8, 0x4c2587c6), WTCP(0x66ada5a5, 0x4c6d7190),
+ WTCP(0x66780878, 0x4cb5446a), WTCP(0x66422e60, 0x4cfcffd5),
+ WTCP(0x660c1790, 0x4d44a353), WTCP(0x65d5c439, 0x4d8c2e64),
+ WTCP(0x659f348e, 0x4dd3a08c), WTCP(0x656868c3, 0x4e1af94b),
+ WTCP(0x6531610d, 0x4e623825), WTCP(0x64fa1da3, 0x4ea95c9d),
+ WTCP(0x64c29ebb, 0x4ef06637), WTCP(0x648ae48d, 0x4f375477),
+ WTCP(0x6452ef53, 0x4f7e26e1), WTCP(0x641abf46, 0x4fc4dcfb),
+ WTCP(0x63e254a2, 0x500b7649), WTCP(0x63a9afa2, 0x5051f253),
+ WTCP(0x6370d083, 0x5098509f), WTCP(0x6337b784, 0x50de90b3),
+ WTCP(0x62fe64e3, 0x5124b218), WTCP(0x62c4d8e0, 0x516ab455),
+ WTCP(0x628b13bc, 0x51b096f3), WTCP(0x625115b8, 0x51f6597b),
+ WTCP(0x6216df18, 0x523bfb78), WTCP(0x61dc701f, 0x52817c72),
+ WTCP(0x61a1c912, 0x52c6dbf5), WTCP(0x6166ea36, 0x530c198d),
+ WTCP(0x612bd3d2, 0x535134c5), WTCP(0x60f0862d, 0x53962d2a),
+ WTCP(0x60b50190, 0x53db024a), WTCP(0x60794644, 0x541fb3b1),
+ WTCP(0x603d5494, 0x546440ef), WTCP(0x60012cca, 0x54a8a992),
+ WTCP(0x5fc4cf33, 0x54eced2b), WTCP(0x5f883c1c, 0x55310b48),
+ WTCP(0x5f4b73d2, 0x5575037c), WTCP(0x5f0e76a5, 0x55b8d558),
+ WTCP(0x5ed144e5, 0x55fc806f), WTCP(0x5e93dee1, 0x56400452),
+ WTCP(0x5e5644ec, 0x56836096), WTCP(0x5e187757, 0x56c694cf),
+ WTCP(0x5dda7677, 0x5709a092), WTCP(0x5d9c429f, 0x574c8374),
+ WTCP(0x5d5ddc24, 0x578f3d0d), WTCP(0x5d1f435d, 0x57d1ccf2),
+ WTCP(0x5ce078a0, 0x581432bd), WTCP(0x5ca17c45, 0x58566e04),
+ WTCP(0x5c624ea4, 0x58987e63), WTCP(0x5c22f016, 0x58da6372),
+ WTCP(0x5be360f6, 0x591c1ccc), WTCP(0x5ba3a19f, 0x595daa0d),
+ WTCP(0x5b63b26c, 0x599f0ad1), WTCP(0x5b2393ba, 0x59e03eb6),
+ WTCP(0x5ae345e7, 0x5a214558), WTCP(0x5aa2c951, 0x5a621e56),
+};
+
+/**
+ * \brief Helper table containing the length, rasterand shape mapping to
+ * individual window slope tables. [0: sine ][0: radix2 raster
+ * ][ceil(log2(length)) length 4 .. 1024 ] [1: 10ms raster
+ * ][ceil(log2(length)) length 3.25 .. 960 ] [2: 3/4 of radix 2
+ * raster][ceil(log2(length)) length 3 .. 768 ] [1: KBD ][0:
+ * radix2 raster ][ceil(log2(length)) length 128 .. 1024 ] [1: 10ms
+ * raster ][ceil(log2(length)) length 120 .. 960 ] [2:
+ * 3/4 of radix 2 raster][ceil(log2(length)) length 96 .. 768 ]
+ */
+const FIXP_WTP *const windowSlopes[2][4][9] = {
+ { /* Sine */
+ {/* Radix 2 */
+ NULL, SineWindow8, SineWindow16, SineWindow32, SineWindow64,
+ SineWindow128, SineWindow256, SineWindow512, SineWindow1024},
+ { /* 10ms raster */
+ NULL, /* 3.25 */
+ NULL, /* 7.5 */
+ NULL, NULL, NULL, SineWindow120, SineWindow240, SineWindow480,
+ SineWindow960},
+ { /* 3/4 radix2 raster */
+ NULL, /* 3 */
+ NULL, /* 6 */
+ SineWindow12, SineWindow24, SineWindow48, SineWindow96, SineWindow192,
+ SineWindow384, SineWindow768},
+ {
+ /* 3/4 radix2 raster */
+ NULL,
+ NULL, /* 3 */
+ NULL, /* 6 */
+ SineWindow20,
+ SineWindow40,
+ NULL,
+ SineWindow160,
+ NULL,
+ NULL,
+ }},
+ { /* KBD */
+ {/* Radix 2 */
+ NULL, KBDWindow128, KBDWindow256, SineWindow512, KBDWindow1024},
+ {/* 10ms raster */
+ NULL, KBDWindow120, NULL, SineWindow480, KBDWindow960},
+ {/* 3/4 radix2 raster */
+ NULL, KBDWindow96,
+ SineWindow192, /* This entry might be accessed for erred bit streams. */
+ NULL, KBDWindow768},
+ {NULL, NULL, NULL, NULL}}};
+
+const FIXP_WTP *FDKgetWindowSlope(int length, int shape) {
+ const FIXP_WTP *w = NULL;
+ int raster, ld2_length;
+
+ /* Get ld2 of length - 2 + 1
+ -2: because first table entry is window of size 4
+ +1: because we already include +1 because of ceil(log2(length)) */
+ ld2_length = DFRACT_BITS - 1 - fNormz((FIXP_DBL)length) - 1;
+
+ /* Extract sort of "eigenvalue" (the 4 left most bits) of length. */
+ switch ((length) >> (ld2_length - 2)) {
+ case 0x8: /* radix 2 */
+ raster = 0;
+ ld2_length--; /* revert + 1 because of ceil(log2(length)) from above. */
+ break;
+ case 0xf: /* 10 ms */
+ raster = 1;
+ break;
+ case 0xc: /* 3/4 of radix 2 */
+ raster = 2;
+ break;
+ default:
+ raster = 0;
+ break;
+ }
+
+ /* The table for sine windows (shape == 0) is 4 entries longer. */
+ if (shape == 1) {
+ ld2_length -= 4;
+ }
+
+ /* Look up table */
+ w = windowSlopes[shape & 1][raster][ld2_length];
+
+ FDK_ASSERT(w != NULL);
+
+ return w;
+}
+
+ /*
+ * QMF filter and twiddle tables
+ */
+
+#ifdef QMF_COEFF_16BIT
+#define QFC(x) FX_DBL2FXCONST_SGL(x)
+#define QTCFL(x) FL2FXCONST_SGL(x)
+#define QTC(x) FX_DBL2FXCONST_SGL(x)
+#else
+#define QFC(x) ((FIXP_DBL)(x))
+#define QTCFL(x) FL2FXCONST_DBL(x)
+#define QTC(x) ((FIXP_DBL)(x))
+#endif /* ARCH_PREFER_MULT_32x16 */
+
+/*!
+ \name QMF
+ \brief QMF-Table
+ 64 channels, N = 640, optimized by PE 010516
+
+ The coeffs are rearranged compared with the reference in the following
+ way, exploiting symmetry :
+ sbr_qmf_64[5] = p_64_640_qmf[0];
+ sbr_qmf_64[6] = p_64_640_qmf[128];
+ sbr_qmf_64[7] = p_64_640_qmf[256];
+ sbr_qmf_64[8] = p_64_640_qmf[384];
+ sbr_qmf_64[9] = p_64_640_qmf[512];
+
+ sbr_qmf_64[10] = p_64_640_qmf[1];
+ sbr_qmf_64[11] = p_64_640_qmf[129];
+ sbr_qmf_64[12] = p_64_640_qmf[257];
+ sbr_qmf_64[13] = p_64_640_qmf[385];
+ sbr_qmf_64[14] = p_64_640_qmf[513];
+ .
+ .
+ .
+ sbr_qmf_64_640_qmf[315] = p_64_640_qmf[62];
+ sbr_qmf_64_640_qmf[316] = p_64_640_qmf[190];
+ sbr_qmf_64_640_qmf[317] = p_64_640_qmf[318];
+ sbr_qmf_64_640_qmf[318] = p_64_640_qmf[446];
+ sbr_qmf_64_640_qmf[319] = p_64_640_qmf[574];
+
+ sbr_qmf_64_640_qmf[320] = p_64_640_qmf[63];
+ sbr_qmf_64_640_qmf[321] = p_64_640_qmf[191];
+ sbr_qmf_64_640_qmf[322] = p_64_640_qmf[319];
+ sbr_qmf_64_640_qmf[323] = p_64_640_qmf[447];
+ sbr_qmf_64_640_qmf[324] = p_64_640_qmf[575];
+
+ sbr_qmf_64_640_qmf[319] = p_64_640_qmf[64];
+ sbr_qmf_64_640_qmf[318] = p_64_640_qmf[192];
+ sbr_qmf_64_640_qmf[317] = p_64_640_qmf[320];
+ sbr_qmf_64_640_qmf[316] = p_64_640_qmf[448];
+ sbr_qmf_64_640_qmf[315] = p_64_640_qmf[576];
+
+ sbr_qmf_64_640_qmf[314] = p_64_640_qmf[65];
+ sbr_qmf_64_640_qmf[313] = p_64_640_qmf[193];
+ sbr_qmf_64_640_qmf[312] = p_64_640_qmf[321];
+ sbr_qmf_64_640_qmf[311] = p_64_640_qmf[449];
+ sbr_qmf_64_640_qmf[310] = p_64_640_qmf[577];
+ .
+ .
+ .
+ sbr_qmf_64[9] = p_64_640_qmf[126]
+ sbr_qmf_64[8] = p_64_640_qmf[254];
+ sbr_qmf_64[7] = p_64_640_qmf[382];
+ sbr_qmf_64[6] = p_64_640_qmf[510];
+ sbr_qmf_64[5] = p_64_640_qmf[638];
+
+ sbr_qmf_64[4] = p_64_640_qmf[127]
+ sbr_qmf_64[3] = p_64_640_qmf[255];
+ sbr_qmf_64[2] = p_64_640_qmf[383];
+ sbr_qmf_64[1] = p_64_640_qmf[511];
+ sbr_qmf_64[0] = p_64_640_qmf[639];
+
+ Max sum of all FIR filter absolute coefficients is: 0x7FF5B201
+ thus, the filter output is not required to be scaled.
+
+ \showinitializer
+*/
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_PFT qmf_pfilt120[] = {
+ QFC(0x00000000), QFC(0x01b2e41d), QFC(0x2e3a7532), QFC(0xd1c58ace),
+ QFC(0xfe4d1be3), QFC(0xffefcdb5), QFC(0x02828e13), QFC(0x35eecfd1),
+ QFC(0xd94e53e3), QFC(0xfefdfe42), QFC(0xffec30b0), QFC(0x036b8e20),
+ QFC(0x3daa7c5c), QFC(0xe08b3fa6), QFC(0xff8f33fc), QFC(0xffe88ba8),
+ QFC(0x04694101), QFC(0x4547daeb), QFC(0xe75f8bb7), QFC(0x0000e790),
+ QFC(0xffe69150), QFC(0x057341bc), QFC(0x4c9ef50f), QFC(0xedb0fdbd),
+ QFC(0x00549c76), QFC(0xffe6db43), QFC(0x067ef951), QFC(0x5389d1bb),
+ QFC(0xf36dbfe6), QFC(0x008cbe92), QFC(0xffea353a), QFC(0x077fedb3),
+ QFC(0x59e2f69e), QFC(0xf887507c), QFC(0x00acbd2f), QFC(0xfff176e1),
+ QFC(0x086685a4), QFC(0x5f845914), QFC(0xfcf2b6c8), QFC(0x00b881db),
+ QFC(0xfffd1253), QFC(0x09233c49), QFC(0x64504658), QFC(0x00adb69e),
+ QFC(0x00b4790a), QFC(0x000d31b5), QFC(0x09a3e163), QFC(0x682b39a4),
+ QFC(0x03b8f8dc), QFC(0x00a520bb), QFC(0x0021e26b), QFC(0x09d536b4),
+ QFC(0x6afb0c80), QFC(0x06186566), QFC(0x008db1f0), QFC(0x003a81c0),
+ QFC(0x09a505f2), QFC(0x6cb28145), QFC(0x07d6e67c), QFC(0x00728512),
+ QFC(0x0055dba1), QFC(0x09015651), QFC(0x6d474e1d), QFC(0x09015651),
+ QFC(0x0055dba1), QFC(0xfe4d1be3), QFC(0xd1c58ace), QFC(0x2e3a7532),
+ QFC(0x01b2e41d), QFC(0x00000000),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_PFT qmf_pfilt200[] = {
+ QFC(0x00000000), QFC(0x01b2e41d), QFC(0x2e3a7532), QFC(0xd1c58ace),
+ QFC(0xfe4d1be3), QFC(0xffefd5d9), QFC(0x022c39a4), QFC(0x32d6e6f6),
+ QFC(0xd652421f), QFC(0xfebafd64), QFC(0xffef3d2e), QFC(0x02af2a39),
+ QFC(0x377b44a6), QFC(0xdac7ff47), QFC(0xff1d9e1f), QFC(0xffed03e9),
+ QFC(0x033b07ff), QFC(0x3c1fc4e4), QFC(0xdf2029d5), QFC(0xff74a37e),
+ QFC(0xffeab7cc), QFC(0x03cf3ade), QFC(0x40bc12f6), QFC(0xe3546cf8),
+ QFC(0xffc070af), QFC(0xffe88ba8), QFC(0x04694101), QFC(0x4547daeb),
+ QFC(0xe75f8bb7), QFC(0x0000e790), QFC(0xffe7546d), QFC(0x050826e6),
+ QFC(0x49ba0a48), QFC(0xeb3ac63a), QFC(0x0036aa5d), QFC(0xffe6665c),
+ QFC(0x05a92d73), QFC(0x4e0b0602), QFC(0xeee323fd), QFC(0x0061fdf9),
+ QFC(0xffe6858d), QFC(0x0649e26b), QFC(0x523225cf), QFC(0xf2549ca7),
+ QFC(0x00838276), QFC(0xffe7e0bd), QFC(0x06e7cba4), QFC(0x5627597c),
+ QFC(0xf58c23ae), QFC(0x009c49df), QFC(0xffea353a), QFC(0x077fedb3),
+ QFC(0x59e2f69e), QFC(0xf887507c), QFC(0x00acbd2f), QFC(0xffee0a64),
+ QFC(0x080e83ac), QFC(0x5d5bac5e), QFC(0xfb432a8a), QFC(0x00b5e294),
+ QFC(0xfff35c0f), QFC(0x08905893), QFC(0x608bf7c1), QFC(0xfdbfe2d8),
+ QFC(0x00b8dcd6), QFC(0xfffa67ed), QFC(0x0901a70f), QFC(0x636d2657),
+ QFC(0xfffccdc7), QFC(0x00b66387), QFC(0x0002f512), QFC(0x095eb98e),
+ QFC(0x65f9595d), QFC(0x01fa380f), QFC(0x00afb0f3), QFC(0x000d31b5),
+ QFC(0x09a3e163), QFC(0x682b39a4), QFC(0x03b8f8dc), QFC(0x00a520bb),
+ QFC(0x00193141), QFC(0x09cc1a7d), QFC(0x69fbfee3), QFC(0x05395430),
+ QFC(0x0097ce05), QFC(0x00269ad4), QFC(0x09d3fe14), QFC(0x6b69bfaf),
+ QFC(0x067e12f2), QFC(0x00889924), QFC(0x003567de), QFC(0x09b75cca),
+ QFC(0x6c716eb9), QFC(0x0789e850), QFC(0x00781556), QFC(0x0045436a),
+ QFC(0x097277a9), QFC(0x6d110fe4), QFC(0x085f29c6), QFC(0x00670cb6),
+ QFC(0x0055dba1), QFC(0x09015651), QFC(0x6d474e1d), QFC(0x09015651),
+ QFC(0x0055dba1), QFC(0xfe4d1be3), QFC(0xd1c58ace), QFC(0x2e3a7532),
+ QFC(0x01b2e41d), QFC(0x00000000),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_cos40[] = {
+ QTC(0x7fef5260), QTC(0x7f69ff76), QTC(0x7e5fe493), QTC(0x7cd21707),
+ QTC(0x7ac23561), QTC(0x783265c0), QTC(0x75255392), QTC(0x719e2cd2),
+ QTC(0x6da09eb1), QTC(0x6930d1c4), QTC(0x645365b2), QTC(0x5f0d6c5b),
+ QTC(0x59646498), QTC(0x535e3479), QTC(0x4d012324), QTC(0x4653d24b),
+ QTC(0x3f5d373e), QTC(0x382493b0), QTC(0x30b16e23), QTC(0x290b8a12),
+ QTC(0x213adfda), QTC(0x1947946c), QTC(0x1139f0cf), QTC(0x091a597e),
+ QTC(0x00f145ab), QTC(0xf8c73668), QTC(0xf0a4adcf), QTC(0xe8922622),
+ QTC(0xe09808f5), QTC(0xd8bea66a), QTC(0xd10e2c89), QTC(0xc98e9eb5),
+ QTC(0xc247cd5a), QTC(0xbb414dc0), QTC(0xb4827228), QTC(0xae12422c),
+ QTC(0xa7f7736a), QTC(0xa2386284), QTC(0x9cdb0c83), QTC(0x97e50896),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_sin40[] = {
+ QTC(0x0415583b), QTC(0x0c3bc74f), QTC(0x145576b1), QTC(0x1c59f557),
+ QTC(0x2440e84d), QTC(0x2c021369), QTC(0x339561e1), QTC(0x3af2eeb7),
+ QTC(0x42130cf0), QTC(0x48ee4f98), QTC(0x4f7d917c), QTC(0x55b9fc9e),
+ QTC(0x5b9d1154), QTC(0x6120ad0d), QTC(0x663f10b7), QTC(0x6af2e6bc),
+ QTC(0x6f374891), QTC(0x7307c3d0), QTC(0x76605edb), QTC(0x793d9d03),
+ QTC(0x7b9c8226), QTC(0x7d7a95cf), QTC(0x7ed5e5c6), QTC(0x7fad081b),
+ QTC(0x7fff1c9b), QTC(0x7fcbcdbc), QTC(0x7f1350f8), QTC(0x7dd6668f),
+ QTC(0x7c1658c5), QTC(0x79d4fa89), QTC(0x7714a58b), QTC(0x73d837ca),
+ QTC(0x7023109a), QTC(0x6bf90d1d), QTC(0x675e843e), QTC(0x6258422c),
+ QTC(0x5ceb8355), QTC(0x571deefa), QTC(0x50f59141), QTC(0x4a78d4f0),
+};
+
+/* This filter is scaled (0.8*pfilt) */
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_PFT qmf_pfilt400[] = {
+ QFC(0x00000000), QFC(0x015be9b1), QFC(0x24fb90f5), QFC(0xdb046f0b),
+ QFC(0xfea4164f), QFC(0xfff15ed6), QFC(0x018b53a8), QFC(0x26d2bd4e),
+ QFC(0xdcd812f9), QFC(0xfed12595), QFC(0xfff3117b), QFC(0x01bcfae9),
+ QFC(0x28abebf8), QFC(0xdea834e5), QFC(0xfefbfdea), QFC(0xfff32e53),
+ QFC(0x01f075de), QFC(0x2a86e540), QFC(0xe07383c3), QFC(0xff24936e),
+ QFC(0xfff29758), QFC(0x0225bb61), QFC(0x2c629d51), QFC(0xe2399905),
+ QFC(0xff4ae4e6), QFC(0xfff1ab73), QFC(0x025cb6d7), QFC(0x2e3e69f9),
+ QFC(0xe3fa13fc), QFC(0xff6eefd4), QFC(0xfff0cfed), QFC(0x0295a000),
+ QFC(0x30196a50), QFC(0xe5b354ab), QFC(0xff9082cb), QFC(0xffefd442),
+ QFC(0x02d01d61), QFC(0x31f2b6ac), QFC(0xe765dadc), QFC(0xffb0037f),
+ QFC(0xffeef970), QFC(0x030c2f18), QFC(0x33c9a8c5), QFC(0xe910572d),
+ QFC(0xffcd26f2), QFC(0xffee0f91), QFC(0x03494088), QFC(0x359ce8be),
+ QFC(0xeab28265), QFC(0xffe8133f), QFC(0xffed3c86), QFC(0x03876734),
+ QFC(0x376caf22), QFC(0xec4c6fc6), QFC(0x0000b940), QFC(0xffecb05f),
+ QFC(0x03c6b32b), QFC(0x3936c186), QFC(0xeddbfa4a), QFC(0x00174372),
+ QFC(0xffec438a), QFC(0x04068585), QFC(0x3afb3b6d), QFC(0xef62382f),
+ QFC(0x002bbb7e), QFC(0xffebc5c7), QFC(0x0446af4f), QFC(0x3cb9159f),
+ QFC(0xf0de3518), QFC(0x003e0713), QFC(0xffeb8517), QFC(0x0487578f),
+ QFC(0x3e6f3802), QFC(0xf24f4ffd), QFC(0x004e64c7), QFC(0xffeb8b0d),
+ QFC(0x04c7cd0d), QFC(0x401d78d8), QFC(0xf3b6114c), QFC(0x005ccd60),
+ QFC(0xffeb9e0a), QFC(0x0507e855), QFC(0x41c1b7d9), QFC(0xf5107d52),
+ QFC(0x0069352b), QFC(0xffec0c97), QFC(0x054789e4), QFC(0x435c76d2),
+ QFC(0xf6600380), QFC(0x0073ff44), QFC(0xffecb3ca), QFC(0x05863c83),
+ QFC(0x44ec4796), QFC(0xf7a34fbf), QFC(0x007d07e5), QFC(0xffed65ae),
+ QFC(0x05c3bdde), QFC(0x46702a28), QFC(0xf8da6b28), QFC(0x008444ef),
+ QFC(0xffee90fb), QFC(0x05fff15c), QFC(0x47e8c54c), QFC(0xfa05d9fc),
+ QFC(0x008a30f2), QFC(0xffefff78), QFC(0x0639db53), QFC(0x4952ab1e),
+ QFC(0xfb23d977), QFC(0x008e9313), QFC(0xfff1a1ea), QFC(0x067202f0),
+ QFC(0x4aafbd18), QFC(0xfc35bba2), QFC(0x00918210), QFC(0xfff3a45f),
+ QFC(0x06a741b7), QFC(0x4bfdfb06), QFC(0xfd3aee85), QFC(0x009350b6),
+ QFC(0xfff5e33f), QFC(0x06d9e076), QFC(0x4d3cc634), QFC(0xfe331be0),
+ QFC(0x0093e3de), QFC(0xfff867de), QFC(0x07090b4f), QFC(0x4e6cc1b3),
+ QFC(0xff1f4fd2), QFC(0x00936109), QFC(0xfffb8658), QFC(0x073485a5),
+ QFC(0x4f8a8512), QFC(0xfffd716c), QFC(0x0091e939), QFC(0xfffec6af),
+ QFC(0x075c2159), QFC(0x50986228), QFC(0x00cfb536), QFC(0x008f7f85),
+ QFC(0x00025da8), QFC(0x077efad8), QFC(0x5194477e), QFC(0x0194f9a6),
+ QFC(0x008c8d8f), QFC(0x00064e63), QFC(0x079d423f), QFC(0x527db75e),
+ QFC(0x024d9e1c), QFC(0x00886b36), QFC(0x000a8e2a), QFC(0x07b64de9),
+ QFC(0x5355c7b6), QFC(0x02fa60b0), QFC(0x00841a2f), QFC(0x000f2b4f),
+ QFC(0x07c95704), QFC(0x5418bd4a), QFC(0x0399eb6f), QFC(0x007eea79),
+ QFC(0x00142767), QFC(0x07d67b97), QFC(0x54c998b6), QFC(0x042ddcf3),
+ QFC(0x0079719e), QFC(0x00193ee8), QFC(0x07dd27cf), QFC(0x55662c93),
+ QFC(0x04b5da5c), QFC(0x007369b7), QFC(0x001ee243), QFC(0x07dccb44),
+ QFC(0x55ee32f2), QFC(0x0531a8c2), QFC(0x006d4750), QFC(0x002471ce),
+ QFC(0x07d588d9), QFC(0x566317ad), QFC(0x05a2ff7a), QFC(0x0066c7aa),
+ QFC(0x002ab97f), QFC(0x07c5e3d5), QFC(0x56c12561), QFC(0x0607ed0d),
+ QFC(0x00601112), QFC(0x0030e1af), QFC(0x07ae9698), QFC(0x570be9e8),
+ QFC(0x0662a78a), QFC(0x005958bb), QFC(0x00376922), QFC(0x078ec621),
+ QFC(0x5740d984), QFC(0x06b287d1), QFC(0x00527092), QFC(0x003e065c),
+ QFC(0x0765b74d), QFC(0x57607ccb), QFC(0x06f819ec), QFC(0x004b9363),
+ QFC(0x0044afb4), QFC(0x0734450e), QFC(0x576c3e7e), QFC(0x0734450e),
+ QFC(0x0044afb4), QFC(0xfea4164f), QFC(0xdb046f0b), QFC(0x24fb90f5),
+ QFC(0x015be9b1), QFC(0x00000000),
+};
+
+const FIXP_QTW qmf_phaseshift_cos16[] = {
+ QTC(0x7fc25596), QTC(0x7dd6668f), QTC(0x7a05eead), QTC(0x745f9dd1),
+ QTC(0x6cf934fc), QTC(0x63ef3290), QTC(0x59646498), QTC(0x4d8162c4),
+ QTC(0x4073f21d), QTC(0x326e54c7), QTC(0x23a6887f), QTC(0x145576b1),
+ QTC(0x04b6195d), QTC(0xf50497fb), QTC(0xe57d5fda), QTC(0xd65c3b7b),
+};
+const FIXP_QTW qmf_phaseshift_sin16[] = {
+ QTC(0x07d95b9e), QTC(0x176dd9de), QTC(0x26a82186), QTC(0x354d9057),
+ QTC(0x4325c135), QTC(0x4ffb654d), QTC(0x5b9d1154), QTC(0x65ddfbd3),
+ QTC(0x6e96a99d), QTC(0x75a585cf), QTC(0x7aef6323), QTC(0x7e5fe493),
+ QTC(0x7fe9cbc0), QTC(0x7f872bf3), QTC(0x7d3980ec), QTC(0x7909a92d),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_PFT qmf_pfilt240[] = {
+ /* FP filter implementation */
+ QFC(0x00000000), QFC(0x0121ed68), QFC(0x1ed1a380), QFC(0xe12e5c80),
+ QFC(0xfede1298), QFC(0xfff4b438), QFC(0x0164d8de), QFC(0x21610064),
+ QFC(0xe3b64ef2), QFC(0xff1ba1be), QFC(0xfff533ce), QFC(0x01ac5eb8),
+ QFC(0x23f48a8e), QFC(0xe63437e4), QFC(0xff53fed7), QFC(0xfff40ee0),
+ QFC(0x01f7edb3), QFC(0x26895855), QFC(0xe8a5bb55), QFC(0xff871d30),
+ QFC(0xfff2cb20), QFC(0x0247b415), QFC(0x291c52e4), QFC(0xeb077fc7),
+ QFC(0xffb4cd53), QFC(0xfff18a22), QFC(0x029b070e), QFC(0x2baa29ab),
+ QFC(0xed57da15), QFC(0xffdd4df1), QFC(0xfff05d1b), QFC(0x02f0d600),
+ QFC(0x2e2fe755), QFC(0xef9507d5), QFC(0x00009a60), QFC(0xffefac36),
+ QFC(0x0348fcbc), QFC(0x30a98c1c), QFC(0xf1bba8f2), QFC(0x001eed4c),
+ QFC(0xffef0b8b), QFC(0x03a22bd2), QFC(0x3314a372), QFC(0xf3cb53d5),
+ QFC(0x0038684e), QFC(0xffeef3e0), QFC(0x03fbd58b), QFC(0x356de4ab),
+ QFC(0xf5c263c0), QFC(0x004d55d0), QFC(0xffef3cd8), QFC(0x0454a637),
+ QFC(0x37b13672), QFC(0xf79e7feb), QFC(0x005dd461), QFC(0xfff01619),
+ QFC(0x04abb9c0), QFC(0x39dc5c00), QFC(0xf95f9279), QFC(0x006a5b4d),
+ QFC(0xfff178d2), QFC(0x04fff3cb), QFC(0x3beca455), QFC(0xfb04e050),
+ QFC(0x007328ca), QFC(0xfff390f0), QFC(0x054fa1dc), QFC(0x3ddd668e),
+ QFC(0xfc8c7550), QFC(0x00788f16), QFC(0xfff64f40), QFC(0x0599ae6b),
+ QFC(0x3fad90c7), QFC(0xfdf72485), QFC(0x007b013c), QFC(0xfff9abe4),
+ QFC(0x05dcdec0), QFC(0x415aa155), QFC(0xff44c284), QFC(0x007ad0dd),
+ QFC(0xfffe0c37), QFC(0x06177d87), QFC(0x42e02f00), QFC(0x0073cf14),
+ QFC(0x007850b2), QFC(0x000314dd), QFC(0x0647fe8b), QFC(0x443e0472),
+ QFC(0x0185ddb7), QFC(0x00741328), QFC(0x0008cbce), QFC(0x066d40eb),
+ QFC(0x45722655), QFC(0x027b5093), QFC(0x006e15d2), QFC(0x000f67a8),
+ QFC(0x0684f772), QFC(0x46789539), QFC(0x03537bc9), QFC(0x0066c76d),
+ QFC(0x001696f2), QFC(0x068e247c), QFC(0x47520855), QFC(0x04104399),
+ QFC(0x005e76a0), QFC(0x001e5ed7), QFC(0x06874760), QFC(0x47fd3e55),
+ QFC(0x04b27f90), QFC(0x0055a663), QFC(0x0027012b), QFC(0x066e03f9),
+ QFC(0x487700c7), QFC(0x0539eefc), QFC(0x004c58b7), QFC(0x0030042f),
+ QFC(0x0641b0ab), QFC(0x48c0afc7), QFC(0x05a90172), QFC(0x0042c9e7),
+ QFC(0x00393d16), QFC(0x0600e435), QFC(0x48da3400), QFC(0x0600e435),
+ QFC(0x00393d16), QFC(0xfede1298), QFC(0xe12e5c80), QFC(0x1ed1a380),
+ QFC(0x0121ed68), QFC(0x00000000),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_cos24[] = {
+ QTC(0x7fded530), QTC(0x7ed5e5c6), QTC(0x7cc62bdf), QTC(0x79b3ece0),
+ QTC(0x75a585cf), QTC(0x70a35e25), QTC(0x6ab7d663), QTC(0x63ef3290),
+ QTC(0x5c5780d3), QTC(0x54007c51), QTC(0x4afb6c98), QTC(0x415b01ce),
+ QTC(0x37332dfd), QTC(0x2c98fbba), QTC(0x21a26295), QTC(0x1666198d),
+ QTC(0x0afb6805), QTC(0xff79f587), QTC(0xf3f998c0), QTC(0xe8922622),
+ QTC(0xdd5b3e7b), QTC(0xd26c1e08), QTC(0xc7db6c50), QTC(0xbdbf0d2f),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_sin24[] = {
+ QTC(0x05c1f4e7), QTC(0x1139f0cf), QTC(0x1c8e3bbe), QTC(0x27a75c95),
+ QTC(0x326e54c7), QTC(0x3cccd004), QTC(0x46ad5278), QTC(0x4ffb654d),
+ QTC(0x58a3c118), QTC(0x609475c3), QTC(0x67bd0fbd), QTC(0x6e0eba0c),
+ QTC(0x737c5d0b), QTC(0x77fab989), QTC(0x7b808015), QTC(0x7e06644c),
+ QTC(0x7f872bf3), QTC(0x7fffb9d1), QTC(0x7f6f141f), QTC(0x7dd6668f),
+ QTC(0x7b38ffde), QTC(0x779c4afc), QTC(0x7307c3d0), QTC(0x6d84e7b7),
+};
+
+/* qmf_pfilt640 is used with stride 2 instead of qmf_pfilt320[] */
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_cos32[] = {
+ QTC(0x7fe9cbc0), QTC(0x7f3857f6), QTC(0x7dd6668f), QTC(0x7bc5e290),
+ QTC(0x7909a92d), QTC(0x75a585cf), QTC(0x719e2cd2), QTC(0x6cf934fc),
+ QTC(0x67bd0fbd), QTC(0x61f1003f), QTC(0x5b9d1154), QTC(0x54ca0a4b),
+ QTC(0x4d8162c4), QTC(0x45cd358f), QTC(0x3db832a6), QTC(0x354d9057),
+ QTC(0x2c98fbba), QTC(0x23a6887f), QTC(0x1a82a026), QTC(0x1139f0cf),
+ QTC(0x07d95b9e), QTC(0xfe6de2e0), QTC(0xf50497fb), QTC(0xebaa894f),
+ QTC(0xe26cb01b), QTC(0xd957de7a), QTC(0xd078ad9e), QTC(0xc7db6c50),
+ QTC(0xbf8c0de3), QTC(0xb796199b), QTC(0xb0049ab3), QTC(0xa8e21106),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_sin32[] = {
+ QTC(0x04b6195d), QTC(0x0e1bc2e4), QTC(0x176dd9de), QTC(0x209f701c),
+ QTC(0x29a3c485), QTC(0x326e54c7), QTC(0x3af2eeb7), QTC(0x4325c135),
+ QTC(0x4afb6c98), QTC(0x5269126e), QTC(0x59646498), QTC(0x5fe3b38d),
+ QTC(0x65ddfbd3), QTC(0x6b4af279), QTC(0x7023109a), QTC(0x745f9dd1),
+ QTC(0x77fab989), QTC(0x7aef6323), QTC(0x7d3980ec), QTC(0x7ed5e5c6),
+ QTC(0x7fc25596), QTC(0x7ffd885a), QTC(0x7f872bf3), QTC(0x7e5fe493),
+ QTC(0x7c894bde), QTC(0x7a05eead), QTC(0x76d94989), QTC(0x7307c3d0),
+ QTC(0x6e96a99d), QTC(0x698c246c), QTC(0x63ef3290), QTC(0x5dc79d7c),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_cos_downsamp32[] = {
+ QTC(0x7fd8878e), QTC(0x7e9d55fc), QTC(0x7c29fbee), QTC(0x78848414),
+ QTC(0x73b5ebd1), QTC(0x6dca0d14), QTC(0x66cf8120), QTC(0x5ed77c8a),
+ QTC(0x55f5a4d2), QTC(0x4c3fdff4), QTC(0x41ce1e65), QTC(0x36ba2014),
+ QTC(0x2b1f34eb), QTC(0x1f19f97b), QTC(0x12c8106f), QTC(0x0647d97c),
+ QTC(0xf9b82684), QTC(0xed37ef91), QTC(0xe0e60685), QTC(0xd4e0cb15),
+ QTC(0xc945dfec), QTC(0xbe31e19b), QTC(0xb3c0200c), QTC(0xaa0a5b2e),
+ QTC(0xa1288376), QTC(0x99307ee0), QTC(0x9235f2ec), QTC(0x8c4a142f),
+ QTC(0x877b7bec), QTC(0x83d60412), QTC(0x8162aa04), QTC(0x80277872),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_sin_downsamp32[] = {
+ QTC(0x0647d97c), QTC(0x12c8106f), QTC(0x1f19f97b), QTC(0x2b1f34eb),
+ QTC(0x36ba2014), QTC(0x41ce1e65), QTC(0x4c3fdff4), QTC(0x55f5a4d2),
+ QTC(0x5ed77c8a), QTC(0x66cf8120), QTC(0x6dca0d14), QTC(0x73b5ebd1),
+ QTC(0x78848414), QTC(0x7c29fbee), QTC(0x7e9d55fc), QTC(0x7fd8878e),
+ QTC(0x7fd8878e), QTC(0x7e9d55fc), QTC(0x7c29fbee), QTC(0x78848414),
+ QTC(0x73b5ebd1), QTC(0x6dca0d14), QTC(0x66cf8120), QTC(0x5ed77c8a),
+ QTC(0x55f5a4d2), QTC(0x4c3fdff4), QTC(0x41ce1e65), QTC(0x36ba2014),
+ QTC(0x2b1f34eb), QTC(0x1f19f97b), QTC(0x12c8106f), QTC(0x0647d97c),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_PFT qmf_pfilt640[] = {
+ QFC(0x00000000), QFC(0x01b2e41d), QFC(0x2e3a7532), QFC(0xd1c58ace),
+ QFC(0xfe4d1be3), QFC(0xffede50e), QFC(0x01d78bfc), QFC(0x2faa221c),
+ QFC(0xd3337b3d), QFC(0xfe70b8d1), QFC(0xffed978a), QFC(0x01fd3ba0),
+ QFC(0x311af3a4), QFC(0xd49fd55f), QFC(0xfe933dc0), QFC(0xffefc9b9),
+ QFC(0x02244a25), QFC(0x328cc6f0), QFC(0xd60a46e5), QFC(0xfeb48d0d),
+ QFC(0xfff0065d), QFC(0x024bf7a1), QFC(0x33ff670e), QFC(0xd7722f04),
+ QFC(0xfed4bec3), QFC(0xffeff6ca), QFC(0x0274ba43), QFC(0x3572ec70),
+ QFC(0xd8d7f21f), QFC(0xfef3f6ab), QFC(0xffef7b8b), QFC(0x029e35b4),
+ QFC(0x36e69691), QFC(0xda3b176a), QFC(0xff120d70), QFC(0xffeedfa4),
+ QFC(0x02c89901), QFC(0x385a49c4), QFC(0xdb9b5b12), QFC(0xff2ef725),
+ QFC(0xffee1650), QFC(0x02f3e48d), QFC(0x39ce0477), QFC(0xdcf898fb),
+ QFC(0xff4aabc8), QFC(0xffed651d), QFC(0x03201116), QFC(0x3b415115),
+ QFC(0xde529086), QFC(0xff6542d1), QFC(0xffecc31b), QFC(0x034d01f1),
+ QFC(0x3cb41219), QFC(0xdfa93ab5), QFC(0xff7ee3f1), QFC(0xffebe77b),
+ QFC(0x037ad438), QFC(0x3e25b17e), QFC(0xe0fc421e), QFC(0xff975c01),
+ QFC(0xffeb50b2), QFC(0x03a966bc), QFC(0x3f962fb8), QFC(0xe24b8f66),
+ QFC(0xffaea5d6), QFC(0xffea9192), QFC(0x03d8afe6), QFC(0x41058bc6),
+ QFC(0xe396a45d), QFC(0xffc4e365), QFC(0xffe9ca76), QFC(0x04083fec),
+ QFC(0x4272a385), QFC(0xe4de0cb0), QFC(0xffda17f2), QFC(0xffe940f4),
+ QFC(0x043889c6), QFC(0x43de620a), QFC(0xe620c476), QFC(0xffee183b),
+ QFC(0xffe88ba8), QFC(0x04694101), QFC(0x4547daeb), QFC(0xe75f8bb7),
+ QFC(0x0000e790), QFC(0xffe83a07), QFC(0x049aa82f), QFC(0x46aea856),
+ QFC(0xe89971b7), QFC(0x00131c75), QFC(0xffe79e16), QFC(0x04cc2fcf),
+ QFC(0x4812f848), QFC(0xe9cea84a), QFC(0x0023b989), QFC(0xffe7746e),
+ QFC(0x04fe20be), QFC(0x4973fef2), QFC(0xeafee7f1), QFC(0x0033b927),
+ QFC(0xffe6d466), QFC(0x05303f88), QFC(0x4ad237a2), QFC(0xec2a3f5f),
+ QFC(0x00426f36), QFC(0xffe6afed), QFC(0x05626209), QFC(0x4c2ca3df),
+ QFC(0xed50a31d), QFC(0x00504f41), QFC(0xffe65416), QFC(0x05950122),
+ QFC(0x4d83976d), QFC(0xee71b2fe), QFC(0x005d36df), QFC(0xffe681c6),
+ QFC(0x05c76fed), QFC(0x4ed62be3), QFC(0xef8d4d7b), QFC(0x006928a0),
+ QFC(0xffe66dd0), QFC(0x05f9c051), QFC(0x5024d70e), QFC(0xf0a3959f),
+ QFC(0x007400b8), QFC(0xffe66fab), QFC(0x062bf5ec), QFC(0x516eefb9),
+ QFC(0xf1b461ab), QFC(0x007e0393), QFC(0xffe69423), QFC(0x065dd56a),
+ QFC(0x52b449de), QFC(0xf2bf6ea4), QFC(0x00872c63), QFC(0xffe6fed4),
+ QFC(0x068f8b44), QFC(0x53f495aa), QFC(0xf3c4e887), QFC(0x008f87aa),
+ QFC(0xffe75361), QFC(0x06c0f0c0), QFC(0x552f8ff7), QFC(0xf4c473c5),
+ QFC(0x0096dcc2), QFC(0xffe80414), QFC(0x06f1825d), QFC(0x56654bdd),
+ QFC(0xf5be0fa9), QFC(0x009da526), QFC(0xffe85b4a), QFC(0x0721bf22),
+ QFC(0x579505f5), QFC(0xf6b1f3c3), QFC(0x00a3508f), QFC(0xffe954d0),
+ QFC(0x075112a2), QFC(0x58befacd), QFC(0xf79fa13a), QFC(0x00a85e94),
+ QFC(0xffea353a), QFC(0x077fedb3), QFC(0x59e2f69e), QFC(0xf887507c),
+ QFC(0x00acbd2f), QFC(0xffeb3849), QFC(0x07ad8c26), QFC(0x5b001db8),
+ QFC(0xf96916f5), QFC(0x00b06b68), QFC(0xffec8409), QFC(0x07da2b7f),
+ QFC(0x5c16d0ae), QFC(0xfa44a069), QFC(0x00b36acd), QFC(0xffedc418),
+ QFC(0x08061671), QFC(0x5d26be9b), QFC(0xfb19b7bd), QFC(0x00b58c8d),
+ QFC(0xffef2395), QFC(0x08303897), QFC(0x5e2f6367), QFC(0xfbe8f5bd),
+ QFC(0x00b73ab0), QFC(0xfff0e7ef), QFC(0x08594888), QFC(0x5f30ff5f),
+ QFC(0xfcb1d740), QFC(0x00b85f70), QFC(0xfff294c3), QFC(0x0880ffdd),
+ QFC(0x602b0c7f), QFC(0xfd7475d8), QFC(0x00b8c6b0), QFC(0xfff48700),
+ QFC(0x08a75da4), QFC(0x611d58a3), QFC(0xfe310657), QFC(0x00b8fe0d),
+ QFC(0xfff681d6), QFC(0x08cb4e23), QFC(0x6207f220), QFC(0xfee723c6),
+ QFC(0x00b8394b), QFC(0xfff91fc9), QFC(0x08edfeaa), QFC(0x62ea6474),
+ QFC(0xff96db8f), QFC(0x00b74c37), QFC(0xfffb42b0), QFC(0x090ec1fd),
+ QFC(0x63c45243), QFC(0x0040c497), QFC(0x00b5c867), QFC(0xfffdfa24),
+ QFC(0x092d7970), QFC(0x64964063), QFC(0x00e42fa2), QFC(0x00b3d15c),
+ QFC(0x00007134), QFC(0x0949eaac), QFC(0x655f63f2), QFC(0x01816e06),
+ QFC(0x00b1978d), QFC(0x00039609), QFC(0x0963ed46), QFC(0x661fd6b8),
+ QFC(0x02186a92), QFC(0x00af374c), QFC(0x0006b1cf), QFC(0x097c1ee9),
+ QFC(0x66d76725), QFC(0x02a99097), QFC(0x00abe79e), QFC(0x0009aa3f),
+ QFC(0x099140a7), QFC(0x6785c24d), QFC(0x03343534), QFC(0x00a8739d),
+ QFC(0x000d31b5), QFC(0x09a3e163), QFC(0x682b39a4), QFC(0x03b8f8dc),
+ QFC(0x00a520bb), QFC(0x0010bc63), QFC(0x09b3d780), QFC(0x68c7269c),
+ QFC(0x0437fb0a), QFC(0x00a1039c), QFC(0x001471f8), QFC(0x09c0e59f),
+ QFC(0x6959709d), QFC(0x04b0adcb), QFC(0x009d10bf), QFC(0x0018703f),
+ QFC(0x09cab9f2), QFC(0x69e29784), QFC(0x05237f9d), QFC(0x0098b855),
+ QFC(0x001c3549), QFC(0x09d19ca9), QFC(0x6a619c5e), QFC(0x0590a67d),
+ QFC(0x009424c6), QFC(0x002064f8), QFC(0x09d52709), QFC(0x6ad73e8e),
+ QFC(0x05f7fb90), QFC(0x008f4bfd), QFC(0x0024dd50), QFC(0x09d5560b),
+ QFC(0x6b42a864), QFC(0x06593912), QFC(0x008a7dd7), QFC(0x00293718),
+ QFC(0x09d1fa23), QFC(0x6ba4629f), QFC(0x06b559c3), QFC(0x0085c217),
+ QFC(0x002d8e42), QFC(0x09caeb0f), QFC(0x6bfbdd98), QFC(0x070bbf58),
+ QFC(0x00807994), QFC(0x00329ab6), QFC(0x09c018cf), QFC(0x6c492217),
+ QFC(0x075ca90c), QFC(0x007b3875), QFC(0x003745f9), QFC(0x09b18a1d),
+ QFC(0x6c8c4c7a), QFC(0x07a8127d), QFC(0x0075fded), QFC(0x003c1fa4),
+ QFC(0x099ec3dc), QFC(0x6cc59bab), QFC(0x07ee507c), QFC(0x0070c8a5),
+ QFC(0x004103f5), QFC(0x09881dc5), QFC(0x6cf4073e), QFC(0x082f552e),
+ QFC(0x006b47fa), QFC(0x00465348), QFC(0x096d0e22), QFC(0x6d18520e),
+ QFC(0x086b1eec), QFC(0x0065fde5), QFC(0x004b6c46), QFC(0x094d7ec2),
+ QFC(0x6d32730f), QFC(0x08a24899), QFC(0x006090c4), QFC(0x0050b177),
+ QFC(0x09299ead), QFC(0x6d41d964), QFC(0x08d3e41b), QFC(0x005b5371),
+ QFC(0x0055dba1), QFC(0x09015651), QFC(0x6d474e1d), QFC(0x09015651),
+ QFC(0x0055dba1), QFC(0xfe4d1be3), QFC(0xd1c58ace), QFC(0x2e3a7532),
+ QFC(0x01b2e41d), QFC(0x00000000),
+};
+
+/* This variant of the table above is used on platforms, that have vectorized
+ access to the table reading 4 filter sets (each of 5 coefficients) in a
+ block. Format: 1st row flt[0] of 4 sets (e.g. set 0, 1, 2, 3) 2nd row
+ flt[1] of 4 sets (e.g. set 0, 1, 2, 3) 3rd row flt[2] of 4 sets (e.g. set
+ 0, 1, 2, 3) 4th row flt[3] of 4 sets (e.g. set 0, 1, 2, 3) 5th row
+ flt[4] of 4 sets (e.g. set 0, 1, 2, 3) There are 32 blocks of 20
+ coefficients, in total 640. Each of the rows must be at least 64-bit aligned
+ (see: RAM_ALIGN).
+*/
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_PFT qmf_pfilt640_vector[] = {
+ /*------------- 1 .. 4 ---------------*/
+ QFC(0xFFEDE50E),
+ QFC(0xFFED978A),
+ QFC(0xFFEFC9B9),
+ QFC(0xFFF0065D),
+ QFC(0x01D78BFC),
+ QFC(0x01FD3BA0),
+ QFC(0x02244A25),
+ QFC(0x024BF7A1),
+ QFC(0x2FAA221C),
+ QFC(0x311AF3A4),
+ QFC(0x328CC6F0),
+ QFC(0x33FF670E),
+ QFC(0xD3337B3D),
+ QFC(0xD49FD55F),
+ QFC(0xD60A46E5),
+ QFC(0xD7722F04),
+ QFC(0xFE70B8D1),
+ QFC(0xFE933DC0),
+ QFC(0xFEB48D0D),
+ QFC(0xFED4BEC3),
+ /*------------- 5 .. 8 ---------------*/
+ QFC(0xFFEFF6CA),
+ QFC(0xFFEF7B8B),
+ QFC(0xFFEEDFA4),
+ QFC(0xFFEE1650),
+ QFC(0x0274BA43),
+ QFC(0x029E35B4),
+ QFC(0x02C89901),
+ QFC(0x02F3E48D),
+ QFC(0x3572EC70),
+ QFC(0x36E69691),
+ QFC(0x385A49C4),
+ QFC(0x39CE0477),
+ QFC(0xD8D7F21F),
+ QFC(0xDA3B176A),
+ QFC(0xDB9B5B12),
+ QFC(0xDCF898FB),
+ QFC(0xFEF3F6AB),
+ QFC(0xFF120D70),
+ QFC(0xFF2EF725),
+ QFC(0xFF4AABC8),
+ /*------------- 9 .. 12 ---------------*/
+ QFC(0xFFED651D),
+ QFC(0xFFECC31B),
+ QFC(0xFFEBE77B),
+ QFC(0xFFEB50B2),
+ QFC(0x03201116),
+ QFC(0x034D01F1),
+ QFC(0x037AD438),
+ QFC(0x03A966BC),
+ QFC(0x3B415115),
+ QFC(0x3CB41219),
+ QFC(0x3E25B17E),
+ QFC(0x3F962FB8),
+ QFC(0xDE529086),
+ QFC(0xDFA93AB5),
+ QFC(0xE0FC421E),
+ QFC(0xE24B8F66),
+ QFC(0xFF6542D1),
+ QFC(0xFF7EE3F1),
+ QFC(0xFF975C01),
+ QFC(0xFFAEA5D6),
+ /*------------- 13 .. 16 ---------------*/
+ QFC(0xFFEA9192),
+ QFC(0xFFE9CA76),
+ QFC(0xFFE940F4),
+ QFC(0xFFE88BA8),
+ QFC(0x03D8AFE6),
+ QFC(0x04083FEC),
+ QFC(0x043889C6),
+ QFC(0x04694101),
+ QFC(0x41058BC6),
+ QFC(0x4272A385),
+ QFC(0x43DE620A),
+ QFC(0x4547DAEB),
+ QFC(0xE396A45D),
+ QFC(0xE4DE0CB0),
+ QFC(0xE620C476),
+ QFC(0xE75F8BB7),
+ QFC(0xFFC4E365),
+ QFC(0xFFDA17F2),
+ QFC(0xFFEE183B),
+ QFC(0x0000E790),
+ /*------------- 17 .. 20 ---------------*/
+ QFC(0xFFE83A07),
+ QFC(0xFFE79E16),
+ QFC(0xFFE7746E),
+ QFC(0xFFE6D466),
+ QFC(0x049AA82F),
+ QFC(0x04CC2FCF),
+ QFC(0x04FE20BE),
+ QFC(0x05303F88),
+ QFC(0x46AEA856),
+ QFC(0x4812F848),
+ QFC(0x4973FEF2),
+ QFC(0x4AD237A2),
+ QFC(0xE89971B7),
+ QFC(0xE9CEA84A),
+ QFC(0xEAFEE7F1),
+ QFC(0xEC2A3F5F),
+ QFC(0x00131C75),
+ QFC(0x0023B989),
+ QFC(0x0033B927),
+ QFC(0x00426F36),
+ /*------------- 21 .. 24 ---------------*/
+ QFC(0xFFE6AFED),
+ QFC(0xFFE65416),
+ QFC(0xFFE681C6),
+ QFC(0xFFE66DD0),
+ QFC(0x05626209),
+ QFC(0x05950122),
+ QFC(0x05C76FED),
+ QFC(0x05F9C051),
+ QFC(0x4C2CA3DF),
+ QFC(0x4D83976D),
+ QFC(0x4ED62BE3),
+ QFC(0x5024D70E),
+ QFC(0xED50A31D),
+ QFC(0xEE71B2FE),
+ QFC(0xEF8D4D7B),
+ QFC(0xF0A3959F),
+ QFC(0x00504F41),
+ QFC(0x005D36DF),
+ QFC(0x006928A0),
+ QFC(0x007400B8),
+ /*------------- 25 .. 28 ---------------*/
+ QFC(0xFFE66FAB),
+ QFC(0xFFE69423),
+ QFC(0xFFE6FED4),
+ QFC(0xFFE75361),
+ QFC(0x062BF5EC),
+ QFC(0x065DD56A),
+ QFC(0x068F8B44),
+ QFC(0x06C0F0C0),
+ QFC(0x516EEFB9),
+ QFC(0x52B449DE),
+ QFC(0x53F495AA),
+ QFC(0x552F8FF7),
+ QFC(0xF1B461AB),
+ QFC(0xF2BF6EA4),
+ QFC(0xF3C4E887),
+ QFC(0xF4C473C5),
+ QFC(0x007E0393),
+ QFC(0x00872C63),
+ QFC(0x008F87AA),
+ QFC(0x0096DCC2),
+ /*------------- 29 .. 32 ---------------*/
+ QFC(0xFFE80414),
+ QFC(0xFFE85B4A),
+ QFC(0xFFE954D0),
+ QFC(0xFFEA353A),
+ QFC(0x06F1825D),
+ QFC(0x0721BF22),
+ QFC(0x075112A2),
+ QFC(0x077FEDB3),
+ QFC(0x56654BDD),
+ QFC(0x579505F5),
+ QFC(0x58BEFACD),
+ QFC(0x59E2F69E),
+ QFC(0xF5BE0FA9),
+ QFC(0xF6B1F3C3),
+ QFC(0xF79FA13A),
+ QFC(0xF887507C),
+ QFC(0x009DA526),
+ QFC(0x00A3508F),
+ QFC(0x00A85E94),
+ QFC(0x00ACBD2F),
+ /*------------- 33 .. 36 ---------------*/
+ QFC(0xFFEB3849),
+ QFC(0xFFEC8409),
+ QFC(0xFFEDC418),
+ QFC(0xFFEF2395),
+ QFC(0x07AD8C26),
+ QFC(0x07DA2B7F),
+ QFC(0x08061671),
+ QFC(0x08303897),
+ QFC(0x5B001DB8),
+ QFC(0x5C16D0AE),
+ QFC(0x5D26BE9B),
+ QFC(0x5E2F6367),
+ QFC(0xF96916F5),
+ QFC(0xFA44A069),
+ QFC(0xFB19B7BD),
+ QFC(0xFBE8F5BD),
+ QFC(0x00B06B68),
+ QFC(0x00B36ACD),
+ QFC(0x00B58C8D),
+ QFC(0x00B73AB0),
+ /*------------- 37 .. 40 ---------------*/
+ QFC(0xFFF0E7EF),
+ QFC(0xFFF294C3),
+ QFC(0xFFF48700),
+ QFC(0xFFF681D6),
+ QFC(0x08594888),
+ QFC(0x0880FFDD),
+ QFC(0x08A75DA4),
+ QFC(0x08CB4E23),
+ QFC(0x5F30FF5F),
+ QFC(0x602B0C7F),
+ QFC(0x611D58A3),
+ QFC(0x6207F220),
+ QFC(0xFCB1D740),
+ QFC(0xFD7475D8),
+ QFC(0xFE310657),
+ QFC(0xFEE723C6),
+ QFC(0x00B85F70),
+ QFC(0x00B8C6B0),
+ QFC(0x00B8FE0D),
+ QFC(0x00B8394B),
+ /*------------- 41 .. 44 ---------------*/
+ QFC(0xFFF91FC9),
+ QFC(0xFFFB42B0),
+ QFC(0xFFFDFA24),
+ QFC(0x00007134),
+ QFC(0x08EDFEAA),
+ QFC(0x090EC1FD),
+ QFC(0x092D7970),
+ QFC(0x0949EAAC),
+ QFC(0x62EA6474),
+ QFC(0x63C45243),
+ QFC(0x64964063),
+ QFC(0x655F63F2),
+ QFC(0xFF96DB8F),
+ QFC(0x0040C497),
+ QFC(0x00E42FA2),
+ QFC(0x01816E06),
+ QFC(0x00B74C37),
+ QFC(0x00B5C867),
+ QFC(0x00B3D15C),
+ QFC(0x00B1978D),
+ /*------------- 45 .. 48 ---------------*/
+ QFC(0x00039609),
+ QFC(0x0006B1CF),
+ QFC(0x0009AA3F),
+ QFC(0x000D31B5),
+ QFC(0x0963ED46),
+ QFC(0x097C1EE9),
+ QFC(0x099140A7),
+ QFC(0x09A3E163),
+ QFC(0x661FD6B8),
+ QFC(0x66D76725),
+ QFC(0x6785C24D),
+ QFC(0x682B39A4),
+ QFC(0x02186A92),
+ QFC(0x02A99097),
+ QFC(0x03343534),
+ QFC(0x03B8F8DC),
+ QFC(0x00AF374C),
+ QFC(0x00ABE79E),
+ QFC(0x00A8739D),
+ QFC(0x00A520BB),
+ /*------------- 49 .. 52 ---------------*/
+ QFC(0x0010BC63),
+ QFC(0x001471F8),
+ QFC(0x0018703F),
+ QFC(0x001C3549),
+ QFC(0x09B3D780),
+ QFC(0x09C0E59F),
+ QFC(0x09CAB9F2),
+ QFC(0x09D19CA9),
+ QFC(0x68C7269C),
+ QFC(0x6959709D),
+ QFC(0x69E29784),
+ QFC(0x6A619C5E),
+ QFC(0x0437FB0A),
+ QFC(0x04B0ADCB),
+ QFC(0x05237F9D),
+ QFC(0x0590A67D),
+ QFC(0x00A1039C),
+ QFC(0x009D10BF),
+ QFC(0x0098B855),
+ QFC(0x009424C6),
+ /*------------- 53 .. 56 ---------------*/
+ QFC(0x002064F8),
+ QFC(0x0024DD50),
+ QFC(0x00293718),
+ QFC(0x002D8E42),
+ QFC(0x09D52709),
+ QFC(0x09D5560B),
+ QFC(0x09D1FA23),
+ QFC(0x09CAEB0F),
+ QFC(0x6AD73E8E),
+ QFC(0x6B42A864),
+ QFC(0x6BA4629F),
+ QFC(0x6BFBDD98),
+ QFC(0x05F7FB90),
+ QFC(0x06593912),
+ QFC(0x06B559C3),
+ QFC(0x070BBF58),
+ QFC(0x008F4BFD),
+ QFC(0x008A7DD7),
+ QFC(0x0085C217),
+ QFC(0x00807994),
+ /*------------- 57 .. 60 ---------------*/
+ QFC(0x00329AB6),
+ QFC(0x003745F9),
+ QFC(0x003C1FA4),
+ QFC(0x004103F5),
+ QFC(0x09C018CF),
+ QFC(0x09B18A1D),
+ QFC(0x099EC3DC),
+ QFC(0x09881DC5),
+ QFC(0x6C492217),
+ QFC(0x6C8C4C7A),
+ QFC(0x6CC59BAB),
+ QFC(0x6CF4073E),
+ QFC(0x075CA90C),
+ QFC(0x07A8127D),
+ QFC(0x07EE507C),
+ QFC(0x082F552E),
+ QFC(0x007B3875),
+ QFC(0x0075FDED),
+ QFC(0x0070C8A5),
+ QFC(0x006B47FA),
+ /*------------- 61 .. 64 ---------------*/
+ QFC(0x00465348),
+ QFC(0x004B6C46),
+ QFC(0x0050B177),
+ QFC(0x0055DBA1),
+ QFC(0x096D0E22),
+ QFC(0x094D7EC2),
+ QFC(0x09299EAD),
+ QFC(0x09015651),
+ QFC(0x6D18520E),
+ QFC(0x6D32730F),
+ QFC(0x6D41D964),
+ QFC(0x6D474E1D),
+ QFC(0x086B1EEC),
+ QFC(0x08A24899),
+ QFC(0x08D3E41B),
+ QFC(0x09015651),
+ QFC(0x0065FDE5),
+ QFC(0x006090C4),
+ QFC(0x005B5371),
+ QFC(0x0055DBA1),
+ /*------------- 63 .. 60 ---------------*/
+ QFC(0x005B5371),
+ QFC(0x006090C4),
+ QFC(0x0065FDE5),
+ QFC(0x006B47FA),
+ QFC(0x08D3E41B),
+ QFC(0x08A24899),
+ QFC(0x086B1EEC),
+ QFC(0x082F552E),
+ QFC(0x6D41D964),
+ QFC(0x6D32730F),
+ QFC(0x6D18520E),
+ QFC(0x6CF4073E),
+ QFC(0x09299EAD),
+ QFC(0x094D7EC2),
+ QFC(0x096D0E22),
+ QFC(0x09881DC5),
+ QFC(0x0050B177),
+ QFC(0x004B6C46),
+ QFC(0x00465348),
+ QFC(0x004103F5),
+ /*------------- 59 .. 56 ---------------*/
+ QFC(0x0070C8A5),
+ QFC(0x0075FDED),
+ QFC(0x007B3875),
+ QFC(0x00807994),
+ QFC(0x07EE507C),
+ QFC(0x07A8127D),
+ QFC(0x075CA90C),
+ QFC(0x070BBF58),
+ QFC(0x6CC59BAB),
+ QFC(0x6C8C4C7A),
+ QFC(0x6C492217),
+ QFC(0x6BFBDD98),
+ QFC(0x099EC3DC),
+ QFC(0x09B18A1D),
+ QFC(0x09C018CF),
+ QFC(0x09CAEB0F),
+ QFC(0x003C1FA4),
+ QFC(0x003745F9),
+ QFC(0x00329AB6),
+ QFC(0x002D8E42),
+ /*------------- 55 .. 52 ---------------*/
+ QFC(0x0085C217),
+ QFC(0x008A7DD7),
+ QFC(0x008F4BFD),
+ QFC(0x009424C6),
+ QFC(0x06B559C3),
+ QFC(0x06593912),
+ QFC(0x05F7FB90),
+ QFC(0x0590A67D),
+ QFC(0x6BA4629F),
+ QFC(0x6B42A864),
+ QFC(0x6AD73E8E),
+ QFC(0x6A619C5E),
+ QFC(0x09D1FA23),
+ QFC(0x09D5560B),
+ QFC(0x09D52709),
+ QFC(0x09D19CA9),
+ QFC(0x00293718),
+ QFC(0x0024DD50),
+ QFC(0x002064F8),
+ QFC(0x001C3549),
+ /*------------- 51 .. 48 ---------------*/
+ QFC(0x0098B855),
+ QFC(0x009D10BF),
+ QFC(0x00A1039C),
+ QFC(0x00A520BB),
+ QFC(0x05237F9D),
+ QFC(0x04B0ADCB),
+ QFC(0x0437FB0A),
+ QFC(0x03B8F8DC),
+ QFC(0x69E29784),
+ QFC(0x6959709D),
+ QFC(0x68C7269C),
+ QFC(0x682B39A4),
+ QFC(0x09CAB9F2),
+ QFC(0x09C0E59F),
+ QFC(0x09B3D780),
+ QFC(0x09A3E163),
+ QFC(0x0018703F),
+ QFC(0x001471F8),
+ QFC(0x0010BC63),
+ QFC(0x000D31B5),
+ /*------------- 47 .. 44 ---------------*/
+ QFC(0x00A8739D),
+ QFC(0x00ABE79E),
+ QFC(0x00AF374C),
+ QFC(0x00B1978D),
+ QFC(0x03343534),
+ QFC(0x02A99097),
+ QFC(0x02186A92),
+ QFC(0x01816E06),
+ QFC(0x6785C24D),
+ QFC(0x66D76725),
+ QFC(0x661FD6B8),
+ QFC(0x655F63F2),
+ QFC(0x099140A7),
+ QFC(0x097C1EE9),
+ QFC(0x0963ED46),
+ QFC(0x0949EAAC),
+ QFC(0x0009AA3F),
+ QFC(0x0006B1CF),
+ QFC(0x00039609),
+ QFC(0x00007134),
+ /*------------- 43 .. 40 ---------------*/
+ QFC(0x00B3D15C),
+ QFC(0x00B5C867),
+ QFC(0x00B74C37),
+ QFC(0x00B8394B),
+ QFC(0x00E42FA2),
+ QFC(0x0040C497),
+ QFC(0xFF96DB8F),
+ QFC(0xFEE723C6),
+ QFC(0x64964063),
+ QFC(0x63C45243),
+ QFC(0x62EA6474),
+ QFC(0x6207F220),
+ QFC(0x092D7970),
+ QFC(0x090EC1FD),
+ QFC(0x08EDFEAA),
+ QFC(0x08CB4E23),
+ QFC(0xFFFDFA24),
+ QFC(0xFFFB42B0),
+ QFC(0xFFF91FC9),
+ QFC(0xFFF681D6),
+ /*------------- 39 .. 36 ---------------*/
+ QFC(0x00B8FE0D),
+ QFC(0x00B8C6B0),
+ QFC(0x00B85F70),
+ QFC(0x00B73AB0),
+ QFC(0xFE310657),
+ QFC(0xFD7475D8),
+ QFC(0xFCB1D740),
+ QFC(0xFBE8F5BD),
+ QFC(0x611D58A3),
+ QFC(0x602B0C7F),
+ QFC(0x5F30FF5F),
+ QFC(0x5E2F6367),
+ QFC(0x08A75DA4),
+ QFC(0x0880FFDD),
+ QFC(0x08594888),
+ QFC(0x08303897),
+ QFC(0xFFF48700),
+ QFC(0xFFF294C3),
+ QFC(0xFFF0E7EF),
+ QFC(0xFFEF2395),
+ /*------------- 35 .. 32 ---------------*/
+ QFC(0x00B58C8D),
+ QFC(0x00B36ACD),
+ QFC(0x00B06B68),
+ QFC(0x00ACBD2F),
+ QFC(0xFB19B7BD),
+ QFC(0xFA44A069),
+ QFC(0xF96916F5),
+ QFC(0xF887507C),
+ QFC(0x5D26BE9B),
+ QFC(0x5C16D0AE),
+ QFC(0x5B001DB8),
+ QFC(0x59E2F69E),
+ QFC(0x08061671),
+ QFC(0x07DA2B7F),
+ QFC(0x07AD8C26),
+ QFC(0x077FEDB3),
+ QFC(0xFFEDC418),
+ QFC(0xFFEC8409),
+ QFC(0xFFEB3849),
+ QFC(0xFFEA353A),
+ /*------------- 31 .. 28 ---------------*/
+ QFC(0x00A85E94),
+ QFC(0x00A3508F),
+ QFC(0x009DA526),
+ QFC(0x0096DCC2),
+ QFC(0xF79FA13A),
+ QFC(0xF6B1F3C3),
+ QFC(0xF5BE0FA9),
+ QFC(0xF4C473C5),
+ QFC(0x58BEFACD),
+ QFC(0x579505F5),
+ QFC(0x56654BDD),
+ QFC(0x552F8FF7),
+ QFC(0x075112A2),
+ QFC(0x0721BF22),
+ QFC(0x06F1825D),
+ QFC(0x06C0F0C0),
+ QFC(0xFFE954D0),
+ QFC(0xFFE85B4A),
+ QFC(0xFFE80414),
+ QFC(0xFFE75361),
+ /*------------- 27 .. 24 ---------------*/
+ QFC(0x008F87AA),
+ QFC(0x00872C63),
+ QFC(0x007E0393),
+ QFC(0x007400B8),
+ QFC(0xF3C4E887),
+ QFC(0xF2BF6EA4),
+ QFC(0xF1B461AB),
+ QFC(0xF0A3959F),
+ QFC(0x53F495AA),
+ QFC(0x52B449DE),
+ QFC(0x516EEFB9),
+ QFC(0x5024D70E),
+ QFC(0x068F8B44),
+ QFC(0x065DD56A),
+ QFC(0x062BF5EC),
+ QFC(0x05F9C051),
+ QFC(0xFFE6FED4),
+ QFC(0xFFE69423),
+ QFC(0xFFE66FAB),
+ QFC(0xFFE66DD0),
+ /*------------- 23 .. 20 ---------------*/
+ QFC(0x006928A0),
+ QFC(0x005D36DF),
+ QFC(0x00504F41),
+ QFC(0x00426F36),
+ QFC(0xEF8D4D7B),
+ QFC(0xEE71B2FE),
+ QFC(0xED50A31D),
+ QFC(0xEC2A3F5F),
+ QFC(0x4ED62BE3),
+ QFC(0x4D83976D),
+ QFC(0x4C2CA3DF),
+ QFC(0x4AD237A2),
+ QFC(0x05C76FED),
+ QFC(0x05950122),
+ QFC(0x05626209),
+ QFC(0x05303F88),
+ QFC(0xFFE681C6),
+ QFC(0xFFE65416),
+ QFC(0xFFE6AFED),
+ QFC(0xFFE6D466),
+ /*------------- 19 .. 16 ---------------*/
+ QFC(0x0033B927),
+ QFC(0x0023B989),
+ QFC(0x00131C75),
+ QFC(0x0000E790),
+ QFC(0xEAFEE7F1),
+ QFC(0xE9CEA84A),
+ QFC(0xE89971B7),
+ QFC(0xE75F8BB7),
+ QFC(0x4973FEF2),
+ QFC(0x4812F848),
+ QFC(0x46AEA856),
+ QFC(0x4547DAEB),
+ QFC(0x04FE20BE),
+ QFC(0x04CC2FCF),
+ QFC(0x049AA82F),
+ QFC(0x04694101),
+ QFC(0xFFE7746E),
+ QFC(0xFFE79E16),
+ QFC(0xFFE83A07),
+ QFC(0xFFE88BA8),
+ /*------------- 15 .. 12 ---------------*/
+ QFC(0xFFEE183B),
+ QFC(0xFFDA17F2),
+ QFC(0xFFC4E365),
+ QFC(0xFFAEA5D6),
+ QFC(0xE620C476),
+ QFC(0xE4DE0CB0),
+ QFC(0xE396A45D),
+ QFC(0xE24B8F66),
+ QFC(0x43DE620A),
+ QFC(0x4272A385),
+ QFC(0x41058BC6),
+ QFC(0x3F962FB8),
+ QFC(0x043889C6),
+ QFC(0x04083FEC),
+ QFC(0x03D8AFE6),
+ QFC(0x03A966BC),
+ QFC(0xFFE940F4),
+ QFC(0xFFE9CA76),
+ QFC(0xFFEA9192),
+ QFC(0xFFEB50B2),
+ /*------------- 11 .. 8 ---------------*/
+ QFC(0xFF975C01),
+ QFC(0xFF7EE3F1),
+ QFC(0xFF6542D1),
+ QFC(0xFF4AABC8),
+ QFC(0xE0FC421E),
+ QFC(0xDFA93AB5),
+ QFC(0xDE529086),
+ QFC(0xDCF898FB),
+ QFC(0x3E25B17E),
+ QFC(0x3CB41219),
+ QFC(0x3B415115),
+ QFC(0x39CE0477),
+ QFC(0x037AD438),
+ QFC(0x034D01F1),
+ QFC(0x03201116),
+ QFC(0x02F3E48D),
+ QFC(0xFFEBE77B),
+ QFC(0xFFECC31B),
+ QFC(0xFFED651D),
+ QFC(0xFFEE1650),
+ /*------------- 7 .. 4 ---------------*/
+ QFC(0xFF2EF725),
+ QFC(0xFF120D70),
+ QFC(0xFEF3F6AB),
+ QFC(0xFED4BEC3),
+ QFC(0xDB9B5B12),
+ QFC(0xDA3B176A),
+ QFC(0xD8D7F21F),
+ QFC(0xD7722F04),
+ QFC(0x385A49C4),
+ QFC(0x36E69691),
+ QFC(0x3572EC70),
+ QFC(0x33FF670E),
+ QFC(0x02C89901),
+ QFC(0x029E35B4),
+ QFC(0x0274BA43),
+ QFC(0x024BF7A1),
+ QFC(0xFFEEDFA4),
+ QFC(0xFFEF7B8B),
+ QFC(0xFFEFF6CA),
+ QFC(0xFFF0065D),
+ /*------------- 3 .. 0 ---------------*/
+ QFC(0xFEB48D0D),
+ QFC(0xFE933DC0),
+ QFC(0xFE70B8D1),
+ QFC(0xFE4D1BE3),
+ QFC(0xD60A46E5),
+ QFC(0xD49FD55F),
+ QFC(0xD3337B3D),
+ QFC(0xD1C58ACE),
+ QFC(0x328CC6F0),
+ QFC(0x311AF3A4),
+ QFC(0x2FAA221C),
+ QFC(0x2E3A7532),
+ QFC(0x02244A25),
+ QFC(0x01FD3BA0),
+ QFC(0x01D78BFC),
+ QFC(0x01B2E41D),
+ QFC(0xFFEFC9B9),
+ QFC(0xFFED978A),
+ QFC(0xFFEDE50E),
+ QFC(0x00000000),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_cos64[] = {
+ QTC(0x7ff62182), QTC(0x7fa736b4), QTC(0x7f0991c4), QTC(0x7e1d93ea),
+ QTC(0x7ce3ceb2), QTC(0x7b5d039e), QTC(0x798a23b1), QTC(0x776c4edb),
+ QTC(0x7504d345), QTC(0x72552c85), QTC(0x6f5f02b2), QTC(0x6c242960),
+ QTC(0x68a69e81), QTC(0x64e88926), QTC(0x60ec3830), QTC(0x5cb420e0),
+ QTC(0x5842dd54), QTC(0x539b2af0), QTC(0x4ebfe8a5), QTC(0x49b41533),
+ QTC(0x447acd50), QTC(0x3f1749b8), QTC(0x398cdd32), QTC(0x33def287),
+ QTC(0x2e110a62), QTC(0x2826b928), QTC(0x2223a4c5), QTC(0x1c0b826a),
+ QTC(0x15e21445), QTC(0x0fab272b), QTC(0x096a9049), QTC(0x03242abf),
+ QTC(0xfcdbd541), QTC(0xf6956fb7), QTC(0xf054d8d5), QTC(0xea1debbb),
+ QTC(0xe3f47d96), QTC(0xdddc5b3b), QTC(0xd7d946d8), QTC(0xd1eef59e),
+ QTC(0xcc210d79), QTC(0xc67322ce), QTC(0xc0e8b648), QTC(0xbb8532b0),
+ QTC(0xb64beacd), QTC(0xb140175b), QTC(0xac64d510), QTC(0xa7bd22ac),
+ QTC(0xa34bdf20), QTC(0x9f13c7d0), QTC(0x9b1776da), QTC(0x9759617f),
+ QTC(0x93dbd6a0), QTC(0x90a0fd4e), QTC(0x8daad37b), QTC(0x8afb2cbb),
+ QTC(0x8893b125), QTC(0x8675dc4f), QTC(0x84a2fc62), QTC(0x831c314e),
+ QTC(0x81e26c16), QTC(0x80f66e3c), QTC(0x8058c94c), QTC(0x8009de7e),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+const FIXP_QTW qmf_phaseshift_sin64[] = {
+ QTC(0x03242abf), QTC(0x096a9049), QTC(0x0fab272b), QTC(0x15e21445),
+ QTC(0x1c0b826a), QTC(0x2223a4c5), QTC(0x2826b928), QTC(0x2e110a62),
+ QTC(0x33def287), QTC(0x398cdd32), QTC(0x3f1749b8), QTC(0x447acd50),
+ QTC(0x49b41533), QTC(0x4ebfe8a5), QTC(0x539b2af0), QTC(0x5842dd54),
+ QTC(0x5cb420e0), QTC(0x60ec3830), QTC(0x64e88926), QTC(0x68a69e81),
+ QTC(0x6c242960), QTC(0x6f5f02b2), QTC(0x72552c85), QTC(0x7504d345),
+ QTC(0x776c4edb), QTC(0x798a23b1), QTC(0x7b5d039e), QTC(0x7ce3ceb2),
+ QTC(0x7e1d93ea), QTC(0x7f0991c4), QTC(0x7fa736b4), QTC(0x7ff62182),
+ QTC(0x7ff62182), QTC(0x7fa736b4), QTC(0x7f0991c4), QTC(0x7e1d93ea),
+ QTC(0x7ce3ceb2), QTC(0x7b5d039e), QTC(0x798a23b1), QTC(0x776c4edb),
+ QTC(0x7504d345), QTC(0x72552c85), QTC(0x6f5f02b2), QTC(0x6c242960),
+ QTC(0x68a69e81), QTC(0x64e88926), QTC(0x60ec3830), QTC(0x5cb420e0),
+ QTC(0x5842dd54), QTC(0x539b2af0), QTC(0x4ebfe8a5), QTC(0x49b41533),
+ QTC(0x447acd50), QTC(0x3f1749b8), QTC(0x398cdd32), QTC(0x33def287),
+ QTC(0x2e110a62), QTC(0x2826b928), QTC(0x2223a4c5), QTC(0x1c0b826a),
+ QTC(0x15e21445), QTC(0x0fab272b), QTC(0x096a9049), QTC(0x03242abf),
+};
+
+/*
+ * Low Delay QMF aka CLDFB
+ */
+
+#if defined(QMF_COEFF_16BIT)
+#define QTCFLLD(x) FL2FXCONST_SGL(x / (float)(1 << QMF_CLDFB_PFT_SCALE))
+#define QTCFLLDT(x) FL2FXCONST_SGL(x)
+#else
+#define QTCFLLD(x) FL2FXCONST_DBL(x / (float)(1 << QMF_CLDFB_PFT_SCALE))
+#define QTCFLLDT(x) FL2FXCONST_DBL(x)
+#endif
+
+#ifndef LOW_POWER_SBR_ONLY
+/*!
+ \name QMF-Twiddle
+ \brief QMF twiddle factors
+
+ L=32, gain=2.0, angle = 0.75
+*/
+/* sin/cos (angle) / 2 */
+const FIXP_QTW qmf_phaseshift_cos32_cldfb_ana[32] = {
+ /* analysis twiddle table */
+ QTCFLLDT(-7.071067e-01), QTCFLLDT(7.071070e-01), QTCFLLDT(7.071064e-01),
+ QTCFLLDT(-7.071073e-01), QTCFLLDT(-7.071061e-01), QTCFLLDT(7.071076e-01),
+ QTCFLLDT(7.071058e-01), QTCFLLDT(-7.071080e-01), QTCFLLDT(-7.071055e-01),
+ QTCFLLDT(7.071083e-01), QTCFLLDT(7.071052e-01), QTCFLLDT(-7.071086e-01),
+ QTCFLLDT(-7.071049e-01), QTCFLLDT(7.071089e-01), QTCFLLDT(7.071046e-01),
+ QTCFLLDT(-7.071092e-01), QTCFLLDT(-7.071042e-01), QTCFLLDT(7.071095e-01),
+ QTCFLLDT(7.071039e-01), QTCFLLDT(-7.071098e-01), QTCFLLDT(-7.071036e-01),
+ QTCFLLDT(7.071101e-01), QTCFLLDT(7.071033e-01), QTCFLLDT(-7.071104e-01),
+ QTCFLLDT(-7.071030e-01), QTCFLLDT(7.071107e-01), QTCFLLDT(7.071027e-01),
+ QTCFLLDT(-7.071111e-01), QTCFLLDT(-7.071024e-01), QTCFLLDT(7.071114e-01),
+ QTCFLLDT(7.071021e-01), QTCFLLDT(-7.071117e-01),
+};
+
+const FIXP_QTW qmf_phaseshift_cos32_cldfb_syn[32] = {
+ /* synthesis twiddle table */
+ QTCFLLDT(7.071067e-01), QTCFLLDT(-7.071070e-01), QTCFLLDT(-7.071064e-01),
+ QTCFLLDT(7.071073e-01), QTCFLLDT(7.071061e-01), QTCFLLDT(-7.071076e-01),
+ QTCFLLDT(-7.071058e-01), QTCFLLDT(7.071080e-01), QTCFLLDT(7.071055e-01),
+ QTCFLLDT(-7.071083e-01), QTCFLLDT(-7.071052e-01), QTCFLLDT(7.071086e-01),
+ QTCFLLDT(7.071049e-01), QTCFLLDT(-7.071089e-01), QTCFLLDT(-7.071046e-01),
+ QTCFLLDT(7.071092e-01), QTCFLLDT(7.071042e-01), QTCFLLDT(-7.071095e-01),
+ QTCFLLDT(-7.071039e-01), QTCFLLDT(7.071098e-01), QTCFLLDT(7.071036e-01),
+ QTCFLLDT(-7.071101e-01), QTCFLLDT(-7.071033e-01), QTCFLLDT(7.071104e-01),
+ QTCFLLDT(7.071030e-01), QTCFLLDT(-7.071107e-01), QTCFLLDT(-7.071027e-01),
+ QTCFLLDT(7.071111e-01), QTCFLLDT(7.071024e-01), QTCFLLDT(-7.071114e-01),
+ QTCFLLDT(-7.071021e-01), QTCFLLDT(7.071117e-01),
+};
+
+const FIXP_QTW qmf_phaseshift_sin32_cldfb[32] = {
+ QTCFLLDT(7.071068e-01), QTCFLLDT(7.071065e-01), QTCFLLDT(-7.071072e-01),
+ QTCFLLDT(-7.071062e-01), QTCFLLDT(7.071075e-01), QTCFLLDT(7.071059e-01),
+ QTCFLLDT(-7.071078e-01), QTCFLLDT(-7.071056e-01), QTCFLLDT(7.071081e-01),
+ QTCFLLDT(7.071053e-01), QTCFLLDT(-7.071084e-01), QTCFLLDT(-7.071050e-01),
+ QTCFLLDT(7.071087e-01), QTCFLLDT(7.071047e-01), QTCFLLDT(-7.071090e-01),
+ QTCFLLDT(-7.071044e-01), QTCFLLDT(7.071093e-01), QTCFLLDT(7.071041e-01),
+ QTCFLLDT(-7.071096e-01), QTCFLLDT(-7.071038e-01), QTCFLLDT(7.071099e-01),
+ QTCFLLDT(7.071034e-01), QTCFLLDT(-7.071103e-01), QTCFLLDT(-7.071031e-01),
+ QTCFLLDT(7.071106e-01), QTCFLLDT(7.071028e-01), QTCFLLDT(-7.071109e-01),
+ QTCFLLDT(-7.071025e-01), QTCFLLDT(7.071112e-01), QTCFLLDT(7.071022e-01),
+ QTCFLLDT(-7.071115e-01), QTCFLLDT(-7.071019e-01),
+};
+
+/* twiddles for X=(8,16) band qmf are copied from float simpleplayer
+ * implementation: qmf_phaseshift_cosX_cldfb_ana =
+ * QMFlib_twiddle3RealX_SBRLD_A qmf_phaseshift_cosX_cldfb_syn =
+ * -(QMFlib_twiddle3RealX_SBRLD_A) qmf_phaseshift_sinX_cldfb =
+ * QMFlib_twiddle3ImagX_SBRLD_A
+ */
+
+/* cos ((n + 0.5)*pi*angle/L) , order = 159, L=16 */
+const FIXP_QTW qmf_phaseshift_cos16_cldfb_ana[16] = {
+ QTCFLLDT(-0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812),
+ QTCFLLDT(-0.7071067812), QTCFLLDT(-0.7071067812), QTCFLLDT(0.7071067812),
+ QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812), QTCFLLDT(-0.7071067812),
+ QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812),
+ QTCFLLDT(-0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812),
+ QTCFLLDT(-0.7071067812),
+};
+
+/* cos ((n + 0.5)*pi*angle/L) , order = 159, L=16 */
+const FIXP_QTW qmf_phaseshift_cos16_cldfb_syn[16] = {
+ QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812), QTCFLLDT(-0.7071067812),
+ QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812),
+ QTCFLLDT(-0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812),
+ QTCFLLDT(-0.7071067812), QTCFLLDT(-0.7071067812), QTCFLLDT(0.7071067812),
+ QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812), QTCFLLDT(-0.7071067812),
+ QTCFLLDT(0.7071067812),
+};
+
+/* sin ((n + 0.5)*pi*angle/L) , order = 159, L=16 */
+const FIXP_QTW qmf_phaseshift_sin16_cldfb[16] = {
+ QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812),
+ QTCFLLDT(-0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812),
+ QTCFLLDT(-0.7071067812), QTCFLLDT(-0.7071067812), QTCFLLDT(0.7071067812),
+ QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812), QTCFLLDT(-0.7071067812),
+ QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812),
+ QTCFLLDT(-0.7071067812),
+};
+
+/* cos ((n + 0.5)*pi*angle/L) , order = 79, L=8 */
+const FIXP_QTW qmf_phaseshift_cos8_cldfb_ana[8] = {
+ QTCFLLDT(-0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812),
+ QTCFLLDT(-0.7071067812), QTCFLLDT(-0.7071067812), QTCFLLDT(0.7071067812),
+ QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812),
+};
+
+const FIXP_QTW qmf_phaseshift_cos8_cldfb_syn[8] = {
+ QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812), QTCFLLDT(-0.7071067812),
+ QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812),
+ QTCFLLDT(-0.7071067812), QTCFLLDT(0.7071067812),
+};
+
+/* sin ((n + 0.5)*pi*angle/L) , order = 79, L=8 */
+const FIXP_QTW qmf_phaseshift_sin8_cldfb[8] = {
+ QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(-0.7071067812),
+ QTCFLLDT(-0.7071067812), QTCFLLDT(0.7071067812), QTCFLLDT(0.7071067812),
+ QTCFLLDT(-0.7071067812), QTCFLLDT(-0.7071067812),
+};
+
+/* sin/cos (angle) / 128 */
+const FIXP_QTW qmf_phaseshift_cos64_cldfb[64] = {
+ QTCFLLDT(7.071068e-01), QTCFLLDT(-7.071066e-01), QTCFLLDT(-7.071070e-01),
+ QTCFLLDT(7.071065e-01), QTCFLLDT(7.071072e-01), QTCFLLDT(-7.071063e-01),
+ QTCFLLDT(-7.071074e-01), QTCFLLDT(7.071061e-01), QTCFLLDT(7.071075e-01),
+ QTCFLLDT(-7.071059e-01), QTCFLLDT(-7.071078e-01), QTCFLLDT(7.071057e-01),
+ QTCFLLDT(7.071080e-01), QTCFLLDT(-7.071055e-01), QTCFLLDT(-7.071081e-01),
+ QTCFLLDT(7.071053e-01), QTCFLLDT(7.071083e-01), QTCFLLDT(-7.071052e-01),
+ QTCFLLDT(-7.071085e-01), QTCFLLDT(7.071050e-01), QTCFLLDT(7.071087e-01),
+ QTCFLLDT(-7.071048e-01), QTCFLLDT(-7.071089e-01), QTCFLLDT(7.071046e-01),
+ QTCFLLDT(7.071090e-01), QTCFLLDT(-7.071044e-01), QTCFLLDT(-7.071092e-01),
+ QTCFLLDT(7.071042e-01), QTCFLLDT(7.071095e-01), QTCFLLDT(-7.071040e-01),
+ QTCFLLDT(-7.071096e-01), QTCFLLDT(7.071038e-01), QTCFLLDT(7.071098e-01),
+ QTCFLLDT(-7.071037e-01), QTCFLLDT(-7.071100e-01), QTCFLLDT(7.071035e-01),
+ QTCFLLDT(7.071102e-01), QTCFLLDT(-7.071033e-01), QTCFLLDT(-7.071103e-01),
+ QTCFLLDT(7.071031e-01), QTCFLLDT(7.071105e-01), QTCFLLDT(-7.071030e-01),
+ QTCFLLDT(-7.071107e-01), QTCFLLDT(7.071028e-01), QTCFLLDT(7.071109e-01),
+ QTCFLLDT(-7.071025e-01), QTCFLLDT(-7.071111e-01), QTCFLLDT(7.071024e-01),
+ QTCFLLDT(7.071113e-01), QTCFLLDT(-7.071022e-01), QTCFLLDT(-7.071115e-01),
+ QTCFLLDT(7.071020e-01), QTCFLLDT(7.071117e-01), QTCFLLDT(-7.071018e-01),
+ QTCFLLDT(-7.071118e-01), QTCFLLDT(7.071016e-01), QTCFLLDT(7.071120e-01),
+ QTCFLLDT(-7.071015e-01), QTCFLLDT(-7.071122e-01), QTCFLLDT(7.071013e-01),
+ QTCFLLDT(7.071124e-01), QTCFLLDT(-7.071011e-01), QTCFLLDT(-7.071126e-01),
+ QTCFLLDT(7.071009e-01),
+};
+const FIXP_QTW qmf_phaseshift_sin64_cldfb[64] = {
+ QTCFLLDT(7.071067e-01), QTCFLLDT(7.071069e-01), QTCFLLDT(-7.071065e-01),
+ QTCFLLDT(-7.071071e-01), QTCFLLDT(7.071064e-01), QTCFLLDT(7.071073e-01),
+ QTCFLLDT(-7.071062e-01), QTCFLLDT(-7.071075e-01), QTCFLLDT(7.071060e-01),
+ QTCFLLDT(7.071077e-01), QTCFLLDT(-7.071058e-01), QTCFLLDT(-7.071078e-01),
+ QTCFLLDT(7.071056e-01), QTCFLLDT(7.071080e-01), QTCFLLDT(-7.071055e-01),
+ QTCFLLDT(-7.071082e-01), QTCFLLDT(7.071053e-01), QTCFLLDT(7.071084e-01),
+ QTCFLLDT(-7.071050e-01), QTCFLLDT(-7.071086e-01), QTCFLLDT(7.071049e-01),
+ QTCFLLDT(7.071088e-01), QTCFLLDT(-7.071047e-01), QTCFLLDT(-7.071090e-01),
+ QTCFLLDT(7.071045e-01), QTCFLLDT(7.071092e-01), QTCFLLDT(-7.071043e-01),
+ QTCFLLDT(-7.071093e-01), QTCFLLDT(7.071041e-01), QTCFLLDT(7.071095e-01),
+ QTCFLLDT(-7.071040e-01), QTCFLLDT(-7.071097e-01), QTCFLLDT(7.071038e-01),
+ QTCFLLDT(7.071099e-01), QTCFLLDT(-7.071036e-01), QTCFLLDT(-7.071100e-01),
+ QTCFLLDT(7.071034e-01), QTCFLLDT(7.071103e-01), QTCFLLDT(-7.071032e-01),
+ QTCFLLDT(-7.071105e-01), QTCFLLDT(7.071030e-01), QTCFLLDT(7.071106e-01),
+ QTCFLLDT(-7.071028e-01), QTCFLLDT(-7.071108e-01), QTCFLLDT(7.071027e-01),
+ QTCFLLDT(7.071110e-01), QTCFLLDT(-7.071025e-01), QTCFLLDT(-7.071112e-01),
+ QTCFLLDT(7.071023e-01), QTCFLLDT(7.071114e-01), QTCFLLDT(-7.071021e-01),
+ QTCFLLDT(-7.071115e-01), QTCFLLDT(7.071019e-01), QTCFLLDT(7.071117e-01),
+ QTCFLLDT(-7.071017e-01), QTCFLLDT(-7.071120e-01), QTCFLLDT(7.071015e-01),
+ QTCFLLDT(7.071121e-01), QTCFLLDT(-7.071013e-01), QTCFLLDT(-7.071123e-01),
+ QTCFLLDT(7.071012e-01), QTCFLLDT(7.071125e-01), QTCFLLDT(-7.071010e-01),
+ QTCFLLDT(-7.071127e-01),
+};
+
+//@}
+
+#endif /* #ifdef LOW_POWER_SBR_ONLY */
+
+/*!
+ \name QMF
+ \brief QMF-Table
+ 64 channels, N = 640, optimized by PE 010516
+
+ The coeffs are rearranged compared with the reference in the following
+ way:
+ sbr_qmf_64[0] = sbr_qmf_64_reference[0];
+ sbr_qmf_64[1] = sbr_qmf_64_reference[128];
+ sbr_qmf_64[2] = sbr_qmf_64_reference[256];
+ sbr_qmf_64[3] = sbr_qmf_64_reference[384];
+ sbr_qmf_64[4] = sbr_qmf_64_reference[512];
+
+ sbr_qmf_64[5] = sbr_qmf_64_reference[1];
+ sbr_qmf_64[6] = sbr_qmf_64_reference[129];
+ sbr_qmf_64[7] = sbr_qmf_64_reference[257];
+ sbr_qmf_64[8] = sbr_qmf_64_reference[385];
+ sbr_qmf_64[9] = sbr_qmf_64_reference[513];
+ .
+ .
+ .
+ sbr_qmf_64[635] = sbr_qmf_64_reference[127]
+ sbr_qmf_64[636] = sbr_qmf_64_reference[255];
+ sbr_qmf_64[637] = sbr_qmf_64_reference[383];
+ sbr_qmf_64[638] = sbr_qmf_64_reference[511];
+ sbr_qmf_64[639] = sbr_qmf_64_reference[639];
+
+
+ Symmetric properties of qmf coeffs:
+
+ Use point symmetry:
+
+ sbr_qmf_64_640_qmf[320..634] = p_64_640_qmf[314..0]
+
+ Max sum of all FIR filter absolute coefficients is: 0x7FF5B201
+ thus, the filter output is not required to be scaled.
+
+ \showinitializer
+*/
+//@{
+
+LNK_SECTION_CONSTDATA_L1
+RAM_ALIGN
+const FIXP_PFT qmf_cldfb_640[QMF640_CLDFB_PFT_TABLE_SIZE] = {
+ QTCFLLD(6.571760e-07), QTCFLLD(-8.010079e-06), QTCFLLD(-1.250743e-03),
+ QTCFLLD(8.996371e-03), QTCFLLD(5.128557e-01), QTCFLLD(4.118360e-07),
+ QTCFLLD(-1.469933e-05), QTCFLLD(-1.194743e-03), QTCFLLD(9.640299e-03),
+ QTCFLLD(5.299510e-01), QTCFLLD(8.109952e-07), QTCFLLD(4.840578e-06),
+ QTCFLLD(-1.151796e-03), QTCFLLD(1.033126e-02), QTCFLLD(5.470652e-01),
+ QTCFLLD(7.099633e-07), QTCFLLD(7.167101e-06), QTCFLLD(-1.099001e-03),
+ QTCFLLD(1.106959e-02), QTCFLLD(5.641523e-01), QTCFLLD(6.834210e-07),
+ QTCFLLD(1.088325e-05), QTCFLLD(-1.047655e-03), QTCFLLD(1.186211e-02),
+ QTCFLLD(5.811993e-01), QTCFLLD(4.292862e-07), QTCFLLD(1.013260e-05),
+ QTCFLLD(-9.862027e-04), QTCFLLD(1.270747e-02), QTCFLLD(5.981877e-01),
+ QTCFLLD(-5.426597e-09), QTCFLLD(5.869707e-06), QTCFLLD(-9.294665e-04),
+ QTCFLLD(1.361072e-02), QTCFLLD(6.151031e-01), QTCFLLD(6.355303e-08),
+ QTCFLLD(1.125135e-05), QTCFLLD(-9.767709e-04), QTCFLLD(1.456209e-02),
+ QTCFLLD(6.319284e-01), QTCFLLD(5.490570e-07), QTCFLLD(2.015445e-05),
+ QTCFLLD(-1.040598e-03), QTCFLLD(1.557759e-02), QTCFLLD(6.486438e-01),
+ QTCFLLD(1.620171e-06), QTCFLLD(2.800456e-05), QTCFLLD(-1.146268e-03),
+ QTCFLLD(1.665188e-02), QTCFLLD(6.652304e-01), QTCFLLD(-6.025110e-10),
+ QTCFLLD(8.975978e-06), QTCFLLD(-1.292866e-03), QTCFLLD(1.778249e-02),
+ QTCFLLD(6.816668e-01), QTCFLLD(-6.325664e-10), QTCFLLD(8.563820e-06),
+ QTCFLLD(-1.196638e-03), QTCFLLD(1.897506e-02), QTCFLLD(6.979337e-01),
+ QTCFLLD(-4.013525e-09), QTCFLLD(1.168895e-05), QTCFLLD(-9.726699e-04),
+ QTCFLLD(2.023525e-02), QTCFLLD(7.140087e-01), QTCFLLD(-4.244091e-09),
+ QTCFLLD(7.300589e-06), QTCFLLD(-8.029620e-04), QTCFLLD(2.156305e-02),
+ QTCFLLD(7.298746e-01), QTCFLLD(-1.846548e-08), QTCFLLD(3.965364e-06),
+ QTCFLLD(-6.754936e-04), QTCFLLD(2.296471e-02), QTCFLLD(7.455112e-01),
+ QTCFLLD(-3.870537e-09), QTCFLLD(1.374896e-06), QTCFLLD(-5.791145e-04),
+ QTCFLLD(2.443434e-02), QTCFLLD(7.609051e-01), QTCFLLD(-8.883499e-10),
+ QTCFLLD(3.798520e-07), QTCFLLD(-4.733148e-04), QTCFLLD(2.597957e-02),
+ QTCFLLD(7.760386e-01), QTCFLLD(5.303528e-08), QTCFLLD(4.469729e-06),
+ QTCFLLD(-2.998740e-04), QTCFLLD(2.760091e-02), QTCFLLD(7.908995e-01),
+ QTCFLLD(7.391974e-08), QTCFLLD(2.461877e-05), QTCFLLD(7.882620e-05),
+ QTCFLLD(2.931526e-02), QTCFLLD(8.054701e-01), QTCFLLD(1.723217e-09),
+ QTCFLLD(4.005269e-05), QTCFLLD(4.708010e-04), QTCFLLD(3.110861e-02),
+ QTCFLLD(8.197387e-01), QTCFLLD(2.443085e-07), QTCFLLD(5.272982e-05),
+ QTCFLLD(8.089812e-04), QTCFLLD(3.298151e-02), QTCFLLD(8.336864e-01),
+ QTCFLLD(1.387567e-08), QTCFLLD(4.939392e-05), QTCFLLD(1.127142e-03),
+ QTCFLLD(3.493300e-02), QTCFLLD(8.472987e-01), QTCFLLD(-5.690531e-06),
+ QTCFLLD(-4.256442e-05), QTCFLLD(1.417367e-03), QTCFLLD(3.696343e-02),
+ QTCFLLD(8.605543e-01), QTCFLLD(3.629067e-06), QTCFLLD(6.582328e-05),
+ QTCFLLD(1.725030e-03), QTCFLLD(3.907138e-02), QTCFLLD(8.734367e-01),
+ QTCFLLD(-5.393556e-08), QTCFLLD(6.481921e-05), QTCFLLD(1.948069e-03),
+ QTCFLLD(4.125570e-02), QTCFLLD(8.859232e-01), QTCFLLD(1.349944e-07),
+ QTCFLLD(3.367998e-05), QTCFLLD(2.033465e-03), QTCFLLD(4.355568e-02),
+ QTCFLLD(8.979959e-01), QTCFLLD(7.326611e-09), QTCFLLD(4.694252e-05),
+ QTCFLLD(2.239143e-03), QTCFLLD(4.599068e-02), QTCFLLD(9.096311e-01),
+ QTCFLLD(2.399696e-07), QTCFLLD(6.904415e-05), QTCFLLD(2.470456e-03),
+ QTCFLLD(4.849285e-02), QTCFLLD(9.208195e-01), QTCFLLD(3.330982e-07),
+ QTCFLLD(5.643103e-05), QTCFLLD(2.630472e-03), QTCFLLD(5.105621e-02),
+ QTCFLLD(9.315442e-01), QTCFLLD(4.767794e-07), QTCFLLD(7.095887e-05),
+ QTCFLLD(2.703019e-03), QTCFLLD(5.368313e-02), QTCFLLD(9.417976e-01),
+ QTCFLLD(3.428661e-07), QTCFLLD(7.872593e-05), QTCFLLD(2.729137e-03),
+ QTCFLLD(5.637219e-02), QTCFLLD(9.515675e-01), QTCFLLD(8.676848e-06),
+ QTCFLLD(2.666445e-04), QTCFLLD(2.719749e-03), QTCFLLD(5.911363e-02),
+ QTCFLLD(9.608520e-01), QTCFLLD(2.722296e-05), QTCFLLD(5.822201e-04),
+ QTCFLLD(2.530907e-03), QTCFLLD(6.192693e-02), QTCFLLD(9.696426e-01),
+ QTCFLLD(3.575651e-07), QTCFLLD(7.870355e-05), QTCFLLD(2.225524e-03),
+ QTCFLLD(6.480449e-02), QTCFLLD(9.779405e-01), QTCFLLD(6.293002e-07),
+ QTCFLLD(7.245096e-05), QTCFLLD(1.891972e-03), QTCFLLD(6.771675e-02),
+ QTCFLLD(9.857388e-01), QTCFLLD(1.070243e-06), QTCFLLD(7.194151e-05),
+ QTCFLLD(1.557112e-03), QTCFLLD(7.064948e-02), QTCFLLD(9.930380e-01),
+ QTCFLLD(-3.225913e-07), QTCFLLD(-7.679955e-05), QTCFLLD(1.194731e-03),
+ QTCFLLD(7.360559e-02), QTCFLLD(9.998286e-01), QTCFLLD(-9.597516e-09),
+ QTCFLLD(-6.093373e-05), QTCFLLD(6.415402e-04), QTCFLLD(7.657650e-02),
+ QTCFLLD(1.006109e+00), QTCFLLD(-8.908041e-08), QTCFLLD(-1.721347e-05),
+ QTCFLLD(1.092526e-04), QTCFLLD(7.955571e-02), QTCFLLD(1.011868e+00),
+ QTCFLLD(-2.285563e-05), QTCFLLD(-8.882305e-05), QTCFLLD(2.934876e-04),
+ QTCFLLD(8.251962e-02), QTCFLLD(1.017100e+00), QTCFLLD(1.013575e-05),
+ QTCFLLD(6.418658e-05), QTCFLLD(5.721223e-04), QTCFLLD(8.547716e-02),
+ QTCFLLD(1.021799e+00), QTCFLLD(-1.706941e-05), QTCFLLD(1.769262e-04),
+ QTCFLLD(6.976561e-04), QTCFLLD(8.841813e-02), QTCFLLD(1.025967e+00),
+ QTCFLLD(1.356728e-06), QTCFLLD(2.206341e-05), QTCFLLD(7.376101e-04),
+ QTCFLLD(9.133591e-02), QTCFLLD(1.029601e+00), QTCFLLD(-1.398913e-08),
+ QTCFLLD(-6.538879e-06), QTCFLLD(7.154124e-04), QTCFLLD(9.421624e-02),
+ QTCFLLD(1.032713e+00), QTCFLLD(3.552992e-08), QTCFLLD(-1.052707e-05),
+ QTCFLLD(7.139920e-04), QTCFLLD(9.705240e-02), QTCFLLD(1.035312e+00),
+ QTCFLLD(4.211177e-07), QTCFLLD(-9.075431e-06), QTCFLLD(6.944123e-04),
+ QTCFLLD(9.982958e-02), QTCFLLD(1.037422e+00), QTCFLLD(5.433719e-07),
+ QTCFLLD(-1.748285e-05), QTCFLLD(6.766320e-04), QTCFLLD(1.025398e-01),
+ QTCFLLD(1.039062e+00), QTCFLLD(8.226600e-08), QTCFLLD(-3.498286e-05),
+ QTCFLLD(6.887784e-04), QTCFLLD(1.051642e-01), QTCFLLD(1.040262e+00),
+ QTCFLLD(1.272705e-07), QTCFLLD(-4.489491e-05), QTCFLLD(6.673250e-04),
+ QTCFLLD(1.076972e-01), QTCFLLD(1.041043e+00), QTCFLLD(2.542598e-07),
+ QTCFLLD(-5.449816e-05), QTCFLLD(5.970697e-04), QTCFLLD(1.101216e-01),
+ QTCFLLD(1.041434e+00), QTCFLLD(6.322770e-07), QTCFLLD(-5.874199e-05),
+ QTCFLLD(4.749931e-04), QTCFLLD(1.124296e-01), QTCFLLD(1.041443e+00),
+ QTCFLLD(2.801882e-08), QTCFLLD(-7.934510e-05), QTCFLLD(3.189336e-04),
+ QTCFLLD(1.146042e-01), QTCFLLD(1.041087e+00), QTCFLLD(5.891904e-07),
+ QTCFLLD(-8.039232e-05), QTCFLLD(1.218226e-04), QTCFLLD(1.166399e-01),
+ QTCFLLD(1.040350e+00), QTCFLLD(7.301957e-07), QTCFLLD(-9.907631e-05),
+ QTCFLLD(-1.324292e-04), QTCFLLD(1.185243e-01), QTCFLLD(1.039228e+00),
+ QTCFLLD(-4.518603e-06), QTCFLLD(-2.217025e-04), QTCFLLD(-4.268575e-04),
+ QTCFLLD(1.202546e-01), QTCFLLD(1.037683e+00), QTCFLLD(-3.561585e-06),
+ QTCFLLD(-2.415166e-04), QTCFLLD(-7.804546e-04), QTCFLLD(1.218184e-01),
+ QTCFLLD(1.035694e+00), QTCFLLD(-1.074717e-07), QTCFLLD(-2.123672e-04),
+ QTCFLLD(-1.156680e-03), QTCFLLD(1.232132e-01), QTCFLLD(1.033206e+00),
+ QTCFLLD(1.323268e-06), QTCFLLD(-2.078299e-04), QTCFLLD(-1.525819e-03),
+ QTCFLLD(1.244270e-01), QTCFLLD(1.030199e+00), QTCFLLD(3.377815e-06),
+ QTCFLLD(-1.885286e-04), QTCFLLD(-1.914115e-03), QTCFLLD(1.254605e-01),
+ QTCFLLD(1.026616e+00), QTCFLLD(5.161607e-06), QTCFLLD(-1.728673e-04),
+ QTCFLLD(-2.292814e-03), QTCFLLD(1.262996e-01), QTCFLLD(1.022470e+00),
+ QTCFLLD(5.924001e-06), QTCFLLD(-1.744842e-04), QTCFLLD(-2.658042e-03),
+ QTCFLLD(1.269416e-01), QTCFLLD(1.017729e+00), QTCFLLD(6.310208e-06),
+ QTCFLLD(-1.784193e-04), QTCFLLD(-3.000423e-03), QTCFLLD(1.273648e-01),
+ QTCFLLD(1.012508e+00), QTCFLLD(3.357219e-06), QTCFLLD(-2.131406e-04),
+ QTCFLLD(-3.318858e-03), QTCFLLD(1.275561e-01), QTCFLLD(1.006893e+00),
+ QTCFLLD(5.189087e-06), QTCFLLD(-2.078886e-04), QTCFLLD(-3.597476e-03),
+ QTCFLLD(1.274568e-01), QTCFLLD(1.001463e+00), QTCFLLD(4.178050e-06),
+ QTCFLLD(-4.663778e-05), QTCFLLD(-3.870852e-03), QTCFLLD(1.273591e-01),
+ QTCFLLD(9.927544e-01), QTCFLLD(5.364807e-06), QTCFLLD(-5.889277e-06),
+ QTCFLLD(-4.135130e-03), QTCFLLD(1.272499e-01), QTCFLLD(9.807692e-01),
+ QTCFLLD(4.083719e-06), QTCFLLD(-1.774108e-05), QTCFLLD(-4.351668e-03),
+ QTCFLLD(1.268281e-01), QTCFLLD(9.690017e-01), QTCFLLD(3.567581e-06),
+ QTCFLLD(-2.599468e-08), QTCFLLD(-4.517190e-03), QTCFLLD(1.261262e-01),
+ QTCFLLD(9.568886e-01), QTCFLLD(3.262754e-06), QTCFLLD(1.260640e-05),
+ QTCFLLD(-4.636228e-03), QTCFLLD(1.251477e-01), QTCFLLD(9.443803e-01),
+ QTCFLLD(2.041128e-06), QTCFLLD(2.364519e-05), QTCFLLD(-4.704321e-03),
+ QTCFLLD(1.238869e-01), QTCFLLD(9.313874e-01), QTCFLLD(-2.567965e-08),
+ QTCFLLD(2.806963e-05), QTCFLLD(-4.722568e-03), QTCFLLD(1.223371e-01),
+ QTCFLLD(9.179666e-01), QTCFLLD(2.714879e-07), QTCFLLD(4.493916e-05),
+ QTCFLLD(-4.663276e-03), QTCFLLD(1.204854e-01), QTCFLLD(9.041286e-01),
+ QTCFLLD(2.150884e-06), QTCFLLD(5.408155e-05), QTCFLLD(-4.554811e-03),
+ QTCFLLD(1.183233e-01), QTCFLLD(8.899474e-01), QTCFLLD(5.818595e-06),
+ QTCFLLD(3.759630e-05), QTCFLLD(-4.369554e-03), QTCFLLD(1.158359e-01),
+ QTCFLLD(8.754641e-01), QTCFLLD(-1.686137e-09), QTCFLLD(2.515118e-05),
+ QTCFLLD(-4.091033e-03), QTCFLLD(1.130180e-01), QTCFLLD(8.607492e-01),
+ QTCFLLD(-1.775191e-09), QTCFLLD(2.406517e-05), QTCFLLD(-3.794425e-03),
+ QTCFLLD(1.098551e-01), QTCFLLD(8.458450e-01), QTCFLLD(-2.222072e-09),
+ QTCFLLD(3.628511e-05), QTCFLLD(-3.460363e-03), QTCFLLD(1.063455e-01),
+ QTCFLLD(8.308040e-01), QTCFLLD(-1.280675e-08), QTCFLLD(2.241546e-05),
+ QTCFLLD(-3.064311e-03), QTCFLLD(1.024805e-01), QTCFLLD(8.156523e-01),
+ QTCFLLD(-6.977078e-08), QTCFLLD(1.499170e-05), QTCFLLD(-2.621537e-03),
+ QTCFLLD(9.826251e-02), QTCFLLD(8.004165e-01), QTCFLLD(-1.409927e-08),
+ QTCFLLD(5.009913e-06), QTCFLLD(-2.124648e-03), QTCFLLD(9.368652e-02),
+ QTCFLLD(7.851012e-01), QTCFLLD(-2.986489e-09), QTCFLLD(1.277184e-06),
+ QTCFLLD(-1.594861e-03), QTCFLLD(8.875756e-02), QTCFLLD(7.697093e-01),
+ QTCFLLD(1.876022e-07), QTCFLLD(1.580189e-05), QTCFLLD(-1.061499e-03),
+ QTCFLLD(8.347151e-02), QTCFLLD(7.542294e-01), QTCFLLD(1.737277e-07),
+ QTCFLLD(5.533953e-05), QTCFLLD(-6.169855e-04), QTCFLLD(7.783300e-02),
+ QTCFLLD(7.386515e-01), QTCFLLD(3.818589e-09), QTCFLLD(8.870182e-05),
+ QTCFLLD(-2.004823e-04), QTCFLLD(7.184074e-02), QTCFLLD(7.229599e-01),
+ QTCFLLD(5.143615e-07), QTCFLLD(1.035783e-04), QTCFLLD(2.048499e-04),
+ QTCFLLD(6.550209e-02), QTCFLLD(7.071448e-01), QTCFLLD(2.820292e-08),
+ QTCFLLD(9.990758e-05), QTCFLLD(5.621721e-04), QTCFLLD(5.881297e-02),
+ QTCFLLD(6.911982e-01), QTCFLLD(4.677016e-06), QTCFLLD(1.181078e-04),
+ QTCFLLD(9.373975e-04), QTCFLLD(5.177965e-02), QTCFLLD(6.751199e-01),
+ QTCFLLD(3.361682e-06), QTCFLLD(2.126365e-05), QTCFLLD(1.344657e-03),
+ QTCFLLD(4.439684e-02), QTCFLLD(6.589149e-01), QTCFLLD(-4.880845e-08),
+ QTCFLLD(5.861800e-05), QTCFLLD(1.812176e-03), QTCFLLD(3.666943e-02),
+ QTCFLLD(6.425940e-01), QTCFLLD(2.267731e-07), QTCFLLD(5.021906e-05),
+ QTCFLLD(2.172866e-03), QTCFLLD(2.857528e-02), QTCFLLD(6.261725e-01),
+ QTCFLLD(5.158213e-09), QTCFLLD(4.150075e-05), QTCFLLD(1.985825e-03),
+ QTCFLLD(2.012237e-02), QTCFLLD(6.096690e-01), QTCFLLD(-2.066962e-07),
+ QTCFLLD(3.799972e-05), QTCFLLD(1.697653e-03), QTCFLLD(1.132324e-02),
+ QTCFLLD(5.930982e-01), QTCFLLD(4.883305e-07), QTCFLLD(6.606462e-05),
+ QTCFLLD(1.471167e-03), QTCFLLD(2.184257e-03), QTCFLLD(5.764735e-01),
+ QTCFLLD(8.254430e-07), QTCFLLD(9.755685e-05), QTCFLLD(1.232134e-03),
+ QTCFLLD(-7.298198e-03), QTCFLLD(5.598052e-01), QTCFLLD(9.464783e-07),
+ QTCFLLD(1.831121e-04), QTCFLLD(8.990256e-04), QTCFLLD(-1.711324e-02),
+ QTCFLLD(5.430990e-01), QTCFLLD(-1.232693e-05), QTCFLLD(-5.901618e-07),
+ QTCFLLD(6.150317e-04), QTCFLLD(-2.726484e-02), QTCFLLD(5.263554e-01),
+ QTCFLLD(3.867483e-05), QTCFLLD(-3.595054e-04), QTCFLLD(6.307841e-04),
+ QTCFLLD(-3.775928e-02), QTCFLLD(5.095721e-01), QTCFLLD(-9.870548e-07),
+ QTCFLLD(-1.815837e-04), QTCFLLD(4.366447e-04), QTCFLLD(-4.859006e-02),
+ QTCFLLD(4.927464e-01), QTCFLLD(-1.089501e-06), QTCFLLD(-9.204876e-05),
+ QTCFLLD(1.498232e-04), QTCFLLD(-5.973742e-02), QTCFLLD(4.758754e-01),
+ QTCFLLD(-1.569003e-06), QTCFLLD(-5.192444e-05), QTCFLLD(-9.099723e-05),
+ QTCFLLD(-7.120357e-02), QTCFLLD(4.589583e-01), QTCFLLD(-2.778618e-07),
+ QTCFLLD(6.487880e-05), QTCFLLD(-3.337967e-04), QTCFLLD(-8.298103e-02),
+ QTCFLLD(4.420014e-01), QTCFLLD(6.757015e-09), QTCFLLD(5.397065e-05),
+ QTCFLLD(-5.599348e-04), QTCFLLD(-9.506967e-02), QTCFLLD(4.250144e-01),
+ QTCFLLD(1.496436e-07), QTCFLLD(2.472024e-05), QTCFLLD(-7.677634e-04),
+ QTCFLLD(-1.074631e-01), QTCFLLD(4.080155e-01), QTCFLLD(2.068297e-05),
+ QTCFLLD(9.711682e-05), QTCFLLD(-9.730460e-04), QTCFLLD(-1.201629e-01),
+ QTCFLLD(3.910244e-01), QTCFLLD(-9.388963e-06), QTCFLLD(5.144969e-05),
+ QTCFLLD(-1.131860e-03), QTCFLLD(-1.331545e-01), QTCFLLD(3.740644e-01),
+ QTCFLLD(-1.402925e-05), QTCFLLD(-1.039264e-04), QTCFLLD(-1.283281e-03),
+ QTCFLLD(-1.464389e-01), QTCFLLD(3.571528e-01), QTCFLLD(-2.757611e-06),
+ QTCFLLD(2.853437e-06), QTCFLLD(-1.480543e-03), QTCFLLD(-1.600062e-01),
+ QTCFLLD(3.403074e-01), QTCFLLD(2.945239e-08), QTCFLLD(1.334091e-05),
+ QTCFLLD(-1.699161e-03), QTCFLLD(-1.738542e-01), QTCFLLD(3.235299e-01),
+ QTCFLLD(-7.873304e-08), QTCFLLD(2.443161e-05), QTCFLLD(-1.924845e-03),
+ QTCFLLD(-1.879712e-01), QTCFLLD(3.068187e-01), QTCFLLD(-9.897194e-07),
+ QTCFLLD(3.568555e-05), QTCFLLD(-2.152380e-03), QTCFLLD(-2.023548e-01),
+ QTCFLLD(2.901491e-01), QTCFLLD(-1.922074e-06), QTCFLLD(6.193370e-05),
+ QTCFLLD(-2.396404e-03), QTCFLLD(-2.169926e-01), QTCFLLD(2.734977e-01),
+ QTCFLLD(-2.765650e-07), QTCFLLD(1.176237e-04), QTCFLLD(-2.653819e-03),
+ QTCFLLD(-2.318815e-01), QTCFLLD(2.568176e-01), QTCFLLD(-4.636105e-07),
+ QTCFLLD(1.635906e-04), QTCFLLD(-2.927159e-03), QTCFLLD(-2.470098e-01),
+ QTCFLLD(2.400768e-01), QTCFLLD(-9.607069e-07), QTCFLLD(2.060394e-04),
+ QTCFLLD(-3.209093e-03), QTCFLLD(-2.623749e-01), QTCFLLD(2.232277e-01),
+ QTCFLLD(-1.907927e-06), QTCFLLD(2.346981e-04), QTCFLLD(-3.505531e-03),
+ QTCFLLD(-2.779638e-01), QTCFLLD(2.062605e-01), QTCFLLD(-1.551251e-08),
+ QTCFLLD(2.520607e-04), QTCFLLD(-3.811612e-03), QTCFLLD(-2.937725e-01),
+ QTCFLLD(1.891590e-01), QTCFLLD(-1.653464e-06), QTCFLLD(2.556450e-04),
+ QTCFLLD(-4.133640e-03), QTCFLLD(-3.097862e-01), QTCFLLD(1.719726e-01),
+ QTCFLLD(-2.043464e-06), QTCFLLD(3.157664e-04), QTCFLLD(-4.448993e-03),
+ QTCFLLD(-3.259994e-01), QTCFLLD(1.547461e-01), QTCFLLD(1.622786e-05),
+ QTCFLLD(6.205676e-04), QTCFLLD(-4.754192e-03), QTCFLLD(-3.423942e-01),
+ QTCFLLD(1.376150e-01), QTCFLLD(1.395221e-05), QTCFLLD(7.847840e-04),
+ QTCFLLD(-5.063851e-03), QTCFLLD(-3.589627e-01), QTCFLLD(1.206924e-01),
+ QTCFLLD(4.591010e-07), QTCFLLD(9.019129e-04), QTCFLLD(-5.394570e-03),
+ QTCFLLD(-3.756822e-01), QTCFLLD(1.042033e-01), QTCFLLD(-6.261944e-06),
+ QTCFLLD(1.054963e-03), QTCFLLD(-5.741103e-03), QTCFLLD(-3.925409e-01),
+ QTCFLLD(8.829745e-02), QTCFLLD(-1.606051e-05), QTCFLLD(1.089429e-03),
+ QTCFLLD(-6.109179e-03), QTCFLLD(-4.095160e-01), QTCFLLD(7.325979e-02),
+ QTCFLLD(-2.464228e-05), QTCFLLD(1.122503e-03), QTCFLLD(-6.500503e-03),
+ QTCFLLD(-4.265950e-01), QTCFLLD(5.918678e-02), QTCFLLD(-2.976824e-05),
+ QTCFLLD(1.177515e-03), QTCFLLD(-6.925141e-03), QTCFLLD(-4.437530e-01),
+ QTCFLLD(4.634696e-02), QTCFLLD(-3.177468e-05), QTCFLLD(1.226113e-03),
+ QTCFLLD(-7.380544e-03), QTCFLLD(-4.609829e-01), QTCFLLD(3.450719e-02),
+ QTCFLLD(-4.373302e-05), QTCFLLD(1.263569e-03), QTCFLLD(-7.876393e-03),
+ QTCFLLD(-4.782650e-01), QTCFLLD(2.353060e-02), QTCFLLD(-3.299004e-05),
+ QTCFLLD(1.287819e-03), QTCFLLD(-8.407749e-03), QTCFLLD(-4.956175e-01),
+ QTCFLLD(1.129580e-02),
+};
+
+RAM_ALIGN
+const FIXP_PFT qmf_cldfb_320[QMF320_CLDFB_PFT_TABLE_SIZE] = {
+ QTCFLLD(5.345060e-07), QTCFLLD(-1.135471e-05), QTCFLLD(-1.222743e-03),
+ QTCFLLD(9.318335e-03), QTCFLLD(5.214033e-01), QTCFLLD(7.604792e-07),
+ QTCFLLD(6.003839e-06), QTCFLLD(-1.125398e-03), QTCFLLD(1.070043e-02),
+ QTCFLLD(5.556087e-01), QTCFLLD(5.563536e-07), QTCFLLD(1.050792e-05),
+ QTCFLLD(-1.016929e-03), QTCFLLD(1.228479e-02), QTCFLLD(5.896935e-01),
+ QTCFLLD(2.906322e-08), QTCFLLD(8.560527e-06), QTCFLLD(-9.531187e-04),
+ QTCFLLD(1.408640e-02), QTCFLLD(6.235157e-01), QTCFLLD(1.084614e-06),
+ QTCFLLD(2.407951e-05), QTCFLLD(-1.093433e-03), QTCFLLD(1.611474e-02),
+ QTCFLLD(6.569371e-01), QTCFLLD(-6.175387e-10), QTCFLLD(8.769899e-06),
+ QTCFLLD(-1.244752e-03), QTCFLLD(1.837877e-02), QTCFLLD(6.898003e-01),
+ QTCFLLD(-4.128808e-09), QTCFLLD(9.494767e-06), QTCFLLD(-8.878160e-04),
+ QTCFLLD(2.089915e-02), QTCFLLD(7.219416e-01), QTCFLLD(-1.116801e-08),
+ QTCFLLD(2.670130e-06), QTCFLLD(-6.273041e-04), QTCFLLD(2.369952e-02),
+ QTCFLLD(7.532082e-01), QTCFLLD(2.607347e-08), QTCFLLD(2.424790e-06),
+ QTCFLLD(-3.865944e-04), QTCFLLD(2.679024e-02), QTCFLLD(7.834691e-01),
+ QTCFLLD(3.782148e-08), QTCFLLD(3.233573e-05), QTCFLLD(2.748136e-04),
+ QTCFLLD(3.021193e-02), QTCFLLD(8.126044e-01), QTCFLLD(1.290921e-07),
+ QTCFLLD(5.106187e-05), QTCFLLD(9.680615e-04), QTCFLLD(3.395726e-02),
+ QTCFLLD(8.404925e-01), QTCFLLD(-1.030732e-06), QTCFLLD(1.162943e-05),
+ QTCFLLD(1.571198e-03), QTCFLLD(3.801740e-02), QTCFLLD(8.669955e-01),
+ QTCFLLD(4.052940e-08), QTCFLLD(4.924960e-05), QTCFLLD(1.990767e-03),
+ QTCFLLD(4.240569e-02), QTCFLLD(8.919595e-01), QTCFLLD(1.236481e-07),
+ QTCFLLD(5.799333e-05), QTCFLLD(2.354800e-03), QTCFLLD(4.724177e-02),
+ QTCFLLD(9.152253e-01), QTCFLLD(4.049388e-07), QTCFLLD(6.369496e-05),
+ QTCFLLD(2.666746e-03), QTCFLLD(5.236967e-02), QTCFLLD(9.366709e-01),
+ QTCFLLD(4.509857e-06), QTCFLLD(1.726852e-04), QTCFLLD(2.724443e-03),
+ QTCFLLD(5.774291e-02), QTCFLLD(9.562097e-01), QTCFLLD(1.379026e-05),
+ QTCFLLD(3.304619e-04), QTCFLLD(2.378216e-03), QTCFLLD(6.336571e-02),
+ QTCFLLD(9.737916e-01), QTCFLLD(8.497715e-07), QTCFLLD(7.219624e-05),
+ QTCFLLD(1.724542e-03), QTCFLLD(6.918311e-02), QTCFLLD(9.893883e-01),
+ QTCFLLD(-1.660944e-07), QTCFLLD(-6.886664e-05), QTCFLLD(9.181354e-04),
+ QTCFLLD(7.509105e-02), QTCFLLD(1.002969e+00), QTCFLLD(-1.147235e-05),
+ QTCFLLD(-5.301826e-05), QTCFLLD(2.013701e-04), QTCFLLD(8.103766e-02),
+ QTCFLLD(1.014484e+00), QTCFLLD(-3.466829e-06), QTCFLLD(1.205564e-04),
+ QTCFLLD(6.348892e-04), QTCFLLD(8.694765e-02), QTCFLLD(1.023883e+00),
+ QTCFLLD(6.713692e-07), QTCFLLD(7.762268e-06), QTCFLLD(7.265112e-04),
+ QTCFLLD(9.277608e-02), QTCFLLD(1.031157e+00), QTCFLLD(2.283238e-07),
+ QTCFLLD(-9.801253e-06), QTCFLLD(7.042022e-04), QTCFLLD(9.844099e-02),
+ QTCFLLD(1.036367e+00), QTCFLLD(3.128189e-07), QTCFLLD(-2.623285e-05),
+ QTCFLLD(6.827052e-04), QTCFLLD(1.038520e-01), QTCFLLD(1.039662e+00),
+ QTCFLLD(1.907652e-07), QTCFLLD(-4.969654e-05), QTCFLLD(6.321974e-04),
+ QTCFLLD(1.089094e-01), QTCFLLD(1.041239e+00), QTCFLLD(3.301479e-07),
+ QTCFLLD(-6.904354e-05), QTCFLLD(3.969634e-04), QTCFLLD(1.135169e-01),
+ QTCFLLD(1.041265e+00), QTCFLLD(6.596931e-07), QTCFLLD(-8.973431e-05),
+ QTCFLLD(-5.303260e-06), QTCFLLD(1.175821e-01), QTCFLLD(1.039789e+00),
+ QTCFLLD(-4.040094e-06), QTCFLLD(-2.316096e-04), QTCFLLD(-6.036561e-04),
+ QTCFLLD(1.210365e-01), QTCFLLD(1.036689e+00), QTCFLLD(6.078980e-07),
+ QTCFLLD(-2.100985e-04), QTCFLLD(-1.341249e-03), QTCFLLD(1.238201e-01),
+ QTCFLLD(1.031702e+00), QTCFLLD(4.269711e-06), QTCFLLD(-1.806979e-04),
+ QTCFLLD(-2.103464e-03), QTCFLLD(1.258800e-01), QTCFLLD(1.024543e+00),
+ QTCFLLD(6.117105e-06), QTCFLLD(-1.764517e-04), QTCFLLD(-2.829232e-03),
+ QTCFLLD(1.271532e-01), QTCFLLD(1.015119e+00), QTCFLLD(4.273153e-06),
+ QTCFLLD(-2.105146e-04), QTCFLLD(-3.458167e-03), QTCFLLD(1.275064e-01),
+ QTCFLLD(1.004178e+00), QTCFLLD(4.771428e-06), QTCFLLD(-2.626353e-05),
+ QTCFLLD(-4.002991e-03), QTCFLLD(1.273045e-01), QTCFLLD(9.867618e-01),
+ QTCFLLD(3.825650e-06), QTCFLLD(-8.883540e-06), QTCFLLD(-4.434429e-03),
+ QTCFLLD(1.264771e-01), QTCFLLD(9.629451e-01), QTCFLLD(2.651941e-06),
+ QTCFLLD(1.812579e-05), QTCFLLD(-4.670274e-03), QTCFLLD(1.245173e-01),
+ QTCFLLD(9.378839e-01), QTCFLLD(1.229041e-07), QTCFLLD(3.650440e-05),
+ QTCFLLD(-4.692922e-03), QTCFLLD(1.214113e-01), QTCFLLD(9.110476e-01),
+ QTCFLLD(3.984739e-06), QTCFLLD(4.583892e-05), QTCFLLD(-4.462183e-03),
+ QTCFLLD(1.170796e-01), QTCFLLD(8.827057e-01), QTCFLLD(-1.730664e-09),
+ QTCFLLD(2.460818e-05), QTCFLLD(-3.942729e-03), QTCFLLD(1.114366e-01),
+ QTCFLLD(8.532971e-01), QTCFLLD(-7.514413e-09), QTCFLLD(2.935029e-05),
+ QTCFLLD(-3.262337e-03), QTCFLLD(1.044130e-01), QTCFLLD(8.232281e-01),
+ QTCFLLD(-4.193503e-08), QTCFLLD(1.000081e-05), QTCFLLD(-2.373092e-03),
+ QTCFLLD(9.597452e-02), QTCFLLD(7.927589e-01), QTCFLLD(9.230786e-08),
+ QTCFLLD(8.539538e-06), QTCFLLD(-1.328180e-03), QTCFLLD(8.611453e-02),
+ QTCFLLD(7.619694e-01), QTCFLLD(8.877312e-08), QTCFLLD(7.202067e-05),
+ QTCFLLD(-4.087339e-04), QTCFLLD(7.483687e-02), QTCFLLD(7.308058e-01),
+ QTCFLLD(2.712822e-07), QTCFLLD(1.017429e-04), QTCFLLD(3.835110e-04),
+ QTCFLLD(6.215753e-02), QTCFLLD(6.991715e-01), QTCFLLD(4.019349e-06),
+ QTCFLLD(6.968570e-05), QTCFLLD(1.141027e-03), QTCFLLD(4.808825e-02),
+ QTCFLLD(6.670174e-01), QTCFLLD(8.898233e-08), QTCFLLD(5.441853e-05),
+ QTCFLLD(1.992521e-03), QTCFLLD(3.262236e-02), QTCFLLD(6.343833e-01),
+ QTCFLLD(-1.007690e-07), QTCFLLD(3.975024e-05), QTCFLLD(1.841739e-03),
+ QTCFLLD(1.572281e-02), QTCFLLD(6.013836e-01), QTCFLLD(6.568868e-07),
+ QTCFLLD(8.181074e-05), QTCFLLD(1.351651e-03), QTCFLLD(-2.556970e-03),
+ QTCFLLD(5.681393e-01), QTCFLLD(-5.690228e-06), QTCFLLD(9.126098e-05),
+ QTCFLLD(7.570286e-04), QTCFLLD(-2.218904e-02), QTCFLLD(5.347272e-01),
+ QTCFLLD(1.884389e-05), QTCFLLD(-2.705446e-04), QTCFLLD(5.337144e-04),
+ QTCFLLD(-4.317467e-02), QTCFLLD(5.011593e-01), QTCFLLD(-1.329252e-06),
+ QTCFLLD(-7.198660e-05), QTCFLLD(2.941296e-05), QTCFLLD(-6.547049e-02),
+ QTCFLLD(4.674168e-01), QTCFLLD(-1.355524e-07), QTCFLLD(5.942472e-05),
+ QTCFLLD(-4.468657e-04), QTCFLLD(-8.902535e-02), QTCFLLD(4.335079e-01),
+ QTCFLLD(1.041631e-05), QTCFLLD(6.091853e-05), QTCFLLD(-8.704047e-04),
+ QTCFLLD(-1.138130e-01), QTCFLLD(3.995200e-01), QTCFLLD(-1.170911e-05),
+ QTCFLLD(-2.623833e-05), QTCFLLD(-1.207570e-03), QTCFLLD(-1.397967e-01),
+ QTCFLLD(3.656086e-01), QTCFLLD(-1.364079e-06), QTCFLLD(8.097173e-06),
+ QTCFLLD(-1.589852e-03), QTCFLLD(-1.669302e-01), QTCFLLD(3.319187e-01),
+ QTCFLLD(-5.342262e-07), QTCFLLD(3.005858e-05), QTCFLLD(-2.038612e-03),
+ QTCFLLD(-1.951630e-01), QTCFLLD(2.984839e-01), QTCFLLD(-1.099320e-06),
+ QTCFLLD(8.977871e-05), QTCFLLD(-2.525111e-03), QTCFLLD(-2.244371e-01),
+ QTCFLLD(2.651577e-01), QTCFLLD(-7.121587e-07), QTCFLLD(1.848150e-04),
+ QTCFLLD(-3.068126e-03), QTCFLLD(-2.546924e-01), QTCFLLD(2.316523e-01),
+ QTCFLLD(-9.617199e-07), QTCFLLD(2.433794e-04), QTCFLLD(-3.658572e-03),
+ QTCFLLD(-2.858681e-01), QTCFLLD(1.977098e-01), QTCFLLD(-1.848464e-06),
+ QTCFLLD(2.857057e-04), QTCFLLD(-4.291316e-03), QTCFLLD(-3.178928e-01),
+ QTCFLLD(1.633594e-01), QTCFLLD(1.509004e-05), QTCFLLD(7.026758e-04),
+ QTCFLLD(-4.909021e-03), QTCFLLD(-3.506784e-01), QTCFLLD(1.291537e-01),
+ QTCFLLD(-2.901422e-06), QTCFLLD(9.784381e-04), QTCFLLD(-5.567837e-03),
+ QTCFLLD(-3.841116e-01), QTCFLLD(9.625038e-02), QTCFLLD(-2.035140e-05),
+ QTCFLLD(1.105966e-03), QTCFLLD(-6.304841e-03), QTCFLLD(-4.180555e-01),
+ QTCFLLD(6.622328e-02), QTCFLLD(-3.077146e-05), QTCFLLD(1.201814e-03),
+ QTCFLLD(-7.152842e-03), QTCFLLD(-4.523680e-01), QTCFLLD(4.042707e-02),
+ QTCFLLD(-3.836153e-05), QTCFLLD(1.275694e-03), QTCFLLD(-8.142071e-03),
+ QTCFLLD(-4.869413e-01), QTCFLLD(1.741320e-02),
+};
+
+RAM_ALIGN
+const FIXP_PFT qmf_cldfb_160[QMF160_CLDFB_PFT_TABLE_SIZE] = {
+ QTCFLLD(6.114156e-07), QTCFLLD(-4.929378e-06), QTCFLLD(-1.173270e-03),
+ QTCFLLD(9.985781e-03), QTCFLLD(5.385081e-01), QTCFLLD(2.119298e-07),
+ QTCFLLD(8.001152e-06), QTCFLLD(-9.578346e-04), QTCFLLD(1.315910e-02),
+ QTCFLLD(6.066454e-01), QTCFLLD(8.097845e-07), QTCFLLD(1.849027e-05),
+ QTCFLLD(-1.219567e-03), QTCFLLD(1.721718e-02), QTCFLLD(6.734486e-01),
+ QTCFLLD(-1.135478e-08), QTCFLLD(5.632976e-06), QTCFLLD(-7.392278e-04),
+ QTCFLLD(2.226388e-02), QTCFLLD(7.376929e-01), QTCFLLD(6.347751e-08),
+ QTCFLLD(1.454425e-05), QTCFLLD(-1.105239e-04), QTCFLLD(2.845808e-02),
+ QTCFLLD(7.981848e-01), QTCFLLD(-2.838328e-06), QTCFLLD(3.414749e-06),
+ QTCFLLD(1.272254e-03), QTCFLLD(3.594821e-02), QTCFLLD(8.539265e-01),
+ QTCFLLD(7.116049e-08), QTCFLLD(4.031125e-05), QTCFLLD(2.136304e-03),
+ QTCFLLD(4.477318e-02), QTCFLLD(9.038135e-01), QTCFLLD(4.098227e-07),
+ QTCFLLD(7.484240e-05), QTCFLLD(2.716078e-03), QTCFLLD(5.502766e-02),
+ QTCFLLD(9.466825e-01), QTCFLLD(4.934327e-07), QTCFLLD(7.557725e-05),
+ QTCFLLD(2.058748e-03), QTCFLLD(6.626062e-02), QTCFLLD(9.818396e-01),
+ QTCFLLD(-4.933896e-08), QTCFLLD(-3.907360e-05), QTCFLLD(3.753964e-04),
+ QTCFLLD(7.806610e-02), QTCFLLD(1.008988e+00), QTCFLLD(-7.856341e-06),
+ QTCFLLD(9.949480e-05), QTCFLLD(7.176331e-04), QTCFLLD(8.987702e-02),
+ QTCFLLD(1.027784e+00), QTCFLLD(4.822448e-07), QTCFLLD(-1.327914e-05),
+ QTCFLLD(6.855222e-04), QTCFLLD(1.011847e-01), QTCFLLD(1.038242e+00),
+ QTCFLLD(4.432684e-07), QTCFLLD(-5.662008e-05), QTCFLLD(5.360314e-04),
+ QTCFLLD(1.112756e-01), QTCFLLD(1.041439e+00), QTCFLLD(-1.894204e-06),
+ QTCFLLD(-1.603894e-04), QTCFLLD(-2.796433e-04), QTCFLLD(1.193894e-01),
+ QTCFLLD(1.038456e+00), QTCFLLD(2.350541e-06), QTCFLLD(-1.981793e-04),
+ QTCFLLD(-1.719967e-03), QTCFLLD(1.249437e-01), QTCFLLD(1.028407e+00),
+ QTCFLLD(4.833713e-06), QTCFLLD(-1.957799e-04), QTCFLLD(-3.159640e-03),
+ QTCFLLD(1.274605e-01), QTCFLLD(1.009701e+00), QTCFLLD(4.724263e-06),
+ QTCFLLD(-1.181518e-05), QTCFLLD(-4.243399e-03), QTCFLLD(1.270390e-01),
+ QTCFLLD(9.748854e-01), QTCFLLD(1.007724e-06), QTCFLLD(2.585741e-05),
+ QTCFLLD(-4.713445e-03), QTCFLLD(1.231120e-01), QTCFLLD(9.246770e-01),
+ QTCFLLD(2.908454e-06), QTCFLLD(3.137374e-05), QTCFLLD(-4.230293e-03),
+ QTCFLLD(1.144269e-01), QTCFLLD(8.681067e-01), QTCFLLD(-4.128877e-08),
+ QTCFLLD(1.870358e-05), QTCFLLD(-2.842924e-03), QTCFLLD(1.003715e-01),
+ QTCFLLD(8.080344e-01), QTCFLLD(1.806649e-07), QTCFLLD(3.557071e-05),
+ QTCFLLD(-8.392422e-04), QTCFLLD(8.065225e-02), QTCFLLD(7.464405e-01),
+ QTCFLLD(2.352609e-06), QTCFLLD(1.090077e-04), QTCFLLD(7.497848e-04),
+ QTCFLLD(5.529631e-02), QTCFLLD(6.831591e-01), QTCFLLD(1.159657e-07),
+ QTCFLLD(4.585990e-05), QTCFLLD(2.079346e-03), QTCFLLD(2.434883e-02),
+ QTCFLLD(6.179208e-01), QTCFLLD(8.859606e-07), QTCFLLD(1.403345e-04),
+ QTCFLLD(1.065580e-03), QTCFLLD(-1.220572e-02), QTCFLLD(5.514521e-01),
+ QTCFLLD(-1.038278e-06), QTCFLLD(-1.368162e-04), QTCFLLD(2.932339e-04),
+ QTCFLLD(-5.416374e-02), QTCFLLD(4.843109e-01), QTCFLLD(7.820030e-08),
+ QTCFLLD(3.934544e-05), QTCFLLD(-6.638491e-04), QTCFLLD(-1.012664e-01),
+ QTCFLLD(4.165150e-01), QTCFLLD(-8.393432e-06), QTCFLLD(-5.053646e-05),
+ QTCFLLD(-1.381912e-03), QTCFLLD(-1.532225e-01), QTCFLLD(3.487301e-01),
+ QTCFLLD(-1.455897e-06), QTCFLLD(4.880962e-05), QTCFLLD(-2.274392e-03),
+ QTCFLLD(-2.096737e-01), QTCFLLD(2.818234e-01), QTCFLLD(-1.434317e-06),
+ QTCFLLD(2.203687e-04), QTCFLLD(-3.357312e-03), QTCFLLD(-2.701693e-01),
+ QTCFLLD(2.147441e-01), QTCFLLD(7.092199e-06), QTCFLLD(4.681670e-04),
+ QTCFLLD(-4.601593e-03), QTCFLLD(-3.341968e-01), QTCFLLD(1.461805e-01),
+ QTCFLLD(-1.116123e-05), QTCFLLD(1.072196e-03), QTCFLLD(-5.925141e-03),
+ QTCFLLD(-4.010285e-01), QTCFLLD(8.077862e-02), QTCFLLD(-3.775385e-05),
+ QTCFLLD(1.244841e-03), QTCFLLD(-7.628469e-03), QTCFLLD(-4.696240e-01),
+ QTCFLLD(2.901889e-02),
+};
+
+RAM_ALIGN
+const FIXP_PFT qmf_cldfb_80[QMF80_CLDFB_PFT_TABLE_SIZE] = {
+ QTCFLLD(6.966921e-07), QTCFLLD(9.025176e-06), QTCFLLD(-1.073328e-03),
+ QTCFLLD(1.146585e-02), QTCFLLD(5.726758e-01), QTCFLLD(-2.323046e-09),
+ QTCFLLD(1.012638e-05), QTCFLLD(-1.084654e-03), QTCFLLD(1.960515e-02),
+ QTCFLLD(7.059712e-01), QTCFLLD(1.230159e-07), QTCFLLD(4.639126e-05),
+ QTCFLLD(6.398911e-04), QTCFLLD(3.204506e-02), QTCFLLD(8.267125e-01),
+ QTCFLLD(2.865339e-07), QTCFLLD(6.273759e-05), QTCFLLD(2.550464e-03),
+ QTCFLLD(4.977453e-02), QTCFLLD(9.261818e-01), QTCFLLD(3.738257e-07),
+ QTCFLLD(-2.429021e-06), QTCFLLD(1.375921e-03), QTCFLLD(7.212754e-02),
+ QTCFLLD(9.964333e-01), QTCFLLD(1.077039e-08), QTCFLLD(-8.532976e-06),
+ QTCFLLD(7.147022e-04), QTCFLLD(9.563432e-02), QTCFLLD(1.034012e+00),
+ QTCFLLD(3.086046e-07), QTCFLLD(-7.986870e-05), QTCFLLD(2.203781e-04),
+ QTCFLLD(1.156221e-01), QTCFLLD(1.040718e+00), QTCFLLD(5.542804e-06),
+ QTCFLLD(-1.736757e-04), QTCFLLD(-2.475428e-03), QTCFLLD(1.266206e-01),
+ QTCFLLD(1.020100e+00), QTCFLLD(3.415168e-06), QTCFLLD(6.290201e-06),
+ QTCFLLD(-4.576709e-03), QTCFLLD(1.256370e-01), QTCFLLD(9.506344e-01),
+ QTCFLLD(-1.998632e-09), QTCFLLD(3.017514e-05), QTCFLLD(-3.627394e-03),
+ QTCFLLD(1.081003e-01), QTCFLLD(8.383245e-01), QTCFLLD(2.590900e-07),
+ QTCFLLD(9.614004e-05), QTCFLLD(2.183786e-06), QTCFLLD(6.867141e-02),
+ QTCFLLD(7.150523e-01), QTCFLLD(1.408172e-07), QTCFLLD(5.203217e-05),
+ QTCFLLD(1.584410e-03), QTCFLLD(6.753749e-03), QTCFLLD(5.847858e-01),
+ QTCFLLD(-9.234326e-07), QTCFLLD(6.477183e-06), QTCFLLD(-2.123969e-04),
+ QTCFLLD(-7.709230e-02), QTCFLLD(4.504798e-01), QTCFLLD(-2.464033e-08),
+ QTCFLLD(1.888626e-05), QTCFLLD(-1.812003e-03), QTCFLLD(-1.809127e-01),
+ QTCFLLD(3.151743e-01), QTCFLLD(-8.344882e-07), QTCFLLD(2.538528e-04),
+ QTCFLLD(-3.972626e-03), QTCFLLD(-3.017793e-01), QTCFLLD(1.805658e-01),
+ QTCFLLD(-2.720526e-05), QTCFLLD(1.150009e-03), QTCFLLD(-6.712822e-03),
+ QTCFLLD(-4.351740e-01), QTCFLLD(5.276687e-02),
+};
+
+#if defined(QMF_COEFF_16BIT)
+#define QTMFLLD(x) FL2FXCONST_SGL(x / (float)(1 << QMF_MPSLDFB_PFT_SCALE))
+#define QTMFLLDT(x) FX_DBL2FXCONST_SGL(x)
+#else
+#define QTMFLLD(x) FL2FXCONST_DBL(x / (float)(1 << QMF_MPSLDFB_PFT_SCALE))
+#define QTMFLLDT(x) (FIXP_DBL)(x)
+#endif
+
+/*!
+ \name QMF
+ \brief QMF-Table
+ 32 channels, N = 320,
+
+ The coefficients are derived from the MPS Low Delay coefficient set
+ with 640 samples. The coefficients are interpolated and rearranged
+ in the following way compared to the reference:
+
+ qmf_mpsldfb_320[0] = (qmf_64_reference[ 0] + qmf_64_reference[ 1])/2.0;
+ qmf_mpsldfb_320[1] = (qmf_64_reference[128] + qmf_64_reference[129])/2.0;
+ qmf_mpsldfb_320[2] = (qmf_64_reference[256] + qmf_64_reference[257])/2.0;
+ qmf_mpsldfb_320[3] = (qmf_64_reference[384] + qmf_64_reference[385])/2.0;
+ qmf_mpsldfb_320[4] = (qmf_64_reference[512] + qmf_64_reference[513])/2.0;
+
+ qmf_mpsldfb_320[5] = (qmf_64_reference[ 2] + qmf_64_reference[ 3])/2.0;
+ qmf_mpsldfb_320[6] = (qmf_64_reference[130] + qmf_64_reference[131])/2.0;
+ qmf_mpsldfb_320[7] = (qmf_64_reference[258] + qmf_64_reference[259])/2.0;
+ qmf_mpsldfb_320[8] = (qmf_64_reference[386] + qmf_64_reference[387])/2.0;
+ qmf_mpsldfb_320[9] = (qmf_64_reference[514] + qmf_64_reference[515])/2.0;
+ .
+ .
+ .
+ qmf_mpsldfb_320[315] = (qmf_64_reference[126] + qmf_64_reference[127])/2.0;
+ qmf_mpsldfb_320[316] = (qmf_64_reference[254] + qmf_64_reference[255])/2.0;
+ qmf_mpsldfb_320[317] = (qmf_64_reference[382] + qmf_64_reference[383])/2.0;
+ qmf_mpsldfb_320[318] = (qmf_64_reference[510] + qmf_64_reference[511])/2.0;
+ qmf_mpsldfb_320[319] = (qmf_64_reference[638] + qmf_64_reference[639])/2.0;
+
+ The filter output is required to be scaled by 1 bit.
+
+ \showinitializer
+*/
+//@{
+const FIXP_PFT qmf_mpsldfb_320[QMF320_MPSLDFB_PFT_TABLE_SIZE] = {
+ QTMFLLD(1.0777725402e-004), QTMFLLD(-9.4703806099e-004),
+ QTMFLLD(6.1286436394e-003), QTMFLLD(-9.0161964297e-002),
+ QTMFLLD(5.5554401875e-001), QTMFLLD(1.2731316383e-004),
+ QTMFLLD(-1.2311334722e-003), QTMFLLD(4.9468209036e-003),
+ QTMFLLD(-1.1305026710e-001), QTMFLLD(5.2990418673e-001),
+ QTMFLLD(1.1927412561e-004), QTMFLLD(-1.5128203668e-003),
+ QTMFLLD(3.5794533323e-003), QTMFLLD(-1.3681203127e-001),
+ QTMFLLD(5.0423312187e-001), QTMFLLD(1.0006380762e-004),
+ QTMFLLD(-1.7925058492e-003), QTMFLLD(2.0164034795e-003),
+ QTMFLLD(-1.6139641404e-001), QTMFLLD(4.7861024737e-001),
+ QTMFLLD(7.2826202086e-005), QTMFLLD(-2.0697340369e-003),
+ QTMFLLD(2.4838969694e-004), QTMFLLD(-1.8674756587e-001),
+ QTMFLLD(4.5311337709e-001), QTMFLLD(3.8808015233e-005),
+ QTMFLLD(-2.3429044522e-003), QTMFLLD(-1.7331546405e-003),
+ QTMFLLD(-2.1280488372e-001), QTMFLLD(4.2781800032e-001),
+ QTMFLLD(-5.4359588830e-007), QTMFLLD(-2.6112669148e-003),
+ QTMFLLD(-3.9357249625e-003), QTMFLLD(-2.3950359225e-001),
+ QTMFLLD(4.0279802680e-001), QTMFLLD(-4.3614549213e-005),
+ QTMFLLD(-2.8741455171e-003), QTMFLLD(-6.3655078411e-003),
+ QTMFLLD(-2.6677471399e-001), QTMFLLD(3.7812507153e-001),
+ QTMFLLD(-8.9040157036e-005), QTMFLLD(-3.1308881007e-003),
+ QTMFLLD(-9.0275555849e-003), QTMFLLD(-2.9454550147e-001),
+ QTMFLLD(3.5386830568e-001), QTMFLLD(-1.3519046479e-004),
+ QTMFLLD(-3.3808732405e-003), QTMFLLD(-1.1925406754e-002),
+ QTMFLLD(-3.2273942232e-001), QTMFLLD(3.3009397984e-001),
+ QTMFLLD(-1.8045579782e-004), QTMFLLD(-3.6236830056e-003),
+ QTMFLLD(-1.5061311424e-002), QTMFLLD(-3.5127705336e-001),
+ QTMFLLD(3.0686509609e-001), QTMFLLD(-2.2396800341e-004),
+ QTMFLLD(-3.8587960880e-003), QTMFLLD(-1.8435835838e-002),
+ QTMFLLD(-3.8007527590e-001), QTMFLLD(2.8424069285e-001),
+ QTMFLLD(-2.6416976471e-004), QTMFLLD(-4.0859002620e-003),
+ QTMFLLD(-2.2048022598e-002), QTMFLLD(-4.0904915333e-001),
+ QTMFLLD(2.6227575541e-001), QTMFLLD(-3.0001887353e-004),
+ QTMFLLD(-4.3045589700e-003), QTMFLLD(-2.5894984603e-002),
+ QTMFLLD(-4.3811064959e-001), QTMFLLD(2.4102044106e-001),
+ QTMFLLD(-3.3083156450e-004), QTMFLLD(-4.5145484619e-003),
+ QTMFLLD(-2.9972121119e-002), QTMFLLD(-4.6717000008e-001),
+ QTMFLLD(2.2052007914e-001), QTMFLLD(-3.5614447552e-004),
+ QTMFLLD(-4.7155953944e-003), QTMFLLD(-3.4272894263e-002),
+ QTMFLLD(-4.9613577127e-001), QTMFLLD(2.0081442595e-001),
+ QTMFLLD(-3.7579826312e-004), QTMFLLD(-4.9072988331e-003),
+ QTMFLLD(-3.8788780570e-002), QTMFLLD(-5.2491527796e-001),
+ QTMFLLD(1.8193808198e-001), QTMFLLD(-3.8993739872e-004),
+ QTMFLLD(-5.0893351436e-003), QTMFLLD(-4.3509010226e-002),
+ QTMFLLD(-5.5341482162e-001), QTMFLLD(1.6391974688e-001),
+ QTMFLLD(-3.9912899956e-004), QTMFLLD(-5.2615385503e-003),
+ QTMFLLD(-4.8421185464e-002), QTMFLLD(-5.8154034615e-001),
+ QTMFLLD(1.4678207040e-001), QTMFLLD(-4.0421969607e-004),
+ QTMFLLD(-5.4236799479e-003), QTMFLLD(-5.3510606289e-002),
+ QTMFLLD(-6.0919785500e-001), QTMFLLD(1.3054165244e-001),
+ QTMFLLD(-4.0645478293e-004), QTMFLLD(-5.5756671354e-003),
+ QTMFLLD(-5.8760054410e-002), QTMFLLD(-6.3629388809e-001),
+ QTMFLLD(1.1520925164e-001), QTMFLLD(-4.0720938705e-004),
+ QTMFLLD(-5.7173836976e-003), QTMFLLD(-6.4149998128e-002),
+ QTMFLLD(-6.6273581982e-001), QTMFLLD(1.0078965127e-001),
+ QTMFLLD(-4.0812738007e-004), QTMFLLD(-5.8488911018e-003),
+ QTMFLLD(-6.9658569992e-002), QTMFLLD(-6.8843221664e-001),
+ QTMFLLD(8.7281554937e-002), QTMFLLD(-4.1120912647e-004),
+ QTMFLLD(-5.9703430161e-003), QTMFLLD(-7.5261354446e-002),
+ QTMFLLD(-7.1329379082e-001), QTMFLLD(7.4678033590e-002),
+ QTMFLLD(-4.1838851757e-004), QTMFLLD(-6.0821287334e-003),
+ QTMFLLD(-8.0931767821e-002), QTMFLLD(-7.3723363876e-001),
+ QTMFLLD(6.2966249883e-002), QTMFLLD(-4.3148122495e-004),
+ QTMFLLD(-6.1847940087e-003), QTMFLLD(-8.6640790105e-002),
+ QTMFLLD(-7.6016783714e-001), QTMFLLD(5.2128262818e-002),
+ QTMFLLD(-4.5229538227e-004), QTMFLLD(-6.2791546807e-003),
+ QTMFLLD(-9.2357128859e-002), QTMFLLD(-7.8201586008e-001),
+ QTMFLLD(4.2139917612e-002), QTMFLLD(-4.8211280955e-004),
+ QTMFLLD(-6.3661932945e-003), QTMFLLD(-9.8047181964e-002),
+ QTMFLLD(-8.0270123482e-001), QTMFLLD(3.2972395420e-002),
+ QTMFLLD(-5.2196672186e-004), QTMFLLD(-6.4471233636e-003),
+ QTMFLLD(-1.0367526114e-001), QTMFLLD(-8.2215231657e-001),
+ QTMFLLD(2.4589803070e-002), QTMFLLD(-5.7247944642e-004),
+ QTMFLLD(-6.5232971683e-003), QTMFLLD(-1.0920339823e-001),
+ QTMFLLD(-8.4030228853e-001), QTMFLLD(1.6952158883e-002),
+ QTMFLLD(-6.3343788497e-004), QTMFLLD(-6.5963375382e-003),
+ QTMFLLD(-1.1459194124e-001), QTMFLLD(-8.5709118843e-001),
+ QTMFLLD(1.0006074794e-002), QTMFLLD(-7.0449430496e-004),
+ QTMFLLD(-6.6681848839e-003), QTMFLLD(-1.1979964375e-001),
+ QTMFLLD(-8.7246519327e-001), QTMFLLD(3.6968050990e-003),
+ QTMFLLD(-7.9609593377e-004), QTMFLLD(-6.7403013818e-003),
+ QTMFLLD(-1.2478165329e-001), QTMFLLD(-8.8632321358e-001),
+ QTMFLLD(-1.6344460892e-003), QTMFLLD(-9.0200459817e-004),
+ QTMFLLD(-6.8151149899e-003), QTMFLLD(-1.2949258089e-001),
+ QTMFLLD(-8.9860773087e-001), QTMFLLD(-5.9283543378e-003),
+ QTMFLLD(-1.0116943158e-003), QTMFLLD(-6.8955891766e-003),
+ QTMFLLD(-1.3388808072e-001), QTMFLLD(-9.0933418274e-001),
+ QTMFLLD(-9.6466485411e-003), QTMFLLD(-1.1244935449e-003),
+ QTMFLLD(-6.9835213944e-003), QTMFLLD(-1.3791990280e-001),
+ QTMFLLD(-9.1846722364e-001), QTMFLLD(-1.2838950381e-002),
+ QTMFLLD(-1.2393904617e-003), QTMFLLD(-7.0809246972e-003),
+ QTMFLLD(-1.4153905213e-001), QTMFLLD(-9.2597639561e-001),
+ QTMFLLD(-1.5539921820e-002), QTMFLLD(-1.3542033266e-003),
+ QTMFLLD(-7.1895248257e-003), QTMFLLD(-1.4469626546e-001),
+ QTMFLLD(-9.3183851242e-001), QTMFLLD(-1.7783239484e-002),
+ QTMFLLD(-1.4669501688e-003), QTMFLLD(-7.3110014200e-003),
+ QTMFLLD(-1.4734169841e-001), QTMFLLD(-9.3603670597e-001),
+ QTMFLLD(-1.9597738981e-002), QTMFLLD(-1.5753224725e-003),
+ QTMFLLD(-7.4466220103e-003), QTMFLLD(-1.4942565560e-001),
+ QTMFLLD(-9.3856132030e-001), QTMFLLD(-2.1011535078e-002),
+ QTMFLLD(-1.6771152150e-003), QTMFLLD(-7.5972955674e-003),
+ QTMFLLD(-1.5089863539e-001), QTMFLLD(-9.3940949440e-001),
+ QTMFLLD(-2.2049814463e-002), QTMFLLD(-1.7698677257e-003),
+ QTMFLLD(-7.7634919435e-003), QTMFLLD(-1.5171185136e-001),
+ QTMFLLD(-9.3858534098e-001), QTMFLLD(-2.2738276049e-002),
+ QTMFLLD(-1.8512960523e-003), QTMFLLD(-7.9450644553e-003),
+ QTMFLLD(-1.5181747079e-001), QTMFLLD(-9.3610012531e-001),
+ QTMFLLD(-2.3101080209e-002), QTMFLLD(-1.9192657201e-003),
+ QTMFLLD(-8.1413704902e-003), QTMFLLD(-1.5116891265e-001),
+ QTMFLLD(-9.3197190762e-001), QTMFLLD(-2.3163486272e-002),
+ QTMFLLD(-1.9716904499e-003), QTMFLLD(-8.3509404212e-003),
+ QTMFLLD(-1.4972095191e-001), QTMFLLD(-9.2622530460e-001),
+ QTMFLLD(-2.2950030863e-002), QTMFLLD(-2.0066620782e-003),
+ QTMFLLD(-8.5715763271e-003), QTMFLLD(-1.4743055403e-001),
+ QTMFLLD(-9.1889131069e-001), QTMFLLD(-2.2486699745e-002),
+ QTMFLLD(-2.0227057394e-003), QTMFLLD(-8.8005559519e-003),
+ QTMFLLD(-1.4425669611e-001), QTMFLLD(-9.1000711918e-001),
+ QTMFLLD(-2.1799135953e-002), QTMFLLD(-2.0185527392e-003),
+ QTMFLLD(-9.0341167524e-003), QTMFLLD(-1.4016106725e-001),
+ QTMFLLD(-8.9961612225e-001), QTMFLLD(-2.0914383233e-002),
+ QTMFLLD(-1.9932338037e-003), QTMFLLD(-9.2674419284e-003),
+ QTMFLLD(-1.3510815799e-001), QTMFLLD(-8.8776648045e-001),
+ QTMFLLD(-1.9859094173e-002), QTMFLLD(-1.9461065531e-003),
+ QTMFLLD(-9.4948727638e-003), QTMFLLD(-1.2906542420e-001),
+ QTMFLLD(-8.7451159954e-001), QTMFLLD(-1.8660902977e-002),
+ QTMFLLD(-1.8770052120e-003), QTMFLLD(-9.7100129351e-003),
+ QTMFLLD(-1.2200380862e-001), QTMFLLD(-8.5991013050e-001),
+ QTMFLLD(-1.7346922308e-002), QTMFLLD(-1.7859865911e-003),
+ QTMFLLD(-9.9056493491e-003), QTMFLLD(-1.1389782280e-001),
+ QTMFLLD(-8.4402561188e-001), QTMFLLD(-1.5944939107e-002),
+ QTMFLLD(-1.6734169330e-003), QTMFLLD(-1.0073989630e-002),
+ QTMFLLD(-1.0472598672e-001), QTMFLLD(-8.2692527771e-001),
+ QTMFLLD(-1.4481747523e-002), QTMFLLD(-1.5399802942e-003),
+ QTMFLLD(-1.0205906816e-002), QTMFLLD(-9.4470888376e-002),
+ QTMFLLD(-8.0868041515e-001), QTMFLLD(-1.2984249741e-002),
+ QTMFLLD(-1.3865872752e-003), QTMFLLD(-1.0291703977e-002),
+ QTMFLLD(-8.3119556308e-002), QTMFLLD(-7.8936588764e-001),
+ QTMFLLD(-1.1477986351e-002), QTMFLLD(-1.2144348584e-003),
+ QTMFLLD(-1.0320962407e-002), QTMFLLD(-7.0663399994e-002),
+ QTMFLLD(-7.6905936003e-001), QTMFLLD(-9.9884867668e-003),
+ QTMFLLD(-1.0248266626e-003), QTMFLLD(-1.0282764211e-002),
+ QTMFLLD(-5.7098604739e-002), QTMFLLD(-7.4784147739e-001),
+ QTMFLLD(-8.5393209010e-003), QTMFLLD(-8.1919803051e-004),
+ QTMFLLD(-1.0165717453e-002), QTMFLLD(-4.2426198721e-002),
+ QTMFLLD(-7.2579479218e-001), QTMFLLD(-7.1533406153e-003),
+ QTMFLLD(-5.9914286248e-004), QTMFLLD(-9.9579729140e-003),
+ QTMFLLD(-2.6652012020e-002), QTMFLLD(-7.0300412178e-001),
+ QTMFLLD(-5.8508114889e-003), QTMFLLD(-3.6626873771e-004),
+ QTMFLLD(-9.6475090832e-003), QTMFLLD(-9.7871217877e-003),
+ QTMFLLD(-6.7955517769e-001), QTMFLLD(-4.6512838453e-003),
+ QTMFLLD(-1.2227181287e-004), QTMFLLD(-9.2221321538e-003),
+ QTMFLLD(8.1523396075e-003), QTMFLLD(-6.5553492308e-001),
+ QTMFLLD(-3.5699680448e-003), QTMFLLD(1.3090072025e-004),
+ QTMFLLD(-8.6695179343e-003), QTMFLLD(2.7145106345e-002),
+ QTMFLLD(-6.3103044033e-001), QTMFLLD(-2.6181070134e-003),
+ QTMFLLD(3.9128778735e-004), QTMFLLD(-7.9773496836e-003),
+ QTMFLLD(4.7164849937e-002), QTMFLLD(-6.0613000393e-001),
+ QTMFLLD(-1.7908872105e-003), QTMFLLD(6.5761915175e-004),
+ QTMFLLD(-7.1337916888e-003), QTMFLLD(6.8181537092e-002),
+ QTMFLLD(-5.8092808723e-001), QTMFLLD(-1.0135001503e-003)};
+
+/*!
+ \name QMF
+ \brief QMF-Table
+ 64 channels, N = 640,
+
+ The coeffs are rearranged compared with the reference in the following
+ way:
+
+ qmf_64[0] = qmf_64_reference[0];
+ qmf_64[1] = qmf_64_reference[128];
+ qmf_64[2] = qmf_64_reference[256];
+ qmf_64[3] = qmf_64_reference[384];
+ qmf_64[4] = qmf_64_reference[512];
+
+ qmf_64[5] = qmf_64_reference[1];
+ qmf_64[6] = qmf_64_reference[129];
+ qmf_64[7] = qmf_64_reference[257];
+ qmf_64[8] = qmf_64_reference[385];
+ qmf_64[9] = qmf_64_reference[513];
+ .
+ .
+ .
+ qmf_64[635] = qmf_64_reference[127]
+ qmf_64[636] = qmf_64_reference[255];
+ qmf_64[637] = qmf_64_reference[383];
+ qmf_64[638] = qmf_64_reference[511];
+ qmf_64[639] = qmf_64_reference[639];
+
+ The filter output is required to be scaled by 1 bit.
+
+ \showinitializer
+*/
+//@{
+LNK_SECTION_CONSTDATA_L1
+RAM_ALIGN
+const FIXP_PFT qmf_mpsldfb_640[QMF640_MPSLDFB_PFT_TABLE_SIZE] = {
+ QTMFLLD(9.3863010989e-005), QTMFLLD(-8.7536586216e-004),
+ QTMFLLD(6.4016343094e-003), QTMFLLD(-8.4552817047e-002),
+ QTMFLLD(5.6194400787e-001), QTMFLLD(1.2169149704e-004),
+ QTMFLLD(-1.0187102016e-003), QTMFLLD(5.8556534350e-003),
+ QTMFLLD(-9.5771118999e-002), QTMFLLD(5.4914402962e-001),
+ QTMFLLD(1.2793767382e-004), QTMFLLD(-1.1605311884e-003),
+ QTMFLLD(5.2649765275e-003), QTMFLLD(-1.0721673071e-001),
+ QTMFLLD(5.3632181883e-001), QTMFLLD(1.2668863928e-004),
+ QTMFLLD(-1.3017356396e-003), QTMFLLD(4.6286652796e-003),
+ QTMFLLD(-1.1888379604e-001), QTMFLLD(5.2348655462e-001),
+ QTMFLLD(1.2296593923e-004), QTMFLLD(-1.4426353155e-003),
+ QTMFLLD(3.9453012869e-003), QTMFLLD(-1.3076621294e-001),
+ QTMFLLD(5.1064836979e-001), QTMFLLD(1.1558231199e-004),
+ QTMFLLD(-1.5830053017e-003), QTMFLLD(3.2136053778e-003),
+ QTMFLLD(-1.4285783470e-001), QTMFLLD(4.9781781435e-001),
+ QTMFLLD(1.0582985124e-004), QTMFLLD(-1.7228506040e-003),
+ QTMFLLD(2.4323666003e-003), QTMFLLD(-1.5515175462e-001),
+ QTMFLLD(4.8500382900e-001), QTMFLLD(9.4297764008e-005),
+ QTMFLLD(-1.8621610943e-003), QTMFLLD(1.6004402423e-003),
+ QTMFLLD(-1.6764105856e-001), QTMFLLD(4.7221666574e-001),
+ QTMFLLD(8.0514568253e-005), QTMFLLD(-2.0008818246e-003),
+ QTMFLLD(7.1672687773e-004), QTMFLLD(-1.8031860888e-001),
+ QTMFLLD(4.5946595073e-001), QTMFLLD(6.5137835918e-005),
+ QTMFLLD(-2.1385864820e-003), QTMFLLD(-2.1994746930e-004),
+ QTMFLLD(-1.9317652285e-001), QTMFLLD(4.4676083326e-001),
+ QTMFLLD(4.8101064749e-005), QTMFLLD(-2.2751907818e-003),
+ QTMFLLD(-1.2104592752e-003), QTMFLLD(-2.0620720088e-001),
+ QTMFLLD(4.3411090970e-001), QTMFLLD(2.9514967537e-005),
+ QTMFLLD(-2.4106178898e-003), QTMFLLD(-2.2558500059e-003),
+ QTMFLLD(-2.1940255165e-001), QTMFLLD(4.2152509093e-001),
+ QTMFLLD(9.8814107332e-006), QTMFLLD(-2.5448307861e-003),
+ QTMFLLD(-3.3569468651e-003), QTMFLLD(-2.3275400698e-001),
+ QTMFLLD(4.0901294351e-001), QTMFLLD(-1.0968602510e-005),
+ QTMFLLD(-2.6777030434e-003), QTMFLLD(-4.5145032927e-003),
+ QTMFLLD(-2.4625316262e-001), QTMFLLD(3.9658311009e-001),
+ QTMFLLD(-3.2559255487e-005), QTMFLLD(-2.8091520071e-003),
+ QTMFLLD(-5.7292259298e-003), QTMFLLD(-2.5989097357e-001),
+ QTMFLLD(3.8424444199e-001), QTMFLLD(-5.4669842939e-005),
+ QTMFLLD(-2.9391390271e-003), QTMFLLD(-7.0017897524e-003),
+ QTMFLLD(-2.7365845442e-001), QTMFLLD(3.7200567126e-001),
+ QTMFLLD(-7.7506563684e-005), QTMFLLD(-3.0675258022e-003),
+ QTMFLLD(-8.3327051252e-003), QTMFLLD(-2.8754624724e-001),
+ QTMFLLD(3.5987523198e-001), QTMFLLD(-1.0057374311e-004),
+ QTMFLLD(-3.1942503992e-003), QTMFLLD(-9.7224051133e-003),
+ QTMFLLD(-3.0154475570e-001), QTMFLLD(3.4786140919e-001),
+ QTMFLLD(-1.2368557509e-004), QTMFLLD(-3.3192564733e-003),
+ QTMFLLD(-1.1171258055e-002), QTMFLLD(-3.1564420462e-001),
+ QTMFLLD(3.3597227931e-001), QTMFLLD(-1.4669535449e-004),
+ QTMFLLD(-3.4424900077e-003), QTMFLLD(-1.2679555453e-002),
+ QTMFLLD(-3.2983466983e-001), QTMFLLD(3.2421571016e-001),
+ QTMFLLD(-1.6928518016e-004), QTMFLLD(-3.5639149137e-003),
+ QTMFLLD(-1.4247507788e-002), QTMFLLD(-3.4410607815e-001),
+ QTMFLLD(3.1259948015e-001), QTMFLLD(-1.9162640092e-004),
+ QTMFLLD(-3.6834510975e-003), QTMFLLD(-1.5875114128e-002),
+ QTMFLLD(-3.5844799876e-001), QTMFLLD(3.0113074183e-001),
+ QTMFLLD(-2.1345751884e-004), QTMFLLD(-3.8009947166e-003),
+ QTMFLLD(-1.7562393099e-002), QTMFLLD(-3.7284970284e-001),
+ QTMFLLD(2.8981682658e-001), QTMFLLD(-2.3447850253e-004),
+ QTMFLLD(-3.9165974595e-003), QTMFLLD(-1.9309276715e-002),
+ QTMFLLD(-3.8730087876e-001), QTMFLLD(2.7866455913e-001),
+ QTMFLLD(-2.5462667691e-004), QTMFLLD(-4.0301652625e-003),
+ QTMFLLD(-2.1115457639e-002), QTMFLLD(-4.0179058909e-001),
+ QTMFLLD(2.6768052578e-001), QTMFLLD(-2.7371285250e-004),
+ QTMFLLD(-4.1416347958e-003), QTMFLLD(-2.2980585694e-002),
+ QTMFLLD(-4.1630774736e-001), QTMFLLD(2.5687095523e-001),
+ QTMFLLD(-2.9165804153e-004), QTMFLLD(-4.2509674095e-003),
+ QTMFLLD(-2.4904217571e-002), QTMFLLD(-4.3084129691e-001),
+ QTMFLLD(2.4624188244e-001), QTMFLLD(-3.0837973463e-004),
+ QTMFLLD(-4.3581505306e-003), QTMFLLD(-2.6885753497e-002),
+ QTMFLLD(-4.4538003206e-001), QTMFLLD(2.3579898477e-001),
+ QTMFLLD(-3.2378203468e-004), QTMFLLD(-4.4631510973e-003),
+ QTMFLLD(-2.8924530372e-002), QTMFLLD(-4.5991250873e-001),
+ QTMFLLD(2.2554755211e-001), QTMFLLD(-3.3788106521e-004),
+ QTMFLLD(-4.5659458265e-003), QTMFLLD(-3.1019711867e-002),
+ QTMFLLD(-4.7442746162e-001), QTMFLLD(2.1549259126e-001),
+ QTMFLLD(-3.5053401371e-004), QTMFLLD(-4.6664695255e-003),
+ QTMFLLD(-3.3170353621e-002), QTMFLLD(-4.8891320825e-001),
+ QTMFLLD(2.0563863218e-001), QTMFLLD(-3.6175493733e-004),
+ QTMFLLD(-4.7647207975e-003), QTMFLLD(-3.5375438631e-002),
+ QTMFLLD(-5.0335830450e-001), QTMFLLD(1.9599021971e-001),
+ QTMFLLD(-3.7159718340e-004), QTMFLLD(-4.8605888151e-003),
+ QTMFLLD(-3.7633713335e-002), QTMFLLD(-5.1775097847e-001),
+ QTMFLLD(1.8655113876e-001), QTMFLLD(-3.7999937194e-004),
+ QTMFLLD(-4.9540083855e-003), QTMFLLD(-3.9943847805e-002),
+ QTMFLLD(-5.3207957745e-001), QTMFLLD(1.7732504010e-001),
+ QTMFLLD(-3.8705617771e-004), QTMFLLD(-5.0450465642e-003),
+ QTMFLLD(-4.2304381728e-002), QTMFLLD(-5.4633224010e-001),
+ QTMFLLD(1.6831515729e-001), QTMFLLD(-3.9281861973e-004),
+ QTMFLLD(-5.1336232573e-003), QTMFLLD(-4.4713638723e-002),
+ QTMFLLD(-5.6049734354e-001), QTMFLLD(1.5952435136e-001),
+ QTMFLLD(-3.9737694897e-004), QTMFLLD(-5.2197398618e-003),
+ QTMFLLD(-4.7170232981e-002), QTMFLLD(-5.7456302643e-001),
+ QTMFLLD(1.5095503628e-001), QTMFLLD(-4.0088107926e-004),
+ QTMFLLD(-5.3033372387e-003), QTMFLLD(-4.9672137946e-002),
+ QTMFLLD(-5.8851766586e-001), QTMFLLD(1.4260910451e-001),
+ QTMFLLD(-4.0338383405e-004), QTMFLLD(-5.3843962960e-003),
+ QTMFLLD(-5.2217379212e-002), QTMFLLD(-6.0234934092e-001),
+ QTMFLLD(1.3448855281e-001), QTMFLLD(-4.0505555808e-004),
+ QTMFLLD(-5.4629631341e-003), QTMFLLD(-5.4803829640e-002),
+ QTMFLLD(-6.1604642868e-001), QTMFLLD(1.2659475207e-001),
+ QTMFLLD(-4.0614881436e-004), QTMFLLD(-5.5389581248e-003),
+ QTMFLLD(-5.7429198176e-002), QTMFLLD(-6.2959736586e-001),
+ QTMFLLD(1.1892842501e-001), QTMFLLD(-4.0676075150e-004),
+ QTMFLLD(-5.6123761460e-003), QTMFLLD(-6.0090914369e-002),
+ QTMFLLD(-6.4299046993e-001), QTMFLLD(1.1149007827e-001),
+ QTMFLLD(-4.0709332097e-004), QTMFLLD(-5.6832311675e-003),
+ QTMFLLD(-6.2786586583e-002), QTMFLLD(-6.5621429682e-001),
+ QTMFLLD(1.0428040475e-001), QTMFLLD(-4.0732545312e-004),
+ QTMFLLD(-5.7515366934e-003), QTMFLLD(-6.5513409674e-002),
+ QTMFLLD(-6.6925734282e-001), QTMFLLD(9.7298897803e-002),
+ QTMFLLD(-4.0770808118e-004), QTMFLLD(-5.8172862045e-003),
+ QTMFLLD(-6.8268470466e-002), QTMFLLD(-6.8210834265e-001),
+ QTMFLLD(9.0545162559e-002), QTMFLLD(-4.0854664985e-004),
+ QTMFLLD(-5.8804959990e-003), QTMFLLD(-7.1048669517e-002),
+ QTMFLLD(-6.9475615025e-001), QTMFLLD(8.4017947316e-002),
+ QTMFLLD(-4.1002241778e-004), QTMFLLD(-5.9412117116e-003),
+ QTMFLLD(-7.3850922287e-002), QTMFLLD(-7.0718955994e-001),
+ QTMFLLD(7.7716566622e-002), QTMFLLD(-4.1239586426e-004),
+ QTMFLLD(-5.9994738549e-003), QTMFLLD(-7.6671779156e-002),
+ QTMFLLD(-7.1939796209e-001), QTMFLLD(7.1639508009e-002),
+ QTMFLLD(-4.1594370850e-004), QTMFLLD(-6.0553550720e-003),
+ QTMFLLD(-7.9507902265e-002), QTMFLLD(-7.3137050867e-001),
+ QTMFLLD(6.5784148872e-002), QTMFLLD(-4.2083335575e-004),
+ QTMFLLD(-6.1089023948e-003), QTMFLLD(-8.2355625927e-002),
+ QTMFLLD(-7.4309676886e-001), QTMFLLD(6.0148354620e-002),
+ QTMFLLD(-4.2732476140e-004), QTMFLLD(-6.1602159403e-003),
+ QTMFLLD(-8.5211075842e-002), QTMFLLD(-7.5456637144e-001),
+ QTMFLLD(5.4730266333e-002), QTMFLLD(-4.3563771760e-004),
+ QTMFLLD(-6.2093720771e-003), QTMFLLD(-8.8070511818e-002),
+ QTMFLLD(-7.6576924324e-001), QTMFLLD(4.9526259303e-002),
+ QTMFLLD(-4.4600359979e-004), QTMFLLD(-6.2565426342e-003),
+ QTMFLLD(-9.0929701924e-002), QTMFLLD(-7.7669566870e-001),
+ QTMFLLD(4.4533081353e-002), QTMFLLD(-4.5858716476e-004),
+ QTMFLLD(-6.3017667271e-003), QTMFLLD(-9.3784548342e-002),
+ QTMFLLD(-7.8733605146e-001), QTMFLLD(3.9746750146e-002),
+ QTMFLLD(-4.7345875646e-004), QTMFLLD(-6.3452622853e-003),
+ QTMFLLD(-9.6630692482e-002), QTMFLLD(-7.9768097401e-001),
+ QTMFLLD(3.5163912922e-002), QTMFLLD(-4.9076689174e-004),
+ QTMFLLD(-6.3871243037e-003), QTMFLLD(-9.9463671446e-002),
+ QTMFLLD(-8.0772149563e-001), QTMFLLD(3.0780877918e-002),
+ QTMFLLD(-5.1067111781e-004), QTMFLLD(-6.4275567420e-003),
+ QTMFLLD(-1.0227891803e-001), QTMFLLD(-8.1744915247e-001),
+ QTMFLLD(2.6590615511e-002), QTMFLLD(-5.3326232592e-004),
+ QTMFLLD(-6.4666904509e-003), QTMFLLD(-1.0507161170e-001),
+ QTMFLLD(-8.2685548067e-001), QTMFLLD(2.2588992491e-002),
+ QTMFLLD(-5.5855646497e-004), QTMFLLD(-6.5047293901e-003),
+ QTMFLLD(-1.0783691704e-001), QTMFLLD(-8.3593225479e-001),
+ QTMFLLD(1.8772648647e-002), QTMFLLD(-5.8640236966e-004),
+ QTMFLLD(-6.5418654121e-003), QTMFLLD(-1.1056987941e-001),
+ QTMFLLD(-8.4467232227e-001), QTMFLLD(1.5131668188e-002),
+ QTMFLLD(-6.1692652525e-004), QTMFLLD(-6.5783206373e-003),
+ QTMFLLD(-1.1326543987e-001), QTMFLLD(-8.5306841135e-001),
+ QTMFLLD(1.1661184952e-002), QTMFLLD(-6.4994930290e-004),
+ QTMFLLD(-6.6143544391e-003), QTMFLLD(-1.1591844261e-001),
+ QTMFLLD(-8.6111402512e-001), QTMFLLD(8.3509646356e-003),
+ QTMFLLD(-6.8494328298e-004), QTMFLLD(-6.6502285190e-003),
+ QTMFLLD(-1.1852371693e-001), QTMFLLD(-8.6880439520e-001),
+ QTMFLLD(5.1832948811e-003), QTMFLLD(-7.2404538514e-004),
+ QTMFLLD(-6.6861407831e-003), QTMFLLD(-1.2107557058e-001),
+ QTMFLLD(-8.7612599134e-001), QTMFLLD(2.2103153169e-003),
+ QTMFLLD(-7.7061145566e-004), QTMFLLD(-6.7221261561e-003),
+ QTMFLLD(-1.2356808037e-001), QTMFLLD(-8.8305824995e-001),
+ QTMFLLD(-4.6855807886e-004), QTMFLLD(-8.2158041187e-004),
+ QTMFLLD(-6.7584766075e-003), QTMFLLD(-1.2599521875e-001),
+ QTMFLLD(-8.8958823681e-001), QTMFLLD(-2.8003340121e-003),
+ QTMFLLD(-8.7498105131e-004), QTMFLLD(-6.7957863212e-003),
+ QTMFLLD(-1.2835204601e-001), QTMFLLD(-8.9572954178e-001),
+ QTMFLLD(-4.9293786287e-003), QTMFLLD(-9.2902814504e-004),
+ QTMFLLD(-6.8344431929e-003), QTMFLLD(-1.3063311577e-001),
+ QTMFLLD(-9.0148586035e-001), QTMFLLD(-6.9273295812e-003),
+ QTMFLLD(-9.8383461591e-004), QTMFLLD(-6.8746237084e-003),
+ QTMFLLD(-1.3283239305e-001), QTMFLLD(-9.0685033798e-001),
+ QTMFLLD(-8.7857460603e-003), QTMFLLD(-1.0395538993e-003),
+ QTMFLLD(-6.9165546447e-003), QTMFLLD(-1.3494376838e-001),
+ QTMFLLD(-9.1181802750e-001), QTMFLLD(-1.0507551953e-002),
+ QTMFLLD(-1.0959620122e-003), QTMFLLD(-6.9604511373e-003),
+ QTMFLLD(-1.3696120679e-001), QTMFLLD(-9.1638565063e-001),
+ QTMFLLD(-1.2103702873e-002), QTMFLLD(-1.1530250777e-003),
+ QTMFLLD(-7.0065916516e-003), QTMFLLD(-1.3887859881e-001),
+ QTMFLLD(-9.2054879665e-001), QTMFLLD(-1.3574197888e-002),
+ QTMFLLD(-1.2105966453e-003), QTMFLLD(-7.0552495308e-003),
+ QTMFLLD(-1.4068968594e-001), QTMFLLD(-9.2430406809e-001),
+ QTMFLLD(-1.4923358336e-002), QTMFLLD(-1.2681842782e-003),
+ QTMFLLD(-7.1066003293e-003), QTMFLLD(-1.4238841832e-001),
+ QTMFLLD(-9.2764878273e-001), QTMFLLD(-1.6156485304e-002),
+ QTMFLLD(-1.3256429229e-003), QTMFLLD(-7.1608433500e-003),
+ QTMFLLD(-1.4396859705e-001), QTMFLLD(-9.3058031797e-001),
+ QTMFLLD(-1.7277117819e-002), QTMFLLD(-1.3827638468e-003),
+ QTMFLLD(-7.2182063013e-003), QTMFLLD(-1.4542391896e-001),
+ QTMFLLD(-9.3309664726e-001), QTMFLLD(-1.8289361149e-002),
+ QTMFLLD(-1.4391905861e-003), QTMFLLD(-7.2789187543e-003),
+ QTMFLLD(-1.4674818516e-001), QTMFLLD(-9.3519610167e-001),
+ QTMFLLD(-1.9195662811e-002), QTMFLLD(-1.4947097516e-003),
+ QTMFLLD(-7.3430840857e-003), QTMFLLD(-1.4793521166e-001),
+ QTMFLLD(-9.3687731028e-001), QTMFLLD(-1.9999813288e-002),
+ QTMFLLD(-1.5489540529e-003), QTMFLLD(-7.4108825065e-003),
+ QTMFLLD(-1.4897871017e-001), QTMFLLD(-9.3813979626e-001),
+ QTMFLLD(-2.0706148818e-002), QTMFLLD(-1.6016908921e-003),
+ QTMFLLD(-7.4823615141e-003), QTMFLLD(-1.4987260103e-001),
+ QTMFLLD(-9.3898290396e-001), QTMFLLD(-2.1316919476e-002),
+ QTMFLLD(-1.6526894178e-003), QTMFLLD(-7.5576924719e-003),
+ QTMFLLD(-1.5061059594e-001), QTMFLLD(-9.3940681219e-001),
+ QTMFLLD(-2.1835187450e-002), QTMFLLD(-1.7015410122e-003),
+ QTMFLLD(-7.6368991286e-003), QTMFLLD(-1.5118667483e-001),
+ QTMFLLD(-9.3941211700e-001), QTMFLLD(-2.2264443338e-002),
+ QTMFLLD(-1.7479787348e-003), QTMFLLD(-7.7200052328e-003),
+ QTMFLLD(-1.5159477293e-001), QTMFLLD(-9.3899971247e-001),
+ QTMFLLD(-2.2607907653e-002), QTMFLLD(-1.7917567166e-003),
+ QTMFLLD(-7.8069791198e-003), QTMFLLD(-1.5182891488e-001),
+ QTMFLLD(-9.3817096949e-001), QTMFLLD(-2.2868644446e-002),
+ QTMFLLD(-1.8325200072e-003), QTMFLLD(-7.8977877274e-003),
+ QTMFLLD(-1.5188319981e-001), QTMFLLD(-9.3692785501e-001),
+ QTMFLLD(-2.3049183190e-002), QTMFLLD(-1.8700722139e-003),
+ QTMFLLD(-7.9923402518e-003), QTMFLLD(-1.5175175667e-001),
+ QTMFLLD(-9.3527245522e-001), QTMFLLD(-2.3152977228e-002),
+ QTMFLLD(-1.9041235792e-003), QTMFLLD(-8.0905584618e-003),
+ QTMFLLD(-1.5142890811e-001), QTMFLLD(-9.3320751190e-001),
+ QTMFLLD(-2.3183524609e-002), QTMFLLD(-1.9344078610e-003),
+ QTMFLLD(-8.1921815872e-003), QTMFLLD(-1.5090890229e-001),
+ QTMFLLD(-9.3073624372e-001), QTMFLLD(-2.3143447936e-002),
+ QTMFLLD(-1.9606938586e-003), QTMFLLD(-8.2970457152e-003),
+ QTMFLLD(-1.5018628538e-001), QTMFLLD(-9.2786192894e-001),
+ QTMFLLD(-2.3035895079e-002), QTMFLLD(-1.9826870412e-003),
+ QTMFLLD(-8.4048351273e-003), QTMFLLD(-1.4925561845e-001),
+ QTMFLLD(-9.2458862066e-001), QTMFLLD(-2.2864164785e-002),
+ QTMFLLD(-2.0002126694e-003), QTMFLLD(-8.5152359679e-003),
+ QTMFLLD(-1.4811170101e-001), QTMFLLD(-9.2092043161e-001),
+ QTMFLLD(-2.2631708533e-002), QTMFLLD(-2.0131117199e-003),
+ QTMFLLD(-8.6279176176e-003), QTMFLLD(-1.4674940705e-001),
+ QTMFLLD(-9.1686213017e-001), QTMFLLD(-2.2341690958e-002),
+ QTMFLLD(-2.0211567171e-003), QTMFLLD(-8.7425475940e-003),
+ QTMFLLD(-1.4516362548e-001), QTMFLLD(-9.1241872311e-001),
+ QTMFLLD(-2.1996961907e-002), QTMFLLD(-2.0242547616e-003),
+ QTMFLLD(-8.8585643098e-003), QTMFLLD(-1.4334976673e-001),
+ QTMFLLD(-9.0759557486e-001), QTMFLLD(-2.1601308137e-002),
+ QTMFLLD(-2.0221893210e-003), QTMFLLD(-8.9755039662e-003),
+ QTMFLLD(-1.4130303264e-001), QTMFLLD(-9.0239852667e-001),
+ QTMFLLD(-2.1158147603e-002), QTMFLLD(-2.0149163902e-003),
+ QTMFLLD(-9.0927295387e-003), QTMFLLD(-1.3901908696e-001),
+ QTMFLLD(-8.9683371782e-001), QTMFLLD(-2.0670616999e-002),
+ QTMFLLD(-2.0022888202e-003), QTMFLLD(-9.2095714062e-003),
+ QTMFLLD(-1.3649365306e-001), QTMFLLD(-8.9090716839e-001),
+ QTMFLLD(-2.0142132416e-002), QTMFLLD(-1.9841785543e-003),
+ QTMFLLD(-9.3253115192e-003), QTMFLLD(-1.3372266293e-001),
+ QTMFLLD(-8.8462579250e-001), QTMFLLD(-1.9576057792e-002),
+ QTMFLLD(-1.9606270362e-003), QTMFLLD(-9.4392402098e-003),
+ QTMFLLD(-1.3070219755e-001), QTMFLLD(-8.7799650431e-001),
+ QTMFLLD(-1.8976125866e-002), QTMFLLD(-1.9315859536e-003),
+ QTMFLLD(-9.5505062491e-003), QTMFLLD(-1.2742865086e-001),
+ QTMFLLD(-8.7102663517e-001), QTMFLLD(-1.8345680088e-002),
+ QTMFLLD(-1.8970289966e-003), QTMFLLD(-9.6583357081e-003),
+ QTMFLLD(-1.2389861047e-001), QTMFLLD(-8.6372399330e-001),
+ QTMFLLD(-1.7687706277e-002), QTMFLLD(-1.8569815438e-003),
+ QTMFLLD(-9.7616901621e-003), QTMFLLD(-1.2010899931e-001),
+ QTMFLLD(-8.5609632730e-001), QTMFLLD(-1.7006140202e-002),
+ QTMFLLD(-1.8114587292e-003), QTMFLLD(-9.8597351462e-003),
+ QTMFLLD(-1.1605655402e-001), QTMFLLD(-8.4815198183e-001),
+ QTMFLLD(-1.6304368153e-002), QTMFLLD(-1.7605143366e-003),
+ QTMFLLD(-9.9515644833e-003), QTMFLLD(-1.1173909158e-001),
+ QTMFLLD(-8.3989918232e-001), QTMFLLD(-1.5585509129e-002),
+ QTMFLLD(-1.7042002873e-003), QTMFLLD(-1.0036026128e-002),
+ QTMFLLD(-1.0715358704e-001), QTMFLLD(-8.3134686947e-001),
+ QTMFLLD(-1.4853162691e-002), QTMFLLD(-1.6426335787e-003),
+ QTMFLLD(-1.0111952201e-002), QTMFLLD(-1.0229838639e-001),
+ QTMFLLD(-8.2250368595e-001), QTMFLLD(-1.4110331424e-002),
+ QTMFLLD(-1.5758809168e-003), QTMFLLD(-1.0178210214e-002),
+ QTMFLLD(-9.7171187401e-002), QTMFLLD(-8.1337898970e-001),
+ QTMFLLD(-1.3360806741e-002), QTMFLLD(-1.5040797880e-003),
+ QTMFLLD(-1.0233603418e-002), QTMFLLD(-9.1770596802e-002),
+ QTMFLLD(-8.0398184061e-001), QTMFLLD(-1.2607692741e-002),
+ QTMFLLD(-1.4273397392e-003), QTMFLLD(-1.0276827961e-002),
+ QTMFLLD(-8.6095176637e-002), QTMFLLD(-7.9432225227e-001),
+ QTMFLLD(-1.1853585951e-002), QTMFLLD(-1.3458349276e-003),
+ QTMFLLD(-1.0306579992e-002), QTMFLLD(-8.0143928528e-002),
+ QTMFLLD(-7.8440952301e-001), QTMFLLD(-1.1102385819e-002),
+ QTMFLLD(-1.2597256573e-003), QTMFLLD(-1.0321546346e-002),
+ QTMFLLD(-7.3915921152e-002), QTMFLLD(-7.7425378561e-001),
+ QTMFLLD(-1.0356968269e-002), QTMFLLD(-1.1691439431e-003),
+ QTMFLLD(-1.0320378467e-002), QTMFLLD(-6.7410878837e-002),
+ QTMFLLD(-7.6386493444e-001), QTMFLLD(-9.6200043336e-003),
+ QTMFLLD(-1.0743001476e-003), QTMFLLD(-1.0301630013e-002),
+ QTMFLLD(-6.0628447682e-002), QTMFLLD(-7.5325345993e-001),
+ QTMFLLD(-8.8949296623e-003), QTMFLLD(-9.7535311943e-004),
+ QTMFLLD(-1.0263898410e-002), QTMFLLD(-5.3568758070e-002),
+ QTMFLLD(-7.4242949486e-001), QTMFLLD(-8.1837112084e-003),
+ QTMFLLD(-8.7248592172e-004), QTMFLLD(-1.0205759667e-002),
+ QTMFLLD(-4.6232450753e-002), QTMFLLD(-7.3140352964e-001),
+ QTMFLLD(-7.4901022017e-003), QTMFLLD(-7.6591013931e-004),
+ QTMFLLD(-1.0125675239e-002), QTMFLLD(-3.8619950414e-002),
+ QTMFLLD(-7.2018599510e-001), QTMFLLD(-6.8165790290e-003),
+ QTMFLLD(-6.5580842784e-004), QTMFLLD(-1.0022218339e-002),
+ QTMFLLD(-3.0732547864e-002), QTMFLLD(-7.0878815651e-001),
+ QTMFLLD(-6.1642420478e-003), QTMFLLD(-5.4247735534e-004),
+ QTMFLLD(-9.8937284201e-003), QTMFLLD(-2.2571478039e-002),
+ QTMFLLD(-6.9722014666e-001), QTMFLLD(-5.5373813957e-003),
+ QTMFLLD(-4.2596619460e-004), QTMFLLD(-9.7389295697e-003),
+ QTMFLLD(-1.4138570987e-002), QTMFLLD(-6.8549299240e-001),
+ QTMFLLD(-4.9372608773e-003), QTMFLLD(-3.0657128082e-004),
+ QTMFLLD(-9.5560895279e-003), QTMFLLD(-5.4356725886e-003),
+ QTMFLLD(-6.7361742258e-001), QTMFLLD(-4.3653072789e-003),
+ QTMFLLD(-1.8451632059e-004), QTMFLLD(-9.3438196927e-003),
+ QTMFLLD(3.5346730147e-003), QTMFLLD(-6.6160440445e-001),
+ QTMFLLD(-3.8251809310e-003), QTMFLLD(-6.0027297877e-005),
+ QTMFLLD(-9.1004446149e-003), QTMFLLD(1.2770005502e-002),
+ QTMFLLD(-6.4946544170e-001), QTMFLLD(-3.3147553913e-003),
+ QTMFLLD(6.6618180426e-005), QTMFLLD(-8.8245263323e-003),
+ QTMFLLD(2.2267201915e-002), QTMFLLD(-6.3721030951e-001),
+ QTMFLLD(-2.8387091588e-003), QTMFLLD(1.9518326735e-004),
+ QTMFLLD(-8.5145104676e-003), QTMFLLD(3.2023012638e-002),
+ QTMFLLD(-6.2485051155e-001), QTMFLLD(-2.3975048680e-003),
+ QTMFLLD(3.2545044087e-004), QTMFLLD(-8.1687811762e-003),
+ QTMFLLD(4.2033810169e-002), QTMFLLD(-6.1239802837e-001),
+ QTMFLLD(-1.9807203207e-003), QTMFLLD(4.5712510473e-004),
+ QTMFLLD(-7.7859172598e-003), QTMFLLD(5.2295893431e-002),
+ QTMFLLD(-5.9986191988e-001), QTMFLLD(-1.6010539839e-003),
+ QTMFLLD(5.9015140869e-004), QTMFLLD(-7.3645371012e-003),
+ QTMFLLD(6.2805138528e-002), QTMFLLD(-5.8725595474e-001),
+ QTMFLLD(-1.2320743408e-003), QTMFLLD(7.2508689482e-004),
+ QTMFLLD(-6.9030462764e-003), QTMFLLD(7.3557935655e-002),
+ QTMFLLD(-5.7460016012e-001), QTMFLLD(-7.9492607620e-004)};
+
+//@{
+/*!
+ \name DCT_II twiddle factors, L=64
+*/
+/*! sin (3.14159265358979323 / (2*L) * n) , L=64*/
+LNK_SECTION_CONSTDATA
+RAM_ALIGN
+const FIXP_WTP sin_twiddle_L64[] = {
+ WTCP(0x7fffffff, 0x00000000), WTCP(0x7ff62182, 0x03242abf),
+ WTCP(0x7fd8878e, 0x0647d97c), WTCP(0x7fa736b4, 0x096a9049),
+ WTCP(0x7f62368f, 0x0c8bd35e), WTCP(0x7f0991c4, 0x0fab272b),
+ WTCP(0x7e9d55fc, 0x12c8106f), WTCP(0x7e1d93ea, 0x15e21445),
+ WTCP(0x7d8a5f40, 0x18f8b83c), WTCP(0x7ce3ceb2, 0x1c0b826a),
+ WTCP(0x7c29fbee, 0x1f19f97b), WTCP(0x7b5d039e, 0x2223a4c5),
+ WTCP(0x7a7d055b, 0x25280c5e), WTCP(0x798a23b1, 0x2826b928),
+ WTCP(0x78848414, 0x2b1f34eb), WTCP(0x776c4edb, 0x2e110a62),
+ WTCP(0x7641af3d, 0x30fbc54d), WTCP(0x7504d345, 0x33def287),
+ WTCP(0x73b5ebd1, 0x36ba2014), WTCP(0x72552c85, 0x398cdd32),
+ WTCP(0x70e2cbc6, 0x3c56ba70), WTCP(0x6f5f02b2, 0x3f1749b8),
+ WTCP(0x6dca0d14, 0x41ce1e65), WTCP(0x6c242960, 0x447acd50),
+ WTCP(0x6a6d98a4, 0x471cece7), WTCP(0x68a69e81, 0x49b41533),
+ WTCP(0x66cf8120, 0x4c3fdff4), WTCP(0x64e88926, 0x4ebfe8a5),
+ WTCP(0x62f201ac, 0x5133cc94), WTCP(0x60ec3830, 0x539b2af0),
+ WTCP(0x5ed77c8a, 0x55f5a4d2), WTCP(0x5cb420e0, 0x5842dd54),
+ WTCP(0x5a82799a, 0x5a82799a), WTCP(0x5842dd54, 0x5cb420e0),
+ WTCP(0x55f5a4d2, 0x5ed77c8a), WTCP(0x539b2af0, 0x60ec3830),
+ WTCP(0x5133cc94, 0x62f201ac), WTCP(0x4ebfe8a5, 0x64e88926),
+ WTCP(0x4c3fdff4, 0x66cf8120), WTCP(0x49b41533, 0x68a69e81),
+ WTCP(0x471cece7, 0x6a6d98a4), WTCP(0x447acd50, 0x6c242960),
+ WTCP(0x41ce1e65, 0x6dca0d14), WTCP(0x3f1749b8, 0x6f5f02b2),
+ WTCP(0x3c56ba70, 0x70e2cbc6), WTCP(0x398cdd32, 0x72552c85),
+ WTCP(0x36ba2014, 0x73b5ebd1), WTCP(0x33def287, 0x7504d345),
+ WTCP(0x30fbc54d, 0x7641af3d), WTCP(0x2e110a62, 0x776c4edb),
+ WTCP(0x2b1f34eb, 0x78848414), WTCP(0x2826b928, 0x798a23b1),
+ WTCP(0x25280c5e, 0x7a7d055b), WTCP(0x2223a4c5, 0x7b5d039e),
+ WTCP(0x1f19f97b, 0x7c29fbee), WTCP(0x1c0b826a, 0x7ce3ceb2),
+ WTCP(0x18f8b83c, 0x7d8a5f40), WTCP(0x15e21445, 0x7e1d93ea),
+ WTCP(0x12c8106f, 0x7e9d55fc), WTCP(0x0fab272b, 0x7f0991c4),
+ WTCP(0x0c8bd35e, 0x7f62368f), WTCP(0x096a9049, 0x7fa736b4),
+ WTCP(0x0647d97c, 0x7fd8878e), WTCP(0x03242abf, 0x7ff62182)};
+
+const USHORT sqrt_tab[49] = {
+ 0x5a82, 0x5d4b, 0x6000, 0x62a1, 0x6531, 0x67b1, 0x6a21, 0x6c84, 0x6ed9,
+ 0x7123, 0x7360, 0x7593, 0x77bb, 0x79da, 0x7bef, 0x7dfb, 0x8000, 0x81fc,
+ 0x83f0, 0x85dd, 0x87c3, 0x89a3, 0x8b7c, 0x8d4e, 0x8f1b, 0x90e2, 0x92a4,
+ 0x9460, 0x9617, 0x97ca, 0x9977, 0x9b20, 0x9cc4, 0x9e64, 0xa000, 0xa197,
+ 0xa32b, 0xa4ba, 0xa646, 0xa7cf, 0xa953, 0xaad5, 0xac53, 0xadcd, 0xaf45,
+ 0xb0b9, 0xb22b, 0xb399, 0xb504};
+
+LNK_SECTION_CONSTDATA_L1
+const FIXP_DBL invCount[80] = /* This could be 16-bit wide */
+ {0x00000000, 0x7fffffff, 0x40000000, 0x2aaaaaab, 0x20000000, 0x1999999a,
+ 0x15555555, 0x12492492, 0x10000000, 0x0e38e38e, 0x0ccccccd, 0x0ba2e8ba,
+ 0x0aaaaaab, 0x09d89d8a, 0x09249249, 0x08888889, 0x08000000, 0x07878788,
+ 0x071c71c7, 0x06bca1af, 0x06666666, 0x06186186, 0x05d1745d, 0x0590b216,
+ 0x05555555, 0x051eb852, 0x04ec4ec5, 0x04bda12f, 0x04924925, 0x0469ee58,
+ 0x04444444, 0x04210842, 0x04000000, 0x03e0f83e, 0x03c3c3c4, 0x03a83a84,
+ 0x038e38e4, 0x03759f23, 0x035e50d8, 0x03483483, 0x03333333, 0x031f3832,
+ 0x030c30c3, 0x02fa0be8, 0x02e8ba2f, 0x02d82d83, 0x02c8590b, 0x02b93105,
+ 0x02aaaaab, 0x029cbc15, 0x028f5c29, 0x02828283, 0x02762762, 0x026a439f,
+ 0x025ed098, 0x0253c825, 0x02492492, 0x023ee090, 0x0234f72c, 0x022b63cc,
+ 0x02222222, 0x02192e2a, 0x02108421, 0x02082082, 0x02000000, 0x01f81f82,
+ 0x01f07c1f, 0x01e9131b, 0x01e1e1e2, 0x01dae607, 0x01d41d42, 0x01cd8569,
+ 0x01c71c72, 0x01c0e070, 0x01bacf91, 0x01b4e81b, 0x01af286c, 0x01a98ef6,
+ 0x01a41a42, 0x019ec8e9};
+
+/*
+ * Bitstream data lists
+ */
+
+/*
+ * AOT {2,5,29}
+ * epConfig = -1
+ */
+
+static const rbd_id_t el_aac_sce[] = {
+ adtscrc_start_reg1, element_instance_tag, global_gain, ics_info,
+ section_data, scale_factor_data, pulse, tns_data_present, tns_data,
+ gain_control_data_present,
+ /* gain_control_data, */
+ spectral_data, adtscrc_end_reg1, end_of_sequence};
+
+static const struct element_list node_aac_sce = {el_aac_sce, {NULL, NULL}};
+
+/* CCE */
+static const rbd_id_t el_aac_cce[] = {
+ adtscrc_start_reg1, element_instance_tag,
+ coupled_elements, /* CCE specific */
+ global_gain, ics_info, section_data, scale_factor_data, pulse,
+ tns_data_present, tns_data, gain_control_data_present,
+ /* gain_control_data, */
+ spectral_data, gain_element_lists, /* CCE specific */
+ adtscrc_end_reg1, end_of_sequence};
+
+static const struct element_list node_aac_cce = {el_aac_cce, {NULL, NULL}};
+
+static const rbd_id_t el_aac_cpe[] = {adtscrc_start_reg1, element_instance_tag,
+ common_window, link_sequence};
+
+static const rbd_id_t el_aac_cpe0[] = {
+ /*common_window = 0*/
+ global_gain, ics_info, section_data, scale_factor_data, pulse,
+ tns_data_present, tns_data, gain_control_data_present,
+ /*gain_control_data,*/
+ spectral_data, next_channel,
+
+ adtscrc_start_reg2, global_gain, ics_info, section_data, scale_factor_data,
+ pulse, tns_data_present, tns_data, gain_control_data_present,
+ /*gain_control_data,*/
+ spectral_data, adtscrc_end_reg1, adtscrc_end_reg2, end_of_sequence};
+
+static const rbd_id_t el_aac_cpe1[] = {
+ /* common_window = 1 */
+ ics_info, ms,
+
+ global_gain, section_data, scale_factor_data, pulse, tns_data_present,
+ tns_data, gain_control_data_present,
+ /*gain_control_data,*/
+ spectral_data, next_channel,
+
+ adtscrc_start_reg2, global_gain, section_data, scale_factor_data, pulse,
+ tns_data_present, tns_data, gain_control_data_present,
+ /*gain_control_data,*/
+ spectral_data, adtscrc_end_reg1, adtscrc_end_reg2, end_of_sequence};
+
+static const struct element_list node_aac_cpe0 = {el_aac_cpe0, {NULL, NULL}};
+
+static const struct element_list node_aac_cpe1 = {el_aac_cpe1, {NULL, NULL}};
+
+static const element_list_t node_aac_cpe = {el_aac_cpe,
+ {&node_aac_cpe0, &node_aac_cpe1}};
+
+/*
+ * AOT C- {17,23}
+ * epConfig = 0,1
+ */
+static const rbd_id_t el_aac_sce_epc0[] = {
+ element_instance_tag,
+ global_gain,
+ ics_info,
+ section_data,
+ scale_factor_data,
+ pulse,
+ tns_data_present,
+ gain_control_data_present,
+ gain_control_data,
+ esc1_hcr, /*length_of_rvlc_escapes, length_of_rvlc_sf */
+ esc2_rvlc, /* rvlc_cod_sf, rvlc_esc_sf */
+ tns_data,
+ spectral_data,
+ end_of_sequence};
+
+static const struct element_list node_aac_sce_epc0 = {el_aac_sce_epc0,
+ {NULL, NULL}};
+
+static const rbd_id_t el_aac_sce_epc1[] = {
+ element_instance_tag, global_gain, ics_info, section_data,
+ scale_factor_data, pulse, tns_data_present, gain_control_data_present,
+ /*gain_control_data,*/
+ esc1_hcr, /*length_of_rvlc_escapes, length_of_rvlc_sf */
+ esc2_rvlc, /* rvlc_cod_sf, rvlc_esc_sf */
+ tns_data, spectral_data, end_of_sequence};
+
+static const struct element_list node_aac_sce_epc1 = {el_aac_sce_epc1,
+ {NULL, NULL}};
+
+static const rbd_id_t el_aac_cpe_epc0[] = {element_instance_tag, common_window,
+ link_sequence};
+
+static const rbd_id_t el_aac_cpe0_epc0[] = {
+ /* common_window = 0 */
+ /* ESC 1: */
+ global_gain, ics_info,
+ /* ltp_data_present,
+ ltp_data,
+ */
+ section_data, scale_factor_data, pulse, tns_data_present,
+ gain_control_data_present,
+ /*gain_control_data,*/
+ esc1_hcr, /*length_of_rvlc_escapes, length_of_rvlc_sf */
+ /* ESC 2: */
+ esc2_rvlc, /* rvlc_cod_sf, rvlc_esc_sf */
+ /* ESC 3: */
+ tns_data,
+ /* ESC 4: */
+ spectral_data, next_channel,
+
+ /* ESC 1: */
+ global_gain, ics_info,
+ /* ltp_data_present,
+ ltp_data,
+ */
+ section_data, scale_factor_data, pulse, tns_data_present,
+ gain_control_data_present,
+ /*gain_control_data,*/
+ esc1_hcr, /*length_of_rvlc_escapes, length_of_rvlc_sf */
+ /* ESC 2: */
+ esc2_rvlc, /* rvlc_cod_sf, rvlc_esc_sf */
+ /* ESC 3: */
+ tns_data,
+ /* ESC 4: */
+ spectral_data, end_of_sequence};
+
+static const rbd_id_t el_aac_cpe1_epc0[] = {
+ /* common_window = 1 */
+ /* ESC 0: */
+ ics_info,
+ /* ltp_data_present,
+ ltp_data,
+ next_channel,
+ ltp_data_present,
+ ltp_data,
+ next_channel,
+ */
+ ms,
+
+ /* ESC 1: */
+ global_gain, section_data, scale_factor_data, pulse, tns_data_present,
+ gain_control_data_present,
+ /*gain_control_data,*/
+ esc1_hcr, /* length_of_reordered_spectral_data, length_of_longest_codeword
+ */
+ /* ESC 2: */
+ esc2_rvlc, /* rvlc_cod_sf, rvlc_esc_sf */
+ /* ESC 3: */
+ tns_data,
+ /* ESC 4: */
+ spectral_data, next_channel,
+
+ /* ESC 1: */
+ global_gain, section_data, scale_factor_data, pulse, tns_data_present,
+ gain_control_data_present,
+ /*gain_control_data,*/
+ esc1_hcr, /* length_of_reordered_spectral_data, length_of_longest_codeword
+ */
+ /* ESC 2: */
+ esc2_rvlc, /* rvlc_cod_sf, rvlc_esc_sf */
+ /* ESC 3: */
+ tns_data,
+ /* ESC 4: */
+ spectral_data, end_of_sequence};
+
+static const struct element_list node_aac_cpe0_epc0 = {el_aac_cpe0_epc0,
+ {NULL, NULL}};
+
+static const struct element_list node_aac_cpe1_epc0 = {el_aac_cpe1_epc0,
+ {NULL, NULL}};
+
+static const element_list_t node_aac_cpe_epc0 = {
+ el_aac_cpe_epc0, {&node_aac_cpe0_epc0, &node_aac_cpe1_epc0}};
+
+static const rbd_id_t el_aac_cpe0_epc1[] = {
+ global_gain, ics_info, section_data, scale_factor_data, pulse,
+ tns_data_present, gain_control_data_present,
+ /*gain_control_data,*/
+ next_channel, global_gain, ics_info, section_data, scale_factor_data, pulse,
+ tns_data_present, gain_control_data_present,
+ /*gain_control_data,*/
+ next_channel, esc1_hcr, /*length_of_rvlc_escapes, length_of_rvlc_sf */
+ next_channel, esc1_hcr, /*length_of_rvlc_escapes, length_of_rvlc_sf */
+ next_channel, esc2_rvlc, /* rvlc_cod_sf, rvlc_esc_sf */
+ next_channel, esc2_rvlc, /* rvlc_cod_sf, rvlc_esc_sf */
+ next_channel, tns_data, next_channel, tns_data, next_channel, spectral_data,
+ next_channel, spectral_data, end_of_sequence};
+
+static const rbd_id_t el_aac_cpe1_epc1[] = {
+ ics_info, ms, ltp_data_present,
+ /* ltp_data, */
+ global_gain, section_data, scale_factor_data, pulse, tns_data_present,
+ gain_control_data_present,
+ /*gain_control_data,*/
+ next_channel,
+
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain, section_data, scale_factor_data, pulse, tns_data_present,
+ gain_control_data_present,
+ /*gain_control_data,*/
+ next_channel, esc1_hcr, /*length_of_rvlc_escapes, length_of_rvlc_sf */
+ next_channel, esc1_hcr, /*length_of_rvlc_escapes, length_of_rvlc_sf */
+ next_channel, esc2_rvlc, /* rvlc_cod_sf, rvlc_esc_sf */
+ next_channel, esc2_rvlc, /* rvlc_cod_sf, rvlc_esc_sf */
+
+ 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_aac_cpe0_epc1 = {el_aac_cpe0_epc1,
+ {NULL, NULL}};
+
+static const struct element_list node_aac_cpe1_epc1 = {el_aac_cpe1_epc1,
+ {NULL, NULL}};
+
+static const element_list_t node_aac_cpe_epc1 = {
+ el_aac_cpe, {&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)
+ */
+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
+ * epConfig = 0
+ */
+static const rbd_id_t el_eld_sce_epc0[] = {
+ global_gain, ics_info, section_data, scale_factor_data, tns_data_present,
+ tns_data, esc1_hcr, esc2_rvlc, spectral_data, end_of_sequence};
+
+static const struct element_list node_eld_sce_epc0 = {el_eld_sce_epc0,
+ {NULL, NULL}};
+
+#define node_eld_sce_epc1 node_eld_sce_epc0
+
+static const rbd_id_t el_eld_cpe_epc0[] = {ics_info, ms,
+ global_gain, section_data,
+ scale_factor_data, tns_data_present,
+ tns_data, esc1_hcr,
+ esc2_rvlc, spectral_data,
+ next_channel, global_gain,
+ section_data, scale_factor_data,
+ tns_data_present, tns_data,
+ esc1_hcr, esc2_rvlc,
+ spectral_data, end_of_sequence};
+
+static const rbd_id_t el_eld_cpe_epc1[] = {ics_info, ms,
+ global_gain, section_data,
+ scale_factor_data, tns_data_present,
+ next_channel, global_gain,
+ section_data, scale_factor_data,
+ tns_data_present, next_channel,
+ tns_data, next_channel,
+ tns_data, next_channel,
+ esc1_hcr, esc2_rvlc,
+ spectral_data, next_channel,
+ esc1_hcr, esc2_rvlc,
+ spectral_data, end_of_sequence};
+
+static const struct element_list node_eld_cpe_epc0 = {el_eld_cpe_epc0,
+ {NULL, NULL}};
+
+static const struct element_list node_eld_cpe_epc1 = {el_eld_cpe_epc1,
+ {NULL, NULL}};
+
+/*
+ * AOT = 42
+ * epConfig = 0
+ */
+
+static const rbd_id_t el_usac_coremode[] = {core_mode, next_channel,
+ link_sequence};
+
+static const rbd_id_t el_usac_sce0_epc0[] = {
+ tns_data_present,
+ /* fd_channel_stream */
+ global_gain, noise, ics_info, tw_data, scale_factor_data_usac, tns_data,
+ ac_spectral_data, fac_data, end_of_sequence};
+
+static const rbd_id_t el_usac_lfe_epc0[] = {
+ /* fd_channel_stream */
+ global_gain, ics_info, scale_factor_data_usac,
+ ac_spectral_data, fac_data, end_of_sequence};
+
+static const rbd_id_t el_usac_lpd_epc0[] = {lpd_channel_stream,
+ end_of_sequence};
+
+static const struct element_list node_usac_sce0_epc0 = {el_usac_sce0_epc0,
+ {NULL, NULL}};
+
+static const struct element_list node_usac_sce1_epc0 = {el_usac_lpd_epc0,
+ {NULL, NULL}};
+
+static const struct element_list node_usac_sce_epc0 = {
+ el_usac_coremode, {&node_usac_sce0_epc0, &node_usac_sce1_epc0}};
+
+static const rbd_id_t list_usac_cpe00_epc0[] = {tns_active, common_window,
+ link_sequence};
+
+static const rbd_id_t el_usac_common_tw[] = {common_tw, link_sequence};
+
+static const rbd_id_t list_usac_cpe0000_epc0[] = {
+ /* core_mode0 = 0 */
+ /* core_mode1 = 0 */
+ /* common_window = 0 */
+ /* common_tw = 0 */
+ tns_data_present_usac,
+ global_gain,
+ noise,
+ ics_info,
+ tw_data,
+ scale_factor_data_usac,
+ tns_data,
+ ac_spectral_data,
+ fac_data,
+ next_channel,
+ global_gain,
+ noise,
+ ics_info,
+ tw_data,
+ scale_factor_data_usac,
+ tns_data,
+ ac_spectral_data,
+ fac_data,
+ end_of_sequence};
+
+static const rbd_id_t list_usac_cpe0001_epc0[] = {
+ /*
+ core_mode0 = 0
+ core_mode1 = 0
+ common_window = 0
+ common_tw = 1
+ */
+ tw_data, tns_data_present_usac, global_gain, noise,
+ ics_info, scale_factor_data_usac, tns_data, ac_spectral_data,
+ fac_data, next_channel, global_gain, noise,
+ ics_info, scale_factor_data_usac, tns_data, ac_spectral_data,
+ fac_data, end_of_sequence};
+
+static const rbd_id_t list_usac_cpe001_epc0[] = {
+ /* core_mode0 = 0 */
+ /* core_mode1 = 0 */
+ /* common_window = 1 */
+ ics_info, common_max_sfb, ms, common_tw, link_sequence};
+
+static const rbd_id_t list_usac_cpe0010_epc0[] = {
+ /* core_mode0 = 0 */
+ /* core_mode1 = 0 */
+ /* common_window = 1 */
+ /* common_tw = 0 */
+ tns_data_present_usac,
+ global_gain,
+ noise,
+ tw_data,
+ scale_factor_data_usac,
+ tns_data,
+ ac_spectral_data,
+ fac_data,
+ next_channel,
+ global_gain,
+ noise,
+ tw_data,
+ scale_factor_data_usac,
+ tns_data,
+ ac_spectral_data,
+ fac_data,
+ end_of_sequence};
+
+static const rbd_id_t list_usac_cpe0011_epc0[] = {
+ /* core_mode0 = 0 */
+ /* core_mode1 = 0 */
+ /* common_window = 1 */
+ /* common_tw = 1 */
+ tw_data,
+ tns_data_present_usac,
+ global_gain,
+ noise,
+ scale_factor_data_usac,
+ tns_data,
+ ac_spectral_data,
+ fac_data,
+ next_channel,
+ global_gain,
+ noise,
+ scale_factor_data_usac,
+ tns_data,
+ ac_spectral_data,
+ fac_data,
+ end_of_sequence};
+
+static const rbd_id_t list_usac_cpe10_epc0[] = {
+ /* core_mode0 = 1 */
+ /* core_mode1 = 0 */
+ lpd_channel_stream,
+ next_channel,
+ tns_data_present,
+ global_gain,
+ noise,
+ ics_info,
+ tw_data,
+ scale_factor_data_usac,
+ tns_data,
+ ac_spectral_data,
+ fac_data,
+ end_of_sequence};
+
+static const rbd_id_t list_usac_cpe01_epc0[] = {
+ /* core_mode0 = 0 */
+ /* core_mode1 = 1 */
+ tns_data_present,
+ global_gain,
+ noise,
+ ics_info,
+ tw_data,
+ scale_factor_data_usac,
+ tns_data,
+ ac_spectral_data,
+ fac_data,
+ next_channel,
+ lpd_channel_stream,
+ end_of_sequence};
+
+static const rbd_id_t list_usac_cpe11_epc0[] = {
+ /* core_mode0 = 1 */
+ /* core_mode1 = 1 */
+ lpd_channel_stream, next_channel, lpd_channel_stream, end_of_sequence};
+
+static const struct element_list node_usac_cpe0000_epc0 = {
+ /* core_mode0 = 0 */
+ /* core_mode1 = 0 */
+ /* common_window = 0 */
+ /* common_tw = 0 */
+ list_usac_cpe0000_epc0,
+ {NULL, NULL}};
+
+static const struct element_list node_usac_cpe0010_epc0 = {
+ /* core_mode0 = 0 */
+ /* core_mode1 = 0 */
+ /* common_window = 1 */
+ /* common_tw = 0 */
+ list_usac_cpe0010_epc0,
+ {NULL, NULL}};
+
+static const struct element_list node_usac_cpe0001_epc0 = {
+ /* core_mode0 = 0 */
+ /* core_mode1 = 0 */
+ /* common_window = 0 */
+ /* common_tw = 1 */
+ list_usac_cpe0001_epc0,
+ {NULL, NULL}};
+
+static const struct element_list node_usac_cpe0011_epc0 = {
+ /* core_mode0 = 0 */
+ /* core_mode1 = 0 */
+ /* common_window = 1 */
+ /* common_tw = 1 */
+ list_usac_cpe0011_epc0,
+ {NULL, NULL}};
+
+static const struct element_list node_usac_cpe000_epc0 = {
+ /* core_mode0 = 0 */
+ /* core_mode1 = 0 */
+ /* common_window = 0 */
+ el_usac_common_tw,
+ {&node_usac_cpe0000_epc0, &node_usac_cpe0001_epc0}};
+
+static const struct element_list node_usac_cpe001_epc0 = {
+ list_usac_cpe001_epc0, {&node_usac_cpe0010_epc0, &node_usac_cpe0011_epc0}};
+
+static const struct element_list node_usac_cpe00_epc0 = {
+ /* core_mode0 = 0 */
+ /* core_mode1 = 0 */
+ list_usac_cpe00_epc0,
+ {&node_usac_cpe000_epc0, &node_usac_cpe001_epc0}};
+
+static const struct element_list node_usac_cpe10_epc0 = {
+ /* core_mode0 = 1 */
+ /* core_mode1 = 0 */
+ list_usac_cpe10_epc0,
+ {NULL, NULL}};
+
+static const struct element_list node_usac_cpe01_epc0 = {list_usac_cpe01_epc0,
+ {NULL, NULL}};
+
+static const struct element_list node_usac_cpe11_epc0 = {list_usac_cpe11_epc0,
+ {NULL, NULL}};
+
+static const struct element_list node_usac_cpe0_epc0 = {
+ /* core_mode0 = 0 */
+ el_usac_coremode,
+ {&node_usac_cpe00_epc0, &node_usac_cpe01_epc0}};
+
+static const struct element_list node_usac_cpe1_epc0 = {
+ /* core_mode0 = 1 */
+ el_usac_coremode,
+ {&node_usac_cpe10_epc0, &node_usac_cpe11_epc0}};
+
+static const struct element_list node_usac_cpe_epc0 = {
+ el_usac_coremode, {&node_usac_cpe0_epc0, &node_usac_cpe1_epc0}};
+
+static const struct element_list node_usac_lfe_epc0 = {el_usac_lfe_epc0,
+ {NULL, NULL}};
+
+const element_list_t *getBitstreamElementList(AUDIO_OBJECT_TYPE aot,
+ SCHAR epConfig, UCHAR nChannels,
+ UCHAR layer, UINT elFlags) {
+ switch (aot) {
+ case AOT_AAC_LC:
+ case AOT_SBR:
+ case AOT_PS:
+ case AOT_DABPLUS_AAC_LC:
+ case AOT_DABPLUS_SBR:
+ case AOT_DABPLUS_PS:
+ FDK_ASSERT(epConfig == -1);
+ if (elFlags & AC_EL_GA_CCE) {
+ return &node_aac_cce;
+ } else {
+ if (nChannels == 1) {
+ return &node_aac_sce;
+ } else {
+ return &node_aac_cpe;
+ }
+ }
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LD:
+ if (nChannels == 1) {
+ if (epConfig == 0) {
+ return &node_aac_sce_epc0;
+ } else {
+ return &node_aac_sce_epc1;
+ }
+ } else {
+ if (epConfig == 0)
+ return &node_aac_cpe_epc0;
+ else
+ return &node_aac_cpe_epc1;
+ }
+ case AOT_USAC:
+ if (elFlags & AC_EL_USAC_LFE) {
+ FDK_ASSERT(nChannels == 1);
+ return &node_usac_lfe_epc0;
+ }
+ if (nChannels == 1) {
+ return &node_usac_sce_epc0;
+ } else {
+ return &node_usac_cpe_epc0;
+ }
+ 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;
+ }
+ case AOT_ER_AAC_ELD:
+ if (nChannels == 1) {
+ if (epConfig <= 0)
+ return &node_eld_sce_epc0;
+ else
+ return &node_eld_sce_epc1;
+ } else {
+ if (epConfig <= 0)
+ return &node_eld_cpe_epc0;
+ else
+ return &node_eld_cpe_epc1;
+ }
+ case AOT_DRM_AAC:
+ case AOT_DRM_SBR:
+ case AOT_DRM_MPEG_PS:
+ case AOT_DRM_SURROUND:
+ FDK_ASSERT(epConfig == 1);
+ if (nChannels == 1) {
+ return &node_drm_sce;
+ } else {
+ return &node_drm_cpe;
+ }
+ default:
+ break;
+ }
+ return NULL;
+}
+
+/* Inverse square root table for operands running from 0.5 to ~1.0 */
+/* (INT) (0.5 + 1.0/sqrt((op)/FDKpow(2.0,31))); */
+/* Note: First value is rnot rounded for accuracy reasons */
+/* Implicit exponent is 1. */
+/* Examples: 0x5A82799A = invSqrtNorm2 (0x4000.0000), exp=1 */
+/* 0x5A82799A = invSqrtNorm2 (0x4000.0000), exp=1 */
+
+LNK_SECTION_CONSTDATA_L1
+const FIXP_DBL invSqrtTab[SQRT_VALUES] = {
+ 0x5A827999, 0x5A287E03, 0x59CF8CBC, 0x5977A0AC, 0x5920B4DF, 0x58CAC480,
+ 0x5875CADE, 0x5821C364, 0x57CEA99D, 0x577C7930, 0x572B2DE0, 0x56DAC38E,
+ 0x568B3632, 0x563C81E0, 0x55EEA2C4, 0x55A19522, 0x55555555, 0x5509DFD0,
+ 0x54BF311A, 0x547545D0, 0x542C1AA4, 0x53E3AC5B, 0x539BF7CD, 0x5354F9E7,
+ 0x530EAFA5, 0x52C91618, 0x52842A5F, 0x523FE9AC, 0x51FC5140, 0x51B95E6B,
+ 0x51770E8F, 0x51355F1A, 0x50F44D89, 0x50B3D768, 0x5073FA50, 0x5034B3E7,
+ 0x4FF601E0, 0x4FB7E1FA, 0x4F7A5202, 0x4F3D4FCF, 0x4F00D944, 0x4EC4EC4F,
+ 0x4E8986EA, 0x4E4EA718, 0x4E144AE9, 0x4DDA7073, 0x4DA115DA, 0x4D683948,
+ 0x4D2FD8F4, 0x4CF7F31B, 0x4CC08605, 0x4C899000, 0x4C530F65, 0x4C1D0294,
+ 0x4BE767F5, 0x4BB23DF9, 0x4B7D8317, 0x4B4935CF, 0x4B1554A6, 0x4AE1DE2A,
+ 0x4AAED0F0, 0x4A7C2B93, 0x4A49ECB3, 0x4A1812FA, 0x49E69D16, 0x49B589BB,
+ 0x4984D7A4, 0x49548592, 0x49249249, 0x48F4FC97, 0x48C5C34B, 0x4896E53D,
+ 0x48686148, 0x483A364D, 0x480C6332, 0x47DEE6E1, 0x47B1C049, 0x4784EE60,
+ 0x4758701C, 0x472C447C, 0x47006A81, 0x46D4E130, 0x46A9A794, 0x467EBCBA,
+ 0x46541FB4, 0x4629CF98, 0x45FFCB80, 0x45D6128A, 0x45ACA3D5, 0x45837E88,
+ 0x455AA1CB, 0x45320CC8, 0x4509BEB0, 0x44E1B6B4, 0x44B9F40B, 0x449275ED,
+ 0x446B3B96, 0x44444444, 0x441D8F3B, 0x43F71BBF, 0x43D0E917, 0x43AAF68F,
+ 0x43854374, 0x435FCF15, 0x433A98C6, 0x43159FDC, 0x42F0E3AE, 0x42CC6398,
+ 0x42A81EF6, 0x42841527, 0x4260458E, 0x423CAF8D, 0x4219528B, 0x41F62DF2,
+ 0x41D3412A, 0x41B08BA2, 0x418E0CC8, 0x416BC40D, 0x4149B0E5, 0x4127D2C3,
+ 0x41062920, 0x40E4B374, 0x40C3713B, 0x40A261EF, 0x40818512, 0x4060DA22,
+ 0x404060A1, 0x40201814, 0x40000000, 0x3FE017EC /* , 0x3FC05F61 */
+};
+
+/* number of channels of the formats */
+
+const INT format_nchan[FDK_NFORMATS + 9 - 2] = {
+ 0, /* any set-up, ChConfIdx = 0 */
+ 1, /* mono ChConfIdx = 1 */
+ 2, /* stereo ChConfIdx = 2 */
+ 3, /* 3/0.0 ChConfIdx = 3 */
+ 4, /* 3/1.0 ChConfIdx = 4 */
+ 5, /* 3/2.0 ChConfIdx = 5 */
+ 6, /* 5.1 ChConfIdx = 6 */
+ 8, /* 5/2.1 ALT ChConfIdx = 7 */
+ 0, /* Empty n.a. ChConfIdx = 8 */
+ 3, /* 2/1.0 ChConfIdx = 9 */
+ 4, /* 2/2.0 ChConfIdx = 10 */
+ 7, /* 3/3.1 ChConfIdx = 11 */
+ 8, /* 3/4.1 ChConfIdx = 12 */
+ 24, /* 22.2 ChConfIdx = 13 */
+ 8, /* 5/2.1 ChConfIdx = 14 */
+ 12, /* 5/5.2 ChConfIdx = 15 */
+ 10, /* 5/4.1 ChConfIdx = 16 */
+ 12, /* 6/5.1 ChConfIdx = 17 */
+ 14, /* 6/7.1 ChConfIdx = 18 */
+ 12, /* 5/6.1 ChConfIdx = 19 */
+ 14 /* 7/6.1 ChConfIdx = 20 */
+};
diff --git a/fdk-aac/libFDK/src/FDK_trigFcts.cpp b/fdk-aac/libFDK/src/FDK_trigFcts.cpp
new file mode 100644
index 0000000..4bb6262
--- /dev/null
+++ b/fdk-aac/libFDK/src/FDK_trigFcts.cpp
@@ -0,0 +1,340 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Haricharan Lakshman, Manuel Jander
+
+ Description: Trigonometric functions fixed point fractional implementation.
+
+*******************************************************************************/
+
+#include "FDK_trigFcts.h"
+
+#include "fixpoint_math.h"
+
+#define IMPROVE_ATAN2_ACCURACY 1 /* 0 --> 59 dB SNR 1 --> 65 dB SNR */
+#define MINSFTAB 7
+#define MAXSFTAB 25
+
+#if IMPROVE_ATAN2_ACCURACY
+static const FIXP_DBL f_atan_expand_range[MAXSFTAB - (MINSFTAB - 1)] = {
+ /*****************************************************************************
+ *
+ * Table holds fixp_atan() output values which are outside of input range
+ * of fixp_atan() to improve SNR of fixp_atan2().
+ *
+ * This Table might also be used in fixp_atan() so there a wider input
+ * range can be covered, too.
+ *
+ *****************************************************************************/
+ FL2FXCONST_DBL(7.775862990872099e-001),
+ FL2FXCONST_DBL(7.814919928673978e-001),
+ FL2FXCONST_DBL(7.834450483314648e-001),
+ FL2FXCONST_DBL(7.844216021392089e-001),
+ FL2FXCONST_DBL(7.849098823026687e-001),
+ FL2FXCONST_DBL(7.851540227918509e-001),
+ FL2FXCONST_DBL(7.852760930873737e-001),
+ FL2FXCONST_DBL(7.853371282415015e-001),
+ FL2FXCONST_DBL(7.853676458193612e-001),
+ FL2FXCONST_DBL(7.853829046083906e-001),
+ FL2FXCONST_DBL(7.853905340029177e-001),
+ FL2FXCONST_DBL(7.853943487001828e-001),
+ FL2FXCONST_DBL(7.853962560488155e-001),
+ FL2FXCONST_DBL(7.853972097231319e-001),
+ FL2FXCONST_DBL(7.853976865602901e-001),
+ FL2FXCONST_DBL(7.853979249788692e-001),
+ FL2FXCONST_DBL(7.853980441881587e-001),
+ FL2FXCONST_DBL(7.853981037928035e-001),
+ FL2FXCONST_DBL(7.853981335951259e-001)
+ /* pi/4 = 0.785398163397448 = pi/2/ATO_SCALE */
+};
+#endif
+
+FIXP_DBL fixp_atan2(FIXP_DBL y, FIXP_DBL x) {
+ FIXP_DBL q;
+ FIXP_DBL at; /* atan out */
+ FIXP_DBL at2; /* atan2 out */
+ FIXP_DBL ret = FL2FXCONST_DBL(-1.0f);
+ INT sf, sfo, stf;
+
+ /* --- division */
+
+ if (y > FL2FXCONST_DBL(0.0f)) {
+ if (x > FL2FXCONST_DBL(0.0f)) {
+ q = fDivNormHighPrec(y, x, &sf); /* both pos. */
+ } else if (x < FL2FXCONST_DBL(0.0f)) {
+ q = -fDivNormHighPrec(y, -x, &sf); /* x neg. */
+ } else { /* (x == FL2FXCONST_DBL(0.0f)) */
+ q = FL2FXCONST_DBL(+1.0f); /* y/x = pos/zero = +Inf */
+ sf = 0;
+ }
+ } else if (y < FL2FXCONST_DBL(0.0f)) {
+ if (x > FL2FXCONST_DBL(0.0f)) {
+ q = -fDivNormHighPrec(-y, x, &sf); /* y neg. */
+ } else if (x < FL2FXCONST_DBL(0.0f)) {
+ q = fDivNormHighPrec(-y, -x, &sf); /* both neg. */
+ } else { /* (x == FL2FXCONST_DBL(0.0f)) */
+ q = FL2FXCONST_DBL(-1.0f); /* y/x = neg/zero = -Inf */
+ sf = 0;
+ }
+ } else { /* (y == FL2FXCONST_DBL(0.0f)) */
+ q = FL2FXCONST_DBL(0.0f);
+ sf = 0;
+ }
+ sfo = sf;
+
+ /* --- atan() */
+
+ if (sfo > ATI_SF) {
+ /* --- could not calc fixp_atan() here bec of input data out of range */
+ /* ==> therefore give back boundary values */
+
+#if IMPROVE_ATAN2_ACCURACY
+ if (sfo > MAXSFTAB) sfo = MAXSFTAB;
+#endif
+
+ if (q > FL2FXCONST_DBL(0.0f)) {
+#if IMPROVE_ATAN2_ACCURACY
+ at = +f_atan_expand_range[sfo - ATI_SF - 1];
+#else
+ at = FL2FXCONST_DBL(+M_PI / 2 / ATO_SCALE);
+#endif
+ } else if (q < FL2FXCONST_DBL(0.0f)) {
+#if IMPROVE_ATAN2_ACCURACY
+ at = -f_atan_expand_range[sfo - ATI_SF - 1];
+#else
+ at = FL2FXCONST_DBL(-M_PI / 2 / ATO_SCALE);
+#endif
+ } else { /* q == FL2FXCONST_DBL(0.0f) */
+ at = FL2FXCONST_DBL(0.0f);
+ }
+ } else {
+ /* --- calc of fixp_atan() is possible; input data within range */
+ /* ==> set q on fixed scale level as desired from fixp_atan() */
+ stf = sfo - ATI_SF;
+ if (stf > 0)
+ q = q << (INT)fMin(stf, DFRACT_BITS - 1);
+ else
+ q = q >> (INT)fMin(-stf, DFRACT_BITS - 1);
+ at = fixp_atan(q); /* ATO_SF */
+ }
+
+ // --- atan2()
+
+ at2 = at >> (AT2O_SF - ATO_SF); // now AT2O_SF for atan2
+ if (x > FL2FXCONST_DBL(0.0f)) {
+ ret = at2;
+ } else if (x < FL2FXCONST_DBL(0.0f)) {
+ if (y >= FL2FXCONST_DBL(0.0f)) {
+ ret = at2 + FL2FXCONST_DBL(M_PI / AT2O_SCALE);
+ } else {
+ ret = at2 - FL2FXCONST_DBL(M_PI / AT2O_SCALE);
+ }
+ } else {
+ // x == 0
+ if (y > FL2FXCONST_DBL(0.0f)) {
+ ret = FL2FXCONST_DBL(+M_PI / 2 / AT2O_SCALE);
+ } else if (y < FL2FXCONST_DBL(0.0f)) {
+ ret = FL2FXCONST_DBL(-M_PI / 2 / AT2O_SCALE);
+ } else if (y == FL2FXCONST_DBL(0.0f)) {
+ ret = FL2FXCONST_DBL(0.0f);
+ }
+ }
+ return ret;
+}
+
+FIXP_DBL fixp_atan(FIXP_DBL x) {
+ INT sign;
+ FIXP_DBL result, temp;
+
+ /* SNR of fixp_atan() = 56 dB */
+ FIXP_DBL P281 = (FIXP_DBL)0x00013000; // 0.281 in q18
+ FIXP_DBL ONEP571 = (FIXP_DBL)0x6487ef00; // 1.571 in q30
+
+ if (x < FIXP_DBL(0)) {
+ sign = 1;
+ x = -x;
+ } else {
+ sign = 0;
+ }
+ FDK_ASSERT(FL2FXCONST_DBL(1.0 / 64.0) == Q(Q_ATANINP));
+ /* calc of arctan */
+ if (x < FL2FXCONST_DBL(1.0 / 64.0))
+ /*
+ Chebyshev polynomial approximation of atan(x)
+ 5th-order approximation: atan(x) = a1*x + a2*x^3 + a3*x^5 = x(a1 + x^2*(a2 +
+ a3*x^2)); a1 = 0.9949493661166540f, a2 = 0.2870606355326520f, a3 =
+ 0.0780371764464410f; 7th-order approximation: atan(x) = a1*x + a2*x^3 +
+ a3*x^5 + a3*x^7 = x(a1 + x^2*(a2 + x^2*(a3 + a4*x^2))); a1 =
+ 0.9991334482227801, a2 = -0.3205332923816640, a3 = 0.1449824901444650, a4 =
+ -0.0382544649702990; 7th-order approximation in use (the most accurate
+ solution)
+ */
+ {
+ x <<= ATI_SF;
+ FIXP_DBL x2 = fPow2(x);
+ temp = fMultAddDiv2((FL2FXCONST_DBL(0.1449824901444650f) >> 1), x2,
+ FL2FXCONST_DBL(-0.0382544649702990));
+ temp = fMultAddDiv2((FL2FXCONST_DBL(-0.3205332923816640f) >> 2), x2, temp);
+ temp = fMultAddDiv2((FL2FXCONST_DBL(0.9991334482227801f) >> 3), x2, temp);
+ result = fMult(x, (temp << 2));
+ } else if (x < FL2FXCONST_DBL(1.28 / 64.0)) {
+ FIXP_DBL delta_fix;
+ FIXP_DBL PI_BY_4 = FL2FXCONST_DBL(3.1415926 / 4.0) >> 1; /* pi/4 in q30 */
+
+ delta_fix = (x - FL2FXCONST_DBL(1.0 / 64.0)) << 5; /* q30 */
+ result = PI_BY_4 + (delta_fix >> 1) - (fPow2Div2(delta_fix));
+ } else {
+ /* Other approximation for |x| > 1.28 */
+ INT res_e;
+
+ temp = fPow2Div2(x); /* q25 * q25 - (DFRACT_BITS-1) - 1 = q18 */
+ temp = temp + P281; /* q18 + q18 = q18 */
+ result = fDivNorm(x, temp, &res_e);
+ result = scaleValue(result,
+ (Q_ATANOUT - Q_ATANINP + 18 - DFRACT_BITS + 1) + res_e);
+ result = ONEP571 - result; /* q30 + q30 = q30 */
+ }
+ if (sign) {
+ result = -result;
+ }
+
+ return (result);
+}
+
+#include "FDK_tools_rom.h"
+
+FIXP_DBL fixp_cos(FIXP_DBL x, int scale) {
+ FIXP_DBL residual, error, sine, cosine;
+
+ residual = fixp_sin_cos_residual_inline(x, scale, &sine, &cosine);
+ error = fMult(sine, residual);
+
+#ifdef SINETABLE_16BIT
+ return cosine - error;
+#else
+ /* Undo downscaling by 1 which was done at fixp_sin_cos_residual_inline */
+ return SATURATE_LEFT_SHIFT(cosine - error, 1, DFRACT_BITS);
+#endif
+}
+
+FIXP_DBL fixp_sin(FIXP_DBL x, int scale) {
+ FIXP_DBL residual, error, sine, cosine;
+
+ residual = fixp_sin_cos_residual_inline(x, scale, &sine, &cosine);
+ error = fMult(cosine, residual);
+
+#ifdef SINETABLE_16BIT
+ return sine + error;
+#else
+ return SATURATE_LEFT_SHIFT(sine + error, 1, DFRACT_BITS);
+#endif
+}
+
+void fixp_cos_sin(FIXP_DBL x, int scale, FIXP_DBL *cos, FIXP_DBL *sin) {
+ FIXP_DBL residual, error0, error1, sine, cosine;
+
+ residual = fixp_sin_cos_residual_inline(x, scale, &sine, &cosine);
+ error0 = fMult(sine, residual);
+ error1 = fMult(cosine, residual);
+
+#ifdef SINETABLE_16BIT
+ *cos = cosine - error0;
+ *sin = sine + error1;
+#else
+ *cos = SATURATE_LEFT_SHIFT(cosine - error0, 1, DFRACT_BITS);
+ *sin = SATURATE_LEFT_SHIFT(sine + error1, 1, DFRACT_BITS);
+#endif
+}
diff --git a/fdk-aac/libFDK/src/arm/fft_rad2_arm.cpp b/fdk-aac/libFDK/src/arm/fft_rad2_arm.cpp
new file mode 100644
index 0000000..2c03b11
--- /dev/null
+++ b/fdk-aac/libFDK/src/arm/fft_rad2_arm.cpp
@@ -0,0 +1,321 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: dit_fft ARM assembler replacements.
+
+*******************************************************************************/
+
+#ifndef __FFT_RAD2_CPP__
+#error \
+ "Do not compile this file separately. It is included on demand from fft_rad2.cpp"
+#endif
+
+#ifndef FUNCTION_dit_fft
+#if defined(SINETABLE_16BIT)
+
+#define FUNCTION_dit_fft
+#if defined(FUNCTION_dit_fft)
+
+void dit_fft(FIXP_DBL *x, const INT ldn, const FIXP_STP *trigdata,
+ const INT trigDataSize) {
+ const INT n = 1 << ldn;
+ INT i;
+
+ scramble(x, n);
+ /*
+ * 1+2 stage radix 4
+ */
+
+ for (i = 0; i < n * 2; i += 8) {
+ FIXP_DBL a00, a10, a20, a30;
+ a00 = (x[i + 0] + x[i + 2]) >> 1; /* Re A + Re B */
+ a10 = (x[i + 4] + x[i + 6]) >> 1; /* Re C + Re D */
+ a20 = (x[i + 1] + x[i + 3]) >> 1; /* Im A + Im B */
+ a30 = (x[i + 5] + x[i + 7]) >> 1; /* Im C + Im D */
+
+ x[i + 0] = a00 + a10; /* Re A' = Re A + Re B + Re C + Re D */
+ x[i + 4] = a00 - a10; /* Re C' = Re A + Re B - Re C - Re D */
+ x[i + 1] = a20 + a30; /* Im A' = Im A + Im B + Im C + Im D */
+ x[i + 5] = a20 - a30; /* Im C' = Im A + Im B - Im C - Im D */
+
+ a00 = a00 - x[i + 2]; /* Re A - Re B */
+ a10 = a10 - x[i + 6]; /* Re C - Re D */
+ a20 = a20 - x[i + 3]; /* Im A - Im B */
+ a30 = a30 - x[i + 7]; /* Im C - Im D */
+
+ x[i + 2] = a00 + a30; /* Re B' = Re A - Re B + Im C - Im D */
+ x[i + 6] = a00 - a30; /* Re D' = Re A - Re B - Im C + Im D */
+ x[i + 3] = a20 - a10; /* Im B' = Im A - Im B - Re C + Re D */
+ x[i + 7] = a20 + a10; /* Im D' = Im A - Im B + Re C - Re D */
+ }
+
+ INT mh = 1 << 1;
+ INT ldm = ldn - 2;
+ INT trigstep = trigDataSize;
+
+ do {
+ const FIXP_STP *pTrigData = trigdata;
+ INT j;
+
+ mh <<= 1;
+ trigstep >>= 1;
+
+ FDK_ASSERT(trigstep > 0);
+
+ /* Do first iteration with c=1.0 and s=0.0 separately to avoid loosing to
+ much precision. Beware: The impact on the overal FFT precision is rather
+ large. */
+ {
+ FIXP_DBL *xt1 = x;
+ int r = n;
+
+ do {
+ FIXP_DBL *xt2 = xt1 + (mh << 1);
+ /*
+ FIXP_DBL *xt1 = x+ ((r)<<1);
+ FIXP_DBL *xt2 = xt1 + (mh<<1);
+ */
+ FIXP_DBL vr, vi, ur, ui;
+
+ // cplxMultDiv2(&vi, &vr, x[t2+1], x[t2], (FIXP_SGL)1.0, (FIXP_SGL)0.0);
+ vi = xt2[1] >> 1;
+ vr = xt2[0] >> 1;
+
+ ur = xt1[0] >> 1;
+ ui = xt1[1] >> 1;
+
+ xt1[0] = ur + vr;
+ xt1[1] = ui + vi;
+
+ xt2[0] = ur - vr;
+ xt2[1] = ui - vi;
+
+ xt1 += mh;
+ xt2 += mh;
+
+ // cplxMultDiv2(&vr, &vi, x[t2+1], x[t2], (FIXP_SGL)1.0, (FIXP_SGL)0.0);
+ vr = xt2[1] >> 1;
+ vi = xt2[0] >> 1;
+
+ ur = xt1[0] >> 1;
+ ui = xt1[1] >> 1;
+
+ xt1[0] = ur + vr;
+ xt1[1] = ui - vi;
+
+ xt2[0] = ur - vr;
+ xt2[1] = ui + vi;
+
+ xt1 = xt2 + mh;
+ } while ((r = r - (mh << 1)) != 0);
+ }
+ for (j = 4; j < mh; j += 4) {
+ FIXP_DBL *xt1 = x + (j >> 1);
+ FIXP_SPK cs;
+ int r = n;
+
+ pTrigData += trigstep;
+ cs = *pTrigData;
+
+ do {
+ FIXP_DBL *xt2 = xt1 + (mh << 1);
+ FIXP_DBL vr, vi, ur, ui;
+
+ cplxMultDiv2(&vi, &vr, xt2[1], xt2[0], cs);
+
+ ur = xt1[0] >> 1;
+ ui = xt1[1] >> 1;
+
+ xt1[0] = ur + vr;
+ xt1[1] = ui + vi;
+
+ xt2[0] = ur - vr;
+ xt2[1] = ui - vi;
+
+ xt1 += mh;
+ xt2 += mh;
+
+ cplxMultDiv2(&vr, &vi, xt2[1], xt2[0], cs);
+
+ ur = xt1[0] >> 1;
+ ui = xt1[1] >> 1;
+
+ xt1[0] = ur + vr;
+ xt1[1] = ui - vi;
+
+ xt2[0] = ur - vr;
+ xt2[1] = ui + vi;
+
+ /* Same as above but for t1,t2 with j>mh/4 and thus cs swapped */
+ xt1 = xt1 - (j);
+ xt2 = xt1 + (mh << 1);
+
+ cplxMultDiv2(&vi, &vr, xt2[0], xt2[1], cs);
+
+ ur = xt1[0] >> 1;
+ ui = xt1[1] >> 1;
+
+ xt1[0] = ur + vr;
+ xt1[1] = ui - vi;
+
+ xt2[0] = ur - vr;
+ xt2[1] = ui + vi;
+
+ xt1 += mh;
+ xt2 += mh;
+
+ cplxMultDiv2(&vr, &vi, xt2[0], xt2[1], cs);
+
+ ur = xt1[0] >> 1;
+ ui = xt1[1] >> 1;
+
+ xt1[0] = ur - vr;
+ xt1[1] = ui - vi;
+
+ xt2[0] = ur + vr;
+ xt2[1] = ui + vi;
+
+ xt1 = xt2 + (j);
+ } while ((r = r - (mh << 1)) != 0);
+ }
+ {
+ FIXP_DBL *xt1 = x + (mh >> 1);
+ int r = n;
+
+ do {
+ FIXP_DBL *xt2 = xt1 + (mh << 1);
+ FIXP_DBL vr, vi, ur, ui;
+
+ cplxMultDiv2(&vi, &vr, xt2[1], xt2[0], STC(0x5a82799a),
+ STC(0x5a82799a));
+
+ ur = xt1[0] >> 1;
+ ui = xt1[1] >> 1;
+
+ xt1[0] = ur + vr;
+ xt1[1] = ui + vi;
+
+ xt2[0] = ur - vr;
+ xt2[1] = ui - vi;
+
+ xt1 += mh;
+ xt2 += mh;
+
+ cplxMultDiv2(&vr, &vi, xt2[1], xt2[0], STC(0x5a82799a),
+ STC(0x5a82799a));
+
+ ur = xt1[0] >> 1;
+ ui = xt1[1] >> 1;
+
+ xt1[0] = ur + vr;
+ xt1[1] = ui - vi;
+
+ xt2[0] = ur - vr;
+ xt2[1] = ui + vi;
+
+ xt1 = xt2 + mh;
+ } while ((r = r - (mh << 1)) != 0);
+ }
+ } while (--ldm != 0);
+}
+
+#endif /* if defined(FUNCTION_dit_fft) */
+
+#endif /* if defined(SINETABLE_16BIT) */
+
+#endif /* ifndef FUNCTION_dit_fft */
diff --git a/fdk-aac/libFDK/src/arm/scale_arm.cpp b/fdk-aac/libFDK/src/arm/scale_arm.cpp
new file mode 100644
index 0000000..92c9edc
--- /dev/null
+++ b/fdk-aac/libFDK/src/arm/scale_arm.cpp
@@ -0,0 +1,174 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Arthur Tritthart
+
+ Description: Scaling operations for ARM
+
+*******************************************************************************/
+
+/* prevent multiple inclusion with re-definitions */
+#ifndef __INCLUDE_SCALE_ARM__
+#define __INCLUDE_SCALE_ARM__
+
+#if !defined(FUNCTION_scaleValuesWithFactor_DBL)
+#define FUNCTION_scaleValuesWithFactor_DBL
+SCALE_INLINE
+void scaleValuesWithFactor(FIXP_DBL *vector, FIXP_DBL factor, INT len,
+ INT scalefactor) {
+ /* This code combines the fMult with the scaling */
+ /* It performs a fMultDiv2 and increments shift by 1 */
+ int shift = scalefactor + 1;
+ FIXP_DBL *mySpec = vector;
+
+ shift = fixmin_I(shift, (INT)DFRACT_BITS - 1);
+
+ if (shift >= 0) {
+ for (int i = 0; i < (len >> 2); i++) {
+ FIXP_DBL tmp0 = mySpec[0];
+ FIXP_DBL tmp1 = mySpec[1];
+ FIXP_DBL tmp2 = mySpec[2];
+ FIXP_DBL tmp3 = mySpec[3];
+ tmp0 = fMultDiv2(tmp0, factor);
+ tmp1 = fMultDiv2(tmp1, factor);
+ tmp2 = fMultDiv2(tmp2, factor);
+ tmp3 = fMultDiv2(tmp3, factor);
+ tmp0 <<= shift;
+ tmp1 <<= shift;
+ tmp2 <<= shift;
+ tmp3 <<= shift;
+ *mySpec++ = tmp0;
+ *mySpec++ = tmp1;
+ *mySpec++ = tmp2;
+ *mySpec++ = tmp3;
+ }
+ for (int i = len & 3; i--;) {
+ FIXP_DBL tmp0 = mySpec[0];
+ tmp0 = fMultDiv2(tmp0, factor);
+ tmp0 <<= shift;
+ *mySpec++ = tmp0;
+ }
+ } else {
+ shift = -shift;
+ for (int i = 0; i < (len >> 2); i++) {
+ FIXP_DBL tmp0 = mySpec[0];
+ FIXP_DBL tmp1 = mySpec[1];
+ FIXP_DBL tmp2 = mySpec[2];
+ FIXP_DBL tmp3 = mySpec[3];
+ tmp0 = fMultDiv2(tmp0, factor);
+ tmp1 = fMultDiv2(tmp1, factor);
+ tmp2 = fMultDiv2(tmp2, factor);
+ tmp3 = fMultDiv2(tmp3, factor);
+ tmp0 >>= shift;
+ tmp1 >>= shift;
+ tmp2 >>= shift;
+ tmp3 >>= shift;
+ *mySpec++ = tmp0;
+ *mySpec++ = tmp1;
+ *mySpec++ = tmp2;
+ *mySpec++ = tmp3;
+ }
+ for (int i = len & 3; i--;) {
+ FIXP_DBL tmp0 = mySpec[0];
+ tmp0 = fMultDiv2(tmp0, factor);
+ tmp0 >>= shift;
+ *mySpec++ = tmp0;
+ }
+ }
+}
+#endif /* #if !defined(FUNCTION_scaleValuesWithFactor_DBL) */
+
+#endif /* #ifndef __INCLUDE_SCALE_ARM__ */
diff --git a/fdk-aac/libFDK/src/autocorr2nd.cpp b/fdk-aac/libFDK/src/autocorr2nd.cpp
new file mode 100644
index 0000000..718a555
--- /dev/null
+++ b/fdk-aac/libFDK/src/autocorr2nd.cpp
@@ -0,0 +1,293 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Lohwasser
+
+ Description: auto-correlation functions
+
+*******************************************************************************/
+
+#include "autocorr2nd.h"
+
+/* If the accumulator does not provide enough overflow bits,
+ products have to be shifted down in the autocorrelation below. */
+#define SHIFT_FACTOR (5)
+#define SHIFT >> (SHIFT_FACTOR)
+
+/*!
+ *
+ * \brief Calculate second order autocorrelation using 2 accumulators
+ *
+ */
+#if !defined(FUNCTION_autoCorr2nd_real)
+INT autoCorr2nd_real(
+ ACORR_COEFS *ac, /*!< Pointer to autocorrelation coeffs */
+ const FIXP_DBL *reBuffer, /*!< Pointer to to real part of input samples */
+ const int len /*!< Number input samples */
+) {
+ int j, autoCorrScaling, mScale;
+
+ FIXP_DBL accu1, accu2, accu3, accu4, accu5;
+
+ const FIXP_DBL *pReBuf;
+
+ const FIXP_DBL *realBuf = reBuffer;
+
+ /*
+ r11r,r22r
+ r01r,r12r
+ r02r
+ */
+ pReBuf = realBuf - 2;
+ accu5 = ((fMultDiv2(pReBuf[0], pReBuf[2]) + fMultDiv2(pReBuf[1], pReBuf[3]))
+ SHIFT);
+ pReBuf++;
+
+ /* len must be even */
+ accu1 = fPow2Div2(pReBuf[0]) SHIFT;
+ accu3 = fMultDiv2(pReBuf[0], pReBuf[1]) SHIFT;
+ pReBuf++;
+
+ for (j = (len - 2) >> 1; j != 0; j--, pReBuf += 2) {
+ accu1 += ((fPow2Div2(pReBuf[0]) + fPow2Div2(pReBuf[1])) SHIFT);
+
+ accu3 += ((fMultDiv2(pReBuf[0], pReBuf[1]) +
+ fMultDiv2(pReBuf[1], pReBuf[2])) SHIFT);
+
+ accu5 += ((fMultDiv2(pReBuf[0], pReBuf[2]) +
+ fMultDiv2(pReBuf[1], pReBuf[3])) SHIFT);
+ }
+
+ accu2 = (fPow2Div2(realBuf[-2]) SHIFT);
+ accu2 += accu1;
+
+ accu1 += (fPow2Div2(realBuf[len - 2]) SHIFT);
+
+ accu4 = (fMultDiv2(realBuf[-1], realBuf[-2]) SHIFT);
+ accu4 += accu3;
+
+ accu3 += (fMultDiv2(realBuf[len - 1], realBuf[len - 2]) SHIFT);
+
+ mScale = CntLeadingZeros(
+ (accu1 | accu2 | fAbs(accu3) | fAbs(accu4) | fAbs(accu5))) -
+ 1;
+ autoCorrScaling = mScale - 1 - SHIFT_FACTOR; /* -1 because of fMultDiv2*/
+
+ /* Scale to common scale factor */
+ ac->r11r = accu1 << mScale;
+ ac->r22r = accu2 << mScale;
+ ac->r01r = accu3 << mScale;
+ ac->r12r = accu4 << mScale;
+ ac->r02r = accu5 << mScale;
+
+ ac->det = (fMultDiv2(ac->r11r, ac->r22r) - fMultDiv2(ac->r12r, ac->r12r));
+ mScale = CountLeadingBits(fAbs(ac->det));
+
+ ac->det <<= mScale;
+ ac->det_scale = mScale - 1;
+
+ return autoCorrScaling;
+}
+#endif
+
+#if !defined(FUNCTION_autoCorr2nd_cplx)
+INT autoCorr2nd_cplx(
+ ACORR_COEFS *ac, /*!< Pointer to autocorrelation coeffs */
+ const FIXP_DBL *reBuffer, /*!< Pointer to real part of input samples */
+ const FIXP_DBL *imBuffer, /*!< Pointer to imag part of input samples */
+ const int len /*!< Number of input samples (should be smaller than 128) */
+) {
+ int j, autoCorrScaling, mScale, len_scale;
+
+ FIXP_DBL accu0, accu1, accu2, accu3, accu4, accu5, accu6, accu7, accu8;
+
+ const FIXP_DBL *pReBuf, *pImBuf;
+
+ const FIXP_DBL *realBuf = reBuffer;
+ const FIXP_DBL *imagBuf = imBuffer;
+
+ (len > 64) ? (len_scale = 6) : (len_scale = 5);
+ /*
+ r00r,
+ r11r,r22r
+ r01r,r12r
+ r01i,r12i
+ r02r,r02i
+ */
+ accu1 = accu3 = accu5 = accu7 = accu8 = FL2FXCONST_DBL(0.0f);
+
+ pReBuf = realBuf - 2, pImBuf = imagBuf - 2;
+ accu7 +=
+ ((fMultDiv2(pReBuf[2], pReBuf[0]) + fMultDiv2(pImBuf[2], pImBuf[0])) >>
+ len_scale);
+ accu8 +=
+ ((fMultDiv2(pImBuf[2], pReBuf[0]) - fMultDiv2(pReBuf[2], pImBuf[0])) >>
+ len_scale);
+
+ pReBuf = realBuf - 1, pImBuf = imagBuf - 1;
+ for (j = (len - 1); j != 0; j--, pReBuf++, pImBuf++) {
+ accu1 += ((fPow2Div2(pReBuf[0]) + fPow2Div2(pImBuf[0])) >> len_scale);
+ accu3 +=
+ ((fMultDiv2(pReBuf[0], pReBuf[1]) + fMultDiv2(pImBuf[0], pImBuf[1])) >>
+ len_scale);
+ accu5 +=
+ ((fMultDiv2(pImBuf[1], pReBuf[0]) - fMultDiv2(pReBuf[1], pImBuf[0])) >>
+ len_scale);
+ accu7 +=
+ ((fMultDiv2(pReBuf[2], pReBuf[0]) + fMultDiv2(pImBuf[2], pImBuf[0])) >>
+ len_scale);
+ accu8 +=
+ ((fMultDiv2(pImBuf[2], pReBuf[0]) - fMultDiv2(pReBuf[2], pImBuf[0])) >>
+ len_scale);
+ }
+
+ accu2 = ((fPow2Div2(realBuf[-2]) + fPow2Div2(imagBuf[-2])) >> len_scale);
+ accu2 += accu1;
+
+ accu1 += ((fPow2Div2(realBuf[len - 2]) + fPow2Div2(imagBuf[len - 2])) >>
+ len_scale);
+ accu0 = ((fPow2Div2(realBuf[len - 1]) + fPow2Div2(imagBuf[len - 1])) >>
+ len_scale) -
+ ((fPow2Div2(realBuf[-1]) + fPow2Div2(imagBuf[-1])) >> len_scale);
+ accu0 += accu1;
+
+ accu4 = ((fMultDiv2(realBuf[-1], realBuf[-2]) +
+ fMultDiv2(imagBuf[-1], imagBuf[-2])) >>
+ len_scale);
+ accu4 += accu3;
+
+ accu3 += ((fMultDiv2(realBuf[len - 1], realBuf[len - 2]) +
+ fMultDiv2(imagBuf[len - 1], imagBuf[len - 2])) >>
+ len_scale);
+
+ accu6 = ((fMultDiv2(imagBuf[-1], realBuf[-2]) -
+ fMultDiv2(realBuf[-1], imagBuf[-2])) >>
+ len_scale);
+ accu6 += accu5;
+
+ accu5 += ((fMultDiv2(imagBuf[len - 1], realBuf[len - 2]) -
+ fMultDiv2(realBuf[len - 1], imagBuf[len - 2])) >>
+ len_scale);
+
+ mScale =
+ CntLeadingZeros((accu0 | accu1 | accu2 | fAbs(accu3) | fAbs(accu4) |
+ fAbs(accu5) | fAbs(accu6) | fAbs(accu7) | fAbs(accu8))) -
+ 1;
+ autoCorrScaling = mScale - 1 - len_scale; /* -1 because of fMultDiv2*/
+
+ /* Scale to common scale factor */
+ ac->r00r = (FIXP_DBL)accu0 << mScale;
+ ac->r11r = (FIXP_DBL)accu1 << mScale;
+ ac->r22r = (FIXP_DBL)accu2 << mScale;
+ ac->r01r = (FIXP_DBL)accu3 << mScale;
+ ac->r12r = (FIXP_DBL)accu4 << mScale;
+ ac->r01i = (FIXP_DBL)accu5 << mScale;
+ ac->r12i = (FIXP_DBL)accu6 << mScale;
+ ac->r02r = (FIXP_DBL)accu7 << mScale;
+ ac->r02i = (FIXP_DBL)accu8 << mScale;
+
+ ac->det =
+ (fMultDiv2(ac->r11r, ac->r22r) >> 1) -
+ ((fMultDiv2(ac->r12r, ac->r12r) + fMultDiv2(ac->r12i, ac->r12i)) >> 1);
+ mScale = CntLeadingZeros(fAbs(ac->det)) - 1;
+
+ ac->det <<= mScale;
+ ac->det_scale = mScale - 2;
+
+ return autoCorrScaling;
+}
+
+#endif /* FUNCTION_autoCorr2nd_cplx */
diff --git a/fdk-aac/libFDK/src/dct.cpp b/fdk-aac/libFDK/src/dct.cpp
new file mode 100644
index 0000000..776493e
--- /dev/null
+++ b/fdk-aac/libFDK/src/dct.cpp
@@ -0,0 +1,568 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file dct.cpp
+ \brief DCT Implementations
+ Library functions to calculate standard DCTs. This will most likely be
+ replaced by hand-optimized functions for the specific target processor.
+
+ Three different implementations of the dct type II and the dct type III
+ transforms are provided.
+
+ By default implementations which are based on a single, standard complex
+ FFT-kernel are used (dctII_f() and dctIII_f()). These are specifically helpful
+ in cases where optimized FFT libraries are already available. The FFT used in
+ these implementation is FFT rad2 from FDK_tools.
+
+ Of course, one might also use DCT-libraries should they be available. The DCT
+ and DST type IV implementations are only available in a version based on a
+ complex FFT kernel.
+*/
+
+#include "dct.h"
+
+#include "FDK_tools_rom.h"
+#include "fft.h"
+
+void dct_getTables(const FIXP_WTP **ptwiddle, const FIXP_STP **sin_twiddle,
+ int *sin_step, int length) {
+ const FIXP_WTP *twiddle;
+ int ld2_length;
+
+ /* Get ld2 of length - 2 + 1
+ -2: because first table entry is window of size 4
+ +1: because we already include +1 because of ceil(log2(length)) */
+ ld2_length = DFRACT_BITS - 1 - fNormz((FIXP_DBL)length) - 1;
+
+ /* Extract sort of "eigenvalue" (the 4 left most bits) of length. */
+ switch ((length) >> (ld2_length - 1)) {
+ case 0x4: /* radix 2 */
+ *sin_twiddle = SineTable1024;
+ *sin_step = 1 << (10 - ld2_length);
+ twiddle = windowSlopes[0][0][ld2_length - 1];
+ break;
+ case 0x7: /* 10 ms */
+ *sin_twiddle = SineTable480;
+ *sin_step = 1 << (8 - ld2_length);
+ twiddle = windowSlopes[0][1][ld2_length];
+ break;
+ case 0x6: /* 3/4 of radix 2 */
+ *sin_twiddle = SineTable384;
+ *sin_step = 1 << (8 - ld2_length);
+ twiddle = windowSlopes[0][2][ld2_length];
+ break;
+ case 0x5: /* 5/16 of radix 2*/
+ *sin_twiddle = SineTable80;
+ *sin_step = 1 << (6 - ld2_length);
+ twiddle = windowSlopes[0][3][ld2_length];
+ break;
+ default:
+ *sin_twiddle = NULL;
+ *sin_step = 0;
+ twiddle = NULL;
+ break;
+ }
+
+ if (ptwiddle != NULL) {
+ FDK_ASSERT(twiddle != NULL);
+ *ptwiddle = twiddle;
+ }
+
+ FDK_ASSERT(*sin_step > 0);
+}
+
+#if !defined(FUNCTION_dct_III)
+void dct_III(FIXP_DBL *pDat, /*!< pointer to input/output */
+ FIXP_DBL *tmp, /*!< pointer to temporal working buffer */
+ int L, /*!< lenght of transform */
+ int *pDat_e) {
+ const FIXP_WTP *sin_twiddle;
+ int i;
+ FIXP_DBL xr, accu1, accu2;
+ int inc, index;
+ int M = L >> 1;
+
+ FDK_ASSERT(L % 4 == 0);
+ dct_getTables(NULL, &sin_twiddle, &inc, L);
+ inc >>= 1;
+
+ FIXP_DBL *pTmp_0 = &tmp[2];
+ FIXP_DBL *pTmp_1 = &tmp[(M - 1) * 2];
+
+ index = 4 * inc;
+
+ /* This loop performs multiplication for index i (i*inc) */
+ for (i = 1; i<M>> 1; i++, pTmp_0 += 2, pTmp_1 -= 2) {
+ FIXP_DBL accu3, accu4, accu5, accu6;
+
+ cplxMultDiv2(&accu2, &accu1, pDat[L - i], pDat[i], sin_twiddle[i * inc]);
+ cplxMultDiv2(&accu4, &accu3, pDat[M + i], pDat[M - i],
+ sin_twiddle[(M - i) * inc]);
+ accu3 >>= 1;
+ accu4 >>= 1;
+
+ /* This method is better for ARM926, that uses operand2 shifted right by 1
+ * always */
+ if (2 * i < (M / 2)) {
+ cplxMultDiv2(&accu6, &accu5, (accu3 - (accu1 >> 1)),
+ ((accu2 >> 1) + accu4), sin_twiddle[index]);
+ } else {
+ cplxMultDiv2(&accu6, &accu5, ((accu2 >> 1) + accu4),
+ (accu3 - (accu1 >> 1)), sin_twiddle[index]);
+ accu6 = -accu6;
+ }
+ xr = (accu1 >> 1) + accu3;
+ pTmp_0[0] = (xr >> 1) - accu5;
+ pTmp_1[0] = (xr >> 1) + accu5;
+
+ xr = (accu2 >> 1) - accu4;
+ pTmp_0[1] = (xr >> 1) - accu6;
+ pTmp_1[1] = -((xr >> 1) + accu6);
+
+ /* Create index helper variables for (4*i)*inc indexed equivalent values of
+ * short tables. */
+ if (2 * i < ((M / 2) - 1)) {
+ index += 4 * inc;
+ } else if (2 * i >= ((M / 2))) {
+ index -= 4 * inc;
+ }
+ }
+
+ xr = fMultDiv2(pDat[M], sin_twiddle[M * inc].v.re); /* cos((PI/(2*L))*M); */
+ tmp[0] = ((pDat[0] >> 1) + xr) >> 1;
+ tmp[1] = ((pDat[0] >> 1) - xr) >> 1;
+
+ cplxMultDiv2(&accu2, &accu1, pDat[L - (M / 2)], pDat[M / 2],
+ sin_twiddle[M * inc / 2]);
+ tmp[M] = accu1 >> 1;
+ tmp[M + 1] = accu2 >> 1;
+
+ /* dit_fft expects 1 bit scaled input values */
+ fft(M, tmp, pDat_e);
+
+ /* ARM926: 12 cycles per 2-iteration, no overhead code by compiler */
+ pTmp_1 = &tmp[L];
+ for (i = M >> 1; i--;) {
+ FIXP_DBL tmp1, tmp2, tmp3, tmp4;
+ tmp1 = *tmp++;
+ tmp2 = *tmp++;
+ tmp3 = *--pTmp_1;
+ tmp4 = *--pTmp_1;
+ *pDat++ = tmp1;
+ *pDat++ = tmp3;
+ *pDat++ = tmp2;
+ *pDat++ = tmp4;
+ }
+
+ *pDat_e += 2;
+}
+
+void dst_III(FIXP_DBL *pDat, /*!< pointer to input/output */
+ FIXP_DBL *tmp, /*!< pointer to temporal working buffer */
+ int L, /*!< lenght of transform */
+ int *pDat_e) {
+ int L2 = L >> 1;
+ int i;
+ FIXP_DBL t;
+
+ /* note: DCT III is reused here, direct DST III implementation might be more
+ * efficient */
+
+ /* mirror input */
+ for (i = 0; i < L2; i++) {
+ t = pDat[i];
+ pDat[i] = pDat[L - 1 - i];
+ pDat[L - 1 - i] = t;
+ }
+
+ /* DCT-III */
+ dct_III(pDat, tmp, L, pDat_e);
+
+ /* flip signs at odd indices */
+ for (i = 1; i < L; i += 2) pDat[i] = -pDat[i];
+}
+
+#endif
+
+#if !defined(FUNCTION_dct_II)
+void dct_II(
+ FIXP_DBL *pDat, /*!< pointer to input/output */
+ FIXP_DBL *tmp, /*!< pointer to temporal working buffer */
+ int L, /*!< lenght of transform (has to be a multiple of 8 (or 4 in case
+ DCT_II_L_MULTIPLE_OF_4_SUPPORT is defined) */
+ int *pDat_e) {
+ const FIXP_WTP *sin_twiddle;
+ FIXP_DBL accu1, accu2;
+ FIXP_DBL *pTmp_0, *pTmp_1;
+
+ int i;
+ int inc, index = 0;
+ int M = L >> 1;
+
+ FDK_ASSERT(L % 4 == 0);
+ dct_getTables(NULL, &sin_twiddle, &inc, L);
+ inc >>= 1;
+
+ {
+ for (i = 0; i < M; i++) {
+ tmp[i] = pDat[2 * i] >> 1; /* dit_fft expects 1 bit scaled input values */
+ tmp[L - 1 - i] =
+ pDat[2 * i + 1] >> 1; /* dit_fft expects 1 bit scaled input values */
+ }
+ }
+
+ fft(M, tmp, pDat_e);
+
+ pTmp_0 = &tmp[2];
+ pTmp_1 = &tmp[(M - 1) * 2];
+
+ index = inc * 4;
+
+ for (i = 1; i<M>> 1; i++, pTmp_0 += 2, pTmp_1 -= 2) {
+ FIXP_DBL a1, a2;
+ FIXP_DBL accu3, accu4;
+
+ a1 = ((pTmp_0[1] >> 1) + (pTmp_1[1] >> 1));
+ a2 = ((pTmp_1[0] >> 1) - (pTmp_0[0] >> 1));
+
+ if (2 * i < (M / 2)) {
+ cplxMultDiv2(&accu1, &accu2, a2, a1, sin_twiddle[index]);
+ } else {
+ cplxMultDiv2(&accu1, &accu2, a1, a2, sin_twiddle[index]);
+ accu1 = -accu1;
+ }
+ accu1 <<= 1;
+ accu2 <<= 1;
+
+ a1 = ((pTmp_0[0] >> 1) + (pTmp_1[0] >> 1));
+ a2 = ((pTmp_0[1] >> 1) - (pTmp_1[1] >> 1));
+
+ cplxMultDiv2(&accu3, &accu4, (a1 + accu2), -(accu1 + a2),
+ sin_twiddle[i * inc]);
+ pDat[L - i] = accu4;
+ pDat[i] = accu3;
+
+ cplxMultDiv2(&accu3, &accu4, (a1 - accu2), -(accu1 - a2),
+ sin_twiddle[(M - i) * inc]);
+ pDat[M + i] = accu4;
+ pDat[M - i] = accu3;
+
+ /* Create index helper variables for (4*i)*inc indexed equivalent values of
+ * short tables. */
+ if (2 * i < ((M / 2) - 1)) {
+ index += 4 * inc;
+ } else if (2 * i >= ((M / 2))) {
+ index -= 4 * inc;
+ }
+ }
+
+ cplxMultDiv2(&accu1, &accu2, tmp[M], tmp[M + 1], sin_twiddle[(M / 2) * inc]);
+ pDat[L - (M / 2)] = accu2;
+ pDat[M / 2] = accu1;
+
+ pDat[0] = (tmp[0] >> 1) + (tmp[1] >> 1);
+ pDat[M] = fMult(((tmp[0] >> 1) - (tmp[1] >> 1)),
+ sin_twiddle[M * inc].v.re); /* cos((PI/(2*L))*M); */
+
+ *pDat_e += 2;
+}
+#endif
+
+#if !defined(FUNCTION_dct_IV)
+
+void dct_IV(FIXP_DBL *pDat, int L, int *pDat_e) {
+ int sin_step = 0;
+ int M = L >> 1;
+
+ const FIXP_WTP *twiddle;
+ const FIXP_STP *sin_twiddle;
+
+ FDK_ASSERT(L >= 4);
+
+ FDK_ASSERT(L >= 4);
+
+ dct_getTables(&twiddle, &sin_twiddle, &sin_step, L);
+
+ {
+ FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
+ FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
+ int i;
+
+ /* 29 cycles on ARM926 */
+ for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) {
+ FIXP_DBL accu1, accu2, accu3, accu4;
+
+ accu1 = pDat_1[1];
+ accu2 = pDat_0[0];
+ accu3 = pDat_0[1];
+ accu4 = pDat_1[0];
+
+ cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
+ cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
+
+ pDat_0[0] = accu2 >> 1;
+ pDat_0[1] = accu1 >> 1;
+ pDat_1[0] = accu4 >> 1;
+ pDat_1[1] = -(accu3 >> 1);
+ }
+ if (M & 1) {
+ FIXP_DBL accu1, accu2;
+
+ accu1 = pDat_1[1];
+ accu2 = pDat_0[0];
+
+ cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
+
+ pDat_0[0] = accu2 >> 1;
+ pDat_0[1] = accu1 >> 1;
+ }
+ }
+
+ fft(M, pDat, pDat_e);
+
+ {
+ FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
+ FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
+ FIXP_DBL accu1, accu2, accu3, accu4;
+ int idx, i;
+
+ /* Sin and Cos values are 0.0f and 1.0f */
+ accu1 = pDat_1[0];
+ accu2 = pDat_1[1];
+
+ pDat_1[1] = -pDat_0[1];
+
+ /* 28 cycles for ARM926 */
+ for (idx = sin_step, i = 1; i<(M + 1)>> 1; i++, idx += sin_step) {
+ FIXP_STP twd = sin_twiddle[idx];
+ cplxMult(&accu3, &accu4, accu1, accu2, twd);
+ pDat_0[1] = accu3;
+ pDat_1[0] = accu4;
+
+ pDat_0 += 2;
+ pDat_1 -= 2;
+
+ cplxMult(&accu3, &accu4, pDat_0[1], pDat_0[0], twd);
+
+ accu1 = pDat_1[0];
+ accu2 = pDat_1[1];
+
+ pDat_1[1] = -accu3;
+ pDat_0[0] = accu4;
+ }
+
+ if ((M & 1) == 0) {
+ /* Last Sin and Cos value pair are the same */
+ accu1 = fMult(accu1, WTC(0x5a82799a));
+ accu2 = fMult(accu2, WTC(0x5a82799a));
+
+ pDat_1[0] = accu1 + accu2;
+ pDat_0[1] = accu1 - accu2;
+ }
+ }
+
+ /* Add twiddeling scale. */
+ *pDat_e += 2;
+}
+#endif /* defined (FUNCTION_dct_IV) */
+
+#if !defined(FUNCTION_dst_IV)
+void dst_IV(FIXP_DBL *pDat, int L, int *pDat_e) {
+ int sin_step = 0;
+ int M = L >> 1;
+
+ const FIXP_WTP *twiddle;
+ const FIXP_STP *sin_twiddle;
+
+ FDK_ASSERT(L >= 4);
+
+ FDK_ASSERT(L >= 4);
+
+ dct_getTables(&twiddle, &sin_twiddle, &sin_step, L);
+
+ {
+ FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
+ FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
+ int i;
+
+ /* 34 cycles on ARM926 */
+ for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) {
+ FIXP_DBL accu1, accu2, accu3, accu4;
+
+ accu1 = pDat_1[1];
+ accu2 = -pDat_0[0];
+ accu3 = pDat_0[1];
+ accu4 = -pDat_1[0];
+
+ cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
+ cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
+
+ pDat_0[0] = accu2 >> 1;
+ pDat_0[1] = accu1 >> 1;
+ pDat_1[0] = accu4 >> 1;
+ pDat_1[1] = -(accu3 >> 1);
+ }
+ if (M & 1) {
+ FIXP_DBL accu1, accu2;
+
+ accu1 = pDat_1[1];
+ accu2 = -pDat_0[0];
+
+ cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
+
+ pDat_0[0] = accu2 >> 1;
+ pDat_0[1] = accu1 >> 1;
+ }
+ }
+
+ fft(M, pDat, pDat_e);
+
+ {
+ FIXP_DBL *RESTRICT pDat_0;
+ FIXP_DBL *RESTRICT pDat_1;
+ FIXP_DBL accu1, accu2, accu3, accu4;
+ int idx, i;
+
+ pDat_0 = &pDat[0];
+ pDat_1 = &pDat[L - 2];
+
+ /* Sin and Cos values are 0.0f and 1.0f */
+ accu1 = pDat_1[0];
+ accu2 = pDat_1[1];
+
+ pDat_1[1] = -pDat_0[0];
+ pDat_0[0] = pDat_0[1];
+
+ for (idx = sin_step, i = 1; i<(M + 1)>> 1; i++, idx += sin_step) {
+ FIXP_STP twd = sin_twiddle[idx];
+
+ cplxMult(&accu3, &accu4, accu1, accu2, twd);
+ pDat_1[0] = -accu3;
+ pDat_0[1] = -accu4;
+
+ pDat_0 += 2;
+ pDat_1 -= 2;
+
+ cplxMult(&accu3, &accu4, pDat_0[1], pDat_0[0], twd);
+
+ accu1 = pDat_1[0];
+ accu2 = pDat_1[1];
+
+ pDat_0[0] = accu3;
+ pDat_1[1] = -accu4;
+ }
+
+ if ((M & 1) == 0) {
+ /* Last Sin and Cos value pair are the same */
+ accu1 = fMult(accu1, WTC(0x5a82799a));
+ accu2 = fMult(accu2, WTC(0x5a82799a));
+
+ pDat_0[1] = -accu1 - accu2;
+ pDat_1[0] = accu2 - accu1;
+ }
+ }
+
+ /* Add twiddeling scale. */
+ *pDat_e += 2;
+}
+#endif /* !defined(FUNCTION_dst_IV) */
diff --git a/fdk-aac/libFDK/src/fft.cpp b/fdk-aac/libFDK/src/fft.cpp
new file mode 100644
index 0000000..4e6fdd2
--- /dev/null
+++ b/fdk-aac/libFDK/src/fft.cpp
@@ -0,0 +1,1922 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Josef Hoepfl, DSP Solutions
+
+ Description: Fix point FFT
+
+*******************************************************************************/
+
+#include "fft_rad2.h"
+#include "FDK_tools_rom.h"
+
+#define W_PiFOURTH STC(0x5a82799a)
+//#define W_PiFOURTH ((FIXP_DBL)(0x5a82799a))
+#ifndef SUMDIFF_PIFOURTH
+#define SUMDIFF_PIFOURTH(diff, sum, a, b) \
+ { \
+ FIXP_DBL wa, wb; \
+ wa = fMultDiv2(a, W_PiFOURTH); \
+ wb = fMultDiv2(b, W_PiFOURTH); \
+ diff = wb - wa; \
+ sum = wb + wa; \
+ }
+#define SUMDIFF_PIFOURTH16(diff, sum, a, b) \
+ { \
+ FIXP_SGL wa, wb; \
+ wa = FX_DBL2FX_SGL(fMultDiv2(a, W_PiFOURTH)); \
+ wb = FX_DBL2FX_SGL(fMultDiv2(b, W_PiFOURTH)); \
+ diff = wb - wa; \
+ sum = wb + wa; \
+ }
+#endif
+
+#define SCALEFACTOR2048 10
+#define SCALEFACTOR1024 9
+#define SCALEFACTOR512 8
+#define SCALEFACTOR256 7
+#define SCALEFACTOR128 6
+#define SCALEFACTOR64 5
+#define SCALEFACTOR32 4
+#define SCALEFACTOR16 3
+#define SCALEFACTOR8 2
+#define SCALEFACTOR4 1
+#define SCALEFACTOR2 1
+
+#define SCALEFACTOR3 1
+#define SCALEFACTOR5 1
+#define SCALEFACTOR6 (SCALEFACTOR2 + SCALEFACTOR3 + 2)
+#define SCALEFACTOR7 2
+#define SCALEFACTOR9 2
+#define SCALEFACTOR10 5
+#define SCALEFACTOR12 3
+#define SCALEFACTOR15 3
+#define SCALEFACTOR18 (SCALEFACTOR2 + SCALEFACTOR9 + 2)
+#define SCALEFACTOR20 (SCALEFACTOR4 + SCALEFACTOR5 + 2)
+#define SCALEFACTOR21 (SCALEFACTOR3 + SCALEFACTOR7 + 2)
+#define SCALEFACTOR24 (SCALEFACTOR2 + SCALEFACTOR12 + 2)
+#define SCALEFACTOR30 (SCALEFACTOR2 + SCALEFACTOR15 + 2)
+#define SCALEFACTOR40 (SCALEFACTOR5 + SCALEFACTOR8 + 2)
+#define SCALEFACTOR48 (SCALEFACTOR4 + SCALEFACTOR12 + 2)
+#define SCALEFACTOR60 (SCALEFACTOR4 + SCALEFACTOR15 + 2)
+#define SCALEFACTOR80 (SCALEFACTOR5 + SCALEFACTOR16 + 2)
+#define SCALEFACTOR96 (SCALEFACTOR3 + SCALEFACTOR32 + 2)
+#define SCALEFACTOR120 (SCALEFACTOR8 + SCALEFACTOR15 + 2)
+#define SCALEFACTOR160 (SCALEFACTOR10 + SCALEFACTOR16 + 2)
+#define SCALEFACTOR168 (SCALEFACTOR21 + SCALEFACTOR8 + 2)
+#define SCALEFACTOR192 (SCALEFACTOR12 + SCALEFACTOR16 + 2)
+#define SCALEFACTOR240 (SCALEFACTOR16 + SCALEFACTOR15 + 2)
+#define SCALEFACTOR320 (SCALEFACTOR10 + SCALEFACTOR32 + 2)
+#define SCALEFACTOR336 (SCALEFACTOR21 + SCALEFACTOR16 + 2)
+#define SCALEFACTOR384 (SCALEFACTOR12 + SCALEFACTOR32 + 2)
+#define SCALEFACTOR480 (SCALEFACTOR32 + SCALEFACTOR15 + 2)
+
+#include "fft.h"
+
+#ifndef FUNCTION_fft2
+
+/* Performs the FFT of length 2. Input vector unscaled, output vector scaled
+ * with factor 0.5 */
+static FDK_FORCEINLINE void fft2(FIXP_DBL *RESTRICT pDat) {
+ FIXP_DBL r1, i1;
+ FIXP_DBL r2, i2;
+
+ /* real part */
+ r1 = pDat[2];
+ r2 = pDat[0];
+
+ /* imaginary part */
+ i1 = pDat[3];
+ i2 = pDat[1];
+
+ /* real part */
+ pDat[0] = (r2 + r1) >> 1;
+ pDat[2] = (r2 - r1) >> 1;
+
+ /* imaginary part */
+ pDat[1] = (i2 + i1) >> 1;
+ pDat[3] = (i2 - i1) >> 1;
+}
+#endif /* FUNCTION_fft2 */
+
+#define C31 (STC(0x91261468)) /* FL2FXCONST_DBL(-0.86602540) = -sqrt(3)/2 */
+
+#ifndef FUNCTION_fft3
+/* Performs the FFT of length 3 according to the algorithm after winograd. */
+static FDK_FORCEINLINE void fft3(FIXP_DBL *RESTRICT pDat) {
+ FIXP_DBL r1, r2;
+ FIXP_DBL s1, s2;
+ FIXP_DBL pD;
+
+ /* real part */
+ r1 = pDat[2] + pDat[4];
+ r2 = fMultDiv2((pDat[2] - pDat[4]), C31);
+ pD = pDat[0] >> 1;
+ pDat[0] = pD + (r1 >> 1);
+ r1 = pD - (r1 >> 2);
+
+ /* imaginary part */
+ s1 = pDat[3] + pDat[5];
+ s2 = fMultDiv2((pDat[3] - pDat[5]), C31);
+ pD = pDat[1] >> 1;
+ pDat[1] = pD + (s1 >> 1);
+ s1 = pD - (s1 >> 2);
+
+ /* combination */
+ pDat[2] = r1 - s2;
+ pDat[4] = r1 + s2;
+ pDat[3] = s1 + r2;
+ pDat[5] = s1 - r2;
+}
+#endif /* #ifndef FUNCTION_fft3 */
+
+#define F5C(x) STC(x)
+
+#define C51 (F5C(0x79bc3854)) /* FL2FXCONST_DBL( 0.95105652) */
+#define C52 (F5C(0x9d839db0)) /* FL2FXCONST_DBL(-1.53884180/2) */
+#define C53 (F5C(0xd18053ce)) /* FL2FXCONST_DBL(-0.36327126) */
+#define C54 (F5C(0x478dde64)) /* FL2FXCONST_DBL( 0.55901699) */
+#define C55 (F5C(0xb0000001)) /* FL2FXCONST_DBL(-1.25/2) */
+
+/* performs the FFT of length 5 according to the algorithm after winograd */
+/* This version works with a prescale of 2 instead of 3 */
+static FDK_FORCEINLINE void fft5(FIXP_DBL *RESTRICT pDat) {
+ FIXP_DBL r1, r2, r3, r4;
+ FIXP_DBL s1, s2, s3, s4;
+ FIXP_DBL t;
+
+ /* real part */
+ r1 = (pDat[2] + pDat[8]) >> 1;
+ r4 = (pDat[2] - pDat[8]) >> 1;
+ r3 = (pDat[4] + pDat[6]) >> 1;
+ r2 = (pDat[4] - pDat[6]) >> 1;
+ t = fMult((r1 - r3), C54);
+ r1 = r1 + r3;
+ pDat[0] = (pDat[0] >> 1) + r1;
+ /* Bit shift left because of the constant C55 which was scaled with the factor
+ 0.5 because of the representation of the values as fracts */
+ r1 = pDat[0] + (fMultDiv2(r1, C55) << (2));
+ r3 = r1 - t;
+ r1 = r1 + t;
+ t = fMult((r4 + r2), C51);
+ /* Bit shift left because of the constant C55 which was scaled with the factor
+ 0.5 because of the representation of the values as fracts */
+ r4 = t + (fMultDiv2(r4, C52) << (2));
+ r2 = t + fMult(r2, C53);
+
+ /* imaginary part */
+ s1 = (pDat[3] + pDat[9]) >> 1;
+ s4 = (pDat[3] - pDat[9]) >> 1;
+ s3 = (pDat[5] + pDat[7]) >> 1;
+ s2 = (pDat[5] - pDat[7]) >> 1;
+ t = fMult((s1 - s3), C54);
+ s1 = s1 + s3;
+ pDat[1] = (pDat[1] >> 1) + s1;
+ /* Bit shift left because of the constant C55 which was scaled with the factor
+ 0.5 because of the representation of the values as fracts */
+ s1 = pDat[1] + (fMultDiv2(s1, C55) << (2));
+ s3 = s1 - t;
+ s1 = s1 + t;
+ t = fMult((s4 + s2), C51);
+ /* Bit shift left because of the constant C55 which was scaled with the factor
+ 0.5 because of the representation of the values as fracts */
+ s4 = t + (fMultDiv2(s4, C52) << (2));
+ s2 = t + fMult(s2, C53);
+
+ /* combination */
+ pDat[2] = r1 + s2;
+ pDat[8] = r1 - s2;
+ pDat[4] = r3 - s4;
+ pDat[6] = r3 + s4;
+
+ pDat[3] = s1 - r2;
+ pDat[9] = s1 + r2;
+ pDat[5] = s3 + r4;
+ pDat[7] = s3 - r4;
+}
+
+#define F5C(x) STC(x)
+
+#define C51 (F5C(0x79bc3854)) /* FL2FXCONST_DBL( 0.95105652) */
+#define C52 (F5C(0x9d839db0)) /* FL2FXCONST_DBL(-1.53884180/2) */
+#define C53 (F5C(0xd18053ce)) /* FL2FXCONST_DBL(-0.36327126) */
+#define C54 (F5C(0x478dde64)) /* FL2FXCONST_DBL( 0.55901699) */
+#define C55 (F5C(0xb0000001)) /* FL2FXCONST_DBL(-1.25/2) */
+/**
+ * \brief Function performs a complex 10-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR10 bits.
+ *
+ * WOPS FLC version: 1093 cycles
+ * WOPS with 32x16 bit multiplications: 196 cycles
+ *
+ * \param [i/o] re real input / output
+ * \param [i/o] im imag input / output
+ * \param [i ] s stride real and imag input / output
+ *
+ * \return void
+ */
+static void fft10(FIXP_DBL *x) // FIXP_DBL *re, FIXP_DBL *im, FIXP_SGL s)
+{
+ FIXP_DBL t;
+ FIXP_DBL x0, x1, x2, x3, x4;
+ FIXP_DBL r1, r2, r3, r4;
+ FIXP_DBL s1, s2, s3, s4;
+ FIXP_DBL y00, y01, y02, y03, y04, y05, y06, y07, y08, y09;
+ FIXP_DBL y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
+
+ const int s = 1; // stride factor
+
+ /* 2 fft5 stages */
+
+ /* real part */
+ x0 = (x[s * 0] >> SCALEFACTOR10);
+ x1 = (x[s * 4] >> SCALEFACTOR10);
+ x2 = (x[s * 8] >> SCALEFACTOR10);
+ x3 = (x[s * 12] >> SCALEFACTOR10);
+ x4 = (x[s * 16] >> SCALEFACTOR10);
+
+ r1 = (x3 + x2);
+ r4 = (x3 - x2);
+ r3 = (x1 + x4);
+ r2 = (x1 - x4);
+ t = fMult((r1 - r3), C54);
+ r1 = (r1 + r3);
+ y00 = (x0 + r1);
+ r1 = (y00 + ((fMult(r1, C55) << 1)));
+ r3 = (r1 - t);
+ r1 = (r1 + t);
+ t = fMult((r4 + r2), C51);
+ r4 = (t + (fMult(r4, C52) << 1));
+ r2 = (t + fMult(r2, C53));
+
+ /* imaginary part */
+ x0 = (x[s * 0 + 1] >> SCALEFACTOR10);
+ x1 = (x[s * 4 + 1] >> SCALEFACTOR10);
+ x2 = (x[s * 8 + 1] >> SCALEFACTOR10);
+ x3 = (x[s * 12 + 1] >> SCALEFACTOR10);
+ x4 = (x[s * 16 + 1] >> SCALEFACTOR10);
+
+ s1 = (x3 + x2);
+ s4 = (x3 - x2);
+ s3 = (x1 + x4);
+ s2 = (x1 - x4);
+ t = fMult((s1 - s3), C54);
+ s1 = (s1 + s3);
+ y01 = (x0 + s1);
+ s1 = (y01 + (fMult(s1, C55) << 1));
+ s3 = (s1 - t);
+ s1 = (s1 + t);
+ t = fMult((s4 + s2), C51);
+ s4 = (t + (fMult(s4, C52) << 1));
+ s2 = (t + fMult(s2, C53));
+
+ /* combination */
+ y04 = (r1 + s2);
+ y16 = (r1 - s2);
+ y08 = (r3 - s4);
+ y12 = (r3 + s4);
+
+ y05 = (s1 - r2);
+ y17 = (s1 + r2);
+ y09 = (s3 + r4);
+ y13 = (s3 - r4);
+
+ /* real part */
+ x0 = (x[s * 10] >> SCALEFACTOR10);
+ x1 = (x[s * 2] >> SCALEFACTOR10);
+ x2 = (x[s * 6] >> SCALEFACTOR10);
+ x3 = (x[s * 14] >> SCALEFACTOR10);
+ x4 = (x[s * 18] >> SCALEFACTOR10);
+
+ r1 = (x1 + x4);
+ r4 = (x1 - x4);
+ r3 = (x3 + x2);
+ r2 = (x3 - x2);
+ t = fMult((r1 - r3), C54);
+ r1 = (r1 + r3);
+ y02 = (x0 + r1);
+ r1 = (y02 + ((fMult(r1, C55) << 1)));
+ r3 = (r1 - t);
+ r1 = (r1 + t);
+ t = fMult(((r4 + r2)), C51);
+ r4 = (t + (fMult(r4, C52) << 1));
+ r2 = (t + fMult(r2, C53));
+
+ /* imaginary part */
+ x0 = (x[s * 10 + 1] >> SCALEFACTOR10);
+ x1 = (x[s * 2 + 1] >> SCALEFACTOR10);
+ x2 = (x[s * 6 + 1] >> SCALEFACTOR10);
+ x3 = (x[s * 14 + 1] >> SCALEFACTOR10);
+ x4 = (x[s * 18 + 1] >> SCALEFACTOR10);
+
+ s1 = (x1 + x4);
+ s4 = (x1 - x4);
+ s3 = (x3 + x2);
+ s2 = (x3 - x2);
+ t = fMult((s1 - s3), C54);
+ s1 = (s1 + s3);
+ y03 = (x0 + s1);
+ s1 = (y03 + (fMult(s1, C55) << 1));
+ s3 = (s1 - t);
+ s1 = (s1 + t);
+ t = fMult((s4 + s2), C51);
+ s4 = (t + (fMult(s4, C52) << 1));
+ s2 = (t + fMult(s2, C53));
+
+ /* combination */
+ y06 = (r1 + s2);
+ y18 = (r1 - s2);
+ y10 = (r3 - s4);
+ y14 = (r3 + s4);
+
+ y07 = (s1 - r2);
+ y19 = (s1 + r2);
+ y11 = (s3 + r4);
+ y15 = (s3 - r4);
+
+ /* 5 fft2 stages */
+ x[s * 0] = (y00 + y02);
+ x[s * 0 + 1] = (y01 + y03);
+ x[s * 10] = (y00 - y02);
+ x[s * 10 + 1] = (y01 - y03);
+
+ x[s * 4] = (y04 + y06);
+ x[s * 4 + 1] = (y05 + y07);
+ x[s * 14] = (y04 - y06);
+ x[s * 14 + 1] = (y05 - y07);
+
+ x[s * 8] = (y08 + y10);
+ x[s * 8 + 1] = (y09 + y11);
+ x[s * 18] = (y08 - y10);
+ x[s * 18 + 1] = (y09 - y11);
+
+ x[s * 12] = (y12 + y14);
+ x[s * 12 + 1] = (y13 + y15);
+ x[s * 2] = (y12 - y14);
+ x[s * 2 + 1] = (y13 - y15);
+
+ x[s * 16] = (y16 + y18);
+ x[s * 16 + 1] = (y17 + y19);
+ x[s * 6] = (y16 - y18);
+ x[s * 6 + 1] = (y17 - y19);
+}
+
+#ifndef FUNCTION_fft12
+#define FUNCTION_fft12
+
+#undef C31
+#define C31 (STC(0x91261468)) /* FL2FXCONST_DBL(-0.86602540) = -sqrt(3)/2 */
+
+static inline void fft12(FIXP_DBL *pInput) {
+ FIXP_DBL aDst[24];
+ FIXP_DBL *pSrc, *pDst;
+ int i;
+
+ pSrc = pInput;
+ pDst = aDst;
+ FIXP_DBL r1, r2, s1, s2, pD;
+
+ /* First 3*2 samples are shifted right by 2 before output */
+ r1 = pSrc[8] + pSrc[16];
+ r2 = fMultDiv2((pSrc[8] - pSrc[16]), C31);
+ pD = pSrc[0] >> 1;
+ pDst[0] = (pD + (r1 >> 1)) >> 1;
+ r1 = pD - (r1 >> 2);
+
+ /* imaginary part */
+ s1 = pSrc[9] + pSrc[17];
+ s2 = fMultDiv2((pSrc[9] - pSrc[17]), C31);
+ pD = pSrc[1] >> 1;
+ pDst[1] = (pD + (s1 >> 1)) >> 1;
+ s1 = pD - (s1 >> 2);
+
+ /* combination */
+ pDst[2] = (r1 - s2) >> 1;
+ pDst[3] = (s1 + r2) >> 1;
+ pDst[4] = (r1 + s2) >> 1;
+ pDst[5] = (s1 - r2) >> 1;
+ pSrc += 2;
+ pDst += 6;
+
+ const FIXP_STB *pVecRe = RotVectorReal12;
+ const FIXP_STB *pVecIm = RotVectorImag12;
+ FIXP_DBL re, im;
+ FIXP_STB vre, vim;
+ for (i = 0; i < 2; i++) {
+ /* sample 0,1 are shifted right by 2 before output */
+ /* sample 2,3 4,5 are shifted right by 1 and complex multiplied before
+ * output */
+
+ r1 = pSrc[8] + pSrc[16];
+ r2 = fMultDiv2((pSrc[8] - pSrc[16]), C31);
+ pD = pSrc[0] >> 1;
+ pDst[0] = (pD + (r1 >> 1)) >> 1;
+ r1 = pD - (r1 >> 2);
+
+ /* imaginary part */
+ s1 = pSrc[9] + pSrc[17];
+ s2 = fMultDiv2((pSrc[9] - pSrc[17]), C31);
+ pD = pSrc[1] >> 1;
+ pDst[1] = (pD + (s1 >> 1)) >> 1;
+ s1 = pD - (s1 >> 2);
+
+ /* combination */
+ re = (r1 - s2) >> 0;
+ im = (s1 + r2) >> 0;
+ vre = *pVecRe++;
+ vim = *pVecIm++;
+ cplxMultDiv2(&pDst[3], &pDst[2], im, re, vre, vim);
+
+ re = (r1 + s2) >> 0;
+ im = (s1 - r2) >> 0;
+ vre = *pVecRe++;
+ vim = *pVecIm++;
+ cplxMultDiv2(&pDst[5], &pDst[4], im, re, vre, vim);
+
+ pDst += 6;
+ pSrc += 2;
+ }
+ /* sample 0,1 are shifted right by 2 before output */
+ /* sample 2,3 is shifted right by 1 and complex multiplied with (0.0,+1.0) */
+ /* sample 4,5 is shifted right by 1 and complex multiplied with (-1.0,0.0) */
+ r1 = pSrc[8] + pSrc[16];
+ r2 = fMultDiv2((pSrc[8] - pSrc[16]), C31);
+ pD = pSrc[0] >> 1;
+ pDst[0] = (pD + (r1 >> 1)) >> 1;
+ r1 = pD - (r1 >> 2);
+
+ /* imaginary part */
+ s1 = pSrc[9] + pSrc[17];
+ s2 = fMultDiv2((pSrc[9] - pSrc[17]), C31);
+ pD = pSrc[1] >> 1;
+ pDst[1] = (pD + (s1 >> 1)) >> 1;
+ s1 = pD - (s1 >> 2);
+
+ /* combination */
+ pDst[2] = (s1 + r2) >> 1;
+ pDst[3] = (s2 - r1) >> 1;
+ pDst[4] = -((r1 + s2) >> 1);
+ pDst[5] = (r2 - s1) >> 1;
+
+ /* Perform 3 times the fft of length 4. The input samples are at the address
+ of aDst and the output samples are at the address of pInput. The input vector
+ for the fft of length 4 is built of the interleaved samples in aDst, the
+ output samples are stored consecutively at the address of pInput.
+ */
+ pSrc = aDst;
+ pDst = pInput;
+ for (i = 0; i < 3; i++) {
+ /* inline FFT4 merged with incoming resorting loop */
+ FIXP_DBL a00, a10, a20, a30, tmp0, tmp1;
+
+ a00 = (pSrc[0] + pSrc[12]) >> 1; /* Re A + Re B */
+ a10 = (pSrc[6] + pSrc[18]) >> 1; /* Re C + Re D */
+ a20 = (pSrc[1] + pSrc[13]) >> 1; /* Im A + Im B */
+ a30 = (pSrc[7] + pSrc[19]) >> 1; /* Im C + Im D */
+
+ pDst[0] = a00 + a10; /* Re A' = Re A + Re B + Re C + Re D */
+ pDst[1] = a20 + a30; /* Im A' = Im A + Im B + Im C + Im D */
+
+ tmp0 = a00 - pSrc[12]; /* Re A - Re B */
+ tmp1 = a20 - pSrc[13]; /* Im A - Im B */
+
+ pDst[12] = a00 - a10; /* Re C' = Re A + Re B - Re C - Re D */
+ pDst[13] = a20 - a30; /* Im C' = Im A + Im B - Im C - Im D */
+
+ a10 = a10 - pSrc[18]; /* Re C - Re D */
+ a30 = a30 - pSrc[19]; /* Im C - Im D */
+
+ pDst[6] = tmp0 + a30; /* Re B' = Re A - Re B + Im C - Im D */
+ pDst[18] = tmp0 - a30; /* Re D' = Re A - Re B - Im C + Im D */
+ pDst[7] = tmp1 - a10; /* Im B' = Im A - Im B - Re C + Re D */
+ pDst[19] = tmp1 + a10; /* Im D' = Im A - Im B + Re C - Re D */
+
+ pSrc += 2;
+ pDst += 2;
+ }
+}
+#endif /* FUNCTION_fft12 */
+
+#ifndef FUNCTION_fft15
+
+#define N3 3
+#define N5 5
+#define N6 6
+#define N15 15
+
+/* Performs the FFT of length 15. It is split into FFTs of length 3 and
+ * length 5. */
+static inline void fft15(FIXP_DBL *pInput) {
+ FIXP_DBL aDst[2 * N15];
+ FIXP_DBL aDst1[2 * N15];
+ int i, k, l;
+
+ /* Sort input vector for fft's of length 3
+ input3(0:2) = [input(0) input(5) input(10)];
+ input3(3:5) = [input(3) input(8) input(13)];
+ input3(6:8) = [input(6) input(11) input(1)];
+ input3(9:11) = [input(9) input(14) input(4)];
+ input3(12:14) = [input(12) input(2) input(7)]; */
+ {
+ const FIXP_DBL *pSrc = pInput;
+ FIXP_DBL *RESTRICT pDst = aDst;
+ /* Merge 3 loops into one, skip call of fft3 */
+ for (i = 0, l = 0, k = 0; i < N5; i++, k += 6) {
+ pDst[k + 0] = pSrc[l];
+ pDst[k + 1] = pSrc[l + 1];
+ l += 2 * N5;
+ if (l >= (2 * N15)) l -= (2 * N15);
+
+ pDst[k + 2] = pSrc[l];
+ pDst[k + 3] = pSrc[l + 1];
+ l += 2 * N5;
+ if (l >= (2 * N15)) l -= (2 * N15);
+ pDst[k + 4] = pSrc[l];
+ pDst[k + 5] = pSrc[l + 1];
+ l += (2 * N5) + (2 * N3);
+ if (l >= (2 * N15)) l -= (2 * N15);
+
+ /* fft3 merged with shift right by 2 loop */
+ FIXP_DBL r1, r2, r3;
+ FIXP_DBL s1, s2;
+ /* real part */
+ r1 = pDst[k + 2] + pDst[k + 4];
+ r2 = fMult((pDst[k + 2] - pDst[k + 4]), C31);
+ s1 = pDst[k + 0];
+ pDst[k + 0] = (s1 + r1) >> 2;
+ r1 = s1 - (r1 >> 1);
+
+ /* imaginary part */
+ s1 = pDst[k + 3] + pDst[k + 5];
+ s2 = fMult((pDst[k + 3] - pDst[k + 5]), C31);
+ r3 = pDst[k + 1];
+ pDst[k + 1] = (r3 + s1) >> 2;
+ s1 = r3 - (s1 >> 1);
+
+ /* combination */
+ pDst[k + 2] = (r1 - s2) >> 2;
+ pDst[k + 4] = (r1 + s2) >> 2;
+ pDst[k + 3] = (s1 + r2) >> 2;
+ pDst[k + 5] = (s1 - r2) >> 2;
+ }
+ }
+ /* Sort input vector for fft's of length 5
+ input5(0:4) = [output3(0) output3(3) output3(6) output3(9) output3(12)];
+ input5(5:9) = [output3(1) output3(4) output3(7) output3(10) output3(13)];
+ input5(10:14) = [output3(2) output3(5) output3(8) output3(11) output3(14)]; */
+ /* Merge 2 loops into one, brings about 10% */
+ {
+ const FIXP_DBL *pSrc = aDst;
+ FIXP_DBL *RESTRICT pDst = aDst1;
+ for (i = 0, l = 0, k = 0; i < N3; i++, k += 10) {
+ l = 2 * i;
+ pDst[k + 0] = pSrc[l + 0];
+ pDst[k + 1] = pSrc[l + 1];
+ pDst[k + 2] = pSrc[l + 0 + (2 * N3)];
+ pDst[k + 3] = pSrc[l + 1 + (2 * N3)];
+ pDst[k + 4] = pSrc[l + 0 + (4 * N3)];
+ pDst[k + 5] = pSrc[l + 1 + (4 * N3)];
+ pDst[k + 6] = pSrc[l + 0 + (6 * N3)];
+ pDst[k + 7] = pSrc[l + 1 + (6 * N3)];
+ pDst[k + 8] = pSrc[l + 0 + (8 * N3)];
+ pDst[k + 9] = pSrc[l + 1 + (8 * N3)];
+ fft5(&pDst[k]);
+ }
+ }
+ /* Sort output vector of length 15
+ output = [out5(0) out5(6) out5(12) out5(3) out5(9)
+ out5(10) out5(1) out5(7) out5(13) out5(4)
+ out5(5) out5(11) out5(2) out5(8) out5(14)]; */
+ /* optimize clumsy loop, brings about 5% */
+ {
+ const FIXP_DBL *pSrc = aDst1;
+ FIXP_DBL *RESTRICT pDst = pInput;
+ for (i = 0, l = 0, k = 0; i < N3; i++, k += 10) {
+ pDst[k + 0] = pSrc[l];
+ pDst[k + 1] = pSrc[l + 1];
+ l += (2 * N6);
+ if (l >= (2 * N15)) l -= (2 * N15);
+ pDst[k + 2] = pSrc[l];
+ pDst[k + 3] = pSrc[l + 1];
+ l += (2 * N6);
+ if (l >= (2 * N15)) l -= (2 * N15);
+ pDst[k + 4] = pSrc[l];
+ pDst[k + 5] = pSrc[l + 1];
+ l += (2 * N6);
+ if (l >= (2 * N15)) l -= (2 * N15);
+ pDst[k + 6] = pSrc[l];
+ pDst[k + 7] = pSrc[l + 1];
+ l += (2 * N6);
+ if (l >= (2 * N15)) l -= (2 * N15);
+ pDst[k + 8] = pSrc[l];
+ pDst[k + 9] = pSrc[l + 1];
+ l += 2; /* no modulo check needed, it cannot occur */
+ }
+ }
+}
+#endif /* FUNCTION_fft15 */
+
+/*
+ Select shift placement.
+ Some processors like ARM may shift "for free" in combination with an addition
+ or substraction, but others don't so either combining shift with +/- or reduce
+ the total amount or shift operations is optimal
+ */
+#if !defined(__arm__)
+#define SHIFT_A >> 1
+#define SHIFT_B
+#else
+#define SHIFT_A
+#define SHIFT_B >> 1
+#endif
+
+#ifndef FUNCTION_fft_16 /* we check, if fft_16 (FIXP_DBL *) is not yet defined \
+ */
+
+/* This defines prevents this array to be declared twice, if 16-bit fft is
+ * enabled too */
+#define FUNCTION_DATA_fft_16_w16
+static const FIXP_STP fft16_w16[2] = {STCP(0x7641af3d, 0x30fbc54d),
+ STCP(0x30fbc54d, 0x7641af3d)};
+
+LNK_SECTION_CODE_L1
+inline void fft_16(FIXP_DBL *RESTRICT x) {
+ FIXP_DBL vr, ur;
+ FIXP_DBL vr2, ur2;
+ FIXP_DBL vr3, ur3;
+ FIXP_DBL vr4, ur4;
+ FIXP_DBL vi, ui;
+ FIXP_DBL vi2, ui2;
+ FIXP_DBL vi3, ui3;
+
+ vr = (x[0] >> 1) + (x[16] >> 1); /* Re A + Re B */
+ ur = (x[1] >> 1) + (x[17] >> 1); /* Im A + Im B */
+ vi = (x[8] SHIFT_A) + (x[24] SHIFT_A); /* Re C + Re D */
+ ui = (x[9] SHIFT_A) + (x[25] SHIFT_A); /* Im C + Im D */
+ x[0] = vr + (vi SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[1] = ur + (ui SHIFT_B); /* Im A' = sum of imag values */
+
+ vr2 = (x[4] >> 1) + (x[20] >> 1); /* Re A + Re B */
+ ur2 = (x[5] >> 1) + (x[21] >> 1); /* Im A + Im B */
+
+ x[4] = vr - (vi SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[5] = ur - (ui SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+ vr -= x[16]; /* Re A - Re B */
+ vi = (vi SHIFT_B)-x[24]; /* Re C - Re D */
+ ur -= x[17]; /* Im A - Im B */
+ ui = (ui SHIFT_B)-x[25]; /* Im C - Im D */
+
+ vr3 = (x[2] >> 1) + (x[18] >> 1); /* Re A + Re B */
+ ur3 = (x[3] >> 1) + (x[19] >> 1); /* Im A + Im B */
+
+ x[2] = ui + vr; /* Re B' = Im C - Im D + Re A - Re B */
+ x[3] = ur - vi; /* Im B'= -Re C + Re D + Im A - Im B */
+
+ vr4 = (x[6] >> 1) + (x[22] >> 1); /* Re A + Re B */
+ ur4 = (x[7] >> 1) + (x[23] >> 1); /* Im A + Im B */
+
+ x[6] = vr - ui; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[7] = vi + ur; /* Im D'= Re C - Re D + Im A - Im B */
+
+ vi2 = (x[12] SHIFT_A) + (x[28] SHIFT_A); /* Re C + Re D */
+ ui2 = (x[13] SHIFT_A) + (x[29] SHIFT_A); /* Im C + Im D */
+ x[8] = vr2 + (vi2 SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[9] = ur2 + (ui2 SHIFT_B); /* Im A' = sum of imag values */
+ x[12] = vr2 - (vi2 SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[13] = ur2 - (ui2 SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+ vr2 -= x[20]; /* Re A - Re B */
+ ur2 -= x[21]; /* Im A - Im B */
+ vi2 = (vi2 SHIFT_B)-x[28]; /* Re C - Re D */
+ ui2 = (ui2 SHIFT_B)-x[29]; /* Im C - Im D */
+
+ vi = (x[10] SHIFT_A) + (x[26] SHIFT_A); /* Re C + Re D */
+ ui = (x[11] SHIFT_A) + (x[27] SHIFT_A); /* Im C + Im D */
+
+ x[10] = ui2 + vr2; /* Re B' = Im C - Im D + Re A - Re B */
+ x[11] = ur2 - vi2; /* Im B'= -Re C + Re D + Im A - Im B */
+
+ vi3 = (x[14] SHIFT_A) + (x[30] SHIFT_A); /* Re C + Re D */
+ ui3 = (x[15] SHIFT_A) + (x[31] SHIFT_A); /* Im C + Im D */
+
+ x[14] = vr2 - ui2; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[15] = vi2 + ur2; /* Im D'= Re C - Re D + Im A - Im B */
+
+ x[16] = vr3 + (vi SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[17] = ur3 + (ui SHIFT_B); /* Im A' = sum of imag values */
+ x[20] = vr3 - (vi SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[21] = ur3 - (ui SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+ vr3 -= x[18]; /* Re A - Re B */
+ ur3 -= x[19]; /* Im A - Im B */
+ vi = (vi SHIFT_B)-x[26]; /* Re C - Re D */
+ ui = (ui SHIFT_B)-x[27]; /* Im C - Im D */
+ x[18] = ui + vr3; /* Re B' = Im C - Im D + Re A - Re B */
+ x[19] = ur3 - vi; /* Im B'= -Re C + Re D + Im A - Im B */
+
+ x[24] = vr4 + (vi3 SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[28] = vr4 - (vi3 SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[25] = ur4 + (ui3 SHIFT_B); /* Im A' = sum of imag values */
+ x[29] = ur4 - (ui3 SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+ vr4 -= x[22]; /* Re A - Re B */
+ ur4 -= x[23]; /* Im A - Im B */
+
+ x[22] = vr3 - ui; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[23] = vi + ur3; /* Im D'= Re C - Re D + Im A - Im B */
+
+ vi3 = (vi3 SHIFT_B)-x[30]; /* Re C - Re D */
+ ui3 = (ui3 SHIFT_B)-x[31]; /* Im C - Im D */
+ x[26] = ui3 + vr4; /* Re B' = Im C - Im D + Re A - Re B */
+ x[30] = vr4 - ui3; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[27] = ur4 - vi3; /* Im B'= -Re C + Re D + Im A - Im B */
+ x[31] = vi3 + ur4; /* Im D'= Re C - Re D + Im A - Im B */
+
+ // xt1 = 0
+ // xt2 = 8
+ vr = x[8];
+ vi = x[9];
+ ur = x[0] >> 1;
+ ui = x[1] >> 1;
+ x[0] = ur + (vr >> 1);
+ x[1] = ui + (vi >> 1);
+ x[8] = ur - (vr >> 1);
+ x[9] = ui - (vi >> 1);
+
+ // xt1 = 4
+ // xt2 = 12
+ vr = x[13];
+ vi = x[12];
+ ur = x[4] >> 1;
+ ui = x[5] >> 1;
+ x[4] = ur + (vr >> 1);
+ x[5] = ui - (vi >> 1);
+ x[12] = ur - (vr >> 1);
+ x[13] = ui + (vi >> 1);
+
+ // xt1 = 16
+ // xt2 = 24
+ vr = x[24];
+ vi = x[25];
+ ur = x[16] >> 1;
+ ui = x[17] >> 1;
+ x[16] = ur + (vr >> 1);
+ x[17] = ui + (vi >> 1);
+ x[24] = ur - (vr >> 1);
+ x[25] = ui - (vi >> 1);
+
+ // xt1 = 20
+ // xt2 = 28
+ vr = x[29];
+ vi = x[28];
+ ur = x[20] >> 1;
+ ui = x[21] >> 1;
+ x[20] = ur + (vr >> 1);
+ x[21] = ui - (vi >> 1);
+ x[28] = ur - (vr >> 1);
+ x[29] = ui + (vi >> 1);
+
+ // xt1 = 2
+ // xt2 = 10
+ SUMDIFF_PIFOURTH(vi, vr, x[10], x[11])
+ // vr = fMultDiv2((x[11] + x[10]),W_PiFOURTH);
+ // vi = fMultDiv2((x[11] - x[10]),W_PiFOURTH);
+ ur = x[2];
+ ui = x[3];
+ x[2] = (ur >> 1) + vr;
+ x[3] = (ui >> 1) + vi;
+ x[10] = (ur >> 1) - vr;
+ x[11] = (ui >> 1) - vi;
+
+ // xt1 = 6
+ // xt2 = 14
+ SUMDIFF_PIFOURTH(vr, vi, x[14], x[15])
+ ur = x[6];
+ ui = x[7];
+ x[6] = (ur >> 1) + vr;
+ x[7] = (ui >> 1) - vi;
+ x[14] = (ur >> 1) - vr;
+ x[15] = (ui >> 1) + vi;
+
+ // xt1 = 18
+ // xt2 = 26
+ SUMDIFF_PIFOURTH(vi, vr, x[26], x[27])
+ ur = x[18];
+ ui = x[19];
+ x[18] = (ur >> 1) + vr;
+ x[19] = (ui >> 1) + vi;
+ x[26] = (ur >> 1) - vr;
+ x[27] = (ui >> 1) - vi;
+
+ // xt1 = 22
+ // xt2 = 30
+ SUMDIFF_PIFOURTH(vr, vi, x[30], x[31])
+ ur = x[22];
+ ui = x[23];
+ x[22] = (ur >> 1) + vr;
+ x[23] = (ui >> 1) - vi;
+ x[30] = (ur >> 1) - vr;
+ x[31] = (ui >> 1) + vi;
+
+ // xt1 = 0
+ // xt2 = 16
+ vr = x[16];
+ vi = x[17];
+ ur = x[0] >> 1;
+ ui = x[1] >> 1;
+ x[0] = ur + (vr >> 1);
+ x[1] = ui + (vi >> 1);
+ x[16] = ur - (vr >> 1);
+ x[17] = ui - (vi >> 1);
+
+ // xt1 = 8
+ // xt2 = 24
+ vi = x[24];
+ vr = x[25];
+ ur = x[8] >> 1;
+ ui = x[9] >> 1;
+ x[8] = ur + (vr >> 1);
+ x[9] = ui - (vi >> 1);
+ x[24] = ur - (vr >> 1);
+ x[25] = ui + (vi >> 1);
+
+ // xt1 = 2
+ // xt2 = 18
+ cplxMultDiv2(&vi, &vr, x[19], x[18], fft16_w16[0]);
+ ur = x[2];
+ ui = x[3];
+ x[2] = (ur >> 1) + vr;
+ x[3] = (ui >> 1) + vi;
+ x[18] = (ur >> 1) - vr;
+ x[19] = (ui >> 1) - vi;
+
+ // xt1 = 10
+ // xt2 = 26
+ cplxMultDiv2(&vr, &vi, x[27], x[26], fft16_w16[0]);
+ ur = x[10];
+ ui = x[11];
+ x[10] = (ur >> 1) + vr;
+ x[11] = (ui >> 1) - vi;
+ x[26] = (ur >> 1) - vr;
+ x[27] = (ui >> 1) + vi;
+
+ // xt1 = 4
+ // xt2 = 20
+ SUMDIFF_PIFOURTH(vi, vr, x[20], x[21])
+ ur = x[4];
+ ui = x[5];
+ x[4] = (ur >> 1) + vr;
+ x[5] = (ui >> 1) + vi;
+ x[20] = (ur >> 1) - vr;
+ x[21] = (ui >> 1) - vi;
+
+ // xt1 = 12
+ // xt2 = 28
+ SUMDIFF_PIFOURTH(vr, vi, x[28], x[29])
+ ur = x[12];
+ ui = x[13];
+ x[12] = (ur >> 1) + vr;
+ x[13] = (ui >> 1) - vi;
+ x[28] = (ur >> 1) - vr;
+ x[29] = (ui >> 1) + vi;
+
+ // xt1 = 6
+ // xt2 = 22
+ cplxMultDiv2(&vi, &vr, x[23], x[22], fft16_w16[1]);
+ ur = x[6];
+ ui = x[7];
+ x[6] = (ur >> 1) + vr;
+ x[7] = (ui >> 1) + vi;
+ x[22] = (ur >> 1) - vr;
+ x[23] = (ui >> 1) - vi;
+
+ // xt1 = 14
+ // xt2 = 30
+ cplxMultDiv2(&vr, &vi, x[31], x[30], fft16_w16[1]);
+ ur = x[14];
+ ui = x[15];
+ x[14] = (ur >> 1) + vr;
+ x[15] = (ui >> 1) - vi;
+ x[30] = (ur >> 1) - vr;
+ x[31] = (ui >> 1) + vi;
+}
+#endif /* FUNCTION_fft_16 */
+
+#ifndef FUNCTION_fft_32
+static const FIXP_STP fft32_w32[6] = {
+ STCP(0x7641af3d, 0x30fbc54d), STCP(0x30fbc54d, 0x7641af3d),
+ STCP(0x7d8a5f40, 0x18f8b83c), STCP(0x6a6d98a4, 0x471cece7),
+ STCP(0x471cece7, 0x6a6d98a4), STCP(0x18f8b83c, 0x7d8a5f40)};
+#define W_PiFOURTH STC(0x5a82799a)
+
+LNK_SECTION_CODE_L1
+inline void fft_32(FIXP_DBL *const _x) {
+ /*
+ * 1+2 stage radix 4
+ */
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ {
+ FIXP_DBL *const x = _x;
+ FIXP_DBL vi, ui;
+ FIXP_DBL vi2, ui2;
+ FIXP_DBL vi3, ui3;
+ FIXP_DBL vr, ur;
+ FIXP_DBL vr2, ur2;
+ FIXP_DBL vr3, ur3;
+ FIXP_DBL vr4, ur4;
+
+ // i = 0
+ vr = (x[0] + x[32]) >> 1; /* Re A + Re B */
+ ur = (x[1] + x[33]) >> 1; /* Im A + Im B */
+ vi = (x[16] + x[48]) SHIFT_A; /* Re C + Re D */
+ ui = (x[17] + x[49]) SHIFT_A; /* Im C + Im D */
+
+ x[0] = vr + (vi SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[1] = ur + (ui SHIFT_B); /* Im A' = sum of imag values */
+
+ vr2 = (x[4] + x[36]) >> 1; /* Re A + Re B */
+ ur2 = (x[5] + x[37]) >> 1; /* Im A + Im B */
+
+ x[4] = vr - (vi SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[5] = ur - (ui SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+
+ vr -= x[32]; /* Re A - Re B */
+ ur -= x[33]; /* Im A - Im B */
+ vi = (vi SHIFT_B)-x[48]; /* Re C - Re D */
+ ui = (ui SHIFT_B)-x[49]; /* Im C - Im D */
+
+ vr3 = (x[2] + x[34]) >> 1; /* Re A + Re B */
+ ur3 = (x[3] + x[35]) >> 1; /* Im A + Im B */
+
+ x[2] = ui + vr; /* Re B' = Im C - Im D + Re A - Re B */
+ x[3] = ur - vi; /* Im B'= -Re C + Re D + Im A - Im B */
+
+ vr4 = (x[6] + x[38]) >> 1; /* Re A + Re B */
+ ur4 = (x[7] + x[39]) >> 1; /* Im A + Im B */
+
+ x[6] = vr - ui; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[7] = vi + ur; /* Im D'= Re C - Re D + Im A - Im B */
+
+ // i=16
+ vi = (x[20] + x[52]) SHIFT_A; /* Re C + Re D */
+ ui = (x[21] + x[53]) SHIFT_A; /* Im C + Im D */
+
+ x[16] = vr2 + (vi SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[17] = ur2 + (ui SHIFT_B); /* Im A' = sum of imag values */
+ x[20] = vr2 - (vi SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[21] = ur2 - (ui SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+
+ vr2 -= x[36]; /* Re A - Re B */
+ ur2 -= x[37]; /* Im A - Im B */
+ vi = (vi SHIFT_B)-x[52]; /* Re C - Re D */
+ ui = (ui SHIFT_B)-x[53]; /* Im C - Im D */
+
+ vi2 = (x[18] + x[50]) SHIFT_A; /* Re C + Re D */
+ ui2 = (x[19] + x[51]) SHIFT_A; /* Im C + Im D */
+
+ x[18] = ui + vr2; /* Re B' = Im C - Im D + Re A - Re B */
+ x[19] = ur2 - vi; /* Im B'= -Re C + Re D + Im A - Im B */
+
+ vi3 = (x[22] + x[54]) SHIFT_A; /* Re C + Re D */
+ ui3 = (x[23] + x[55]) SHIFT_A; /* Im C + Im D */
+
+ x[22] = vr2 - ui; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[23] = vi + ur2; /* Im D'= Re C - Re D + Im A - Im B */
+
+ // i = 32
+
+ x[32] = vr3 + (vi2 SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[33] = ur3 + (ui2 SHIFT_B); /* Im A' = sum of imag values */
+ x[36] = vr3 - (vi2 SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[37] = ur3 - (ui2 SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+
+ vr3 -= x[34]; /* Re A - Re B */
+ ur3 -= x[35]; /* Im A - Im B */
+ vi2 = (vi2 SHIFT_B)-x[50]; /* Re C - Re D */
+ ui2 = (ui2 SHIFT_B)-x[51]; /* Im C - Im D */
+
+ x[34] = ui2 + vr3; /* Re B' = Im C - Im D + Re A - Re B */
+ x[35] = ur3 - vi2; /* Im B'= -Re C + Re D + Im A - Im B */
+
+ // i=48
+
+ x[48] = vr4 + (vi3 SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[52] = vr4 - (vi3 SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[49] = ur4 + (ui3 SHIFT_B); /* Im A' = sum of imag values */
+ x[53] = ur4 - (ui3 SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+
+ vr4 -= x[38]; /* Re A - Re B */
+ ur4 -= x[39]; /* Im A - Im B */
+
+ x[38] = vr3 - ui2; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[39] = vi2 + ur3; /* Im D'= Re C - Re D + Im A - Im B */
+
+ vi3 = (vi3 SHIFT_B)-x[54]; /* Re C - Re D */
+ ui3 = (ui3 SHIFT_B)-x[55]; /* Im C - Im D */
+
+ x[50] = ui3 + vr4; /* Re B' = Im C - Im D + Re A - Re B */
+ x[54] = vr4 - ui3; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[51] = ur4 - vi3; /* Im B'= -Re C + Re D + Im A - Im B */
+ x[55] = vi3 + ur4; /* Im D'= Re C - Re D + Im A - Im B */
+
+ // i=8
+ vr = (x[8] + x[40]) >> 1; /* Re A + Re B */
+ ur = (x[9] + x[41]) >> 1; /* Im A + Im B */
+ vi = (x[24] + x[56]) SHIFT_A; /* Re C + Re D */
+ ui = (x[25] + x[57]) SHIFT_A; /* Im C + Im D */
+
+ x[8] = vr + (vi SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[9] = ur + (ui SHIFT_B); /* Im A' = sum of imag values */
+
+ vr2 = (x[12] + x[44]) >> 1; /* Re A + Re B */
+ ur2 = (x[13] + x[45]) >> 1; /* Im A + Im B */
+
+ x[12] = vr - (vi SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[13] = ur - (ui SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+
+ vr -= x[40]; /* Re A - Re B */
+ ur -= x[41]; /* Im A - Im B */
+ vi = (vi SHIFT_B)-x[56]; /* Re C - Re D */
+ ui = (ui SHIFT_B)-x[57]; /* Im C - Im D */
+
+ vr3 = (x[10] + x[42]) >> 1; /* Re A + Re B */
+ ur3 = (x[11] + x[43]) >> 1; /* Im A + Im B */
+
+ x[10] = ui + vr; /* Re B' = Im C - Im D + Re A - Re B */
+ x[11] = ur - vi; /* Im B'= -Re C + Re D + Im A - Im B */
+
+ vr4 = (x[14] + x[46]) >> 1; /* Re A + Re B */
+ ur4 = (x[15] + x[47]) >> 1; /* Im A + Im B */
+
+ x[14] = vr - ui; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[15] = vi + ur; /* Im D'= Re C - Re D + Im A - Im B */
+
+ // i=24
+ vi = (x[28] + x[60]) SHIFT_A; /* Re C + Re D */
+ ui = (x[29] + x[61]) SHIFT_A; /* Im C + Im D */
+
+ x[24] = vr2 + (vi SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[28] = vr2 - (vi SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[25] = ur2 + (ui SHIFT_B); /* Im A' = sum of imag values */
+ x[29] = ur2 - (ui SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+
+ vr2 -= x[44]; /* Re A - Re B */
+ ur2 -= x[45]; /* Im A - Im B */
+ vi = (vi SHIFT_B)-x[60]; /* Re C - Re D */
+ ui = (ui SHIFT_B)-x[61]; /* Im C - Im D */
+
+ vi2 = (x[26] + x[58]) SHIFT_A; /* Re C + Re D */
+ ui2 = (x[27] + x[59]) SHIFT_A; /* Im C + Im D */
+
+ x[26] = ui + vr2; /* Re B' = Im C - Im D + Re A - Re B */
+ x[27] = ur2 - vi; /* Im B'= -Re C + Re D + Im A - Im B */
+
+ vi3 = (x[30] + x[62]) SHIFT_A; /* Re C + Re D */
+ ui3 = (x[31] + x[63]) SHIFT_A; /* Im C + Im D */
+
+ x[30] = vr2 - ui; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[31] = vi + ur2; /* Im D'= Re C - Re D + Im A - Im B */
+
+ // i=40
+
+ x[40] = vr3 + (vi2 SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[44] = vr3 - (vi2 SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[41] = ur3 + (ui2 SHIFT_B); /* Im A' = sum of imag values */
+ x[45] = ur3 - (ui2 SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+
+ vr3 -= x[42]; /* Re A - Re B */
+ ur3 -= x[43]; /* Im A - Im B */
+ vi2 = (vi2 SHIFT_B)-x[58]; /* Re C - Re D */
+ ui2 = (ui2 SHIFT_B)-x[59]; /* Im C - Im D */
+
+ x[42] = ui2 + vr3; /* Re B' = Im C - Im D + Re A - Re B */
+ x[43] = ur3 - vi2; /* Im B'= -Re C + Re D + Im A - Im B */
+
+ // i=56
+
+ x[56] = vr4 + (vi3 SHIFT_B); /* Re A' = ReA + ReB +ReC + ReD */
+ x[60] = vr4 - (vi3 SHIFT_B); /* Re C' = -(ReC+ReD) + (ReA+ReB) */
+ x[57] = ur4 + (ui3 SHIFT_B); /* Im A' = sum of imag values */
+ x[61] = ur4 - (ui3 SHIFT_B); /* Im C' = -Im C -Im D +Im A +Im B */
+
+ vr4 -= x[46]; /* Re A - Re B */
+ ur4 -= x[47]; /* Im A - Im B */
+
+ x[46] = vr3 - ui2; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[47] = vi2 + ur3; /* Im D'= Re C - Re D + Im A - Im B */
+
+ vi3 = (vi3 SHIFT_B)-x[62]; /* Re C - Re D */
+ ui3 = (ui3 SHIFT_B)-x[63]; /* Im C - Im D */
+
+ x[58] = ui3 + vr4; /* Re B' = Im C - Im D + Re A - Re B */
+ x[62] = vr4 - ui3; /* Re D' = -Im C + Im D + Re A - Re B */
+ x[59] = ur4 - vi3; /* Im B'= -Re C + Re D + Im A - Im B */
+ x[63] = vi3 + ur4; /* Im D'= Re C - Re D + Im A - Im B */
+ }
+
+ {
+ FIXP_DBL *xt = _x;
+
+ int j = 4;
+ do {
+ FIXP_DBL vi, ui, vr, ur;
+
+ vr = xt[8];
+ vi = xt[9];
+ ur = xt[0] >> 1;
+ ui = xt[1] >> 1;
+ xt[0] = ur + (vr >> 1);
+ xt[1] = ui + (vi >> 1);
+ xt[8] = ur - (vr >> 1);
+ xt[9] = ui - (vi >> 1);
+
+ vr = xt[13];
+ vi = xt[12];
+ ur = xt[4] >> 1;
+ ui = xt[5] >> 1;
+ xt[4] = ur + (vr >> 1);
+ xt[5] = ui - (vi >> 1);
+ xt[12] = ur - (vr >> 1);
+ xt[13] = ui + (vi >> 1);
+
+ SUMDIFF_PIFOURTH(vi, vr, xt[10], xt[11])
+ ur = xt[2];
+ ui = xt[3];
+ xt[2] = (ur >> 1) + vr;
+ xt[3] = (ui >> 1) + vi;
+ xt[10] = (ur >> 1) - vr;
+ xt[11] = (ui >> 1) - vi;
+
+ SUMDIFF_PIFOURTH(vr, vi, xt[14], xt[15])
+ ur = xt[6];
+ ui = xt[7];
+
+ xt[6] = (ur >> 1) + vr;
+ xt[7] = (ui >> 1) - vi;
+ xt[14] = (ur >> 1) - vr;
+ xt[15] = (ui >> 1) + vi;
+ xt += 16;
+ } while (--j != 0);
+ }
+
+ {
+ FIXP_DBL *const x = _x;
+ FIXP_DBL vi, ui, vr, ur;
+
+ vr = x[16];
+ vi = x[17];
+ ur = x[0] >> 1;
+ ui = x[1] >> 1;
+ x[0] = ur + (vr >> 1);
+ x[1] = ui + (vi >> 1);
+ x[16] = ur - (vr >> 1);
+ x[17] = ui - (vi >> 1);
+
+ vi = x[24];
+ vr = x[25];
+ ur = x[8] >> 1;
+ ui = x[9] >> 1;
+ x[8] = ur + (vr >> 1);
+ x[9] = ui - (vi >> 1);
+ x[24] = ur - (vr >> 1);
+ x[25] = ui + (vi >> 1);
+
+ vr = x[48];
+ vi = x[49];
+ ur = x[32] >> 1;
+ ui = x[33] >> 1;
+ x[32] = ur + (vr >> 1);
+ x[33] = ui + (vi >> 1);
+ x[48] = ur - (vr >> 1);
+ x[49] = ui - (vi >> 1);
+
+ vi = x[56];
+ vr = x[57];
+ ur = x[40] >> 1;
+ ui = x[41] >> 1;
+ x[40] = ur + (vr >> 1);
+ x[41] = ui - (vi >> 1);
+ x[56] = ur - (vr >> 1);
+ x[57] = ui + (vi >> 1);
+
+ cplxMultDiv2(&vi, &vr, x[19], x[18], fft32_w32[0]);
+ ur = x[2];
+ ui = x[3];
+ x[2] = (ur >> 1) + vr;
+ x[3] = (ui >> 1) + vi;
+ x[18] = (ur >> 1) - vr;
+ x[19] = (ui >> 1) - vi;
+
+ cplxMultDiv2(&vr, &vi, x[27], x[26], fft32_w32[0]);
+ ur = x[10];
+ ui = x[11];
+ x[10] = (ur >> 1) + vr;
+ x[11] = (ui >> 1) - vi;
+ x[26] = (ur >> 1) - vr;
+ x[27] = (ui >> 1) + vi;
+
+ cplxMultDiv2(&vi, &vr, x[51], x[50], fft32_w32[0]);
+ ur = x[34];
+ ui = x[35];
+ x[34] = (ur >> 1) + vr;
+ x[35] = (ui >> 1) + vi;
+ x[50] = (ur >> 1) - vr;
+ x[51] = (ui >> 1) - vi;
+
+ cplxMultDiv2(&vr, &vi, x[59], x[58], fft32_w32[0]);
+ ur = x[42];
+ ui = x[43];
+ x[42] = (ur >> 1) + vr;
+ x[43] = (ui >> 1) - vi;
+ x[58] = (ur >> 1) - vr;
+ x[59] = (ui >> 1) + vi;
+
+ SUMDIFF_PIFOURTH(vi, vr, x[20], x[21])
+ ur = x[4];
+ ui = x[5];
+ x[4] = (ur >> 1) + vr;
+ x[5] = (ui >> 1) + vi;
+ x[20] = (ur >> 1) - vr;
+ x[21] = (ui >> 1) - vi;
+
+ SUMDIFF_PIFOURTH(vr, vi, x[28], x[29])
+ ur = x[12];
+ ui = x[13];
+ x[12] = (ur >> 1) + vr;
+ x[13] = (ui >> 1) - vi;
+ x[28] = (ur >> 1) - vr;
+ x[29] = (ui >> 1) + vi;
+
+ SUMDIFF_PIFOURTH(vi, vr, x[52], x[53])
+ ur = x[36];
+ ui = x[37];
+ x[36] = (ur >> 1) + vr;
+ x[37] = (ui >> 1) + vi;
+ x[52] = (ur >> 1) - vr;
+ x[53] = (ui >> 1) - vi;
+
+ SUMDIFF_PIFOURTH(vr, vi, x[60], x[61])
+ ur = x[44];
+ ui = x[45];
+ x[44] = (ur >> 1) + vr;
+ x[45] = (ui >> 1) - vi;
+ x[60] = (ur >> 1) - vr;
+ x[61] = (ui >> 1) + vi;
+
+ cplxMultDiv2(&vi, &vr, x[23], x[22], fft32_w32[1]);
+ ur = x[6];
+ ui = x[7];
+ x[6] = (ur >> 1) + vr;
+ x[7] = (ui >> 1) + vi;
+ x[22] = (ur >> 1) - vr;
+ x[23] = (ui >> 1) - vi;
+
+ cplxMultDiv2(&vr, &vi, x[31], x[30], fft32_w32[1]);
+ ur = x[14];
+ ui = x[15];
+ x[14] = (ur >> 1) + vr;
+ x[15] = (ui >> 1) - vi;
+ x[30] = (ur >> 1) - vr;
+ x[31] = (ui >> 1) + vi;
+
+ cplxMultDiv2(&vi, &vr, x[55], x[54], fft32_w32[1]);
+ ur = x[38];
+ ui = x[39];
+ x[38] = (ur >> 1) + vr;
+ x[39] = (ui >> 1) + vi;
+ x[54] = (ur >> 1) - vr;
+ x[55] = (ui >> 1) - vi;
+
+ cplxMultDiv2(&vr, &vi, x[63], x[62], fft32_w32[1]);
+ ur = x[46];
+ ui = x[47];
+
+ x[46] = (ur >> 1) + vr;
+ x[47] = (ui >> 1) - vi;
+ x[62] = (ur >> 1) - vr;
+ x[63] = (ui >> 1) + vi;
+
+ vr = x[32];
+ vi = x[33];
+ ur = x[0] >> 1;
+ ui = x[1] >> 1;
+ x[0] = ur + (vr >> 1);
+ x[1] = ui + (vi >> 1);
+ x[32] = ur - (vr >> 1);
+ x[33] = ui - (vi >> 1);
+
+ vi = x[48];
+ vr = x[49];
+ ur = x[16] >> 1;
+ ui = x[17] >> 1;
+ x[16] = ur + (vr >> 1);
+ x[17] = ui - (vi >> 1);
+ x[48] = ur - (vr >> 1);
+ x[49] = ui + (vi >> 1);
+
+ cplxMultDiv2(&vi, &vr, x[35], x[34], fft32_w32[2]);
+ ur = x[2];
+ ui = x[3];
+ x[2] = (ur >> 1) + vr;
+ x[3] = (ui >> 1) + vi;
+ x[34] = (ur >> 1) - vr;
+ x[35] = (ui >> 1) - vi;
+
+ cplxMultDiv2(&vr, &vi, x[51], x[50], fft32_w32[2]);
+ ur = x[18];
+ ui = x[19];
+ x[18] = (ur >> 1) + vr;
+ x[19] = (ui >> 1) - vi;
+ x[50] = (ur >> 1) - vr;
+ x[51] = (ui >> 1) + vi;
+
+ cplxMultDiv2(&vi, &vr, x[37], x[36], fft32_w32[0]);
+ ur = x[4];
+ ui = x[5];
+ x[4] = (ur >> 1) + vr;
+ x[5] = (ui >> 1) + vi;
+ x[36] = (ur >> 1) - vr;
+ x[37] = (ui >> 1) - vi;
+
+ cplxMultDiv2(&vr, &vi, x[53], x[52], fft32_w32[0]);
+ ur = x[20];
+ ui = x[21];
+ x[20] = (ur >> 1) + vr;
+ x[21] = (ui >> 1) - vi;
+ x[52] = (ur >> 1) - vr;
+ x[53] = (ui >> 1) + vi;
+
+ cplxMultDiv2(&vi, &vr, x[39], x[38], fft32_w32[3]);
+ ur = x[6];
+ ui = x[7];
+ x[6] = (ur >> 1) + vr;
+ x[7] = (ui >> 1) + vi;
+ x[38] = (ur >> 1) - vr;
+ x[39] = (ui >> 1) - vi;
+
+ cplxMultDiv2(&vr, &vi, x[55], x[54], fft32_w32[3]);
+ ur = x[22];
+ ui = x[23];
+ x[22] = (ur >> 1) + vr;
+ x[23] = (ui >> 1) - vi;
+ x[54] = (ur >> 1) - vr;
+ x[55] = (ui >> 1) + vi;
+
+ SUMDIFF_PIFOURTH(vi, vr, x[40], x[41])
+ ur = x[8];
+ ui = x[9];
+ x[8] = (ur >> 1) + vr;
+ x[9] = (ui >> 1) + vi;
+ x[40] = (ur >> 1) - vr;
+ x[41] = (ui >> 1) - vi;
+
+ SUMDIFF_PIFOURTH(vr, vi, x[56], x[57])
+ ur = x[24];
+ ui = x[25];
+ x[24] = (ur >> 1) + vr;
+ x[25] = (ui >> 1) - vi;
+ x[56] = (ur >> 1) - vr;
+ x[57] = (ui >> 1) + vi;
+
+ cplxMultDiv2(&vi, &vr, x[43], x[42], fft32_w32[4]);
+ ur = x[10];
+ ui = x[11];
+
+ x[10] = (ur >> 1) + vr;
+ x[11] = (ui >> 1) + vi;
+ x[42] = (ur >> 1) - vr;
+ x[43] = (ui >> 1) - vi;
+
+ cplxMultDiv2(&vr, &vi, x[59], x[58], fft32_w32[4]);
+ ur = x[26];
+ ui = x[27];
+ x[26] = (ur >> 1) + vr;
+ x[27] = (ui >> 1) - vi;
+ x[58] = (ur >> 1) - vr;
+ x[59] = (ui >> 1) + vi;
+
+ cplxMultDiv2(&vi, &vr, x[45], x[44], fft32_w32[1]);
+ ur = x[12];
+ ui = x[13];
+ x[12] = (ur >> 1) + vr;
+ x[13] = (ui >> 1) + vi;
+ x[44] = (ur >> 1) - vr;
+ x[45] = (ui >> 1) - vi;
+
+ cplxMultDiv2(&vr, &vi, x[61], x[60], fft32_w32[1]);
+ ur = x[28];
+ ui = x[29];
+ x[28] = (ur >> 1) + vr;
+ x[29] = (ui >> 1) - vi;
+ x[60] = (ur >> 1) - vr;
+ x[61] = (ui >> 1) + vi;
+
+ cplxMultDiv2(&vi, &vr, x[47], x[46], fft32_w32[5]);
+ ur = x[14];
+ ui = x[15];
+ x[14] = (ur >> 1) + vr;
+ x[15] = (ui >> 1) + vi;
+ x[46] = (ur >> 1) - vr;
+ x[47] = (ui >> 1) - vi;
+
+ cplxMultDiv2(&vr, &vi, x[63], x[62], fft32_w32[5]);
+ ur = x[30];
+ ui = x[31];
+ x[30] = (ur >> 1) + vr;
+ x[31] = (ui >> 1) - vi;
+ x[62] = (ur >> 1) - vr;
+ x[63] = (ui >> 1) + vi;
+ }
+}
+#endif /* #ifndef FUNCTION_fft_32 */
+
+/**
+ * \brief Apply rotation vectors to a data buffer.
+ * \param cl length of each row of input data.
+ * \param l total length of input data.
+ * \param pVecRe real part of rotation coefficient vector.
+ * \param pVecIm imaginary part of rotation coefficient vector.
+ */
+
+/*
+ This defines patches each inaccurate 0x7FFF i.e. 0.9999 and uses 0x8000
+ (-1.0) instead. At the end, the sign of the result is inverted
+*/
+#define noFFT_APPLY_ROT_VECTOR_HQ
+
+#ifndef FUNCTION_fft_apply_rot_vector__FIXP_DBL
+static inline void fft_apply_rot_vector(FIXP_DBL *RESTRICT pData, const int cl,
+ const int l, const FIXP_STB *pVecRe,
+ const FIXP_STB *pVecIm) {
+ FIXP_DBL re, im;
+ FIXP_STB vre, vim;
+
+ int i, c;
+
+ for (i = 0; i < cl; i++) {
+ re = pData[2 * i];
+ im = pData[2 * i + 1];
+
+ pData[2 * i] = re >> 2; /* * 0.25 */
+ pData[2 * i + 1] = im >> 2; /* * 0.25 */
+ }
+ for (; i < l; i += cl) {
+ re = pData[2 * i];
+ im = pData[2 * i + 1];
+
+ pData[2 * i] = re >> 2; /* * 0.25 */
+ pData[2 * i + 1] = im >> 2; /* * 0.25 */
+
+ for (c = i + 1; c < i + cl; c++) {
+ re = pData[2 * c] >> 1;
+ im = pData[2 * c + 1] >> 1;
+ vre = *pVecRe++;
+ vim = *pVecIm++;
+
+ cplxMultDiv2(&pData[2 * c + 1], &pData[2 * c], im, re, vre, vim);
+ }
+ }
+}
+#endif /* FUNCTION_fft_apply_rot_vector__FIXP_DBL */
+
+/* select either switch case of function pointer. */
+//#define FFT_TWO_STAGE_SWITCH_CASE
+#ifndef FUNCTION_fftN2_func
+static inline void fftN2_func(FIXP_DBL *pInput, const int length,
+ const int dim1, const int dim2,
+ void (*const fft1)(FIXP_DBL *),
+ void (*const fft2)(FIXP_DBL *),
+ const FIXP_STB *RotVectorReal,
+ const FIXP_STB *RotVectorImag, FIXP_DBL *aDst,
+ FIXP_DBL *aDst2) {
+ /* The real part of the input samples are at the addresses with even indices
+ and the imaginary part of the input samples are at the addresses with odd
+ indices. The output samples are stored at the address of pInput
+ */
+ FIXP_DBL *pSrc, *pDst, *pDstOut;
+ int i;
+
+ FDK_ASSERT(length == dim1 * dim2);
+
+ /* Perform dim2 times the fft of length dim1. The input samples are at the
+ address of pSrc and the output samples are at the address of pDst. The input
+ vector for the fft of length dim1 is built of the interleaved samples in pSrc,
+ the output samples are stored consecutively.
+ */
+ pSrc = pInput;
+ pDst = aDst;
+ for (i = 0; i < dim2; i++) {
+ for (int j = 0; j < dim1; j++) {
+ pDst[2 * j] = pSrc[2 * j * dim2];
+ pDst[2 * j + 1] = pSrc[2 * j * dim2 + 1];
+ }
+
+ /* fft of size dim1 */
+#ifndef FFT_TWO_STAGE_SWITCH_CASE
+ fft1(pDst);
+#else
+ switch (dim1) {
+ case 2:
+ fft2(pDst);
+ break;
+ case 3:
+ fft3(pDst);
+ break;
+ case 4:
+ fft_4(pDst);
+ break;
+ /* case 5: fft5(pDst); break; */
+ /* case 8: fft_8(pDst); break; */
+ case 12:
+ fft12(pDst);
+ break;
+ /* case 15: fft15(pDst); break; */
+ case 16:
+ fft_16(pDst);
+ break;
+ case 32:
+ fft_32(pDst);
+ break;
+ /*case 64: fft_64(pDst); break;*/
+ /* case 128: fft_128(pDst); break; */
+ }
+#endif
+ pSrc += 2;
+ pDst = pDst + 2 * dim1;
+ }
+
+ /* Perform the modulation of the output of the fft of length dim1 */
+ pSrc = aDst;
+ fft_apply_rot_vector(pSrc, dim1, length, RotVectorReal, RotVectorImag);
+
+ /* Perform dim1 times the fft of length dim2. The input samples are at the
+ address of aDst and the output samples are at the address of pInput. The input
+ vector for the fft of length dim2 is built of the interleaved samples in aDst,
+ the output samples are stored consecutively at the address of pInput.
+ */
+ pSrc = aDst;
+ pDst = aDst2;
+ pDstOut = pInput;
+ for (i = 0; i < dim1; i++) {
+ for (int j = 0; j < dim2; j++) {
+ pDst[2 * j] = pSrc[2 * j * dim1];
+ pDst[2 * j + 1] = pSrc[2 * j * dim1 + 1];
+ }
+
+#ifndef FFT_TWO_STAGE_SWITCH_CASE
+ fft2(pDst);
+#else
+ switch (dim2) {
+ case 4:
+ fft_4(pDst);
+ break;
+ case 9:
+ fft9(pDst);
+ break;
+ case 12:
+ fft12(pDst);
+ break;
+ case 15:
+ fft15(pDst);
+ break;
+ case 16:
+ fft_16(pDst);
+ break;
+ case 32:
+ fft_32(pDst);
+ break;
+ }
+#endif
+
+ for (int j = 0; j < dim2; j++) {
+ pDstOut[2 * j * dim1] = pDst[2 * j];
+ pDstOut[2 * j * dim1 + 1] = pDst[2 * j + 1];
+ }
+ pSrc += 2;
+ pDstOut += 2;
+ }
+}
+#endif /* FUNCTION_fftN2_function */
+
+#define fftN2(DATA_TYPE, pInput, length, dim1, dim2, fft_func1, fft_func2, \
+ RotVectorReal, RotVectorImag) \
+ { \
+ C_AALLOC_SCRATCH_START(aDst, DATA_TYPE, 2 * length) \
+ C_AALLOC_SCRATCH_START(aDst2, DATA_TYPE, 2 * dim2) \
+ fftN2_func(pInput, length, dim1, dim2, fft_func1, fft_func2, \
+ RotVectorReal, RotVectorImag, aDst, aDst2); \
+ C_AALLOC_SCRATCH_END(aDst2, DATA_TYPE, 2 * dim2) \
+ C_AALLOC_SCRATCH_END(aDst, DATA_TYPE, 2 * length) \
+ }
+
+ /*!
+ *
+ * \brief complex FFT of length 12,18,24,30,48,60,96, 192, 240, 384, 480
+ * \param pInput contains the input signal prescaled right by 2
+ * pInput contains the output signal scaled by SCALEFACTOR<#length>
+ * The output signal does not have any fixed headroom
+ * \return void
+ *
+ */
+
+#ifndef FUNCTION_fft6
+static inline void fft6(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 6, 2, 3, fft2, fft3, RotVectorReal6, RotVectorImag6);
+}
+#endif /* #ifndef FUNCTION_fft6 */
+
+#ifndef FUNCTION_fft12
+static inline void fft12(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 12, 3, 4, fft3, fft_4, RotVectorReal12,
+ RotVectorImag12); /* 16,58 */
+}
+#endif /* #ifndef FUNCTION_fft12 */
+
+#ifndef FUNCTION_fft20
+static inline void fft20(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 20, 4, 5, fft_4, fft5, RotVectorReal20,
+ RotVectorImag20);
+}
+#endif /* FUNCTION_fft20 */
+
+static inline void fft24(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 24, 2, 12, fft2, fft12, RotVectorReal24,
+ RotVectorImag24); /* 16,73 */
+}
+
+static inline void fft48(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 48, 4, 12, fft_4, fft12, RotVectorReal48,
+ RotVectorImag48); /* 16,32 */
+}
+
+#ifndef FUNCTION_fft60
+static inline void fft60(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 60, 4, 15, fft_4, fft15, RotVectorReal60,
+ RotVectorImag60); /* 15,51 */
+}
+#endif /* FUNCTION_fft60 */
+
+#ifndef FUNCTION_fft80
+static inline void fft80(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 80, 5, 16, fft5, fft_16, RotVectorReal80,
+ RotVectorImag80); /* */
+}
+#endif
+
+#ifndef FUNCTION_fft96
+static inline void fft96(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 96, 3, 32, fft3, fft_32, RotVectorReal96,
+ RotVectorImag96); /* 15,47 */
+}
+#endif /* FUNCTION_fft96*/
+
+#ifndef FUNCTION_fft120
+static inline void fft120(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 120, 8, 15, fft_8, fft15, RotVectorReal120,
+ RotVectorImag120);
+}
+#endif /* FUNCTION_fft120 */
+
+#ifndef FUNCTION_fft192
+static inline void fft192(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 192, 16, 12, fft_16, fft12, RotVectorReal192,
+ RotVectorImag192); /* 15,50 */
+}
+#endif
+
+#ifndef FUNCTION_fft240
+static inline void fft240(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 240, 16, 15, fft_16, fft15, RotVectorReal240,
+ RotVectorImag240); /* 15.44 */
+}
+#endif
+
+#ifndef FUNCTION_fft384
+static inline void fft384(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 384, 12, 32, fft12, fft_32, RotVectorReal384,
+ RotVectorImag384); /* 16.02 */
+}
+#endif /* FUNCTION_fft384 */
+
+#ifndef FUNCTION_fft480
+static inline void fft480(FIXP_DBL *pInput) {
+ fftN2(FIXP_DBL, pInput, 480, 32, 15, fft_32, fft15, RotVectorReal480,
+ RotVectorImag480); /* 15.84 */
+}
+#endif /* FUNCTION_fft480 */
+
+void fft(int length, FIXP_DBL *pInput, INT *pScalefactor) {
+ /* Ensure, that the io-ptr is always (at least 8-byte) aligned */
+ C_ALLOC_ALIGNED_CHECK(pInput);
+
+ if (length == 32) {
+ fft_32(pInput);
+ *pScalefactor += SCALEFACTOR32;
+ } else {
+ switch (length) {
+ case 16:
+ fft_16(pInput);
+ *pScalefactor += SCALEFACTOR16;
+ break;
+ case 8:
+ fft_8(pInput);
+ *pScalefactor += SCALEFACTOR8;
+ break;
+ case 2:
+ fft2(pInput);
+ *pScalefactor += SCALEFACTOR2;
+ break;
+ case 3:
+ fft3(pInput);
+ *pScalefactor += SCALEFACTOR3;
+ break;
+ case 4:
+ fft_4(pInput);
+ *pScalefactor += SCALEFACTOR4;
+ break;
+ case 5:
+ fft5(pInput);
+ *pScalefactor += SCALEFACTOR5;
+ break;
+ case 6:
+ fft6(pInput);
+ *pScalefactor += SCALEFACTOR6;
+ break;
+ case 10:
+ fft10(pInput);
+ *pScalefactor += SCALEFACTOR10;
+ break;
+ case 12:
+ fft12(pInput);
+ *pScalefactor += SCALEFACTOR12;
+ break;
+ case 15:
+ fft15(pInput);
+ *pScalefactor += SCALEFACTOR15;
+ break;
+ case 20:
+ fft20(pInput);
+ *pScalefactor += SCALEFACTOR20;
+ break;
+ case 24:
+ fft24(pInput);
+ *pScalefactor += SCALEFACTOR24;
+ break;
+ case 48:
+ fft48(pInput);
+ *pScalefactor += SCALEFACTOR48;
+ break;
+ case 60:
+ fft60(pInput);
+ *pScalefactor += SCALEFACTOR60;
+ break;
+ case 64:
+ dit_fft(pInput, 6, SineTable512, 512);
+ *pScalefactor += SCALEFACTOR64;
+ break;
+ case 80:
+ fft80(pInput);
+ *pScalefactor += SCALEFACTOR80;
+ break;
+ case 96:
+ fft96(pInput);
+ *pScalefactor += SCALEFACTOR96;
+ break;
+ case 120:
+ fft120(pInput);
+ *pScalefactor += SCALEFACTOR120;
+ break;
+ case 128:
+ dit_fft(pInput, 7, SineTable512, 512);
+ *pScalefactor += SCALEFACTOR128;
+ break;
+ case 192:
+ fft192(pInput);
+ *pScalefactor += SCALEFACTOR192;
+ break;
+ case 240:
+ fft240(pInput);
+ *pScalefactor += SCALEFACTOR240;
+ break;
+ case 256:
+ dit_fft(pInput, 8, SineTable512, 512);
+ *pScalefactor += SCALEFACTOR256;
+ break;
+ case 384:
+ fft384(pInput);
+ *pScalefactor += SCALEFACTOR384;
+ break;
+ case 480:
+ fft480(pInput);
+ *pScalefactor += SCALEFACTOR480;
+ break;
+ case 512:
+ dit_fft(pInput, 9, SineTable512, 512);
+ *pScalefactor += SCALEFACTOR512;
+ break;
+ default:
+ FDK_ASSERT(0); /* FFT length not supported! */
+ break;
+ }
+ }
+}
+
+void ifft(int length, FIXP_DBL *pInput, INT *scalefactor) {
+ switch (length) {
+ default:
+ FDK_ASSERT(0); /* IFFT length not supported! */
+ break;
+ }
+}
diff --git a/fdk-aac/libFDK/src/fft_rad2.cpp b/fdk-aac/libFDK/src/fft_rad2.cpp
new file mode 100644
index 0000000..27f3aa0
--- /dev/null
+++ b/fdk-aac/libFDK/src/fft_rad2.cpp
@@ -0,0 +1,324 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Lohwasser, M. Gayer
+
+ Description:
+
+*******************************************************************************/
+
+#include "fft_rad2.h"
+
+#include "scramble.h"
+
+#define __FFT_RAD2_CPP__
+
+#if defined(__arm__)
+#include "arm/fft_rad2_arm.cpp"
+
+#elif defined(__GNUC__) && defined(__mips__) && defined(__mips_dsp)
+#include "mips/fft_rad2_mips.cpp"
+
+#endif
+
+/*****************************************************************************
+
+ functionname: dit_fft (analysis)
+ description: dit-tukey-algorithm
+ scrambles data at entry
+ i.e. loop is made with scrambled data
+ returns:
+ input:
+ output:
+
+*****************************************************************************/
+
+#ifndef FUNCTION_dit_fft
+
+void dit_fft(FIXP_DBL *x, const INT ldn, const FIXP_STP *trigdata,
+ const INT trigDataSize) {
+ const INT n = 1 << ldn;
+ INT trigstep, i, ldm;
+
+ C_ALLOC_ALIGNED_CHECK(x);
+
+ scramble(x, n);
+ /*
+ * 1+2 stage radix 4
+ */
+
+ for (i = 0; i < n * 2; i += 8) {
+ FIXP_DBL a00, a10, a20, a30;
+ a00 = (x[i + 0] + x[i + 2]) >> 1; /* Re A + Re B */
+ a10 = (x[i + 4] + x[i + 6]) >> 1; /* Re C + Re D */
+ a20 = (x[i + 1] + x[i + 3]) >> 1; /* Im A + Im B */
+ a30 = (x[i + 5] + x[i + 7]) >> 1; /* Im C + Im D */
+
+ x[i + 0] = a00 + a10; /* Re A' = Re A + Re B + Re C + Re D */
+ x[i + 4] = a00 - a10; /* Re C' = Re A + Re B - Re C - Re D */
+ x[i + 1] = a20 + a30; /* Im A' = Im A + Im B + Im C + Im D */
+ x[i + 5] = a20 - a30; /* Im C' = Im A + Im B - Im C - Im D */
+
+ a00 = a00 - x[i + 2]; /* Re A - Re B */
+ a10 = a10 - x[i + 6]; /* Re C - Re D */
+ a20 = a20 - x[i + 3]; /* Im A - Im B */
+ a30 = a30 - x[i + 7]; /* Im C - Im D */
+
+ x[i + 2] = a00 + a30; /* Re B' = Re A - Re B + Im C - Im D */
+ x[i + 6] = a00 - a30; /* Re D' = Re A - Re B - Im C + Im D */
+ x[i + 3] = a20 - a10; /* Im B' = Im A - Im B - Re C + Re D */
+ x[i + 7] = a20 + a10; /* Im D' = Im A - Im B + Re C - Re D */
+ }
+
+ for (ldm = 3; ldm <= ldn; ++ldm) {
+ INT m = (1 << ldm);
+ INT mh = (m >> 1);
+ INT j, r;
+
+ trigstep = ((trigDataSize << 2) >> ldm);
+
+ FDK_ASSERT(trigstep > 0);
+
+ /* Do first iteration with c=1.0 and s=0.0 separately to avoid loosing to
+ much precision. Beware: The impact on the overal FFT precision is rather
+ large. */
+ { /* block 1 */
+
+ j = 0;
+
+ for (r = 0; r < n; r += m) {
+ INT t1 = (r + j) << 1;
+ INT t2 = t1 + (mh << 1);
+ FIXP_DBL vr, vi, ur, ui;
+
+ // cplxMultDiv2(&vi, &vr, x[t2+1], x[t2], (FIXP_SGL)1.0, (FIXP_SGL)0.0);
+ vi = x[t2 + 1] >> 1;
+ vr = x[t2] >> 1;
+
+ ur = x[t1] >> 1;
+ ui = x[t1 + 1] >> 1;
+
+ x[t1] = ur + vr;
+ x[t1 + 1] = ui + vi;
+
+ x[t2] = ur - vr;
+ x[t2 + 1] = ui - vi;
+
+ t1 += mh;
+ t2 = t1 + (mh << 1);
+
+ // cplxMultDiv2(&vr, &vi, x[t2+1], x[t2], (FIXP_SGL)1.0, (FIXP_SGL)0.0);
+ vr = x[t2 + 1] >> 1;
+ vi = x[t2] >> 1;
+
+ ur = x[t1] >> 1;
+ ui = x[t1 + 1] >> 1;
+
+ x[t1] = ur + vr;
+ x[t1 + 1] = ui - vi;
+
+ x[t2] = ur - vr;
+ x[t2 + 1] = ui + vi;
+ }
+
+ } /* end of block 1 */
+
+ for (j = 1; j < mh / 4; ++j) {
+ FIXP_STP cs;
+
+ cs = trigdata[j * trigstep];
+
+ for (r = 0; r < n; r += m) {
+ INT t1 = (r + j) << 1;
+ INT t2 = t1 + (mh << 1);
+ FIXP_DBL vr, vi, ur, ui;
+
+ cplxMultDiv2(&vi, &vr, x[t2 + 1], x[t2], cs);
+
+ ur = x[t1] >> 1;
+ ui = x[t1 + 1] >> 1;
+
+ x[t1] = ur + vr;
+ x[t1 + 1] = ui + vi;
+
+ x[t2] = ur - vr;
+ x[t2 + 1] = ui - vi;
+
+ t1 += mh;
+ t2 = t1 + (mh << 1);
+
+ cplxMultDiv2(&vr, &vi, x[t2 + 1], x[t2], cs);
+
+ ur = x[t1] >> 1;
+ ui = x[t1 + 1] >> 1;
+
+ x[t1] = ur + vr;
+ x[t1 + 1] = ui - vi;
+
+ x[t2] = ur - vr;
+ x[t2 + 1] = ui + vi;
+
+ /* Same as above but for t1,t2 with j>mh/4 and thus cs swapped */
+ t1 = (r + mh / 2 - j) << 1;
+ t2 = t1 + (mh << 1);
+
+ cplxMultDiv2(&vi, &vr, x[t2], x[t2 + 1], cs);
+
+ ur = x[t1] >> 1;
+ ui = x[t1 + 1] >> 1;
+
+ x[t1] = ur + vr;
+ x[t1 + 1] = ui - vi;
+
+ x[t2] = ur - vr;
+ x[t2 + 1] = ui + vi;
+
+ t1 += mh;
+ t2 = t1 + (mh << 1);
+
+ cplxMultDiv2(&vr, &vi, x[t2], x[t2 + 1], cs);
+
+ ur = x[t1] >> 1;
+ ui = x[t1 + 1] >> 1;
+
+ x[t1] = ur - vr;
+ x[t1 + 1] = ui - vi;
+
+ x[t2] = ur + vr;
+ x[t2 + 1] = ui + vi;
+ }
+ }
+
+ { /* block 2 */
+ j = mh / 4;
+
+ for (r = 0; r < n; r += m) {
+ INT t1 = (r + j) << 1;
+ INT t2 = t1 + (mh << 1);
+ FIXP_DBL vr, vi, ur, ui;
+
+ cplxMultDiv2(&vi, &vr, x[t2 + 1], x[t2], STC(0x5a82799a),
+ STC(0x5a82799a));
+
+ ur = x[t1] >> 1;
+ ui = x[t1 + 1] >> 1;
+
+ x[t1] = ur + vr;
+ x[t1 + 1] = ui + vi;
+
+ x[t2] = ur - vr;
+ x[t2 + 1] = ui - vi;
+
+ t1 += mh;
+ t2 = t1 + (mh << 1);
+
+ cplxMultDiv2(&vr, &vi, x[t2 + 1], x[t2], STC(0x5a82799a),
+ STC(0x5a82799a));
+
+ ur = x[t1] >> 1;
+ ui = x[t1 + 1] >> 1;
+
+ x[t1] = ur + vr;
+ x[t1 + 1] = ui - vi;
+
+ x[t2] = ur - vr;
+ x[t2 + 1] = ui + vi;
+ }
+ } /* end of block 2 */
+ }
+}
+
+#endif
diff --git a/fdk-aac/libFDK/src/fixpoint_math.cpp b/fdk-aac/libFDK/src/fixpoint_math.cpp
new file mode 100644
index 0000000..6c656fa
--- /dev/null
+++ b/fdk-aac/libFDK/src/fixpoint_math.cpp
@@ -0,0 +1,900 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): M. Gayer
+
+ Description: Fixed point specific mathematical functions
+
+*******************************************************************************/
+
+#include "fixpoint_math.h"
+
+/*
+ * Hardware specific implementations
+ */
+
+/*
+ * Fallback implementations
+ */
+
+/*****************************************************************************
+ functionname: LdDataVector
+*****************************************************************************/
+LNK_SECTION_CODE_L1
+void LdDataVector(FIXP_DBL *srcVector, FIXP_DBL *destVector, INT n) {
+ INT i;
+ for (i = 0; i < n; i++) {
+ destVector[i] = fLog2(srcVector[i], 0);
+ }
+}
+
+#define MAX_POW2_PRECISION 8
+#ifndef SINETABLE_16BIT
+#define POW2_PRECISION MAX_POW2_PRECISION
+#else
+#define POW2_PRECISION 5
+#endif
+
+/*
+ Taylor series coefficients of the function x^2. The first coefficient is
+ ommited (equal to 1.0).
+
+ pow2Coeff[i-1] = (1/i!) d^i(2^x)/dx^i, i=1..MAX_POW2_PRECISION
+ To evaluate the taylor series around x = 0, the coefficients are: 1/!i *
+ ln(2)^i
+ */
+#ifndef POW2COEFF_16BIT
+RAM_ALIGN
+LNK_SECTION_CONSTDATA_L1
+static const FIXP_DBL pow2Coeff[MAX_POW2_PRECISION] = {
+ FL2FXCONST_DBL(0.693147180559945309417232121458177), /* ln(2)^1 /1! */
+ FL2FXCONST_DBL(0.240226506959100712333551263163332), /* ln(2)^2 /2! */
+ FL2FXCONST_DBL(0.0555041086648215799531422637686218), /* ln(2)^3 /3! */
+ FL2FXCONST_DBL(0.00961812910762847716197907157365887), /* ln(2)^4 /4! */
+ FL2FXCONST_DBL(0.00133335581464284434234122219879962), /* ln(2)^5 /5! */
+ FL2FXCONST_DBL(1.54035303933816099544370973327423e-4), /* ln(2)^6 /6! */
+ FL2FXCONST_DBL(1.52527338040598402800254390120096e-5), /* ln(2)^7 /7! */
+ FL2FXCONST_DBL(1.32154867901443094884037582282884e-6) /* ln(2)^8 /8! */
+};
+#else
+RAM_ALIGN
+LNK_SECTION_CONSTDATA_L1
+static const FIXP_SGL pow2Coeff[MAX_POW2_PRECISION] = {
+ FL2FXCONST_SGL(0.693147180559945309417232121458177), /* ln(2)^1 /1! */
+ FL2FXCONST_SGL(0.240226506959100712333551263163332), /* ln(2)^2 /2! */
+ FL2FXCONST_SGL(0.0555041086648215799531422637686218), /* ln(2)^3 /3! */
+ FL2FXCONST_SGL(0.00961812910762847716197907157365887), /* ln(2)^4 /4! */
+ FL2FXCONST_SGL(0.00133335581464284434234122219879962), /* ln(2)^5 /5! */
+ FL2FXCONST_SGL(1.54035303933816099544370973327423e-4), /* ln(2)^6 /6! */
+ FL2FXCONST_SGL(1.52527338040598402800254390120096e-5), /* ln(2)^7 /7! */
+ FL2FXCONST_SGL(1.32154867901443094884037582282884e-6) /* ln(2)^8 /8! */
+};
+#endif
+
+/*****************************************************************************
+
+ functionname: CalcInvLdData
+ description: Delivers the inverse of function CalcLdData().
+ Delivers 2^(op*LD_DATA_SCALING)
+ input: Input op is assumed to be fractional -1.0 < op < 1.0
+ output: For op == 0, the result is MAXVAL_DBL (almost 1.0).
+ For negative input values the output should be treated as a
+positive fractional value. For positive input values the output should be
+treated as a positive integer value. This function does not output negative
+values.
+
+*****************************************************************************/
+/* Date: 06-JULY-2012 Arthur Tritthart, IIS Fraunhofer Erlangen */
+/* Version with 3 table lookup and 1 linear interpolations */
+/* Algorithm: compute power of 2, argument x is in Q7.25 format */
+/* result = 2^(x/64) */
+/* We split exponent (x/64) into 5 components: */
+/* integer part: represented by b31..b25 (exp) */
+/* fractional part 1: represented by b24..b20 (lookup1) */
+/* fractional part 2: represented by b19..b15 (lookup2) */
+/* fractional part 3: represented by b14..b10 (lookup3) */
+/* fractional part 4: represented by b09..b00 (frac) */
+/* => result = (lookup1*lookup2*(lookup3+C1*frac)<<3)>>exp */
+/* Due to the fact, that all lookup values contain a factor 0.5 */
+/* the result has to be shifted by 3 to the right also. */
+/* Table exp2_tab_long contains the log2 for 0 to 1.0 in steps */
+/* of 1/32, table exp2w_tab_long the log2 for 0 to 1/32 in steps*/
+/* of 1/1024, table exp2x_tab_long the log2 for 0 to 1/1024 in */
+/* steps of 1/32768. Since the 2-logarithm of very very small */
+/* negative value is rather linear, we can use interpolation. */
+/* Limitations: */
+/* For x <= 0, the result is fractional positive */
+/* For x > 0, the result is integer in range 1...7FFF.FFFF */
+/* For x < -31/64, we have to clear the result */
+/* For x = 0, the result is ~1.0 (0x7FFF.FFFF) */
+/* For x >= 31/64, the result is 0x7FFF.FFFF */
+
+/* This table is used for lookup 2^x with */
+/* x in range [0...1.0[ in steps of 1/32 */
+LNK_SECTION_DATA_L1
+const UINT exp2_tab_long[32] = {
+ 0x40000000, 0x4166C34C, 0x42D561B4, 0x444C0740, 0x45CAE0F2, 0x47521CC6,
+ 0x48E1E9BA, 0x4A7A77D4, 0x4C1BF829, 0x4DC69CDD, 0x4F7A9930, 0x51382182,
+ 0x52FF6B55, 0x54D0AD5A, 0x56AC1F75, 0x5891FAC1, 0x5A82799A, 0x5C7DD7A4,
+ 0x5E8451D0, 0x60962665, 0x62B39509, 0x64DCDEC3, 0x6712460B, 0x69540EC9,
+ 0x6BA27E65, 0x6DFDDBCC, 0x70666F76, 0x72DC8374, 0x75606374, 0x77F25CCE,
+ 0x7A92BE8B, 0x7D41D96E
+ // 0x80000000
+};
+
+/* This table is used for lookup 2^x with */
+/* x in range [0...1/32[ in steps of 1/1024 */
+LNK_SECTION_DATA_L1
+const UINT exp2w_tab_long[32] = {
+ 0x40000000, 0x400B1818, 0x4016321B, 0x40214E0C, 0x402C6BE9, 0x40378BB4,
+ 0x4042AD6D, 0x404DD113, 0x4058F6A8, 0x40641E2B, 0x406F479E, 0x407A7300,
+ 0x4085A051, 0x4090CF92, 0x409C00C4, 0x40A733E6, 0x40B268FA, 0x40BD9FFF,
+ 0x40C8D8F5, 0x40D413DD, 0x40DF50B8, 0x40EA8F86, 0x40F5D046, 0x410112FA,
+ 0x410C57A2, 0x41179E3D, 0x4122E6CD, 0x412E3152, 0x41397DCC, 0x4144CC3B,
+ 0x41501CA0, 0x415B6EFB,
+ // 0x4166C34C,
+};
+/* This table is used for lookup 2^x with */
+/* x in range [0...1/1024[ in steps of 1/32768 */
+LNK_SECTION_DATA_L1
+const UINT exp2x_tab_long[32] = {
+ 0x40000000, 0x400058B9, 0x4000B173, 0x40010A2D, 0x400162E8, 0x4001BBA3,
+ 0x4002145F, 0x40026D1B, 0x4002C5D8, 0x40031E95, 0x40037752, 0x4003D011,
+ 0x400428CF, 0x4004818E, 0x4004DA4E, 0x4005330E, 0x40058BCE, 0x4005E48F,
+ 0x40063D51, 0x40069613, 0x4006EED5, 0x40074798, 0x4007A05B, 0x4007F91F,
+ 0x400851E4, 0x4008AAA8, 0x4009036E, 0x40095C33, 0x4009B4FA, 0x400A0DC0,
+ 0x400A6688, 0x400ABF4F,
+ // 0x400B1818
+};
+
+/*****************************************************************************
+ functionname: InitLdInt and CalcLdInt
+ description: Create and access table with integer LdData (0 to
+LD_INT_TAB_LEN)
+*****************************************************************************/
+#ifndef LD_INT_TAB_LEN
+#define LD_INT_TAB_LEN \
+ 193 /* Default tab length. Lower value should be set in fix.h */
+#endif
+
+#if (LD_INT_TAB_LEN <= 120)
+LNK_SECTION_CONSTDATA_L1
+static const FIXP_DBL ldIntCoeff[] = {
+ (FIXP_DBL)0x80000001, (FIXP_DBL)0x00000000, (FIXP_DBL)0x02000000,
+ (FIXP_DBL)0x032b8034, (FIXP_DBL)0x04000000, (FIXP_DBL)0x04a4d3c2,
+ (FIXP_DBL)0x052b8034, (FIXP_DBL)0x059d5da0, (FIXP_DBL)0x06000000,
+ (FIXP_DBL)0x06570069, (FIXP_DBL)0x06a4d3c2, (FIXP_DBL)0x06eb3a9f,
+ (FIXP_DBL)0x072b8034, (FIXP_DBL)0x0766a009, (FIXP_DBL)0x079d5da0,
+ (FIXP_DBL)0x07d053f7, (FIXP_DBL)0x08000000, (FIXP_DBL)0x082cc7ee,
+ (FIXP_DBL)0x08570069, (FIXP_DBL)0x087ef05b, (FIXP_DBL)0x08a4d3c2,
+ (FIXP_DBL)0x08c8ddd4, (FIXP_DBL)0x08eb3a9f, (FIXP_DBL)0x090c1050,
+ (FIXP_DBL)0x092b8034, (FIXP_DBL)0x0949a785, (FIXP_DBL)0x0966a009,
+ (FIXP_DBL)0x0982809d, (FIXP_DBL)0x099d5da0, (FIXP_DBL)0x09b74949,
+ (FIXP_DBL)0x09d053f7, (FIXP_DBL)0x09e88c6b, (FIXP_DBL)0x0a000000,
+ (FIXP_DBL)0x0a16bad3, (FIXP_DBL)0x0a2cc7ee, (FIXP_DBL)0x0a423162,
+ (FIXP_DBL)0x0a570069, (FIXP_DBL)0x0a6b3d79, (FIXP_DBL)0x0a7ef05b,
+ (FIXP_DBL)0x0a92203d, (FIXP_DBL)0x0aa4d3c2, (FIXP_DBL)0x0ab7110e,
+ (FIXP_DBL)0x0ac8ddd4, (FIXP_DBL)0x0ada3f60, (FIXP_DBL)0x0aeb3a9f,
+ (FIXP_DBL)0x0afbd42b, (FIXP_DBL)0x0b0c1050, (FIXP_DBL)0x0b1bf312,
+ (FIXP_DBL)0x0b2b8034, (FIXP_DBL)0x0b3abb40, (FIXP_DBL)0x0b49a785,
+ (FIXP_DBL)0x0b584822, (FIXP_DBL)0x0b66a009, (FIXP_DBL)0x0b74b1fd,
+ (FIXP_DBL)0x0b82809d, (FIXP_DBL)0x0b900e61, (FIXP_DBL)0x0b9d5da0,
+ (FIXP_DBL)0x0baa708f, (FIXP_DBL)0x0bb74949, (FIXP_DBL)0x0bc3e9ca,
+ (FIXP_DBL)0x0bd053f7, (FIXP_DBL)0x0bdc899b, (FIXP_DBL)0x0be88c6b,
+ (FIXP_DBL)0x0bf45e09, (FIXP_DBL)0x0c000000, (FIXP_DBL)0x0c0b73cb,
+ (FIXP_DBL)0x0c16bad3, (FIXP_DBL)0x0c21d671, (FIXP_DBL)0x0c2cc7ee,
+ (FIXP_DBL)0x0c379085, (FIXP_DBL)0x0c423162, (FIXP_DBL)0x0c4caba8,
+ (FIXP_DBL)0x0c570069, (FIXP_DBL)0x0c6130af, (FIXP_DBL)0x0c6b3d79,
+ (FIXP_DBL)0x0c7527b9, (FIXP_DBL)0x0c7ef05b, (FIXP_DBL)0x0c88983f,
+ (FIXP_DBL)0x0c92203d, (FIXP_DBL)0x0c9b8926, (FIXP_DBL)0x0ca4d3c2,
+ (FIXP_DBL)0x0cae00d2, (FIXP_DBL)0x0cb7110e, (FIXP_DBL)0x0cc0052b,
+ (FIXP_DBL)0x0cc8ddd4, (FIXP_DBL)0x0cd19bb0, (FIXP_DBL)0x0cda3f60,
+ (FIXP_DBL)0x0ce2c97d, (FIXP_DBL)0x0ceb3a9f, (FIXP_DBL)0x0cf39355,
+ (FIXP_DBL)0x0cfbd42b, (FIXP_DBL)0x0d03fda9, (FIXP_DBL)0x0d0c1050,
+ (FIXP_DBL)0x0d140ca0, (FIXP_DBL)0x0d1bf312, (FIXP_DBL)0x0d23c41d,
+ (FIXP_DBL)0x0d2b8034, (FIXP_DBL)0x0d3327c7, (FIXP_DBL)0x0d3abb40,
+ (FIXP_DBL)0x0d423b08, (FIXP_DBL)0x0d49a785, (FIXP_DBL)0x0d510118,
+ (FIXP_DBL)0x0d584822, (FIXP_DBL)0x0d5f7cff, (FIXP_DBL)0x0d66a009,
+ (FIXP_DBL)0x0d6db197, (FIXP_DBL)0x0d74b1fd, (FIXP_DBL)0x0d7ba190,
+ (FIXP_DBL)0x0d82809d, (FIXP_DBL)0x0d894f75, (FIXP_DBL)0x0d900e61,
+ (FIXP_DBL)0x0d96bdad, (FIXP_DBL)0x0d9d5da0, (FIXP_DBL)0x0da3ee7f,
+ (FIXP_DBL)0x0daa708f, (FIXP_DBL)0x0db0e412, (FIXP_DBL)0x0db74949,
+ (FIXP_DBL)0x0dbda072, (FIXP_DBL)0x0dc3e9ca, (FIXP_DBL)0x0dca258e};
+
+#elif (LD_INT_TAB_LEN <= 193)
+LNK_SECTION_CONSTDATA_L1
+static const FIXP_DBL ldIntCoeff[] = {
+ (FIXP_DBL)0x80000001, (FIXP_DBL)0x00000000, (FIXP_DBL)0x02000000,
+ (FIXP_DBL)0x032b8034, (FIXP_DBL)0x04000000, (FIXP_DBL)0x04a4d3c2,
+ (FIXP_DBL)0x052b8034, (FIXP_DBL)0x059d5da0, (FIXP_DBL)0x06000000,
+ (FIXP_DBL)0x06570069, (FIXP_DBL)0x06a4d3c2, (FIXP_DBL)0x06eb3a9f,
+ (FIXP_DBL)0x072b8034, (FIXP_DBL)0x0766a009, (FIXP_DBL)0x079d5da0,
+ (FIXP_DBL)0x07d053f7, (FIXP_DBL)0x08000000, (FIXP_DBL)0x082cc7ee,
+ (FIXP_DBL)0x08570069, (FIXP_DBL)0x087ef05b, (FIXP_DBL)0x08a4d3c2,
+ (FIXP_DBL)0x08c8ddd4, (FIXP_DBL)0x08eb3a9f, (FIXP_DBL)0x090c1050,
+ (FIXP_DBL)0x092b8034, (FIXP_DBL)0x0949a785, (FIXP_DBL)0x0966a009,
+ (FIXP_DBL)0x0982809d, (FIXP_DBL)0x099d5da0, (FIXP_DBL)0x09b74949,
+ (FIXP_DBL)0x09d053f7, (FIXP_DBL)0x09e88c6b, (FIXP_DBL)0x0a000000,
+ (FIXP_DBL)0x0a16bad3, (FIXP_DBL)0x0a2cc7ee, (FIXP_DBL)0x0a423162,
+ (FIXP_DBL)0x0a570069, (FIXP_DBL)0x0a6b3d79, (FIXP_DBL)0x0a7ef05b,
+ (FIXP_DBL)0x0a92203d, (FIXP_DBL)0x0aa4d3c2, (FIXP_DBL)0x0ab7110e,
+ (FIXP_DBL)0x0ac8ddd4, (FIXP_DBL)0x0ada3f60, (FIXP_DBL)0x0aeb3a9f,
+ (FIXP_DBL)0x0afbd42b, (FIXP_DBL)0x0b0c1050, (FIXP_DBL)0x0b1bf312,
+ (FIXP_DBL)0x0b2b8034, (FIXP_DBL)0x0b3abb40, (FIXP_DBL)0x0b49a785,
+ (FIXP_DBL)0x0b584822, (FIXP_DBL)0x0b66a009, (FIXP_DBL)0x0b74b1fd,
+ (FIXP_DBL)0x0b82809d, (FIXP_DBL)0x0b900e61, (FIXP_DBL)0x0b9d5da0,
+ (FIXP_DBL)0x0baa708f, (FIXP_DBL)0x0bb74949, (FIXP_DBL)0x0bc3e9ca,
+ (FIXP_DBL)0x0bd053f7, (FIXP_DBL)0x0bdc899b, (FIXP_DBL)0x0be88c6b,
+ (FIXP_DBL)0x0bf45e09, (FIXP_DBL)0x0c000000, (FIXP_DBL)0x0c0b73cb,
+ (FIXP_DBL)0x0c16bad3, (FIXP_DBL)0x0c21d671, (FIXP_DBL)0x0c2cc7ee,
+ (FIXP_DBL)0x0c379085, (FIXP_DBL)0x0c423162, (FIXP_DBL)0x0c4caba8,
+ (FIXP_DBL)0x0c570069, (FIXP_DBL)0x0c6130af, (FIXP_DBL)0x0c6b3d79,
+ (FIXP_DBL)0x0c7527b9, (FIXP_DBL)0x0c7ef05b, (FIXP_DBL)0x0c88983f,
+ (FIXP_DBL)0x0c92203d, (FIXP_DBL)0x0c9b8926, (FIXP_DBL)0x0ca4d3c2,
+ (FIXP_DBL)0x0cae00d2, (FIXP_DBL)0x0cb7110e, (FIXP_DBL)0x0cc0052b,
+ (FIXP_DBL)0x0cc8ddd4, (FIXP_DBL)0x0cd19bb0, (FIXP_DBL)0x0cda3f60,
+ (FIXP_DBL)0x0ce2c97d, (FIXP_DBL)0x0ceb3a9f, (FIXP_DBL)0x0cf39355,
+ (FIXP_DBL)0x0cfbd42b, (FIXP_DBL)0x0d03fda9, (FIXP_DBL)0x0d0c1050,
+ (FIXP_DBL)0x0d140ca0, (FIXP_DBL)0x0d1bf312, (FIXP_DBL)0x0d23c41d,
+ (FIXP_DBL)0x0d2b8034, (FIXP_DBL)0x0d3327c7, (FIXP_DBL)0x0d3abb40,
+ (FIXP_DBL)0x0d423b08, (FIXP_DBL)0x0d49a785, (FIXP_DBL)0x0d510118,
+ (FIXP_DBL)0x0d584822, (FIXP_DBL)0x0d5f7cff, (FIXP_DBL)0x0d66a009,
+ (FIXP_DBL)0x0d6db197, (FIXP_DBL)0x0d74b1fd, (FIXP_DBL)0x0d7ba190,
+ (FIXP_DBL)0x0d82809d, (FIXP_DBL)0x0d894f75, (FIXP_DBL)0x0d900e61,
+ (FIXP_DBL)0x0d96bdad, (FIXP_DBL)0x0d9d5da0, (FIXP_DBL)0x0da3ee7f,
+ (FIXP_DBL)0x0daa708f, (FIXP_DBL)0x0db0e412, (FIXP_DBL)0x0db74949,
+ (FIXP_DBL)0x0dbda072, (FIXP_DBL)0x0dc3e9ca, (FIXP_DBL)0x0dca258e,
+ (FIXP_DBL)0x0dd053f7, (FIXP_DBL)0x0dd6753e, (FIXP_DBL)0x0ddc899b,
+ (FIXP_DBL)0x0de29143, (FIXP_DBL)0x0de88c6b, (FIXP_DBL)0x0dee7b47,
+ (FIXP_DBL)0x0df45e09, (FIXP_DBL)0x0dfa34e1, (FIXP_DBL)0x0e000000,
+ (FIXP_DBL)0x0e05bf94, (FIXP_DBL)0x0e0b73cb, (FIXP_DBL)0x0e111cd2,
+ (FIXP_DBL)0x0e16bad3, (FIXP_DBL)0x0e1c4dfb, (FIXP_DBL)0x0e21d671,
+ (FIXP_DBL)0x0e275460, (FIXP_DBL)0x0e2cc7ee, (FIXP_DBL)0x0e323143,
+ (FIXP_DBL)0x0e379085, (FIXP_DBL)0x0e3ce5d8, (FIXP_DBL)0x0e423162,
+ (FIXP_DBL)0x0e477346, (FIXP_DBL)0x0e4caba8, (FIXP_DBL)0x0e51daa8,
+ (FIXP_DBL)0x0e570069, (FIXP_DBL)0x0e5c1d0b, (FIXP_DBL)0x0e6130af,
+ (FIXP_DBL)0x0e663b74, (FIXP_DBL)0x0e6b3d79, (FIXP_DBL)0x0e7036db,
+ (FIXP_DBL)0x0e7527b9, (FIXP_DBL)0x0e7a1030, (FIXP_DBL)0x0e7ef05b,
+ (FIXP_DBL)0x0e83c857, (FIXP_DBL)0x0e88983f, (FIXP_DBL)0x0e8d602e,
+ (FIXP_DBL)0x0e92203d, (FIXP_DBL)0x0e96d888, (FIXP_DBL)0x0e9b8926,
+ (FIXP_DBL)0x0ea03232, (FIXP_DBL)0x0ea4d3c2, (FIXP_DBL)0x0ea96df0,
+ (FIXP_DBL)0x0eae00d2, (FIXP_DBL)0x0eb28c7f, (FIXP_DBL)0x0eb7110e,
+ (FIXP_DBL)0x0ebb8e96, (FIXP_DBL)0x0ec0052b, (FIXP_DBL)0x0ec474e4,
+ (FIXP_DBL)0x0ec8ddd4, (FIXP_DBL)0x0ecd4012, (FIXP_DBL)0x0ed19bb0,
+ (FIXP_DBL)0x0ed5f0c4, (FIXP_DBL)0x0eda3f60, (FIXP_DBL)0x0ede8797,
+ (FIXP_DBL)0x0ee2c97d, (FIXP_DBL)0x0ee70525, (FIXP_DBL)0x0eeb3a9f,
+ (FIXP_DBL)0x0eef69ff, (FIXP_DBL)0x0ef39355, (FIXP_DBL)0x0ef7b6b4,
+ (FIXP_DBL)0x0efbd42b, (FIXP_DBL)0x0effebcd, (FIXP_DBL)0x0f03fda9,
+ (FIXP_DBL)0x0f0809cf, (FIXP_DBL)0x0f0c1050, (FIXP_DBL)0x0f10113b,
+ (FIXP_DBL)0x0f140ca0, (FIXP_DBL)0x0f18028d, (FIXP_DBL)0x0f1bf312,
+ (FIXP_DBL)0x0f1fde3d, (FIXP_DBL)0x0f23c41d, (FIXP_DBL)0x0f27a4c0,
+ (FIXP_DBL)0x0f2b8034};
+
+#else
+#error "ldInt table size too small"
+
+#endif
+
+LNK_SECTION_INITCODE
+void InitLdInt() { /* nothing to do! Use preinitialized logarithm table */
+}
+
+#if (LD_INT_TAB_LEN != 0)
+
+LNK_SECTION_CODE_L1
+FIXP_DBL CalcLdInt(INT i) {
+ /* calculates ld(op)/LD_DATA_SCALING */
+ /* op is assumed to be an integer value between 1 and LD_INT_TAB_LEN */
+
+ FDK_ASSERT((LD_INT_TAB_LEN > 0) &&
+ ((FIXP_DBL)ldIntCoeff[0] ==
+ (FIXP_DBL)0x80000001)); /* tab has to be initialized */
+
+ if ((i > 0) && (i < LD_INT_TAB_LEN))
+ return ldIntCoeff[i];
+ else {
+ return (0);
+ }
+}
+#endif /* (LD_INT_TAB_LEN!=0) */
+
+#if !defined(FUNCTION_schur_div)
+/*****************************************************************************
+
+ functionname: schur_div
+ description: delivers op1/op2 with op3-bit accuracy
+
+*****************************************************************************/
+
+FIXP_DBL schur_div(FIXP_DBL num, FIXP_DBL denum, INT count) {
+ INT L_num = (LONG)num >> 1;
+ INT L_denum = (LONG)denum >> 1;
+ INT div = 0;
+ INT k = count;
+
+ FDK_ASSERT(num >= (FIXP_DBL)0);
+ FDK_ASSERT(denum > (FIXP_DBL)0);
+ FDK_ASSERT(num <= denum);
+
+ if (L_num != 0)
+ while (--k) {
+ div <<= 1;
+ L_num <<= 1;
+ if (L_num >= L_denum) {
+ L_num -= L_denum;
+ div++;
+ }
+ }
+ return (FIXP_DBL)(div << (DFRACT_BITS - count));
+}
+
+#endif /* !defined(FUNCTION_schur_div) */
+
+#ifndef FUNCTION_fMultNorm
+FIXP_DBL fMultNorm(FIXP_DBL f1, FIXP_DBL f2, INT *result_e) {
+ INT product = 0;
+ INT norm_f1, norm_f2;
+
+ if ((f1 == (FIXP_DBL)0) || (f2 == (FIXP_DBL)0)) {
+ *result_e = 0;
+ return (FIXP_DBL)0;
+ }
+ norm_f1 = CountLeadingBits(f1);
+ f1 = f1 << norm_f1;
+ norm_f2 = CountLeadingBits(f2);
+ f2 = f2 << norm_f2;
+
+ if ((f1 == (FIXP_DBL)MINVAL_DBL) && (f2 == (FIXP_DBL)MINVAL_DBL)) {
+ product = -((FIXP_DBL)MINVAL_DBL >> 1);
+ *result_e = -(norm_f1 + norm_f2 - 1);
+ } else {
+ product = fMult(f1, f2);
+ *result_e = -(norm_f1 + norm_f2);
+ }
+
+ return (FIXP_DBL)product;
+}
+#endif
+
+#ifndef FUNCTION_fDivNorm
+FIXP_DBL fDivNorm(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e) {
+ FIXP_DBL div;
+ INT norm_num, norm_den;
+
+ FDK_ASSERT(L_num >= (FIXP_DBL)0);
+ FDK_ASSERT(L_denum > (FIXP_DBL)0);
+
+ if (L_num == (FIXP_DBL)0) {
+ *result_e = 0;
+ return ((FIXP_DBL)0);
+ }
+
+ norm_num = CountLeadingBits(L_num);
+ L_num = L_num << norm_num;
+ L_num = L_num >> 1;
+ *result_e = -norm_num + 1;
+
+ norm_den = CountLeadingBits(L_denum);
+ L_denum = L_denum << norm_den;
+ *result_e -= -norm_den;
+
+ div = schur_div(L_num, L_denum, FRACT_BITS);
+
+ return div;
+}
+#endif /* !FUNCTION_fDivNorm */
+
+#ifndef FUNCTION_fDivNorm
+FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom) {
+ INT e;
+ FIXP_DBL res;
+
+ FDK_ASSERT(denom >= num);
+
+ res = fDivNorm(num, denom, &e);
+
+ /* Avoid overflow since we must output a value with exponent 0
+ there is no other choice than saturating to almost 1.0f */
+ if (res == (FIXP_DBL)(1 << (DFRACT_BITS - 2)) && e == 1) {
+ res = (FIXP_DBL)MAXVAL_DBL;
+ } else {
+ res = scaleValue(res, e);
+ }
+
+ return res;
+}
+#endif /* !FUNCTION_fDivNorm */
+
+#ifndef FUNCTION_fDivNormSigned
+FIXP_DBL fDivNormSigned(FIXP_DBL num, FIXP_DBL denom) {
+ INT e;
+ FIXP_DBL res;
+ int sign;
+
+ if (denom == (FIXP_DBL)0) {
+ return (FIXP_DBL)MAXVAL_DBL;
+ }
+
+ sign = ((num >= (FIXP_DBL)0) != (denom >= (FIXP_DBL)0));
+ res = fDivNormSigned(num, denom, &e);
+
+ /* Saturate since we must output a value with exponent 0 */
+ if ((e > 0) && (fAbs(res) >= FL2FXCONST_DBL(0.5))) {
+ if (sign) {
+ res = (FIXP_DBL)MINVAL_DBL;
+ } else {
+ res = (FIXP_DBL)MAXVAL_DBL;
+ }
+ } else {
+ res = scaleValue(res, e);
+ }
+
+ return res;
+}
+FIXP_DBL fDivNormSigned(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e) {
+ FIXP_DBL div;
+ INT norm_num, norm_den;
+ int sign;
+
+ sign = ((L_num >= (FIXP_DBL)0) != (L_denum >= (FIXP_DBL)0));
+
+ if (L_num == (FIXP_DBL)0) {
+ *result_e = 0;
+ return ((FIXP_DBL)0);
+ }
+ if (L_denum == (FIXP_DBL)0) {
+ *result_e = 14;
+ return ((FIXP_DBL)MAXVAL_DBL);
+ }
+
+ norm_num = CountLeadingBits(L_num);
+ L_num = L_num << norm_num;
+ L_num = L_num >> 2;
+ L_num = fAbs(L_num);
+ *result_e = -norm_num + 1;
+
+ norm_den = CountLeadingBits(L_denum);
+ L_denum = L_denum << norm_den;
+ L_denum = L_denum >> 1;
+ L_denum = fAbs(L_denum);
+ *result_e -= -norm_den;
+
+ div = schur_div(L_num, L_denum, FRACT_BITS);
+
+ if (sign) {
+ div = -div;
+ }
+
+ return div;
+}
+#endif /* FUNCTION_fDivNormSigned */
+
+#ifndef FUNCTION_fDivNormHighPrec
+FIXP_DBL fDivNormHighPrec(FIXP_DBL num, FIXP_DBL denom, INT *result_e) {
+ FIXP_DBL div;
+ INT norm_num, norm_den;
+
+ FDK_ASSERT(num >= (FIXP_DBL)0);
+ FDK_ASSERT(denom > (FIXP_DBL)0);
+
+ if (num == (FIXP_DBL)0) {
+ *result_e = 0;
+ return ((FIXP_DBL)0);
+ }
+
+ norm_num = CountLeadingBits(num);
+ num = num << norm_num;
+ num = num >> 1;
+ *result_e = -norm_num + 1;
+
+ norm_den = CountLeadingBits(denom);
+ denom = denom << norm_den;
+ *result_e -= -norm_den;
+
+ div = schur_div(num, denom, 31);
+ return div;
+}
+#endif /* !FUNCTION_fDivNormHighPrec */
+
+#ifndef FUNCTION_fPow
+FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e, INT *result_e) {
+ FIXP_DBL frac_part, result_m;
+ INT int_part;
+
+ if (exp_e > 0) {
+ INT exp_bits = DFRACT_BITS - 1 - exp_e;
+ int_part = exp_m >> exp_bits;
+ frac_part = exp_m - (FIXP_DBL)(int_part << exp_bits);
+ frac_part = frac_part << exp_e;
+ } else {
+ int_part = 0;
+ frac_part = exp_m >> -exp_e;
+ }
+
+ /* Best accuracy is around 0, so try to get there with the fractional part. */
+ if (frac_part > FL2FXCONST_DBL(0.5f)) {
+ int_part = int_part + 1;
+ frac_part = frac_part + FL2FXCONST_DBL(-1.0f);
+ }
+ if (frac_part < FL2FXCONST_DBL(-0.5f)) {
+ int_part = int_part - 1;
+ frac_part = -(FL2FXCONST_DBL(-1.0f) - frac_part);
+ }
+
+ /* "+ 1" compensates fMultAddDiv2() of the polynomial evaluation below. */
+ *result_e = int_part + 1;
+
+ /* Evaluate taylor polynomial which approximates 2^x */
+ {
+ FIXP_DBL p;
+
+ /* result_m ~= 2^frac_part */
+ p = frac_part;
+ /* First taylor series coefficient a_0 = 1.0, scaled by 0.5 due to
+ * fMultDiv2(). */
+ result_m = FL2FXCONST_DBL(1.0f / 2.0f);
+ for (INT i = 0; i < POW2_PRECISION; i++) {
+ /* next taylor series term: a_i * x^i, x=0 */
+ result_m = fMultAddDiv2(result_m, pow2Coeff[i], p);
+ p = fMult(p, frac_part);
+ }
+ }
+ return result_m;
+}
+
+FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e) {
+ FIXP_DBL result_m;
+ INT result_e;
+
+ result_m = f2Pow(exp_m, exp_e, &result_e);
+ result_e = fixMin(DFRACT_BITS - 1, fixMax(-(DFRACT_BITS - 1), result_e));
+
+ return scaleValue(result_m, result_e);
+}
+
+FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e,
+ INT *result_e) {
+ INT ans_lg2_e, baselg2_e;
+ FIXP_DBL base_lg2, ans_lg2, result;
+
+ /* Calc log2 of base */
+ base_lg2 = fLog2(base_m, base_e, &baselg2_e);
+
+ /* Prepare exp */
+ {
+ INT leadingBits;
+
+ leadingBits = CountLeadingBits(fAbs(exp_m));
+ exp_m = exp_m << leadingBits;
+ exp_e -= leadingBits;
+ }
+
+ /* Calc base pow exp */
+ ans_lg2 = fMult(base_lg2, exp_m);
+ ans_lg2_e = exp_e + baselg2_e;
+
+ /* Calc antilog */
+ result = f2Pow(ans_lg2, ans_lg2_e, result_e);
+
+ return result;
+}
+
+FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e,
+ INT *result_e) {
+ INT ans_lg2_e;
+ FIXP_DBL ans_lg2, result;
+
+ /* Prepare exp */
+ {
+ INT leadingBits;
+
+ leadingBits = CountLeadingBits(fAbs(exp_m));
+ exp_m = exp_m << leadingBits;
+ exp_e -= leadingBits;
+ }
+
+ /* Calc base pow exp */
+ ans_lg2 = fMult(baseLd_m, exp_m);
+ ans_lg2_e = exp_e + baseLd_e;
+
+ /* Calc antilog */
+ result = f2Pow(ans_lg2, ans_lg2_e, result_e);
+
+ return result;
+}
+
+FIXP_DBL fLdPow(FIXP_DBL baseLd_m, INT baseLd_e, FIXP_DBL exp_m, INT exp_e) {
+ FIXP_DBL result_m;
+ int result_e;
+
+ result_m = fLdPow(baseLd_m, baseLd_e, exp_m, exp_e, &result_e);
+
+ return SATURATE_SHIFT(result_m, -result_e, DFRACT_BITS);
+}
+
+FIXP_DBL fPowInt(FIXP_DBL base_m, INT base_e, INT exp, INT *pResult_e) {
+ FIXP_DBL result;
+
+ if (exp != 0) {
+ INT result_e = 0;
+
+ if (base_m != (FIXP_DBL)0) {
+ {
+ INT leadingBits;
+ leadingBits = CountLeadingBits(base_m);
+ base_m <<= leadingBits;
+ base_e -= leadingBits;
+ }
+
+ result = base_m;
+
+ {
+ int i;
+ for (i = 1; i < fAbs(exp); i++) {
+ result = fMult(result, base_m);
+ }
+ }
+
+ if (exp < 0) {
+ /* 1.0 / ans */
+ result = fDivNorm(FL2FXCONST_DBL(0.5f), result, &result_e);
+ result_e++;
+ } else {
+ int ansScale = CountLeadingBits(result);
+ result <<= ansScale;
+ result_e -= ansScale;
+ }
+
+ result_e += exp * base_e;
+
+ } else {
+ result = (FIXP_DBL)0;
+ }
+ *pResult_e = result_e;
+ } else {
+ result = FL2FXCONST_DBL(0.5f);
+ *pResult_e = 1;
+ }
+
+ return result;
+}
+#endif /* FUNCTION_fPow */
+
+#ifndef FUNCTION_fLog2
+FIXP_DBL CalcLog2(FIXP_DBL base_m, INT base_e, INT *result_e) {
+ return fLog2(base_m, base_e, result_e);
+}
+#endif /* FUNCTION_fLog2 */
+
+INT fixp_floorToInt(FIXP_DBL f_inp, INT sf) {
+ FDK_ASSERT(sf >= 0);
+ INT floorInt = (INT)(f_inp >> ((DFRACT_BITS - 1) - sf));
+ return floorInt;
+}
+
+FIXP_DBL fixp_floor(FIXP_DBL f_inp, INT sf) {
+ FDK_ASSERT(sf >= 0);
+ INT floorInt = fixp_floorToInt(f_inp, sf);
+ FIXP_DBL f_floor = (FIXP_DBL)(floorInt << ((DFRACT_BITS - 1) - sf));
+ return f_floor;
+}
+
+INT fixp_ceilToInt(FIXP_DBL f_inp, INT sf) // sf mantissaBits left of dot
+{
+ FDK_ASSERT(sf >= 0);
+ INT sx = (DFRACT_BITS - 1) - sf; // sx mantissaBits right of dot
+ INT inpINT = (INT)f_inp;
+
+ INT mask = (0x1 << sx) - 1;
+ INT ceilInt = (INT)(f_inp >> sx);
+
+ if (inpINT & mask) {
+ ceilInt++; // increment only, if there is at least one set mantissaBit
+ // right of dot [in inpINT]
+ }
+
+ return ceilInt;
+}
+
+FIXP_DBL fixp_ceil(FIXP_DBL f_inp, INT sf) {
+ FDK_ASSERT(sf >= 0);
+ INT sx = (DFRACT_BITS - 1) - sf;
+ INT ceilInt = fixp_ceilToInt(f_inp, sf);
+ ULONG mask = (ULONG)0x1 << (DFRACT_BITS - 1); // 0x80000000
+ ceilInt = ceilInt
+ << sx; // no fract warn bec. shift into saturation done on int side
+
+ if ((f_inp > FL2FXCONST_DBL(0.0f)) && (ceilInt & mask)) {
+ --ceilInt;
+ }
+ FIXP_DBL f_ceil = (FIXP_DBL)ceilInt;
+
+ return f_ceil;
+}
+
+/*****************************************************************************
+ fixp_truncateToInt()
+ Just remove the fractional part which is located right of decimal point
+ Same as which is done when a float is casted to (INT) :
+ result_INTtype = (INT)b_floatTypeInput;
+
+ returns INT
+*****************************************************************************/
+INT fixp_truncateToInt(FIXP_DBL f_inp, INT sf) // sf mantissaBits left of dot
+ // (without sign) e.g. at width
+ // 32 this would be [sign]7.
+ // supposed sf equals 8.
+{
+ FDK_ASSERT(sf >= 0);
+ INT sx = (DFRACT_BITS - 1) - sf; // sx mantissaBits right of dot
+ // at width 32 this would be .24
+ // supposed sf equals 8.
+ INT fbaccu = (INT)f_inp;
+ INT mask = (0x1 << sx);
+
+ if ((fbaccu < 0) && (fbaccu & (mask - 1))) {
+ fbaccu = fbaccu + mask;
+ }
+
+ fbaccu = fbaccu >> sx;
+ return fbaccu;
+}
+
+/*****************************************************************************
+ fixp_truncate()
+ Just remove the fractional part which is located right of decimal point
+
+ returns FIXP_DBL
+*****************************************************************************/
+FIXP_DBL fixp_truncate(FIXP_DBL f_inp, INT sf) {
+ FDK_ASSERT(sf >= 0);
+ INT truncateInt = fixp_truncateToInt(f_inp, sf);
+ FIXP_DBL f_truncate = (FIXP_DBL)(truncateInt << ((DFRACT_BITS - 1) - sf));
+ return f_truncate;
+}
+
+/*****************************************************************************
+ fixp_roundToInt()
+ round [typical rounding]
+
+ See fct roundRef() [which is the reference]
+ returns INT
+*****************************************************************************/
+INT fixp_roundToInt(FIXP_DBL f_inp, INT sf) {
+ FDK_ASSERT(sf >= 0);
+ INT sx = DFRACT_BITS - 1 - sf;
+ INT inp = (INT)f_inp;
+ INT mask1 = (0x1 << (sx - 1));
+ INT mask2 = (0x1 << (sx)) - 1;
+ INT mask3 = 0x7FFFFFFF;
+ INT iam = inp & mask2;
+ INT rnd;
+
+ if ((inp < 0) && !(iam == mask1))
+ rnd = inp + mask1;
+ else if ((inp > 0) && !(inp == mask3))
+ rnd = inp + mask1;
+ else
+ rnd = inp;
+
+ rnd = rnd >> sx;
+
+ if (inp == mask3) rnd++;
+
+ return rnd;
+}
+
+/*****************************************************************************
+ fixp_round()
+ round [typical rounding]
+
+ See fct roundRef() [which is the reference]
+ returns FIXP_DBL
+*****************************************************************************/
+FIXP_DBL fixp_round(FIXP_DBL f_inp, INT sf) {
+ FDK_ASSERT(sf >= 0);
+ INT sx = DFRACT_BITS - 1 - sf;
+ INT r = fixp_roundToInt(f_inp, sf);
+ ULONG mask = (ULONG)0x1 << (DFRACT_BITS - 1); // 0x80000000
+ r = r << sx;
+
+ if ((f_inp > FL2FXCONST_DBL(0.0f)) && (r & mask)) {
+ --r;
+ }
+
+ FIXP_DBL f_round = (FIXP_DBL)r;
+ return f_round;
+}
diff --git a/fdk-aac/libFDK/src/huff_nodes.cpp b/fdk-aac/libFDK/src/huff_nodes.cpp
new file mode 100644
index 0000000..66dc908
--- /dev/null
+++ b/fdk-aac/libFDK/src/huff_nodes.cpp
@@ -0,0 +1,1084 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Omer Osman
+
+ Description: MPEG-D SAC/USAC/SAOC Huffman Part0 Tables
+
+*******************************************************************************/
+
+#include "huff_nodes.h"
+
+const HUFF_PT0_NODES FDK_huffPart0Nodes = {
+ {{2, 1}, {4, 3}, {6, 5}, {8, 7}, {10, 9}, {12, 11},
+ {14, 13}, {-8, 15}, {-9, 16}, {-10, 17}, {-18, 18}, {-17, -19},
+ {-16, 19}, {-11, -20}, {-15, -21}, {-7, 20}, {-22, 21}, {-12, -14},
+ {-13, -23}, {23, 22}, {-24, -31}, {-6, 24}, {-25, -26}, {26, 25},
+ {-5, -27}, {-28, 27}, {-4, 28}, {-29, 29}, {-1, -30}, {-2, -3}},
+ {{2, 1}, {-5, 3}, {-4, -6}, {-3, 4}, {-2, 5}, {-1, 6}, {-7, -8}},
+ {{-1, 1}, {-8, 2}, {-2, 3}, {5, 4}, {-7, 6}, {-3, -5}, {-4, -6}},
+ {{-1, 1},
+ {3, 2},
+ {-8, 4},
+ {6, 5},
+ {-16, 7},
+ {9, 8},
+ {11, 10},
+ {-2, -7},
+ {-6, 12},
+ {-4, -5},
+ {-3, 13},
+ {-10, 14},
+ {-11, -12},
+ {-14, -15},
+ {-9, -13}},
+ {{2, 1}, {4, 3}, {6, 5}, {8, 7}, {10, 9}, {12, 11},
+ {14, 13}, {16, 15}, {18, 17}, {20, 19}, {22, 21}, {24, 23},
+ {26, 25}, {28, 27}, {30, 29}, {32, 31}, {-47, 33}, {-54, 34},
+ {-46, 35}, {-48, 36}, {-23, -27}, {-45, 37}, {-55, 38}, {-22, -49},
+ {-24, -53}, {-44, 39}, {-57, 40}, {-28, 41}, {-52, -56}, {-43, 42},
+ {-50, 43}, {-25, -26}, {-29, -64}, {-62, 44}, {-21, -51}, {-58, 45},
+ {-32, 46}, {-31, -42}, {-60, 47}, {-30, 48}, {-20, -61}, {-41, -63},
+ {-19, -59}, {-40, 49}, {-18, -38}, {-39, 50}, {-36, -37}, {-35, 51},
+ {-17, 52}, {-16, -34}, {-33, 53}, {-15, 54}, {-14, 55}, {-13, 56},
+ {-12, 57}, {-11, 58}, {-10, 59}, {-9, 60}, {-7, 61}, {-1, -4},
+ {-6, 62}, {-5, -8}, {-2, -3}}};
+
+const HUFF_LAV_NODES FDK_huffLavIdxNodes = {{{-1, 1}, {-2, 2}, {-3, -4}}};
+
+static const HUFF_ICC_NOD_1D FDK_huffICCNodes_h1D_0 = {
+ {{-1, 1}, {-2, 2}, {-3, 3}, {-4, 4}, {-5, 5}, {-6, 6}, {-7, -8}}};
+
+static const HUFF_ICC_NOD_2D FDK_huffICCNodes_h2D_0_0 = {
+ {{-1, 1}, {-18, 2}, {-2, -17}},
+ {{2, 1},
+ {-1, -52},
+ {-2, 3},
+ {5, 4},
+ {-51, 6},
+ {-18, 7},
+ {-17, 8},
+ {-3, 9},
+ {-36, 10},
+ {-19, -50},
+ {-35, 11},
+ {-4, 12},
+ {-34, 13},
+ {-33, 14},
+ {-20, -49}},
+ {{2, 1}, {-86, 3}, {-1, 4}, {6, 5}, {-2, 7}, {-85, 8},
+ {-18, 9}, {11, 10}, {-17, 12}, {14, 13}, {-70, 15}, {-3, -19},
+ {-69, 16}, {-84, 17}, {-68, 18}, {-20, -35}, {-34, -83}, {20, 19},
+ {-4, 21}, {-33, 22}, {-5, 23}, {-53, 24}, {-36, -52}, {-67, 25},
+ {-21, -82}, {-54, 26}, {-6, 27}, {-51, 28}, {-50, 29}, {-49, 30},
+ {-37, 31}, {-38, 0}, {0, 0}, {0, 0}, {0, 0}},
+ {{2, 1}, {4, 3}, {-1, -120}, {6, 5}, {8, 7}, {-18, 9},
+ {-2, 10}, {12, 11}, {14, 13}, {-17, -119}, {16, 15}, {-103, 17},
+ {-104, 18}, {-52, 19}, {21, 20}, {-69, 22}, {24, 23}, {-3, -35},
+ {-19, 25}, {-34, -85}, {27, 26}, {-86, 28}, {-118, 29}, {-37, 30},
+ {32, 31}, {-102, 33}, {-20, -22}, {-4, -117}, {-87, 34}, {-100, 35},
+ {-33, -36}, {37, 36}, {-70, -88}, {-101, 38}, {-5, 39}, {-51, -53},
+ {-50, 40}, {-115, 41}, {-21, 42}, {-116, 43}, {-38, 44}, {-23, -84},
+ {-49, -99}, {46, 45}, {-6, -114}, {-7, -72}, {-71, 47}, {-8, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}}};
+static const HUFF_ICC_NOD_2D FDK_huffICCNodes_h2D_0_1 = {
+ {{-1, 1}, {-18, 2}, {-2, -17}},
+ {{2, 1},
+ {-1, -52},
+ {-17, 3},
+ {5, 4},
+ {-36, 6},
+ {-2, 7},
+ {-18, -33},
+ {9, 8},
+ {-20, 10},
+ {-34, -51},
+ {-49, 11},
+ {-35, 12},
+ {-19, 13},
+ {-3, 14},
+ {-4, -50}},
+ {{2, 1}, {-86, 3}, {-1, 4}, {-17, 5}, {7, 6}, {-70, 8},
+ {-33, 9}, {-18, 10}, {-2, 11}, {-54, 12}, {-49, 13}, {-38, 14},
+ {-34, -65}, {-85, 15}, {-50, 16}, {-69, 17}, {-22, 18}, {-53, 19},
+ {21, 20}, {-19, -81}, {-66, 22}, {-3, -35}, {24, 23}, {-37, 25},
+ {-68, -84}, {-51, 26}, {28, 27}, {-20, -52}, {30, 29}, {-4, -36},
+ {-83, 31}, {-67, 32}, {-82, 33}, {-21, 34}, {-5, -6}},
+ {{2, 1}, {-1, 3}, {-120, 4}, {-17, 5}, {7, 6}, {-104, 8},
+ {-33, 9}, {11, 10}, {13, 12}, {-49, 14}, {-88, 15}, {-18, -97},
+ {-65, 16}, {-40, 17}, {-2, -72}, {19, 18}, {-113, 20}, {-34, 21},
+ {-56, -81}, {23, 22}, {-50, 24}, {-82, -119}, {-24, -103}, {26, 25},
+ {28, 27}, {30, 29}, {-55, -87}, {-66, 31}, {33, 32}, {-98, 34},
+ {-35, -67}, {-19, 35}, {-70, 36}, {-71, 37}, {-51, -52}, {-3, 38},
+ {40, 39}, {-86, -118}, {42, 41}, {-39, -69}, {-54, -83}, {44, 43},
+ {-102, 45}, {-101, 46}, {-68, -85}, {-36, -53}, {-5, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}}};
+static const HUFF_ICC_NOD_2D FDK_huffICCNodes_h2D_1_0 = {
+ {{-1, 1}, {-18, 2}, {-2, -17}},
+ {{-52, 1},
+ {-1, 2},
+ {4, 3},
+ {-2, -17},
+ {-18, 5},
+ {-36, 6},
+ {-51, 7},
+ {9, 8},
+ {-33, 10},
+ {-34, 11},
+ {-35, 12},
+ {-19, -20},
+ {-3, 13},
+ {-49, 14},
+ {-4, -50}},
+ {{-1, 1}, {-86, 2}, {4, 3}, {-17, 5}, {-2, 6}, {-18, 7},
+ {-70, 8}, {-85, 9}, {11, 10}, {13, 12}, {-33, 14}, {16, 15},
+ {-34, -54}, {-69, 17}, {-38, 18}, {-50, 19}, {-35, -53}, {-49, 20},
+ {-19, 21}, {-3, 22}, {-65, 23}, {-68, 24}, {-22, 25}, {-81, -84},
+ {-66, 26}, {-37, 27}, {-20, -51}, {29, 28}, {-52, 30}, {-4, -83},
+ {-36, 31}, {-67, 32}, {-5, 33}, {-82, 34}, {-21, 0}},
+ {{-1, 1}, {-120, 2}, {4, 3}, {-17, 5}, {-2, 6}, {8, 7},
+ {-18, 9}, {-104, 10}, {12, 11}, {14, 13}, {16, 15}, {-119, 17},
+ {-81, 18}, {20, 19}, {-33, 21}, {-88, 22}, {-103, 23}, {-34, 24},
+ {-56, 25}, {-72, 26}, {-49, 27}, {-82, 28}, {-50, 29}, {-65, 30},
+ {-55, -87}, {-19, 31}, {-67, 32}, {-35, -40}, {34, 33}, {-52, -71},
+ {-66, 35}, {-70, 36}, {38, 37}, {-51, -97}, {-86, -102}, {-3, 39},
+ {-118, 40}, {42, 41}, {-24, -85}, {-54, 43}, {-39, 44}, {-98, -113},
+ {-36, -37}, {-20, -69}, {-4, 45}, {-5, 46}, {-21, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}}};
+static const HUFF_ICC_NOD_2D FDK_huffICCNodes_h2D_1_1 = {
+ {{-1, 1}, {-18, 2}, {-2, -17}},
+ {{-52, 1},
+ {-1, 2},
+ {4, 3},
+ {-2, 5},
+ {-17, -18},
+ {-51, 6},
+ {-36, 7},
+ {9, 8},
+ {-35, 10},
+ {-3, 11},
+ {-19, -34},
+ {-33, 12},
+ {-50, 13},
+ {-20, 14},
+ {-4, -49}},
+ {{2, 1}, {-86, 3}, {-1, 4}, {6, 5}, {-18, 7}, {-2, -17},
+ {9, 8}, {-70, 10}, {-69, -85}, {-35, 11}, {13, 12}, {-34, 14},
+ {-19, 15}, {-53, 16}, {-68, 17}, {-33, 18}, {-3, -52}, {20, 19},
+ {-54, 21}, {-84, 22}, {-50, 23}, {-20, -51}, {-36, 24}, {26, 25},
+ {-83, 27}, {-4, -38}, {-49, 28}, {-37, 29}, {-67, 30}, {-5, 31},
+ {-21, 32}, {-65, -66}, {-82, 33}, {-22, 34}, {-6, -81}},
+ {{2, 1}, {-1, -120}, {4, 3}, {6, 5}, {-18, 7}, {9, 8},
+ {-17, 10}, {-2, 11}, {-103, 12}, {-52, 13}, {-35, -104}, {-119, 14},
+ {16, 15}, {-69, -86}, {18, 17}, {-34, 19}, {-19, 20}, {22, 21},
+ {-70, 23}, {-87, 24}, {-102, 25}, {-85, 26}, {-33, 27}, {-36, 28},
+ {-3, 29}, {-88, 30}, {-51, 31}, {-118, 32}, {34, 33}, {-68, 35},
+ {-53, 36}, {-67, 37}, {-20, 38}, {-101, 39}, {-50, 40}, {42, 41},
+ {-37, 43}, {-116, 44}, {-117, 45}, {-49, 46}, {-21, -100}, {48, 47},
+ {-55, -71}, {-4, 49}, {-22, -84}, {-115, 50}, {-66, -82}, {-72, 51},
+ {-5, -6}, {-54, 52}, {-38, 53}, {-83, 54}, {-40, 55}, {-39, 56},
+ {-99, 57}, {-23, -56}, {-7, 58}, {-65, -97}, {-8, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}}};
+
+const HUFF_ICC_NODES FDK_huffICCNodes = {
+ {&FDK_huffICCNodes_h1D_0, &FDK_huffICCNodes_h1D_0, &FDK_huffICCNodes_h1D_0},
+ {{&FDK_huffICCNodes_h2D_0_0, &FDK_huffICCNodes_h2D_0_1},
+ {&FDK_huffICCNodes_h2D_1_0, &FDK_huffICCNodes_h2D_1_1},
+ {&FDK_huffICCNodes_h2D_0_1, &FDK_huffICCNodes_h2D_0_1}}};
+
+static const HUFF_CLD_NOD_1D FDK_huffCLDNodes_h1D_0 = {
+ {{-1, 1}, {-2, 2}, {-3, 3}, {-4, 4}, {-5, 5}, {-6, 6},
+ {-7, 7}, {-8, 8}, {-9, 9}, {-10, 10}, {-11, 11}, {-12, 12},
+ {-13, 13}, {15, 14}, {-14, 16}, {-15, 17}, {-16, 18}, {-17, 19},
+ {-18, 20}, {-19, 21}, {-20, -21}, {-23, 22}, {-22, 23}, {-24, 24},
+ {-25, 25}, {27, 26}, {29, 28}, {-30, -31}, {-28, -29}, {-26, -27}}};
+static const HUFF_CLD_NOD_1D FDK_huffCLDNodes_h1D_1 = {
+ {{-1, 1}, {-2, 2}, {-3, 3}, {-4, 4}, {-5, 5}, {-6, 6},
+ {-7, 7}, {9, 8}, {-8, 10}, {-9, 11}, {-10, 12}, {-11, 13},
+ {-12, 14}, {-13, 15}, {-14, 16}, {-15, 17}, {-16, 18}, {-17, 19},
+ {-18, 20}, {-19, -20}, {-21, 21}, {-22, 22}, {-23, 23}, {25, 24},
+ {-24, 26}, {-25, 27}, {29, 28}, {-26, -31}, {-29, -30}, {-27, -28}}};
+
+static const HUFF_CLD_NOD_2D FDK_huffCLDNodes_h2_0_0 = {
+ {{2, 1},
+ {-1, -52},
+ {4, 3},
+ {-2, 5},
+ {-51, 6},
+ {-17, -18},
+ {8, 7},
+ {10, 9},
+ {-3, -36},
+ {-19, 11},
+ {-35, -50},
+ {-34, 12},
+ {-4, 13},
+ {-33, 14},
+ {-20, -49}},
+ {{2, 1}, {4, 3}, {-86, 5}, {7, 6}, {9, 8}, {-1, -2},
+ {-85, 10}, {-18, 11}, {-17, 12}, {14, 13}, {-70, 15}, {17, 16},
+ {-19, -69}, {-84, 18}, {-3, 19}, {21, 20}, {-34, -68}, {-20, 22},
+ {-35, 23}, {-83, 24}, {-33, 25}, {-4, 26}, {-53, 27}, {-54, -67},
+ {-36, 28}, {-21, -52}, {-82, 29}, {-5, -50}, {-51, 30}, {-38, 31},
+ {-37, -49}, {-6, 32}, {-66, 33}, {-65, 34}, {-22, -81}},
+ {{2, 1}, {4, 3}, {-120, 5}, {7, 6}, {9, 8}, {11, 10},
+ {-1, 12}, {-18, -119}, {-2, 13}, {15, 14}, {-17, 16}, {-104, 17},
+ {19, 18}, {-19, 20}, {-103, 21}, {-118, 22}, {24, 23}, {-3, 25},
+ {27, 26}, {-34, 28}, {-102, 29}, {-20, 30}, {-35, 31}, {33, 32},
+ {-117, 34}, {-33, 35}, {-88, 36}, {-4, 37}, {-87, 38}, {40, 39},
+ {-36, -101}, {-86, 41}, {-21, -37}, {-85, -100}, {-52, 42}, {-22, 43},
+ {-116, 44}, {-50, 45}, {47, 46}, {-5, -51}, {-115, 48}, {-70, 49},
+ {-84, 50}, {-38, -49}, {-72, -99}, {-53, 51}, {-69, -71}, {-23, 52},
+ {-6, -67}, {-114, 53}, {-7, 54}, {-66, -68}, {-55, 55}, {57, 56},
+ {-54, -65}, {-8, -56}, {-82, -83}, {59, 58}, {-39, -40}, {-81, 60},
+ {-98, 61}, {-97, 62}, {-24, -113}},
+ {{2, 1}, {4, 3}, {6, 5}, {-154, 7}, {9, 8},
+ {11, 10}, {13, 12}, {15, 14}, {-18, 16}, {-153, 17},
+ {-1, -2}, {19, 18}, {-138, 20}, {-17, 21}, {23, 22},
+ {25, 24}, {-19, -137}, {27, 26}, {-152, 28}, {30, 29},
+ {-3, -34}, {32, 31}, {34, 33}, {36, 35}, {-136, 37},
+ {-35, 38}, {-20, 39}, {-122, 40}, {-151, 41}, {-33, 42},
+ {-121, 43}, {45, 44}, {47, 46}, {-4, 48}, {-36, -120},
+ {-135, 49}, {51, 50}, {-21, 52}, {54, 53}, {56, 55},
+ {-50, -150}, {58, 57}, {-51, 59}, {61, 60}, {-119, 62},
+ {-52, 63}, {-5, 64}, {-37, 65}, {-117, -134}, {-39, -54},
+ {-22, 66}, {-106, 67}, {-69, -102}, {-132, 68}, {-105, 69},
+ {-49, 70}, {-149, 71}, {-24, -104}, {73, 72}, {-53, 74},
+ {-38, -118}, {-103, 75}, {-6, 76}, {-66, -87}, {-133, -147},
+ {-23, 77}, {-67, 78}, {-68, -86}, {-70, -101}, {-40, -148},
+ {-116, 79}, {-55, 80}, {-84, -131}, {82, 81}, {-89, -90},
+ {-7, -25}, {-85, -88}, {-65, 83}, {-72, -146}, {85, 84},
+ {-9, -71}, {-83, 86}, {-82, 87}, {-8, 88}, {-100, 89},
+ {-74, -99}, {-73, 90}, {-10, -81}, {-56, 91}, {-57, -98},
+ {93, 92}, {-58, -114}, {-97, -115}, {95, 94}, {-41, 96},
+ {-42, 97}, {-26, -129}, {-113, 98}, {-130, -145}}};
+static const HUFF_CLD_NOD_2D FDK_huffCLDNodes_h2_0_1 = {
+ {{-1, 1},
+ {-52, 2},
+ {-17, 3},
+ {5, 4},
+ {-36, 6},
+ {-33, 7},
+ {-2, -18},
+ {-20, 8},
+ {10, 9},
+ {-34, -49},
+ {-51, 11},
+ {-35, 12},
+ {-19, 13},
+ {-3, 14},
+ {-4, -50}},
+ {{2, 1}, {4, 3}, {-86, 5}, {-1, 6}, {-17, 7}, {-70, 8},
+ {10, 9}, {-18, 11}, {-33, 12}, {-54, 13}, {-2, 14}, {-34, 15},
+ {-38, 16}, {-49, 17}, {-85, 18}, {-50, 19}, {-69, 20}, {-53, -65},
+ {-22, 21}, {-66, 22}, {-19, 23}, {-37, 24}, {-35, -81}, {-3, 25},
+ {-51, 26}, {-68, -84}, {-52, 27}, {29, 28}, {-20, 30}, {-4, -36},
+ {-83, 31}, {-67, 32}, {-21, 33}, {-5, 34}, {-6, -82}},
+ {{2, 1}, {4, 3}, {6, 5}, {-120, 7}, {-17, 8}, {-1, -104},
+ {10, 9}, {12, 11}, {-18, 13}, {-33, -88}, {15, 14}, {17, 16},
+ {-2, 18}, {-34, 19}, {-72, 20}, {-49, 21}, {-119, 22}, {-50, 23},
+ {-103, 24}, {-56, 25}, {-65, 26}, {28, 27}, {-40, -87}, {-66, 29},
+ {-82, 30}, {32, 31}, {-19, -81}, {-71, 33}, {-97, 34}, {-35, -55},
+ {-24, 35}, {37, 36}, {-3, -98}, {-51, 38}, {-67, 39}, {-39, -118},
+ {-113, 40}, {-102, 41}, {-86, 42}, {-70, -83}, {44, 43}, {-20, -54},
+ {-52, 45}, {-36, 46}, {-4, 47}, {-68, 48}, {-85, 49}, {-101, -117},
+ {-69, 50}, {52, 51}, {-21, -37}, {-53, 53}, {55, 54}, {-5, -100},
+ {-116, 56}, {-84, 57}, {-38, 58}, {-22, -99}, {-115, 59}, {-6, 60},
+ {-23, 61}, {-7, 62}, {-114, 0}},
+ {{2, 1}, {4, 3}, {6, 5}, {-154, 7}, {9, 8},
+ {-17, 10}, {-138, 11}, {-1, 12}, {14, 13}, {16, 15},
+ {-33, -122}, {-18, 17}, {19, 18}, {-34, 20}, {-2, 21},
+ {-106, 22}, {-49, 23}, {25, 24}, {-50, 26}, {-153, 27},
+ {-90, 28}, {-137, 29}, {-65, 30}, {32, 31}, {-66, 33},
+ {-121, 34}, {-74, 35}, {-81, 36}, {38, 37}, {-42, 39},
+ {-82, 40}, {-105, 41}, {-19, -114}, {-58, 42}, {-35, 43},
+ {-97, 44}, {46, 45}, {-129, 47}, {-26, -89}, {-57, -98},
+ {-51, 48}, {-3, 49}, {-113, 50}, {-130, 51}, {-152, 52},
+ {-67, -73}, {-99, -136}, {-145, 53}, {-120, 54}, {-41, 55},
+ {-83, 56}, {-72, 57}, {-104, 58}, {-115, 59}, {-20, 60},
+ {62, 61}, {-36, -88}, {-84, 63}, {-52, -56}, {65, 64},
+ {-4, -87}, {-68, 66}, {-151, 67}, {-100, -135}, {69, 68},
+ {-69, -119}, {-103, 70}, {-71, 71}, {73, 72}, {-21, 74},
+ {-85, 75}, {-37, -53}, {-86, 76}, {78, 77}, {-102, -150},
+ {-5, 79}, {-134, 80}, {-118, 81}, {-54, -117}, {83, 82},
+ {-38, -70}, {-22, 84}, {-6, 85}, {87, 86}, {-55, 88},
+ {-101, 89}, {-133, -149}, {-24, -39}, {91, 90}, {-132, 92},
+ {-23, 93}, {-7, 94}, {-147, -148}, {-116, -131}, {-25, 95},
+ {-40, 0}, {0, 0}, {0, 0}, {0, 0}}};
+static const HUFF_CLD_NOD_2D FDK_huffCLDNodes_h2_1_0 = {
+ {{-1, 1},
+ {-52, 2},
+ {-17, 3},
+ {5, 4},
+ {-2, -36},
+ {-18, 6},
+ {8, 7},
+ {-51, 9},
+ {-33, 10},
+ {-34, 11},
+ {-20, -35},
+ {-19, 12},
+ {-3, 13},
+ {-49, 14},
+ {-4, -50}},
+ {{2, 1}, {-86, 3}, {-1, 4}, {-17, 5}, {7, 6}, {-70, 8},
+ {-2, -18}, {10, 9}, {12, 11}, {-85, 13}, {-33, 14}, {-34, -54},
+ {16, 15}, {-69, 17}, {19, 18}, {-50, -53}, {-19, 20}, {-38, 21},
+ {-35, -49}, {-3, 22}, {24, 23}, {-68, 25}, {-84, 26}, {-65, 27},
+ {-51, -66}, {-22, -37}, {-52, 28}, {-20, 29}, {-36, 30}, {-81, 31},
+ {-4, -83}, {-67, 32}, {-21, 33}, {-5, 34}, {-6, -82}},
+ {{2, 1}, {-120, 3}, {-1, 4}, {6, 5}, {-17, 7}, {-104, 8},
+ {-18, 9}, {-2, 10}, {12, 11}, {14, 13}, {-119, 15}, {-33, 16},
+ {-34, -88}, {-103, 17}, {19, 18}, {21, 20}, {23, 22}, {25, 24},
+ {-19, -72}, {-50, 26}, {-49, 27}, {-87, 28}, {30, 29}, {32, 31},
+ {-3, -35}, {34, 33}, {-56, 35}, {-65, -66}, {-40, 36}, {-82, -118},
+ {-71, 37}, {-55, 38}, {-67, -102}, {-51, 39}, {-70, 40}, {42, 41},
+ {-81, 43}, {-86, 44}, {-52, -97}, {-98, 45}, {-24, -39}, {-20, 46},
+ {-54, -83}, {-36, 47}, {-85, 48}, {-68, 49}, {-4, 50}, {-69, -113},
+ {-117, 51}, {-37, -101}, {-53, 52}, {-21, 53}, {55, 54}, {-84, -100},
+ {-5, 56}, {-116, 57}, {-22, 58}, {-38, -115}, {60, 59}, {-6, -99},
+ {-23, 61}, {-114, 62}, {-7, -8}},
+ {{2, 1}, {-154, 3}, {5, 4}, {-1, 6}, {8, 7},
+ {-17, 9}, {-138, 10}, {-18, 11}, {-2, 12}, {14, 13},
+ {16, 15}, {-153, 17}, {-34, 18}, {-33, -122}, {20, 19},
+ {22, 21}, {-137, 23}, {25, 24}, {27, 26}, {-106, 28},
+ {30, 29}, {-50, 31}, {-19, 32}, {-49, -121}, {34, 33},
+ {36, 35}, {-35, 37}, {-90, 38}, {-66, 39}, {-3, 40},
+ {42, 41}, {-65, 43}, {-105, 44}, {46, 45}, {-74, 47},
+ {-51, 48}, {-82, -152}, {-136, 49}, {-81, 50}, {-42, -89},
+ {-114, 51}, {53, 52}, {-57, -58}, {-120, 54}, {-98, 55},
+ {-67, 56}, {-97, 57}, {59, 58}, {-99, 60}, {-73, -104},
+ {-72, 61}, {-113, 62}, {-20, -83}, {-84, -130}, {-36, 63},
+ {-26, 64}, {-41, 65}, {-52, -129}, {-87, -88}, {67, 66},
+ {-115, 68}, {-68, 69}, {-56, -69}, {-4, -100}, {-151, 70},
+ {-135, 71}, {-103, -119}, {73, 72}, {-71, -145}, {-102, 74},
+ {76, 75}, {-53, -85}, {-37, 77}, {-21, -86}, {79, 78},
+ {-5, 80}, {-54, -134}, {-150, 81}, {-118, 82}, {-70, 83},
+ {-117, 84}, {-22, -38}, {-101, 85}, {-55, 86}, {-149, 87},
+ {-39, 88}, {-133, 89}, {-6, 90}, {-116, 91}, {-24, 92},
+ {-7, -132}, {-23, 93}, {-40, 94}, {-131, -148}, {-25, 95},
+ {-147, 96}, {-146, 97}, {-8, 0}, {0, 0}}};
+static const HUFF_CLD_NOD_2D FDK_huffCLDNodes_h2_1_1 = {
+ {{-1, 1},
+ {-52, 2},
+ {4, 3},
+ {-2, 5},
+ {-17, 6},
+ {-18, 7},
+ {-36, -51},
+ {9, 8},
+ {-35, 10},
+ {-34, 11},
+ {-19, -33},
+ {-3, 12},
+ {-20, 13},
+ {-50, 14},
+ {-4, -49}},
+ {{2, 1}, {-86, 3}, {5, 4}, {-1, 6}, {8, 7}, {-17, -18},
+ {-2, 9}, {-70, 10}, {-85, 11}, {13, 12}, {-69, 14}, {-34, 15},
+ {17, 16}, {-19, 18}, {-33, -35}, {-54, 19}, {-53, 20}, {-3, 21},
+ {-68, 22}, {-84, 23}, {-50, 24}, {-52, 25}, {-51, 26}, {-20, -36},
+ {-49, 27}, {-38, 28}, {-37, 29}, {-4, -83}, {-67, 30}, {-66, 31},
+ {-21, 32}, {-22, -65}, {-5, 33}, {-82, 34}, {-6, -81}},
+ {{2, 1}, {4, 3}, {-120, 5}, {7, 6}, {9, 8}, {-1, 10},
+ {-18, 11}, {-17, 12}, {-2, -104}, {-119, 13}, {15, 14}, {-103, 16},
+ {18, 17}, {-34, 19}, {-19, 20}, {22, 21}, {-35, 23}, {-33, 24},
+ {-88, 25}, {-87, 26}, {28, 27}, {-3, -102}, {-86, 29}, {-52, -118},
+ {31, 30}, {-50, 32}, {-51, 33}, {-70, 34}, {-36, 35}, {-85, 36},
+ {-20, 37}, {39, 38}, {-69, -71}, {-72, 40}, {-49, -67}, {42, 41},
+ {-68, 43}, {-4, -101}, {-53, -117}, {-37, 44}, {-66, 45}, {-55, 46},
+ {48, 47}, {-54, 49}, {-21, 50}, {-84, -100}, {-56, -65}, {52, 51},
+ {-82, -83}, {54, 53}, {-5, -116}, {-22, 55}, {-38, 56}, {-39, -40},
+ {58, 57}, {-81, -115}, {-98, -99}, {-6, 59}, {-23, 60}, {-24, 61},
+ {-7, -97}, {-114, 62}, {-8, -113}},
+ {{2, 1}, {4, 3}, {-154, 5}, {7, 6}, {9, 8},
+ {11, 10}, {-1, 12}, {-18, 13}, {-17, 14}, {-2, -138},
+ {16, 15}, {-153, 17}, {-137, 18}, {20, 19}, {22, 21},
+ {-34, 23}, {-19, 24}, {-35, 25}, {27, 26}, {29, 28},
+ {-121, 30}, {-120, 31}, {-136, 32}, {-33, -122}, {34, 33},
+ {-152, 35}, {-3, 36}, {-51, 37}, {-52, 38}, {-69, 39},
+ {-36, 40}, {-50, 41}, {43, 42}, {-20, 44}, {-104, 45},
+ {-103, 46}, {-87, 47}, {-119, 48}, {-105, 49}, {-86, 50},
+ {-102, 51}, {-106, 52}, {-49, -135}, {-68, 53}, {55, 54},
+ {-53, 56}, {-67, -151}, {-4, 57}, {-84, 58}, {-85, 59},
+ {-66, 60}, {-37, 61}, {-70, 62}, {-54, -88}, {-21, 63},
+ {65, 64}, {-89, 66}, {-118, 67}, {-72, 68}, {-90, 69},
+ {-71, 70}, {-65, -134}, {-150, 71}, {-83, 72}, {-5, 73},
+ {-101, -117}, {-82, 74}, {76, 75}, {-99, 77}, {-38, 78},
+ {-100, 79}, {-22, 80}, {-73, 81}, {-39, -74}, {83, 82},
+ {-55, -81}, {-57, 84}, {-133, -149}, {-56, 85}, {-6, 86},
+ {-98, 87}, {-132, 88}, {-23, 89}, {-114, 90}, {-116, 91},
+ {-58, -115}, {-24, 92}, {-97, -148}, {-40, -41}, {-7, -42},
+ {-147, 93}, {95, 94}, {-131, 96}, {-8, -130}, {-25, -113},
+ {-9, 97}, {-26, -129}, {-146, 98}, {-10, -145}}};
+
+const HUFF_CLD_NODES FDK_huffCLDNodes = {
+ {&FDK_huffCLDNodes_h1D_0, &FDK_huffCLDNodes_h1D_1, &FDK_huffCLDNodes_h1D_1},
+ {{&FDK_huffCLDNodes_h2_0_0, &FDK_huffCLDNodes_h2_0_1},
+ {&FDK_huffCLDNodes_h2_1_0, &FDK_huffCLDNodes_h2_1_1},
+ {&FDK_huffCLDNodes_h2_0_1, &FDK_huffCLDNodes_h2_0_1}}};
+
+const HUFF_RES_NODES FDK_huffReshapeNodes = {
+ {{2, 1}, {4, 3}, {6, 5}, {-33, 7}, {-17, 8}, {-49, 9},
+ {-34, 10}, {12, 11}, {-18, -35}, {-50, 13}, {15, 14}, {-40, 16},
+ {-36, 17}, {-19, 18}, {-1, -37}, {-51, 19}, {21, 20}, {-38, -65},
+ {-2, -39}, {-20, 22}, {-52, 23}, {25, 24}, {-21, 26}, {-66, 27},
+ {-53, 28}, {-3, 29}, {31, 30}, {-22, 32}, {-54, 33}, {-4, 34},
+ {-56, 35}, {-24, -67}, {-23, -55}, {-8, -72}, {-5, 36}, {-68, 37},
+ {-6, 38}, {-7, -69}, {-70, -71}}};
+
+const HUFF_IPD_NODES FDK_huffIPDNodes = {
+ {{{{-1, 1}, {-8, 2}, {-2, 3}, {5, 4}, {-3, -7}, {-6, 6}, {-4, -5}}},
+ {{{-1, 1}, {-2, 2}, {-8, 3}, {-3, 4}, {-7, 5}, {-4, 6}, {-5, -6}}},
+ {{{-1, 1}, {-8, 2}, {-2, 3}, {5, 4}, {-3, -7}, {-6, 6}, {-4, -5}}}},
+ {{{{{-1, 1}, {-18, 2}, {-17, 0}},
+ {{-1, 1},
+ {-36, 2},
+ {-18, 3},
+ {-35, 4},
+ {-52, 5},
+ {7, 6},
+ {-34, 8},
+ {-33, -49},
+ {-20, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}},
+ {{-1, 1}, {3, 2}, {5, 4}, {-86, 6}, {-66, 7}, {9, 8},
+ {11, 10}, {-18, 12}, {-51, 13}, {-37, -52}, {-69, 14}, {-38, 15},
+ {-53, 16}, {-35, 17}, {-50, -70}, {-22, -49}, {-33, 18}, {-17, 19},
+ {-34, -65}, {-81, 20}, {-54, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
+ {{2, 1}, {4, 3}, {-1, 5}, {-69, 6}, {-120, 7}, {-68, 8},
+ {10, 9}, {12, 11}, {14, 13}, {-52, -54}, {-18, 15}, {-70, 16},
+ {-67, 17}, {19, 18}, {-17, 20}, {-113, 21}, {23, 22}, {-83, 24},
+ {-24, 25}, {-103, -104}, {-51, -55}, {27, 26}, {-71, 28}, {-86, 29},
+ {-35, 30}, {-66, 31}, {-39, -50}, {-82, -98}, {-72, 32}, {-56, -87},
+ {-34, 33}, {-33, -88}, {-40, -97}, {-65, 34}, {-49, 35}, {-81, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}}},
+ {{{-1, 1}, {-18, 2}, {-17, 0}},
+ {{-1, 1},
+ {-36, 2},
+ {-18, 3},
+ {-35, 4},
+ {-52, 5},
+ {7, 6},
+ {-34, 8},
+ {-33, -49},
+ {-20, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}},
+ {{-1, 1}, {3, 2}, {5, 4}, {-86, 6}, {-66, 7}, {9, 8},
+ {11, 10}, {-18, 12}, {-51, 13}, {-37, -52}, {-69, 14}, {-38, 15},
+ {-53, 16}, {-35, 17}, {-50, -70}, {-22, -49}, {-33, 18}, {-17, 19},
+ {-34, -65}, {-81, 20}, {-54, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
+ {{2, 1}, {4, 3}, {-1, 5}, {-69, 6}, {-120, 7}, {-68, 8},
+ {10, 9}, {12, 11}, {14, 13}, {-52, -54}, {-18, 15}, {-70, 16},
+ {-67, 17}, {19, 18}, {-17, 20}, {-113, 21}, {23, 22}, {-83, 24},
+ {-24, 25}, {-103, -104}, {-51, -55}, {27, 26}, {-71, 28}, {-86, 29},
+ {-35, 30}, {-66, 31}, {-39, -50}, {-82, -98}, {-72, 32}, {-56, -87},
+ {-34, 33}, {-33, -88}, {-40, -97}, {-65, 34}, {-49, 35}, {-81, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}}}},
+ {{{{-1, 1}, {-18, 2}, {-17, 0}},
+ {{-1, 1},
+ {3, 2},
+ {-18, 4},
+ {-52, 5},
+ {-34, -36},
+ {-35, 6},
+ {-17, 7},
+ {-33, 8},
+ {-20, 9},
+ {-49, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}},
+ {{-1, 1}, {3, 2}, {-52, 4}, {-86, 5}, {-35, 6}, {-53, 7},
+ {-70, 8}, {-17, 9}, {-37, 10}, {12, 11}, {-38, -66}, {-18, 13},
+ {-51, 14}, {16, 15}, {-34, -69}, {18, 17}, {-54, -65}, {-50, 19},
+ {-33, -49}, {-22, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
+ {{-1, 1}, {-69, 2}, {4, 3}, {-120, 5}, {7, 6}, {-113, 8},
+ {-68, 9}, {11, 10}, {-17, 12}, {-52, 13}, {-24, 14}, {-18, 15},
+ {17, 16}, {-104, 18}, {20, 19}, {-54, -70}, {22, 21}, {24, 23},
+ {-86, -97}, {-103, 25}, {-83, 26}, {-35, 27}, {-34, -98}, {-40, 28},
+ {-39, -67}, {30, 29}, {-33, -51}, {-87, 31}, {-88, 32}, {-82, 33},
+ {-55, -81}, {-56, -71}, {-72, 34}, {-50, -66}, {-65, 35}, {-49, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}}},
+ {{{-1, 1}, {-18, 2}, {-17, 0}},
+ {{-1, 1},
+ {3, 2},
+ {-18, 4},
+ {-52, 5},
+ {-34, -36},
+ {-35, 6},
+ {-17, 7},
+ {-33, 8},
+ {-20, 9},
+ {-49, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}},
+ {{-1, 1}, {3, 2}, {-52, 4}, {-86, 5}, {-35, 6}, {-53, 7},
+ {-70, 8}, {-17, 9}, {-37, 10}, {12, 11}, {-38, -66}, {-18, 13},
+ {-51, 14}, {16, 15}, {-34, -69}, {18, 17}, {-54, -65}, {-50, 19},
+ {-33, -49}, {-22, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
+ {{-1, 1}, {-69, 2}, {4, 3}, {-120, 5}, {7, 6}, {-113, 8},
+ {-68, 9}, {11, 10}, {-17, 12}, {-52, 13}, {-24, 14}, {-18, 15},
+ {17, 16}, {-104, 18}, {20, 19}, {-54, -70}, {22, 21}, {24, 23},
+ {-86, -97}, {-103, 25}, {-83, 26}, {-35, 27}, {-34, -98}, {-40, 28},
+ {-39, -67}, {30, 29}, {-33, -51}, {-87, 31}, {-88, 32}, {-82, 33},
+ {-55, -81}, {-56, -71}, {-72, 34}, {-50, -66}, {-65, 35}, {-49, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}}}},
+ {{{{-1, 1}, {-18, 2}, {-17, 0}},
+ {{-1, 1},
+ {-36, 2},
+ {-18, 3},
+ {-35, 4},
+ {-52, 5},
+ {7, 6},
+ {-34, 8},
+ {-33, -49},
+ {-20, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}},
+ {{-1, 1}, {3, 2}, {5, 4}, {-86, 6}, {-66, 7}, {9, 8},
+ {11, 10}, {-18, 12}, {-51, 13}, {-37, -52}, {-69, 14}, {-38, 15},
+ {-53, 16}, {-35, 17}, {-50, -70}, {-22, -49}, {-33, 18}, {-17, 19},
+ {-34, -65}, {-81, 20}, {-54, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
+ {{2, 1}, {4, 3}, {-1, 5}, {-69, 6}, {-120, 7}, {-68, 8},
+ {10, 9}, {12, 11}, {14, 13}, {-52, -54}, {-18, 15}, {-70, 16},
+ {-67, 17}, {19, 18}, {-17, 20}, {-113, 21}, {23, 22}, {-83, 24},
+ {-24, 25}, {-103, -104}, {-51, -55}, {27, 26}, {-71, 28}, {-86, 29},
+ {-35, 30}, {-66, 31}, {-39, -50}, {-82, -98}, {-72, 32}, {-56, -87},
+ {-34, 33}, {-33, -88}, {-40, -97}, {-65, 34}, {-49, 35}, {-81, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}}},
+ {{{-1, 1}, {-18, 2}, {-17, 0}},
+ {{-1, 1},
+ {-36, 2},
+ {-18, 3},
+ {-35, 4},
+ {-52, 5},
+ {7, 6},
+ {-34, 8},
+ {-33, -49},
+ {-20, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 0}},
+ {{-1, 1}, {3, 2}, {5, 4}, {-86, 6}, {-66, 7}, {9, 8},
+ {11, 10}, {-18, 12}, {-51, 13}, {-37, -52}, {-69, 14}, {-38, 15},
+ {-53, 16}, {-35, 17}, {-50, -70}, {-22, -49}, {-33, 18}, {-17, 19},
+ {-34, -65}, {-81, 20}, {-54, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}},
+ {{2, 1}, {4, 3}, {-1, 5}, {-69, 6}, {-120, 7}, {-68, 8},
+ {10, 9}, {12, 11}, {14, 13}, {-52, -54}, {-18, 15}, {-70, 16},
+ {-67, 17}, {19, 18}, {-17, 20}, {-113, 21}, {23, 22}, {-83, 24},
+ {-24, 25}, {-103, -104}, {-51, -55}, {27, 26}, {-71, 28}, {-86, 29},
+ {-35, 30}, {-66, 31}, {-39, -50}, {-82, -98}, {-72, 32}, {-56, -87},
+ {-34, 33}, {-33, -88}, {-40, -97}, {-65, 34}, {-49, 35}, {-81, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}}}}}};
+
+static const HUFF_OLD_NOD_1D huffOLDNodes_h1D_0 = {{{-1, 1},
+ {3, 2},
+ {-2, 4},
+ {-3, 5},
+ {-4, 6},
+ {-5, 7},
+ {-6, -8},
+ {-7, 8},
+ {10, 9},
+ {12, 11},
+ {-9, -11},
+ {-10, 13},
+ {-12, 14},
+ {-13, -16},
+ {-14, -15}}};
+
+static const HUFF_OLD_NOD_1D huffOLDNodes_h1D_1 = {{{-1, 1},
+ {-2, 2},
+ {4, 3},
+ {-3, 5},
+ {-4, 6},
+ {-5, 7},
+ {-6, -8},
+ {-7, 8},
+ {10, 9},
+ {12, 11},
+ {-9, 13},
+ {-16, 14},
+ {-10, -15},
+ {-11, -12},
+ {-13, -14}}};
+
+static const HUFF_OLD_NOD_2D huffOLDNodes_h2D_0_0 = {
+ {{2, 1},
+ {-1, 3},
+ {5, 4},
+ {-2, 6},
+ {-3, -4},
+ {-17, 7},
+ {-18, 8},
+ {-19, 9},
+ {-20, 10},
+ {-52, 11},
+ {-33, 12},
+ {-34, -35},
+ {-36, 13},
+ {-51, 14},
+ {-49, -50}},
+ {{-1, 1}, {3, 2}, {5, 4}, {7, 6}, {-103, 8}, {10, 9},
+ {12, 11}, {-18, 13}, {15, 14}, {-2, 16}, {-86, 17}, {-35, 18},
+ {20, 19}, {-102, 21}, {23, 22}, {-69, 24}, {-87, 25}, {-3, 26},
+ {-17, 27}, {-19, 28}, {-52, 29}, {-34, -101}, {31, 30}, {-85, 32},
+ {34, 33}, {-20, -70}, {-4, 35}, {-71, -100}, {-5, -33}, {-50, 36},
+ {-36, -55}, {-54, -84}, {38, 37}, {-51, -53}, {-21, 39}, {-6, -99},
+ {-37, -68}, {-83, 40}, {-7, -49}, {-22, -98}, {42, 41}, {44, 43},
+ {-66, 45}, {-67, 46}, {-38, -39}, {-65, -82}, {-23, 47}, {-81, -97}},
+ {{-1, 1}, {3, 2}, {5, 4}, {7, 6}, {9, 8},
+ {11, 10}, {13, 12}, {15, 14}, {-154, 16}, {-103, 17},
+ {19, 18}, {21, 20}, {-18, 22}, {24, 23}, {26, 25},
+ {28, 27}, {-137, 29}, {31, 30}, {-2, -51}, {33, 32},
+ {-35, 34}, {-26, 35}, {37, 36}, {-8, 38}, {-70, -153},
+ {40, 39}, {-120, 41}, {-52, 42}, {44, 43}, {-3, -138},
+ {46, 45}, {48, 47}, {-34, 49}, {-7, 50}, {-19, 51},
+ {-17, 52}, {-152, 53}, {-4, -151}, {-33, 54}, {-106, 55},
+ {-53, -122}, {-105, -136}, {-121, 56}, {-104, 57}, {-50, -118},
+ {-20, 58}, {-5, 59}, {-38, 60}, {-133, 61}, {-148, 62},
+ {-23, -135}, {-36, 63}, {-6, 64}, {66, 65}, {-21, -150},
+ {68, 67}, {-49, 69}, {-134, 70}, {-119, 71}, {-37, 72},
+ {-149, 73}, {-9, 74}, {-69, 75}, {-86, 76}, {-22, 77},
+ {-68, 78}, {80, 79}, {82, 81}, {84, 83}, {-88, 85},
+ {-132, 86}, {-90, 87}, {-10, -117}, {-67, 88}, {-71, 89},
+ {-87, 90}, {-54, -66}, {-25, 91}, {-89, 92}, {-72, 93},
+ {-131, 94}, {-113, -115}, {-99, 95}, {-73, -116}, {-24, -85},
+ {-84, -102}, {-39, 96}, {-55, -98}, {-81, -97}, {-82, -83},
+ {-114, 97}, {-146, -147}, {-42, -101}, {-57, -100}, {-65, -130},
+ {-74, 98}, {-56, -58}, {-40, -129}, {-41, -145}},
+ {{2, 1}, {4, 3}, {6, 5}, {8, 7}, {10, 9},
+ {12, 11}, {-4, 13}, {-11, -28}, {-21, 14}, {-1, 15},
+ {17, 16}, {19, 18}, {-38, 20}, {22, 21}, {24, 23},
+ {26, 25}, {28, 27}, {-54, 29}, {31, 30}, {-44, 32},
+ {-45, 33}, {-37, 34}, {-5, 35}, {-27, 36}, {38, 37},
+ {40, 39}, {-53, 41}, {-12, 42}, {-22, 43}, {-20, 44},
+ {-36, 45}, {-43, 46}, {-6, 47}, {-205, 48}, {-51, -52},
+ {-35, 49}, {-34, 50}, {-13, 51}, {-42, 52}, {-29, 53},
+ {-18, -41}, {55, 54}, {-17, -26}, {-19, 56}, {-7, 57},
+ {-23, -188}, {59, 58}, {-10, 60}, {62, 61}, {-39, 63},
+ {-33, 64}, {-2, 65}, {-204, 66}, {68, 67}, {-189, 69},
+ {-171, 70}, {72, 71}, {74, 73}, {-203, 75}, {-3, -25},
+ {-24, 76}, {78, 77}, {80, 79}, {82, 81}, {-173, 83},
+ {-172, -187}, {85, 84}, {-86, 86}, {-50, 87}, {-202, 88},
+ {90, 89}, {-154, 91}, {93, 92}, {-120, 94}, {96, 95},
+ {-186, 97}, {99, 98}, {-69, 100}, {-156, -157}, {102, 101},
+ {104, 103}, {-170, -201}, {-103, 105}, {107, 106}, {-155, 108},
+ {-137, 109}, {-185, 110}, {-49, 111}, {-8, 112}, {-66, 113},
+ {-67, 114}, {116, 115}, {-169, 117}, {-141, 118}, {120, 119},
+ {122, 121}, {-200, 123}, {-68, -121}, {125, 124}, {-136, 126},
+ {-140, 127}, {-71, 128}, {-139, 129}, {-151, -184}, {-82, 130},
+ {-56, -101}, {132, 131}, {-9, -153}, {-40, 133}, {-138, 134},
+ {-83, -199}, {-84, 135}, {-90, -168}, {-65, -91}, {-102, 136},
+ {-135, -166}, {-72, -183}, {-87, -150}, {-181, 137}, {-125, 138},
+ {-55, -70}, {-85, -152}, {-106, -124}, {-89, -123}, {-198, 139},
+ {-57, 140}, {-105, 141}, {-167, -196}, {-81, -122}, {-182, 142},
+ {-99, -180}, {-100, -104}, {-116, -165}, {-98, 143}, {-117, -119},
+ {-88, -134}, {-197, 144}, {-73, -195}, {-92, -149}, {-118, -164},
+ {-58, -108}, {-107, -179}, {-109, 145}, {-93, -97}, {-115, -194},
+ {-114, 146}, {-113, 147}, {149, 148}, {151, 150}, {153, 152},
+ {155, 154}, {157, 156}, {159, 158}, {161, 160}, {163, 162},
+ {165, 164}, {167, 166}, {-178, -193}, {-163, -177}, {-161, -162},
+ {-147, -148}, {-145, -146}, {-132, -133}, {-130, -131}, {-77, -129},
+ {-75, -76}, {-61, -74}, {-59, -60}}};
+
+static const HUFF_OLD_NOD_2D huffOLDNodes_h2D_0_1 = {
+ {{-1, 1},
+ {3, 2},
+ {5, 4},
+ {-52, 6},
+ {-49, 7},
+ {9, 8},
+ {-17, 10},
+ {-36, 11},
+ {-18, 12},
+ {-2, -3},
+ {-35, 13},
+ {-34, -50},
+ {-4, -33},
+ {-20, 14},
+ {-19, -51}},
+ {{-1, 1}, {3, 2}, {-103, 4}, {6, 5}, {8, 7}, {-18, 9},
+ {11, 10}, {-87, 12}, {-17, 13}, {15, 14}, {-86, 16}, {18, 17},
+ {-71, 19}, {21, 20}, {-33, -35}, {-34, 22}, {-55, 23}, {-2, 24},
+ {-50, -102}, {26, 25}, {-49, 27}, {-69, -70}, {-39, 28}, {-65, 29},
+ {-66, 30}, {-54, 31}, {-19, 32}, {-23, -52}, {-51, 33}, {-81, 34},
+ {-82, 35}, {-3, -38}, {-85, -101}, {-67, -97}, {37, 36}, {-20, -53},
+ {-36, 38}, {40, 39}, {-100, 41}, {-4, -84}, {-68, 42}, {-21, 43},
+ {-37, 44}, {-99, 45}, {-5, -83}, {-22, 46}, {-98, 47}, {-6, -7}},
+ {{-1, 1}, {3, 2}, {5, 4}, {7, 6}, {9, 8},
+ {-154, 10}, {12, 11}, {14, 13}, {-18, 15}, {17, 16},
+ {19, 18}, {21, 20}, {-17, 22}, {-137, 23}, {-35, 24},
+ {-138, 25}, {27, 26}, {-113, 28}, {-34, 29}, {31, 30},
+ {33, 32}, {-122, 34}, {-33, 35}, {-73, 36}, {38, 37},
+ {40, 39}, {-106, 41}, {-52, 42}, {-58, -120}, {-50, 43},
+ {45, 44}, {-49, 46}, {-10, -103}, {-36, 47}, {-54, -90},
+ {-53, 48}, {-2, 49}, {-98, -153}, {-121, 50}, {-66, 51},
+ {-65, -72}, {-51, 52}, {-74, 53}, {-9, 54}, {-105, 55},
+ {-71, -82}, {-19, -55}, {-81, 56}, {58, 57}, {-83, 59},
+ {-68, -88}, {-89, -97}, {-70, 60}, {-3, 61}, {-67, 62},
+ {64, 63}, {-69, 65}, {-104, 66}, {-136, -152}, {68, 67},
+ {-8, -26}, {-37, 69}, {-4, 70}, {72, 71}, {-22, 73},
+ {-42, 74}, {-7, -20}, {76, 75}, {78, 77}, {-6, 79},
+ {-114, 80}, {-25, -135}, {-119, -151}, {-24, 81}, {-57, 82},
+ {-5, 83}, {-99, 84}, {-23, -130}, {-129, 85}, {-118, 86},
+ {-21, -41}, {-86, 87}, {-115, -145}, {-84, 88}, {-87, -150},
+ {-38, -56}, {-134, 89}, {-100, 90}, {-85, -133}, {-149, 91},
+ {-102, 92}, {-117, -148}, {94, 93}, {-39, 95}, {-101, 96},
+ {-116, 97}, {-131, -132}, {-40, 98}, {-146, -147}},
+ {{2, 1}, {-1, 3}, {5, 4}, {7, 6}, {9, 8},
+ {-205, 10}, {12, 11}, {14, 13}, {16, 15}, {-18, 17},
+ {19, 18}, {21, 20}, {23, 22}, {-189, 24}, {-188, 25},
+ {27, 26}, {-17, 28}, {-173, 29}, {31, 30}, {33, 32},
+ {-34, -157}, {-35, 34}, {-33, 35}, {37, 36}, {39, 38},
+ {41, 40}, {-50, 42}, {-49, 43}, {-141, 44}, {-204, 45},
+ {-2, -171}, {-172, 46}, {-66, 47}, {49, 48}, {51, 50},
+ {-65, 52}, {-125, 53}, {-156, 54}, {-82, 55}, {57, 56},
+ {59, 58}, {-19, -52}, {61, 60}, {-81, 62}, {64, 63},
+ {-109, -140}, {-51, 65}, {67, 66}, {-98, 68}, {70, 69},
+ {72, 71}, {-67, -93}, {74, 73}, {-203, 75}, {-154, 76},
+ {-124, 77}, {-97, -187}, {-114, 78}, {-61, 79}, {-155, 80},
+ {82, 81}, {-113, 83}, {-3, -146}, {-83, 84}, {-108, 85},
+ {-20, 86}, {-76, 87}, {-45, -77}, {-139, 88}, {90, 89},
+ {-69, -130}, {-129, 91}, {-36, 92}, {-99, -161}, {94, 93},
+ {-92, -162}, {-68, 95}, {-29, 96}, {-86, 97}, {-60, 98},
+ {-123, -177}, {-145, 99}, {-91, -131}, {101, 100}, {-137, -178},
+ {-115, 102}, {-84, -116}, {-147, 103}, {-4, 104}, {-106, -202},
+ {106, 105}, {-132, -186}, {-107, 107}, {-193, 108}, {-100, -120},
+ {-75, -170}, {-44, 109}, {-122, -163}, {-138, 110}, {-90, 111},
+ {-37, 112}, {-101, 113}, {-121, 114}, {116, 115}, {-103, 117},
+ {-74, -201}, {-21, -85}, {-53, -59}, {-117, 118}, {-148, 119},
+ {-5, 120}, {-169, 121}, {-105, -185}, {123, 122}, {-102, -133},
+ {-136, 124}, {-153, 125}, {127, 126}, {-54, 128}, {130, 129},
+ {-22, -104}, {-38, 131}, {-89, -118}, {-184, 132}, {-71, 133},
+ {-87, 134}, {-70, 135}, {-200, 136}, {-168, 137}, {-152, 138},
+ {-6, -23}, {-39, 139}, {-119, -199}, {141, 140}, {-55, 142},
+ {-7, -151}, {-183, 143}, {145, 144}, {-135, 146}, {-56, 147},
+ {-150, 148}, {-40, 149}, {-72, -198}, {-88, 150}, {-57, -134},
+ {-41, 151}, {-166, -167}, {-25, -165}, {-9, 152}, {-8, -24},
+ {-73, -181}, {-182, 153}, {155, 154}, {-197, 156}, {-42, -180},
+ {158, 157}, {-43, -149}, {-196, 159}, {-58, -164}, {-26, 160},
+ {162, 161}, {164, 163}, {166, 165}, {-195, 167}, {-179, -194},
+ {-27, -28}, {-12, -13}, {-10, -11}}};
+
+static const HUFF_OLD_NOD_2D huffOLDNodes_h2D_1_0 = {
+ {{-1, 1},
+ {-52, 2},
+ {4, 3},
+ {-18, 5},
+ {7, 6},
+ {-17, 8},
+ {-36, 9},
+ {-35, 10},
+ {-2, 11},
+ {-19, 12},
+ {-33, -51},
+ {-20, -34},
+ {14, 13},
+ {-3, -49},
+ {-4, -50}},
+ {{-1, 1}, {3, 2}, {5, 4}, {-103, 6}, {8, 7}, {-18, 9},
+ {11, 10}, {13, 12}, {-86, 14}, {-87, 15}, {17, 16}, {-35, 18},
+ {-17, 19}, {21, 20}, {-34, -71}, {23, 22}, {-50, -55}, {-33, 24},
+ {-69, 25}, {-2, -70}, {27, 26}, {-102, 28}, {-49, 29}, {-66, 30},
+ {-39, -54}, {-52, 31}, {-51, 32}, {-65, 33}, {-19, 34}, {-38, -82},
+ {-23, -85}, {-67, 35}, {-81, 36}, {-3, 37}, {-53, -101}, {-20, -97},
+ {39, 38}, {-36, 40}, {-84, 41}, {-100, 42}, {-4, -68}, {-21, 43},
+ {-37, 44}, {-83, 45}, {-5, -99}, {-22, 46}, {-98, 47}, {-6, -7}},
+ {{-1, 1}, {3, 2}, {5, 4}, {7, 6}, {9, 8},
+ {-154, 10}, {12, 11}, {14, 13}, {-18, 15}, {17, 16},
+ {-113, 18}, {20, 19}, {-137, 21}, {23, 22}, {25, 24},
+ {27, 26}, {-35, 28}, {-138, 29}, {-58, 30}, {-103, 31},
+ {-98, 32}, {34, 33}, {-122, 35}, {-120, 36}, {-17, -73},
+ {-34, 37}, {-106, 38}, {-50, 39}, {-83, -90}, {-74, 40},
+ {-52, 41}, {-66, -121}, {-33, -88}, {43, 42}, {-82, -105},
+ {-49, 44}, {-68, -153}, {-2, -89}, {-51, -65}, {-67, 45},
+ {-81, -97}, {47, 46}, {-104, 48}, {-19, 49}, {51, 50},
+ {53, 52}, {55, 54}, {-136, 56}, {-152, 57}, {-3, 58},
+ {60, 59}, {62, 61}, {64, 63}, {-36, 65}, {-20, 66},
+ {-53, 67}, {-114, 68}, {-57, -99}, {-72, 69}, {-69, 70},
+ {-42, 71}, {-151, 72}, {-119, 73}, {-84, -118}, {-135, 74},
+ {-4, -130}, {-115, 75}, {-26, -41}, {-87, 76}, {-56, -86},
+ {-100, 77}, {-37, -129}, {-21, 78}, {-38, 79}, {-71, -145},
+ {-134, 80}, {-85, 81}, {-150, 82}, {-5, 83}, {-133, 84},
+ {-102, 85}, {-22, 86}, {-23, 87}, {-54, 88}, {-149, 89},
+ {-117, -148}, {-70, 90}, {-6, -101}, {92, 91}, {-8, -55},
+ {-7, 93}, {-132, 94}, {-39, -116}, {-24, 95}, {-147, 96},
+ {-40, 97}, {-10, -131}, {-146, 98}, {-9, -25}},
+ {{2, 1}, {-1, 3}, {5, 4}, {7, 6}, {9, 8},
+ {11, 10}, {13, 12}, {-205, 14}, {16, 15}, {18, 17},
+ {20, 19}, {-18, 21}, {23, 22}, {25, 24}, {27, 26},
+ {29, 28}, {-188, 30}, {32, 31}, {34, 33}, {36, 35},
+ {-189, 37}, {39, 38}, {-35, 40}, {42, 41}, {44, 43},
+ {46, 45}, {-173, 47}, {49, 48}, {-34, 50}, {-17, 51},
+ {53, 52}, {-157, 54}, {56, 55}, {58, 57}, {-171, 59},
+ {-50, 60}, {62, 61}, {-66, -141}, {-172, 63}, {-125, 64},
+ {66, 65}, {-33, 67}, {-52, 68}, {-204, 69}, {-82, 70},
+ {-156, 71}, {-2, 72}, {74, 73}, {-109, 75}, {-51, -98},
+ {77, 76}, {-49, -140}, {79, 78}, {-146, 80}, {-124, 81},
+ {-61, -93}, {-19, -76}, {-81, -154}, {-65, -114}, {83, 82},
+ {-83, -108}, {-67, 84}, {-77, 85}, {-130, 86}, {-99, -155},
+ {88, 87}, {-97, 89}, {-69, -91}, {-92, 90}, {-131, 91},
+ {93, 92}, {-116, -187}, {-123, 94}, {-60, 95}, {-86, -139},
+ {97, 96}, {-68, -162}, {99, 98}, {-45, -113}, {-147, -203},
+ {-115, 100}, {-75, 101}, {-84, -106}, {-129, 102}, {-3, 103},
+ {-137, 104}, {-132, 105}, {-44, -120}, {-107, 106}, {-20, -100},
+ {-36, 107}, {-90, -163}, {-161, 108}, {-59, -145}, {-101, 109},
+ {-29, -138}, {-121, 110}, {-177, -178}, {-186, 111}, {-122, -148},
+ {-117, 112}, {-85, -170}, {-202, 113}, {-4, 114}, {-37, -105},
+ {-74, 115}, {-133, 116}, {-102, 117}, {119, 118}, {-89, -193},
+ {-103, 120}, {-21, -53}, {-153, 121}, {123, 122}, {125, 124},
+ {-185, 126}, {-104, -169}, {-201, 127}, {-136, 128}, {-118, 129},
+ {-87, 130}, {-5, 131}, {-38, 132}, {-54, 133}, {-70, -184},
+ {-71, -168}, {-22, 134}, {136, 135}, {-151, -152}, {-55, 137},
+ {-6, 138}, {-39, -72}, {-200, 139}, {-167, 140}, {142, 141},
+ {-119, -166}, {-88, 143}, {-23, -135}, {-199, 144}, {-165, 145},
+ {-56, -150}, {-57, -183}, {-7, 146}, {-41, 147}, {-181, 148},
+ {-134, 149}, {-24, -25}, {-40, 150}, {-73, 151}, {-9, 152},
+ {-43, 153}, {-182, -197}, {-8, -195}, {-198, 154}, {-149, 155},
+ {157, 156}, {159, 158}, {161, 160}, {163, 162}, {165, 164},
+ {167, 166}, {-194, -196}, {-179, -180}, {-58, -164}, {-28, -42},
+ {-26, -27}, {-12, -13}, {-10, -11}}};
+
+static const HUFF_OLD_NOD_2D huffOLDNodes_h2D_1_1 = {
+ {{-1, 1},
+ {-52, 2},
+ {4, 3},
+ {6, 5},
+ {-18, 7},
+ {-2, 8},
+ {-17, 9},
+ {-35, 10},
+ {-36, -51},
+ {-34, 11},
+ {-33, 12},
+ {-19, 13},
+ {-3, -20},
+ {-50, 14},
+ {-4, -49}},
+ {{-1, 1}, {3, 2}, {5, 4}, {-103, 6}, {8, 7}, {-18, 9},
+ {11, 10}, {13, 12}, {-86, 14}, {16, 15}, {-2, -35}, {-17, 17},
+ {-87, 18}, {-102, 19}, {21, 20}, {-69, 22}, {-34, 23}, {-19, 24},
+ {26, 25}, {-3, 27}, {-52, -70}, {-33, -71}, {-85, 28}, {-101, 29},
+ {31, 30}, {-50, 32}, {-51, 33}, {-20, 34}, {-36, 35}, {-4, -55},
+ {-54, 36}, {-49, -100}, {-53, 37}, {-84, 38}, {-68, 39}, {41, 40},
+ {-5, 42}, {-21, 43}, {-65, -66}, {-67, 44}, {-37, -99}, {-39, 45},
+ {-6, 46}, {-38, -83}, {-22, 47}, {-81, -82}, {-7, -98}, {-23, -97}},
+ {{-1, 1}, {3, 2}, {5, 4}, {7, 6}, {9, 8},
+ {-154, 10}, {-103, 11}, {13, 12}, {-18, 14}, {16, 15},
+ {-137, 17}, {19, 18}, {-35, 20}, {22, 21}, {-120, 23},
+ {25, 24}, {-52, 26}, {-2, 27}, {-138, 28}, {-153, 29},
+ {-17, 30}, {32, 31}, {34, 33}, {-34, 35}, {-19, 36},
+ {38, 37}, {40, 39}, {-3, 41}, {-121, 42}, {-122, 43},
+ {-136, -152}, {-33, 44}, {-104, 45}, {-105, 46}, {-51, -106},
+ {-50, 47}, {-36, 48}, {-20, 49}, {-53, -119}, {-4, 50},
+ {-135, -151}, {-68, 51}, {53, 52}, {-49, 54}, {56, 55},
+ {-118, 57}, {-88, 58}, {60, 59}, {-5, -8}, {-38, 61},
+ {63, 62}, {-21, 64}, {-37, -83}, {-67, 65}, {-66, -133},
+ {-6, 66}, {-150, 67}, {-134, 68}, {-23, -65}, {-73, -90},
+ {-69, -89}, {-148, 69}, {-7, -22}, {-98, -113}, {71, 70},
+ {-82, 72}, {-86, -149}, {-58, -81}, {-74, 73}, {75, 74},
+ {77, 76}, {-87, -97}, {-102, 78}, {80, 79}, {-84, 81},
+ {-85, 82}, {-54, 83}, {-70, 84}, {-72, 85}, {-117, 86},
+ {-71, 87}, {-99, 88}, {-101, 89}, {-39, -100}, {-55, 90},
+ {-57, 91}, {-132, 92}, {-56, 93}, {-24, -114}, {-115, 94},
+ {-40, -116}, {-42, -147}, {-9, -41}, {-131, 95}, {97, 96},
+ {-129, 98}, {-25, -130}, {-26, -146}, {-10, -145}},
+ {{2, 1}, {-1, 3}, {5, 4}, {7, 6}, {9, 8},
+ {11, 10}, {13, 12}, {-205, 14}, {16, 15}, {18, 17},
+ {-18, 19}, {21, 20}, {23, 22}, {-188, 24}, {26, 25},
+ {28, 27}, {30, 29}, {-35, 31}, {33, 32}, {35, 34},
+ {-171, 36}, {-189, 37}, {-204, 38}, {40, 39}, {-2, 41},
+ {43, 42}, {-17, 44}, {-52, 45}, {-34, 46}, {-19, 47},
+ {49, 48}, {-154, 50}, {52, 51}, {54, 53}, {-172, 55},
+ {-173, 56}, {-69, -187}, {-203, 57}, {59, 58}, {-86, 60},
+ {-3, 61}, {63, 62}, {-33, -50}, {-51, 64}, {-36, 65},
+ {-137, 66}, {-20, 67}, {69, 68}, {-120, 70}, {72, 71},
+ {-156, -157}, {-155, 73}, {-170, 74}, {76, 75}, {-186, -202},
+ {78, 77}, {80, 79}, {82, 81}, {-4, -67}, {-49, -103},
+ {-66, 83}, {-68, 84}, {-53, 85}, {-21, 86}, {-37, 87},
+ {89, 88}, {91, 90}, {93, 92}, {-138, 94}, {-140, 95},
+ {-141, -153}, {-139, 96}, {-201, 97}, {-185, 98}, {-121, 99},
+ {-169, 100}, {-5, 101}, {-136, 102}, {-65, -84}, {-83, -85},
+ {-82, 103}, {-70, 104}, {-54, 105}, {-38, 106}, {108, 107},
+ {-101, 109}, {-22, -102}, {-122, -123}, {111, 110}, {113, 112},
+ {-125, 114}, {-87, -124}, {-71, 115}, {-168, 116}, {-6, -200},
+ {-184, 117}, {-152, 118}, {-81, 119}, {121, 120}, {-105, 122},
+ {-106, 123}, {-99, 124}, {-98, -100}, {-23, 125}, {-104, 126},
+ {-39, 127}, {-135, 128}, {-55, -151}, {130, 129}, {-91, -119},
+ {-7, -199}, {-183, 131}, {-107, -108}, {-116, 132}, {-109, -117},
+ {-56, -167}, {-97, 133}, {-90, 134}, {-72, 135}, {-115, -118},
+ {-92, 136}, {-93, -166}, {-24, -114}, {-89, 137}, {-88, -150},
+ {139, 138}, {-8, 140}, {-40, 141}, {-198, 142}, {-134, 143},
+ {-113, 144}, {-182, 145}, {147, 146}, {-41, 148}, {-57, -181},
+ {-131, 149}, {151, 150}, {-25, 152}, {-132, 153}, {155, 154},
+ {-9, -76}, {-42, -165}, {-73, -133}, {-77, 156}, {-130, 157},
+ {-75, -149}, {-10, -146}, {-26, 158}, {-197, 159}, {-180, 160},
+ {-147, -196}, {-58, -74}, {-27, 161}, {-129, -148}, {-11, -61},
+ {-60, 162}, {-59, 163}, {-43, -145}, {-12, -164}, {-161, 164},
+ {-163, 165}, {-162, -195}, {-179, 166}, {-177, 167}, {-28, -178},
+ {-45, -194}, {-29, -44}, {-13, -193}}};
+
+const HUFF_OLD_NODES huffOLDNodes = {
+ {&huffOLDNodes_h1D_0, &huffOLDNodes_h1D_1, &huffOLDNodes_h1D_1},
+ {{&huffOLDNodes_h2D_0_0, &huffOLDNodes_h2D_0_1},
+ {&huffOLDNodes_h2D_1_0, &huffOLDNodes_h2D_1_1},
+ {&huffOLDNodes_h2D_0_1, &huffOLDNodes_h2D_0_1}}};
diff --git a/fdk-aac/libFDK/src/mdct.cpp b/fdk-aac/libFDK/src/mdct.cpp
new file mode 100644
index 0000000..f5aa284
--- /dev/null
+++ b/fdk-aac/libFDK/src/mdct.cpp
@@ -0,0 +1,730 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Josef Hoepfl, Manuel Jander, Youliy Ninov, Daniel Hagel
+
+ Description: MDCT/MDST routines
+
+*******************************************************************************/
+
+#include "mdct.h"
+
+#include "FDK_tools_rom.h"
+#include "dct.h"
+#include "fixpoint_math.h"
+
+void mdct_init(H_MDCT hMdct, FIXP_DBL *overlap, INT overlapBufferSize) {
+ hMdct->overlap.freq = overlap;
+ // FDKmemclear(overlap, overlapBufferSize*sizeof(FIXP_DBL));
+ hMdct->prev_fr = 0;
+ hMdct->prev_nr = 0;
+ hMdct->prev_tl = 0;
+ hMdct->ov_size = overlapBufferSize;
+ hMdct->prevAliasSymmetry = 0;
+ hMdct->prevPrevAliasSymmetry = 0;
+ hMdct->pFacZir = NULL;
+ hMdct->pAsymOvlp = NULL;
+}
+
+/*
+This program implements the forward MDCT transform on an input block of data.
+The input block is in a form (A,B,C,D) where A,B,C and D are the respective
+1/4th segments of the block. The program takes the input block and folds it in
+the form:
+(-D-Cr,A-Br). This block is twice shorter and here the 'r' suffix denotes
+flipping of the sequence (reversing the order of the samples). While folding the
+input block in the above mentioned shorter block the program windows the data.
+Because the two operations (windowing and folding) are not implemented
+sequentially, but together the program's structure is not easy to understand.
+Once the output (already windowed) block (-D-Cr,A-Br) is ready it is passed to
+the DCT IV for processing.
+*/
+INT mdct_block(H_MDCT hMdct, const INT_PCM *RESTRICT timeData,
+ const INT noInSamples, FIXP_DBL *RESTRICT mdctData,
+ const INT nSpec, const INT tl, const FIXP_WTP *pRightWindowPart,
+ const INT fr, SHORT *pMdctData_e) {
+ int i, n;
+ /* tl: transform length
+ fl: left window slope length
+ nl: left window slope offset
+ fr: right window slope length
+ nr: right window slope offset
+ See FDK_tools/doc/intern/mdct.tex for more detail. */
+ int fl, nl, nr;
+ const FIXP_WTP *wls, *wrs;
+
+ wrs = pRightWindowPart;
+
+ /* Detect FRprevious / FL mismatches and override parameters accordingly */
+ if (hMdct->prev_fr ==
+ 0) { /* At start just initialize and pass parameters as they are */
+ hMdct->prev_fr = fr;
+ hMdct->prev_wrs = wrs;
+ hMdct->prev_tl = tl;
+ }
+
+ /* Derive NR */
+ nr = (tl - fr) >> 1;
+
+ /* Skip input samples if tl is smaller than block size */
+ timeData += (noInSamples - tl) >> 1;
+
+ /* windowing */
+ for (n = 0; n < nSpec; n++) {
+ /*
+ * MDCT scale:
+ * + 1: fMultDiv2() in windowing.
+ * + 1: Because of factor 1/2 in Princen-Bradley compliant windowed TDAC.
+ */
+ INT mdctData_e = 1 + 1;
+
+ /* Derive left parameters */
+ wls = hMdct->prev_wrs;
+ fl = hMdct->prev_fr;
+ nl = (tl - fl) >> 1;
+
+ /* Here we implement a simplified version of what happens after the this
+ piece of code (see the comments below). We implement the folding of A and B
+ segments to (A-Br) but A is zero, because in this part of the MDCT sequence
+ the window coefficients with which A must be multiplied are zero. */
+ for (i = 0; i < nl; i++) {
+#if SAMPLE_BITS == DFRACT_BITS /* SPC_BITS and DFRACT_BITS should be equal. */
+ mdctData[(tl / 2) + i] = -((FIXP_DBL)timeData[tl - i - 1] >> (1));
+#else
+ mdctData[(tl / 2) + i] = -(FIXP_DBL)timeData[tl - i - 1]
+ << (DFRACT_BITS - SAMPLE_BITS - 1); /* 0(A)-Br */
+#endif
+ }
+
+ /* Implements the folding and windowing of the left part of the sequence,
+ that is segments A and B. The A segment is multiplied by the respective left
+ window coefficient and placed in a temporary variable.
+
+ tmp0 = fMultDiv2((FIXP_PCM)timeData[i+nl], pLeftWindowPart[i].v.im);
+
+ After this the B segment taken in reverse order is multiplied by the left
+ window and subtracted from the previously derived temporary variable, so
+ that finally we implement the A-Br operation. This output is written to the
+ right part of the MDCT output : (-D-Cr,A-Br).
+
+ mdctData[(tl/2)+i+nl] = fMultSubDiv2(tmp0, (FIXP_PCM)timeData[tl-nl-i-1],
+ pLeftWindowPart[i].v.re);//A*window-Br*window
+
+ The (A-Br) data is written to the output buffer (mdctData) without being
+ flipped. */
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL tmp0;
+ tmp0 = fMultDiv2((FIXP_PCM)timeData[i + nl], wls[i].v.im); /* a*window */
+ mdctData[(tl / 2) + i + nl] =
+ fMultSubDiv2(tmp0, (FIXP_PCM)timeData[tl - nl - i - 1],
+ wls[i].v.re); /* A*window-Br*window */
+ }
+
+ /* Right window slope offset */
+ /* Here we implement a simplified version of what happens after the this
+ piece of code (see the comments below). We implement the folding of C and D
+ segments to (-D-Cr) but D is zero, because in this part of the MDCT sequence
+ the window coefficients with which D must be multiplied are zero. */
+ for (i = 0; i < nr; i++) {
+#if SAMPLE_BITS == \
+ DFRACT_BITS /* This should be SPC_BITS instead of DFRACT_BITS. */
+ mdctData[(tl / 2) - 1 - i] = -((FIXP_DBL)timeData[tl + i] >> (1));
+#else
+ mdctData[(tl / 2) - 1 - i] =
+ -(FIXP_DBL)timeData[tl + i]
+ << (DFRACT_BITS - SAMPLE_BITS - 1); /* -C flipped at placing */
+#endif
+ }
+
+ /* Implements the folding and windowing of the right part of the sequence,
+ that is, segments C and D. The C segment is multiplied by the respective
+ right window coefficient and placed in a temporary variable.
+
+ tmp1 = fMultDiv2((FIXP_PCM)timeData[tl+nr+i], pRightWindowPart[i].v.re);
+
+ After this the D segment taken in reverse order is multiplied by the right
+ window and added from the previously derived temporary variable, so that we
+ get (C+Dr) operation. This output is negated to get (-C-Dr) and written to
+ the left part of the MDCT output while being reversed (flipped) at the same
+ time, so that from (-C-Dr) we get (-D-Cr)=> (-D-Cr,A-Br).
+
+ mdctData[(tl/2)-nr-i-1] = -fMultAddDiv2(tmp1,
+ (FIXP_PCM)timeData[(tl*2)-nr-i-1], pRightWindowPart[i].v.im);*/
+ for (i = 0; i < fr / 2; i++) {
+ FIXP_DBL tmp1;
+ tmp1 = fMultDiv2((FIXP_PCM)timeData[tl + nr + i],
+ wrs[i].v.re); /* C*window */
+ mdctData[(tl / 2) - nr - i - 1] =
+ -fMultAddDiv2(tmp1, (FIXP_PCM)timeData[(tl * 2) - nr - i - 1],
+ wrs[i].v.im); /* -(C*window+Dr*window) and flip before
+ placing -> -Cr - D */
+ }
+
+ /* We pass the shortened folded data (-D-Cr,A-Br) to the MDCT function */
+ dct_IV(mdctData, tl, &mdctData_e);
+
+ pMdctData_e[n] = (SHORT)mdctData_e;
+
+ timeData += tl;
+ mdctData += tl;
+
+ hMdct->prev_wrs = wrs;
+ hMdct->prev_fr = fr;
+ hMdct->prev_tl = tl;
+ }
+
+ return nSpec * tl;
+}
+
+void imdct_gain(FIXP_DBL *pGain_m, int *pGain_e, int tl) {
+ FIXP_DBL gain_m = *pGain_m;
+ int gain_e = *pGain_e;
+ int log2_tl;
+
+ gain_e += -MDCT_OUTPUT_GAIN - MDCT_OUT_HEADROOM + 1;
+ if (tl == 0) {
+ /* Dont regard the 2/N factor from the IDCT. It is compensated for somewhere
+ * else. */
+ *pGain_e = gain_e;
+ return;
+ }
+
+ log2_tl = DFRACT_BITS - 1 - fNormz((FIXP_DBL)tl);
+ gain_e += -log2_tl;
+
+ FDK_ASSERT(log2_tl - 2 >= 0);
+ FDK_ASSERT(log2_tl - 2 < 8*sizeof(int));
+
+ /* Detect non-radix 2 transform length and add amplitude compensation factor
+ which cannot be included into the exponent above */
+ switch ((tl) >> (log2_tl - 2)) {
+ case 0x7: /* 10 ms, 1/tl = 1.0/(FDKpow(2.0, -log2_tl) *
+ 0.53333333333333333333) */
+ if (gain_m == (FIXP_DBL)0) {
+ gain_m = FL2FXCONST_DBL(0.53333333333333333333f);
+ } else {
+ gain_m = fMult(gain_m, FL2FXCONST_DBL(0.53333333333333333333f));
+ }
+ break;
+ case 0x6: /* 3/4 of radix 2, 1/tl = 1.0/(FDKpow(2.0, -log2_tl) * 2.0/3.0) */
+ if (gain_m == (FIXP_DBL)0) {
+ gain_m = FL2FXCONST_DBL(2.0 / 3.0f);
+ } else {
+ gain_m = fMult(gain_m, FL2FXCONST_DBL(2.0 / 3.0f));
+ }
+ break;
+ case 0x5: /* 0.8 of radix 2 (e.g. tl 160), 1/tl = 1.0/(FDKpow(2.0, -log2_tl)
+ * 0.8/1.5) */
+ if (gain_m == (FIXP_DBL)0) {
+ gain_m = FL2FXCONST_DBL(0.53333333333333333333f);
+ } else {
+ gain_m = fMult(gain_m, FL2FXCONST_DBL(0.53333333333333333333f));
+ }
+ break;
+ case 0x4:
+ /* radix 2, nothing to do. */
+ break;
+ default:
+ /* unsupported */
+ FDK_ASSERT(0);
+ break;
+ }
+
+ *pGain_m = gain_m;
+ *pGain_e = gain_e;
+}
+
+INT imdct_drain(H_MDCT hMdct, FIXP_DBL *output, INT nrSamplesRoom) {
+ int buffered_samples = 0;
+
+ if (nrSamplesRoom > 0) {
+ buffered_samples = hMdct->ov_offset;
+
+ FDK_ASSERT(buffered_samples <= nrSamplesRoom);
+
+ if (buffered_samples > 0) {
+ FDKmemcpy(output, hMdct->overlap.time,
+ buffered_samples * sizeof(FIXP_DBL));
+ hMdct->ov_offset = 0;
+ }
+ }
+ return buffered_samples;
+}
+
+INT imdct_copy_ov_and_nr(H_MDCT hMdct, FIXP_DBL *pTimeData, INT nrSamples) {
+ FIXP_DBL *pOvl;
+ int nt, nf, i;
+
+ nt = fMin(hMdct->ov_offset, nrSamples);
+ nrSamples -= nt;
+ nf = fMin(hMdct->prev_nr, nrSamples);
+ FDKmemcpy(pTimeData, hMdct->overlap.time, nt * sizeof(FIXP_DBL));
+ pTimeData += nt;
+
+ pOvl = hMdct->overlap.freq + hMdct->ov_size - 1;
+ if (hMdct->prevPrevAliasSymmetry == 0) {
+ for (i = 0; i < nf; i++) {
+ FIXP_DBL x = -(*pOvl--);
+ *pTimeData = IMDCT_SCALE_DBL(x);
+ pTimeData++;
+ }
+ } else {
+ for (i = 0; i < nf; i++) {
+ FIXP_DBL x = (*pOvl--);
+ *pTimeData = IMDCT_SCALE_DBL(x);
+ pTimeData++;
+ }
+ }
+
+ return (nt + nf);
+}
+
+void imdct_adapt_parameters(H_MDCT hMdct, int *pfl, int *pnl, int tl,
+ const FIXP_WTP *wls, int noOutSamples) {
+ int fl = *pfl, nl = *pnl;
+ int window_diff, use_current = 0, use_previous = 0;
+ if (hMdct->prev_tl == 0) {
+ hMdct->prev_wrs = wls;
+ hMdct->prev_fr = fl;
+ hMdct->prev_nr = (noOutSamples - fl) >> 1;
+ hMdct->prev_tl = noOutSamples;
+ hMdct->ov_offset = 0;
+ use_current = 1;
+ }
+
+ window_diff = (hMdct->prev_fr - fl) >> 1;
+
+ /* check if the previous window slope can be adjusted to match the current
+ * window slope */
+ if (hMdct->prev_nr + window_diff > 0) {
+ use_current = 1;
+ }
+ /* check if the current window slope can be adjusted to match the previous
+ * window slope */
+ if (nl - window_diff > 0) {
+ use_previous = 1;
+ }
+
+ /* if both is possible choose the larger of both window slope lengths */
+ if (use_current && use_previous) {
+ if (fl < hMdct->prev_fr) {
+ use_current = 0;
+ }
+ }
+ /*
+ * If the previous transform block is big enough, enlarge previous window
+ * overlap, if not, then shrink current window overlap.
+ */
+ if (use_current) {
+ hMdct->prev_nr += window_diff;
+ hMdct->prev_fr = fl;
+ hMdct->prev_wrs = wls;
+ } else {
+ nl -= window_diff;
+ fl = hMdct->prev_fr;
+ }
+
+ *pfl = fl;
+ *pnl = nl;
+}
+
+/*
+This program implements the inverse modulated lapped transform, a generalized
+version of the inverse MDCT transform. Setting none of the MLT_*_ALIAS_FLAG
+flags computes the IMDCT, setting all of them computes the IMDST. Other
+combinations of these flags compute type III transforms used by the RSVD60
+multichannel tool for transitions between MDCT/MDST. The following description
+relates to the IMDCT only.
+
+If we pass the data block (A,B,C,D,E,F) to the FORWARD MDCT it will produce two
+outputs. The first one will be over the (A,B,C,D) part =>(-D-Cr,A-Br) and the
+second one will be over the (C,D,E,F) part => (-F-Er,C-Dr), since there is a
+overlap between consequtive passes of the algorithm. This overlap is over the
+(C,D) segments. The two outputs will be given sequentially to the DCT IV
+algorithm. At the INVERSE MDCT side we get two consecutive outputs from the IDCT
+IV algorithm, namely the same blocks: (-D-Cr,A-Br) and (-F-Er,C-Dr). The first
+of them lands in the Overlap buffer and the second is in the working one, which,
+one algorithm pass later will substitute the one residing in the overlap
+register. The IMDCT algorithm has to produce the C and D segments from the two
+buffers. In order to do this we take the left part of the overlap
+buffer(-D-Cr,A-Br), namely (-D-Cr) and add it appropriately to the right part of
+the working buffer (-F-Er,C-Dr), namely (C-Dr), so that we get first the C
+segment and later the D segment. We do this in the following way: From the right
+part of the working buffer(C-Dr) we subtract the flipped left part of the
+overlap buffer(-D-Cr):
+
+Result = (C-Dr) - flipped(-D-Cr) = C -Dr + Dr + C = 2C
+We divide by two and get the C segment. What we did is adding the right part of
+the first frame to the left part of the second one. While applying these
+operation we multiply the respective segments with the appropriate window
+functions.
+
+In order to get the D segment we do the following:
+From the negated second part of the working buffer(C-Dr) we subtract the flipped
+first part of the overlap buffer (-D-Cr):
+
+Result= - (C -Dr) - flipped(-D-Cr)= -C +Dr +Dr +C = 2Dr.
+After dividing by two and flipping we get the D segment.What we did is adding
+the right part of the first frame to the left part of the second one. While
+applying these operation we multiply the respective segments with the
+appropriate window functions.
+
+Once we have obtained the C and D segments the overlap buffer is emptied and the
+current buffer is sent in it, so that the E and F segments are available for
+decoding in the next algorithm pass.*/
+INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum,
+ const SHORT scalefactor[], const INT nSpec,
+ const INT noOutSamples, const INT tl, const FIXP_WTP *wls,
+ INT fl, const FIXP_WTP *wrs, const INT fr, FIXP_DBL gain,
+ int flags) {
+ FIXP_DBL *pOvl;
+ FIXP_DBL *pOut0 = output, *pOut1;
+ INT nl, nr;
+ int w, i, nrSamples = 0, specShiftScale, transform_gain_e = 0;
+ int currAliasSymmetry = (flags & MLT_FLAG_CURR_ALIAS_SYMMETRY);
+
+ /* Derive NR and NL */
+ nr = (tl - fr) >> 1;
+ nl = (tl - fl) >> 1;
+
+ /* Include 2/N IMDCT gain into gain factor and exponent. */
+ imdct_gain(&gain, &transform_gain_e, tl);
+
+ /* Detect FRprevious / FL mismatches and override parameters accordingly */
+ if (hMdct->prev_fr != fl) {
+ imdct_adapt_parameters(hMdct, &fl, &nl, tl, wls, noOutSamples);
+ }
+
+ pOvl = hMdct->overlap.freq + hMdct->ov_size - 1;
+
+ if (noOutSamples > nrSamples) {
+ /* Purge buffered output. */
+ for (i = 0; i < hMdct->ov_offset; i++) {
+ *pOut0 = hMdct->overlap.time[i];
+ pOut0++;
+ }
+ nrSamples = hMdct->ov_offset;
+ hMdct->ov_offset = 0;
+ }
+
+ for (w = 0; w < nSpec; w++) {
+ FIXP_DBL *pSpec, *pCurr;
+ const FIXP_WTP *pWindow;
+
+ /* Detect FRprevious / FL mismatches and override parameters accordingly */
+ if (hMdct->prev_fr != fl) {
+ imdct_adapt_parameters(hMdct, &fl, &nl, tl, wls, noOutSamples);
+ }
+
+ specShiftScale = transform_gain_e;
+
+ /* Setup window pointers */
+ pWindow = hMdct->prev_wrs;
+
+ /* Current spectrum */
+ pSpec = spectrum + w * tl;
+
+ /* DCT IV of current spectrum. */
+ if (currAliasSymmetry == 0) {
+ if (hMdct->prevAliasSymmetry == 0) {
+ dct_IV(pSpec, tl, &specShiftScale);
+ } else {
+ FIXP_DBL _tmp[1024 + ALIGNMENT_DEFAULT / sizeof(FIXP_DBL)];
+ FIXP_DBL *tmp = (FIXP_DBL *)ALIGN_PTR(_tmp);
+ C_ALLOC_ALIGNED_REGISTER(tmp, sizeof(_tmp));
+ dct_III(pSpec, tmp, tl, &specShiftScale);
+ C_ALLOC_ALIGNED_UNREGISTER(tmp);
+ }
+ } else {
+ if (hMdct->prevAliasSymmetry == 0) {
+ FIXP_DBL _tmp[1024 + ALIGNMENT_DEFAULT / sizeof(FIXP_DBL)];
+ FIXP_DBL *tmp = (FIXP_DBL *)ALIGN_PTR(_tmp);
+ C_ALLOC_ALIGNED_REGISTER(tmp, sizeof(_tmp));
+ dst_III(pSpec, tmp, tl, &specShiftScale);
+ C_ALLOC_ALIGNED_UNREGISTER(tmp);
+ } else {
+ dst_IV(pSpec, tl, &specShiftScale);
+ }
+ }
+
+ /* Optional scaling of time domain - no yet windowed - of current spectrum
+ */
+ /* and de-scale current spectrum signal (time domain, no yet windowed) */
+ if (gain != (FIXP_DBL)0) {
+ for (i = 0; i < tl; i++) {
+ pSpec[i] = fMult(pSpec[i], gain);
+ }
+ }
+
+ {
+ int loc_scale =
+ fixmin_I(scalefactor[w] + specShiftScale, (INT)DFRACT_BITS - 1);
+ DWORD_ALIGNED(pSpec);
+ scaleValuesSaturate(pSpec, tl, loc_scale);
+ }
+
+ if (noOutSamples <= nrSamples) {
+ /* Divert output first half to overlap buffer if we already got enough
+ * output samples. */
+ pOut0 = hMdct->overlap.time + hMdct->ov_offset;
+ hMdct->ov_offset += hMdct->prev_nr + fl / 2;
+ } else {
+ /* Account output samples */
+ nrSamples += hMdct->prev_nr + fl / 2;
+ }
+
+ /* NR output samples 0 .. NR. -overlap[TL/2..TL/2-NR] */
+ if ((hMdct->pFacZir != 0) && (hMdct->prev_nr == fl / 2)) {
+ /* In the case of ACELP -> TCX20 -> FD short add FAC ZIR on nr signal part
+ */
+ for (i = 0; i < hMdct->prev_nr; i++) {
+ FIXP_DBL x = -(*pOvl--);
+ *pOut0 = IMDCT_SCALE_DBL(x + hMdct->pFacZir[i]);
+ pOut0++;
+ }
+ hMdct->pFacZir = NULL;
+ } else {
+ /* Here we implement a simplified version of what happens after the this
+ piece of code (see the comments below). We implement the folding of C and
+ D segments from (-D-Cr) but D is zero, because in this part of the MDCT
+ sequence the window coefficients with which D must be multiplied are zero.
+ "pOut0" writes sequentially the C block from left to right. */
+ if (hMdct->prevPrevAliasSymmetry == 0) {
+ for (i = 0; i < hMdct->prev_nr; i++) {
+ FIXP_DBL x = -(*pOvl--);
+ *pOut0 = IMDCT_SCALE_DBL(x);
+ pOut0++;
+ }
+ } else {
+ for (i = 0; i < hMdct->prev_nr; i++) {
+ FIXP_DBL x = *pOvl--;
+ *pOut0 = IMDCT_SCALE_DBL(x);
+ pOut0++;
+ }
+ }
+ }
+
+ if (noOutSamples <= nrSamples) {
+ /* Divert output second half to overlap buffer if we already got enough
+ * output samples. */
+ pOut1 = hMdct->overlap.time + hMdct->ov_offset + fl / 2 - 1;
+ hMdct->ov_offset += fl / 2 + nl;
+ } else {
+ pOut1 = pOut0 + (fl - 1);
+ nrSamples += fl / 2 + nl;
+ }
+
+ /* output samples before window crossing point NR .. TL/2.
+ * -overlap[TL/2-NR..TL/2-NR-FL/2] + current[NR..TL/2] */
+ /* output samples after window crossing point TL/2 .. TL/2+FL/2.
+ * -overlap[0..FL/2] - current[TL/2..FL/2] */
+ pCurr = pSpec + tl - fl / 2;
+ DWORD_ALIGNED(pCurr);
+ C_ALLOC_ALIGNED_REGISTER(pWindow, fl);
+ DWORD_ALIGNED(pWindow);
+ C_ALLOC_ALIGNED_UNREGISTER(pWindow);
+
+ if (hMdct->prevPrevAliasSymmetry == 0) {
+ if (hMdct->prevAliasSymmetry == 0) {
+ if (!hMdct->pAsymOvlp) {
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x0, x1;
+ cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]);
+ *pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
+ *pOut1 = IMDCT_SCALE_DBL_LSH1(-x1);
+ pOut0++;
+ pOut1--;
+ }
+ } else {
+ FIXP_DBL *pAsymOvl = hMdct->pAsymOvlp + fl / 2 - 1;
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x0, x1;
+ x1 = -fMultDiv2(*pCurr, pWindow[i].v.re) +
+ fMultDiv2(*pAsymOvl, pWindow[i].v.im);
+ x0 = fMultDiv2(*pCurr, pWindow[i].v.im) -
+ fMultDiv2(*pOvl, pWindow[i].v.re);
+ pCurr++;
+ pOvl--;
+ pAsymOvl--;
+ *pOut0++ = IMDCT_SCALE_DBL_LSH1(x0);
+ *pOut1-- = IMDCT_SCALE_DBL_LSH1(x1);
+ }
+ hMdct->pAsymOvlp = NULL;
+ }
+ } else { /* prevAliasingSymmetry == 1 */
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x0, x1;
+ cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]);
+ *pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
+ *pOut1 = IMDCT_SCALE_DBL_LSH1(x1);
+ pOut0++;
+ pOut1--;
+ }
+ }
+ } else { /* prevPrevAliasingSymmetry == 1 */
+ if (hMdct->prevAliasSymmetry == 0) {
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x0, x1;
+ cplxMultDiv2(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]);
+ *pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
+ *pOut1 = IMDCT_SCALE_DBL_LSH1(-x1);
+ pOut0++;
+ pOut1--;
+ }
+ } else { /* prevAliasingSymmetry == 1 */
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x0, x1;
+ cplxMultDiv2(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]);
+ *pOut0 = IMDCT_SCALE_DBL_LSH1(x0);
+ *pOut1 = IMDCT_SCALE_DBL_LSH1(x1);
+ pOut0++;
+ pOut1--;
+ }
+ }
+ }
+
+ if (hMdct->pFacZir != 0) {
+ /* add FAC ZIR of previous ACELP -> mdct transition */
+ FIXP_DBL *pOut = pOut0 - fl / 2;
+ FDK_ASSERT(fl / 2 <= 128);
+ for (i = 0; i < fl / 2; i++) {
+ pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
+ }
+ hMdct->pFacZir = NULL;
+ }
+ pOut0 += (fl / 2) + nl;
+
+ /* NL output samples TL/2+FL/2..TL. - current[FL/2..0] */
+ pOut1 += (fl / 2) + 1;
+ pCurr = pSpec + tl - fl / 2 - 1;
+ /* Here we implement a simplified version of what happens above the this
+ piece of code (see the comments above). We implement the folding of C and D
+ segments from (C-Dr) but C is zero, because in this part of the MDCT
+ sequence the window coefficients with which C must be multiplied are zero.
+ "pOut1" writes sequentially the D block from left to right. */
+ if (hMdct->prevAliasSymmetry == 0) {
+ for (i = 0; i < nl; i++) {
+ FIXP_DBL x = -(*pCurr--);
+ *pOut1++ = IMDCT_SCALE_DBL(x);
+ }
+ } else {
+ for (i = 0; i < nl; i++) {
+ FIXP_DBL x = *pCurr--;
+ *pOut1++ = IMDCT_SCALE_DBL(x);
+ }
+ }
+
+ /* Set overlap source pointer for next window pOvl = pSpec + tl/2 - 1; */
+ pOvl = pSpec + tl / 2 - 1;
+
+ /* Previous window values. */
+ hMdct->prev_nr = nr;
+ hMdct->prev_fr = fr;
+ hMdct->prev_tl = tl;
+ hMdct->prev_wrs = wrs;
+
+ /* Previous aliasing symmetry */
+ hMdct->prevPrevAliasSymmetry = hMdct->prevAliasSymmetry;
+ hMdct->prevAliasSymmetry = currAliasSymmetry;
+ }
+
+ /* Save overlap */
+
+ pOvl = hMdct->overlap.freq + hMdct->ov_size - tl / 2;
+ FDKmemcpy(pOvl, &spectrum[(nSpec - 1) * tl], (tl / 2) * sizeof(FIXP_DBL));
+
+ return nrSamples;
+}
diff --git a/fdk-aac/libFDK/src/mips/fft_rad2_mips.cpp b/fdk-aac/libFDK/src/mips/fft_rad2_mips.cpp
new file mode 100644
index 0000000..7db8b4e
--- /dev/null
+++ b/fdk-aac/libFDK/src/mips/fft_rad2_mips.cpp
@@ -0,0 +1,165 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: dit_fft MIPS assembler replacements.
+
+*******************************************************************************/
+
+#ifndef __FFT_RAD2_CPP__
+#error \
+ "Do not compile this file separately. It is included on demand from fft_rad2.cpp"
+#endif
+
+#if defined(MIPS_DSP_LIB)
+
+#include "dsplib_util.h"
+#include "dsplib_dsp.h"
+
+#define FUNCTION_dit_fft
+
+#ifdef FUNCTION_dit_fft
+
+#include "mips_fft_twiddles.cpp"
+
+void dit_fft(FIXP_DBL *x, const INT ldn, const FIXP_STP *trigdata,
+ const INT trigDataSize) {
+ int i;
+
+ int32c *din = (int32c *)x;
+ int32c *dout = (int32c *)x;
+
+ int32c scratch[1024];
+ int32c *twiddles;
+
+ switch (ldn) {
+ case 4:
+ twiddles = (int32c *)__twiddles_mips_fft32_16;
+ break;
+ case 5:
+ twiddles = (int32c *)__twiddles_mips_fft32_32;
+ break;
+ case 6:
+ twiddles = (int32c *)__twiddles_mips_fft32_64;
+ break;
+ case 7:
+ twiddles = (int32c *)__twiddles_mips_fft32_128;
+ break;
+ case 8:
+ twiddles = (int32c *)__twiddles_mips_fft32_256;
+ break;
+ case 9:
+ twiddles = (int32c *)__twiddles_mips_fft32_512;
+ break;
+ case 10:
+ twiddles = (int32c *)__twiddles_mips_fft32_1024;
+ break;
+ default:
+ FDK_ASSERT(0);
+ break;
+ }
+
+ mips_fft32(dout, din, twiddles, scratch, ldn);
+
+ for (i = 0; i < (1 << ldn); i++) {
+ x[2 * i] = dout[i].re << 1;
+ x[2 * i + 1] = dout[i].im << 1;
+ }
+}
+#endif
+
+#endif /* defined(MIPS_DSP_LIB) */
diff --git a/fdk-aac/libFDK/src/mips/mips_fft_twiddles.cpp b/fdk-aac/libFDK/src/mips/mips_fft_twiddles.cpp
new file mode 100644
index 0000000..f905f86
--- /dev/null
+++ b/fdk-aac/libFDK/src/mips/mips_fft_twiddles.cpp
@@ -0,0 +1,931 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+static const INT __twiddles_mips_fft32_16[] = {
+ (0x7FFFFFFF), (0x00000000), (0x7641AF32), (0xCF043A9E), (0x5A827978),
+ (0xA57D8646), (0x30FBC547), (0x89BE50C2), (0xFFFFFFA3), (0x80000002),
+ (0xCF043AF8), (0x89BE50A8), (0xA57D865E), (0xA57D8670), (0x89BE5100),
+ (0xCF043A24), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000)};
+
+static const INT __twiddles_mips_fft32_32[] = {
+ (0x7FFFFFFF), (0x00000000), (0x7D8A5F3C), (0xE70747B9), (0x7641AF32),
+ (0xCF043A9E), (0x6A6D98A1), (0xB8E31318), (0x5A827978), (0xA57D8646),
+ (0x471CED05), (0x95926772), (0x30FBC547), (0x89BE50C2), (0x18F8B888),
+ (0x8275A0D1), (0xFFFFFFA3), (0x80000002), (0xE70747BB), (0x8275A0C3),
+ (0xCF043AF8), (0x89BE50A8), (0xB8E3139E), (0x95926705), (0xA57D865E),
+ (0xA57D8670), (0x959266F7), (0xB8E313B4), (0x89BE5100), (0xCF043A24),
+ (0x8275A0BE), (0xE70747D4), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x37000000), (0x000080A3), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000)};
+
+static const INT __twiddles_mips_fft32_64[] = {
+ (0x7FFFFFFF), (0x00000000), (0x7F62368D), (0xF3742C9D), (0x7D8A5F3C),
+ (0xE70747B9), (0x7A7D0559), (0xDAD7F3A2), (0x7641AF32), (0xCF043A9E),
+ (0x70E2CBCD), (0xC3A945A1), (0x6A6D98A1), (0xB8E31318), (0x62F201C4),
+ (0xAECC338B), (0x5A827978), (0xA57D8646), (0x5133CC8F), (0x9D0DFE52),
+ (0x471CED05), (0x95926772), (0x3C56BAB5), (0x8F1D3461), (0x30FBC547),
+ (0x89BE50C2), (0x25280C05), (0x8582FA8C), (0x18F8B888), (0x8275A0D1),
+ (0x0C8BD356), (0x809DC971), (0xFFFFFFA3), (0x80000002), (0xF3742CEE),
+ (0x809DC96B), (0xE70747BB), (0x8275A0C3), (0xDAD7F348), (0x8582FAC2),
+ (0xCF043AF8), (0x89BE50A8), (0xC3A94669), (0x8F1D33C8), (0xB8E3139E),
+ (0x95926705), (0xAECC33A5), (0x9D0DFE27), (0xA57D865E), (0xA57D8670),
+ (0x9D0DFE16), (0xAECC33B9), (0x959266F7), (0xB8E313B4), (0x8F1D34AD),
+ (0xC3A944BC), (0x89BE5100), (0xCF043A24), (0x8582FABB), (0xDAD7F360),
+ (0x8275A0BE), (0xE70747D4), (0x809DC968), (0xF3742D08), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0xFF7B0000),
+ (0x2E8050F1), (0x10214482), (0x1BA00005), (0x0000C0FF), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000)};
+
+static const INT __twiddles_mips_fft32_128[] = {
+ (0x7FFFFFFF), (0x00000000), (0x7FD8878C), (0xF9B82681), (0x7F62368D),
+ (0xF3742C9D), (0x7E9D55FB), (0xED37EF91), (0x7D8A5F3C), (0xE70747B9),
+ (0x7C29FBEF), (0xE0E6068F), (0x7A7D0559), (0xDAD7F3A2), (0x78848419),
+ (0xD4E0CB28), (0x7641AF32), (0xCF043A9E), (0x73B5EBCF), (0xC945DFEB),
+ (0x70E2CBCD), (0xC3A945A1), (0x6DCA0D27), (0xBE31E1BF), (0x6A6D98A1),
+ (0xB8E31318), (0x66CF8103), (0xB3C01FE9), (0x62F201C4), (0xAECC338B),
+ (0x5ED77C86), (0xAA0A5B2C), (0x5A827978), (0xA57D8646), (0x55F5A4ED),
+ (0xA1288391), (0x5133CC8F), (0x9D0DFE52), (0x4C3FDFCC), (0x99307EC5),
+ (0x471CED05), (0x95926772), (0x41CE1ECD), (0x9235F32C), (0x3C56BAB5),
+ (0x8F1D3461), (0x36BA2034), (0x8C4A1440), (0x30FBC547), (0x89BE50C2),
+ (0x2B1F34BC), (0x877B7BDD), (0x25280C05), (0x8582FA8C), (0x1F19F9F0),
+ (0x83D60431), (0x18F8B888), (0x8275A0D1), (0x12C81090), (0x8162AA0A),
+ (0x0C8BD356), (0x809DC971), (0x0647D949), (0x80277871), (0xFFFFFFA3),
+ (0x80000002), (0xF9B826FB), (0x8027786E), (0xF3742CEE), (0x809DC96B),
+ (0xED37EFB3), (0x8162AA00), (0xE70747BB), (0x8275A0C3), (0xE0E60653),
+ (0x83D60420), (0xDAD7F348), (0x8582FAC2), (0xD4E0CB84), (0x877B7BC6),
+ (0xCF043AF8), (0x89BE50A8), (0xC945E00A), (0x8C4A1423), (0xC3A94669),
+ (0x8F1D33C8), (0xBE31E16E), (0x9235F309), (0xB8E3139E), (0x95926705),
+ (0xB3C01F9D), (0x99307F35), (0xAECC33A5), (0x9D0DFE27), (0xAA0A5A88),
+ (0xA128840F), (0xA57D865E), (0xA57D8670), (0xA12883FE), (0xAA0A5A9B),
+ (0x9D0DFE16), (0xAECC33B9), (0x99307F26), (0xB3C01FB2), (0x959266F7),
+ (0xB8E313B4), (0x9235F2FC), (0xBE31E184), (0x8F1D34AD), (0xC3A944BC),
+ (0x8C4A1418), (0xC945E021), (0x89BE5100), (0xCF043A24), (0x877B7BBD),
+ (0xD4E0CB9C), (0x8582FABB), (0xDAD7F360), (0x83D603DC), (0xE0E60764),
+ (0x8275A0BE), (0xE70747D4), (0x8162AA22), (0xED37EECF), (0x809DC968),
+ (0xF3742D08), (0x80277879), (0xF9B82615), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0xA4370000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0xFF770000), (0x2E8050F1), (0x1A214462),
+ (0x04D6D583), (0x40031282), (0x6469A735), (0x0B4C99A3), (0x0AF88594),
+ (0xF90969D7), (0x96131C92), (0x025EEA10), (0x3A1FE421), (0x614FF390),
+ (0x1CFDC327), (0xC177E04F), (0xF4D87E82), (0x78253F39), (0xBB839F94),
+ (0x998B3EB1), (0x0CBCC021), (0x41BEC843), (0xAC0EE121), (0x52719643),
+ (0x909A2B1D), (0xF38931E1), (0xF41327FF), (0xF6099847), (0xA70D219C),
+ (0x7BD52135), (0x78060F71), (0xEA3C87D8), (0x3FAF3A24), (0xE4B2C421),
+ (0xB99D1453), (0x2741E264), (0x2239813A), (0x2944DA20), (0x441EF7C4),
+ (0x0BD0B720), (0xED84EA26), (0x73E0C0D2), (0x678E3039), (0x21420109),
+ (0x8607492E), (0x28CEF440), (0x022768C8), (0xF68E3611), (0x84E84D55),
+ (0x73004C04), (0xF9B6630E), (0x677FFA8F), (0x530CB18F), (0x2C4EE310),
+ (0xABC7537C), (0x82CFDBCB), (0x100C63A2), (0x876D75BA), (0xC683F888),
+ (0x0CDC1E1E), (0xA600E833), (0x33036066), (0x4305049C), (0x40890713),
+ (0x9D12532E), (0x7B6E2FE2), (0xE244CC09), (0x9FFB2082), (0xAB3735D3),
+ (0x00000080), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0x00000000)};
+
+static const INT __twiddles_mips_fft32_256[] = {
+ (0x7FFFFFFF), (0x00000000), (0x7FF62181), (0xFCDBD540), (0x7FD8878C),
+ (0xF9B82681), (0x7FA736B2), (0xF6956FB7), (0x7F62368D), (0xF3742C9D),
+ (0x7F0991C3), (0xF054D8DA), (0x7E9D55FB), (0xED37EF91), (0x7E1D93EA),
+ (0xEA1DEBC6), (0x7D8A5F3C), (0xE70747B9), (0x7CE3CEB0), (0xE3F47D95),
+ (0x7C29FBEF), (0xE0E6068F), (0x7B5D03A1), (0xDDDC5B4F), (0x7A7D0559),
+ (0xDAD7F3A2), (0x798A23A8), (0xD7D946C3), (0x78848419), (0xD4E0CB28),
+ (0x776C4ED9), (0xD1EEF59D), (0x7641AF32), (0xCF043A9E), (0x7504D34C),
+ (0xCC210D8B), (0x73B5EBCF), (0xC945DFEB), (0x72552C79), (0xC67322B9),
+ (0x70E2CBCD), (0xC3A945A1), (0x6F5F02CF), (0xC0E8B67E), (0x6DCA0D27),
+ (0xBE31E1BF), (0x6C242969), (0xBB8532C0), (0x6A6D98A1), (0xB8E31318),
+ (0x68A69E72), (0xB64BEAB9), (0x66CF8103), (0xB3C01FE9), (0x64E8894A),
+ (0xB140178C), (0x62F201C4), (0xAECC338B), (0x60EC383A), (0xAC64D51F),
+ (0x5ED77C86), (0xAA0A5B2C), (0x5CB420CD), (0xA7BD229A), (0x5A827978),
+ (0xA57D8646), (0x5842DD7E), (0xA34BDF4B), (0x55F5A4ED), (0xA1288391),
+ (0x539B2AFB), (0x9F13C7DC), (0x5133CC8F), (0x9D0DFE52), (0x4EBFE88F),
+ (0x9B1776CB), (0x4C3FDFCC), (0x99307EC5), (0x49B41562), (0x975961A2),
+ (0x471CED05), (0x95926772), (0x447ACD5D), (0x93DBD6AA), (0x41CE1ECD),
+ (0x9235F32C), (0x3F17499F), (0x90A0FD42), (0x3C56BAB5), (0x8F1D3461),
+ (0x398CDCF3), (0x8DAAD35D), (0x36BA2034), (0x8C4A1440), (0x33DEF21F),
+ (0x8AFB2C8E), (0x30FBC547), (0x89BE50C2), (0x2E110ABF), (0x8893B14A),
+ (0x2B1F34BC), (0x877B7BDD), (0x2826B95E), (0x8675DC62), (0x25280C05),
+ (0x8582FA8C), (0x2223A4D2), (0x84A2FC68), (0x1F19F9F0), (0x83D60431),
+ (0x1C0B824E), (0x831C314A), (0x18F8B888), (0x8275A0D1), (0x15E213FD),
+ (0x81E26C0B), (0x12C81090), (0x8162AA0A), (0x0FAB26B9), (0x80F66E30),
+ (0x0C8BD356), (0x809DC971), (0x096A90AB), (0x8058C955), (0x0647D949),
+ (0x80277871), (0x03242AF6), (0x8009DE81), (0xFFFFFFA3), (0x80000002),
+ (0xFCDBD54E), (0x8009DE7F), (0xF9B826FB), (0x8027786E), (0xF6956F99),
+ (0x8058C950), (0xF3742CEE), (0x809DC96B), (0xF054D88D), (0x80F66E47),
+ (0xED37EFB3), (0x8162AA00), (0xEA1DEB4A), (0x81E26C2C), (0xE70747BB),
+ (0x8275A0C3), (0xE3F47DF5), (0x831C313B), (0xE0E60653), (0x83D60420),
+ (0xDDDC5B6F), (0x84A2FC55), (0xDAD7F348), (0x8582FAC2), (0xD7D946E3),
+ (0x8675DC4D), (0xD4E0CB84), (0x877B7BC6), (0xD1EEF581), (0x8893B132),
+ (0xCF043AF8), (0x89BE50A8), (0xCC210D35), (0x8AFB2CDB), (0xC945E00A),
+ (0x8C4A1423), (0xC6732265), (0x8DAAD3B2), (0xC3A94669), (0x8F1D33C8),
+ (0xC0E8B69C), (0x90A0FD21), (0xBE31E16E), (0x9235F309), (0xBB853205),
+ (0x93DBD70E), (0xB8E3139E), (0x95926705), (0xB64BEAD5), (0x9759617B),
+ (0xB3C01F9D), (0x99307F35), (0xB140180C), (0x9B177652), (0xAECC33A5),
+ (0x9D0DFE27), (0xAC64D4D8), (0x9F13C803), (0xAA0A5A88), (0xA128840F),
+ (0xA7BD2310), (0xA34BDEC3), (0xA57D865E), (0xA57D8670), (0xA34BDEB2),
+ (0xA7BD2322), (0xA12883FE), (0xAA0A5A9B), (0x9F13C7F2), (0xAC64D4EB),
+ (0x9D0DFE16), (0xAECC33B9), (0x9B177642), (0xB1401820), (0x99307F26),
+ (0xB3C01FB2), (0x9759616C), (0xB64BEAEA), (0x959266F7), (0xB8E313B4),
+ (0x93DBD700), (0xBB85321A), (0x9235F2FC), (0xBE31E184), (0x90A0FD14),
+ (0xC0E8B6B2), (0x8F1D34AD), (0xC3A944BC), (0x8DAAD3A6), (0xC673227C),
+ (0x8C4A1418), (0xC945E021), (0x8AFB2C68), (0xCC210E37), (0x89BE5100),
+ (0xCF043A24), (0x8893B128), (0xD1EEF599), (0x877B7BBD), (0xD4E0CB9C),
+ (0x8675DC95), (0xD7D94608), (0x8582FABB), (0xDAD7F360), (0x84A2FC4F),
+ (0xDDDC5B88), (0x83D603DC), (0xE0E60764), (0x831C316D), (0xE3F47D14),
+ (0x8275A0BE), (0xE70747D4), (0x81E26BFB), (0xEA1DEC5F), (0x8162AA22),
+ (0xED37EECF), (0x80F66E44), (0xF054D8A6), (0x809DC968), (0xF3742D08),
+ (0x8058C93B), (0xF69570B2), (0x80277879), (0xF9B82615), (0x8009DE7E),
+ (0xFCDBD568), (0x00000000), (0x00000000), (0x00000000), (0x00000000),
+ (0xF1FF7A00), (0xE23A8050), (0x841A2114), (0xC588DA75), (0x02400143),
+ (0xAED6AAD7), (0x94C2545B), (0x3E46156C), (0x05BFDF27), (0xB0822075),
+ (0xD24C7BC4), (0x62122054), (0x8CC41C49), (0x2C414972), (0x718D7C5E),
+ (0xDEE2A3D8), (0x4544C135), (0x64292573), (0x76B51F8A), (0x4B7D6557),
+ (0x87164907), (0xF59DBFEC), (0x04CEE9DE), (0xB4BC4C90), (0x9AFCCD30),
+ (0x8C7A316F), (0x90FDACA7), (0x4E0D6383), (0xAEF16C0B), (0x0622020A),
+ (0x37B6A738), (0xFFBB7D71), (0x5FEDD12F), (0xEE47FDC8), (0x3DC7913F),
+ (0xEAEEF7FD), (0x219DADEC), (0xF9E53F5F), (0xB3D82D9E), (0xBBB79BCB),
+ (0x43AD2AAB), (0x0E7ADBC0), (0xABBD0952), (0x1A6EF43A), (0xCD9B2A9D),
+ (0x7222B366), (0x979E89E9), (0x02C9113F), (0x1D511466), (0x57A92206),
+ (0x4A412075), (0xFD31D783), (0xA7542EFC), (0x24B76975), (0xB99962C7),
+ (0x19F1D356), (0x9D12C3CB), (0x6D37D542), (0x29E7214D), (0x8900F645),
+ (0xB154AD4A), (0xF047D988), (0x3F2E5E77), (0xAFB68C49), (0xC9F19E51),
+ (0x6192F53A), (0x5AE3D080), (0x1DA6C677), (0xD485D50C), (0x9AA7E8B2),
+ (0xF55EE1D5), (0xC00B6932), (0x85ACE912), (0x8208B1B9), (0x80E14170),
+ (0xA1D67C3F), (0x058035B3), (0xA4FE36CA), (0xBEE547E4), (0xEF276052),
+ (0x42AA4388), (0x9C11A2ED), (0x10202541), (0x2D480910), (0xB09B1AC4),
+ (0x19E7D17D), (0x52082450), (0x3EED1705), (0xF20FF8A1), (0x89F6E17F),
+ (0x17D7DC00), (0x09B9F2C3), (0x6378968C), (0xAF0607F6), (0xFDFDE0C9),
+ (0x3CE3DFEE), (0x5168229E), (0x7CF79734), (0xF5FFF56F), (0x30700093),
+ (0x135F5C75), (0xE6D73EEE), (0x6E400DF9), (0x58252ACB), (0x557311CA),
+ (0x5539B303), (0x56557355), (0xB6BDACEF), (0x59F9428D), (0x9AE63020),
+ (0x558FF7E7), (0x7955806D), (0x09D549F3), (0x603BF5B7), (0x3134413B),
+ (0xBCA7C1AA), (0xA98D1339), (0x57B29C97), (0x50F1FF07), (0xE4A13980),
+ (0xD0881A21), (0xC1FFE30A), (0xB0A66C19), (0x18416490), (0x160E0214),
+ (0xA584CBB5), (0x02AAA82A), (0x73981340), (0x964A24DE), (0x6E829FC4),
+ (0xDFD62360), (0x4C3BF152), (0x38721574), (0xD46BC912), (0x1EB7FDD8),
+ (0x1CA6CBC0), (0xBBCBC111), (0xA6FD1403), (0x76C688D9), (0xB47186CB),
+ (0x5E98936D), (0x9BBF7E2E), (0x8B7FBCEC), (0x9DAF7EF5), (0x7E3A79F1),
+ (0x9C896ACD), (0x628F249A), (0xDD6E51AF), (0xAF73994B), (0x5966995D),
+ (0xB7620597), (0x369B1E54), (0x7CEDC787), (0xE7B15B1F), (0xB36F5F7D),
+ (0xB5B73EF6), (0xD76EEEE2), (0x14E86186), (0xCC159291), (0x4EC85CA3),
+ (0xEC3C704E), (0x0B6633B3), (0x4D992D4B), (0xEB1B5774), (0xDFB9D508),
+ (0x11783719), (0x77BB10B0), (0xFCDF8350), (0xD34A7C65), (0xEF6E57BB),
+ (0xECD56C68), (0x8EB7CA36), (0x2F26B136), (0x55631269), (0xEF1213E1),
+ (0xA56AB844), (0xAA4B1D64), (0x64341EA9), (0x0CE9DB48), (0x460C2144),
+ (0xADC50205), (0x515C472F), (0x304C29BD), (0x76AF8711), (0x557CADB7),
+ (0x2A9BBC8E), (0xE50E145B), (0x9C2031FD), (0xD9121A8C), (0xF51A96FD),
+ (0x45CCBEBF), (0x5F884871), (0x66DAE291), (0x95ADC9E5), (0x33CF304D),
+ (0x23C87DCE), (0xA7014FB3), (0xFB351E71), (0x8D60F66F), (0xBFD6DDD5),
+ (0x151FE6F1), (0xDCC7935A), (0x0CACFBF0), (0xEE55A371), (0xBE46B755),
+ (0x0F79DCD2), (0x23DFF76D), (0x83DE76D7), (0x8B0E3AEE), (0xB01BFB44),
+ (0x4E3619FA), (0xA19F9E64), (0xBD492AD9), (0x0899E45F), (0x8156E41D),
+ (0x5DA539BA), (0x0AF35B2C), (0xDB89BAAE), (0xA128C966), (0xA02CEAEE),
+ (0xC5A1B291), (0x08CBA93E), (0x90FD887A), (0x60304386), (0x6A59F1EA),
+ (0xA461E67B), (0xC1622B76), (0x6FA2F906), (0xAA3A401A), (0xB68EA47B),
+ (0xC617A889), (0x6024A57B), (0x2DD53555), (0xF1FFEA30), (0x813A8050),
+ (0x8D1A21B4), (0xFFE72CF7), (0xA37415E1), (0x30A2C830), (0xA3A1CA28),
+ (0x4C5E3586), (0x309861B9), (0x1F49850D), (0x6164C748), (0x9D7048E5),
+ (0xC124569E), (0xCCB0E111), (0x15B2BB86), (0x18371D9C), (0xB2ABD94D),
+ (0x8EC656B3), (0xBF010995)};
+
+static const INT __twiddles_mips_fft32_512[] = {
+ (0x7FFFFFFF), (0x00000000), (0x7FFD8859), (0xFE6DE2E0), (0x7FF62181),
+ (0xFCDBD540), (0x7FE9CBBE), (0xFB49E6A3), (0x7FD8878C), (0xF9B82681),
+ (0x7FC25595), (0xF826A464), (0x7FA736B2), (0xF6956FB7), (0x7F872BF2),
+ (0xF5049800), (0x7F62368D), (0xF3742C9D), (0x7F3857F4), (0xF1E43D1C),
+ (0x7F0991C3), (0xF054D8DA), (0x7ED5E5C6), (0xEEC60F3C), (0x7E9D55FB),
+ (0xED37EF91), (0x7E5FE490), (0xEBAA8944), (0x7E1D93EA), (0xEA1DEBC6),
+ (0x7DD6668D), (0xE8922621), (0x7D8A5F3C), (0xE70747B9), (0x7D3980ED),
+ (0xE57D5FE4), (0x7CE3CEB0), (0xE3F47D95), (0x7C894BDA), (0xE26CB010),
+ (0x7C29FBEF), (0xE0E6068F), (0x7BC5E296), (0xDF609002), (0x7B5D03A1),
+ (0xDDDC5B4F), (0x7AEF6325), (0xDC59778B), (0x7A7D0559), (0xDAD7F3A2),
+ (0x7A05EEA8), (0xD957DE6F), (0x798A23A8), (0xD7D946C3), (0x7909A935),
+ (0xD65C3B98), (0x78848419), (0xD4E0CB28), (0x77FAB98A), (0xD367044F),
+ (0x776C4ED9), (0xD1EEF59D), (0x76D94983), (0xD078AD93), (0x7641AF32),
+ (0xCF043A9E), (0x75A585D9), (0xCD91AB55), (0x7504D34C), (0xCC210D8B),
+ (0x745F9DD3), (0xCAB26FB2), (0x73B5EBCF), (0xC945DFEB), (0x7307C3C9),
+ (0xC7DB6C45), (0x72552C79), (0xC67322B9), (0x719E2CDE), (0xC50D1164),
+ (0x70E2CBCD), (0xC3A945A1), (0x7023109C), (0xC247CD62), (0x6F5F02CF),
+ (0xC0E8B67E), (0x6E96A995), (0xBF8C0DD8), (0x6DCA0D27), (0xBE31E1BF),
+ (0x6CF934E8), (0xBCDA3EAE), (0x6C242969), (0xBB8532C0), (0x6B4AF258),
+ (0xBA32CA42), (0x6A6D98A1), (0xB8E31318), (0x698C2487), (0xB79619C6),
+ (0x68A69E72), (0xB64BEAB9), (0x67BD0FCC), (0xB5049380), (0x66CF8103),
+ (0xB3C01FE9), (0x65DDFBD6), (0xB27E9D43), (0x64E8894A), (0xB140178C),
+ (0x63EF3286), (0xB0049AA9), (0x62F201C4), (0xAECC338B), (0x61F10027),
+ (0xAD96ED77), (0x60EC383A), (0xAC64D51F), (0x5FE3B366), (0xAB35F58C),
+ (0x5ED77C86), (0xAA0A5B2C), (0x5DC79D9C), (0xA8E2112C), (0x5CB420CD),
+ (0xA7BD229A), (0x5B9D1166), (0xA69B9B7D), (0x5A827978), (0xA57D8646),
+ (0x5964649B), (0xA462EEB2), (0x5842DD7E), (0xA34BDF4B), (0x571DEEED),
+ (0xA238627B), (0x55F5A4ED), (0xA1288391), (0x54CA0A2E), (0xA01C4C5C),
+ (0x539B2AFB), (0x9F13C7DC), (0x52691241), (0x9E0EFF9D), (0x5133CC8F),
+ (0x9D0DFE52), (0x4FFB6572), (0x9C10CD90), (0x4EBFE88F), (0x9B1776CB),
+ (0x4D8162D8), (0x9A22043F), (0x4C3FDFCC), (0x99307EC5), (0x4AFB6C9B),
+ (0x9842F048), (0x49B41562), (0x975961A2), (0x4869E657), (0x9673DB8C),
+ (0x471CED05), (0x95926772), (0x45CD356F), (0x94B50D74), (0x447ACD5D),
+ (0x93DBD6AA), (0x4325C102), (0x9306CAE7), (0x41CE1ECD), (0x9235F32C),
+ (0x4073F245), (0x9169567D), (0x3F17499F), (0x90A0FD42), (0x3DB8324C),
+ (0x8FDCEF37), (0x3C56BAB5), (0x8F1D3461), (0x3AF2EEBA), (0x8E61D331),
+ (0x398CDCF3), (0x8DAAD35D), (0x38249413), (0x8CF83C62), (0x36BA2034),
+ (0x8C4A1440), (0x354D9033), (0x8BA06221), (0x33DEF21F), (0x8AFB2C8E),
+ (0x326E5505), (0x8A5A7A4D), (0x30FBC547), (0x89BE50C2), (0x2F875216),
+ (0x8926B65A), (0x2E110ABF), (0x8893B14A), (0x2C98FBD1), (0x88054682),
+ (0x2B1F34BC), (0x877B7BDD), (0x29A3C40F), (0x86F656AC), (0x2826B95E),
+ (0x8675DC62), (0x26A82174), (0x85FA114F), (0x25280C05), (0x8582FA8C),
+ (0x23A688D3), (0x85109CF7), (0x2223A4D2), (0x84A2FC68), (0x209F6FE1),
+ (0x843A1D62), (0x1F19F9F0), (0x83D60431), (0x1D935011), (0x8376B42E),
+ (0x1C0B824E), (0x831C314A), (0x1A829FC0), (0x82C67F00), (0x18F8B888),
+ (0x8275A0D1), (0x176DD9E1), (0x82299974), (0x15E213FD), (0x81E26C0B),
+ (0x1455771D), (0x81A01B80), (0x12C81090), (0x8162AA0A), (0x1139F0A7),
+ (0x812A1A36), (0x0FAB26B9), (0x80F66E30), (0x0E1BC326), (0x80C7A813),
+ (0x0C8BD356), (0x809DC971), (0x0AFB67B2), (0x8078D407), (0x096A90AB),
+ (0x8058C955), (0x07D95BB6), (0x803DAA6D), (0x0647D949), (0x80277871),
+ (0x04B618DF), (0x8016343D), (0x03242AF6), (0x8009DE81), (0x01921D0C),
+ (0x800277A7), (0xFFFFFFA3), (0x80000002), (0xFE6DE338), (0x800277A6),
+ (0xFCDBD54E), (0x8009DE7F), (0xFB49E665), (0x80163444), (0xF9B826FB),
+ (0x8027786E), (0xF826A48E), (0x803DAA69), (0xF6956F99), (0x8058C950),
+ (0xF5049793), (0x8078D418), (0xF3742CEE), (0x809DC96B), (0xF1E43D1E),
+ (0x80C7A80C), (0xF054D88D), (0x80F66E47), (0xEEC60F9D), (0x812A1A2D),
+ (0xED37EFB3), (0x8162AA00), (0xEBAA8927), (0x81A01B75), (0xEA1DEB4A),
+ (0x81E26C2C), (0xE8922662), (0x82299967), (0xE70747BB), (0x8275A0C3),
+ (0xE57D5F89), (0x82C67F27), (0xE3F47DF5), (0x831C313B), (0xE26CB031),
+ (0x8376B41E), (0xE0E60653), (0x83D60420), (0xDF608F69), (0x843A1D92),
+ (0xDDDC5B6F), (0x84A2FC55), (0xDC59776E), (0x85109CE4), (0xDAD7F348),
+ (0x8582FAC2), (0xD957DECD), (0x85FA113A), (0xD7D946E3), (0x8675DC4D),
+ (0xD65C3B40), (0x86F656E9), (0xD4E0CB84), (0x877B7BC6), (0xD367046F),
+ (0x8805466A), (0xD1EEF581), (0x8893B132), (0xD078AD3C), (0x8926B6A0),
+ (0xCF043AF8), (0x89BE50A8), (0xCD91AB39), (0x8A5A7A32), (0xCC210D35),
+ (0x8AFB2CDB), (0xCAB2700B), (0x8BA06204), (0xC945E00A), (0x8C4A1423),
+ (0xC7DB6C2A), (0x8CF83C44), (0xC6732265), (0x8DAAD3B2), (0xC50D109F),
+ (0x8E61D388), (0xC3A94669), (0x8F1D33C8), (0xC247CDF0), (0x8FDCEF16),
+ (0xC0E8B69C), (0x90A0FD21), (0xBF8C0DF6), (0x9169565A), (0xBE31E16E),
+ (0x9235F309), (0xBCDA3E5E), (0x9306CB49), (0xBB853205), (0x93DBD70E),
+ (0xBA32CB35), (0x94B50D09), (0xB8E3139E), (0x95926705), (0xB79619E2),
+ (0x9673DB66), (0xB64BEAD5), (0x9759617B), (0xB5049334), (0x9842F06B),
+ (0xB3C01F9D), (0x99307F35), (0xB27E9C92), (0x9A2204B0), (0xB140180C),
+ (0x9B177652), (0xB0049B27), (0x9C10CD15), (0xAECC33A5), (0x9D0DFE27),
+ (0xAD96ED91), (0x9E0EFFC3), (0xAC64D4D8), (0x9F13C803), (0xAB35F545),
+ (0xA01C4CD8), (0xAA0A5A88), (0xA128840F), (0xA8E211A2), (0xA23861F5),
+ (0xA7BD2310), (0xA34BDEC3), (0xA69B9B96), (0xA462EE82), (0xA57D865E),
+ (0xA57D8670), (0xA462EE70), (0xA69B9BA8), (0xA34BDEB2), (0xA7BD2322),
+ (0xA23861E4), (0xA8E211B5), (0xA12883FE), (0xAA0A5A9B), (0xA01C4CC7),
+ (0xAB35F559), (0x9F13C7F2), (0xAC64D4EB), (0x9E0EFFB3), (0xAD96EDA5),
+ (0x9D0DFE16), (0xAECC33B9), (0x9C10CD05), (0xB0049B3B), (0x9B177642),
+ (0xB1401820), (0x9A2204A1), (0xB27E9CA6), (0x99307F26), (0xB3C01FB2),
+ (0x9842F05C), (0xB5049349), (0x9759616C), (0xB64BEAEA), (0x9673DB57),
+ (0xB79619F7), (0x959266F7), (0xB8E313B4), (0x94B50E13), (0xBA32C99E),
+ (0x93DBD700), (0xBB85321A), (0x9306CB3C), (0xBCDA3E74), (0x9235F2FC),
+ (0xBE31E184), (0x9169564D), (0xBF8C0E0C), (0x90A0FD14), (0xC0E8B6B2),
+ (0x8FDCEF09), (0xC247CE07), (0x8F1D34AD), (0xC3A944BC), (0x8E61D37C),
+ (0xC50D10B6), (0x8DAAD3A6), (0xC673227C), (0x8CF83C39), (0xC7DB6C41),
+ (0x8C4A1418), (0xC945E021), (0x8BA061F9), (0xCAB27022), (0x8AFB2C68),
+ (0xCC210E37), (0x8A5A7A8D), (0xCD91AA66), (0x89BE5100), (0xCF043A24),
+ (0x8926B697), (0xD078AD53), (0x8893B128), (0xD1EEF599), (0x88054661),
+ (0xD3670487), (0x877B7BBD), (0xD4E0CB9C), (0x86F6568E), (0xD65C3C4A),
+ (0x8675DC95), (0xD7D94608), (0x85FA1180), (0xD957DDF1), (0x8582FABB),
+ (0xDAD7F360), (0x85109CDD), (0xDC597787), (0x84A2FC4F), (0xDDDC5B88),
+ (0x843A1D4B), (0xDF60907A), (0x83D603DC), (0xE0E60764), (0x8376B454),
+ (0xE26CAF51), (0x831C316D), (0xE3F47D14), (0x82C67F21), (0xE57D5FA2),
+ (0x8275A0BE), (0xE70747D4), (0x82299962), (0xE892267C), (0x81E26BFB),
+ (0xEA1DEC5F), (0x81A01B48), (0xEBAA8A3D), (0x8162AA22), (0xED37EECF),
+ (0x812A1A4C), (0xEEC60EB9), (0x80F66E44), (0xF054D8A6), (0x80C7A809),
+ (0xF1E43D38), (0x809DC968), (0xF3742D08), (0x8078D3FF), (0xF50498AB),
+ (0x8058C93B), (0xF69570B2), (0x803DAA77), (0xF826A3A8), (0x80277879),
+ (0xF9B82615), (0x80163443), (0xFB49E67F), (0x8009DE7E), (0xFCDBD568),
+ (0x800277A6), (0xFE6DE352), (0x465220BB), (0xC66E1FFC), (0x2C61D356),
+ (0xAFFB176D), (0x88067E23), (0x3796F008), (0xC8D128F3), (0xB661A5FA),
+ (0xF19CE4F0), (0x3F7D0345), (0xE97E6030), (0x4ABA91CF), (0xDEEDAB0C),
+ (0x35FD1D77), (0xDD636439), (0x2F8B794C), (0x764E1D32), (0x7A8D0B1B),
+ (0x8EACB27F), (0x577AD67B), (0x2B3FE2C5), (0x8ACD024A), (0xEDF5C42C),
+ (0xF1CA951C), (0xB98B6D04), (0x6D12B864), (0x50E74D08), (0x73D1503B),
+ (0xC7D3F6A9), (0x1F365E97), (0xE1340E59), (0x89D21B9D), (0x9B756733),
+ (0x9024CD50), (0xE2C7FF52), (0xD9F061EF), (0x77151392), (0xA0E4A004),
+ (0x60BE820F), (0xC7603BAF), (0xA62E3DA9), (0xA400E11F), (0x155111D4),
+ (0x9030A374), (0x14185124), (0x8D043A00), (0x50945258), (0x20A6653E),
+ (0xA19BA8B9), (0x3CFBE692), (0x91471D98), (0x0B9D03FF), (0xA5BA8E29),
+ (0xFFC8EB22), (0x142CB1B0), (0x55317319), (0x33ADC77C), (0xF69BADCE),
+ (0x78423D3C), (0xBE67BBF0), (0x7D88BD15), (0x1E9EF673), (0x512098B3),
+ (0x326A3D3D), (0x161EF3B6), (0x0E4C4ED5), (0x4E9F9982), (0xD0AB6A36),
+ (0xF17DD377), (0x5E53F31C), (0xBE9112EA), (0x3DE1B0FF), (0xD7F39AE7),
+ (0xA34B9635), (0x49CFEE6C), (0x8A063AC6), (0xBA79BC0D), (0x6A588782),
+ (0x439BE593), (0x0A5F7E8D), (0xD2FC2561), (0x4698AC8F), (0x247C3BC2),
+ (0x5826523D), (0x4D2BD753), (0x4B8BCC17), (0x9B743503), (0x9F84E434),
+ (0x8B97B41A), (0x3CFCE75F), (0x32D2D487), (0x3E80B4AF), (0x42F8B0EA),
+ (0xEC0C81EE), (0x17279309), (0x681FA0F3), (0x8BAD208E), (0xD11792C6),
+ (0xF1FF07B3), (0x21338050), (0x8A1A21A4), (0xFF0358D8), (0x416C13C1),
+ (0x46348858), (0x83820519), (0xABC08822), (0x6A1A5200), (0x0C83122A),
+ (0xA67FDF06), (0x0629F970), (0xEFAA2743), (0x0C00AD95), (0xFF09F5CF),
+ (0xC784DB8B), (0xCB00BA7D), (0x6220909F), (0x7149B7DF), (0x5BD3EBEC),
+ (0x0485EF71), (0x07FE23B1), (0x80737668), (0x42A32645), (0xD6EDBB18),
+ (0x407E72C5), (0x901402E0), (0x0C1B7905), (0x01CE11FC), (0x00C64914),
+ (0x3037978A), (0xFABC9190), (0x43A0AC89), (0xB9998370), (0xD6D69209),
+ (0xF132455E), (0x9DAFF482), (0xA2D635C2), (0xBD976B5E), (0x79ED93ED),
+ (0x7D42CA22), (0x2E23F9C1), (0xCF0E7521), (0x96D88AC1), (0x420C2845),
+ (0x1E19573D), (0xF8FE9279), (0xC1495100), (0x201249C2), (0x8B183723),
+ (0x450615A5), (0x004C0112), (0x85EB5235), (0x1BD8BD48), (0xA2914F03),
+ (0x51420EAC), (0xCE788470), (0x0508030B), (0xA4CD2A6C), (0x9626C062),
+ (0xF88D2DE5), (0xA9D6B399), (0xB3C57BFD), (0xCB1E9C4C), (0x004A5094),
+ (0xD0CBC42A), (0x3BE1A694), (0x3C353FA7), (0xA5697C57), (0xFE961665),
+ (0xED6B7C7D), (0x433DCF8D), (0xDA7D6C24), (0x407112C1), (0x4B9D285D),
+ (0x6C9A2F57), (0x1BF9FAEF), (0x4EE3E2E9), (0xE5AE7E92), (0x60A11D3F),
+ (0x4B441B63), (0xC8419BB1), (0x2C4F6DDD), (0xCEC3CF6D), (0x325A65CA),
+ (0x818FC6A4), (0xC55E5E5B), (0x277445A3), (0x6B3289F7), (0x09147D55),
+ (0x4F378D53), (0x588B0DC8), (0xF70BA347), (0xCBC43FAE), (0xD98E6639),
+ (0x07AF9ED0), (0xE2E6305A), (0x5E003571), (0x18523E7A), (0xF70D1E27),
+ (0xD7288950), (0x12C11132), (0xFF1C9D17), (0x318050F1), (0x1A219821),
+ (0xBF21998A), (0x6C13C1FF), (0x8C605861), (0x0A183954), (0x7BE4C1B6),
+ (0xA2CBC410), (0x7CC00A55), (0x5E58A973), (0x1122EF86), (0x80568E39),
+ (0x2310C300), (0x0E152D0E), (0x9E017C1C), (0x851DFC26), (0xD1B1E662),
+ (0x81BA10B0), (0x96C2E977), (0x8688E419), (0x97C94989), (0x250D535E),
+ (0x35FDE732), (0x147AD183), (0xCF9D75C0), (0x6B2C183C), (0x1D326489),
+ (0xC0807D98), (0xC081622E), (0x15C87B87), (0x7404598C), (0xFC3C7FA6),
+ (0x28BA8CF5), (0xE311EA9B), (0xEABFD4A5), (0x8768834A), (0x0F7D7440),
+ (0x40593152), (0xCF1E8BF5), (0xE32017B6), (0x39E66070), (0x560ECE9D),
+ (0xF4132C77), (0x722945C1), (0x96ECB5D5), (0x0C100C06), (0x30E96C02),
+ (0xE0B0159B), (0x163A40CB), (0x1B28B750), (0x11420E11), (0x34DC5981),
+ (0xD2769C3C), (0x569402D0), (0xE4F157C0), (0x120DF24C), (0x40D86153),
+ (0x1942CD11), (0x22484C3B), (0x8B299144), (0x58F1AAF8), (0xB2CD4777),
+ (0x4A53AB02), (0x55A5DAD4), (0xC8D58D79), (0x6CAEC011), (0x1C955C84),
+ (0xDE08A6C6), (0xD402AF7D), (0x695E6FA4), (0x4DA863B9), (0x5118070C),
+ (0x5A97EF1C), (0x8880B388), (0x4D596B2D), (0x37D74DCF), (0x58138B38),
+ (0x5B7BCD4E), (0xAE6C4422), (0x4E5D1AF1), (0xDE7396A5), (0xB442F217),
+ (0x0DF7A006), (0x96EEF8A2), (0xE2847B26), (0x68B9F67B), (0x8FE1FA65),
+ (0xE0A87E56), (0x1BE8FC4C), (0xBBD65F9D), (0xE6F02C9D), (0x867C6EEC),
+ (0x43FAB725), (0xA4144419), (0x69BB6AAF), (0xCE27B744), (0x022241A9),
+ (0xC05DF14E), (0x8050F1FF), (0x218C2131), (0xBE25941A), (0x9041CD06),
+ (0x1EE8A9C0), (0xD530FEDD), (0x7495C808), (0x050918A6), (0x3CE732E9),
+ (0xF87262FC), (0x01B812F1), (0x1FBA4842), (0x3E86C7F2), (0x270DB358),
+ (0xF9D22834), (0x74D4F469), (0x9A6E87D2), (0x8CBB0A50), (0xC0784B92),
+ (0x278DA581), (0x9221A7D5), (0xDE801B54), (0x4B531FDA), (0xC8B91F91),
+ (0x7A90DA40), (0x2967A429), (0x50CC1D8D), (0x9AE9110E), (0x50F250EE),
+ (0xD695B072), (0xFC7A5718), (0x1F1A26E6), (0x7D5ADD4D), (0xC8978597),
+ (0xEB326DC3), (0x384E9824), (0xC3B9D78C), (0xD8D2E214), (0xEFFBB048),
+ (0x00AB7714), (0x9D89CA13), (0xF70688D0), (0xADDA3A37), (0x5FBE5943),
+ (0x4ED9D613), (0x8A9DCC93), (0x19814236), (0x09A68BCC), (0xCEAC33AC),
+ (0x0BA70BB3), (0x326272E1), (0x2A8C6D20), (0x23083D0B), (0xFA809C02),
+ (0x5825C6C2), (0x061B4695), (0x8DB97748), (0x5071E584), (0x08760959),
+ (0x44EA8D04), (0x5CE6E2AA), (0x009AD176), (0xAEC64F19), (0xCADDA632),
+ (0x8D795445), (0x16E3EA24), (0xF12648CA), (0xD5CC350C), (0x615EBAD7),
+ (0x4E769FB6), (0x6C5EB380), (0x5BB46425), (0xEAB6C77C), (0x10945408),
+ (0xC1291B86), (0x913B71A5), (0x003BA329), (0x91812854), (0xE200CB12),
+ (0x7A4696A8), (0x76E55D25), (0xD6D3C577), (0x8B1B79B1), (0x296B04CD),
+ (0xA024CC35), (0x3341A477), (0x8EC12358), (0xF5982B2F), (0x36F120C9),
+ (0x79DBE799), (0xED74F092), (0xA1031AE3), (0xB2D98C6B), (0x358CAB73),
+ (0x41153C19), (0x474D4548), (0xA7E834A9), (0x999738AE), (0x50F1FFE8),
+ (0x88612F80), (0xFD931A21), (0x23839ABD), (0xBE604701), (0x812274B9),
+ (0x4CA9EA32), (0xE5F2D207), (0xC1CF4653), (0x43561B23), (0x53B2E277),
+ (0x4F2B00EC), (0xF2B3BA80), (0xFC708CC5), (0xE7F63F00), (0x26120342),
+ (0x1A49C7A8), (0xA9350A7C), (0xE530A06C), (0x5CB9E550), (0xB1672913),
+ (0x65FA76F9), (0xC9F92DCA), (0x7D4E9195), (0x4DBB8265), (0x2036E26C),
+ (0xEDC026E6), (0xB9A617E0), (0x6469F0EE), (0xE9DAABB2), (0x26063210),
+ (0xAC545DF4), (0x134E035A), (0x216EDE10), (0xEC81158D), (0x122A2CAE),
+ (0xA263D0E1), (0x6CA1FB28), (0xBE287DF0), (0x548104E8), (0x35987D93),
+ (0xBC3E549C), (0x3ACEFD64), (0x3348CD92), (0x914472FD), (0x80F28098),
+ (0xDF3FABCD), (0x24D840AC), (0xBA95321C), (0xDC211D20), (0x15041942),
+ (0x61858ABD), (0x546084A1), (0xCEDC07F4), (0xEAB2DE00), (0x045BC1E8),
+ (0x82B2AE86), (0xE4BF2823), (0x9A01B47A), (0x1769438E), (0x015C7986),
+ (0x5FDFF97D), (0x5F28D62C), (0x83C84C8C), (0xDBAC601A), (0x1AE2844F),
+ (0x79F9DC1C), (0x01C3AB5C), (0xC971D839), (0x44DEA398), (0xC0A64EA1),
+ (0x387E24A5), (0x0600D59F), (0x5169B371), (0xEC782B6B), (0xF7FF769D),
+ (0x317B0AE8), (0xE33846C7), (0x2FE05849), (0x03273853), (0x2ED27A88),
+ (0x24DF4343), (0xFB03C70F), (0x82783231), (0xD31C0D29), (0xADC5BD8B),
+ (0x7D024F1B), (0x91C18D19), (0xA8EE58E2), (0x4C23A59F), (0xC61DCA9F),
+ (0x03BC91EC), (0x51986147), (0x05B8BE24), (0x872AC918), (0x8050F1FF),
+ (0x2184812F), (0xB20D941A), (0x9141CB0C), (0xF600A340), (0x80E82AC2),
+ (0x66028631), (0x120FFA45), (0x889F24CB), (0x81F0BB27), (0x3100D51A),
+ (0x2309A0B3), (0xAE004718), (0xAA584A8D), (0x9432DD2E), (0xDD0E93FA),
+ (0xC12993A6), (0x6E28035D), (0x9BF7772B), (0x1D608C32)};
+
+static const INT __twiddles_mips_fft32_1024[] = {
+ (0x7FFFFFFF), (0x00000000), (0x7FFF6215), (0xFF36F078), (0x7FFD8859),
+ (0xFE6DE2E0), (0x7FFA72D0), (0xFDA4D929), (0x7FF62181), (0xFCDBD540),
+ (0x7FF09476), (0xFC12D91B), (0x7FE9CBBE), (0xFB49E6A3), (0x7FE1C76A),
+ (0xFA80FFCE), (0x7FD8878C), (0xF9B82681), (0x7FCE0C3D), (0xF8EF5CBC),
+ (0x7FC25595), (0xF826A464), (0x7FB563B2), (0xF75DFF6B), (0x7FA736B2),
+ (0xF6956FB7), (0x7F97CEBB), (0xF5CCF73E), (0x7F872BF2), (0xF5049800),
+ (0x7F754E7E), (0xF43C53CB), (0x7F62368D), (0xF3742C9D), (0x7F4DE450),
+ (0xF2AC2473), (0x7F3857F4), (0xF1E43D1C), (0x7F2191B2), (0xF11C7895),
+ (0x7F0991C3), (0xF054D8DA), (0x7EF05860), (0xEF8D5FC8), (0x7ED5E5C6),
+ (0xEEC60F3C), (0x7EBA3A38), (0xEDFEE930), (0x7E9D55FB), (0xED37EF91),
+ (0x7E7F3954), (0xEC71244A), (0x7E5FE490), (0xEBAA8944), (0x7E3F5800),
+ (0xEAE4208A), (0x7E1D93EA), (0xEA1DEBC6), (0x7DFA98A7), (0xE957ED00),
+ (0x7DD6668D), (0xE8922621), (0x7DB0FDF5), (0xE7CC9912), (0x7D8A5F3C),
+ (0xE70747B9), (0x7D628AC7), (0xE642341C), (0x7D3980ED), (0xE57D5FE4),
+ (0x7D0F4217), (0xE4B8CD16), (0x7CE3CEB0), (0xE3F47D95), (0x7CB72721),
+ (0xE3307347), (0x7C894BDA), (0xE26CB010), (0x7C5A3D52), (0xE1A935F1),
+ (0x7C29FBEF), (0xE0E6068F), (0x7BF88830), (0xE02323EA), (0x7BC5E296),
+ (0xDF609002), (0x7B920B86), (0xDE9E4C5B), (0x7B5D03A1), (0xDDDC5B4F),
+ (0x7B26CB49), (0xDD1ABE41), (0x7AEF6325), (0xDC59778B), (0x7AB6CB9A),
+ (0xDB98888E), (0x7A7D0559), (0xDAD7F3A2), (0x7A4210DE), (0xDA17BA63),
+ (0x7A05EEA8), (0xD957DE6F), (0x79C89F71), (0xD898621A), (0x798A23A8),
+ (0xD7D946C3), (0x794A7C11), (0xD71A8EBA), (0x7909A935), (0xD65C3B98),
+ (0x78C7AB9E), (0xD59E4EF9), (0x78848419), (0xD4E0CB28), (0x78403321),
+ (0xD423B181), (0x77FAB98A), (0xD367044F), (0x77B417D4), (0xD2AAC4EB),
+ (0x776C4ED9), (0xD1EEF59D), (0x77235F35), (0xD13397FA), (0x76D94983),
+ (0xD078AD93), (0x768E0EA9), (0xCFBE38AD), (0x7641AF32), (0xCF043A9E),
+ (0x75F42C0B), (0xCE4AB5A6), (0x75A585D9), (0xCD91AB55), (0x7555BD47),
+ (0xCCD91D37), (0x7504D34C), (0xCC210D8B), (0x74B2C87B), (0xCB697DA0),
+ (0x745F9DD3), (0xCAB26FB2), (0x740B53ED), (0xC9FBE50E), (0x73B5EBCF),
+ (0xC945DFEB), (0x735F662F), (0xC89061D1), (0x7307C3C9), (0xC7DB6C45),
+ (0x72AF05AB), (0xC727017A), (0x72552C79), (0xC67322B9), (0x71FA3948),
+ (0xC5BFD232), (0x719E2CDE), (0xC50D1164), (0x71410800), (0xC45AE1D1),
+ (0x70E2CBCD), (0xC3A945A1), (0x708378F4), (0xC2F83E1B), (0x7023109C),
+ (0xC247CD62), (0x6FC19376), (0xC197F4BB), (0x6F5F02CF), (0xC0E8B67E),
+ (0x6EFB5F1D), (0xC03A137E), (0x6E96A995), (0xBF8C0DD8), (0x6E30E32F),
+ (0xBEDEA73A), (0x6DCA0D27), (0xBE31E1BF), (0x6D6227FA), (0xBD85BE33),
+ (0x6CF934E8), (0xBCDA3EAE), (0x6C8F3538), (0xBC2F6544), (0x6C242969),
+ (0xBB8532C0), (0x6BB812C5), (0xBADBA934), (0x6B4AF258), (0xBA32CA42),
+ (0x6ADCC976), (0xB98A97F6), (0x6A6D98A1), (0xB8E31318), (0x69FD6132),
+ (0xB83C3DB1), (0x698C2487), (0xB79619C6), (0x6919E326), (0xB6F0A81D),
+ (0x68A69E72), (0xB64BEAB9), (0x68325786), (0xB5A7E331), (0x67BD0FCC),
+ (0xB5049380), (0x6746C7D1), (0xB461FC6A), (0x66CF8103), (0xB3C01FE9),
+ (0x66573CD5), (0xB31EFFF0), (0x65DDFBD6), (0xB27E9D43), (0x6563BF7E),
+ (0xB1DEF9D2), (0x64E8894A), (0xB140178C), (0x646C59CC), (0xB0A1F730),
+ (0x63EF3286), (0xB0049AA9), (0x637114AB), (0xAF68037B), (0x62F201C4),
+ (0xAECC338B), (0x6271FA69), (0xAE312B94), (0x61F10027), (0xAD96ED77),
+ (0x616F148E), (0xACFD7B13), (0x60EC383A), (0xAC64D51F), (0x60686CC0),
+ (0xABCCFD75), (0x5FE3B366), (0xAB35F58C), (0x5F5E0DC8), (0xAA9FBF38),
+ (0x5ED77C86), (0xAA0A5B2C), (0x5E500140), (0xA975CB39), (0x5DC79D9C),
+ (0xA8E2112C), (0x5D3E523E), (0xA84F2DB4), (0x5CB420CD), (0xA7BD229A),
+ (0x5C290AA0), (0xA72BF148), (0x5B9D1166), (0xA69B9B7D), (0x5B1035C7),
+ (0xA60C21E8), (0x5A827978), (0xA57D8646), (0x59F3DE30), (0xA4EFCA51),
+ (0x5964649B), (0xA462EEB2), (0x58D40E75), (0xA3D6F51F), (0x5842DD7E),
+ (0xA34BDF4B), (0x57B0D265), (0xA2C1ADDA), (0x571DEEED), (0xA238627B),
+ (0x568A3482), (0xA1AFFE81), (0x55F5A4ED), (0xA1288391), (0x556040E2),
+ (0xA0A1F24F), (0x54CA0A2E), (0xA01C4C5C), (0x543302A5), (0x9F979356),
+ (0x539B2AFB), (0x9F13C7DC), (0x53028507), (0x9E90EB88), (0x52691241),
+ (0x9E0EFF9D), (0x51CED486), (0x9D8E05AD), (0x5133CC8F), (0x9D0DFE52),
+ (0x5097FC3C), (0x9C8EEB1A), (0x4FFB6572), (0x9C10CD90), (0x4F5E08EB),
+ (0x9B93A649), (0x4EBFE88F), (0x9B1776CB), (0x4E2105E4), (0x9A9C4048),
+ (0x4D8162D8), (0x9A22043F), (0x4CE1002B), (0x99A8C340), (0x4C3FDFCC),
+ (0x99307EC5), (0x4B9E03B1), (0x98B93843), (0x4AFB6C9B), (0x9842F048),
+ (0x4A581C83), (0x97CDA844), (0x49B41562), (0x975961A2), (0x490F57FF),
+ (0x96E61CED), (0x4869E657), (0x9673DB8C), (0x47C3C202), (0x96029E99),
+ (0x471CED05), (0x95926772), (0x46756827), (0x9523369D), (0x45CD356F),
+ (0x94B50D74), (0x452456E9), (0x9447ED4D), (0x447ACD5D), (0x93DBD6AA),
+ (0x43D09AD9), (0x9370CADA), (0x4325C102), (0x9306CAE7), (0x427A417D),
+ (0x929DD7D5), (0x41CE1ECD), (0x9235F32C), (0x412158E3), (0x91CF1CE3),
+ (0x4073F245), (0x9169567D), (0x3FC5ECA0), (0x9104A0F4), (0x3F17499F),
+ (0x90A0FD42), (0x3E680AF3), (0x903E6C5D), (0x3DB8324C), (0x8FDCEF37),
+ (0x3D07C23C), (0x8F7C873A), (0x3C56BAB5), (0x8F1D3461), (0x3BA51E4D),
+ (0x8EBEF810), (0x3AF2EEBA), (0x8E61D331), (0x3A402DB4), (0x8E05C6AA),
+ (0x398CDCF3), (0x8DAAD35D), (0x38D8FE32), (0x8D50FA2B), (0x38249413),
+ (0x8CF83C62), (0x376F9E88), (0x8CA099FB), (0x36BA2034), (0x8C4A1440),
+ (0x36041AD7), (0x8BF4AC06), (0x354D9033), (0x8BA06221), (0x3496820A),
+ (0x8B4D375F), (0x33DEF21F), (0x8AFB2C8E), (0x3326E323), (0x8AAA42E0),
+ (0x326E5505), (0x8A5A7A4D), (0x31B54A79), (0x8A0BD403), (0x30FBC547),
+ (0x89BE50C2), (0x3041C737), (0x8971F14B), (0x2F875216), (0x8926B65A),
+ (0x2ECC67AF), (0x88DCA0A9), (0x2E110ABF), (0x8893B14A), (0x2D553B35),
+ (0x884BE838), (0x2C98FBD1), (0x88054682), (0x2BDC4E63), (0x87BFCCD5),
+ (0x2B1F34BC), (0x877B7BDD), (0x2A61B0AF), (0x87385443), (0x29A3C40F),
+ (0x86F656AC), (0x28E571A3), (0x86B5840E), (0x2826B95E), (0x8675DC62),
+ (0x27679E06), (0x8637609A), (0x26A82174), (0x85FA114F), (0x25E84581),
+ (0x85BDEF19), (0x25280C05), (0x8582FA8C), (0x246777D0), (0x85493482),
+ (0x23A688D3), (0x85109CF7), (0x22E541E0), (0x84D934C0), (0x2223A4D2),
+ (0x84A2FC68), (0x2161B389), (0x846DF472), (0x209F6FE1), (0x843A1D62),
+ (0x1FDCDBBB), (0x840777B9), (0x1F19F9F0), (0x83D60431), (0x1E56CA6E),
+ (0x83A5C2C5), (0x1D935011), (0x8376B42E), (0x1CCF8CBB), (0x8348D8DF),
+ (0x1C0B824E), (0x831C314A), (0x1B4732AE), (0x82F0BDDB), (0x1A829FC0),
+ (0x82C67F00), (0x19BDCC63), (0x829D7553), (0x18F8B888), (0x8275A0D1),
+ (0x18336710), (0x824F0211), (0x176DD9E1), (0x82299974), (0x16A812E3),
+ (0x82056754), (0x15E213FD), (0x81E26C0B), (0x151BDF19), (0x81C0A7F1),
+ (0x1455771D), (0x81A01B80), (0x138EDBF8), (0x8180C6B6), (0x12C81090),
+ (0x8162AA0A), (0x120116D2), (0x8145C5C8), (0x1139F0A7), (0x812A1A36),
+ (0x10729FFB), (0x810FA798), (0x0FAB26B9), (0x80F66E30), (0x0EE387CD),
+ (0x80DE6E5A), (0x0E1BC326), (0x80C7A813), (0x0D53DBAF), (0x80B21BB4),
+ (0x0C8BD356), (0x809DC971), (0x0BC3AC07), (0x808AB17E), (0x0AFB67B2),
+ (0x8078D407), (0x0A330844), (0x8068313B), (0x096A90AB), (0x8058C955),
+ (0x08A200D7), (0x804A9C53), (0x07D95BB6), (0x803DAA6D), (0x0710A337),
+ (0x8031F3C3), (0x0647D949), (0x80277871), (0x057EFFDC), (0x801E3892),
+ (0x04B618DF), (0x8016343D), (0x03ED2743), (0x800F6B8D), (0x03242AF6),
+ (0x8009DE81), (0x025B26E9), (0x80058D31), (0x01921D0C), (0x800277A7),
+ (0x00C90F4F), (0x80009DEB), (0xFFFFFFA3), (0x80000002), (0xFF36F0F5),
+ (0x80009DEB), (0xFE6DE338), (0x800277A6), (0xFDA4D95B), (0x80058D2F),
+ (0xFCDBD54E), (0x8009DE7F), (0xFC12D902), (0x800F6B8A), (0xFB49E665),
+ (0x80163444), (0xFA80FF69), (0x801E389A), (0xF9B826FB), (0x8027786E),
+ (0xF8EF5D0E), (0x8031F3BF), (0xF826A48E), (0x803DAA69), (0xF75DFF6D),
+ (0x804A9C4E), (0xF6956F99), (0x8058C950), (0xF5CCF701), (0x8068314A),
+ (0xF5049793), (0x8078D418), (0xF43C543D), (0x808AB177), (0xF3742CEE),
+ (0x809DC96B), (0xF2AC2495), (0x80B21BAD), (0xF1E43D1E), (0x80C7A80C),
+ (0xF11C7877), (0x80DE6E52), (0xF054D88D), (0x80F66E47), (0xEF8D5F4B),
+ (0x810FA7B0), (0xEEC60F9D), (0x812A1A2D), (0xEDFEE972), (0x8145C5BE),
+ (0xED37EFB3), (0x8162AA00), (0xEC71244C), (0x8180C6AB), (0xEBAA8927),
+ (0x81A01B75), (0xEAE4202D), (0x81C0A810), (0xEA1DEB4A), (0x81E26C2C),
+ (0xE957ED61), (0x82056748), (0xE8922662), (0x82299967), (0xE7CC9933),
+ (0x824F0204), (0xE70747BB), (0x8275A0C3), (0xE64233E0), (0x829D7545),
+ (0xE57D5F89), (0x82C67F27), (0xE4B8CC9B), (0x82F0BE03), (0xE3F47DF5),
+ (0x831C313B), (0xE3307388), (0x8348D8D0), (0xE26CB031), (0x8376B41E),
+ (0xE1A935D4), (0x83A5C2B5), (0xE0E60653), (0x83D60420), (0xE023238F),
+ (0x840777E8), (0xDF608F69), (0x843A1D92), (0xDE9E4CB9), (0x846DF460),
+ (0xDDDC5B6F), (0x84A2FC55), (0xDD1ABE62), (0x84D934AE), (0xDC59776E),
+ (0x85109CE4), (0xDB988872), (0x8549346E), (0xDAD7F348), (0x8582FAC2),
+ (0xDA17BAC1), (0x85BDEF05), (0xD957DECD), (0x85FA113A), (0xD898623B),
+ (0x86376085), (0xD7D946E3), (0x8675DC4D), (0xD71A8E9D), (0x86B583F8),
+ (0xD65C3B40), (0x86F656E9), (0xD59E4EA0), (0x87385481), (0xD4E0CB84),
+ (0x877B7BC6), (0xD423B1DD), (0x87BFCCBD), (0xD367046F), (0x8805466A),
+ (0xD2AAC50A), (0x884BE820), (0xD1EEF581), (0x8893B132), (0xD13397A2),
+ (0x88DCA0EE), (0xD078AD3C), (0x8926B6A0), (0xCFBE3908), (0x8971F132),
+ (0xCF043AF8), (0x89BE50A8), (0xCE4AB5C6), (0x8A0BD3E8), (0xCD91AB39),
+ (0x8A5A7A32), (0xCCD91D1C), (0x8AAA42C5), (0xCC210D35), (0x8AFB2CDB),
+ (0xCB697D4B), (0x8B4D37AC), (0xCAB2700B), (0x8BA06204), (0xC9FBE567),
+ (0x8BF4ABE9), (0xC945E00A), (0x8C4A1423), (0xC89061B6), (0x8CA099DE),
+ (0xC7DB6C2A), (0x8CF83C44), (0xC7270126), (0x8D50FA7F), (0xC6732265),
+ (0x8DAAD3B2), (0xC5BFD1A5), (0x8E05C6FF), (0xC50D109F), (0x8E61D388),
+ (0xC45AE10D), (0x8EBEF868), (0xC3A94669), (0x8F1D33C8), (0xC2F83EE1),
+ (0x8F7C86A0), (0xC247CDF0), (0x8FDCEF16), (0xC197F548), (0x903E6C3B),
+ (0xC0E8B69C), (0x90A0FD21), (0xC03A139B), (0x9104A0D2), (0xBF8C0DF6),
+ (0x9169565A), (0xBEDEA758), (0x91CF1CC0), (0xBE31E16E), (0x9235F309),
+ (0xBD85BDE2), (0x929DD837), (0xBCDA3E5E), (0x9306CB49), (0xBC2F6487),
+ (0x9370CB3D), (0xBB853205), (0x93DBD70E), (0xBADBA879), (0x9447EDB3),
+ (0xBA32CB35), (0x94B50D09), (0xB98A987D), (0x95233631), (0xB8E3139E),
+ (0x95926705), (0xB83C3E37), (0x96029E73), (0xB79619E2), (0x9673DB66),
+ (0xB6F0A839), (0x96E61CC6), (0xB64BEAD5), (0x9759617B), (0xB5A7E34D),
+ (0x97CDA867), (0xB5049334), (0x9842F06B), (0xB461FC1F), (0x98B93866),
+ (0xB3C01F9D), (0x99307F35), (0xB31EFF3F), (0x99A8C3B0), (0xB27E9C92),
+ (0x9A2204B0), (0xB1DEF922), (0x9A9C4109), (0xB140180C), (0x9B177652),
+ (0xB0A1F7AF), (0x9B93A5CF), (0xB0049B27), (0x9C10CD15), (0xAF6803F9),
+ (0x9C8EEAEF), (0xAECC33A5), (0x9D0DFE27), (0xAE312BAE), (0x9D8E0581),
+ (0xAD96ED91), (0x9E0EFFC3), (0xACFD7ACC), (0x9E90EBAF), (0xAC64D4D8),
+ (0x9F13C803), (0xABCCFD2E), (0x9F97937D), (0xAB35F545), (0xA01C4CD8),
+ (0xAA9FBE92), (0xA0A1F2CC), (0xAA0A5A88), (0xA128840F), (0xA975CC0F),
+ (0xA1AFFDFC), (0xA8E211A2), (0xA23861F5), (0xA84F2E2A), (0xA2C1AD53),
+ (0xA7BD2310), (0xA34BDEC3), (0xA72BF1BC), (0xA3D6F4F0), (0xA69B9B96),
+ (0xA462EE82), (0xA60C2200), (0xA4EFCA21), (0xA57D865E), (0xA57D8670),
+ (0xA4EFCA0F), (0xA60C2213), (0xA462EE70), (0xA69B9BA8), (0xA3D6F4DE),
+ (0xA72BF1CF), (0xA34BDEB2), (0xA7BD2322), (0xA2C1AD42), (0xA84F2E3D),
+ (0xA23861E4), (0xA8E211B5), (0xA1AFFF45), (0xA975CAA9), (0xA12883FE),
+ (0xAA0A5A9B), (0xA0A1F2BB), (0xAA9FBEA5), (0xA01C4CC7), (0xAB35F559),
+ (0x9F97936C), (0xABCCFD41), (0x9F13C7F2), (0xAC64D4EB), (0x9E90EB9E),
+ (0xACFD7ADF), (0x9E0EFFB3), (0xAD96EDA5), (0x9D8E0571), (0xAE312BC2),
+ (0x9D0DFE16), (0xAECC33B9), (0x9C8EEADF), (0xAF68040D), (0x9C10CD05),
+ (0xB0049B3B), (0x9B93A5BF), (0xB0A1F7C3), (0x9B177642), (0xB1401820),
+ (0x9A9C40F9), (0xB1DEF936), (0x9A2204A1), (0xB27E9CA6), (0x99A8C3A1),
+ (0xB31EFF54), (0x99307F26), (0xB3C01FB2), (0x98B93857), (0xB461FC33),
+ (0x9842F05C), (0xB5049349), (0x97CDA858), (0xB5A7E362), (0x9759616C),
+ (0xB64BEAEA), (0x96E61CB8), (0xB6F0A84E), (0x9673DB57), (0xB79619F7),
+ (0x96029E64), (0xB83C3E4C), (0x959266F7), (0xB8E313B4), (0x95233623),
+ (0xB98A9893), (0x94B50E13), (0xBA32C99E), (0x9447EDA5), (0xBADBA88F),
+ (0x93DBD700), (0xBB85321A), (0x9370CB30), (0xBC2F649D), (0x9306CB3C),
+ (0xBCDA3E74), (0x929DD829), (0xBD85BDF8), (0x9235F2FC), (0xBE31E184),
+ (0x91CF1CB3), (0xBEDEA76E), (0x9169564D), (0xBF8C0E0C), (0x9104A0C5),
+ (0xC03A13B2), (0x90A0FD14), (0xC0E8B6B2), (0x903E6C2F), (0xC197F55F),
+ (0x8FDCEF09), (0xC247CE07), (0x8F7C8694), (0xC2F83EF8), (0x8F1D34AD),
+ (0xC3A944BC), (0x8EBEF85C), (0xC45AE123), (0x8E61D37C), (0xC50D10B6),
+ (0x8E05C6F4), (0xC5BFD1BC), (0x8DAAD3A6), (0xC673227C), (0x8D50FA73),
+ (0xC727013D), (0x8CF83C39), (0xC7DB6C41), (0x8CA099D3), (0xC89061CD),
+ (0x8C4A1418), (0xC945E021), (0x8BF4ABDF), (0xC9FBE57E), (0x8BA061F9),
+ (0xCAB27022), (0x8B4D3738), (0xCB697E4C), (0x8AFB2C68), (0xCC210E37),
+ (0x8AAA4254), (0xCCD91E1E), (0x8A5A7A8D), (0xCD91AA66), (0x8A0BD442),
+ (0xCE4AB4F1), (0x89BE5100), (0xCF043A24), (0x8971F188), (0xCFBE3833),
+ (0x8926B697), (0xD078AD53), (0x88DCA0E4), (0xD13397BA), (0x8893B128),
+ (0xD1EEF599), (0x884BE817), (0xD2AAC522), (0x88054661), (0xD3670487),
+ (0x87BFCCB5), (0xD423B1F5), (0x877B7BBD), (0xD4E0CB9C), (0x87385424),
+ (0xD59E4FAA), (0x86F6568E), (0xD65C3C4A), (0x86B5839E), (0xD71A8FA8),
+ (0x8675DC95), (0xD7D94608), (0x863760CC), (0xD8986160), (0x85FA1180),
+ (0xD957DDF1), (0x85BDEF49), (0xDA17B9E5), (0x8582FABB), (0xDAD7F360),
+ (0x85493467), (0xDB98888A), (0x85109CDD), (0xDC597787), (0x84D934A7),
+ (0xDD1ABE7A), (0x84A2FC4F), (0xDDDC5B88), (0x846DF45A), (0xDE9E4CD2),
+ (0x843A1D4B), (0xDF60907A), (0x840777A2), (0xE02324A0), (0x83D603DC),
+ (0xE0E60764), (0x83A5C2EC), (0xE1A934F4), (0x8376B454), (0xE26CAF51),
+ (0x8348D904), (0xE33072A7), (0x831C316D), (0xE3F47D14), (0x82F0BDFE),
+ (0xE4B8CCB4), (0x82C67F21), (0xE57D5FA2), (0x829D7540), (0xE64233F9),
+ (0x8275A0BE), (0xE70747D4), (0x824F0200), (0xE7CC994C), (0x82299962),
+ (0xE892267C), (0x82056743), (0xE957ED7A), (0x81E26BFB), (0xEA1DEC5F),
+ (0x81C0A7E1), (0xEAE42143), (0x81A01B48), (0xEBAA8A3D), (0x8180C6CF),
+ (0xEC712368), (0x8162AA22), (0xED37EECF), (0x8145C5DF), (0xEDFEE88E),
+ (0x812A1A4C), (0xEEC60EB9), (0x810FA7AD), (0xEF8D5F65), (0x80F66E44),
+ (0xF054D8A6), (0x80DE6E4F), (0xF11C7891), (0x80C7A809), (0xF1E43D38),
+ (0x80B21BAA), (0xF2AC24AF), (0x809DC968), (0xF3742D08), (0x808AB175),
+ (0xF43C5456), (0x8078D3FF), (0xF50498AB), (0x80683134), (0xF5CCF819),
+ (0x8058C93B), (0xF69570B2), (0x804A9C5E), (0xF75DFE87), (0x803DAA77),
+ (0xF826A3A8), (0x8031F3CB), (0xF8EF5C28), (0x80277879), (0xF9B82615),
+ (0x801E3899), (0xFA80FF82), (0x80163443), (0xFB49E67F), (0x800F6B8A),
+ (0xFC12D91B), (0x8009DE7E), (0xFCDBD568), (0x80058D2F), (0xFDA4D975),
+ (0x800277A6), (0xFE6DE352), (0x80009DEA), (0xFF36F10F), (0x656DBCC8),
+ (0x7A9108CA), (0xBA3670F0), (0x699195A2), (0x172D2FD0), (0xBE386D51),
+ (0xC4AEA51C), (0x2AA77D7D), (0x8B51D3B4), (0xCF490FD9), (0x4A7BEBCA),
+ (0x91072E04), (0xA175872D), (0x54464A9E), (0x67A6CD02), (0x9E8204A8),
+ (0x10C14BF6), (0x75ACDA16), (0xF78D7B3E), (0x6AB3CF69), (0xA4D8C756),
+ (0xCB8FCD24), (0x75CC5713), (0xC13E5AE3), (0xA8C3176D), (0x5EE6D416),
+ (0x80C5DA0E), (0xD84A007C), (0x719E73C0), (0x765014B0), (0x0A391BC8),
+ (0x60A70223), (0x54CDA46B), (0x4606D455), (0xA606FB2A), (0xE4CE1557),
+ (0x73240820), (0x8037A8B4), (0xA1D88032), (0x75A3F1C7), (0x32BB0370),
+ (0x5F850242), (0x85EC8F5B), (0x8AA2B33C), (0x91B370C2), (0x938E9DDB),
+ (0xE6B6983E), (0x49602AA9), (0x6C2D9965), (0x5B16AE72), (0x69579B6B),
+ (0xCD3AB415), (0x5B7CF03C), (0xD7B27637), (0x2D69B79A), (0x3237B468),
+ (0x5F94D650), (0xAB37106D), (0x0B831457), (0xAFD80334), (0xB5A0B27B),
+ (0x16B763E9), (0x3B454756), (0x3167CD98), (0x707239AF), (0x0A4F132A),
+ (0x2782C8CA), (0x1AC1DD4E), (0x121CADFE), (0x9A911D90), (0x0157ADD6),
+ (0x1559BB95), (0x2854C84A), (0xD97E3685), (0x76308AA0), (0x8050F1FF),
+ (0x2180612F), (0xFFFB8A1A), (0x0BC1FFFF), (0x1032846C), (0x002A30C2),
+ (0x654C58F2), (0xA58ABACC), (0xC3E9831C), (0x27531B8C), (0xADBB8698),
+ (0x06801C12), (0xAFAEEC8E), (0xC3269291), (0x5C2E01A0), (0x4A61087C),
+ (0x60F21E7B), (0x6B92C670), (0xC9872364), (0x48464C97), (0x342E6499),
+ (0xA6849A48), (0xF034002D), (0x442B4488), (0x160B0442), (0xED52CF50),
+ (0x4D436C05), (0x6841C602), (0xA14F8A82), (0x9AC20DDE), (0x5B9251EE),
+ (0x8ED998D5), (0x92B6EA22), (0x5B136C4B), (0x97C0A45B), (0x459C94A4),
+ (0xCD9583C0), (0x6C589DF8), (0x3C9A17CD), (0x906601BF), (0x84D612E1),
+ (0x67176F5F), (0xE47D5A44), (0x37386D5E), (0x92A4D61B), (0x28C513FB),
+ (0x6E91599A), (0x653DA16D), (0xA19C39C0), (0x427690AD), (0x7005461C),
+ (0xAB6C1EE4), (0x80BACC2D), (0x780A18C5), (0x822DC774), (0xB6043036),
+ (0x00789C18), (0x106C9507), (0x4103A864), (0xC511585B), (0xF3E9B7F8),
+ (0x24D79C4D), (0x31B20EB5), (0xB1C0483E), (0xE25C56B9), (0x96991096),
+ (0x7CD4121F), (0x8A3B83F4), (0x704271C2), (0xB5C26ACC), (0x2B131AF0),
+ (0x549CB16C), (0x74649E69), (0xD8D48ADE), (0x1253AEDD), (0x80410FD2),
+ (0x5B36889D), (0x880CE1E7), (0x56C498E7), (0xFA2BAAB2), (0xD4154F5C),
+ (0x79516EED), (0xA42FDA7D), (0x278D2873), (0x19121535), (0x9C6EC6C7),
+ (0x402340CB), (0x5A6A32B3), (0xE4345F27), (0x8DC2D901), (0x02E7F88E),
+ (0x7B3C6BEB), (0xE0946A4F), (0x9452886C), (0xFF2F6187), (0x2F8050F1),
+ (0x2A217C61), (0x0AB21594), (0x801145C4), (0x1CF200A5), (0x82C544F1),
+ (0xCF3C50B0), (0xD577FEF7), (0x60AD3C6E), (0x91AFF79E), (0x070723B3),
+ (0x5870ECF6), (0x64C224E2), (0x24FB1EC8), (0xC3481048), (0x151ABF3C),
+ (0x136AC219), (0x4716CED1), (0xC8B8CE4E), (0x1D168210), (0x92334A81),
+ (0x90DC910C), (0x49A00220), (0xE5F2C831), (0xB67DC785), (0x3C495174),
+ (0x0D1F4C2A), (0x3AD787FD), (0xE9C9FB27), (0x7DFC2713), (0xEB39C4B3),
+ (0x96F75F18), (0x883CCC47), (0x91390BD1), (0x0EE25F6D), (0x6B688EF0),
+ (0x2C8557DC), (0xE80C9172), (0xDE63DE06), (0x3E1B707B), (0xB2CF2E76),
+ (0x490D1DF3), (0xCD1B51E1), (0xC228F0F9), (0xEEE2A00A), (0x081D834A),
+ (0x1D2C1403), (0x083FE940), (0x7614EDA0), (0x8282095A), (0xA7C08821),
+ (0x4CD47D20), (0x32299191), (0x52A030E6), (0xDF7CB76E), (0x232ED44B),
+ (0x8DAA150A), (0x1B593C51), (0x449CBA82), (0xABE6D3C4), (0xCCF6F5C3),
+ (0x9064C1C2), (0x031FF59C), (0x4159FE4E), (0x421482C0), (0x20F6F00A),
+ (0xB866CA49), (0x75A66FAA), (0x5453515F), (0xB545D486), (0x885D9493),
+ (0xEEC4EEB4), (0x88F9C893), (0xBBAA38B4), (0x5A57BA83), (0x12E848CC),
+ (0x2FB62160), (0x840A1A54), (0x2A7AEDD6), (0x89AF2DBD), (0xC8BAAE2E),
+ (0x56EEBD75), (0xE595B86D), (0xEEB123C6), (0x3F94EBC1), (0x78CFBEE2),
+ (0xCF901F11), (0x5A35A350), (0xDA22CB58), (0xBE4B8287), (0x25E078C0),
+ (0x2BD4F0D3), (0x6A464B99), (0x4884B156), (0xF1FF7630), (0xC1328050),
+ (0xD84C216C), (0x84A4D942), (0x2157A0A0), (0xF30A1412), (0x54AF6011),
+ (0x00D70542), (0xBDABE7DB), (0x1FF3534C), (0xD8672B4E), (0x7BE3BB3A),
+ (0xC5595540), (0x161E1BFF), (0xD4372309), (0x7BC2ED52), (0xC1C636ED),
+ (0x4DD32AA4), (0x86163246), (0x614EF688), (0x4EB44270), (0x88ED077C),
+ (0x2F229466), (0x1A585201), (0x65BB2EE2), (0xDBADA0DD), (0xE50995CB),
+ (0xCA1E2760), (0x583FD81F), (0xE48D4859), (0xC2006152), (0x8F1F770C),
+ (0x27CAA86F), (0x9610B845), (0xFC25BCE3), (0x37B8B39F), (0x10DCCDD1),
+ (0xD57A4CAB), (0x7D543DE8), (0x6F45B958), (0x12F0B979), (0x818E79F9),
+ (0xB4B2B01F), (0xF3035901), (0x372F7BD9), (0x5D592E67), (0xDB5A552F),
+ (0x6E61E625), (0x4E8A6A42), (0x2458ADB8), (0x5F12528C), (0x272B3ADE),
+ (0xDE666A83), (0x7F18CFD7), (0x2F877DD8), (0xD73FFFB6), (0x79867956),
+ (0x4E05FCAD), (0x19E78EEE), (0xE1BA6512), (0x99F6F091), (0x91690516),
+ (0x16AE4041), (0x04B96805), (0x7CA052FC), (0xA4D05EFD), (0x413D1F04),
+ (0x53E91CC0), (0x6F87A082), (0x604FD202), (0x0B368D9F), (0xD5F22E5C),
+ (0x2BE5A74E), (0x2F69EADE), (0x8BE537E1), (0x96975789), (0x3675A3A0),
+ (0x0A272B71), (0x754B1D61), (0x98600581), (0x659A2BE3), (0xB21BEF54),
+ (0xF26351B0), (0x1C599573), (0x6B423B59), (0xEA371C96), (0xC9BDA499),
+ (0xDDF25F37), (0xFBCAC4AD), (0x40CA788B), (0x13BC3981), (0x4176DA58),
+ (0xD848DA74), (0x94740642), (0x54FD5479), (0x71502362), (0x25E81CF9),
+ (0x53249562), (0x52814827), (0x55DC5F2C), (0x8825BC50), (0x8E4D04D9),
+ (0x8050F1FF), (0x212CC13E), (0x00C0D84C), (0x07711003), (0x406A5F45),
+ (0xED0A98DE), (0x8A619731), (0x796A3B04), (0x7EAECF71), (0x7DF3DABE),
+ (0x2B0FFB4A), (0xBA8A3FB8), (0x6202F8F2), (0x632C37B2), (0x205271AA),
+ (0xBA1C438C), (0xAA1C1182), (0xE6442A65), (0xD736E043), (0x95715C5C),
+ (0x3D604C28), (0xD21D0D74), (0xA1FB0C21), (0xCE8F065D), (0xB8B36463),
+ (0x7F788C33), (0x84AB53A5), (0x4B33AF46), (0x40C2736A), (0x0D6571B7),
+ (0xFC8D8292), (0x9D1C5182), (0xF7B670E2), (0xBB2B9E91), (0x137851D5),
+ (0xBCF87CA8), (0xE082A7A6), (0x502404E5), (0x5025A6E0), (0x25494EA6),
+ (0x5A6A8A14), (0xE301A689), (0x70CBEE6B), (0xC80644C1), (0xE9914CE6),
+ (0x9481F1E6), (0xB9E4DA34), (0x584B1ED8), (0xACC39648), (0x31EFCD62),
+ (0x07C82AE9), (0xEE9D90E5), (0x59BAEC75), (0x40178B0E), (0x9FDC1C9C),
+ (0xF3A6488F), (0x4B6C1367), (0x9F7DF109), (0xCBDF8EDF), (0xBA76ED33),
+ (0xF15DBB9F), (0xD48A197F), (0xF11E75EE), (0xA76B479B), (0x706DE78B),
+ (0x6559AC65), (0xC013C182), (0x461E93C7), (0xA989EAF1), (0x59448C00),
+ (0x721FAC38), (0x546DEA79), (0x223F67C0), (0x5434647C), (0xB3EF4F0A),
+ (0xD4FAF1F1), (0x0BD4E38A), (0xFF61527E), (0xD6EA5DD2), (0x644C7105),
+ (0x31AE2189), (0x11EC0A1A), (0x18B3AD80), (0x47D0E80A), (0x773D8BB2),
+ (0xEFA6747E), (0xF23DE8B0), (0x026BB1E7), (0x03C14060), (0xC1997DF7),
+ (0x95986B9C), (0x8A5D6170), (0x54DB3A56), (0x22961D41), (0x46813471),
+ (0xABED16A4), (0xD1F83E8C), (0x2594ACAC), (0x1D5560EA), (0x0432EFF4),
+ (0xA389D7E8), (0xAFE92C62), (0xFBBAF1E7), (0x42D0D0A1), (0xA2C3ECB2),
+ (0x603DD635), (0xEBBC5915), (0x5B0C7CE0), (0x8D03640C), (0x22E298DB),
+ (0x38CE3BDC), (0x21E6B6B4), (0xC9742C3F), (0x4BDF7448), (0xBAD09D00),
+ (0xED6A8397), (0xF6F8001A), (0x31E3591E), (0xAEC37EFE), (0x22D9AD06),
+ (0x5E254AEC), (0xD852D32E), (0xE1C968AE), (0xA3C3C265), (0xD67BD78A),
+ (0xF1FF9D8C), (0xC03A8050), (0x847A21FC), (0x810EDA5D), (0x63808951),
+ (0xC8FE9E9E), (0xFB6DD3E5), (0x77BD7A03), (0x6DC14677), (0xFF81D831),
+ (0x43201100), (0xA78E16FE), (0x393CD0A0), (0x514F6DDD), (0x427BA4BC),
+ (0xEBE7A676), (0xB771639B), (0x8DABB9E7), (0x812FA5AD), (0x3F102120),
+ (0x60E42454), (0xEFFBFFC5), (0xBEB1D5DD), (0x7A59DDFD), (0xE8968D7A),
+ (0x8AAD3462), (0xAB65327D), (0x0CF2ECFB), (0xFA3249A4), (0x97FC3A42),
+ (0x314A7089), (0x2991E6DC), (0xA98693C4), (0x65EB2011), (0xCB4D8594),
+ (0x1AAFF14E), (0x1D0D0492), (0x2E5A784D), (0xAE4EC738), (0xF16D667A),
+ (0xB0C26030), (0xADA3DFC9), (0x4ED874E5), (0xD441A6AE), (0x19E3AC05),
+ (0xC6B865DC), (0xE8E4285A), (0x99248C2B), (0xC2981122), (0x1B014288),
+ (0x442A0580), (0x84A0A1C1), (0x216F0248), (0x202E5602), (0xEAEBAACA),
+ (0xDD5ABEE7), (0x8B9C4B43), (0x5D5D46D7), (0x8FBE7C1D), (0x6F9CAB87),
+ (0xB0AB0AAE), (0x98BC7936), (0xF251B911), (0x4469F2D1), (0xA9099088),
+ (0xD219BD66), (0x7490AE22), (0xBC0A9820), (0x119D0136), (0x8592661C),
+ (0x260C0D18), (0xB9A1C5B1), (0xA68591E4), (0xFCBD4F29), (0x5965A3C7),
+ (0x7D1ED664), (0x9BDDEEE3), (0x92237D5A), (0xB7332DA6), (0xEA5632E5),
+ (0x9BFE1624), (0x6A2BB18A), (0x8C0DD72C), (0x4F319F56), (0xEE8B5B03),
+ (0x60967BC8), (0xB4918F75), (0xF295D5F6), (0x652AD80D), (0x0CCE9552),
+ (0x0BCAA0A6), (0x3CF2D28E), (0x1853956E), (0x7B38DEAA), (0xEAAB970B),
+ (0x64086D1F), (0x3E7645DD), (0x986F1342), (0xBBB0E188), (0x7D6D5642),
+ (0x6821827D), (0xFCBC4729), (0x3D114FB9), (0x2D2542E5), (0x654CC1F0),
+ (0x04F1B75E), (0x290B54AF), (0x7D79AB1A), (0xF34E31A2), (0x73A9F300),
+ (0x7ABCA89E), (0xB56DA974), (0xCACDB07C), (0x4EE1ADD4), (0xEF859B34),
+ (0x89F47B47), (0x515C155A), (0x38D06757), (0x8050F1FF), (0x21C8E03A),
+ (0xB155841A), (0x30716685), (0x0A2B48AC), (0x7041C40A), (0x104C44D0),
+ (0x1F51B618), (0xF0D4F39B), (0xFCAEBA52), (0x30EA62CD), (0xA294B772),
+ (0x221E0417), (0xAA8EF192), (0x3E568C78), (0xD386EF9A), (0x13B54FB1),
+ (0x84818EC3), (0xB87669F8), (0xCD90565A), (0x73D7C876), (0xD6191512),
+ (0xAC228704), (0xA7785D48), (0x17CF34DD), (0x8AF5AB40), (0x365C6AFA),
+ (0x17DFD59E), (0xB924C26E), (0xE9DE5844), (0x3DCDDCD9), (0xCDA2DFB4),
+ (0x8A5B534E), (0xA2D9DACA), (0x11679569), (0xAEF6E7E9), (0xC9D2417C),
+ (0x515DC9C3), (0x157A5B12), (0x4C960DD6), (0xD413CC01), (0x65319545),
+ (0x6CF1309D), (0x000338C7), (0x460AA7FC), (0xC1FA4440), (0x0E3AE048),
+ (0xF4B212B5), (0xC7895D2B), (0x676AFAF3), (0xEF404F75), (0xBFCDB17C),
+ (0xA37FE6C6), (0x20123DD5), (0xEE96BD3B), (0x3EB8A62E), (0x068845E1),
+ (0xC4960216), (0x7BB11D8D), (0x2D657467), (0xFC6FACC5), (0xC21AAD31),
+ (0x642745F4), (0x4507E139), (0xF7369DC9), (0x6198ADEB), (0x63B98B10),
+ (0xDEE585AB), (0xA38EFFAC), (0x30AE1E41), (0x820667A9), (0x6B77A007),
+ (0x240040A7), (0xB77A7D95), (0x208893CA), (0x085B4610), (0x14234854),
+ (0xAC022786), (0x2D57346F), (0xB64A1A67), (0x605D45B2), (0xE051C001),
+ (0x9176C11D), (0x23BBE945), (0x2C03E26A), (0xC2811BAD), (0x1DD814D4),
+ (0x3C674B68), (0x28EC33C7), (0xD9EDE5E4), (0x5C46C248), (0x4098898F),
+ (0x5BA96280), (0xEFF77B91), (0x3332CA5B), (0x661CAF6B), (0x6E0D564E),
+ (0xB70D0863), (0x240285C0), (0xBBBD3EA7), (0xCA2E568D), (0xD1D3F612),
+ (0xC916115E), (0xB7FC0A6C), (0x1961AE9A), (0xB5DF3965), (0xC1B95065),
+ (0x89E29665), (0x3F29FBED), (0x3F1BED73), (0xC155BE1D), (0x7256AE4C),
+ (0x4A59797B), (0x6009D13B), (0x91850385), (0xE4545920), (0x15ECCDA1),
+ (0xFFC7BA20), (0x2B8050F1), (0x1A21D4C0), (0x3008BE89), (0x6C0FF317),
+ (0x7444D852), (0x05841411), (0x84C80022), (0x07C630E0), (0x7E6F8FA3),
+ (0xF3BDF3C7), (0x4C55DFF7), (0xE0B1C8D1), (0xC3F5CF4D), (0x1C22A836),
+ (0xB29D3315), (0xD4966541), (0x45C85800), (0xAD8DBD46), (0x2C19CFAA),
+ (0x540FA674), (0xC3C913D8), (0xD2183753), (0xCB9FCF26), (0x8346FC89),
+ (0xA3408078), (0xCFD84CC1), (0xF580F035), (0x7FD067A7), (0x87E7FCB8),
+ (0x09C09406), (0xDDBB3131), (0xFF79FFE1), (0xEAFBEEF1), (0xB660BCE8),
+ (0x99899C31), (0x9FEB22C1), (0xC75EF68F), (0x13800B99), (0xCD7F3100),
+ (0x09502ADC), (0x101E00E8), (0x406CB945), (0x820A1B2B), (0x68A0B082),
+ (0x0C1B1864), (0xB3690354), (0x63C5B5A3), (0x535EB4C8), (0xF7D86918),
+ (0xD1BA58FC), (0xF42910FA), (0xFBDB1929), (0xC7C0C2A4), (0xD2074752),
+ (0xB96803B4), (0x84065E38), (0x819AF48E), (0xE9864FF3), (0xA6E41D0E),
+ (0x50E7442B), (0xC7574D7B), (0x196B6AB3), (0x041D5854), (0x629162D3),
+ (0x042713E0), (0x9AE31297), (0x4B2F4E36), (0xCB8CE0E0), (0xB2F0682A),
+ (0xAB33D6F5), (0x2F53D82E), (0x66A43815), (0x4433AAA8), (0x82EA0ED5),
+ (0x457876F2), (0xD30BD36C), (0x8D49D28C), (0x0E68260E), (0xD056512C),
+ (0x7B86DB11), (0x64633661), (0x8265FF25), (0x6D2B7148), (0x529DA0D8),
+ (0xBC180017), (0x19AB803B), (0x83F00020), (0x50F1FF07), (0xD4C02D80),
+ (0xFC881A21), (0xC1BF0100), (0x5841680B), (0x103B2CC0), (0xB042C28A),
+ (0x2324E8A8), (0x31531430), (0xEF71DD0E), (0x7C1B9D8E), (0x0998C228),
+ (0xD9EC6548), (0x8EEF8448), (0x0C561CAF), (0x4BA39DFD), (0x58947FE2),
+ (0x959B12A2), (0x6D52EAEC), (0x1D95DDD5), (0x310C222B), (0x63634B18),
+ (0x4DE6C5B8), (0x526C9106), (0x49B5E8CC), (0xC3C33004), (0x605CD287),
+ (0x09A6390C), (0x350C33BC), (0x953050CC), (0x960552A3), (0x54F01186),
+ (0x0E8D7CFE), (0x459A0022), (0xC3576966), (0xB0D6F6E8), (0xB8F13AAC),
+ (0xE440034C), (0x36118851), (0xF51BE727), (0x2E1689A0), (0xE82CCF55),
+ (0x6DF4E3CB), (0xEA665663), (0xC2E53D6F), (0x9DC1F06B), (0xFCC2E878),
+ (0x4292D162), (0x4840C433), (0xB618DB43), (0x06092C15), (0x500134C1),
+ (0xA6DB8955), (0xD5E8A5BB), (0x142B7829), (0x75F42939), (0x0EBF4D10),
+ (0x1A2B078C), (0x7C2A5A46), (0x3EA1B9A7), (0x31AAC898), (0x1327B852),
+ (0x277C65A1), (0x5280CE27), (0xFF512213), (0x39B47EBF), (0x154CA000),
+ (0x106E7DA2), (0xAFA4C925), (0xC48CE379), (0xAB2E4573), (0x5E44B8FD),
+ (0xECD2A424), (0x8C5300AA), (0xE425A180), (0x6D5D0D3B), (0xA70540A8),
+ (0xF8ECF432), (0x884696B0), (0xB79755BF), (0x62CAD419), (0x4BBB38B6),
+ (0xCD5C79D7), (0x82D4E29B), (0x6DD48E91), (0xA128A3A9), (0xF2ED6726),
+ (0x339A63F6), (0x35D6F4EA), (0x8DC8B491), (0xCA04D09C), (0xFF074FD0),
+ (0x2D8050F1), (0x1A21D880), (0x1900FE88), (0x6C09D1BF), (0x56483001),
+ (0xC20A1A29), (0x449180A3), (0x028C5160), (0x75FAECDD), (0x6250705B),
+ (0x89EA010A), (0x7B9F9851), (0x9D6C5994), (0x8602C3E4), (0x03D0E863),
+ (0x04322251), (0x116095B7), (0x789276CA), (0x00000000), (0x00000978),
+ (0x8000C688), (0x8000BCD8), (0x80010000), (0x9FC3F7B8), (0xDE47BC1B),
+ (0xE60FB4F8), (0xEA27469D), (0xCCA1E66D), (0x8FFF7010), (0x8000BCD8),
+ (0x000000D0), (0x8000B4B0), (0x8FFFFB24), (0x9FC3F7B8), (0x00000000),
+ (0x8000B418), (0x8FFF7010), (0x8000C688), (0x000000D0), (0x9FC3FD3C),
+ (0xD625F8C0), (0x478D832A), (0xF693D922), (0x3617D816), (0x80000648),
+ (0x00000000), (0x00000003), (0x00000012), (0x9FC49964), (0x46141924),
+ (0x4D834205), (0x16B799A6), (0xA39494A6), (0xCCF23C60), (0x00000001),
+ (0x9FC47468), (0x00000000), (0x00000072), (0x00008001), (0x8FFFFB58),
+ (0x00000003), (0x402C7413), (0x00000016), (0x402C7413), (0x9FC48498),
+ (0x00000000), (0x00000002), (0x00000001), (0x00000072), (0x9FC4783C),
+ (0x8000C690), (0x0358CDD5), (0x00000000), (0x00008001), (0x00000072),
+ (0x80000648), (0x00000000), (0x00008001), (0x8000BD40), (0x1A19F8D8),
+ (0x00008001), (0x800003C0), (0x00000003), (0x9FC428CC), (0xF6192015),
+ (0xFBB77F92), (0x8F2C8BFC), (0x3C391923), (0x4014428C), (0x140045AE),
+ (0xFFFD2BB6), (0x2D8050F1), (0x8000BD40), (0x00000003), (0x00000000),
+ (0x2CC05811), (0x00008001), (0x800003C0), (0x80000648), (0x80000648),
+ (0x9FC4206C), (0x8FFFFD78), (0x8FFFFEEC), (0x8000C668), (0x80000648),
+ (0x8FFFFD78), (0x00000000), (0x00003040), (0x8000FFC0), (0x8000BCD8),
+ (0x80010000), (0x9FC3F7B8), (0x00000000), (0x00002CC0), (0x80013340),
+ (0x8000BCD8), (0x80010FD0), (0x80012548)};
diff --git a/fdk-aac/libFDK/src/mips/scale_mips.cpp b/fdk-aac/libFDK/src/mips/scale_mips.cpp
new file mode 100644
index 0000000..1a3d33c
--- /dev/null
+++ b/fdk-aac/libFDK/src/mips/scale_mips.cpp
@@ -0,0 +1,133 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#if defined(__mips_dsp)
+
+#ifndef FUNCTION_getScalefactor_DBL
+#define FUNCTION_getScalefactor_DBL
+/*!
+ *
+ * \brief Calculate max possible scale factor for input vector
+ *
+ * \return Maximum scale factor
+ *
+ * This function can constitute a significant amount of computational
+ * complexity - very much depending on the bitrate. Since it is a rather small
+ * function, effective assembler optimization might be possible.
+ *
+ */
+SCALE_INLINE
+INT getScalefactor(const FIXP_DBL *vector, /*!< Pointer to input vector */
+ INT len) /*!< Length of input vector */
+{
+ INT i;
+ FIXP_DBL maxVal = FL2FX_DBL(0.0f);
+
+ for (i = len; i != 0; i--) {
+ maxVal |= __builtin_mips_absq_s_w(*vector++);
+ }
+
+ return fixMax((INT)0, (CntLeadingZeros(maxVal) - 1));
+}
+#endif
+
+#endif /*__mips_dsp */
diff --git a/fdk-aac/libFDK/src/nlc_dec.cpp b/fdk-aac/libFDK/src/nlc_dec.cpp
new file mode 100644
index 0000000..6e98ce0
--- /dev/null
+++ b/fdk-aac/libFDK/src/nlc_dec.cpp
@@ -0,0 +1,1071 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Omer Osman
+
+ Description: SAC/SAOC Dec Noiseless Coding
+
+*******************************************************************************/
+
+#include "nlc_dec.h"
+#include "FDK_tools_rom.h"
+
+/* MAX_PARAMETER_BANDS defines array length in huffdec */
+
+#ifndef min
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+ERROR_t sym_restoreIPD(HANDLE_FDK_BITSTREAM strm, int lav, SCHAR data[2]) {
+ int sum_val = data[0] + data[1];
+ int diff_val = data[0] - data[1];
+
+ if (sum_val > lav) {
+ data[0] = -sum_val + (2 * lav + 1);
+ data[1] = -diff_val;
+ } else {
+ data[0] = sum_val;
+ data[1] = diff_val;
+ }
+
+ if (data[0] - data[1] != 0) {
+ ULONG sym_bit;
+ sym_bit = FDKreadBits(strm, 1);
+ if (sym_bit) {
+ int tmp;
+ tmp = data[0];
+ data[0] = data[1];
+ data[1] = tmp;
+ }
+ }
+
+ return HUFFDEC_OK;
+}
+
+static int ilog2(unsigned int i) {
+ int l = 0;
+
+ if (i) i--;
+ while (i > 0) {
+ i >>= 1;
+ l++;
+ }
+
+ return l;
+}
+
+static ERROR_t pcm_decode(HANDLE_FDK_BITSTREAM strm, SCHAR* out_data_1,
+ SCHAR* out_data_2, int offset, int num_val,
+ int num_levels) {
+ int i = 0, j = 0, idx = 0;
+ int max_grp_len = 0, next_val = 0;
+ ULONG tmp;
+
+ int pcm_chunk_size[7] = {0};
+
+ switch (num_levels) {
+ case 3:
+ max_grp_len = 5;
+ break;
+ case 7:
+ max_grp_len = 6;
+ break;
+ case 11:
+ max_grp_len = 2;
+ break;
+ case 13:
+ max_grp_len = 4;
+ break;
+ case 19:
+ max_grp_len = 4;
+ break;
+ case 25:
+ max_grp_len = 3;
+ break;
+ case 51:
+ max_grp_len = 4;
+ break;
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ case 26:
+ case 31:
+ max_grp_len = 1;
+ break;
+ default:
+ return HUFFDEC_NOTOK;
+ }
+
+ tmp = 1;
+ for (i = 1; i <= max_grp_len; i++) {
+ tmp *= num_levels;
+ pcm_chunk_size[i] = ilog2(tmp);
+ }
+
+ for (i = 0; i < num_val; i += max_grp_len) {
+ int grp_len, grp_val, data;
+ grp_len = min(max_grp_len, num_val - i);
+ data = FDKreadBits(strm, pcm_chunk_size[grp_len]);
+
+ grp_val = data;
+
+ for (j = 0; j < grp_len; j++) {
+ idx = i + (grp_len - j - 1);
+ next_val = grp_val % num_levels;
+
+ if (out_data_2 == NULL) {
+ out_data_1[idx] = next_val - offset;
+ } else if (out_data_1 == NULL) {
+ out_data_2[idx] = next_val - offset;
+ } else {
+ if (idx % 2) {
+ out_data_2[idx / 2] = next_val - offset;
+ } else {
+ out_data_1[idx / 2] = next_val - offset;
+ }
+ }
+
+ grp_val = (grp_val - next_val) / num_levels;
+ }
+ }
+
+ return HUFFDEC_OK;
+}
+
+static ERROR_t huff_read(HANDLE_FDK_BITSTREAM strm,
+ const SHORT (*nodeTab)[MAX_ENTRIES][2],
+ int* out_data) {
+ int node = 0;
+ int len = 0;
+
+ do {
+ ULONG next_bit;
+ next_bit = FDKreadBits(strm, 1);
+ len++;
+ node = (*nodeTab)[node][next_bit];
+ } while (node > 0);
+
+ *out_data = node;
+
+ return HUFFDEC_OK;
+}
+
+static ERROR_t huff_read_2D(HANDLE_FDK_BITSTREAM strm,
+ const SHORT (*nodeTab)[MAX_ENTRIES][2],
+ SCHAR out_data[2], int* escape) {
+ ERROR_t err = HUFFDEC_OK;
+
+ int huff_2D_8bit = 0;
+ int node = 0;
+
+ if ((err = huff_read(strm, nodeTab, &node)) != HUFFDEC_OK) {
+ goto bail;
+ }
+ *escape = (node == 0);
+
+ if (*escape) {
+ out_data[0] = 0;
+ out_data[1] = 1;
+ } else {
+ huff_2D_8bit = -(node + 1);
+ out_data[0] = huff_2D_8bit >> 4;
+ out_data[1] = huff_2D_8bit & 0xf;
+ }
+
+bail:
+ return err;
+}
+
+static ERROR_t sym_restore(HANDLE_FDK_BITSTREAM strm, int lav, SCHAR data[2]) {
+ ULONG sym_bit = 0;
+
+ int sum_val = data[0] + data[1];
+ int diff_val = data[0] - data[1];
+
+ if (sum_val > lav) {
+ data[0] = -sum_val + (2 * lav + 1);
+ data[1] = -diff_val;
+ } else {
+ data[0] = sum_val;
+ data[1] = diff_val;
+ }
+
+ if (data[0] + data[1] != 0) {
+ sym_bit = FDKreadBits(strm, 1);
+ if (sym_bit) {
+ data[0] = -data[0];
+ data[1] = -data[1];
+ }
+ }
+
+ if (data[0] - data[1] != 0) {
+ sym_bit = FDKreadBits(strm, 1);
+ if (sym_bit) {
+ int tmp;
+ tmp = data[0];
+ data[0] = data[1];
+ data[1] = tmp;
+ }
+ }
+
+ return HUFFDEC_OK;
+}
+
+static ERROR_t huff_dec_1D(HANDLE_FDK_BITSTREAM strm, const DATA_TYPE data_type,
+ const INT dim1, SCHAR* out_data, const INT num_val,
+ const INT p0_flag)
+
+{
+ ERROR_t err = HUFFDEC_OK;
+ int i = 0, node = 0, offset = 0;
+ int od = 0, od_sign = 0;
+ ULONG data = 0;
+ int bitsAvail = 0;
+
+ const SHORT(*partTab)[MAX_ENTRIES][2] = NULL;
+ const SHORT(*nodeTab)[MAX_ENTRIES][2] = NULL;
+
+ switch (data_type) {
+ case t_CLD:
+ partTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.cld[0][0];
+ nodeTab = (HANDLE_HUFF_NODE)&FDK_huffCLDNodes.h1D[dim1]->nodeTab[0][0];
+ break;
+ case t_ICC:
+ partTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.icc[0][0];
+ nodeTab = (HANDLE_HUFF_NODE)&FDK_huffICCNodes.h1D[dim1]->nodeTab[0][0];
+ break;
+ case t_OLD:
+ partTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.old[0][0];
+ nodeTab = (HANDLE_HUFF_NODE)&huffOLDNodes.h1D[dim1]->nodeTab[0][0];
+ break;
+ case t_IPD:
+ partTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.ipd[0][0];
+ nodeTab = (HANDLE_HUFF_NODE)&FDK_huffIPDNodes.h1D[dim1].nodeTab[0][0];
+ break;
+ default:
+ FDK_ASSERT(0);
+ err = HUFFDEC_NOTOK;
+ goto bail;
+ }
+
+ if (p0_flag) {
+ if ((err = huff_read(strm, partTab, &node)) != HUFFDEC_OK) {
+ goto bail;
+ }
+
+ out_data[0] = -(node + 1);
+ offset = 1;
+ }
+
+ for (i = offset; i < num_val; i++) {
+ bitsAvail = FDKgetValidBits(strm);
+ if (bitsAvail < 1) {
+ err = HUFFDEC_NOTOK;
+ goto bail;
+ }
+
+ if ((err = huff_read(strm, nodeTab, &node)) != HUFFDEC_OK) {
+ goto bail;
+ }
+ od = -(node + 1);
+
+ if (data_type != t_IPD) {
+ if (od != 0) {
+ bitsAvail = FDKgetValidBits(strm);
+ if (bitsAvail < 1) {
+ err = HUFFDEC_NOTOK;
+ goto bail;
+ }
+
+ data = FDKreadBits(strm, 1);
+ od_sign = data;
+
+ if (od_sign) od = -od;
+ }
+ }
+
+ out_data[i] = od;
+ }
+
+bail:
+ return err;
+}
+
+static ERROR_t huff_dec_2D(HANDLE_FDK_BITSTREAM strm, const DATA_TYPE data_type,
+ const INT dim1, const INT dim2, SCHAR out_data[][2],
+ const INT num_val, const INT stride,
+ SCHAR* p0_data[2]) {
+ ERROR_t err = HUFFDEC_OK;
+ int i = 0, lav = 0, escape = 0, escCntr = 0;
+ int node = 0;
+ unsigned long data = 0;
+
+ SCHAR esc_data[2][28] = {{0}};
+ int escIdx[28] = {0};
+ const SHORT(*nodeTab)[MAX_ENTRIES][2] = NULL;
+
+ /* LAV */
+ if ((err =
+ huff_read(strm, (HANDLE_HUFF_NODE)&FDK_huffLavIdxNodes.nodeTab[0][0],
+ &node)) != HUFFDEC_OK) {
+ goto bail;
+ }
+ data = -(node + 1);
+
+ switch (data_type) {
+ case t_CLD:
+ lav = 2 * data + 3; /* 3, 5, 7, 9 */
+ nodeTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.cld[0][0];
+ break;
+ case t_ICC:
+ lav = 2 * data + 1; /* 1, 3, 5, 7 */
+ nodeTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.icc[0][0];
+ break;
+ case t_OLD:
+ lav = 3 * data + 3;
+ nodeTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.old[0][0];
+ break;
+ case t_IPD:
+ if (data == 0)
+ data = 3;
+ else
+ data--;
+ lav = 2 * data + 1; /* 1, 3, 5, 7 */
+ nodeTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.ipd[0][0];
+ break;
+ default:
+ FDK_ASSERT(0);
+ err = HUFFDEC_NOTOK;
+ goto bail;
+ }
+
+ /* Partition 0 */
+ if (p0_data[0] != NULL) {
+ if ((err = huff_read(strm, nodeTab, &node)) != HUFFDEC_OK) {
+ goto bail;
+ }
+ *p0_data[0] = -(node + 1);
+ }
+ if (p0_data[1] != NULL) {
+ if ((err = huff_read(strm, nodeTab, &node)) != HUFFDEC_OK) {
+ goto bail;
+ }
+ *p0_data[1] = -(node + 1);
+ }
+
+ switch (data_type) {
+ case t_CLD:
+ switch (lav) {
+ case 3:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffCLDNodes.h2D[dim1][dim2]->lav3[0][0];
+ break;
+ case 5:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffCLDNodes.h2D[dim1][dim2]->lav5[0][0];
+ break;
+ case 7:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffCLDNodes.h2D[dim1][dim2]->lav7[0][0];
+ break;
+ case 9:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffCLDNodes.h2D[dim1][dim2]->lav9[0][0];
+ break;
+ }
+ break;
+ case t_ICC:
+ switch (lav) {
+ case 1:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffICCNodes.h2D[dim1][dim2]->lav1[0][0];
+ break;
+ case 3:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffICCNodes.h2D[dim1][dim2]->lav3[0][0];
+ break;
+ case 5:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffICCNodes.h2D[dim1][dim2]->lav5[0][0];
+ break;
+ case 7:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffICCNodes.h2D[dim1][dim2]->lav7[0][0];
+ break;
+ }
+ break;
+ case t_OLD:
+ switch (lav) {
+ case 3:
+ nodeTab = (HANDLE_HUFF_NODE)&huffOLDNodes.h2D[dim1][dim2]->lav3[0][0];
+ break;
+ case 6:
+ nodeTab = (HANDLE_HUFF_NODE)&huffOLDNodes.h2D[dim1][dim2]->lav6[0][0];
+ break;
+ case 9:
+ nodeTab = (HANDLE_HUFF_NODE)&huffOLDNodes.h2D[dim1][dim2]->lav9[0][0];
+ break;
+ case 12:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&huffOLDNodes.h2D[dim1][dim2]->lav12[0][0];
+ break;
+ }
+ break;
+ case t_IPD:
+ switch (lav) {
+ case 1:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffIPDNodes.h2D[dim1][dim2].lav1[0][0];
+ break;
+ case 3:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffIPDNodes.h2D[dim1][dim2].lav3[0][0];
+ break;
+ case 5:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffIPDNodes.h2D[dim1][dim2].lav5[0][0];
+ break;
+ case 7:
+ nodeTab =
+ (HANDLE_HUFF_NODE)&FDK_huffIPDNodes.h2D[dim1][dim2].lav7[0][0];
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ for (i = 0; i < num_val; i += stride) {
+ if ((err = huff_read_2D(strm, nodeTab, out_data[i], &escape)) !=
+ HUFFDEC_OK) {
+ goto bail;
+ }
+
+ if (escape) {
+ escIdx[escCntr++] = i;
+ } else {
+ if (data_type == t_IPD) {
+ if ((err = sym_restoreIPD(strm, lav, out_data[i])) != HUFFDEC_OK) {
+ goto bail;
+ }
+ } else {
+ if ((err = sym_restore(strm, lav, out_data[i])) != HUFFDEC_OK) {
+ goto bail;
+ }
+ }
+ }
+ } /* i */
+
+ if (escCntr > 0) {
+ if ((err = pcm_decode(strm, esc_data[0], esc_data[1], 0, 2 * escCntr,
+ (2 * lav + 1))) != HUFFDEC_OK) {
+ goto bail;
+ }
+
+ for (i = 0; i < escCntr; i++) {
+ out_data[escIdx[i]][0] = esc_data[0][i] - lav;
+ out_data[escIdx[i]][1] = esc_data[1][i] - lav;
+ }
+ }
+bail:
+ return err;
+}
+
+static ERROR_t huff_decode(HANDLE_FDK_BITSTREAM strm, SCHAR* out_data_1,
+ SCHAR* out_data_2, DATA_TYPE data_type,
+ DIFF_TYPE diff_type_1, DIFF_TYPE diff_type_2,
+ int num_val, CODING_SCHEME* cdg_scheme, int ldMode) {
+ ERROR_t err = HUFFDEC_OK;
+ DIFF_TYPE diff_type;
+
+ int i = 0;
+ ULONG data = 0;
+
+ SCHAR pair_vec[28][2];
+
+ SCHAR* p0_data_1[2] = {NULL, NULL};
+ SCHAR* p0_data_2[2] = {NULL, NULL};
+
+ int p0_flag[2];
+
+ int num_val_1_int = num_val;
+ int num_val_2_int = num_val;
+
+ SCHAR* out_data_1_int = out_data_1;
+ SCHAR* out_data_2_int = out_data_2;
+
+ int df_rest_flag_1 = 0;
+ int df_rest_flag_2 = 0;
+
+ int hufYY1;
+ int hufYY2;
+ int hufYY;
+
+ /* Coding scheme */
+ data = FDKreadBits(strm, 1);
+ *cdg_scheme = (CODING_SCHEME)(data << PAIR_SHIFT);
+
+ if (*cdg_scheme >> PAIR_SHIFT == HUFF_2D) {
+ if ((out_data_1 != NULL) && (out_data_2 != NULL) && (ldMode == 0)) {
+ data = FDKreadBits(strm, 1);
+ *cdg_scheme = (CODING_SCHEME)(*cdg_scheme | data);
+ } else {
+ *cdg_scheme = (CODING_SCHEME)(*cdg_scheme | FREQ_PAIR);
+ }
+ }
+
+ {
+ hufYY1 = diff_type_1;
+ hufYY2 = diff_type_2;
+ }
+
+ switch (*cdg_scheme >> PAIR_SHIFT) {
+ case HUFF_1D:
+ p0_flag[0] = (diff_type_1 == DIFF_FREQ);
+ p0_flag[1] = (diff_type_2 == DIFF_FREQ);
+ if (out_data_1 != NULL) {
+ if ((err = huff_dec_1D(strm, data_type, hufYY1, out_data_1,
+ num_val_1_int, p0_flag[0])) != HUFFDEC_OK) {
+ goto bail;
+ }
+ }
+ if (out_data_2 != NULL) {
+ if ((err = huff_dec_1D(strm, data_type, hufYY2, out_data_2,
+ num_val_2_int, p0_flag[1])) != HUFFDEC_OK) {
+ goto bail;
+ }
+ }
+
+ break; /* HUFF_1D */
+
+ case HUFF_2D:
+
+ switch (*cdg_scheme & PAIR_MASK) {
+ case FREQ_PAIR:
+
+ if (out_data_1 != NULL) {
+ if (diff_type_1 == DIFF_FREQ) {
+ p0_data_1[0] = &out_data_1[0];
+ p0_data_1[1] = NULL;
+
+ num_val_1_int -= 1;
+ out_data_1_int += 1;
+ }
+ df_rest_flag_1 = num_val_1_int % 2;
+ if (df_rest_flag_1) num_val_1_int -= 1;
+ if (num_val_1_int < 0) {
+ err = HUFFDEC_NOTOK;
+ goto bail;
+ }
+ }
+ if (out_data_2 != NULL) {
+ if (diff_type_2 == DIFF_FREQ) {
+ p0_data_2[0] = NULL;
+ p0_data_2[1] = &out_data_2[0];
+
+ num_val_2_int -= 1;
+ out_data_2_int += 1;
+ }
+ df_rest_flag_2 = num_val_2_int % 2;
+ if (df_rest_flag_2) num_val_2_int -= 1;
+ if (num_val_2_int < 0) {
+ err = HUFFDEC_NOTOK;
+ goto bail;
+ }
+ }
+
+ if (out_data_1 != NULL) {
+ if ((err = huff_dec_2D(strm, data_type, hufYY1, FREQ_PAIR, pair_vec,
+ num_val_1_int, 2, p0_data_1)) !=
+ HUFFDEC_OK) {
+ goto bail;
+ }
+ if (df_rest_flag_1) {
+ if ((err = huff_dec_1D(strm, data_type, hufYY1,
+ out_data_1_int + num_val_1_int, 1, 0)) !=
+ HUFFDEC_OK) {
+ goto bail;
+ }
+ }
+ }
+ if (out_data_2 != NULL) {
+ if ((err = huff_dec_2D(strm, data_type, hufYY2, FREQ_PAIR,
+ pair_vec + 1, num_val_2_int, 2,
+ p0_data_2)) != HUFFDEC_OK) {
+ goto bail;
+ }
+ if (df_rest_flag_2) {
+ if ((err = huff_dec_1D(strm, data_type, hufYY2,
+ out_data_2_int + num_val_2_int, 1, 0)) !=
+ HUFFDEC_OK) {
+ goto bail;
+ }
+ }
+ }
+
+ if (out_data_1 != NULL) {
+ for (i = 0; i < num_val_1_int - 1; i += 2) {
+ out_data_1_int[i] = pair_vec[i][0];
+ out_data_1_int[i + 1] = pair_vec[i][1];
+ }
+ }
+ if (out_data_2 != NULL) {
+ for (i = 0; i < num_val_2_int - 1; i += 2) {
+ out_data_2_int[i] = pair_vec[i + 1][0];
+ out_data_2_int[i + 1] = pair_vec[i + 1][1];
+ }
+ }
+ break; /* FREQ_PAIR */
+
+ case TIME_PAIR:
+ if (((diff_type_1 == DIFF_FREQ) || (diff_type_2 == DIFF_FREQ))) {
+ p0_data_1[0] = &out_data_1[0];
+ p0_data_1[1] = &out_data_2[0];
+
+ out_data_1_int += 1;
+ out_data_2_int += 1;
+
+ num_val_1_int -= 1;
+ }
+
+ if ((diff_type_1 == DIFF_TIME) || (diff_type_2 == DIFF_TIME)) {
+ diff_type = DIFF_TIME;
+ } else {
+ diff_type = DIFF_FREQ;
+ }
+ { hufYY = diff_type; }
+
+ if ((err = huff_dec_2D(strm, data_type, hufYY, TIME_PAIR, pair_vec,
+ num_val_1_int, 1, p0_data_1)) != HUFFDEC_OK) {
+ goto bail;
+ }
+
+ for (i = 0; i < num_val_1_int; i++) {
+ out_data_1_int[i] = pair_vec[i][0];
+ out_data_2_int[i] = pair_vec[i][1];
+ }
+
+ break; /* TIME_PAIR */
+
+ default:
+ break;
+ }
+
+ break; /* HUFF_2D */
+
+ default:
+ break;
+ }
+bail:
+ return err;
+}
+
+static void diff_freq_decode(const SCHAR* const diff_data,
+ SCHAR* const out_data, const int num_val) {
+ int i = 0;
+ out_data[0] = diff_data[0];
+
+ for (i = 1; i < num_val; i++) {
+ out_data[i] = out_data[i - 1] + diff_data[i];
+ }
+}
+
+static void diff_time_decode_backwards(const SCHAR* const prev_data,
+ const SCHAR* const diff_data,
+ SCHAR* const out_data,
+ const int mixed_diff_type,
+ const int num_val) {
+ int i = 0; /* default start value*/
+
+ if (mixed_diff_type) {
+ out_data[0] = diff_data[0];
+ i = 1; /* new start value */
+ }
+ for (; i < num_val; i++) {
+ out_data[i] = prev_data[i] + diff_data[i];
+ }
+}
+
+static void diff_time_decode_forwards(const SCHAR* const prev_data,
+ const SCHAR* const diff_data,
+ SCHAR* const out_data,
+ const int mixed_diff_type,
+ const int num_val) {
+ int i = 0; /* default start value*/
+
+ if (mixed_diff_type) {
+ out_data[0] = diff_data[0];
+ i = 1; /* new start value */
+ }
+ for (; i < num_val; i++) {
+ out_data[i] = prev_data[i] - diff_data[i];
+ }
+}
+
+static ERROR_t attach_lsb(HANDLE_FDK_BITSTREAM strm, SCHAR* in_data_msb,
+ int offset, int num_lsb, int num_val,
+ SCHAR* out_data) {
+ int i = 0, lsb = 0;
+ ULONG data = 0;
+
+ for (i = 0; i < num_val; i++) {
+ int msb;
+ msb = in_data_msb[i];
+
+ if (num_lsb > 0) {
+ data = FDKreadBits(strm, num_lsb);
+ lsb = data;
+
+ out_data[i] = ((msb << num_lsb) | lsb) - offset;
+ } else
+ out_data[i] = msb - offset;
+ }
+
+ return HUFFDEC_OK; /* dummy */
+}
+
+ERROR_t EcDataPairDec(DECODER_TYPE DECODER, HANDLE_FDK_BITSTREAM strm,
+ SCHAR* aaOutData1, SCHAR* aaOutData2, SCHAR* aHistory,
+ DATA_TYPE data_type, int startBand, int dataBands,
+ int pair_flag, int coarse_flag,
+ int allowDiffTimeBack_flag)
+
+{
+ ERROR_t err = HUFFDEC_OK;
+
+ // int allowDiffTimeBack_flag = !independency_flag || (setIdx > 0);
+ int attachLsb_flag = 0;
+ int pcmCoding_flag = 0;
+
+ int mixed_time_pair = 0, numValPcm = 0;
+ int quant_levels = 0, quant_offset = 0;
+ ULONG data = 0;
+
+ SCHAR aaDataPair[2][28] = {{0}};
+ SCHAR aaDataDiff[2][28] = {{0}};
+
+ SCHAR aHistoryMsb[28] = {0};
+
+ SCHAR* pDataVec[2] = {NULL, NULL};
+
+ DIFF_TYPE diff_type[2] = {DIFF_FREQ, DIFF_FREQ};
+ CODING_SCHEME cdg_scheme = HUFF_1D;
+ DIRECTION direction = BACKWARDS;
+
+ switch (data_type) {
+ case t_CLD:
+ if (coarse_flag) {
+ attachLsb_flag = 0;
+ quant_levels = 15;
+ quant_offset = 7;
+ } else {
+ attachLsb_flag = 0;
+ quant_levels = 31;
+ quant_offset = 15;
+ }
+
+ break;
+
+ case t_ICC:
+ if (coarse_flag) {
+ attachLsb_flag = 0;
+ quant_levels = 4;
+ quant_offset = 0;
+ } else {
+ attachLsb_flag = 0;
+ quant_levels = 8;
+ quant_offset = 0;
+ }
+
+ break;
+
+ case t_OLD:
+ if (coarse_flag) {
+ attachLsb_flag = 0;
+ quant_levels = 8;
+ quant_offset = 0;
+ } else {
+ attachLsb_flag = 0;
+ quant_levels = 16;
+ quant_offset = 0;
+ }
+ break;
+
+ case t_NRG:
+ if (coarse_flag) {
+ attachLsb_flag = 0;
+ quant_levels = 32;
+ quant_offset = 0;
+ } else {
+ attachLsb_flag = 0;
+ quant_levels = 64;
+ quant_offset = 0;
+ }
+ break;
+
+ case t_IPD:
+ if (!coarse_flag) {
+ attachLsb_flag = 1;
+ quant_levels = 16;
+ quant_offset = 0;
+ } else {
+ attachLsb_flag = 0;
+ quant_levels = 8;
+ quant_offset = 0;
+ }
+ break;
+
+ default:
+ return HUFFDEC_NOTOK;
+ }
+
+ data = FDKreadBits(strm, 1);
+ pcmCoding_flag = data;
+
+ if (pcmCoding_flag) {
+ if (pair_flag) {
+ pDataVec[0] = aaDataPair[0];
+ pDataVec[1] = aaDataPair[1];
+ numValPcm = 2 * dataBands;
+ } else {
+ pDataVec[0] = aaDataPair[0];
+ pDataVec[1] = NULL;
+ numValPcm = dataBands;
+ }
+
+ err = pcm_decode(strm, pDataVec[0], pDataVec[1], quant_offset, numValPcm,
+ quant_levels);
+ if (err != HUFFDEC_OK) return HUFFDEC_NOTOK;
+
+ } else { /* Differential/Huffman/LSB Coding */
+
+ if (pair_flag) {
+ pDataVec[0] = aaDataDiff[0];
+ pDataVec[1] = aaDataDiff[1];
+ } else {
+ pDataVec[0] = aaDataDiff[0];
+ pDataVec[1] = NULL;
+ }
+
+ diff_type[0] = DIFF_FREQ;
+ diff_type[1] = DIFF_FREQ;
+
+ direction = BACKWARDS;
+ {
+ if (pair_flag || allowDiffTimeBack_flag) {
+ data = FDKreadBits(strm, 1);
+ diff_type[0] = (DIFF_TYPE)data;
+ }
+
+ if (pair_flag &&
+ ((diff_type[0] == DIFF_FREQ) || allowDiffTimeBack_flag)) {
+ data = FDKreadBits(strm, 1);
+ diff_type[1] = (DIFF_TYPE)data;
+ }
+ }
+ /* Huffman decoding */
+ err = huff_decode(strm, pDataVec[0], pDataVec[1], data_type, diff_type[0],
+ diff_type[1], dataBands, &cdg_scheme,
+ (DECODER == SAOC_DECODER));
+ if (err != HUFFDEC_OK) {
+ return HUFFDEC_NOTOK;
+ }
+
+ {
+ /* Differential decoding */
+ if ((diff_type[0] == DIFF_TIME) || (diff_type[1] == DIFF_TIME)) {
+ if (DECODER == SAOC_DECODER) {
+ direction = BACKWARDS;
+ } else {
+ if (pair_flag) {
+ if ((diff_type[0] == DIFF_TIME) && !allowDiffTimeBack_flag) {
+ direction = FORWARDS;
+ } else if (diff_type[1] == DIFF_TIME) {
+ direction = BACKWARDS;
+ } else {
+ data = FDKreadBits(strm, 1);
+ direction = (DIRECTION)data;
+ }
+ } else {
+ direction = BACKWARDS;
+ }
+ }
+ }
+
+ mixed_time_pair = (diff_type[0] != diff_type[1]) &&
+ ((cdg_scheme & PAIR_MASK) == TIME_PAIR);
+
+ if (direction == BACKWARDS) {
+ if (diff_type[0] == DIFF_FREQ) {
+ diff_freq_decode(aaDataDiff[0], aaDataPair[0], dataBands);
+ } else {
+ int i;
+ for (i = 0; i < dataBands; i++) {
+ aHistoryMsb[i] = aHistory[i + startBand] + quant_offset;
+ if (attachLsb_flag) {
+ aHistoryMsb[i] >>= 1;
+ }
+ }
+ diff_time_decode_backwards(aHistoryMsb, aaDataDiff[0], aaDataPair[0],
+ mixed_time_pair, dataBands);
+ }
+ if (diff_type[1] == DIFF_FREQ) {
+ diff_freq_decode(aaDataDiff[1], aaDataPair[1], dataBands);
+ } else {
+ diff_time_decode_backwards(aaDataPair[0], aaDataDiff[1],
+ aaDataPair[1], mixed_time_pair, dataBands);
+ }
+ } else {
+ /* diff_type[1] MUST BE DIFF_FREQ */
+ diff_freq_decode(aaDataDiff[1], aaDataPair[1], dataBands);
+
+ if (diff_type[0] == DIFF_FREQ) {
+ diff_freq_decode(aaDataDiff[0], aaDataPair[0], dataBands);
+ } else {
+ diff_time_decode_forwards(aaDataPair[1], aaDataDiff[0], aaDataPair[0],
+ mixed_time_pair, dataBands);
+ }
+ }
+ }
+
+ /* LSB decoding */
+ err = attach_lsb(strm, aaDataPair[0], quant_offset, attachLsb_flag ? 1 : 0,
+ dataBands, aaDataPair[0]);
+ if (err != HUFFDEC_OK) goto bail;
+
+ if (pair_flag) {
+ err = attach_lsb(strm, aaDataPair[1], quant_offset,
+ attachLsb_flag ? 1 : 0, dataBands, aaDataPair[1]);
+ if (err != HUFFDEC_OK) goto bail;
+ }
+ } /* End: Differential/Huffman/LSB Coding */
+
+ /* Copy data to output arrays */
+ FDKmemcpy(aaOutData1 + startBand, aaDataPair[0], sizeof(SCHAR) * dataBands);
+ if (pair_flag) {
+ FDKmemcpy(aaOutData2 + startBand, aaDataPair[1], sizeof(SCHAR) * dataBands);
+ }
+
+bail:
+ return err;
+}
+
+ERROR_t huff_dec_reshape(HANDLE_FDK_BITSTREAM strm, int* out_data,
+ int num_val) {
+ ERROR_t err = HUFFDEC_OK;
+ int val_rcvd = 0, dummy = 0, i = 0, val = 0, len = 0;
+ SCHAR rl_data[2] = {0};
+
+ while (val_rcvd < num_val) {
+ err = huff_read_2D(strm,
+ (HANDLE_HUFF_NODE)&FDK_huffReshapeNodes.nodeTab[0][0],
+ rl_data, &dummy);
+ if (err != HUFFDEC_OK) goto bail;
+ val = rl_data[0];
+ len = rl_data[1] + 1;
+ if (val_rcvd + len > num_val) {
+ err = HUFFDEC_NOTOK;
+ goto bail;
+ }
+ for (i = val_rcvd; i < val_rcvd + len; i++) {
+ out_data[i] = val;
+ }
+ val_rcvd += len;
+ }
+bail:
+ return err;
+}
diff --git a/fdk-aac/libFDK/src/qmf.cpp b/fdk-aac/libFDK/src/qmf.cpp
new file mode 100644
index 0000000..6fca043
--- /dev/null
+++ b/fdk-aac/libFDK/src/qmf.cpp
@@ -0,0 +1,1135 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s): Markus Lohwasser, Josef Hoepfl, Manuel Jander
+
+ Description: QMF filterbank
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Complex qmf analysis/synthesis
+ This module contains the qmf filterbank for analysis [
+ cplxAnalysisQmfFiltering() ] and synthesis [ cplxSynthesisQmfFiltering() ]. It
+ is a polyphase implementation of a complex exponential modulated filter bank.
+ The analysis part usually runs at half the sample rate than the synthesis
+ part. (So called "dual-rate" mode.)
+
+ The coefficients of the prototype filter are specified in #qmf_pfilt640 (in
+ sbr_rom.cpp). Thus only a 64 channel version (32 on the analysis side) with a
+ 640 tap prototype filter are used.
+
+ \anchor PolyphaseFiltering <h2>About polyphase filtering</h2>
+ The polyphase implementation of a filterbank requires filtering at the input
+ and output. This is implemented as part of cplxAnalysisQmfFiltering() and
+ cplxSynthesisQmfFiltering(). The implementation requires the filter
+ coefficients in a specific structure as described in #sbr_qmf_64_640_qmf (in
+ sbr_rom.cpp).
+
+ This module comprises the computationally most expensive functions of the SBR
+ decoder. The accuracy of computations is also important and has a direct
+ impact on the overall sound quality. Therefore a special test program is
+ available which can be used to only test the filterbank: main_audio.cpp
+
+ This modules also uses scaling of data to provide better SNR on fixed-point
+ processors. See #QMF_SCALE_FACTOR (in sbr_scale.h) for details. An interesting
+ note: The function getScalefactor() can constitute a significant amount of
+ computational complexity - very much depending on the bitrate. Since it is a
+ rather small function, effective assembler optimization might be possible.
+
+*/
+
+#include "qmf.h"
+
+#include "FDK_trigFcts.h"
+#include "fixpoint_math.h"
+#include "dct.h"
+
+#define QSSCALE (0)
+#define FX_DBL2FX_QSS(x) (x)
+#define FX_QSS2FX_DBL(x) (x)
+
+/* moved to qmf_pcm.h: -> qmfSynPrototypeFirSlot */
+/* moved to qmf_pcm.h: -> qmfSynPrototypeFirSlot_NonSymmetric */
+/* moved to qmf_pcm.h: -> qmfSynthesisFilteringSlot */
+
+#ifndef FUNCTION_qmfAnaPrototypeFirSlot
+/*!
+ \brief Perform Analysis Prototype Filtering on a single slot of input data.
+*/
+static void qmfAnaPrototypeFirSlot(
+ FIXP_DBL *analysisBuffer,
+ INT no_channels, /*!< Number channels of analysis filter */
+ const FIXP_PFT *p_filter, INT p_stride, /*!< Stride of analysis filter */
+ FIXP_QAS *RESTRICT pFilterStates) {
+ INT k;
+
+ FIXP_DBL accu;
+ const FIXP_PFT *RESTRICT p_flt = p_filter;
+ FIXP_DBL *RESTRICT pData_0 = analysisBuffer + 2 * no_channels - 1;
+ FIXP_DBL *RESTRICT pData_1 = analysisBuffer;
+
+ FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates;
+ FIXP_QAS *RESTRICT sta_1 =
+ (FIXP_QAS *)pFilterStates + (2 * QMF_NO_POLY * no_channels) - 1;
+ INT pfltStep = QMF_NO_POLY * (p_stride);
+ INT staStep1 = no_channels << 1;
+ INT staStep2 = (no_channels << 3) - 1; /* Rewind one less */
+
+ /* FIR filters 127..64 0..63 */
+ for (k = 0; k < no_channels; k++) {
+ accu = fMultDiv2(p_flt[0], *sta_1);
+ sta_1 -= staStep1;
+ accu += fMultDiv2(p_flt[1], *sta_1);
+ sta_1 -= staStep1;
+ accu += fMultDiv2(p_flt[2], *sta_1);
+ sta_1 -= staStep1;
+ accu += fMultDiv2(p_flt[3], *sta_1);
+ sta_1 -= staStep1;
+ accu += fMultDiv2(p_flt[4], *sta_1);
+ *pData_1++ = (accu << 1);
+ sta_1 += staStep2;
+
+ p_flt += pfltStep;
+ accu = fMultDiv2(p_flt[0], *sta_0);
+ sta_0 += staStep1;
+ accu += fMultDiv2(p_flt[1], *sta_0);
+ sta_0 += staStep1;
+ accu += fMultDiv2(p_flt[2], *sta_0);
+ sta_0 += staStep1;
+ accu += fMultDiv2(p_flt[3], *sta_0);
+ sta_0 += staStep1;
+ accu += fMultDiv2(p_flt[4], *sta_0);
+ *pData_0-- = (accu << 1);
+ sta_0 -= staStep2;
+ }
+}
+#endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */
+
+#ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric
+/*!
+ \brief Perform Analysis Prototype Filtering on a single slot of input data.
+*/
+static void qmfAnaPrototypeFirSlot_NonSymmetric(
+ FIXP_DBL *analysisBuffer,
+ int no_channels, /*!< Number channels of analysis filter */
+ const FIXP_PFT *p_filter, int p_stride, /*!< Stride of analysis filter */
+ FIXP_QAS *RESTRICT pFilterStates) {
+ const FIXP_PFT *RESTRICT p_flt = p_filter;
+ int p, k;
+
+ for (k = 0; k < 2 * no_channels; k++) {
+ FIXP_DBL accu = (FIXP_DBL)0;
+
+ p_flt += QMF_NO_POLY * (p_stride - 1);
+
+ /*
+ Perform FIR-Filter
+ */
+ for (p = 0; p < QMF_NO_POLY; p++) {
+ accu += fMultDiv2(*p_flt++, pFilterStates[2 * no_channels * p]);
+ }
+ analysisBuffer[2 * no_channels - 1 - k] = (accu << 1);
+ pFilterStates++;
+ }
+}
+#endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */
+
+/*!
+ *
+ * \brief Perform real-valued forward modulation of the time domain
+ * data of timeIn and stores the real part of the subband
+ * samples in rSubband
+ *
+ */
+static void qmfForwardModulationLP_even(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
+ FIXP_DBL *timeIn, /*!< Time Signal */
+ FIXP_DBL *rSubband) /*!< Real Output */
+{
+ int i;
+ int L = anaQmf->no_channels;
+ int M = L >> 1;
+ int scale;
+ FIXP_DBL accu;
+
+ const FIXP_DBL *timeInTmp1 = (FIXP_DBL *)&timeIn[3 * M];
+ const FIXP_DBL *timeInTmp2 = timeInTmp1;
+ FIXP_DBL *rSubbandTmp = rSubband;
+
+ rSubband[0] = timeIn[3 * M] >> 1;
+
+ for (i = M - 1; i != 0; i--) {
+ accu = ((*--timeInTmp1) >> 1) + ((*++timeInTmp2) >> 1);
+ *++rSubbandTmp = accu;
+ }
+
+ timeInTmp1 = &timeIn[2 * M];
+ timeInTmp2 = &timeIn[0];
+ rSubbandTmp = &rSubband[M];
+
+ for (i = L - M; i != 0; i--) {
+ accu = ((*timeInTmp1--) >> 1) - ((*timeInTmp2++) >> 1);
+ *rSubbandTmp++ = accu;
+ }
+
+ dct_III(rSubband, timeIn, L, &scale);
+}
+
+#if !defined(FUNCTION_qmfForwardModulationLP_odd)
+static void qmfForwardModulationLP_odd(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
+ const FIXP_DBL *timeIn, /*!< Time Signal */
+ FIXP_DBL *rSubband) /*!< Real Output */
+{
+ int i;
+ int L = anaQmf->no_channels;
+ int M = L >> 1;
+ int shift = (anaQmf->no_channels >> 6) + 1;
+
+ for (i = 0; i < M; i++) {
+ rSubband[M + i] = (timeIn[L - 1 - i] >> 1) - (timeIn[i] >> shift);
+ rSubband[M - 1 - i] =
+ (timeIn[L + i] >> 1) + (timeIn[2 * L - 1 - i] >> shift);
+ }
+
+ dct_IV(rSubband, L, &shift);
+}
+#endif /* !defined(FUNCTION_qmfForwardModulationLP_odd) */
+
+/*!
+ *
+ * \brief Perform complex-valued forward modulation of the time domain
+ * data of timeIn and stores the real part of the subband
+ * samples in rSubband, and the imaginary part in iSubband
+ *
+ *
+ */
+#if !defined(FUNCTION_qmfForwardModulationHQ)
+static void qmfForwardModulationHQ(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
+ const FIXP_DBL *RESTRICT timeIn, /*!< Time Signal */
+ FIXP_DBL *RESTRICT rSubband, /*!< Real Output */
+ FIXP_DBL *RESTRICT iSubband /*!< Imaginary Output */
+) {
+ int i;
+ int L = anaQmf->no_channels;
+ int L2 = L << 1;
+ int shift = 0;
+
+ /* Time advance by one sample, which is equivalent to the complex
+ rotation at the end of the analysis. Works only for STD mode. */
+ if ((L == 64) && !(anaQmf->flags & (QMF_FLAG_CLDFB | QMF_FLAG_MPSLDFB))) {
+ FIXP_DBL x, y;
+
+ /*rSubband[0] = u[1] + u[0]*/
+ /*iSubband[0] = u[1] - u[0]*/
+ x = timeIn[1] >> 1;
+ y = timeIn[0];
+ rSubband[0] = x + (y >> 1);
+ iSubband[0] = x - (y >> 1);
+
+ /*rSubband[n] = u[n+1] - u[2M-n], n=1,...,M-1*/
+ /*iSubband[n] = u[n+1] + u[2M-n], n=1,...,M-1*/
+ for (i = 1; i < L; i++) {
+ x = timeIn[i + 1] >> 1; /*u[n+1] */
+ y = timeIn[L2 - i]; /*u[2M-n] */
+ rSubband[i] = x - (y >> 1);
+ iSubband[i] = x + (y >> 1);
+ }
+ } else {
+ for (i = 0; i < L; i += 2) {
+ FIXP_DBL x0, x1, y0, y1;
+
+ x0 = timeIn[i + 0] >> 1;
+ x1 = timeIn[i + 1] >> 1;
+ y0 = timeIn[L2 - 1 - i];
+ y1 = timeIn[L2 - 2 - i];
+
+ rSubband[i + 0] = x0 - (y0 >> 1);
+ rSubband[i + 1] = x1 - (y1 >> 1);
+ iSubband[i + 0] = x0 + (y0 >> 1);
+ iSubband[i + 1] = x1 + (y1 >> 1);
+ }
+ }
+
+ dct_IV(rSubband, L, &shift);
+ dst_IV(iSubband, L, &shift);
+
+ /* Do the complex rotation except for the case of 64 bands (in STD mode). */
+ if ((L != 64) || (anaQmf->flags & (QMF_FLAG_CLDFB | QMF_FLAG_MPSLDFB))) {
+ if (anaQmf->flags & QMF_FLAG_MPSLDFB_OPTIMIZE_MODULATION) {
+ FIXP_DBL iBand;
+ for (i = 0; i < fMin(anaQmf->lsb, L); i += 2) {
+ iBand = rSubband[i];
+ rSubband[i] = -iSubband[i];
+ iSubband[i] = iBand;
+
+ iBand = -rSubband[i + 1];
+ rSubband[i + 1] = iSubband[i + 1];
+ iSubband[i + 1] = iBand;
+ }
+ } else {
+ const FIXP_QTW *sbr_t_cos;
+ const FIXP_QTW *sbr_t_sin;
+ const int len = L; /* was len = fMin(anaQmf->lsb, L) but in case of USAC
+ the signal above lsb is actually needed in some
+ cases (HBE?) */
+ sbr_t_cos = anaQmf->t_cos;
+ sbr_t_sin = anaQmf->t_sin;
+
+ for (i = 0; i < len; i++) {
+ cplxMult(&iSubband[i], &rSubband[i], iSubband[i], rSubband[i],
+ sbr_t_cos[i], sbr_t_sin[i]);
+ }
+ }
+ }
+}
+#endif /* FUNCTION_qmfForwardModulationHQ */
+
+/*
+ * \brief Perform one QMF slot analysis of the time domain data of timeIn
+ * with specified stride and stores the real part of the subband
+ * samples in rSubband, and the imaginary part in iSubband
+ *
+ * Note: anaQmf->lsb can be greater than anaQmf->no_channels in case
+ * of implicit resampling (USAC with reduced 3/4 core frame length).
+ */
+#if (SAMPLE_BITS != DFRACT_BITS) && (QAS_BITS == DFRACT_BITS)
+void qmfAnalysisFilteringSlot(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
+ FIXP_DBL *qmfReal, /*!< Low and High band, real */
+ FIXP_DBL *qmfImag, /*!< Low and High band, imag */
+ const LONG *RESTRICT timeIn, /*!< Pointer to input */
+ const int stride, /*!< stride factor of input */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
+) {
+ int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1);
+ /*
+ Feed time signal into oldest anaQmf->no_channels states
+ */
+ {
+ FIXP_DBL *FilterStatesAnaTmp = ((FIXP_DBL *)anaQmf->FilterStates) + offset;
+
+ /* Feed and scale actual time in slot */
+ for (int i = anaQmf->no_channels >> 1; i != 0; i--) {
+ /* Place INT_PCM value left aligned in scaledTimeIn */
+
+ *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
+ timeIn += stride;
+ *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
+ timeIn += stride;
+ }
+ }
+
+ if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
+ qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels,
+ anaQmf->p_filter, anaQmf->p_stride,
+ (FIXP_QAS *)anaQmf->FilterStates);
+ } else {
+ qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter,
+ anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates);
+ }
+
+ if (anaQmf->flags & QMF_FLAG_LP) {
+ if (anaQmf->flags & QMF_FLAG_CLDFB)
+ qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal);
+ else
+ qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal);
+
+ } else {
+ qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag);
+ }
+ /*
+ Shift filter states
+
+ Should be realized with modulo adressing on a DSP instead of a true buffer
+ shift
+ */
+ FDKmemmove(anaQmf->FilterStates,
+ (FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels,
+ offset * sizeof(FIXP_QAS));
+}
+#endif
+
+void qmfAnalysisFilteringSlot(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */
+ FIXP_DBL *qmfReal, /*!< Low and High band, real */
+ FIXP_DBL *qmfImag, /*!< Low and High band, imag */
+ const INT_PCM *RESTRICT timeIn, /*!< Pointer to input */
+ const int stride, /*!< stride factor of input */
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
+) {
+ int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1);
+ /*
+ Feed time signal into oldest anaQmf->no_channels states
+ */
+ {
+ FIXP_QAS *FilterStatesAnaTmp = ((FIXP_QAS *)anaQmf->FilterStates) + offset;
+
+ /* Feed and scale actual time in slot */
+ for (int i = anaQmf->no_channels >> 1; i != 0; i--) {
+ /* Place INT_PCM value left aligned in scaledTimeIn */
+#if (QAS_BITS == SAMPLE_BITS)
+ *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
+ timeIn += stride;
+ *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn;
+ timeIn += stride;
+#elif (QAS_BITS > SAMPLE_BITS)
+ *FilterStatesAnaTmp++ = ((FIXP_QAS)*timeIn) << (QAS_BITS - SAMPLE_BITS);
+ timeIn += stride;
+ *FilterStatesAnaTmp++ = ((FIXP_QAS)*timeIn) << (QAS_BITS - SAMPLE_BITS);
+ timeIn += stride;
+#else
+ *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn) >> (SAMPLE_BITS - QAS_BITS));
+ timeIn += stride;
+ *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn) >> (SAMPLE_BITS - QAS_BITS));
+ timeIn += stride;
+#endif
+ }
+ }
+
+ if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) {
+ qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels,
+ anaQmf->p_filter, anaQmf->p_stride,
+ (FIXP_QAS *)anaQmf->FilterStates);
+ } else {
+ qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter,
+ anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates);
+ }
+
+ if (anaQmf->flags & QMF_FLAG_LP) {
+ if (anaQmf->flags & QMF_FLAG_CLDFB)
+ qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal);
+ else
+ qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal);
+
+ } else {
+ qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag);
+ }
+ /*
+ Shift filter states
+
+ Should be realized with modulo adressing on a DSP instead of a true buffer
+ shift
+ */
+ FDKmemmove(anaQmf->FilterStates,
+ (FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels,
+ offset * sizeof(FIXP_QAS));
+}
+
+/*!
+ *
+ * \brief Perform complex-valued subband filtering of the time domain
+ * data of timeIn and stores the real part of the subband
+ * samples in rAnalysis, and the imaginary part in iAnalysis
+ * The qmf coefficient table is symmetric. The symmetry is expoited by
+ * shrinking the coefficient table to half the size. The addressing mode
+ * takes care of the symmetries.
+ *
+ *
+ * \sa PolyphaseFiltering
+ */
+#if (SAMPLE_BITS != DFRACT_BITS) && (QAS_BITS == DFRACT_BITS)
+void qmfAnalysisFiltering(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
+ FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
+ FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
+ QMF_SCALE_FACTOR *scaleFactor, const LONG *timeIn, /*!< Time signal */
+ const int timeIn_e, const int stride,
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
+) {
+ int i;
+ int no_channels = anaQmf->no_channels;
+
+ scaleFactor->lb_scale =
+ -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e;
+ scaleFactor->lb_scale -= anaQmf->filterScale;
+
+ for (i = 0; i < anaQmf->no_col; i++) {
+ FIXP_DBL *qmfImagSlot = NULL;
+
+ if (!(anaQmf->flags & QMF_FLAG_LP)) {
+ qmfImagSlot = qmfImag[i];
+ }
+
+ qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride,
+ pWorkBuffer);
+
+ timeIn += no_channels * stride;
+
+ } /* no_col loop i */
+}
+#endif
+
+void qmfAnalysisFiltering(
+ HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
+ FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */
+ FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */
+ QMF_SCALE_FACTOR *scaleFactor, const INT_PCM *timeIn, /*!< Time signal */
+ const int timeIn_e, const int stride,
+ FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */
+) {
+ int i;
+ int no_channels = anaQmf->no_channels;
+
+ scaleFactor->lb_scale =
+ -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e;
+ scaleFactor->lb_scale -= anaQmf->filterScale;
+
+ for (i = 0; i < anaQmf->no_col; i++) {
+ FIXP_DBL *qmfImagSlot = NULL;
+
+ if (!(anaQmf->flags & QMF_FLAG_LP)) {
+ qmfImagSlot = qmfImag[i];
+ }
+
+ qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride,
+ pWorkBuffer);
+
+ timeIn += no_channels * stride;
+
+ } /* no_col loop i */
+}
+
+/*!
+ *
+ * \brief Perform low power inverse modulation of the subband
+ * samples stored in rSubband (real part) and iSubband (imaginary
+ * part) and stores the result in pWorkBuffer.
+ *
+ */
+inline static void qmfInverseModulationLP_even(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
+ const FIXP_DBL *qmfReal, /*!< Pointer to qmf real subband slot (input) */
+ const int scaleFactorLowBand, /*!< Scalefactor for Low band */
+ const int scaleFactorHighBand, /*!< Scalefactor for High band */
+ FIXP_DBL *pTimeOut /*!< Pointer to qmf subband slot (output)*/
+) {
+ int i;
+ int L = synQmf->no_channels;
+ int M = L >> 1;
+ int scale;
+ FIXP_DBL tmp;
+ FIXP_DBL *RESTRICT tReal = pTimeOut;
+ FIXP_DBL *RESTRICT tImag = pTimeOut + L;
+
+ /* Move input to output vector with offset */
+ scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
+ scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
+ synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
+ FDKmemclear(&tReal[0 + synQmf->usb], (L - synQmf->usb) * sizeof(FIXP_DBL));
+
+ /* Dct type-2 transform */
+ dct_II(tReal, tImag, L, &scale);
+
+ /* Expand output and replace inplace the output buffers */
+ tImag[0] = tReal[M];
+ tImag[M] = (FIXP_DBL)0;
+ tmp = tReal[0];
+ tReal[0] = tReal[M];
+ tReal[M] = tmp;
+
+ for (i = 1; i < M / 2; i++) {
+ /* Imag */
+ tmp = tReal[L - i];
+ tImag[M - i] = tmp;
+ tImag[i + M] = -tmp;
+
+ tmp = tReal[M + i];
+ tImag[i] = tmp;
+ tImag[L - i] = -tmp;
+
+ /* Real */
+ tReal[M + i] = tReal[i];
+ tReal[L - i] = tReal[M - i];
+ tmp = tReal[i];
+ tReal[i] = tReal[M - i];
+ tReal[M - i] = tmp;
+ }
+ /* Remaining odd terms */
+ tmp = tReal[M + M / 2];
+ tImag[M / 2] = tmp;
+ tImag[M / 2 + M] = -tmp;
+
+ tReal[M + M / 2] = tReal[M / 2];
+}
+
+inline static void qmfInverseModulationLP_odd(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
+ const FIXP_DBL *qmfReal, /*!< Pointer to qmf real subband slot (input) */
+ const int scaleFactorLowBand, /*!< Scalefactor for Low band */
+ const int scaleFactorHighBand, /*!< Scalefactor for High band */
+ FIXP_DBL *pTimeOut /*!< Pointer to qmf subband slot (output)*/
+) {
+ int i;
+ int L = synQmf->no_channels;
+ int M = L >> 1;
+ int shift = 0;
+
+ /* Move input to output vector with offset */
+ scaleValues(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
+ scaleValues(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
+ synQmf->usb - synQmf->lsb, scaleFactorHighBand);
+ FDKmemclear(pTimeOut + M + synQmf->usb, (L - synQmf->usb) * sizeof(FIXP_DBL));
+
+ dct_IV(pTimeOut + M, L, &shift);
+ for (i = 0; i < M; i++) {
+ pTimeOut[i] = pTimeOut[L - 1 - i];
+ pTimeOut[2 * L - 1 - i] = -pTimeOut[L + i];
+ }
+}
+
+#ifndef FUNCTION_qmfInverseModulationHQ
+/*!
+ *
+ * \brief Perform complex-valued inverse modulation of the subband
+ * samples stored in rSubband (real part) and iSubband (imaginary
+ * part) and stores the result in pWorkBuffer.
+ *
+ */
+inline static void qmfInverseModulationHQ(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
+ const FIXP_DBL *qmfReal, /*!< Pointer to qmf real subband slot */
+ const FIXP_DBL *qmfImag, /*!< Pointer to qmf imag subband slot */
+ const int scaleFactorLowBand, /*!< Scalefactor for Low band */
+ const int scaleFactorHighBand, /*!< Scalefactor for High band */
+ FIXP_DBL *pWorkBuffer /*!< WorkBuffer (output) */
+) {
+ int i;
+ int L = synQmf->no_channels;
+ int M = L >> 1;
+ int shift = 0;
+ FIXP_DBL *RESTRICT tReal = pWorkBuffer;
+ FIXP_DBL *RESTRICT tImag = pWorkBuffer + L;
+
+ if (synQmf->flags & QMF_FLAG_CLDFB) {
+ for (i = 0; i < synQmf->lsb; i++) {
+ cplxMult(&tImag[i], &tReal[i], scaleValue(qmfImag[i], scaleFactorLowBand),
+ scaleValue(qmfReal[i], scaleFactorLowBand), synQmf->t_cos[i],
+ synQmf->t_sin[i]);
+ }
+ for (; i < synQmf->usb; i++) {
+ cplxMult(&tImag[i], &tReal[i],
+ scaleValue(qmfImag[i], scaleFactorHighBand),
+ scaleValue(qmfReal[i], scaleFactorHighBand), synQmf->t_cos[i],
+ synQmf->t_sin[i]);
+ }
+ }
+
+ if ((synQmf->flags & QMF_FLAG_CLDFB) == 0) {
+ scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
+ scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
+ synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
+ scaleValues(&tImag[0], &qmfImag[0], synQmf->lsb, (int)scaleFactorLowBand);
+ scaleValues(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
+ synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
+ }
+
+ FDKmemclear(&tReal[synQmf->usb],
+ (synQmf->no_channels - synQmf->usb) * sizeof(FIXP_DBL));
+ FDKmemclear(&tImag[synQmf->usb],
+ (synQmf->no_channels - synQmf->usb) * sizeof(FIXP_DBL));
+
+ dct_IV(tReal, L, &shift);
+ dst_IV(tImag, L, &shift);
+
+ if (synQmf->flags & QMF_FLAG_CLDFB) {
+ for (i = 0; i < M; i++) {
+ FIXP_DBL r1, i1, r2, i2;
+ r1 = tReal[i];
+ i2 = tImag[L - 1 - i];
+ r2 = tReal[L - i - 1];
+ i1 = tImag[i];
+
+ tReal[i] = (r1 - i1) >> 1;
+ tImag[L - 1 - i] = -(r1 + i1) >> 1;
+ tReal[L - i - 1] = (r2 - i2) >> 1;
+ tImag[i] = -(r2 + i2) >> 1;
+ }
+ } else {
+ /* The array accesses are negative to compensate the missing minus sign in
+ * the low and hi band gain. */
+ /* 26 cycles on ARM926 */
+ for (i = 0; i < M; i++) {
+ FIXP_DBL r1, i1, r2, i2;
+ r1 = -tReal[i];
+ i2 = -tImag[L - 1 - i];
+ r2 = -tReal[L - i - 1];
+ i1 = -tImag[i];
+
+ tReal[i] = (r1 - i1) >> 1;
+ tImag[L - 1 - i] = -(r1 + i1) >> 1;
+ tReal[L - i - 1] = (r2 - i2) >> 1;
+ tImag[i] = -(r2 + i2) >> 1;
+ }
+ }
+}
+#endif /* #ifndef FUNCTION_qmfInverseModulationHQ */
+
+/*!
+ *
+ * \brief Create QMF filter bank instance
+ *
+ * \return 0 if successful
+ *
+ */
+static int qmfInitFilterBank(
+ HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Handle to return */
+ void *pFilterStates, /*!< Handle to filter states */
+ int noCols, /*!< Number of timeslots per frame */
+ int lsb, /*!< Lower end of QMF frequency range */
+ int usb, /*!< Upper end of QMF frequency range */
+ int no_channels, /*!< Number of channels (bands) */
+ UINT flags, /*!< flags */
+ int synflag) /*!< 1: synthesis; 0: analysis */
+{
+ FDKmemclear(h_Qmf, sizeof(QMF_FILTER_BANK));
+
+ if (flags & QMF_FLAG_MPSLDFB) {
+ flags |= QMF_FLAG_NONSYMMETRIC;
+ flags |= QMF_FLAG_MPSLDFB_OPTIMIZE_MODULATION;
+
+ h_Qmf->t_cos = NULL;
+ h_Qmf->t_sin = NULL;
+ h_Qmf->filterScale = QMF_MPSLDFB_PFT_SCALE;
+ h_Qmf->p_stride = 1;
+
+ switch (no_channels) {
+ case 64:
+ h_Qmf->p_filter = qmf_mpsldfb_640;
+ h_Qmf->FilterSize = 640;
+ break;
+ case 32:
+ h_Qmf->p_filter = qmf_mpsldfb_320;
+ h_Qmf->FilterSize = 320;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ if (!(flags & QMF_FLAG_MPSLDFB) && (flags & QMF_FLAG_CLDFB)) {
+ flags |= QMF_FLAG_NONSYMMETRIC;
+ h_Qmf->filterScale = QMF_CLDFB_PFT_SCALE;
+
+ h_Qmf->p_stride = 1;
+ switch (no_channels) {
+ case 64:
+ h_Qmf->t_cos = qmf_phaseshift_cos64_cldfb;
+ h_Qmf->t_sin = qmf_phaseshift_sin64_cldfb;
+ h_Qmf->p_filter = qmf_cldfb_640;
+ h_Qmf->FilterSize = 640;
+ break;
+ case 32:
+ h_Qmf->t_cos = (synflag) ? qmf_phaseshift_cos32_cldfb_syn
+ : qmf_phaseshift_cos32_cldfb_ana;
+ h_Qmf->t_sin = qmf_phaseshift_sin32_cldfb;
+ h_Qmf->p_filter = qmf_cldfb_320;
+ h_Qmf->FilterSize = 320;
+ break;
+ case 16:
+ h_Qmf->t_cos = (synflag) ? qmf_phaseshift_cos16_cldfb_syn
+ : qmf_phaseshift_cos16_cldfb_ana;
+ h_Qmf->t_sin = qmf_phaseshift_sin16_cldfb;
+ h_Qmf->p_filter = qmf_cldfb_160;
+ h_Qmf->FilterSize = 160;
+ break;
+ case 8:
+ h_Qmf->t_cos = (synflag) ? qmf_phaseshift_cos8_cldfb_syn
+ : qmf_phaseshift_cos8_cldfb_ana;
+ h_Qmf->t_sin = qmf_phaseshift_sin8_cldfb;
+ h_Qmf->p_filter = qmf_cldfb_80;
+ h_Qmf->FilterSize = 80;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ if (!(flags & QMF_FLAG_MPSLDFB) && ((flags & QMF_FLAG_CLDFB) == 0)) {
+ switch (no_channels) {
+ case 64:
+ h_Qmf->p_filter = qmf_pfilt640;
+ h_Qmf->t_cos = qmf_phaseshift_cos64;
+ h_Qmf->t_sin = qmf_phaseshift_sin64;
+ h_Qmf->p_stride = 1;
+ h_Qmf->FilterSize = 640;
+ h_Qmf->filterScale = 0;
+ break;
+ case 40:
+ if (synflag) {
+ break;
+ } else {
+ h_Qmf->p_filter = qmf_pfilt400; /* Scaling factor 0.8 */
+ h_Qmf->t_cos = qmf_phaseshift_cos40;
+ h_Qmf->t_sin = qmf_phaseshift_sin40;
+ h_Qmf->filterScale = 1;
+ h_Qmf->p_stride = 1;
+ h_Qmf->FilterSize = no_channels * 10;
+ }
+ break;
+ case 32:
+ h_Qmf->p_filter = qmf_pfilt640;
+ if (flags & QMF_FLAG_DOWNSAMPLED) {
+ h_Qmf->t_cos = qmf_phaseshift_cos_downsamp32;
+ h_Qmf->t_sin = qmf_phaseshift_sin_downsamp32;
+ } else {
+ h_Qmf->t_cos = qmf_phaseshift_cos32;
+ h_Qmf->t_sin = qmf_phaseshift_sin32;
+ }
+ h_Qmf->p_stride = 2;
+ h_Qmf->FilterSize = 640;
+ h_Qmf->filterScale = 0;
+ break;
+ case 20:
+ h_Qmf->p_filter = qmf_pfilt200;
+ h_Qmf->p_stride = 1;
+ h_Qmf->FilterSize = 200;
+ h_Qmf->filterScale = 0;
+ break;
+ case 12:
+ h_Qmf->p_filter = qmf_pfilt120;
+ h_Qmf->p_stride = 1;
+ h_Qmf->FilterSize = 120;
+ h_Qmf->filterScale = 0;
+ break;
+ case 8:
+ h_Qmf->p_filter = qmf_pfilt640;
+ h_Qmf->p_stride = 8;
+ h_Qmf->FilterSize = 640;
+ h_Qmf->filterScale = 0;
+ break;
+ case 16:
+ h_Qmf->p_filter = qmf_pfilt640;
+ h_Qmf->t_cos = qmf_phaseshift_cos16;
+ h_Qmf->t_sin = qmf_phaseshift_sin16;
+ h_Qmf->p_stride = 4;
+ h_Qmf->FilterSize = 640;
+ h_Qmf->filterScale = 0;
+ break;
+ case 24:
+ h_Qmf->p_filter = qmf_pfilt240;
+ h_Qmf->t_cos = qmf_phaseshift_cos24;
+ h_Qmf->t_sin = qmf_phaseshift_sin24;
+ h_Qmf->p_stride = 1;
+ h_Qmf->FilterSize = 240;
+ h_Qmf->filterScale = 1;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ h_Qmf->synScalefactor = h_Qmf->filterScale;
+ // DCT|DST dependency
+ switch (no_channels) {
+ case 128:
+ h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + 1;
+ break;
+ case 40: {
+ h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 1;
+ } break;
+ case 64:
+ h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK;
+ break;
+ case 8:
+ h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 3;
+ break;
+ case 12:
+ h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK;
+ break;
+ case 20:
+ h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + 1;
+ break;
+ case 32:
+ h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 1;
+ break;
+ case 16:
+ h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 2;
+ break;
+ case 24:
+ h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 1;
+ break;
+ default:
+ return -1;
+ }
+
+ h_Qmf->flags = flags;
+
+ h_Qmf->no_channels = no_channels;
+ h_Qmf->no_col = noCols;
+
+ h_Qmf->lsb = fMin(lsb, h_Qmf->no_channels);
+ h_Qmf->usb = synflag
+ ? fMin(usb, h_Qmf->no_channels)
+ : usb; /* was: h_Qmf->usb = fMin(usb, h_Qmf->no_channels); */
+
+ h_Qmf->FilterStates = (void *)pFilterStates;
+
+ h_Qmf->outScalefactor =
+ (ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + h_Qmf->filterScale) +
+ h_Qmf->synScalefactor;
+
+ h_Qmf->outGain_m =
+ (FIXP_DBL)0x80000000; /* default init value will be not applied */
+ h_Qmf->outGain_e = 0;
+
+ return (0);
+}
+
+/*!
+ *
+ * \brief Adjust synthesis qmf filter states
+ *
+ * \return void
+ *
+ */
+static inline void qmfAdaptFilterStates(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Filter Bank */
+ int scaleFactorDiff) /*!< Scale factor difference to be applied */
+{
+ if (synQmf == NULL || synQmf->FilterStates == NULL) {
+ return;
+ }
+ if (scaleFactorDiff > 0) {
+ scaleValuesSaturate((FIXP_QSS *)synQmf->FilterStates,
+ synQmf->no_channels * (QMF_NO_POLY * 2 - 1),
+ scaleFactorDiff);
+ } else {
+ scaleValues((FIXP_QSS *)synQmf->FilterStates,
+ synQmf->no_channels * (QMF_NO_POLY * 2 - 1), scaleFactorDiff);
+ }
+}
+
+/*!
+ *
+ * \brief Create QMF filter bank instance
+ *
+ *
+ * \return 0 if succesful
+ *
+ */
+int qmfInitAnalysisFilterBank(
+ HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */
+ FIXP_QAS *pFilterStates, /*!< Handle to filter states */
+ int noCols, /*!< Number of timeslots per frame */
+ int lsb, /*!< lower end of QMF */
+ int usb, /*!< upper end of QMF */
+ int no_channels, /*!< Number of channels (bands) */
+ int flags) /*!< Low Power flag */
+{
+ int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb,
+ no_channels, flags, 0);
+ if (!(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL)) {
+ FDKmemclear(h_Qmf->FilterStates,
+ (2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QAS));
+ }
+
+ FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb);
+
+ return err;
+}
+
+/*!
+ *
+ * \brief Create QMF filter bank instance
+ *
+ *
+ * \return 0 if succesful
+ *
+ */
+int qmfInitSynthesisFilterBank(
+ HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */
+ FIXP_QSS *pFilterStates, /*!< Handle to filter states */
+ int noCols, /*!< Number of timeslots per frame */
+ int lsb, /*!< lower end of QMF */
+ int usb, /*!< upper end of QMF */
+ int no_channels, /*!< Number of channels (bands) */
+ int flags) /*!< Low Power flag */
+{
+ int oldOutScale = h_Qmf->outScalefactor;
+ int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb,
+ no_channels, flags, 1);
+ if (h_Qmf->FilterStates != NULL) {
+ if (!(flags & QMF_FLAG_KEEP_STATES)) {
+ FDKmemclear(
+ h_Qmf->FilterStates,
+ (2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QSS));
+ } else {
+ qmfAdaptFilterStates(h_Qmf, oldOutScale - h_Qmf->outScalefactor);
+ }
+ }
+
+ FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb);
+ FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->usb);
+
+ return err;
+}
+
+/*!
+ *
+ * \brief Change scale factor for output data and adjust qmf filter states
+ *
+ * \return void
+ *
+ */
+void qmfChangeOutScalefactor(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
+ int outScalefactor /*!< New scaling factor for output data */
+) {
+ if (synQmf == NULL) {
+ return;
+ }
+
+ /* Add internal filterbank scale */
+ outScalefactor +=
+ (ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + synQmf->filterScale) +
+ synQmf->synScalefactor;
+
+ /* adjust filter states when scale factor has been changed */
+ if (synQmf->outScalefactor != outScalefactor) {
+ int diff;
+
+ diff = synQmf->outScalefactor - outScalefactor;
+
+ qmfAdaptFilterStates(synQmf, diff);
+
+ /* save new scale factor */
+ synQmf->outScalefactor = outScalefactor;
+ }
+}
+
+/*!
+ *
+ * \brief Get scale factor change which was set by qmfChangeOutScalefactor()
+ *
+ * \return scaleFactor
+ *
+ */
+int qmfGetOutScalefactor(
+ HANDLE_QMF_FILTER_BANK synQmf) /*!< Handle of Qmf Synthesis Bank */
+{
+ int scaleFactor = synQmf->outScalefactor
+ ? (synQmf->outScalefactor -
+ (ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK +
+ synQmf->filterScale + synQmf->synScalefactor))
+ : 0;
+ return scaleFactor;
+}
+
+/*!
+ *
+ * \brief Change gain for output data
+ *
+ * \return void
+ *
+ */
+void qmfChangeOutGain(
+ HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
+ FIXP_DBL outputGain, /*!< New gain for output data (mantissa) */
+ int outputGainScale /*!< New gain for output data (exponent) */
+) {
+ synQmf->outGain_m = outputGain;
+ synQmf->outGain_e = outputGainScale;
+}
+
+/* When QMF_16IN_32OUT is set, synthesis functions for 16 and 32 bit parallel
+ * output is compiled */
+#define INT_PCM_QMFOUT INT_PCM
+#define SAMPLE_BITS_QMFOUT SAMPLE_BITS
+#include "qmf_pcm.h"
diff --git a/fdk-aac/libFDK/src/scale.cpp b/fdk-aac/libFDK/src/scale.cpp
new file mode 100644
index 0000000..24a8a5b
--- /dev/null
+++ b/fdk-aac/libFDK/src/scale.cpp
@@ -0,0 +1,720 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/******************* Library for basic calculation routines ********************
+
+ Author(s):
+
+ Description: Scaling operations
+
+*******************************************************************************/
+
+#include "common_fix.h"
+
+#include "genericStds.h"
+
+/**************************************************
+ * Inline definitions
+ **************************************************/
+
+#include "scale.h"
+
+#if defined(__mips__)
+#include "mips/scale_mips.cpp"
+
+#elif defined(__arm__)
+#include "arm/scale_arm.cpp"
+
+#endif
+
+#ifndef FUNCTION_scaleValues_SGL
+/*!
+ *
+ * \brief Multiply input vector by \f$ 2^{scalefactor} \f$
+ * \param len must be larger than 4
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValues_SGL
+void scaleValues(FIXP_SGL *vector, /*!< Vector */
+ INT len, /*!< Length */
+ INT scalefactor /*!< Scalefactor */
+) {
+ INT i;
+
+ /* Return if scalefactor is Zero */
+ if (scalefactor == 0) return;
+
+ if (scalefactor > 0) {
+ scalefactor = fixmin_I(scalefactor, (INT)(FRACT_BITS - 1));
+ for (i = len & 3; i--;) {
+ *(vector++) <<= scalefactor;
+ }
+ for (i = len >> 2; i--;) {
+ *(vector++) <<= scalefactor;
+ *(vector++) <<= scalefactor;
+ *(vector++) <<= scalefactor;
+ *(vector++) <<= scalefactor;
+ }
+ } else {
+ INT negScalefactor = fixmin_I(-scalefactor, (INT)FRACT_BITS - 1);
+ for (i = len & 3; i--;) {
+ *(vector++) >>= negScalefactor;
+ }
+ for (i = len >> 2; i--;) {
+ *(vector++) >>= negScalefactor;
+ *(vector++) >>= negScalefactor;
+ *(vector++) >>= negScalefactor;
+ *(vector++) >>= negScalefactor;
+ }
+ }
+}
+#endif
+
+#ifndef FUNCTION_scaleValues_DBL
+/*!
+ *
+ * \brief Multiply input vector by \f$ 2^{scalefactor} \f$
+ * \param len must be larger than 4
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValues_DBL
+SCALE_INLINE
+void scaleValues(FIXP_DBL *vector, /*!< Vector */
+ INT len, /*!< Length */
+ INT scalefactor /*!< Scalefactor */
+) {
+ INT i;
+
+ /* Return if scalefactor is Zero */
+ if (scalefactor == 0) return;
+
+ if (scalefactor > 0) {
+ scalefactor = fixmin_I(scalefactor, (INT)DFRACT_BITS - 1);
+ for (i = len & 3; i--;) {
+ *(vector++) <<= scalefactor;
+ }
+ for (i = len >> 2; i--;) {
+ *(vector++) <<= scalefactor;
+ *(vector++) <<= scalefactor;
+ *(vector++) <<= scalefactor;
+ *(vector++) <<= scalefactor;
+ }
+ } else {
+ INT negScalefactor = fixmin_I(-scalefactor, (INT)DFRACT_BITS - 1);
+ for (i = len & 3; i--;) {
+ *(vector++) >>= negScalefactor;
+ }
+ for (i = len >> 2; i--;) {
+ *(vector++) >>= negScalefactor;
+ *(vector++) >>= negScalefactor;
+ *(vector++) >>= negScalefactor;
+ *(vector++) >>= negScalefactor;
+ }
+ }
+}
+#endif
+
+#ifndef FUNCTION_scaleValuesSaturate_DBL
+/*!
+ *
+ * \brief Multiply input vector by \f$ 2^{scalefactor} \f$
+ * \param vector source/destination buffer
+ * \param len length of vector
+ * \param scalefactor amount of shifts to be applied
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValuesSaturate_DBL
+SCALE_INLINE
+void scaleValuesSaturate(FIXP_DBL *vector, /*!< Vector */
+ INT len, /*!< Length */
+ INT scalefactor /*!< Scalefactor */
+) {
+ INT i;
+
+ /* Return if scalefactor is Zero */
+ if (scalefactor == 0) return;
+
+ scalefactor = fixmax_I(fixmin_I(scalefactor, (INT)DFRACT_BITS - 1),
+ (INT) - (DFRACT_BITS - 1));
+
+ for (i = 0; i < len; i++) {
+ vector[i] = scaleValueSaturate(vector[i], scalefactor);
+ }
+}
+#endif /* FUNCTION_scaleValuesSaturate_DBL */
+
+#ifndef FUNCTION_scaleValuesSaturate_DBL_DBL
+/*!
+ *
+ * \brief Multiply input vector by \f$ 2^{scalefactor} \f$
+ * \param dst destination buffer
+ * \param src source buffer
+ * \param len length of vector
+ * \param scalefactor amount of shifts to be applied
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValuesSaturate_DBL_DBL
+SCALE_INLINE
+void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
+ FIXP_DBL *src, /*!< Input */
+ INT len, /*!< Length */
+ INT scalefactor /*!< Scalefactor */
+) {
+ INT i;
+
+ /* Return if scalefactor is Zero */
+ if (scalefactor == 0) {
+ FDKmemmove(dst, src, len * sizeof(FIXP_DBL));
+ return;
+ }
+
+ scalefactor = fixmax_I(fixmin_I(scalefactor, (INT)DFRACT_BITS - 1),
+ (INT) - (DFRACT_BITS - 1));
+
+ for (i = 0; i < len; i++) {
+ dst[i] = scaleValueSaturate(src[i], scalefactor);
+ }
+}
+#endif /* FUNCTION_scaleValuesSaturate_DBL_DBL */
+
+#ifndef FUNCTION_scaleValuesSaturate_SGL_DBL
+/*!
+ *
+ * \brief Multiply input vector by \f$ 2^{scalefactor} \f$
+ * \param dst destination buffer (FIXP_SGL)
+ * \param src source buffer (FIXP_DBL)
+ * \param len length of vector
+ * \param scalefactor amount of shifts to be applied
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValuesSaturate_SGL_DBL
+SCALE_INLINE
+void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
+ FIXP_DBL *src, /*!< Input */
+ INT len, /*!< Length */
+ INT scalefactor) /*!< Scalefactor */
+{
+ INT i;
+ scalefactor = fixmax_I(fixmin_I(scalefactor, (INT)DFRACT_BITS - 1),
+ (INT) - (DFRACT_BITS - 1));
+
+ for (i = 0; i < len; i++) {
+ dst[i] = FX_DBL2FX_SGL(fAddSaturate(scaleValueSaturate(src[i], scalefactor),
+ (FIXP_DBL)0x8000));
+ }
+}
+#endif /* FUNCTION_scaleValuesSaturate_SGL_DBL */
+
+#ifndef FUNCTION_scaleValuesSaturate_SGL
+/*!
+ *
+ * \brief Multiply input vector by \f$ 2^{scalefactor} \f$
+ * \param vector source/destination buffer
+ * \param len length of vector
+ * \param scalefactor amount of shifts to be applied
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValuesSaturate_SGL
+SCALE_INLINE
+void scaleValuesSaturate(FIXP_SGL *vector, /*!< Vector */
+ INT len, /*!< Length */
+ INT scalefactor /*!< Scalefactor */
+) {
+ INT i;
+
+ /* Return if scalefactor is Zero */
+ if (scalefactor == 0) return;
+
+ scalefactor = fixmax_I(fixmin_I(scalefactor, (INT)DFRACT_BITS - 1),
+ (INT) - (DFRACT_BITS - 1));
+
+ for (i = 0; i < len; i++) {
+ vector[i] = FX_DBL2FX_SGL(
+ scaleValueSaturate(FX_SGL2FX_DBL(vector[i]), scalefactor));
+ }
+}
+#endif /* FUNCTION_scaleValuesSaturate_SGL */
+
+#ifndef FUNCTION_scaleValuesSaturate_SGL_SGL
+/*!
+ *
+ * \brief Multiply input vector by \f$ 2^{scalefactor} \f$
+ * \param dst destination buffer
+ * \param src source buffer
+ * \param len length of vector
+ * \param scalefactor amount of shifts to be applied
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValuesSaturate_SGL_SGL
+SCALE_INLINE
+void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
+ FIXP_SGL *src, /*!< Input */
+ INT len, /*!< Length */
+ INT scalefactor /*!< Scalefactor */
+) {
+ INT i;
+
+ /* Return if scalefactor is Zero */
+ if (scalefactor == 0) {
+ FDKmemmove(dst, src, len * sizeof(FIXP_SGL));
+ return;
+ }
+
+ scalefactor = fixmax_I(fixmin_I(scalefactor, (INT)DFRACT_BITS - 1),
+ (INT) - (DFRACT_BITS - 1));
+
+ for (i = 0; i < len; i++) {
+ dst[i] =
+ FX_DBL2FX_SGL(scaleValueSaturate(FX_SGL2FX_DBL(src[i]), scalefactor));
+ }
+}
+#endif /* FUNCTION_scaleValuesSaturate_SGL_SGL */
+
+#ifndef FUNCTION_scaleValues_DBLDBL
+/*!
+ *
+ * \brief Multiply input vector src by \f$ 2^{scalefactor} \f$
+ * and place result into dst
+ * \param dst detination buffer
+ * \param src source buffer
+ * \param len must be larger than 4
+ * \param scalefactor amount of left shifts to be applied
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValues_DBLDBL
+SCALE_INLINE
+void scaleValues(FIXP_DBL *dst, /*!< dst Vector */
+ const FIXP_DBL *src, /*!< src Vector */
+ INT len, /*!< Length */
+ INT scalefactor /*!< Scalefactor */
+) {
+ INT i;
+
+ /* Return if scalefactor is Zero */
+ if (scalefactor == 0) {
+ if (dst != src) FDKmemmove(dst, src, len * sizeof(FIXP_DBL));
+ } else {
+ if (scalefactor > 0) {
+ scalefactor = fixmin_I(scalefactor, (INT)DFRACT_BITS - 1);
+ for (i = len & 3; i--;) {
+ *(dst++) = *(src++) << scalefactor;
+ }
+ for (i = len >> 2; i--;) {
+ *(dst++) = *(src++) << scalefactor;
+ *(dst++) = *(src++) << scalefactor;
+ *(dst++) = *(src++) << scalefactor;
+ *(dst++) = *(src++) << scalefactor;
+ }
+ } else {
+ INT negScalefactor = fixmin_I(-scalefactor, (INT)DFRACT_BITS - 1);
+ for (i = len & 3; i--;) {
+ *(dst++) = *(src++) >> negScalefactor;
+ }
+ for (i = len >> 2; i--;) {
+ *(dst++) = *(src++) >> negScalefactor;
+ *(dst++) = *(src++) >> negScalefactor;
+ *(dst++) = *(src++) >> negScalefactor;
+ *(dst++) = *(src++) >> negScalefactor;
+ }
+ }
+ }
+}
+#endif
+
+#if (SAMPLE_BITS == 16)
+#ifndef FUNCTION_scaleValues_PCMDBL
+/*!
+ *
+ * \brief Multiply input vector src by \f$ 2^{scalefactor} \f$
+ * and place result into dst
+ * \param dst detination buffer
+ * \param src source buffer
+ * \param len must be larger than 4
+ * \param scalefactor amount of left shifts to be applied
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValues_PCMDBL
+SCALE_INLINE
+void scaleValues(FIXP_PCM *dst, /*!< dst Vector */
+ const FIXP_DBL *src, /*!< src Vector */
+ INT len, /*!< Length */
+ INT scalefactor /*!< Scalefactor */
+) {
+ INT i;
+
+ scalefactor -= DFRACT_BITS - SAMPLE_BITS;
+
+ /* Return if scalefactor is Zero */
+ {
+ if (scalefactor > 0) {
+ scalefactor = fixmin_I(scalefactor, (INT)DFRACT_BITS - 1);
+ for (i = len & 3; i--;) {
+ *(dst++) = (FIXP_PCM)(*(src++) << scalefactor);
+ }
+ for (i = len >> 2; i--;) {
+ *(dst++) = (FIXP_PCM)(*(src++) << scalefactor);
+ *(dst++) = (FIXP_PCM)(*(src++) << scalefactor);
+ *(dst++) = (FIXP_PCM)(*(src++) << scalefactor);
+ *(dst++) = (FIXP_PCM)(*(src++) << scalefactor);
+ }
+ } else {
+ INT negScalefactor = fixmin_I(-scalefactor, (INT)DFRACT_BITS - 1);
+ for (i = len & 3; i--;) {
+ *(dst++) = (FIXP_PCM)(*(src++) >> negScalefactor);
+ }
+ for (i = len >> 2; i--;) {
+ *(dst++) = (FIXP_PCM)(*(src++) >> negScalefactor);
+ *(dst++) = (FIXP_PCM)(*(src++) >> negScalefactor);
+ *(dst++) = (FIXP_PCM)(*(src++) >> negScalefactor);
+ *(dst++) = (FIXP_PCM)(*(src++) >> negScalefactor);
+ }
+ }
+ }
+}
+#endif
+#endif /* (SAMPLE_BITS == 16) */
+
+#ifndef FUNCTION_scaleValues_SGLSGL
+/*!
+ *
+ * \brief Multiply input vector src by \f$ 2^{scalefactor} \f$
+ * and place result into dst
+ * \param dst detination buffer
+ * \param src source buffer
+ * \param len must be larger than 4
+ * \param scalefactor amount of left shifts to be applied
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValues_SGLSGL
+SCALE_INLINE
+void scaleValues(FIXP_SGL *dst, /*!< dst Vector */
+ const FIXP_SGL *src, /*!< src Vector */
+ INT len, /*!< Length */
+ INT scalefactor /*!< Scalefactor */
+) {
+ INT i;
+
+ /* Return if scalefactor is Zero */
+ if (scalefactor == 0) {
+ if (dst != src) FDKmemmove(dst, src, len * sizeof(FIXP_DBL));
+ } else {
+ if (scalefactor > 0) {
+ scalefactor = fixmin_I(scalefactor, (INT)DFRACT_BITS - 1);
+ for (i = len & 3; i--;) {
+ *(dst++) = *(src++) << scalefactor;
+ }
+ for (i = len >> 2; i--;) {
+ *(dst++) = *(src++) << scalefactor;
+ *(dst++) = *(src++) << scalefactor;
+ *(dst++) = *(src++) << scalefactor;
+ *(dst++) = *(src++) << scalefactor;
+ }
+ } else {
+ INT negScalefactor = fixmin_I(-scalefactor, (INT)DFRACT_BITS - 1);
+ for (i = len & 3; i--;) {
+ *(dst++) = *(src++) >> negScalefactor;
+ }
+ for (i = len >> 2; i--;) {
+ *(dst++) = *(src++) >> negScalefactor;
+ *(dst++) = *(src++) >> negScalefactor;
+ *(dst++) = *(src++) >> negScalefactor;
+ *(dst++) = *(src++) >> negScalefactor;
+ }
+ }
+ }
+}
+#endif
+
+#ifndef FUNCTION_scaleValuesWithFactor_DBL
+/*!
+ *
+ * \brief Multiply input vector by \f$ 2^{scalefactor} \f$
+ * \param len must be larger than 4
+ * \return void
+ *
+ */
+#define FUNCTION_scaleValuesWithFactor_DBL
+SCALE_INLINE
+void scaleValuesWithFactor(FIXP_DBL *vector, FIXP_DBL factor, INT len,
+ INT scalefactor) {
+ INT i;
+
+ /* Compensate fMultDiv2 */
+ scalefactor++;
+
+ if (scalefactor > 0) {
+ scalefactor = fixmin_I(scalefactor, (INT)DFRACT_BITS - 1);
+ for (i = len & 3; i--;) {
+ *vector = fMultDiv2(*vector, factor) << scalefactor;
+ vector++;
+ }
+ for (i = len >> 2; i--;) {
+ *vector = fMultDiv2(*vector, factor) << scalefactor;
+ vector++;
+ *vector = fMultDiv2(*vector, factor) << scalefactor;
+ vector++;
+ *vector = fMultDiv2(*vector, factor) << scalefactor;
+ vector++;
+ *vector = fMultDiv2(*vector, factor) << scalefactor;
+ vector++;
+ }
+ } else {
+ INT negScalefactor = fixmin_I(-scalefactor, (INT)DFRACT_BITS - 1);
+ for (i = len & 3; i--;) {
+ *vector = fMultDiv2(*vector, factor) >> negScalefactor;
+ vector++;
+ }
+ for (i = len >> 2; i--;) {
+ *vector = fMultDiv2(*vector, factor) >> negScalefactor;
+ vector++;
+ *vector = fMultDiv2(*vector, factor) >> negScalefactor;
+ vector++;
+ *vector = fMultDiv2(*vector, factor) >> negScalefactor;
+ vector++;
+ *vector = fMultDiv2(*vector, factor) >> negScalefactor;
+ vector++;
+ }
+ }
+}
+#endif /* FUNCTION_scaleValuesWithFactor_DBL */
+
+ /*******************************************
+
+ IMPORTANT NOTE for usage of getScalefactor()
+
+ If the input array contains negative values too, then these functions may
+ sometimes return the actual maximum value minus 1, due to the nature of the
+ applied algorithm. So be careful with possible fractional -1 values that may
+ lead to overflows when being fPow2()'ed.
+
+ ********************************************/
+
+#ifndef FUNCTION_getScalefactorShort
+/*!
+ *
+ * \brief Calculate max possible scale factor for input vector of shorts
+ *
+ * \return Maximum scale factor / possible left shift
+ *
+ */
+#define FUNCTION_getScalefactorShort
+SCALE_INLINE
+INT getScalefactorShort(const SHORT *vector, /*!< Pointer to input vector */
+ INT len /*!< Length of input vector */
+) {
+ INT i;
+ SHORT temp, maxVal = 0;
+
+ for (i = len; i != 0; i--) {
+ temp = (SHORT)(*vector++);
+ maxVal |= (temp ^ (temp >> (SHORT_BITS - 1)));
+ }
+
+ return fixmax_I((INT)0, (INT)(fixnormz_D((INT)maxVal) - (INT)1 -
+ (INT)(DFRACT_BITS - SHORT_BITS)));
+}
+#endif
+
+#ifndef FUNCTION_getScalefactorPCM
+/*!
+ *
+ * \brief Calculate max possible scale factor for input vector of shorts
+ *
+ * \return Maximum scale factor
+ *
+ */
+#define FUNCTION_getScalefactorPCM
+SCALE_INLINE
+INT getScalefactorPCM(const INT_PCM *vector, /*!< Pointer to input vector */
+ INT len, /*!< Length of input vector */
+ INT stride) {
+ INT i;
+ INT_PCM temp, maxVal = 0;
+
+ for (i = len; i != 0; i--) {
+ temp = (INT_PCM)(*vector);
+ vector += stride;
+ maxVal |= (temp ^ (temp >> ((sizeof(INT_PCM) * 8) - 1)));
+ }
+ return fixmax_I((INT)0, (INT)(fixnormz_D((INT)maxVal) - (INT)1 -
+ (INT)(DFRACT_BITS - SAMPLE_BITS)));
+}
+#endif
+
+#ifndef FUNCTION_getScalefactorShort
+/*!
+ *
+ * \brief Calculate max possible scale factor for input vector of shorts
+ * \param stride, item increment between vector members.
+ * \return Maximum scale factor
+ *
+ */
+#define FUNCTION_getScalefactorShort
+SCALE_INLINE
+INT getScalefactorShort(const SHORT *vector, /*!< Pointer to input vector */
+ INT len, /*!< Length of input vector */
+ INT stride) {
+ INT i;
+ SHORT temp, maxVal = 0;
+
+ for (i = len; i != 0; i--) {
+ temp = (SHORT)(*vector);
+ vector += stride;
+ maxVal |= (temp ^ (temp >> (SHORT_BITS - 1)));
+ }
+
+ return fixmax_I((INT)0, (INT)(fixnormz_D((INT)maxVal) - (INT)1 -
+ (INT)(DFRACT_BITS - SHORT_BITS)));
+}
+#endif
+
+#ifndef FUNCTION_getScalefactor_DBL
+/*!
+ *
+ * \brief Calculate max possible scale factor for input vector
+ *
+ * \return Maximum scale factor
+ *
+ * This function can constitute a significant amount of computational
+ * complexity - very much depending on the bitrate. Since it is a rather small
+ * function, effective assembler optimization might be possible.
+ *
+ * If all data is 0xFFFF.FFFF or 0x0000.0000 function returns 31
+ * Note: You can skip data normalization only if return value is 0
+ *
+ */
+#define FUNCTION_getScalefactor_DBL
+SCALE_INLINE
+INT getScalefactor(const FIXP_DBL *vector, /*!< Pointer to input vector */
+ INT len) /*!< Length of input vector */
+{
+ INT i;
+ FIXP_DBL temp, maxVal = (FIXP_DBL)0;
+
+ for (i = len; i != 0; i--) {
+ temp = (LONG)(*vector++);
+ maxVal |= (FIXP_DBL)((LONG)temp ^ (LONG)(temp >> (DFRACT_BITS - 1)));
+ }
+
+ return fixmax_I((INT)0, (INT)(fixnormz_D(maxVal) - 1));
+}
+#endif
+
+#ifndef FUNCTION_getScalefactor_SGL
+#define FUNCTION_getScalefactor_SGL
+SCALE_INLINE
+INT getScalefactor(const FIXP_SGL *vector, /*!< Pointer to input vector */
+ INT len) /*!< Length of input vector */
+{
+ INT i;
+ SHORT temp, maxVal = (FIXP_SGL)0;
+
+ for (i = len; i != 0; i--) {
+ temp = (SHORT)(*vector++);
+ maxVal |= (temp ^ (temp >> (FRACT_BITS - 1)));
+ }
+
+ return fixmax_I((INT)0, (INT)(fixnormz_S((FIXP_SGL)maxVal)) - 1);
+}
+#endif
diff --git a/fdk-aac/libMpegTPDec/include/tp_data.h b/fdk-aac/libMpegTPDec/include/tp_data.h
new file mode 100644
index 0000000..b015332
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/include/tp_data.h
@@ -0,0 +1,466 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ Author(s): Manuel Jander
+
+ Description: MPEG Transport data tables
+
+*******************************************************************************/
+
+#ifndef TP_DATA_H
+#define TP_DATA_H
+
+#include "machine_type.h"
+#include "FDK_audio.h"
+#include "FDK_bitstream.h"
+
+/*
+ * Configuration
+ */
+
+#define TP_USAC_MAX_SPEAKERS (24)
+
+#define TP_USAC_MAX_EXT_ELEMENTS ((24))
+
+#define TP_USAC_MAX_ELEMENTS ((24) + TP_USAC_MAX_EXT_ELEMENTS)
+
+#define TP_USAC_MAX_CONFIG_LEN \
+ 512 /* next power of two of maximum of escapedValue(hBs, 4, 4, 8) in \
+ AudioPreRoll() (285) */
+
+#define TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES \
+ (1) /* Number of frames for config change in USAC */
+
+enum {
+ TPDEC_FLUSH_OFF = 0,
+ TPDEC_RSV60_CFG_CHANGE_ATSC_FLUSH_ON = 1,
+ TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON = 2,
+ TPDEC_USAC_DASH_IPF_FLUSH_ON = 3
+};
+
+enum {
+ TPDEC_BUILD_UP_OFF = 0,
+ TPDEC_RSV60_BUILD_UP_ON = 1,
+ TPDEC_RSV60_BUILD_UP_ON_IN_BAND = 2,
+ TPDEC_USAC_BUILD_UP_ON = 3,
+ TPDEC_RSV60_BUILD_UP_IDLE = 4,
+ TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND = 5
+};
+
+/**
+ * ProgramConfig struct.
+ */
+/* ISO/IEC 14496-3 4.4.1.1 Table 4.2 Program config element */
+#define PC_FSB_CHANNELS_MAX 16 /* Front/Side/Back channels */
+#define PC_LFE_CHANNELS_MAX 4
+#define PC_ASSOCDATA_MAX 8
+#define PC_CCEL_MAX 16 /* CC elements */
+#define PC_COMMENTLENGTH 256
+#define PC_NUM_HEIGHT_LAYER 3
+
+typedef struct {
+ /* PCE bitstream elements: */
+ UCHAR ElementInstanceTag;
+ UCHAR Profile;
+ UCHAR SamplingFrequencyIndex;
+ UCHAR NumFrontChannelElements;
+ UCHAR NumSideChannelElements;
+ UCHAR NumBackChannelElements;
+ UCHAR NumLfeChannelElements;
+ UCHAR NumAssocDataElements;
+ UCHAR NumValidCcElements;
+
+ UCHAR MonoMixdownPresent;
+ UCHAR MonoMixdownElementNumber;
+
+ UCHAR StereoMixdownPresent;
+ UCHAR StereoMixdownElementNumber;
+
+ UCHAR MatrixMixdownIndexPresent;
+ UCHAR MatrixMixdownIndex;
+ UCHAR PseudoSurroundEnable;
+
+ UCHAR FrontElementIsCpe[PC_FSB_CHANNELS_MAX];
+ UCHAR FrontElementTagSelect[PC_FSB_CHANNELS_MAX];
+ UCHAR FrontElementHeightInfo[PC_FSB_CHANNELS_MAX];
+
+ UCHAR SideElementIsCpe[PC_FSB_CHANNELS_MAX];
+ UCHAR SideElementTagSelect[PC_FSB_CHANNELS_MAX];
+ UCHAR SideElementHeightInfo[PC_FSB_CHANNELS_MAX];
+
+ UCHAR BackElementIsCpe[PC_FSB_CHANNELS_MAX];
+ UCHAR BackElementTagSelect[PC_FSB_CHANNELS_MAX];
+ UCHAR BackElementHeightInfo[PC_FSB_CHANNELS_MAX];
+
+ UCHAR LfeElementTagSelect[PC_LFE_CHANNELS_MAX];
+
+ UCHAR AssocDataElementTagSelect[PC_ASSOCDATA_MAX];
+
+ UCHAR CcElementIsIndSw[PC_CCEL_MAX];
+ UCHAR ValidCcElementTagSelect[PC_CCEL_MAX];
+
+ UCHAR CommentFieldBytes;
+ UCHAR Comment[PC_COMMENTLENGTH];
+
+ /* Helper variables for administration: */
+ UCHAR isValid; /*!< Flag showing if PCE has been read successfully. */
+ UCHAR
+ NumChannels; /*!< Amount of audio channels summing all channel elements
+ including LFEs */
+ UCHAR NumEffectiveChannels; /*!< Amount of audio channels summing only SCEs
+ and CPEs */
+ UCHAR elCounter;
+
+} CProgramConfig;
+
+typedef enum {
+ ASCEXT_UNKOWN = -1,
+ ASCEXT_SBR = 0x2b7,
+ ASCEXT_PS = 0x548,
+ ASCEXT_MPS = 0x76a,
+ ASCEXT_SAOC = 0x7cb,
+ ASCEXT_LDMPS = 0x7cc
+
+} TP_ASC_EXTENSION_ID;
+
+/**
+ * GaSpecificConfig struct
+ */
+typedef struct {
+ UINT m_frameLengthFlag;
+ UINT m_dependsOnCoreCoder;
+ UINT m_coreCoderDelay;
+
+ UINT m_extensionFlag;
+ UINT m_extensionFlag3;
+
+ UINT m_layer;
+ UINT m_numOfSubFrame;
+ UINT m_layerLength;
+
+} CSGaSpecificConfig;
+
+typedef enum {
+ ELDEXT_TERM = 0x0, /* Termination tag */
+ ELDEXT_SAOC = 0x1, /* SAOC config */
+ ELDEXT_LDSAC = 0x2, /* LD MPEG Surround config */
+ ELDEXT_DOWNSCALEINFO = 0x3 /* ELD sample rate adaptation */
+ /* reserved */
+} ASC_ELD_EXT_TYPE;
+
+typedef struct {
+ UCHAR m_frameLengthFlag;
+
+ UCHAR m_sbrPresentFlag;
+ UCHAR
+ m_useLdQmfTimeAlign; /* Use LD-MPS QMF in SBR to achive time alignment */
+ UCHAR m_sbrSamplingRate;
+ UCHAR m_sbrCrcFlag;
+ UINT m_downscaledSamplingFrequency;
+
+} CSEldSpecificConfig;
+
+typedef struct {
+ USAC_EXT_ELEMENT_TYPE usacExtElementType;
+ USHORT usacExtElementConfigLength;
+ USHORT usacExtElementDefaultLength;
+ UCHAR usacExtElementPayloadFrag;
+ UCHAR usacExtElementHasAudioPreRoll;
+} CSUsacExtElementConfig;
+
+typedef struct {
+ MP4_ELEMENT_ID usacElementType;
+ UCHAR m_noiseFilling;
+ UCHAR m_harmonicSBR;
+ UCHAR m_interTes;
+ UCHAR m_pvc;
+ UCHAR m_stereoConfigIndex;
+ CSUsacExtElementConfig extElement;
+} CSUsacElementConfig;
+
+typedef struct {
+ UCHAR m_frameLengthFlag;
+ UCHAR m_coreSbrFrameLengthIndex;
+ UCHAR m_sbrRatioIndex;
+ UCHAR m_nUsacChannels; /* number of audio channels signaled in
+ UsacDecoderConfig() / rsv603daDecoderConfig() via
+ numElements and usacElementType */
+ UCHAR m_channelConfigurationIndex;
+ UINT m_usacNumElements;
+ CSUsacElementConfig element[TP_USAC_MAX_ELEMENTS];
+
+ UCHAR numAudioChannels;
+ UCHAR m_usacConfigExtensionPresent;
+ UCHAR elementLengthPresent;
+ UCHAR UsacConfig[TP_USAC_MAX_CONFIG_LEN];
+ USHORT UsacConfigBits;
+} CSUsacConfig;
+
+/**
+ * Audio configuration struct, suitable for encoder and decoder configuration.
+ */
+typedef struct {
+ /* XYZ Specific Data */
+ union {
+ CSGaSpecificConfig
+ m_gaSpecificConfig; /**< General audio specific configuration. */
+ CSEldSpecificConfig m_eldSpecificConfig; /**< ELD specific configuration. */
+ CSUsacConfig m_usacConfig; /**< USAC specific configuration */
+ } m_sc;
+
+ /* Common ASC parameters */
+ CProgramConfig m_progrConfigElement; /**< Program configuration. */
+
+ AUDIO_OBJECT_TYPE m_aot; /**< Audio Object Type. */
+ UINT m_samplingFrequency; /**< Samplerate. */
+ UINT m_samplesPerFrame; /**< Amount of samples per frame. */
+ UINT m_directMapping; /**< Document this please !! */
+
+ AUDIO_OBJECT_TYPE m_extensionAudioObjectType; /**< Audio object type */
+ UINT m_extensionSamplingFrequency; /**< Samplerate */
+
+ SCHAR m_channelConfiguration; /**< Channel configuration index */
+
+ SCHAR m_epConfig; /**< Error protection index */
+ SCHAR m_vcb11Flag; /**< aacSectionDataResilienceFlag */
+ SCHAR m_rvlcFlag; /**< aacScalefactorDataResilienceFlag */
+ SCHAR m_hcrFlag; /**< aacSpectralDataResilienceFlag */
+
+ SCHAR m_sbrPresentFlag; /**< Flag indicating the presence of SBR data in the
+ bitstream */
+ SCHAR
+ m_psPresentFlag; /**< Flag indicating the presence of parametric stereo
+ data in the bitstream */
+ UCHAR m_samplingFrequencyIndex; /**< Samplerate index */
+ UCHAR m_extensionSamplingFrequencyIndex; /**< Samplerate index */
+ SCHAR m_extensionChannelConfiguration; /**< Channel configuration index */
+
+ UCHAR
+ configMode; /**< The flag indicates if the callback shall work in memory
+ allocation mode or in config change detection mode */
+ UCHAR AacConfigChanged; /**< The flag will be set if at least one aac config
+ parameter has changed that requires a memory
+ reconfiguration, otherwise it will be cleared */
+ UCHAR SbrConfigChanged; /**< The flag will be set if at least one sbr config
+ parameter has changed that requires a memory
+ reconfiguration, otherwise it will be cleared */
+ UCHAR SacConfigChanged; /**< The flag will be set if at least one sac config
+ parameter has changed that requires a memory
+ reconfiguration, otherwise it will be cleared */
+
+ UCHAR
+ config[TP_USAC_MAX_CONFIG_LEN]; /**< Configuration stored as bitstream */
+ UINT configBits; /**< Configuration length in bits */
+
+} CSAudioSpecificConfig;
+
+typedef struct {
+ SCHAR flushCnt; /**< Flush frame counter */
+ UCHAR flushStatus; /**< Flag indicates flush mode: on|off */
+ SCHAR buildUpCnt; /**< Build up frame counter */
+ UCHAR buildUpStatus; /**< Flag indicates build up mode: on|off */
+ UCHAR cfgChanged; /**< Flag indicates that the config changed and the decoder
+ needs to be initialized again via callback. Make sure
+ that memory is freed before initialization. */
+ UCHAR contentChanged; /**< Flag indicates that the content changed i.e. a
+ right truncation occured before */
+ UCHAR forceCfgChange; /**< Flag indicates if config change has to be forced
+ even if new config is the same */
+} CCtrlCFGChange;
+
+typedef INT (*cbUpdateConfig_t)(void *, const CSAudioSpecificConfig *,
+ const UCHAR configMode, UCHAR *configChanged);
+typedef INT (*cbFreeMem_t)(void *, const CSAudioSpecificConfig *);
+typedef INT (*cbCtrlCFGChange_t)(void *, const CCtrlCFGChange *);
+typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const INT samplingRate, const INT frameSize,
+ const INT stereoConfigIndex,
+ const INT coreSbrFrameLengthIndex, const INT configBytes,
+ const UCHAR configMode, UCHAR *configChanged);
+
+typedef INT (*cbSbr_t)(void *self, HANDLE_FDK_BITSTREAM hBs,
+ const INT sampleRateIn, const INT sampleRateOut,
+ const INT samplesPerFrame,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const MP4_ELEMENT_ID elementID, const INT elementIndex,
+ const UCHAR harmonicSbr, const UCHAR stereoConfigIndex,
+ const UCHAR configMode, UCHAR *configChanged,
+ const INT downscaleFactor);
+
+typedef INT (*cbUsac_t)(void *self, HANDLE_FDK_BITSTREAM hBs);
+
+typedef INT (*cbUniDrc_t)(void *self, HANDLE_FDK_BITSTREAM hBs,
+ const INT fullPayloadLength, const INT payloadType,
+ const INT subStreamIndex, const INT payloadStart,
+ const AUDIO_OBJECT_TYPE);
+
+typedef struct {
+ cbUpdateConfig_t cbUpdateConfig; /*!< Function pointer for Config change
+ notify callback. */
+ void *cbUpdateConfigData; /*!< User data pointer for Config change notify
+ callback. */
+ cbFreeMem_t cbFreeMem; /*!< Function pointer for free memory callback. */
+ void *cbFreeMemData; /*!< User data pointer for free memory callback. */
+ cbCtrlCFGChange_t cbCtrlCFGChange; /*!< Function pointer for config change
+ control callback. */
+ void *cbCtrlCFGChangeData; /*!< User data pointer for config change control
+ callback. */
+ cbSsc_t cbSsc; /*!< Function pointer for SSC parser callback. */
+ void *cbSscData; /*!< User data pointer for SSC parser callback. */
+ cbSbr_t cbSbr; /*!< Function pointer for SBR header parser callback. */
+ void *cbSbrData; /*!< User data pointer for SBR header parser callback. */
+ cbUsac_t cbUsac;
+ void *cbUsacData;
+ cbUniDrc_t cbUniDrc; /*!< Function pointer for uniDrcConfig and
+ loudnessInfoSet parser callback. */
+ void *cbUniDrcData; /*!< User data pointer for uniDrcConfig and
+ loudnessInfoSet parser callback. */
+} CSTpCallBacks;
+
+static const UINT SamplingRateTable[] = {
+ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025,
+ 8000, 7350, 0, 0, 57600, 51200, 40000, 38400, 34150, 28800, 25600,
+ 20000, 19200, 17075, 14400, 12800, 9600, 0, 0, 0, 0};
+
+static inline int getSamplingRateIndex(UINT samplingRate, UINT nBits) {
+ UINT sf_index;
+ UINT tableSize = (1 << nBits) - 1;
+
+ for (sf_index = 0; sf_index < tableSize; sf_index++) {
+ if (SamplingRateTable[sf_index] == samplingRate) break;
+ }
+
+ if (sf_index > tableSize) {
+ return tableSize - 1;
+ }
+
+ return sf_index;
+}
+
+/*
+ * Get Channel count from channel configuration
+ */
+static inline int getNumberOfTotalChannels(int channelConfig) {
+ switch (channelConfig) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ return channelConfig;
+ case 7:
+ case 12:
+ case 14:
+ return 8;
+ case 11:
+ return 7;
+ case 13:
+ return 24;
+ default:
+ return 0;
+ }
+}
+
+static inline int getNumberOfEffectiveChannels(
+ const int
+ channelConfig) { /* index: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 */
+ const int n[] = {0, 1, 2, 3, 4, 5, 5, 7, 0, 0, 0, 6, 7, 22, 7, 0};
+ return n[channelConfig];
+}
+
+#endif /* TP_DATA_H */
diff --git a/fdk-aac/libMpegTPDec/include/tpdec_lib.h b/fdk-aac/libMpegTPDec/include/tpdec_lib.h
new file mode 100644
index 0000000..30e53c1
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/include/tpdec_lib.h
@@ -0,0 +1,664 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ Author(s): Manuel Jander
+
+ Description: MPEG Transport decoder
+
+*******************************************************************************/
+
+#ifndef TPDEC_LIB_H
+#define TPDEC_LIB_H
+
+#include "tp_data.h"
+
+#include "FDK_bitstream.h"
+
+typedef enum {
+ TRANSPORTDEC_OK = 0, /*!< All fine. */
+
+ /* Synchronization errors. Wait for new input data and try again. */
+ tpdec_sync_error_start = 0x100,
+ TRANSPORTDEC_NOT_ENOUGH_BITS, /*!< Out of bits. Provide more bits and try
+ again. */
+ TRANSPORTDEC_SYNC_ERROR, /*!< No sync was found or sync got lost. Keep trying.
+ */
+ tpdec_sync_error_end,
+
+ /* Decode errors. Mostly caused due to bit errors. */
+ tpdec_decode_error_start = 0x400,
+ TRANSPORTDEC_PARSE_ERROR, /*!< Bitstream data showed inconsistencies (wrong
+ syntax). */
+ TRANSPORTDEC_UNSUPPORTED_FORMAT, /*!< Unsupported format or feature found in
+ the bitstream data. */
+ TRANSPORTDEC_CRC_ERROR, /*!< CRC error encountered in bitstream data. */
+ tpdec_decode_error_end,
+
+ /* Fatal errors. Stop immediately on one of these errors! */
+ tpdec_fatal_error_start = 0x200,
+ TRANSPORTDEC_UNKOWN_ERROR, /*!< An unknown error occured. */
+ TRANSPORTDEC_INVALID_PARAMETER, /*!< An invalid parameter was passed to a
+ function. */
+ TRANSPORTDEC_NEED_TO_RESTART, /*!< The decoder needs to be restarted, since
+ the requiered configuration change cannot
+ be performed. */
+ TRANSPORTDEC_TOO_MANY_BITS, /*!< In case of packet based formats: Supplied
+ number of bits exceed the size of the
+ internal bit buffer. */
+ tpdec_fatal_error_end
+
+} TRANSPORTDEC_ERROR;
+
+/** Macro to identify decode errors. */
+#define TPDEC_IS_DECODE_ERROR(err) \
+ (((err >= tpdec_decode_error_start) && (err <= tpdec_decode_error_end)) ? 1 \
+ : 0)
+/** Macro to identify fatal errors. */
+#define TPDEC_IS_FATAL_ERROR(err) \
+ (((err >= tpdec_fatal_error_start) && (err <= tpdec_fatal_error_end)) ? 1 : 0)
+
+/**
+ * \brief Parameter identifiers for transportDec_SetParam()
+ */
+typedef enum {
+ TPDEC_PARAM_MINIMIZE_DELAY = 1, /** Delay minimization strategy. 0: none, 1:
+ discard as many frames as possible. */
+ TPDEC_PARAM_EARLY_CONFIG, /** Enable early config discovery. */
+ TPDEC_PARAM_IGNORE_BUFFERFULLNESS, /** Ignore buffer fullness. */
+ TPDEC_PARAM_SET_BITRATE, /** Set average bit rate for bit stream interruption
+ frame misses estimation. */
+ TPDEC_PARAM_RESET, /** Reset transport decoder instance status. */
+ TPDEC_PARAM_BURST_PERIOD, /** Set data reception burst period in mili seconds.
+ */
+ TPDEC_PARAM_TARGETLAYOUT, /** Set CICP target layout */
+ TPDEC_PARAM_FORCE_CONFIG_CHANGE, /** Force config change for next received
+ config */
+ TPDEC_PARAM_USE_ELEM_SKIPPING
+} TPDEC_PARAM;
+
+/*!
+ \brief Reset Program Config Element.
+ \param pPce Program Config Element structure.
+ \return void
+*/
+void CProgramConfig_Reset(CProgramConfig *pPce);
+
+/*!
+ \brief Initialize Program Config Element.
+ \param pPce Program Config Element structure.
+ \return void
+*/
+void CProgramConfig_Init(CProgramConfig *pPce);
+
+/*!
+ \brief Inquire state of present Program Config Element
+ structure. \param pPce Program Config Element structure. \return
+ 1 if the PCE structure is filled correct, 0 if no valid PCE present.
+*/
+int CProgramConfig_IsValid(const CProgramConfig *pPce);
+
+/*!
+ \brief Read Program Config Element.
+ \param pPce Program Config Element structure.
+ \param bs Bitstream buffer to read from.
+ \param alignAnchor Align bitstream to alignAnchor bits after all read
+ operations. \return void
+*/
+void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs,
+ UINT alignAnchor);
+
+/*!
+ \brief Compare two Program Config Elements.
+ \param pPce1 Pointer to first Program Config Element structure.
+ \param pPce2 Pointer to second Program Config Element structure.
+ \return -1 if PCEs are completely different,
+ 0 if PCEs are completely equal,
+ 1 if PCEs are different but have the same channel
+ config, 2 if PCEs have different channel config but same number of channels.
+*/
+int CProgramConfig_Compare(const CProgramConfig *const pPce1,
+ const CProgramConfig *const pPce2);
+
+/*!
+ \brief Get a Program Config Element that matches the predefined
+ MPEG-4 channel configurations 1-14. \param pPce Program Config
+ Element structure. \param channelConfig MPEG-4 channel configuration. \return
+ void
+*/
+void CProgramConfig_GetDefault(CProgramConfig *pPce, const UINT channelConfig);
+
+/**
+ * \brief Lookup and verify a given element. The decoder calls this
+ * method with every new element ID found in the bitstream.
+ *
+ * \param pPce A valid Program config structure.
+ * \param chConfig MPEG-4 channel configuration.
+ * \param tag Tag of the current element to be looked up.
+ * \param channelIdx The current channel count of the decoder parser.
+ * \param chMapping Array to store the canonical channel mapping indexes.
+ * \param chType Array to store the audio channel type.
+ * \param chIndex Array to store the individual audio channel type index.
+ * \param chDescrLen Length of the output channel description array.
+ * \param elMapping Pointer where the canonical element index is stored.
+ * \param elType The element id of the current element to be looked up.
+ *
+ * \return Non-zero if the element belongs to the current program,
+ * zero if it does not.
+ */
+int CProgramConfig_LookupElement(CProgramConfig *pPce, UINT chConfig,
+ const UINT tag, const UINT channelIdx,
+ UCHAR chMapping[], AUDIO_CHANNEL_TYPE chType[],
+ UCHAR chIndex[], const UINT chDescrLen,
+ UCHAR *elMapping, MP4_ELEMENT_ID elList[],
+ MP4_ELEMENT_ID elType);
+
+/**
+ * \brief Get table of channel indices in the order of their
+ * appearance in by the program config field.
+ * \param pPce A valid program config structure.
+ * \param pceChMap Array to store the channel mapping indices like they
+ * appear in the PCE.
+ * \param pceChMapLen Lenght of the channel mapping index array (pceChMap).
+ *
+ * \return Non-zero if any error occured otherwise zero.
+ */
+int CProgramConfig_GetPceChMap(const CProgramConfig *pPce, UCHAR pceChMap[],
+ const UINT pceChMapLen);
+
+/**
+ * \brief Get table of elements in canonical order from a
+ * give program config field.
+ * \param pPce A valid program config structure.
+ * \param table An array where the element IDs are stored.
+ * \param elListSize The length of the table array.
+ * \param pChMapIdx Pointer to a field receiving the corresponding
+ * implicit channel configuration index of the given
+ * PCE. If none can be found it receives the value 0.
+ * \return Total element count including all SCE, CPE and LFE.
+ */
+int CProgramConfig_GetElementTable(const CProgramConfig *pPce,
+ MP4_ELEMENT_ID table[], const INT elListSize,
+ UCHAR *pChMapIdx);
+
+/**
+ * \brief Get channel description (type and index) for implicit
+ configurations (chConfig > 0) in MPEG canonical order.
+ * \param chConfig MPEG-4 channel configuration.
+ * \param chType Array to store the audio channel type.
+ * \param chIndex Array to store the individual audio channel type index.
+ * \return void
+ */
+void CProgramConfig_GetChannelDescription(const UINT chConfig,
+ const CProgramConfig *pPce,
+ AUDIO_CHANNEL_TYPE chType[],
+ UCHAR chIndex[]);
+
+/**
+ * \brief Initialize a given AudioSpecificConfig structure.
+ * \param pAsc A pointer to an allocated CSAudioSpecificConfig struct.
+ * \return void
+ */
+void AudioSpecificConfig_Init(CSAudioSpecificConfig *pAsc);
+
+/**
+ * \brief Parse a AudioSpecificConfig from a given bitstream handle.
+ *
+ * \param pAsc A pointer to an allocated
+ * CSAudioSpecificConfig struct.
+ * \param hBs Bitstream handle.
+ * \param fExplicitBackwardCompatible Do explicit backward compatibility
+ * parsing if set (flag).
+ * \param cb pointer to structure holding callback information
+ * \param configMode Config modes: memory allocation mode or config change
+ * detection mode.
+ * \param configChanged Indicates a config change.
+ * \param m_aot in case of unequal AOT_NULL_OBJECT only the specific config is
+ * parsed.
+ *
+ * \return Total element count including all SCE, CPE and LFE.
+ */
+TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
+ CSAudioSpecificConfig *pAsc, HANDLE_FDK_BITSTREAM hBs,
+ int fExplicitBackwardCompatible, CSTpCallBacks *cb, UCHAR configMode,
+ UCHAR configChanged, AUDIO_OBJECT_TYPE m_aot);
+
+/* CELP stuff */
+enum { MPE = 0, RPE = 1, fs8KHz = 0, fs16KHz = 1 };
+
+/* Defintion of flags that can be passed to transportDecOpen() */
+#define TP_FLAG_MPEG4 1
+
+/* Capability flags */
+#define CAPF_TPDEC_ADIF \
+ 0x00001000 /**< Flag indicating support for ADIF transport format. */
+#define CAPF_TPDEC_ADTS \
+ 0x00002000 /**< Flag indicating support for ADTS transport format. */
+#define CAPF_TPDEC_LOAS \
+ 0x00004000 /**< Flag indicating support for LOAS transport format. */
+#define CAPF_TPDEC_LATM \
+ 0x00008000 /**< Flag indicating support for LATM transport format. */
+#define CAPF_TPDEC_RAWPACKETS \
+ 0x00010000 /**< Flag indicating support for raw packets transport format. */
+
+typedef struct TRANSPORTDEC *HANDLE_TRANSPORTDEC;
+
+/**
+ * \brief Configure Transport Decoder via a binary coded AudioSpecificConfig or
+ * StreamMuxConfig. The previously requested configuration callback will be
+ * called as well. The buffer conf must containt a SMC in case of
+ * LOAS/LATM transport format, and an ASC elseways.
+ *
+ * \param hTp Handle of a transport decoder.
+ * \param conf UCHAR buffer of the binary coded config (ASC or SMC).
+ * \param length The length in bytes of the conf buffer.
+ *
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(const HANDLE_TRANSPORTDEC hTp,
+ UCHAR *conf, const UINT length,
+ const UINT layer);
+
+/**
+ * \brief Configure Transport Decoder via a binary coded USAC/RSV603DA Config.
+ * The buffer newConfig contains a binary coded USAC/RSV603DA config of
+ * length newConfigLength bytes. If the new config and the previous config are
+ * different configChanged is set to 1 otherwise it is set to 0.
+ *
+ * \param hTp Handle of a transport decoder.
+ * \param newConfig buffer of the binary coded config.
+ * \param newConfigLength Length of new config in bytes.
+ * \param buildUpStatus Indicates build up status: off|on|idle.
+ * \param configChanged Indicates if config changed.
+ * \param layer Instance layer.
+ *
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_InBandConfig(
+ const HANDLE_TRANSPORTDEC hTp, UCHAR *newConfig, const UINT newConfigLength,
+ const UCHAR buildUpStatus, UCHAR *configChanged, const UINT layer,
+ UCHAR *implicitExplicitCfgDiff);
+
+/**
+ * \brief Open Transport medium for reading.
+ *
+ * \param transportDecFmt Format of the transport decoder medium to be accessed.
+ * \param flags Transport decoder flags. Currently only TP_FLAG_MPEG4,
+ * which signals a MPEG4 capable decoder (relevant for ADTS only).
+ *
+ * \return A pointer to a valid and allocated HANDLE_TRANSPORTDEC or a null
+ * pointer on failure.
+ */
+HANDLE_TRANSPORTDEC transportDec_Open(TRANSPORT_TYPE transportDecFmt,
+ const UINT flags, const UINT nrOfLayer);
+
+/**
+ * \brief Register configuration change callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbUpdateConfig Pointer to a callback function to handle audio config
+ * changes.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTp,
+ const cbUpdateConfig_t cbUpdateConfig,
+ void *user_data);
+
+/**
+ * \brief Register free memory callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbFreeMem Pointer to a callback function to free config dependent
+ * memory.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTp,
+ const cbFreeMem_t cbFreeMem,
+ void *user_data);
+
+/**
+ * \brief Register config change control callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbCtrlCFGChange Pointer to a callback function for config change
+ * control.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportDec_RegisterCtrlCFGChangeCallback(
+ HANDLE_TRANSPORTDEC hTp, const cbCtrlCFGChange_t cbCtrlCFGChange,
+ void *user_data);
+
+/**
+ * \brief Register SSC parser callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbUpdateConfig Pointer to a callback function to handle SSC parsing.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTp,
+ const cbSsc_t cbSscParse, void *user_data);
+
+/**
+ * \brief Register SBR header parser callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbUpdateConfig Pointer to a callback function to handle SBR header
+ * parsing.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbSbr_t cbSbr, void *user_data);
+
+/**
+ * \brief Register USAC SC parser callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbUpdateConfig Pointer to a callback function to handle USAC SC
+ * parsing.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbUsac_t cbUsac, void *user_data);
+
+/**
+ * \brief Register uniDrcConfig and loudnessInfoSet parser
+ * callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbUpdateConfig Pointer to a callback function to handle uniDrcConfig
+ * and loudnessInfoSet parsing.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbUniDrc_t cbUniDrc,
+ void *user_data,
+ UINT *pLoudnessInfoSetPosition);
+
+/**
+ * \brief Fill internal input buffer with bitstream data from the external input
+ * buffer. The function only copies such data as long as the decoder-internal
+ * input buffer is not full. So it grabs whatever it can from pBuffer and
+ * returns information (bytesValid) so that at a subsequent call of
+ * %transportDec_FillData(), the right position in pBuffer can be determined to
+ * grab the next data.
+ *
+ * \param hTp Handle of transportDec.
+ * \param pBuffer Pointer to external input buffer.
+ * \param bufferSize Size of external input buffer. This argument is required
+ * because decoder-internally we need the information to calculate the offset to
+ * pBuffer, where the next available data is, which is then
+ * fed into the decoder-internal buffer (as much as
+ * possible). Our example framework implementation fills the
+ * buffer at pBuffer again, once it contains no available valid bytes anymore
+ * (meaning bytesValid equal 0).
+ * \param bytesValid Number of bitstream bytes in the external bitstream buffer
+ * that have not yet been copied into the decoder's internal bitstream buffer by
+ * calling this function. The value is updated according to
+ * the amount of newly copied bytes.
+ * \param layer The layer the bitstream belongs to.
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
+ UCHAR *pBuffer, const UINT bufferSize,
+ UINT *pBytesValid, const INT layer);
+
+/**
+ * \brief Get transportDec bitstream handle.
+ * \param hTp Pointer to a transport decoder handle.
+ * \return HANDLE_FDK_BITSTREAM bitstream handle.
+ */
+HANDLE_FDK_BITSTREAM transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer);
+
+/**
+ * \brief Get transport format.
+ * \param hTp Pointer to a transport decoder handle.
+ * \return The transport format.
+ */
+TRANSPORT_TYPE transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp);
+
+/**
+ * \brief Get the current buffer fullness value.
+ *
+ * \param hTp Handle of a transport decoder.
+ *
+ * \return Buffer fullness
+ */
+INT transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp);
+
+/**
+ * \brief Close and deallocate transportDec.
+ * \param phTp Pointer to a previously allocated transport decoder handle.
+ * \return void
+ */
+void transportDec_Close(HANDLE_TRANSPORTDEC *phTp);
+
+/**
+ * \brief Read one access unit from the transportDec medium.
+ * \param hTp Handle of transportDec.
+ * \param length On return, this value is overwritten with the actual access
+ * unit length in bits. Set to -1 if length is unknown.
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer);
+
+/**
+ * \brief Get AudioSpecificConfig.
+ * \param hTp Handle of transportDec.
+ * \param layer Transport layer.
+ * \param asc Pointer to AudioSpecificConfig.
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer,
+ CSAudioSpecificConfig *asc);
+
+/**
+ * \brief Get the remaining amount of bits of the current access unit. The
+ * result can be below zero, meaning that too many bits have been read.
+ * \param hTp Handle of transportDec.
+ * \return amount of remaining bits.
+ */
+INT transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer);
+
+/**
+ * \brief Get the total amount of bits of the current access unit.
+ * \param hTp Handle of transportDec.
+ * \return amount of total bits.
+ */
+INT transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer);
+
+/**
+ * \brief This function is required to be called when the decoder has
+ * finished parsing one Access Unit for bitstream housekeeping.
+ * \param hTp Transport Handle.
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_EndAccessUnit(const HANDLE_TRANSPORTDEC hTp);
+
+/**
+ * \brief Obtain the amount of missing access units if applicable in case
+ * of a bit stream synchronization error. Each time
+ * transportDec_ReadAccessUnit() returns TRANSPORTDEC_SYNC_ERROR
+ * this function can be called to retrieve an estimate of the amount
+ * of missing access units. This works only in case of constant
+ * average bit rate (has to be known) and if the parameter
+ * TPDEC_PARAM_SET_BITRATE has been set accordingly.
+ * \param hTp Transport Handle.
+ * \param pNAccessUnits pointer to a memory location where the estimated lost
+ * frame count will be stored into.
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount(
+ INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp);
+
+/**
+ * \brief Set a given setting.
+ * \param hTp Transport Handle.
+ * \param param Identifier of the parameter to be changed.
+ * \param value Value for the parameter to be changed.
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,
+ const TPDEC_PARAM param,
+ const INT value);
+
+/**
+ * \brief Get number of subframes (for LATM or ADTS)
+ * \param hTp Transport Handle.
+ * \return Number of ADTS/LATM subframes (return 1 for all other transport
+ * types).
+ */
+UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp);
+
+/**
+ * \brief Get info structure of transport decoder library.
+ * \param info A pointer to an allocated LIB_INFO struct.
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info);
+
+/* ADTS CRC support */
+
+/**
+ * \brief Set current bitstream position as start of a new data region.
+ * \param hTp Transport handle.
+ * \param mBits Size in bits of the data region. Set to 0 if it should not be
+ * of a fixed size.
+ * \return Data region ID, which should be used when calling
+ * transportDec_CrcEndReg().
+ */
+int transportDec_CrcStartReg(const HANDLE_TRANSPORTDEC hTp, const INT mBits);
+
+/**
+ * \brief Set end of data region.
+ * \param hTp Transport handle.
+ * \param reg Data region ID, opbtained from transportDec_CrcStartReg().
+ * \return void
+ */
+void transportDec_CrcEndReg(const HANDLE_TRANSPORTDEC hTp, const INT reg);
+
+/**
+ * \brief Calculate ADTS crc and check if it is correct. The ADTS checksum
+ * is held internally.
+ * \param hTp Transport handle.
+ * \return Return TRANSPORTDEC_OK if the CRC is ok, or error if CRC is not
+ * correct.
+ */
+TRANSPORTDEC_ERROR transportDec_CrcCheck(const HANDLE_TRANSPORTDEC hTp);
+
+/**
+ * \brief Only check whether a given config seems to be valid without modifying
+ * internal states.
+ *
+ * \param conf UCHAR buffer of the binary coded config (SDC type 9).
+ * \param length The length in bytes of the conf buffer.
+ *
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_DrmRawSdcAudioConfig_Check(UCHAR *conf,
+ const UINT length);
+
+#endif /* #ifndef TPDEC_LIB_H */
diff --git a/fdk-aac/libMpegTPDec/src/tp_version.h b/fdk-aac/libMpegTPDec/src/tp_version.h
new file mode 100644
index 0000000..4faed8c
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/src/tp_version.h
@@ -0,0 +1,118 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#if !defined(TP_VERSION_H)
+#define TP_VERSION_H
+
+/* library info */
+#define TP_LIB_VL0 3
+#define TP_LIB_VL1 0
+#define TP_LIB_VL2 0
+#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_TIME __TIME__
+#endif
+#endif /* !defined(TP_VERSION_H) */
diff --git a/fdk-aac/libMpegTPDec/src/tpdec_adif.cpp b/fdk-aac/libMpegTPDec/src/tpdec_adif.cpp
new file mode 100644
index 0000000..ec20b9b
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/src/tpdec_adif.cpp
@@ -0,0 +1,158 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ Author(s): Josef Hoepfl
+
+ Description: ADIF reader
+
+*******************************************************************************/
+
+#include "tpdec_adif.h"
+
+#include "FDK_bitstream.h"
+#include "genericStds.h"
+
+TRANSPORTDEC_ERROR adifRead_DecodeHeader(CAdifHeader *pAdifHeader,
+ CProgramConfig *pPce,
+ HANDLE_FDK_BITSTREAM bs) {
+ int i;
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ UINT startAnchor = FDKgetValidBits(bs);
+
+ if ((INT)startAnchor < MIN_ADIF_HEADERLENGTH) {
+ return (TRANSPORTDEC_NOT_ENOUGH_BITS);
+ }
+
+ if (FDKreadBits(bs, 8) != 'A') {
+ return (TRANSPORTDEC_SYNC_ERROR);
+ }
+ if (FDKreadBits(bs, 8) != 'D') {
+ return (TRANSPORTDEC_SYNC_ERROR);
+ }
+ if (FDKreadBits(bs, 8) != 'I') {
+ return (TRANSPORTDEC_SYNC_ERROR);
+ }
+ if (FDKreadBits(bs, 8) != 'F') {
+ return (TRANSPORTDEC_SYNC_ERROR);
+ }
+
+ if ((pAdifHeader->CopyrightIdPresent = FDKreadBits(bs, 1)) != 0)
+ FDKpushBiDirectional(bs, 72); /* CopyrightId */
+
+ pAdifHeader->OriginalCopy = FDKreadBits(bs, 1);
+ pAdifHeader->Home = FDKreadBits(bs, 1);
+ pAdifHeader->BitstreamType = FDKreadBits(bs, 1);
+
+ /* pAdifHeader->BitRate = FDKreadBits(bs, 23); */
+ pAdifHeader->BitRate = FDKreadBits(bs, 16);
+ pAdifHeader->BitRate <<= 7;
+ pAdifHeader->BitRate |= FDKreadBits(bs, 7);
+
+ pAdifHeader->NumProgramConfigElements = FDKreadBits(bs, 4) + 1;
+
+ if (pAdifHeader->BitstreamType == 0) {
+ FDKpushBiDirectional(bs, 20); /* adif_buffer_fullness */
+ }
+
+ /* Parse all PCEs but keep only one */
+ for (i = 0; i < pAdifHeader->NumProgramConfigElements; i++) {
+ CProgramConfig_Read(pPce, bs, startAnchor);
+ }
+
+ FDKbyteAlign(bs, startAnchor);
+
+ return (ErrorStatus);
+}
diff --git a/fdk-aac/libMpegTPDec/src/tpdec_adif.h b/fdk-aac/libMpegTPDec/src/tpdec_adif.h
new file mode 100644
index 0000000..72ccc6a
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/src/tpdec_adif.h
@@ -0,0 +1,134 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ Author(s): Josef Hoepfl
+
+ Description: ADIF reader
+
+*******************************************************************************/
+
+#ifndef TPDEC_ADIF_H
+#define TPDEC_ADIF_H
+
+#include "tpdec_lib.h"
+
+#define MIN_ADIF_HEADERLENGTH 63 /* in bits */
+
+typedef struct {
+ INT NumProgramConfigElements;
+ UINT BitRate;
+ UCHAR CopyrightIdPresent;
+ UCHAR OriginalCopy;
+ UCHAR Home;
+ UCHAR BitstreamType;
+} CAdifHeader;
+
+/**
+ * \brief Parse a ADIF header at the given bitstream and store the parsed data
+ * into a given CAdifHeader and CProgramConfig struct
+ *
+ * \param pAdifHeader pointer to a CAdifHeader structure to hold the parsed ADIF
+ * header data.
+ * \param pPce pointer to a CProgramConfig structure where the last PCE will
+ * remain.
+ *
+ * \return TRANSPORTDEC_ERROR error code
+ */
+TRANSPORTDEC_ERROR adifRead_DecodeHeader(CAdifHeader *pAdifHeader,
+ CProgramConfig *pPce,
+ HANDLE_FDK_BITSTREAM bs);
+
+#endif /* TPDEC_ADIF_H */
diff --git a/fdk-aac/libMpegTPDec/src/tpdec_adts.cpp b/fdk-aac/libMpegTPDec/src/tpdec_adts.cpp
new file mode 100644
index 0000000..1a4e3fd
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/src/tpdec_adts.cpp
@@ -0,0 +1,392 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ Author(s): Josef Hoepfl
+
+ Description: ADTS interface
+
+*******************************************************************************/
+
+#include "tpdec_adts.h"
+
+#include "FDK_bitstream.h"
+
+void adtsRead_CrcInit(
+ HANDLE_ADTS pAdts) /*!< pointer to adts crc info stucture */
+{
+ FDKcrcInit(&pAdts->crcInfo, 0x8005, 0xFFFF, 16);
+}
+
+int adtsRead_CrcStartReg(
+ HANDLE_ADTS pAdts, /*!< pointer to adts stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int mBits /*!< number of bits in crc region */
+) {
+ if (pAdts->bs.protection_absent) {
+ return 0;
+ }
+
+ return (FDKcrcStartReg(&pAdts->crcInfo, hBs, mBits));
+}
+
+void adtsRead_CrcEndReg(
+ HANDLE_ADTS pAdts, /*!< pointer to adts crc info stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int reg /*!< crc region */
+) {
+ if (pAdts->bs.protection_absent == 0) {
+ FDKcrcEndReg(&pAdts->crcInfo, hBs, reg);
+ }
+}
+
+TRANSPORTDEC_ERROR adtsRead_CrcCheck(HANDLE_ADTS pAdts) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ USHORT crc;
+
+ if (pAdts->bs.protection_absent) return TRANSPORTDEC_OK;
+
+ crc = FDKcrcGetCRC(&pAdts->crcInfo);
+ if (crc != pAdts->crcReadValue) {
+ return (TRANSPORTDEC_CRC_ERROR);
+ }
+
+ return (ErrorStatus);
+}
+
+#define Adts_Length_SyncWord 12
+#define Adts_Length_Id 1
+#define Adts_Length_Layer 2
+#define Adts_Length_ProtectionAbsent 1
+#define Adts_Length_Profile 2
+#define Adts_Length_SamplingFrequencyIndex 4
+#define Adts_Length_PrivateBit 1
+#define Adts_Length_ChannelConfiguration 3
+#define Adts_Length_OriginalCopy 1
+#define Adts_Length_Home 1
+#define Adts_Length_CopyrightIdentificationBit 1
+#define Adts_Length_CopyrightIdentificationStart 1
+#define Adts_Length_FrameLength 13
+#define Adts_Length_BufferFullness 11
+#define Adts_Length_NumberOfRawDataBlocksInFrame 2
+#define Adts_Length_CrcCheck 16
+
+TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts,
+ CSAudioSpecificConfig *pAsc,
+ HANDLE_FDK_BITSTREAM hBs,
+ const INT ignoreBufferFullness) {
+ INT crcReg;
+
+ INT valBits;
+ INT cmp_buffer_fullness;
+ int i, adtsHeaderLength;
+
+ STRUCT_ADTS_BS bs;
+
+ CProgramConfig oldPce;
+ /* Store the old PCE temporarily. Maybe we'll need it later if we
+ have channelConfig=0 and no PCE in this frame. */
+ FDKmemcpy(&oldPce, &pAsc->m_progrConfigElement, sizeof(CProgramConfig));
+
+ valBits = FDKgetValidBits(hBs) + ADTS_SYNCLENGTH;
+
+ if (valBits < ADTS_HEADERLENGTH) {
+ return TRANSPORTDEC_NOT_ENOUGH_BITS;
+ }
+
+ /* adts_fixed_header */
+ bs.mpeg_id = FDKreadBits(hBs, Adts_Length_Id);
+ bs.layer = FDKreadBits(hBs, Adts_Length_Layer);
+ bs.protection_absent = FDKreadBits(hBs, Adts_Length_ProtectionAbsent);
+ bs.profile = FDKreadBits(hBs, Adts_Length_Profile);
+ bs.sample_freq_index = FDKreadBits(hBs, Adts_Length_SamplingFrequencyIndex);
+ bs.private_bit = FDKreadBits(hBs, Adts_Length_PrivateBit);
+ bs.channel_config = FDKreadBits(hBs, Adts_Length_ChannelConfiguration);
+ bs.original = FDKreadBits(hBs, Adts_Length_OriginalCopy);
+ bs.home = FDKreadBits(hBs, Adts_Length_Home);
+
+ /* adts_variable_header */
+ bs.copyright_id = FDKreadBits(hBs, Adts_Length_CopyrightIdentificationBit);
+ bs.copyright_start =
+ FDKreadBits(hBs, Adts_Length_CopyrightIdentificationStart);
+ bs.frame_length = FDKreadBits(hBs, Adts_Length_FrameLength);
+ bs.adts_fullness = FDKreadBits(hBs, Adts_Length_BufferFullness);
+ bs.num_raw_blocks =
+ FDKreadBits(hBs, Adts_Length_NumberOfRawDataBlocksInFrame);
+ bs.num_pce_bits = 0;
+
+ adtsHeaderLength = ADTS_HEADERLENGTH;
+
+ if (valBits < bs.frame_length * 8) {
+ goto bail;
+ }
+
+ if (!bs.protection_absent) {
+ FDKcrcReset(&pAdts->crcInfo);
+ FDKpushBack(hBs, 56); /* complete fixed and variable header! */
+ crcReg = FDKcrcStartReg(&pAdts->crcInfo, hBs, 0);
+ FDKpushFor(hBs, 56);
+ }
+
+ if (!bs.protection_absent && bs.num_raw_blocks > 0) {
+ if ((INT)FDKgetValidBits(hBs) < bs.num_raw_blocks * 16) {
+ goto bail;
+ }
+ for (i = 0; i < bs.num_raw_blocks; i++) {
+ pAdts->rawDataBlockDist[i] = (USHORT)FDKreadBits(hBs, 16);
+ adtsHeaderLength += 16;
+ }
+ /* Change raw data blocks to delta values */
+ pAdts->rawDataBlockDist[bs.num_raw_blocks] =
+ bs.frame_length - 7 - bs.num_raw_blocks * 2 - 2;
+ for (i = bs.num_raw_blocks; i > 0; i--) {
+ pAdts->rawDataBlockDist[i] -= pAdts->rawDataBlockDist[i - 1];
+ }
+ }
+
+ /* adts_error_check */
+ if (!bs.protection_absent) {
+ USHORT crc_check;
+
+ FDKcrcEndReg(&pAdts->crcInfo, hBs, crcReg);
+
+ if ((INT)FDKgetValidBits(hBs) < Adts_Length_CrcCheck) {
+ goto bail;
+ }
+
+ crc_check = FDKreadBits(hBs, Adts_Length_CrcCheck);
+ adtsHeaderLength += Adts_Length_CrcCheck;
+
+ pAdts->crcReadValue = crc_check;
+ /* Check header CRC in case of multiple raw data blocks */
+ if (bs.num_raw_blocks > 0) {
+ if (pAdts->crcReadValue != FDKcrcGetCRC(&pAdts->crcInfo)) {
+ return TRANSPORTDEC_CRC_ERROR;
+ }
+ /* Reset CRC for the upcoming raw_data_block() */
+ FDKcrcReset(&pAdts->crcInfo);
+ }
+ }
+
+ /* check if valid header */
+ if ((bs.layer != 0) || // we only support MPEG ADTS
+ (bs.sample_freq_index >= 13) // we only support 96kHz - 7350kHz
+ ) {
+ FDKpushFor(hBs, bs.frame_length * 8); // try again one frame later
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+
+ /* special treatment of id-bit */
+ if ((bs.mpeg_id == 0) && (pAdts->decoderCanDoMpeg4 == 0)) {
+ /* MPEG-2 decoder cannot play MPEG-4 bitstreams */
+
+ FDKpushFor(hBs, bs.frame_length * 8); // try again one frame later
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+
+ if (!ignoreBufferFullness) {
+ cmp_buffer_fullness =
+ bs.frame_length * 8 +
+ bs.adts_fullness * 32 * getNumberOfEffectiveChannels(bs.channel_config);
+
+ /* Evaluate buffer fullness */
+ if (bs.adts_fullness != 0x7FF) {
+ if (pAdts->BufferFullnesStartFlag) {
+ if (valBits < cmp_buffer_fullness) {
+ /* Condition for start of decoding is not fulfilled */
+
+ /* The current frame will not be decoded */
+ FDKpushBack(hBs, adtsHeaderLength);
+
+ if ((cmp_buffer_fullness + adtsHeaderLength) >
+ (((8192 * 4) << 3) - 7)) {
+ return TRANSPORTDEC_SYNC_ERROR;
+ } else {
+ return TRANSPORTDEC_NOT_ENOUGH_BITS;
+ }
+ } else {
+ pAdts->BufferFullnesStartFlag = 0;
+ }
+ }
+ }
+ }
+
+ /* Get info from ADTS header */
+ AudioSpecificConfig_Init(pAsc);
+ pAsc->m_aot = (AUDIO_OBJECT_TYPE)(bs.profile + 1);
+ pAsc->m_samplingFrequencyIndex = bs.sample_freq_index;
+ pAsc->m_samplingFrequency = SamplingRateTable[bs.sample_freq_index];
+ pAsc->m_channelConfiguration = bs.channel_config;
+ pAsc->m_samplesPerFrame = 1024;
+
+ if (bs.channel_config == 0) {
+ int pceBits = 0;
+ UINT alignAnchor = FDKgetValidBits(hBs);
+
+ if (FDKreadBits(hBs, 3) == ID_PCE) {
+ /* Got luck! Parse the PCE */
+ crcReg = adtsRead_CrcStartReg(pAdts, hBs, 0);
+
+ CProgramConfig_Read(&pAsc->m_progrConfigElement, hBs, alignAnchor);
+
+ adtsRead_CrcEndReg(pAdts, hBs, crcReg);
+ pceBits = alignAnchor - FDKgetValidBits(hBs);
+ /* store the number of PCE bits */
+ bs.num_pce_bits = pceBits;
+ } else {
+ /* No PCE in this frame! Push back the ID tag bits. */
+ FDKpushBack(hBs, 3);
+
+ /* Encoders do not have to write a PCE in each frame.
+ So if we already have a valid PCE we have to use it. */
+ if (oldPce.isValid &&
+ (bs.sample_freq_index ==
+ pAdts->bs.sample_freq_index) /* we could compare the complete fixed
+ header (bytes) here! */
+ && (bs.channel_config == pAdts->bs.channel_config) /* == 0 */
+ &&
+ (bs.mpeg_id ==
+ pAdts->bs.mpeg_id)) { /* Restore previous PCE which is still valid */
+ FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce, sizeof(CProgramConfig));
+ } else if (bs.mpeg_id == 0) {
+ /* If not it seems that we have a implicit channel configuration.
+ This mode is not allowed in the context of ISO/IEC 14496-3.
+ Skip this frame and try the next one. */
+ FDKpushFor(hBs, (bs.frame_length << 3) - adtsHeaderLength - 3);
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ /* else {
+ ISO/IEC 13818-7 implicit channel mapping is allowed.
+ So just open the box of chocolates to see what we got.
+ } */
+ }
+ }
+
+ /* Copy bit stream data struct to persistent memory now, once we passed all
+ * sanity checks above. */
+ FDKmemcpy(&pAdts->bs, &bs, sizeof(STRUCT_ADTS_BS));
+
+ return TRANSPORTDEC_OK;
+
+bail:
+ FDKpushBack(hBs, adtsHeaderLength);
+ return TRANSPORTDEC_NOT_ENOUGH_BITS;
+}
+
+int adtsRead_GetRawDataBlockLength(HANDLE_ADTS pAdts, INT blockNum) {
+ int length;
+
+ if (pAdts->bs.num_raw_blocks == 0) {
+ length =
+ (pAdts->bs.frame_length - 7)
+ << 3; /* aac_frame_length subtracted by the header size (7 bytes). */
+ if (pAdts->bs.protection_absent == 0)
+ length -= 16; /* substract 16 bit CRC */
+ } else {
+ if (pAdts->bs.protection_absent) {
+ length = -1; /* raw data block length is unknown */
+ } else {
+ if (blockNum < 0 || blockNum > 3) {
+ length = -1;
+ } else {
+ length = (pAdts->rawDataBlockDist[blockNum] << 3) - 16;
+ }
+ }
+ }
+ if (blockNum == 0 && length > 0) {
+ length -= pAdts->bs.num_pce_bits;
+ }
+ return length;
+}
diff --git a/fdk-aac/libMpegTPDec/src/tpdec_adts.h b/fdk-aac/libMpegTPDec/src/tpdec_adts.h
new file mode 100644
index 0000000..68f3f63
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/src/tpdec_adts.h
@@ -0,0 +1,234 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ Author(s): Josef Hoepfl
+
+ Description: ADTS interface
+
+*******************************************************************************/
+
+#ifndef TPDEC_ADTS_H
+#define TPDEC_ADTS_H
+
+#include "tpdec_lib.h"
+
+#define ADTS_SYNCWORD (0xfff)
+#define ADTS_SYNCLENGTH (12) /* in bits */
+#define ADTS_HEADERLENGTH (56) /* minimum header size in bits */
+#define ADTS_FIXED_HEADERLENGTH (28) /* in bits */
+#define ADTS_VARIABLE_HEADERLENGTH (ADTS_HEADERLENGTH - ADTS_FIXED_HEADERLENGTH)
+
+#ifdef CHECK_TWO_SYNCS
+#define ADTS_MIN_TP_BUF_SIZE (8191 + 2)
+#else
+#define ADTS_MIN_TP_BUF_SIZE (8191)
+#endif
+
+#include "FDK_crc.h"
+
+typedef struct {
+ /* ADTS header fields */
+ UCHAR mpeg_id;
+ UCHAR layer;
+ UCHAR protection_absent;
+ UCHAR profile;
+ UCHAR sample_freq_index;
+ UCHAR private_bit;
+ UCHAR channel_config;
+ UCHAR original;
+ UCHAR home;
+ UCHAR copyright_id;
+ UCHAR copyright_start;
+ USHORT frame_length;
+ USHORT adts_fullness;
+ UCHAR num_raw_blocks;
+ UCHAR num_pce_bits;
+} STRUCT_ADTS_BS;
+
+struct STRUCT_ADTS {
+ STRUCT_ADTS_BS bs;
+
+ UCHAR decoderCanDoMpeg4;
+ UCHAR BufferFullnesStartFlag;
+
+ FDK_CRCINFO crcInfo; /* CRC state info */
+ USHORT crcReadValue; /* CRC value read from bitstream data */
+ USHORT rawDataBlockDist[4]; /* distance between each raw data block. Not the
+ same as found in the bitstream */
+};
+
+typedef struct STRUCT_ADTS *HANDLE_ADTS;
+
+/*!
+ \brief Initialize ADTS CRC
+
+ The function initialzes the crc buffer and the crc lookup table.
+
+ \return none
+*/
+void adtsRead_CrcInit(HANDLE_ADTS pAdts);
+
+/**
+ * \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 pAdts ADTS 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 adtsRead_CrcStartReg(HANDLE_ADTS pAdts, HANDLE_FDK_BITSTREAM hBs,
+ int mBits);
+
+/**
+ * \brief Ends CRC region identified by reg
+ *
+ * \param pAdts ADTS data handle
+ * \param hBs bitstream handle, on which the CRC region referes to
+ * \param reg CRC regions ID returned by adtsRead_CrcStartReg()
+ *
+ * \return none
+ */
+void adtsRead_CrcEndReg(HANDLE_ADTS pAdts, 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 pAdts ADTS data handle
+ *
+ * \return Returns 0 if they are identical otherwise 1
+ */
+TRANSPORTDEC_ERROR adtsRead_CrcCheck(HANDLE_ADTS pAdts);
+
+/**
+ * \brief Check if we have a valid ADTS 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 pAdts ADTS data handle which is filled with parsed ADTS header data
+ * \param bs handle of bitstream from whom the ADTS header is read
+ *
+ * \return error status
+ */
+TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts,
+ CSAudioSpecificConfig *pAsc,
+ HANDLE_FDK_BITSTREAM bs,
+ const INT ignoreBufferFullness);
+
+/**
+ * \brief Get the raw data block length of the given block number.
+ *
+ * \param pAdts ADTS data handle
+ * \param blockNum current raw data block index
+ * \param pLength pointer to an INT where the length of the given raw data block
+ * is stored into the returned value might be -1, in which case the raw data
+ * block length is unknown.
+ *
+ * \return error status
+ */
+int adtsRead_GetRawDataBlockLength(HANDLE_ADTS pAdts, INT blockNum);
+
+#endif /* TPDEC_ADTS_H */
diff --git a/fdk-aac/libMpegTPDec/src/tpdec_asc.cpp b/fdk-aac/libMpegTPDec/src/tpdec_asc.cpp
new file mode 100644
index 0000000..28bc22d
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/src/tpdec_asc.cpp
@@ -0,0 +1,2592 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ Author(s): Daniel Homm
+
+ Description:
+
+*******************************************************************************/
+
+#include "tpdec_lib.h"
+#include "tp_data.h"
+
+#include "FDK_crc.h"
+
+#include "common_fix.h"
+
+/**
+ * The following arrays provide the IDs of the consecutive elements for each
+ * channel configuration. Every channel_configuration has to be finalized with
+ * ID_NONE.
+ */
+static const MP4_ELEMENT_ID channel_configuration_0[] = {ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_1[] = {ID_SCE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_2[] = {ID_CPE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_3[] = {ID_SCE, ID_CPE,
+ ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_4[] = {ID_SCE, ID_CPE, ID_SCE,
+ ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_5[] = {ID_SCE, ID_CPE, ID_CPE,
+ ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_6[] = {ID_SCE, ID_CPE, ID_CPE,
+ ID_LFE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_7[] = {
+ ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_8[] = {
+ ID_NONE}; /* reserved */
+static const MP4_ELEMENT_ID channel_configuration_9[] = {
+ ID_NONE}; /* reserved */
+static const MP4_ELEMENT_ID channel_configuration_10[] = {
+ ID_NONE}; /* reserved */
+static const MP4_ELEMENT_ID channel_configuration_11[] = {
+ ID_SCE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_12[] = {
+ ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_13[] = {
+ ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_LFE, ID_SCE,
+ ID_CPE, ID_CPE, ID_SCE, ID_CPE, ID_SCE, ID_SCE, ID_CPE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_14[] = {
+ ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_CPE, ID_NONE};
+
+static const MP4_ELEMENT_ID *channel_configuration_array[] = {
+ channel_configuration_0, channel_configuration_1,
+ channel_configuration_2, channel_configuration_3,
+ channel_configuration_4, channel_configuration_5,
+ channel_configuration_6, channel_configuration_7,
+ channel_configuration_8, channel_configuration_9,
+ channel_configuration_10, channel_configuration_11,
+ channel_configuration_12, channel_configuration_13,
+ channel_configuration_14};
+
+#define TP_USAC_MAX_CHANNEL_CONFIGURATION_INDEX (13)
+#define SC_CHANNEL_CONFIG_TAB_SIZE (TP_USAC_MAX_CHANNEL_CONFIGURATION_INDEX + 1)
+
+/* channel config structure used for sanity check */
+typedef struct {
+ SCHAR nCh; /* number of channels */
+ SCHAR nSCE; /* number of SCE's */
+ SCHAR nCPE; /* number of CPE's */
+ SCHAR nLFE; /* number of LFE's */
+} SC_CHANNEL_CONFIG;
+
+static const SC_CHANNEL_CONFIG sc_chan_config_tab[SC_CHANNEL_CONFIG_TAB_SIZE] =
+ {
+ /* nCh, nSCE, nCPE, nLFE, cci */
+ {0, 0, 0, 0}, /* 0 */
+ {1, 1, 0, 0}, /* 1 */
+ {2, 0, 1, 0}, /* 2 */
+ {3, 1, 1, 0}, /* 3 */
+ {4, 2, 1, 0}, /* 4 */
+ {5, 1, 2, 0}, /* 5 */
+ {6, 1, 2, 1}, /* 6 */
+ {8, 1, 3, 1}, /* 7 */
+ {2, 2, 0, 0}, /* 8 */
+ {3, 1, 1, 0}, /* 9 */
+ {4, 0, 2, 0}, /* 10 */
+ {7, 2, 2, 1}, /* 11 */
+ {8, 1, 3, 1}, /* 12 */
+ {24, 6, 8, 2} /* 13 */
+};
+
+void CProgramConfig_Reset(CProgramConfig *pPce) { pPce->elCounter = 0; }
+
+void CProgramConfig_Init(CProgramConfig *pPce) {
+ FDKmemclear(pPce, sizeof(CProgramConfig));
+ pPce->SamplingFrequencyIndex = 0xf;
+}
+
+int CProgramConfig_IsValid(const CProgramConfig *pPce) {
+ return ((pPce->isValid) ? 1 : 0);
+}
+
+#define PCE_HEIGHT_EXT_SYNC (0xAC)
+
+/*
+ * Read the extension for height info.
+ * return 0 if successfull,
+ * -1 if the CRC failed,
+ * -2 if invalid HeightInfo.
+ */
+static int CProgramConfig_ReadHeightExt(CProgramConfig *pPce,
+ HANDLE_FDK_BITSTREAM bs,
+ int *const bytesAvailable,
+ const UINT alignmentAnchor) {
+ int err = 0;
+ FDK_CRCINFO crcInfo; /* CRC state info */
+ INT crcReg;
+ FDKcrcInit(&crcInfo, 0x07, 0xFF, 8);
+ crcReg = FDKcrcStartReg(&crcInfo, bs, 0);
+ UINT startAnchor = FDKgetValidBits(bs);
+
+ FDK_ASSERT(pPce != NULL);
+ FDK_ASSERT(bs != NULL);
+ FDK_ASSERT(bytesAvailable != NULL);
+
+ if ((startAnchor >= 24) && (*bytesAvailable >= 3) &&
+ (FDKreadBits(bs, 8) == PCE_HEIGHT_EXT_SYNC)) {
+ int i;
+
+ for (i = 0; i < pPce->NumFrontChannelElements; i++) {
+ if ((pPce->FrontElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
+ PC_NUM_HEIGHT_LAYER) {
+ err = -2; /* height information is out of the valid range */
+ }
+ }
+ for (i = 0; i < pPce->NumSideChannelElements; i++) {
+ if ((pPce->SideElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
+ PC_NUM_HEIGHT_LAYER) {
+ err = -2; /* height information is out of the valid range */
+ }
+ }
+ for (i = 0; i < pPce->NumBackChannelElements; i++) {
+ if ((pPce->BackElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
+ PC_NUM_HEIGHT_LAYER) {
+ err = -2; /* height information is out of the valid range */
+ }
+ }
+ FDKbyteAlign(bs, alignmentAnchor);
+
+ FDKcrcEndReg(&crcInfo, bs, crcReg);
+ if ((USHORT)FDKreadBits(bs, 8) != FDKcrcGetCRC(&crcInfo)) {
+ /* CRC failed */
+ err = -1;
+ }
+ if (err != 0) {
+ /* Reset whole height information in case an error occured during parsing.
+ The return value ensures that pPce->isValid is set to 0 and implicit
+ channel mapping is used. */
+ FDKmemclear(pPce->FrontElementHeightInfo,
+ sizeof(pPce->FrontElementHeightInfo));
+ FDKmemclear(pPce->SideElementHeightInfo,
+ sizeof(pPce->SideElementHeightInfo));
+ FDKmemclear(pPce->BackElementHeightInfo,
+ sizeof(pPce->BackElementHeightInfo));
+ }
+ } else {
+ /* No valid extension data found -> restore the initial bitbuffer state */
+ FDKpushBack(bs, (INT)startAnchor - (INT)FDKgetValidBits(bs));
+ }
+
+ /* Always report the bytes read. */
+ *bytesAvailable -= ((INT)startAnchor - (INT)FDKgetValidBits(bs)) >> 3;
+
+ return (err);
+}
+
+void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs,
+ UINT alignmentAnchor) {
+ int i, err = 0;
+ int commentBytes;
+
+ pPce->NumEffectiveChannels = 0;
+ pPce->NumChannels = 0;
+ pPce->ElementInstanceTag = (UCHAR)FDKreadBits(bs, 4);
+ pPce->Profile = (UCHAR)FDKreadBits(bs, 2);
+ pPce->SamplingFrequencyIndex = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumFrontChannelElements = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumSideChannelElements = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumBackChannelElements = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumLfeChannelElements = (UCHAR)FDKreadBits(bs, 2);
+ pPce->NumAssocDataElements = (UCHAR)FDKreadBits(bs, 3);
+ pPce->NumValidCcElements = (UCHAR)FDKreadBits(bs, 4);
+
+ if ((pPce->MonoMixdownPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
+ pPce->MonoMixdownElementNumber = (UCHAR)FDKreadBits(bs, 4);
+ }
+
+ if ((pPce->StereoMixdownPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
+ pPce->StereoMixdownElementNumber = (UCHAR)FDKreadBits(bs, 4);
+ }
+
+ if ((pPce->MatrixMixdownIndexPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
+ pPce->MatrixMixdownIndex = (UCHAR)FDKreadBits(bs, 2);
+ pPce->PseudoSurroundEnable = (UCHAR)FDKreadBits(bs, 1);
+ }
+
+ for (i = 0; i < pPce->NumFrontChannelElements; i++) {
+ pPce->FrontElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1);
+ pPce->FrontElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumChannels += pPce->FrontElementIsCpe[i] ? 2 : 1;
+ }
+
+ for (i = 0; i < pPce->NumSideChannelElements; i++) {
+ pPce->SideElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1);
+ pPce->SideElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumChannels += pPce->SideElementIsCpe[i] ? 2 : 1;
+ }
+
+ for (i = 0; i < pPce->NumBackChannelElements; i++) {
+ pPce->BackElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1);
+ pPce->BackElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumChannels += pPce->BackElementIsCpe[i] ? 2 : 1;
+ }
+
+ pPce->NumEffectiveChannels = pPce->NumChannels;
+
+ for (i = 0; i < pPce->NumLfeChannelElements; i++) {
+ pPce->LfeElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumChannels += 1;
+ }
+
+ for (i = 0; i < pPce->NumAssocDataElements; i++) {
+ pPce->AssocDataElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
+ }
+
+ for (i = 0; i < pPce->NumValidCcElements; i++) {
+ pPce->CcElementIsIndSw[i] = (UCHAR)FDKreadBits(bs, 1);
+ pPce->ValidCcElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
+ }
+
+ FDKbyteAlign(bs, alignmentAnchor);
+
+ pPce->CommentFieldBytes = (UCHAR)FDKreadBits(bs, 8);
+ commentBytes = pPce->CommentFieldBytes;
+
+ /* Search for height info extension and read it if available */
+ err = CProgramConfig_ReadHeightExt(pPce, bs, &commentBytes, alignmentAnchor);
+
+ for (i = 0; i < commentBytes; i++) {
+ UCHAR text;
+
+ text = (UCHAR)FDKreadBits(bs, 8);
+
+ if (i < PC_COMMENTLENGTH) {
+ pPce->Comment[i] = text;
+ }
+ }
+
+ pPce->isValid = (err) ? 0 : 1;
+}
+
+/*
+ * Compare two program configurations.
+ * Returns the result of the comparison:
+ * -1 - completely different
+ * 0 - completely equal
+ * 1 - different but same channel configuration
+ * 2 - different channel configuration but same number of channels
+ */
+int CProgramConfig_Compare(const CProgramConfig *const pPce1,
+ const CProgramConfig *const pPce2) {
+ int result = 0; /* Innocent until proven false. */
+
+ if (FDKmemcmp(pPce1, pPce2, sizeof(CProgramConfig)) !=
+ 0) { /* Configurations are not completely equal.
+ So look into details and analyse the channel configurations: */
+ result = -1;
+
+ if (pPce1->NumChannels ==
+ pPce2->NumChannels) { /* Now the logic changes. We first assume to have
+ the same channel configuration and then prove
+ if this assumption is true. */
+ result = 1;
+
+ /* Front channels */
+ if (pPce1->NumFrontChannelElements != pPce2->NumFrontChannelElements) {
+ result = 2; /* different number of front channel elements */
+ } else {
+ int el, numCh1 = 0, numCh2 = 0;
+ for (el = 0; el < pPce1->NumFrontChannelElements; el += 1) {
+ if (pPce1->FrontElementHeightInfo[el] !=
+ pPce2->FrontElementHeightInfo[el]) {
+ result = 2; /* different height info */
+ break;
+ }
+ numCh1 += pPce1->FrontElementIsCpe[el] ? 2 : 1;
+ numCh2 += pPce2->FrontElementIsCpe[el] ? 2 : 1;
+ }
+ if (numCh1 != numCh2) {
+ result = 2; /* different number of front channels */
+ }
+ }
+ /* Side channels */
+ if (pPce1->NumSideChannelElements != pPce2->NumSideChannelElements) {
+ result = 2; /* different number of side channel elements */
+ } else {
+ int el, numCh1 = 0, numCh2 = 0;
+ for (el = 0; el < pPce1->NumSideChannelElements; el += 1) {
+ if (pPce1->SideElementHeightInfo[el] !=
+ pPce2->SideElementHeightInfo[el]) {
+ result = 2; /* different height info */
+ break;
+ }
+ numCh1 += pPce1->SideElementIsCpe[el] ? 2 : 1;
+ numCh2 += pPce2->SideElementIsCpe[el] ? 2 : 1;
+ }
+ if (numCh1 != numCh2) {
+ result = 2; /* different number of side channels */
+ }
+ }
+ /* Back channels */
+ if (pPce1->NumBackChannelElements != pPce2->NumBackChannelElements) {
+ result = 2; /* different number of back channel elements */
+ } else {
+ int el, numCh1 = 0, numCh2 = 0;
+ for (el = 0; el < pPce1->NumBackChannelElements; el += 1) {
+ if (pPce1->BackElementHeightInfo[el] !=
+ pPce2->BackElementHeightInfo[el]) {
+ result = 2; /* different height info */
+ break;
+ }
+ numCh1 += pPce1->BackElementIsCpe[el] ? 2 : 1;
+ numCh2 += pPce2->BackElementIsCpe[el] ? 2 : 1;
+ }
+ if (numCh1 != numCh2) {
+ result = 2; /* different number of back channels */
+ }
+ }
+ /* LFE channels */
+ if (pPce1->NumLfeChannelElements != pPce2->NumLfeChannelElements) {
+ result = 2; /* different number of lfe channels */
+ }
+ /* LFEs are always SCEs so we don't need to count the channels. */
+ }
+ }
+
+ return result;
+}
+
+void CProgramConfig_GetDefault(CProgramConfig *pPce, const UINT channelConfig) {
+ FDK_ASSERT(pPce != NULL);
+
+ /* Init PCE */
+ CProgramConfig_Init(pPce);
+ pPce->Profile =
+ 1; /* Set AAC LC because it is the only supported object type. */
+
+ switch (channelConfig) {
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ case 32: /* 7.1 side channel configuration as defined in FDK_audio.h */
+ pPce->NumFrontChannelElements = 2;
+ pPce->FrontElementIsCpe[0] = 0;
+ pPce->FrontElementIsCpe[1] = 1;
+ pPce->NumSideChannelElements = 1;
+ pPce->SideElementIsCpe[0] = 1;
+ pPce->NumBackChannelElements = 1;
+ pPce->BackElementIsCpe[0] = 1;
+ pPce->NumLfeChannelElements = 1;
+ pPce->NumChannels = 8;
+ pPce->NumEffectiveChannels = 7;
+ pPce->isValid = 1;
+ break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ case 12: /* 3/0/4.1ch surround back */
+ pPce->BackElementIsCpe[1] = 1;
+ pPce->NumChannels += 1;
+ pPce->NumEffectiveChannels += 1;
+ FDK_FALLTHROUGH;
+ case 11: /* 3/0/3.1ch */
+ pPce->NumFrontChannelElements += 2;
+ pPce->FrontElementIsCpe[0] = 0;
+ pPce->FrontElementIsCpe[1] = 1;
+ pPce->NumBackChannelElements += 2;
+ pPce->BackElementIsCpe[0] = 1;
+ pPce->BackElementIsCpe[1] += 0;
+ pPce->NumLfeChannelElements += 1;
+ pPce->NumChannels += 7;
+ pPce->NumEffectiveChannels += 6;
+ pPce->isValid = 1;
+ break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ case 14: /* 2/0/0-3/0/2-0.1ch front height */
+ pPce->FrontElementHeightInfo[2] = 1; /* Top speaker */
+ FDK_FALLTHROUGH;
+ case 7: /* 5/0/2.1ch front */
+ pPce->NumFrontChannelElements += 1;
+ pPce->FrontElementIsCpe[2] = 1;
+ pPce->NumChannels += 2;
+ pPce->NumEffectiveChannels += 2;
+ FDK_FALLTHROUGH;
+ case 6: /* 3/0/2.1ch */
+ pPce->NumLfeChannelElements += 1;
+ pPce->NumChannels += 1;
+ FDK_FALLTHROUGH;
+ case 5: /* 3/0/2.0ch */
+ case 4: /* 3/0/1.0ch */
+ pPce->NumBackChannelElements += 1;
+ pPce->BackElementIsCpe[0] = (channelConfig > 4) ? 1 : 0;
+ pPce->NumChannels += (channelConfig > 4) ? 2 : 1;
+ pPce->NumEffectiveChannels += (channelConfig > 4) ? 2 : 1;
+ FDK_FALLTHROUGH;
+ case 3: /* 3/0/0.0ch */
+ pPce->NumFrontChannelElements += 1;
+ pPce->FrontElementIsCpe[1] = 1;
+ pPce->NumChannels += 2;
+ pPce->NumEffectiveChannels += 2;
+ FDK_FALLTHROUGH;
+ case 1: /* 1/0/0.0ch */
+ pPce->NumFrontChannelElements += 1;
+ pPce->FrontElementIsCpe[0] = 0;
+ pPce->NumChannels += 1;
+ pPce->NumEffectiveChannels += 1;
+ pPce->isValid = 1;
+ break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ case 2: /* 2/0/0.ch */
+ pPce->NumFrontChannelElements = 1;
+ pPce->FrontElementIsCpe[0] = 1;
+ pPce->NumChannels += 2;
+ pPce->NumEffectiveChannels += 2;
+ pPce->isValid = 1;
+ break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ default:
+ pPce->isValid = 0; /* To be explicit! */
+ break;
+ }
+
+ if (pPce->isValid) {
+ /* Create valid element instance tags */
+ int el, elTagSce = 0, elTagCpe = 0;
+
+ for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
+ pPce->FrontElementTagSelect[el] =
+ (pPce->FrontElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
+ }
+ for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
+ pPce->SideElementTagSelect[el] =
+ (pPce->SideElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
+ }
+ for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
+ pPce->BackElementTagSelect[el] =
+ (pPce->BackElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
+ }
+ elTagSce = 0;
+ for (el = 0; el < pPce->NumLfeChannelElements; el += 1) {
+ pPce->LfeElementTagSelect[el] = elTagSce++;
+ }
+ }
+}
+
+/**
+ * \brief get implicit audio channel type for given channelConfig and MPEG
+ * ordered channel index
+ * \param channelConfig MPEG channelConfiguration from 1 upto 14
+ * \param index MPEG channel order index
+ * \return audio channel type.
+ */
+static void getImplicitAudioChannelTypeAndIndex(AUDIO_CHANNEL_TYPE *chType,
+ UCHAR *chIndex,
+ UINT channelConfig,
+ UINT index) {
+ if (index < 3) {
+ *chType = ACT_FRONT;
+ *chIndex = index;
+ } else {
+ switch (channelConfig) {
+ case 4: /* SCE, CPE, SCE */
+ case 5: /* SCE, CPE, CPE */
+ case 6: /* SCE, CPE, CPE, LFE */
+ switch (index) {
+ case 3:
+ case 4:
+ *chType = ACT_BACK;
+ *chIndex = index - 3;
+ break;
+ case 5:
+ *chType = ACT_LFE;
+ *chIndex = 0;
+ break;
+ }
+ break;
+ case 7: /* SCE,CPE,CPE,CPE,LFE */
+ switch (index) {
+ case 3:
+ case 4:
+ *chType = ACT_FRONT;
+ *chIndex = index;
+ break;
+ case 5:
+ case 6:
+ *chType = ACT_BACK;
+ *chIndex = index - 5;
+ break;
+ case 7:
+ *chType = ACT_LFE;
+ *chIndex = 0;
+ break;
+ }
+ break;
+ case 11: /* SCE,CPE,CPE,SCE,LFE */
+ if (index < 6) {
+ *chType = ACT_BACK;
+ *chIndex = index - 3;
+ } else {
+ *chType = ACT_LFE;
+ *chIndex = 0;
+ }
+ break;
+ case 12: /* SCE,CPE,CPE,CPE,LFE */
+ if (index < 7) {
+ *chType = ACT_BACK;
+ *chIndex = index - 3;
+ } else {
+ *chType = ACT_LFE;
+ *chIndex = 0;
+ }
+ break;
+ case 14: /* SCE,CPE,CPE,LFE,CPE */
+ switch (index) {
+ case 3:
+ case 4:
+ *chType = ACT_BACK;
+ *chIndex = index - 3;
+ break;
+ case 5:
+ *chType = ACT_LFE;
+ *chIndex = 0;
+ break;
+ case 6:
+ case 7:
+ *chType = ACT_FRONT_TOP;
+ *chIndex = index - 6; /* handle the top layer independently */
+ break;
+ }
+ break;
+ default:
+ *chType = ACT_NONE;
+ break;
+ }
+ }
+}
+
+int CProgramConfig_LookupElement(CProgramConfig *pPce, UINT channelConfig,
+ const UINT tag, const UINT channelIdx,
+ UCHAR chMapping[], AUDIO_CHANNEL_TYPE chType[],
+ UCHAR chIndex[], const UINT chDescrLen,
+ UCHAR *elMapping, MP4_ELEMENT_ID elList[],
+ MP4_ELEMENT_ID elType) {
+ if (channelConfig > 0) {
+ /* Constant channel mapping must have
+ been set during initialization. */
+ if (IS_CHANNEL_ELEMENT(elType)) {
+ *elMapping = pPce->elCounter;
+ if (elList[pPce->elCounter] != elType &&
+ !IS_USAC_CHANNEL_ELEMENT(elType)) {
+ /* Not in the list */
+ if ((channelConfig == 2) &&
+ (elType == ID_SCE)) { /* This scenario occurs with HE-AAC v2 streams
+ of buggy encoders. In other decoder
+ implementations decoding of this kind of
+ streams is desired. */
+ channelConfig = 1;
+ } else if ((elList[pPce->elCounter] == ID_LFE) &&
+ (elType ==
+ ID_SCE)) { /* Decode bitstreams which wrongly use ID_SCE
+ instead of ID_LFE element type. */
+ ;
+ } else {
+ return 0;
+ }
+ }
+ /* Assume all front channels */
+ getImplicitAudioChannelTypeAndIndex(
+ &chType[channelIdx], &chIndex[channelIdx], channelConfig, channelIdx);
+ if (elType == ID_CPE || elType == ID_USAC_CPE) {
+ chType[channelIdx + 1] = chType[channelIdx];
+ chIndex[channelIdx + 1] = chIndex[channelIdx] + 1;
+ }
+ pPce->elCounter++;
+ }
+ /* Accept all non-channel elements, too. */
+ return 1;
+ } else {
+ if ((!pPce->isValid) || (pPce->NumChannels > chDescrLen)) {
+ /* Implicit channel mapping. */
+ if (IS_USAC_CHANNEL_ELEMENT(elType)) {
+ *elMapping = pPce->elCounter++;
+ } else if (IS_MP4_CHANNEL_ELEMENT(elType)) {
+ /* Store all channel element IDs */
+ elList[pPce->elCounter] = elType;
+ *elMapping = pPce->elCounter++;
+ }
+ } else {
+ /* Accept the additional channel(s), only if the tag is in the lists */
+ int isCpe = 0, i;
+ /* Element counter */
+ int ec[PC_NUM_HEIGHT_LAYER] = {0};
+ /* Channel counters */
+ int cc[PC_NUM_HEIGHT_LAYER] = {0};
+ int fc[PC_NUM_HEIGHT_LAYER] = {0}; /* front channel counter */
+ int sc[PC_NUM_HEIGHT_LAYER] = {0}; /* side channel counter */
+ int bc[PC_NUM_HEIGHT_LAYER] = {0}; /* back channel counter */
+ int lc = 0; /* lfe channel counter */
+
+ /* General MPEG (PCE) composition rules:
+ - Over all:
+ <normal height channels><top height channels><bottom height
+ channels>
+ - Within each height layer:
+ <front channels><side channels><back channels>
+ - Exception:
+ The LFE channels have no height info and thus they are arranged at
+ the very end of the normal height layer channels.
+ */
+
+ switch (elType) {
+ case ID_CPE:
+ isCpe = 1;
+ FDK_FALLTHROUGH;
+ case ID_SCE:
+ /* search in front channels */
+ for (i = 0; i < pPce->NumFrontChannelElements; i++) {
+ int heightLayer = pPce->FrontElementHeightInfo[i];
+ if (isCpe == pPce->FrontElementIsCpe[i] &&
+ pPce->FrontElementTagSelect[i] == tag) {
+ int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
+ AUDIO_CHANNEL_TYPE aChType =
+ (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_FRONT);
+ for (h = heightLayer - 1; h >= 0; h -= 1) {
+ int el;
+ /* Count front channels/elements */
+ for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
+ if (pPce->FrontElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ /* Count side channels/elements */
+ for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
+ if (pPce->SideElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ /* Count back channels/elements */
+ for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
+ if (pPce->BackElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ if (h == 0) { /* normal height */
+ elIdx += pPce->NumLfeChannelElements;
+ chIdx += pPce->NumLfeChannelElements;
+ }
+ }
+ chMapping[chIdx] = channelIdx;
+ chType[chIdx] = aChType;
+ chIndex[chIdx] = fc[heightLayer];
+ if (isCpe) {
+ chMapping[chIdx + 1] = channelIdx + 1;
+ chType[chIdx + 1] = aChType;
+ chIndex[chIdx + 1] = fc[heightLayer] + 1;
+ }
+ *elMapping = elIdx;
+ return 1;
+ }
+ ec[heightLayer] += 1;
+ if (pPce->FrontElementIsCpe[i]) {
+ cc[heightLayer] += 2;
+ fc[heightLayer] += 2;
+ } else {
+ cc[heightLayer] += 1;
+ fc[heightLayer] += 1;
+ }
+ }
+ /* search in side channels */
+ for (i = 0; i < pPce->NumSideChannelElements; i++) {
+ int heightLayer = pPce->SideElementHeightInfo[i];
+ if (isCpe == pPce->SideElementIsCpe[i] &&
+ pPce->SideElementTagSelect[i] == tag) {
+ int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
+ AUDIO_CHANNEL_TYPE aChType =
+ (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_SIDE);
+ for (h = heightLayer - 1; h >= 0; h -= 1) {
+ int el;
+ /* Count front channels/elements */
+ for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
+ if (pPce->FrontElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ /* Count side channels/elements */
+ for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
+ if (pPce->SideElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ /* Count back channels/elements */
+ for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
+ if (pPce->BackElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ if (h ==
+ 0) { /* LFE channels belong to the normal height layer */
+ elIdx += pPce->NumLfeChannelElements;
+ chIdx += pPce->NumLfeChannelElements;
+ }
+ }
+ chMapping[chIdx] = channelIdx;
+ chType[chIdx] = aChType;
+ chIndex[chIdx] = sc[heightLayer];
+ if (isCpe) {
+ chMapping[chIdx + 1] = channelIdx + 1;
+ chType[chIdx + 1] = aChType;
+ chIndex[chIdx + 1] = sc[heightLayer] + 1;
+ }
+ *elMapping = elIdx;
+ return 1;
+ }
+ ec[heightLayer] += 1;
+ if (pPce->SideElementIsCpe[i]) {
+ cc[heightLayer] += 2;
+ sc[heightLayer] += 2;
+ } else {
+ cc[heightLayer] += 1;
+ sc[heightLayer] += 1;
+ }
+ }
+ /* search in back channels */
+ for (i = 0; i < pPce->NumBackChannelElements; i++) {
+ int heightLayer = pPce->BackElementHeightInfo[i];
+ if (isCpe == pPce->BackElementIsCpe[i] &&
+ pPce->BackElementTagSelect[i] == tag) {
+ int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
+ AUDIO_CHANNEL_TYPE aChType =
+ (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_BACK);
+ for (h = heightLayer - 1; h >= 0; h -= 1) {
+ int el;
+ /* Count front channels/elements */
+ for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
+ if (pPce->FrontElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ /* Count side channels/elements */
+ for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
+ if (pPce->SideElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ /* Count back channels/elements */
+ for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
+ if (pPce->BackElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ if (h == 0) { /* normal height */
+ elIdx += pPce->NumLfeChannelElements;
+ chIdx += pPce->NumLfeChannelElements;
+ }
+ }
+ chMapping[chIdx] = channelIdx;
+ chType[chIdx] = aChType;
+ chIndex[chIdx] = bc[heightLayer];
+ if (isCpe) {
+ chMapping[chIdx + 1] = channelIdx + 1;
+ chType[chIdx + 1] = aChType;
+ chIndex[chIdx + 1] = bc[heightLayer] + 1;
+ }
+ *elMapping = elIdx;
+ return 1;
+ }
+ ec[heightLayer] += 1;
+ if (pPce->BackElementIsCpe[i]) {
+ cc[heightLayer] += 2;
+ bc[heightLayer] += 2;
+ } else {
+ cc[heightLayer] += 1;
+ bc[heightLayer] += 1;
+ }
+ }
+ break;
+
+ case ID_LFE: { /* Unfortunately we have to go through all normal height
+ layer elements to get the position of the LFE
+ channels. Start with counting the front
+ channels/elements at normal height */
+ for (i = 0; i < pPce->NumFrontChannelElements; i += 1) {
+ int heightLayer = pPce->FrontElementHeightInfo[i];
+ ec[heightLayer] += 1;
+ cc[heightLayer] += (pPce->FrontElementIsCpe[i]) ? 2 : 1;
+ }
+ /* Count side channels/elements at normal height */
+ for (i = 0; i < pPce->NumSideChannelElements; i += 1) {
+ int heightLayer = pPce->SideElementHeightInfo[i];
+ ec[heightLayer] += 1;
+ cc[heightLayer] += (pPce->SideElementIsCpe[i]) ? 2 : 1;
+ }
+ /* Count back channels/elements at normal height */
+ for (i = 0; i < pPce->NumBackChannelElements; i += 1) {
+ int heightLayer = pPce->BackElementHeightInfo[i];
+ ec[heightLayer] += 1;
+ cc[heightLayer] += (pPce->BackElementIsCpe[i]) ? 2 : 1;
+ }
+
+ /* search in lfe channels */
+ for (i = 0; i < pPce->NumLfeChannelElements; i++) {
+ int elIdx =
+ ec[0]; /* LFE channels belong to the normal height layer */
+ int chIdx = cc[0];
+ if (pPce->LfeElementTagSelect[i] == tag) {
+ chMapping[chIdx] = channelIdx;
+ *elMapping = elIdx;
+ chType[chIdx] = ACT_LFE;
+ chIndex[chIdx] = lc;
+ return 1;
+ }
+ ec[0] += 1;
+ cc[0] += 1;
+ lc += 1;
+ }
+ } break;
+
+ /* Non audio elements */
+ case ID_CCE:
+ /* search in cce channels */
+ for (i = 0; i < pPce->NumValidCcElements; i++) {
+ if (pPce->ValidCcElementTagSelect[i] == tag) {
+ return 1;
+ }
+ }
+ break;
+ case ID_DSE:
+ /* search associated data elements */
+ for (i = 0; i < pPce->NumAssocDataElements; i++) {
+ if (pPce->AssocDataElementTagSelect[i] == tag) {
+ return 1;
+ }
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 0; /* not found in any list */
+ }
+ }
+
+ return 1;
+}
+
+#define SPEAKER_PLANE_NORMAL 0
+#define SPEAKER_PLANE_TOP 1
+#define SPEAKER_PLANE_BOTTOM 2
+
+void CProgramConfig_GetChannelDescription(const UINT chConfig,
+ const CProgramConfig *pPce,
+ AUDIO_CHANNEL_TYPE chType[],
+ UCHAR chIndex[]) {
+ FDK_ASSERT(chType != NULL);
+ FDK_ASSERT(chIndex != NULL);
+
+ if ((chConfig == 0) && (pPce != NULL)) {
+ if (pPce->isValid) {
+ int spkPlane, chIdx = 0;
+ for (spkPlane = SPEAKER_PLANE_NORMAL; spkPlane <= SPEAKER_PLANE_BOTTOM;
+ spkPlane += 1) {
+ int elIdx, grpChIdx = 0;
+ for (elIdx = 0; elIdx < pPce->NumFrontChannelElements; elIdx += 1) {
+ if (pPce->FrontElementHeightInfo[elIdx] == spkPlane) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_FRONT);
+ chIndex[chIdx++] = grpChIdx++;
+ if (pPce->FrontElementIsCpe[elIdx]) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_FRONT);
+ chIndex[chIdx++] = grpChIdx++;
+ }
+ }
+ }
+ grpChIdx = 0;
+ for (elIdx = 0; elIdx < pPce->NumSideChannelElements; elIdx += 1) {
+ if (pPce->SideElementHeightInfo[elIdx] == spkPlane) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_SIDE);
+ chIndex[chIdx++] = grpChIdx++;
+ if (pPce->SideElementIsCpe[elIdx]) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_SIDE);
+ chIndex[chIdx++] = grpChIdx++;
+ }
+ }
+ }
+ grpChIdx = 0;
+ for (elIdx = 0; elIdx < pPce->NumBackChannelElements; elIdx += 1) {
+ if (pPce->BackElementHeightInfo[elIdx] == spkPlane) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_BACK);
+ chIndex[chIdx++] = grpChIdx++;
+ if (pPce->BackElementIsCpe[elIdx]) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_BACK);
+ chIndex[chIdx++] = grpChIdx++;
+ }
+ }
+ }
+ grpChIdx = 0;
+ if (spkPlane == SPEAKER_PLANE_NORMAL) {
+ for (elIdx = 0; elIdx < pPce->NumLfeChannelElements; elIdx += 1) {
+ chType[chIdx] = ACT_LFE;
+ chIndex[chIdx++] = grpChIdx++;
+ }
+ }
+ }
+ }
+ } else {
+ int chIdx;
+ for (chIdx = 0; chIdx < getNumberOfTotalChannels(chConfig); chIdx += 1) {
+ getImplicitAudioChannelTypeAndIndex(&chType[chIdx], &chIndex[chIdx],
+ chConfig, chIdx);
+ }
+ }
+}
+
+int CProgramConfig_GetPceChMap(const CProgramConfig *pPce, UCHAR pceChMap[],
+ const UINT pceChMapLen) {
+ const UCHAR *nElements = &pPce->NumFrontChannelElements;
+ const UCHAR *elHeight[3], *elIsCpe[3];
+ unsigned chIdx, plane, grp, offset, totCh[3], numCh[3][4];
+
+ FDK_ASSERT(pPce != NULL);
+ FDK_ASSERT(pceChMap != NULL);
+
+ /* Init counter: */
+ FDKmemclear(totCh, 3 * sizeof(unsigned));
+ FDKmemclear(numCh, 3 * 4 * sizeof(unsigned));
+
+ /* Analyse PCE: */
+ elHeight[0] = pPce->FrontElementHeightInfo;
+ elIsCpe[0] = pPce->FrontElementIsCpe;
+ elHeight[1] = pPce->SideElementHeightInfo;
+ elIsCpe[1] = pPce->SideElementIsCpe;
+ elHeight[2] = pPce->BackElementHeightInfo;
+ elIsCpe[2] = pPce->BackElementIsCpe;
+
+ for (plane = 0; plane <= SPEAKER_PLANE_BOTTOM; plane += 1) {
+ for (grp = 0; grp < 3; grp += 1) { /* front, side, back */
+ unsigned el;
+ for (el = 0; el < nElements[grp]; el += 1) {
+ if (elHeight[grp][el] == plane) {
+ unsigned elCh = elIsCpe[grp][el] ? 2 : 1;
+ numCh[plane][grp] += elCh;
+ totCh[plane] += elCh;
+ }
+ }
+ }
+ if (plane == SPEAKER_PLANE_NORMAL) {
+ unsigned elCh = pPce->NumLfeChannelElements;
+ numCh[plane][grp] += elCh;
+ totCh[plane] += elCh;
+ }
+ }
+ /* Sanity checks: */
+ chIdx = totCh[SPEAKER_PLANE_NORMAL] + totCh[SPEAKER_PLANE_TOP] +
+ totCh[SPEAKER_PLANE_BOTTOM];
+ if (chIdx > pceChMapLen) {
+ return -1;
+ }
+
+ /* Create map: */
+ offset = grp = 0;
+ unsigned grpThresh = numCh[SPEAKER_PLANE_NORMAL][grp];
+ for (chIdx = 0; chIdx < totCh[SPEAKER_PLANE_NORMAL]; chIdx += 1) {
+ while ((chIdx >= grpThresh) && (grp < 3)) {
+ offset += numCh[1][grp] + numCh[2][grp];
+ grp += 1;
+ grpThresh += numCh[SPEAKER_PLANE_NORMAL][grp];
+ }
+ pceChMap[chIdx] = chIdx + offset;
+ }
+ offset = 0;
+ for (grp = 0; grp < 4; grp += 1) { /* front, side, back and lfe */
+ offset += numCh[SPEAKER_PLANE_NORMAL][grp];
+ for (plane = SPEAKER_PLANE_TOP; plane <= SPEAKER_PLANE_BOTTOM; plane += 1) {
+ unsigned mapCh;
+ for (mapCh = 0; mapCh < numCh[plane][grp]; mapCh += 1) {
+ pceChMap[chIdx++] = offset;
+ offset += 1;
+ }
+ }
+ }
+ return 0;
+}
+
+int CProgramConfig_GetElementTable(const CProgramConfig *pPce,
+ MP4_ELEMENT_ID elList[],
+ const INT elListSize, UCHAR *pChMapIdx) {
+ int i, el = 0;
+
+ FDK_ASSERT(elList != NULL);
+ FDK_ASSERT(pChMapIdx != NULL);
+ FDK_ASSERT(pPce != NULL);
+
+ *pChMapIdx = 0;
+
+ if ((elListSize <
+ pPce->NumFrontChannelElements + pPce->NumSideChannelElements +
+ pPce->NumBackChannelElements + pPce->NumLfeChannelElements) ||
+ (pPce->NumChannels == 0)) {
+ return 0;
+ }
+
+ for (i = 0; i < pPce->NumFrontChannelElements; i += 1) {
+ elList[el++] = (pPce->FrontElementIsCpe[i]) ? ID_CPE : ID_SCE;
+ }
+
+ for (i = 0; i < pPce->NumSideChannelElements; i += 1) {
+ elList[el++] = (pPce->SideElementIsCpe[i]) ? ID_CPE : ID_SCE;
+ }
+
+ for (i = 0; i < pPce->NumBackChannelElements; i += 1) {
+ elList[el++] = (pPce->BackElementIsCpe[i]) ? ID_CPE : ID_SCE;
+ }
+
+ for (i = 0; i < pPce->NumLfeChannelElements; i += 1) {
+ elList[el++] = ID_LFE;
+ }
+
+ /* Find an corresponding channel configuration if possible */
+ switch (pPce->NumChannels) {
+ case 1:
+ case 2:
+ /* One and two channels have no alternatives. */
+ *pChMapIdx = pPce->NumChannels;
+ break;
+ case 3:
+ case 4:
+ case 5:
+ case 6: { /* Test if the number of channels can be used as channel config:
+ */
+ C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
+ /* Create a PCE for the config to test ... */
+ CProgramConfig_GetDefault(tmpPce, pPce->NumChannels);
+ /* ... and compare it with the given one. */
+ *pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE))
+ ? pPce->NumChannels
+ : 0;
+ /* If compare result is 0 or 1 we can be sure that it is channel
+ * config 11. */
+ C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
+ } break;
+ case 7: {
+ C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
+ /* Create a PCE for the config to test ... */
+ CProgramConfig_GetDefault(tmpPce, 11);
+ /* ... and compare it with the given one. */
+ *pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE)) ? 11 : 0;
+ /* If compare result is 0 or 1 we can be sure that it is channel
+ * config 11. */
+ C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
+ } break;
+ case 8: { /* Try the four possible 7.1ch configurations. One after the
+ other. */
+ UCHAR testCfg[4] = {32, 14, 12, 7};
+ C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
+ for (i = 0; i < 4; i += 1) {
+ /* Create a PCE for the config to test ... */
+ CProgramConfig_GetDefault(tmpPce, testCfg[i]);
+ /* ... and compare it with the given one. */
+ if (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE)) {
+ /* If the compare result is 0 or 1 than the two channel configurations
+ * match. */
+ /* Explicit mapping of 7.1 side channel configuration to 7.1 rear
+ * channel mapping. */
+ *pChMapIdx = (testCfg[i] == 32) ? 12 : testCfg[i];
+ }
+ }
+ C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
+ } break;
+ default:
+ /* The PCE does not match any predefined channel configuration. */
+ *pChMapIdx = 0;
+ break;
+ }
+
+ return el;
+}
+
+static AUDIO_OBJECT_TYPE getAOT(HANDLE_FDK_BITSTREAM bs) {
+ int tmp = 0;
+
+ tmp = FDKreadBits(bs, 5);
+ if (tmp == AOT_ESCAPE) {
+ int tmp2 = FDKreadBits(bs, 6);
+ tmp = 32 + tmp2;
+ }
+
+ return (AUDIO_OBJECT_TYPE)tmp;
+}
+
+static INT getSampleRate(HANDLE_FDK_BITSTREAM bs, UCHAR *index, int nBits) {
+ INT sampleRate;
+ int idx;
+
+ idx = FDKreadBits(bs, nBits);
+ if (idx == (1 << nBits) - 1) {
+ if (FDKgetValidBits(bs) < 24) {
+ return 0;
+ }
+ sampleRate = FDKreadBits(bs, 24);
+ } else {
+ sampleRate = SamplingRateTable[idx];
+ }
+
+ *index = idx;
+
+ return sampleRate;
+}
+
+static TRANSPORTDEC_ERROR GaSpecificConfig_Parse(CSGaSpecificConfig *self,
+ CSAudioSpecificConfig *asc,
+ HANDLE_FDK_BITSTREAM bs,
+ UINT ascStartAnchor) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+
+ self->m_frameLengthFlag = FDKreadBits(bs, 1);
+
+ self->m_dependsOnCoreCoder = FDKreadBits(bs, 1);
+
+ if (self->m_dependsOnCoreCoder) self->m_coreCoderDelay = FDKreadBits(bs, 14);
+
+ self->m_extensionFlag = FDKreadBits(bs, 1);
+
+ if (asc->m_channelConfiguration == 0) {
+ CProgramConfig_Read(&asc->m_progrConfigElement, bs, ascStartAnchor);
+ }
+
+ if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) {
+ self->m_layer = FDKreadBits(bs, 3);
+ }
+
+ if (self->m_extensionFlag) {
+ if (asc->m_aot == AOT_ER_BSAC) {
+ self->m_numOfSubFrame = FDKreadBits(bs, 5);
+ self->m_layerLength = FDKreadBits(bs, 11);
+ }
+
+ if ((asc->m_aot == AOT_ER_AAC_LC) || (asc->m_aot == AOT_ER_AAC_LTP) ||
+ (asc->m_aot == AOT_ER_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_LD)) {
+ asc->m_vcb11Flag = FDKreadBits(bs, 1); /* aacSectionDataResilienceFlag */
+ asc->m_rvlcFlag =
+ FDKreadBits(bs, 1); /* aacScalefactorDataResilienceFlag */
+ asc->m_hcrFlag = FDKreadBits(bs, 1); /* aacSpectralDataResilienceFlag */
+ }
+
+ self->m_extensionFlag3 = FDKreadBits(bs, 1);
+ }
+ return (ErrorStatus);
+}
+
+static INT skipSbrHeader(HANDLE_FDK_BITSTREAM hBs, int isUsac) {
+ /* Dummy parse SbrDfltHeader() */
+ INT dflt_header_extra1, dflt_header_extra2, bitsToSkip = 0;
+
+ if (!isUsac) {
+ bitsToSkip = 6;
+ FDKpushFor(hBs, 6); /* amp res 1, xover freq 3, reserved 2 */
+ }
+ bitsToSkip += 8;
+ FDKpushFor(hBs, 8); /* start / stop freq */
+ bitsToSkip += 2;
+ dflt_header_extra1 = FDKreadBit(hBs);
+ dflt_header_extra2 = FDKreadBit(hBs);
+ bitsToSkip += 5 * dflt_header_extra1 + 6 * dflt_header_extra2;
+ FDKpushFor(hBs, 5 * dflt_header_extra1 + 6 * dflt_header_extra2);
+
+ return bitsToSkip;
+}
+
+static INT ld_sbr_header(CSAudioSpecificConfig *asc, const INT dsFactor,
+ HANDLE_FDK_BITSTREAM hBs, CSTpCallBacks *cb) {
+ const int channelConfiguration = asc->m_channelConfiguration;
+ int i = 0, j = 0;
+ INT error = 0;
+ MP4_ELEMENT_ID element = ID_NONE;
+
+ /* check whether the channelConfiguration is defined in
+ * channel_configuration_array */
+ if (channelConfiguration < 0 ||
+ channelConfiguration > (INT)(sizeof(channel_configuration_array) /
+ sizeof(MP4_ELEMENT_ID **) -
+ 1)) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ /* read elements of the passed channel_configuration until there is ID_NONE */
+ while ((element = channel_configuration_array[channelConfiguration][j]) !=
+ ID_NONE) {
+ /* Setup LFE element for upsampling too. This is essential especially for
+ * channel configs where the LFE element is not at the last position for
+ * example in channel config 13 or 14. It leads to memory leaks if the setup
+ * of the LFE element would be done later in the core. */
+ if (element == ID_SCE || element == ID_CPE || element == ID_LFE) {
+ error |= cb->cbSbr(
+ cb->cbSbrData, hBs, asc->m_samplingFrequency / dsFactor,
+ asc->m_extensionSamplingFrequency / dsFactor,
+ asc->m_samplesPerFrame / dsFactor, AOT_ER_AAC_ELD, element, i++, 0, 0,
+ asc->configMode, &asc->SbrConfigChanged, dsFactor);
+ if (error != TRANSPORTDEC_OK) {
+ goto bail;
+ }
+ }
+ j++;
+ }
+bail:
+ return error;
+}
+
+static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
+ HANDLE_FDK_BITSTREAM hBs,
+ CSTpCallBacks *cb) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
+ ASC_ELD_EXT_TYPE eldExtType;
+ int eldExtLen, len, cnt, ldSbrLen = 0, eldExtLenSum, numSbrHeader = 0,
+ sbrIndex;
+
+ unsigned char downscale_fill_nibble;
+
+ FDKmemclear(esc, sizeof(CSEldSpecificConfig));
+
+ esc->m_frameLengthFlag = FDKreadBits(hBs, 1);
+ if (esc->m_frameLengthFlag) {
+ asc->m_samplesPerFrame = 480;
+ } else {
+ asc->m_samplesPerFrame = 512;
+ }
+
+ asc->m_vcb11Flag = FDKreadBits(hBs, 1);
+ asc->m_rvlcFlag = FDKreadBits(hBs, 1);
+ asc->m_hcrFlag = FDKreadBits(hBs, 1);
+
+ esc->m_sbrPresentFlag = FDKreadBits(hBs, 1);
+
+ if (esc->m_sbrPresentFlag == 1) {
+ esc->m_sbrSamplingRate =
+ FDKreadBits(hBs, 1); /* 0: single rate, 1: dual rate */
+ esc->m_sbrCrcFlag = FDKreadBits(hBs, 1);
+
+ asc->m_extensionSamplingFrequency = asc->m_samplingFrequency
+ << esc->m_sbrSamplingRate;
+
+ if (cb->cbSbr != NULL) {
+ /* ELD reduced delay mode: LD-SBR initialization has to know the downscale
+ information. Postpone LD-SBR initialization and read ELD extension
+ information first. */
+ switch (asc->m_channelConfiguration) {
+ case 1:
+ case 2:
+ numSbrHeader = 1;
+ break;
+ case 3:
+ numSbrHeader = 2;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ numSbrHeader = 3;
+ break;
+ case 7:
+ case 11:
+ case 12:
+ case 14:
+ numSbrHeader = 4;
+ break;
+ default:
+ numSbrHeader = 0;
+ break;
+ }
+ for (sbrIndex = 0; sbrIndex < numSbrHeader; sbrIndex++) {
+ ldSbrLen += skipSbrHeader(hBs, 0);
+ }
+ } else {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ }
+ esc->m_useLdQmfTimeAlign = 0;
+
+ /* new ELD syntax */
+ eldExtLenSum = FDKgetValidBits(hBs);
+ esc->m_downscaledSamplingFrequency = asc->m_samplingFrequency;
+ /* parse ExtTypeConfigData */
+ while (
+ ((eldExtType = (ASC_ELD_EXT_TYPE)FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
+ ((INT)FDKgetValidBits(hBs) >= 0)) {
+ eldExtLen = len = FDKreadBits(hBs, 4);
+ if (len == 0xf) {
+ len = FDKreadBits(hBs, 8);
+ eldExtLen += len;
+
+ if (len == 0xff) {
+ len = FDKreadBits(hBs, 16);
+ eldExtLen += len;
+ }
+ }
+
+ switch (eldExtType) {
+ case ELDEXT_LDSAC:
+ esc->m_useLdQmfTimeAlign = 1;
+ if (cb->cbSsc != NULL) {
+ ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
+ cb->cbSscData, hBs, asc->m_aot,
+ asc->m_samplingFrequency << esc->m_sbrSamplingRate,
+ asc->m_samplesPerFrame << esc->m_sbrSamplingRate,
+ 1, /* stereoConfigIndex */
+ -1, /* nTimeSlots: read from bitstream */
+ eldExtLen, asc->configMode, &asc->SacConfigChanged);
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ if (esc->m_downscaledSamplingFrequency != asc->m_samplingFrequency) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* ELDv2 w/ ELD downscaled
+ mode not allowed */
+ }
+ break;
+ }
+
+ FDK_FALLTHROUGH;
+ default:
+ for (cnt = 0; cnt < eldExtLen; cnt++) {
+ FDKreadBits(hBs, 8);
+ }
+ break;
+
+ case ELDEXT_DOWNSCALEINFO:
+ UCHAR tmpDownscaleFreqIdx;
+ esc->m_downscaledSamplingFrequency =
+ getSampleRate(hBs, &tmpDownscaleFreqIdx, 4);
+ if (esc->m_downscaledSamplingFrequency == 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ downscale_fill_nibble = FDKreadBits(hBs, 4);
+ if (downscale_fill_nibble != 0x0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ if (esc->m_useLdQmfTimeAlign == 1) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* ELDv2 w/ ELD downscaled
+ mode not allowed */
+ }
+ break;
+ }
+ }
+
+ if ((INT)FDKgetValidBits(hBs) < 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ if (esc->m_sbrPresentFlag == 1 && numSbrHeader != 0) {
+ INT dsFactor = 1; /* Downscale factor must be 1 or even for SBR */
+ if (esc->m_downscaledSamplingFrequency != 0) {
+ if (asc->m_samplingFrequency % esc->m_downscaledSamplingFrequency != 0) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ dsFactor = asc->m_samplingFrequency / esc->m_downscaledSamplingFrequency;
+ if (dsFactor != 1 && (dsFactor)&1) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* SBR needs an even downscale
+ factor */
+ }
+ if (dsFactor != 1 && dsFactor != 2 && dsFactor != 4) {
+ dsFactor = 1; /* don't apply dsf for not yet supported even dsfs */
+ }
+ if ((INT)asc->m_samplesPerFrame % dsFactor != 0) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* frameSize/dsf must be an
+ integer number */
+ }
+ }
+ eldExtLenSum = eldExtLenSum - FDKgetValidBits(hBs);
+ FDKpushBack(hBs, eldExtLenSum + ldSbrLen);
+ if (0 != ld_sbr_header(asc, dsFactor, hBs, cb)) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ FDKpushFor(hBs, eldExtLenSum);
+ }
+ return (ErrorStatus);
+}
+
+/*
+Subroutine to store config in UCHAR buffer. Bit stream position does not change.
+*/
+static UINT StoreConfigAsBitstream(
+ HANDLE_FDK_BITSTREAM hBs, const INT configSize_bits, /* If < 0 (> 0) config
+ to read is before
+ (after) current bit
+ stream position. */
+ UCHAR *configTargetBuffer, const USHORT configTargetBufferSize_bytes) {
+ FDK_BITSTREAM usacConf;
+ UINT const nBits = fAbs(configSize_bits);
+ UINT j, tmp;
+
+ if (nBits > 8 * (UINT)configTargetBufferSize_bytes) {
+ return 1;
+ }
+ FDKmemclear(configTargetBuffer, configTargetBufferSize_bytes);
+
+ FDKinitBitStream(&usacConf, configTargetBuffer, configTargetBufferSize_bytes,
+ nBits, BS_WRITER);
+ if (configSize_bits < 0) {
+ FDKpushBack(hBs, nBits);
+ }
+ for (j = nBits; j > 31; j -= 32) {
+ tmp = FDKreadBits(hBs, 32);
+ FDKwriteBits(&usacConf, tmp, 32);
+ }
+ if (j > 0) {
+ tmp = FDKreadBits(hBs, j);
+ FDKwriteBits(&usacConf, tmp, j);
+ }
+ FDKsyncCache(&usacConf);
+ if (configSize_bits > 0) {
+ FDKpushBack(hBs, nBits);
+ }
+
+ return 0;
+}
+
+/* maps coreSbrFrameLengthIndex to coreCoderFrameLength */
+static const USHORT usacFrameLength[8] = {768, 1024, 2048, 2048, 4096, 0, 0, 0};
+/* maps coreSbrFrameLengthIndex to sbrRatioIndex */
+static const UCHAR sbrRatioIndex[8] = {0, 0, 2, 3, 1, 0, 0, 0};
+
+/*
+ subroutine for parsing extension element configuration:
+ UsacExtElementConfig() q.v. ISO/IEC FDIS 23003-3:2011(E) Table 14
+ rsv603daExtElementConfig() q.v. ISO/IEC DIS 23008-3 Table 13
+*/
+static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement,
+ HANDLE_FDK_BITSTREAM hBs,
+ const CSTpCallBacks *cb,
+ const UCHAR numSignalsInGroup,
+ const UINT coreFrameLength,
+ const int subStreamIndex,
+ const AUDIO_OBJECT_TYPE aot) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+
+ USAC_EXT_ELEMENT_TYPE usacExtElementType =
+ (USAC_EXT_ELEMENT_TYPE)escapedValue(hBs, 4, 8, 16);
+
+ /* recurve extension elements which are invalid for USAC */
+ if (aot == AOT_USAC) {
+ switch (usacExtElementType) {
+ case ID_EXT_ELE_FILL:
+ case ID_EXT_ELE_MPEGS:
+ case ID_EXT_ELE_SAOC:
+ case ID_EXT_ELE_AUDIOPREROLL:
+ case ID_EXT_ELE_UNI_DRC:
+ break;
+ default:
+ usacExtElementType = ID_EXT_ELE_UNKNOWN;
+ break;
+ }
+ }
+
+ extElement->usacExtElementType = usacExtElementType;
+ int usacExtElementConfigLength = escapedValue(hBs, 4, 8, 16);
+ extElement->usacExtElementConfigLength = (USHORT)usacExtElementConfigLength;
+ INT bsAnchor;
+
+ if (FDKreadBit(hBs)) /* usacExtElementDefaultLengthPresent */
+ extElement->usacExtElementDefaultLength = escapedValue(hBs, 8, 16, 0) + 1;
+ else
+ extElement->usacExtElementDefaultLength = 0;
+
+ extElement->usacExtElementPayloadFrag = FDKreadBit(hBs);
+
+ bsAnchor = (INT)FDKgetValidBits(hBs);
+
+ switch (usacExtElementType) {
+ case ID_EXT_ELE_UNKNOWN:
+ case ID_EXT_ELE_FILL:
+ break;
+ case ID_EXT_ELE_AUDIOPREROLL:
+ /* No configuration element */
+ extElement->usacExtElementHasAudioPreRoll = 1;
+ break;
+ case ID_EXT_ELE_UNI_DRC: {
+ if (cb->cbUniDrc != NULL) {
+ ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
+ cb->cbUniDrcData, hBs, usacExtElementConfigLength,
+ 0, /* uniDrcConfig */
+ subStreamIndex, 0, aot);
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ return ErrorStatus;
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+
+ /* Adjust bit stream position. This is required because of byte alignment and
+ * unhandled extensions. */
+ {
+ INT left_bits = (usacExtElementConfigLength << 3) -
+ (bsAnchor - (INT)FDKgetValidBits(hBs));
+ if (left_bits >= 0) {
+ FDKpushFor(hBs, left_bits);
+ } else {
+ /* parsed too many bits */
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+
+ return ErrorStatus;
+}
+
+/*
+ subroutine for parsing the USAC / RSVD60 configuration extension:
+ UsacConfigExtension() q.v. ISO/IEC FDIS 23003-3:2011(E) Table 15
+ rsv603daConfigExtension() q.v. ISO/IEC DIS 23008-3 Table 14
+*/
+static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc,
+ HANDLE_FDK_BITSTREAM hBs,
+ const CSTpCallBacks *cb) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+
+ int numConfigExtensions;
+ CONFIG_EXT_ID usacConfigExtType;
+ int usacConfigExtLength;
+
+ numConfigExtensions = (int)escapedValue(hBs, 2, 4, 8) + 1;
+ for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) {
+ INT nbits;
+ int loudnessInfoSetConfigExtensionPosition = FDKgetValidBits(hBs);
+ usacConfigExtType = (CONFIG_EXT_ID)escapedValue(hBs, 4, 8, 16);
+ usacConfigExtLength = (int)escapedValue(hBs, 4, 8, 16);
+
+ /* Start bit position of config extension */
+ nbits = (INT)FDKgetValidBits(hBs);
+
+ /* Return an error in case the bitbuffer fill level is too low. */
+ if (nbits < usacConfigExtLength * 8) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ switch (usacConfigExtType) {
+ case ID_CONFIG_EXT_FILL:
+ for (int i = 0; i < usacConfigExtLength; i++) {
+ if (FDKreadBits(hBs, 8) != 0xa5) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ break;
+ case ID_CONFIG_EXT_LOUDNESS_INFO: {
+ if (cb->cbUniDrc != NULL) {
+ ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
+ cb->cbUniDrcData, hBs, usacConfigExtLength,
+ 1, /* loudnessInfoSet */
+ 0, loudnessInfoSetConfigExtensionPosition, AOT_USAC);
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ return ErrorStatus;
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+
+ /* Skip remaining bits. If too many bits were parsed, assume error. */
+ usacConfigExtLength =
+ 8 * usacConfigExtLength - (nbits - (INT)FDKgetValidBits(hBs));
+ if (usacConfigExtLength < 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ FDKpushFor(hBs, usacConfigExtLength);
+ }
+
+ return ErrorStatus;
+}
+
+/* This function unifies decoder config parsing of USAC and RSV60:
+ rsv603daDecoderConfig() ISO/IEC DIS 23008-3 Table 8
+ UsacDecoderConfig() ISO/IEC FDIS 23003-3 Table 6
+ */
+static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
+ CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM hBs,
+ const CSTpCallBacks *cb) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ CSUsacConfig *usc = &asc->m_sc.m_usacConfig;
+ int i, numberOfElements;
+ int channelElementIdx =
+ 0; /* index for elements which contain audio channels (sce, cpe, lfe) */
+ SC_CHANNEL_CONFIG sc_chan_config = {0, 0, 0, 0};
+
+ numberOfElements = (int)escapedValue(hBs, 4, 8, 16) + 1;
+ usc->m_usacNumElements = numberOfElements;
+ if (numberOfElements > TP_USAC_MAX_ELEMENTS) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ usc->m_nUsacChannels = 0;
+ usc->m_channelConfigurationIndex = asc->m_channelConfiguration;
+
+ if (asc->m_aot == AOT_USAC) {
+ sc_chan_config = sc_chan_config_tab[usc->m_channelConfigurationIndex];
+
+ if (sc_chan_config.nCh > (SCHAR)TP_USAC_MAX_SPEAKERS) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+
+ for (i = 0; i < numberOfElements; i++) {
+ MP4_ELEMENT_ID usacElementType = (MP4_ELEMENT_ID)(
+ FDKreadBits(hBs, 2) | USAC_ID_BIT); /* set USAC_ID_BIT to map
+ usacElementType to
+ MP4_ELEMENT_ID enum */
+ usc->element[i].usacElementType = usacElementType;
+
+ /* sanity check: update element counter */
+ if (asc->m_aot == AOT_USAC) {
+ switch (usacElementType) {
+ case ID_USAC_SCE:
+ sc_chan_config.nSCE--;
+ break;
+ case ID_USAC_CPE:
+ sc_chan_config.nCPE--;
+ break;
+ case ID_USAC_LFE:
+ sc_chan_config.nLFE--;
+ break;
+ default:
+ break;
+ }
+ if (usc->m_channelConfigurationIndex) {
+ /* sanity check: no element counter may be smaller zero */
+ if (sc_chan_config.nCPE < 0 || sc_chan_config.nSCE < 0 ||
+ sc_chan_config.nLFE < 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ }
+
+ switch (usacElementType) {
+ case ID_USAC_SCE:
+ /* UsacCoreConfig() ISO/IEC FDIS 23003-3 Table 10 */
+ if (FDKreadBit(hBs)) { /* tw_mdct */
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1);
+ /* end of UsacCoreConfig() */
+ if (usc->m_sbrRatioIndex > 0) {
+ if (cb->cbSbr == NULL) {
+ return TRANSPORTDEC_UNKOWN_ERROR;
+ }
+ /* SbrConfig() ISO/IEC FDIS 23003-3 Table 11 */
+ usc->element[i].m_harmonicSBR = FDKreadBit(hBs);
+ usc->element[i].m_interTes = FDKreadBit(hBs);
+ usc->element[i].m_pvc = FDKreadBit(hBs);
+ if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
+ asc->m_extensionSamplingFrequency,
+ asc->m_samplesPerFrame, asc->m_aot, ID_SCE,
+ channelElementIdx, usc->element[i].m_harmonicSBR,
+ usc->element[i].m_stereoConfigIndex, asc->configMode,
+ &asc->SbrConfigChanged, 1)) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ /* end of SbrConfig() */
+ }
+ usc->m_nUsacChannels += 1;
+ channelElementIdx++;
+ break;
+
+ case ID_USAC_CPE:
+ /* UsacCoreConfig() ISO/IEC FDIS 23003-3 Table 10 */
+ if (FDKreadBit(hBs)) { /* tw_mdct */
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1);
+ /* end of UsacCoreConfig() */
+ if (usc->m_sbrRatioIndex > 0) {
+ if (cb->cbSbr == NULL) return TRANSPORTDEC_UNKOWN_ERROR;
+ /* SbrConfig() ISO/IEC FDIS 23003-3 */
+ usc->element[i].m_harmonicSBR = FDKreadBit(hBs);
+ usc->element[i].m_interTes = FDKreadBit(hBs);
+ usc->element[i].m_pvc = FDKreadBit(hBs);
+ {
+ INT bitsToSkip = skipSbrHeader(hBs, 1);
+ /* read stereoConfigIndex */
+ usc->element[i].m_stereoConfigIndex = FDKreadBits(hBs, 2);
+ /* rewind */
+ FDKpushBack(hBs, bitsToSkip + 2);
+ }
+ {
+ MP4_ELEMENT_ID el_type =
+ (usc->element[i].m_stereoConfigIndex == 1 ||
+ usc->element[i].m_stereoConfigIndex == 2)
+ ? ID_SCE
+ : ID_CPE;
+ if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
+ asc->m_extensionSamplingFrequency,
+ asc->m_samplesPerFrame, asc->m_aot, el_type,
+ channelElementIdx, usc->element[i].m_harmonicSBR,
+ usc->element[i].m_stereoConfigIndex, asc->configMode,
+ &asc->SbrConfigChanged, 1)) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ /* end of SbrConfig() */
+
+ usc->element[i].m_stereoConfigIndex =
+ FDKreadBits(hBs, 2); /* Needed in RM5 syntax */
+
+ if (usc->element[i].m_stereoConfigIndex > 0) {
+ if (cb->cbSsc != NULL) {
+ int samplesPerFrame = asc->m_samplesPerFrame;
+
+ if (usc->m_sbrRatioIndex == 1) samplesPerFrame <<= 2;
+ if (usc->m_sbrRatioIndex == 2)
+ samplesPerFrame = (samplesPerFrame * 8) / 3;
+ if (usc->m_sbrRatioIndex == 3) samplesPerFrame <<= 1;
+
+ /* Mps212Config() ISO/IEC FDIS 23003-3 */
+ if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot,
+ asc->m_extensionSamplingFrequency, samplesPerFrame,
+ usc->element[i].m_stereoConfigIndex,
+ usc->m_coreSbrFrameLengthIndex,
+ 0, /* don't know the length */
+ asc->configMode, &asc->SacConfigChanged)) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ /* end of Mps212Config() */
+ } else {
+ return TRANSPORTDEC_UNKOWN_ERROR;
+ }
+ }
+ } else {
+ usc->element[i].m_stereoConfigIndex = 0;
+ }
+ usc->m_nUsacChannels += 2;
+
+ channelElementIdx++;
+ break;
+
+ case ID_USAC_LFE:
+ usc->element[i].m_noiseFilling = 0;
+ usc->m_nUsacChannels += 1;
+ if (usc->m_sbrRatioIndex > 0) {
+ /* Use SBR for upsampling */
+ if (cb->cbSbr == NULL) return ErrorStatus = TRANSPORTDEC_UNKOWN_ERROR;
+ usc->element[i].m_harmonicSBR = (UCHAR)0;
+ usc->element[i].m_interTes = (UCHAR)0;
+ usc->element[i].m_pvc = (UCHAR)0;
+ if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
+ asc->m_extensionSamplingFrequency,
+ asc->m_samplesPerFrame, asc->m_aot, ID_LFE,
+ channelElementIdx, usc->element[i].m_harmonicSBR,
+ usc->element[i].m_stereoConfigIndex, asc->configMode,
+ &asc->SbrConfigChanged, 1)) {
+ return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ channelElementIdx++;
+ break;
+
+ case ID_USAC_EXT:
+ ErrorStatus = extElementConfig(&usc->element[i].extElement, hBs, cb, 0,
+ asc->m_samplesPerFrame, 0, asc->m_aot);
+
+ if (ErrorStatus) {
+ return ErrorStatus;
+ }
+ break;
+
+ default:
+ /* non USAC-element encountered */
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+
+ if (asc->m_aot == AOT_USAC) {
+ if (usc->m_channelConfigurationIndex) {
+ /* sanity check: all element counter must be zero */
+ if (sc_chan_config.nCPE | sc_chan_config.nSCE | sc_chan_config.nLFE) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ } else {
+ /* sanity check: number of audio channels shall be equal to or smaller
+ * than the accumulated sum of all channels */
+ if ((INT)(-2 * sc_chan_config.nCPE - sc_chan_config.nSCE -
+ sc_chan_config.nLFE) < (INT)usc->numAudioChannels) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ }
+
+ return ErrorStatus;
+}
+
+/* Mapping of coreSbrFrameLengthIndex defined by Table 70 in ISO/IEC 23003-3 */
+static TRANSPORTDEC_ERROR UsacConfig_SetCoreSbrFrameLengthIndex(
+ CSAudioSpecificConfig *asc, int coreSbrFrameLengthIndex) {
+ int sbrRatioIndex_val;
+
+ if (coreSbrFrameLengthIndex > 4) {
+ return TRANSPORTDEC_PARSE_ERROR; /* reserved values */
+ }
+ asc->m_sc.m_usacConfig.m_coreSbrFrameLengthIndex = coreSbrFrameLengthIndex;
+ asc->m_samplesPerFrame = usacFrameLength[coreSbrFrameLengthIndex];
+ sbrRatioIndex_val = sbrRatioIndex[coreSbrFrameLengthIndex];
+ asc->m_sc.m_usacConfig.m_sbrRatioIndex = sbrRatioIndex_val;
+
+ if (sbrRatioIndex_val > 0) {
+ asc->m_sbrPresentFlag = 1;
+ asc->m_extensionSamplingFrequency = asc->m_samplingFrequency;
+ asc->m_extensionSamplingFrequencyIndex = asc->m_samplingFrequencyIndex;
+ switch (sbrRatioIndex_val) {
+ case 1: /* sbrRatio = 4:1 */
+ asc->m_samplingFrequency >>= 2;
+ asc->m_samplesPerFrame >>= 2;
+ break;
+ case 2: /* sbrRatio = 8:3 */
+ asc->m_samplingFrequency = (asc->m_samplingFrequency * 3) / 8;
+ asc->m_samplesPerFrame = (asc->m_samplesPerFrame * 3) / 8;
+ break;
+ case 3: /* sbrRatio = 2:1 */
+ asc->m_samplingFrequency >>= 1;
+ asc->m_samplesPerFrame >>= 1;
+ break;
+ default:
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ asc->m_samplingFrequencyIndex =
+ getSamplingRateIndex(asc->m_samplingFrequency, 4);
+ }
+
+ return TRANSPORTDEC_OK;
+}
+
+static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc,
+ HANDLE_FDK_BITSTREAM hBs,
+ CSTpCallBacks *cb) {
+ int usacSamplingFrequency, channelConfigurationIndex, coreSbrFrameLengthIndex;
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+
+ /* Start bit position of usacConfig */
+ INT nbits = (INT)FDKgetValidBits(hBs);
+
+ usacSamplingFrequency = getSampleRate(hBs, &asc->m_samplingFrequencyIndex, 5);
+ asc->m_samplingFrequency = (UINT)usacSamplingFrequency;
+
+ coreSbrFrameLengthIndex = FDKreadBits(hBs, 3);
+ if (UsacConfig_SetCoreSbrFrameLengthIndex(asc, coreSbrFrameLengthIndex) !=
+ TRANSPORTDEC_OK) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ channelConfigurationIndex = FDKreadBits(hBs, 5);
+ if (channelConfigurationIndex > 2) {
+ return TRANSPORTDEC_PARSE_ERROR; /* only channelConfigurationIndex = [1,2]
+ are supported */
+ }
+
+ if (channelConfigurationIndex == 0) {
+ return TRANSPORTDEC_PARSE_ERROR; /* only channelConfigurationIndex = [1,2]
+ are supported */
+ }
+ asc->m_channelConfiguration = channelConfigurationIndex;
+
+ err = UsacRsv60DecoderConfig_Parse(asc, hBs, cb);
+ if (err != TRANSPORTDEC_OK) {
+ return err;
+ }
+
+ if (FDKreadBits(hBs, 1)) { /* usacConfigExtensionPresent */
+ err = configExtension(&asc->m_sc.m_usacConfig, hBs, cb);
+ if (err != TRANSPORTDEC_OK) {
+ return err;
+ }
+ }
+
+ /* sanity check whether number of channels signaled in UsacDecoderConfig()
+ matches the number of channels required by channelConfigurationIndex */
+ if ((channelConfigurationIndex > 0) &&
+ (sc_chan_config_tab[channelConfigurationIndex].nCh !=
+ asc->m_sc.m_usacConfig.m_nUsacChannels)) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ /* Copy UsacConfig() to asc->m_sc.m_usacConfig.UsacConfig[] buffer. */
+ INT configSize_bits = (INT)FDKgetValidBits(hBs) - nbits;
+ StoreConfigAsBitstream(hBs, configSize_bits,
+ asc->m_sc.m_usacConfig.UsacConfig,
+ TP_USAC_MAX_CONFIG_LEN);
+ asc->m_sc.m_usacConfig.UsacConfigBits = fAbs(configSize_bits);
+
+ return err;
+}
+
+static TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(
+ CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs, CSTpCallBacks *cb) {
+ TP_ASC_EXTENSION_ID lastAscExt, ascExtId = ASCEXT_UNKOWN;
+ INT bitsAvailable = (INT)FDKgetValidBits(bs);
+
+ while (bitsAvailable >= 11) {
+ lastAscExt = ascExtId;
+ ascExtId = (TP_ASC_EXTENSION_ID)FDKreadBits(bs, 11);
+ bitsAvailable -= 11;
+
+ switch (ascExtId) {
+ case ASCEXT_SBR: /* 0x2b7 */
+ if ((self->m_extensionAudioObjectType != AOT_SBR) &&
+ (bitsAvailable >= 5)) {
+ self->m_extensionAudioObjectType = getAOT(bs);
+
+ if ((self->m_extensionAudioObjectType == AOT_SBR) ||
+ (self->m_extensionAudioObjectType ==
+ AOT_ER_BSAC)) { /* Get SBR extension configuration */
+ self->m_sbrPresentFlag = FDKreadBits(bs, 1);
+ if (self->m_aot == AOT_USAC && self->m_sbrPresentFlag > 0 &&
+ self->m_sc.m_usacConfig.m_sbrRatioIndex == 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ if (self->m_sbrPresentFlag == 1) {
+ self->m_extensionSamplingFrequency = getSampleRate(
+ bs, &self->m_extensionSamplingFrequencyIndex, 4);
+
+ if ((INT)self->m_extensionSamplingFrequency <= 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ if (self->m_extensionAudioObjectType == AOT_ER_BSAC) {
+ self->m_extensionChannelConfiguration = FDKreadBits(bs, 4);
+ }
+ }
+ /* Update counter because of variable length fields (AOT and sampling
+ * rate) */
+ bitsAvailable = (INT)FDKgetValidBits(bs);
+ }
+ break;
+ case ASCEXT_PS: /* 0x548 */
+ if ((lastAscExt == ASCEXT_SBR) &&
+ (self->m_extensionAudioObjectType == AOT_SBR) &&
+ (bitsAvailable > 0)) { /* Get PS extension configuration */
+ self->m_psPresentFlag = FDKreadBits(bs, 1);
+ bitsAvailable -= 1;
+ }
+ break;
+ case ASCEXT_MPS: /* 0x76a */
+ if (self->m_extensionAudioObjectType == AOT_MPEGS) break;
+ FDK_FALLTHROUGH;
+ case ASCEXT_LDMPS: /* 0x7cc */
+ if ((ascExtId == ASCEXT_LDMPS) &&
+ (self->m_extensionAudioObjectType == AOT_LD_MPEGS))
+ break;
+ if (bitsAvailable >= 1) {
+ bitsAvailable -= 1;
+ if (FDKreadBits(bs, 1)) { /* self->m_mpsPresentFlag */
+ int sscLen = FDKreadBits(bs, 8);
+ bitsAvailable -= 8;
+ if (sscLen == 0xFF) {
+ sscLen += FDKreadBits(bs, 16);
+ bitsAvailable -= 16;
+ }
+ FDKpushFor(bs, sscLen); /* Skip SSC to be able to read the next
+ extension if there is one. */
+
+ bitsAvailable -= sscLen * 8;
+ }
+ }
+ break;
+ case ASCEXT_SAOC:
+ if ((ascExtId == ASCEXT_SAOC) &&
+ (self->m_extensionAudioObjectType == AOT_SAOC))
+ break;
+ if (FDKreadBits(bs, 1)) { /* saocPresent */
+ int saocscLen = FDKreadBits(bs, 8);
+ bitsAvailable -= 8;
+ if (saocscLen == 0xFF) {
+ saocscLen += FDKreadBits(bs, 16);
+ bitsAvailable -= 16;
+ }
+ FDKpushFor(bs, saocscLen);
+ bitsAvailable -= saocscLen * 8;
+ }
+ break;
+ default:
+ /* Just ignore anything. */
+ return TRANSPORTDEC_OK;
+ }
+ }
+
+ return TRANSPORTDEC_OK;
+}
+
+/*
+ * API Functions
+ */
+
+void AudioSpecificConfig_Init(CSAudioSpecificConfig *asc) {
+ FDKmemclear(asc, sizeof(CSAudioSpecificConfig));
+
+ /* Init all values that should not be zero. */
+ asc->m_aot = AOT_NONE;
+ asc->m_samplingFrequencyIndex = 0xf;
+ asc->m_epConfig = -1;
+ asc->m_extensionAudioObjectType = AOT_NULL_OBJECT;
+ CProgramConfig_Init(&asc->m_progrConfigElement);
+}
+
+TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
+ CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs,
+ int fExplicitBackwardCompatible, CSTpCallBacks *cb, UCHAR configMode,
+ UCHAR configChanged, AUDIO_OBJECT_TYPE m_aot) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ UINT ascStartAnchor = FDKgetValidBits(bs);
+ int frameLengthFlag = -1;
+
+ AudioSpecificConfig_Init(self);
+
+ self->configMode = configMode;
+ self->AacConfigChanged = configChanged;
+ self->SbrConfigChanged = configChanged;
+ self->SacConfigChanged = configChanged;
+
+ if (m_aot != AOT_NULL_OBJECT) {
+ self->m_aot = m_aot;
+ } else {
+ self->m_aot = getAOT(bs);
+ self->m_samplingFrequency =
+ getSampleRate(bs, &self->m_samplingFrequencyIndex, 4);
+ if (self->m_samplingFrequency <= 0 ||
+ (self->m_samplingFrequency > 96000 && self->m_aot != 39) ||
+ self->m_samplingFrequency > 4 * 96000) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ self->m_channelConfiguration = FDKreadBits(bs, 4);
+
+ /* SBR extension ( explicit non-backwards compatible mode ) */
+ self->m_sbrPresentFlag = 0;
+ self->m_psPresentFlag = 0;
+
+ if (self->m_aot == AOT_SBR || self->m_aot == AOT_PS) {
+ self->m_extensionAudioObjectType = AOT_SBR;
+
+ self->m_sbrPresentFlag = 1;
+ if (self->m_aot == AOT_PS) {
+ self->m_psPresentFlag = 1;
+ }
+
+ self->m_extensionSamplingFrequency =
+ getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
+ self->m_aot = getAOT(bs);
+
+ switch (self->m_aot) {
+ case AOT_AAC_LC:
+ break;
+ case AOT_ER_BSAC:
+ break;
+ default:
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+
+ if (self->m_aot == AOT_ER_BSAC) {
+ self->m_extensionChannelConfiguration = FDKreadBits(bs, 4);
+ }
+ } else {
+ self->m_extensionAudioObjectType = AOT_NULL_OBJECT;
+ }
+ }
+
+ /* Parse whatever specific configs */
+ switch (self->m_aot) {
+ case AOT_AAC_LC:
+ case AOT_AAC_SCAL:
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LD:
+ case AOT_ER_AAC_SCAL:
+ case AOT_ER_BSAC:
+ if ((ErrorStatus = GaSpecificConfig_Parse(&self->m_sc.m_gaSpecificConfig,
+ self, bs, ascStartAnchor)) !=
+ TRANSPORTDEC_OK) {
+ return (ErrorStatus);
+ }
+ frameLengthFlag = self->m_sc.m_gaSpecificConfig.m_frameLengthFlag;
+ break;
+ case AOT_MPEGS:
+ if (cb->cbSsc != NULL) {
+ if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency,
+ self->m_samplesPerFrame, 1,
+ -1, /* nTimeSlots: read from bitstream */
+ 0, /* don't know the length */
+ self->configMode, &self->SacConfigChanged)) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ } else {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ break;
+ case AOT_ER_AAC_ELD:
+ if ((ErrorStatus = EldSpecificConfig_Parse(self, bs, cb)) !=
+ TRANSPORTDEC_OK) {
+ return (ErrorStatus);
+ }
+ frameLengthFlag = self->m_sc.m_eldSpecificConfig.m_frameLengthFlag;
+ self->m_sbrPresentFlag = self->m_sc.m_eldSpecificConfig.m_sbrPresentFlag;
+ self->m_extensionSamplingFrequency =
+ (self->m_sc.m_eldSpecificConfig.m_sbrSamplingRate + 1) *
+ self->m_samplingFrequency;
+ break;
+ case AOT_USAC:
+ if ((ErrorStatus = UsacConfig_Parse(self, bs, cb)) != TRANSPORTDEC_OK) {
+ return (ErrorStatus);
+ }
+ break;
+
+ default:
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+
+ /* Frame length */
+ switch (self->m_aot) {
+ case AOT_AAC_LC:
+ case AOT_AAC_SCAL:
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_SCAL:
+ case AOT_ER_BSAC:
+ /*case AOT_USAC:*/
+ if (!frameLengthFlag)
+ self->m_samplesPerFrame = 1024;
+ else
+ self->m_samplesPerFrame = 960;
+ break;
+ case AOT_ER_AAC_LD:
+ if (!frameLengthFlag)
+ self->m_samplesPerFrame = 512;
+ else
+ self->m_samplesPerFrame = 480;
+ break;
+ default:
+ break;
+ }
+
+ switch (self->m_aot) {
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LD:
+ case AOT_ER_AAC_ELD:
+ case AOT_ER_AAC_SCAL:
+ case AOT_ER_CELP:
+ case AOT_ER_HVXC:
+ case AOT_ER_BSAC:
+ self->m_epConfig = FDKreadBits(bs, 2);
+
+ if (self->m_epConfig > 1) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT; // EPCONFIG;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (fExplicitBackwardCompatible &&
+ (self->m_aot == AOT_AAC_LC || self->m_aot == AOT_ER_AAC_LD ||
+ self->m_aot == AOT_ER_BSAC)) {
+ ErrorStatus = AudioSpecificConfig_ExtensionParse(self, bs, cb);
+ }
+
+ /* Copy config() to asc->config[] buffer. */
+ if ((ErrorStatus == TRANSPORTDEC_OK) && (self->m_aot == AOT_USAC)) {
+ INT configSize_bits = (INT)FDKgetValidBits(bs) - (INT)ascStartAnchor;
+ StoreConfigAsBitstream(bs, configSize_bits, self->config,
+ TP_USAC_MAX_CONFIG_LEN);
+ self->configBits = fAbs(configSize_bits);
+ }
+
+ return (ErrorStatus);
+}
+
+static TRANSPORTDEC_ERROR Drm_xHEAACDecoderConfig(
+ CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM hBs, int audioMode,
+ CSTpCallBacks *cb /* use cb == NULL to signal config check only mode */
+) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ CSUsacConfig *usc = &asc->m_sc.m_usacConfig;
+ int elemIdx = 0;
+
+ usc->element[elemIdx].m_stereoConfigIndex = 0;
+
+ usc->m_usacNumElements = 1; /* Currently all extension elements are skipped
+ -> only one SCE or CPE. */
+
+ switch (audioMode) {
+ case 0: /* mono: ID_USAC_SCE */
+ usc->element[elemIdx].usacElementType = ID_USAC_SCE;
+ usc->m_nUsacChannels = 1;
+ usc->element[elemIdx].m_noiseFilling = FDKreadBits(hBs, 1);
+ if (usc->m_sbrRatioIndex > 0) {
+ if (cb == NULL) {
+ return ErrorStatus;
+ }
+ if (cb->cbSbr != NULL) {
+ usc->element[elemIdx].m_harmonicSBR = FDKreadBit(hBs);
+ usc->element[elemIdx].m_interTes = FDKreadBit(hBs);
+ usc->element[elemIdx].m_pvc = FDKreadBit(hBs);
+ if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
+ asc->m_extensionSamplingFrequency,
+ asc->m_samplesPerFrame, asc->m_aot, ID_SCE, elemIdx,
+ usc->element[elemIdx].m_harmonicSBR,
+ usc->element[elemIdx].m_stereoConfigIndex,
+ asc->configMode, &asc->SbrConfigChanged, 1)) {
+ return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ }
+ break;
+ case 2: /* stereo: ID_USAC_CPE */
+ usc->element[elemIdx].usacElementType = ID_USAC_CPE;
+ usc->m_nUsacChannels = 2;
+ usc->element[elemIdx].m_noiseFilling = FDKreadBits(hBs, 1);
+ if (usc->m_sbrRatioIndex > 0) {
+ usc->element[elemIdx].m_harmonicSBR = FDKreadBit(hBs);
+ usc->element[elemIdx].m_interTes = FDKreadBit(hBs);
+ usc->element[elemIdx].m_pvc = FDKreadBit(hBs);
+ {
+ INT bitsToSkip = skipSbrHeader(hBs, 1);
+ /* read stereoConfigIndex */
+ usc->element[elemIdx].m_stereoConfigIndex = FDKreadBits(hBs, 2);
+ /* rewind */
+ FDKpushBack(hBs, bitsToSkip + 2);
+ }
+ /*
+ The application of the following tools is mutually exclusive per audio
+ stream configuration (see clause 5.3.2, xHE-AAC codec configuration):
+ - MPS212 parametric stereo tool with residual coding
+ (stereoConfigIndex>1); and
+ - QMF based Harmonic Transposer (harmonicSBR==1).
+ */
+ if ((usc->element[elemIdx].m_stereoConfigIndex > 1) &&
+ usc->element[elemIdx].m_harmonicSBR) {
+ return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ /*
+ The 4:1 sbrRatio (sbrRatioIndex==1 in [11]) may only be employed:
+ - in mono operation; or
+ - in stereo operation if parametric stereo (MPS212) without residual
+ coding is applied, i.e. if stereoConfigIndex==1 (see clause 5.3.2,
+ xHE-AAC codec configuration).
+ */
+ if ((usc->m_sbrRatioIndex == 1) &&
+ (usc->element[elemIdx].m_stereoConfigIndex != 1)) {
+ return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ if (cb == NULL) {
+ return ErrorStatus;
+ }
+ {
+ MP4_ELEMENT_ID el_type =
+ (usc->element[elemIdx].m_stereoConfigIndex == 1 ||
+ usc->element[elemIdx].m_stereoConfigIndex == 2)
+ ? ID_SCE
+ : ID_CPE;
+ if (cb->cbSbr == NULL) return ErrorStatus = TRANSPORTDEC_UNKOWN_ERROR;
+ if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
+ asc->m_extensionSamplingFrequency,
+ asc->m_samplesPerFrame, asc->m_aot, el_type, elemIdx,
+ usc->element[elemIdx].m_harmonicSBR,
+ usc->element[elemIdx].m_stereoConfigIndex,
+ asc->configMode, &asc->SbrConfigChanged, 1)) {
+ return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ /*usc->element[elemIdx].m_stereoConfigIndex =*/FDKreadBits(hBs, 2);
+ if (usc->element[elemIdx].m_stereoConfigIndex > 0) {
+ if (cb->cbSsc != NULL) {
+ int samplesPerFrame = asc->m_samplesPerFrame;
+
+ if (usc->m_sbrRatioIndex == 1) samplesPerFrame <<= 2;
+ if (usc->m_sbrRatioIndex == 2)
+ samplesPerFrame = (samplesPerFrame * 8) / 3;
+ if (usc->m_sbrRatioIndex == 3) samplesPerFrame <<= 1;
+
+ ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
+ cb->cbSscData, hBs,
+ AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */
+ asc->m_extensionSamplingFrequency, samplesPerFrame,
+ usc->element[elemIdx].m_stereoConfigIndex,
+ usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */
+ asc->configMode, &asc->SacConfigChanged);
+ } else {
+ /* ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; */
+ }
+ }
+ }
+ break;
+ default:
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ return ErrorStatus;
+}
+
+TRANSPORTDEC_ERROR Drm_xHEAACStaticConfig(
+ CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM bs, int audioMode,
+ CSTpCallBacks *cb /* use cb == NULL to signal config check only mode */
+) {
+ int coreSbrFrameLengthIndexDrm = FDKreadBits(bs, 2);
+ if (UsacConfig_SetCoreSbrFrameLengthIndex(
+ asc, coreSbrFrameLengthIndexDrm + 1) != TRANSPORTDEC_OK) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ asc->m_channelConfiguration = (audioMode) ? 2 : 1;
+
+ if (Drm_xHEAACDecoderConfig(asc, bs, audioMode, cb) != TRANSPORTDEC_OK) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ return TRANSPORTDEC_OK;
+}
+
+/* Mapping of DRM audio sampling rate field to MPEG usacSamplingFrequencyIndex
+ */
+const UCHAR mapSr2MPEGIdx[8] = {
+ 0x1b, /* 9.6 kHz */
+ 0x09, /* 12.0 kHz */
+ 0x08, /* 16.0 kHz */
+ 0x17, /* 19.2 kHz */
+ 0x06, /* 24.0 kHz */
+ 0x05, /* 32.0 kHz */
+ 0x12, /* 38.4 kHz */
+ 0x03 /* 48.0 kHz */
+};
+
+TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
+ CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs,
+ CSTpCallBacks *cb, /* use cb == NULL to signal config check only mode */
+ UCHAR configMode, UCHAR configChanged) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+
+ AudioSpecificConfig_Init(self);
+
+ if ((INT)FDKgetValidBits(bs) < 16) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ } else {
+ /* DRM - Audio information data entity - type 9
+ - Short Id 2 bits (not part of the config buffer)
+ - Stream Id 2 bits (not part of the config buffer)
+ - 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;
+
+ self->configMode = configMode;
+ self->AacConfigChanged = configChanged;
+ self->SbrConfigChanged = configChanged;
+ self->SacConfigChanged = configChanged;
+
+ /* Read the SDC field */
+ 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 */
+ if (audioCoding == 3) {
+ sfIdx = (int)mapSr2MPEGIdx[cSamplingFreq];
+ sbrFlag = 0; /* rfa */
+ } else {
+ 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 */
+ if ((coderField >> 2) && (audioMode != 1)) {
+ self->m_aot = AOT_DRM_SURROUND; /* Set pseudo AOT for Drm Surround */
+ } else {
+ self->m_aot = AOT_DRM_AAC; /* Set pseudo AOT for Drm AAC */
+ }
+ switch (audioMode) {
+ case 1: /* parametric stereo */
+ self->m_psPresentFlag = 1;
+ FDK_FALLTHROUGH;
+ 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: /* xHE-AAC */
+ {
+ /* payload is MPEG conform -> no pseudo DRM AOT needed */
+ self->m_aot = AOT_USAC;
+ }
+ switch (audioMode) {
+ case 0: /* mono */
+ case 2: /* stereo */
+ /* codec specific config 8n bits */
+ ErrorStatus = Drm_xHEAACStaticConfig(self, bs, audioMode, cb);
+ break;
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ break;
+ 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);
+}
diff --git a/fdk-aac/libMpegTPDec/src/tpdec_drm.cpp b/fdk-aac/libMpegTPDec/src/tpdec_drm.cpp
new file mode 100644
index 0000000..27c1c1d
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/src/tpdec_drm.cpp
@@ -0,0 +1,148 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ 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);
+}
diff --git a/fdk-aac/libMpegTPDec/src/tpdec_drm.h b/fdk-aac/libMpegTPDec/src/tpdec_drm.h
new file mode 100644
index 0000000..09822dc
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/src/tpdec_drm.h
@@ -0,0 +1,202 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ 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.
+ * \param cb A pointer to structure holding callback
+ * information Note: A NULL pointer for cb can be used to signal a "Check Config
+ * only functionality"
+ * \param configMode Config modes: memory allocation mode or
+ * config change detection mode
+ * \param configChanged Indicates a config change
+ *
+ * \return Total element count including all SCE, CPE and LFE.
+ */
+TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(CSAudioSpecificConfig *pAsc,
+ HANDLE_FDK_BITSTREAM hBs,
+ CSTpCallBacks *cb,
+ const UCHAR configMode,
+ const UCHAR configChanged);
+
+#endif /* TPDEC_DRM_H */
diff --git a/fdk-aac/libMpegTPDec/src/tpdec_latm.cpp b/fdk-aac/libMpegTPDec/src/tpdec_latm.cpp
new file mode 100644
index 0000000..2edf055
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/src/tpdec_latm.cpp
@@ -0,0 +1,676 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ Author(s): Daniel Homm
+
+ Description:
+
+*******************************************************************************/
+
+#include "tpdec_latm.h"
+
+#include "FDK_bitstream.h"
+
+#define TPDEC_TRACKINDEX(p, l) (1 * (p) + (l))
+
+static UINT CLatmDemux_GetValue(HANDLE_FDK_BITSTREAM bs) {
+ UCHAR bytesForValue = 0, tmp = 0;
+ int value = 0;
+
+ bytesForValue = (UCHAR)FDKreadBits(bs, 2);
+
+ for (UINT i = 0; i <= bytesForValue; i++) {
+ value <<= 8;
+ tmp = (UCHAR)FDKreadBits(bs, 8);
+ value += tmp;
+ }
+
+ return value;
+}
+
+static TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement(
+ HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, int m_muxConfigPresent,
+ CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
+ int *pfConfigFound) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+
+ if (m_muxConfigPresent) {
+ pLatmDemux->m_useSameStreamMux = FDKreadBits(bs, 1);
+
+ if (!pLatmDemux->m_useSameStreamMux) {
+ int i;
+ UCHAR configChanged = 0;
+ UCHAR configMode = 0;
+
+ FDK_BITSTREAM bsAnchor;
+
+ FDK_BITSTREAM bsAnchorDummyParse;
+
+ if (!pLatmDemux->applyAsc) {
+ bsAnchorDummyParse = *bs;
+ pLatmDemux->newCfgHasAudioPreRoll = 0;
+ /* do dummy-parsing of ASC to determine if there is an audioPreRoll */
+ configMode |= AC_CM_DET_CFG_CHANGE;
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = CLatmDemux_ReadStreamMuxConfig(
+ bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound,
+ configMode, configChanged))) {
+ goto bail;
+ }
+
+ /* Allow flushing only when audioPreroll functionality is enabled in
+ * current and new config otherwise the new config can be applied
+ * immediately. */
+ if (pAsc->m_sc.m_usacConfig.element[0]
+ .extElement.usacExtElementHasAudioPreRoll &&
+ pLatmDemux->newCfgHasAudioPreRoll) {
+ pLatmDemux->newCfgHasAudioPreRoll = 0;
+ /* with audioPreRoll we must flush before applying new cfg */
+ pLatmDemux->applyAsc = 0;
+ } else {
+ *bs = bsAnchorDummyParse;
+ pLatmDemux->applyAsc = 1; /* apply new config immediate */
+ }
+ }
+
+ if (pLatmDemux->applyAsc) {
+ for (i = 0; i < 2; i++) {
+ configMode = 0;
+
+ if (i == 0) {
+ configMode |= AC_CM_DET_CFG_CHANGE;
+ bsAnchor = *bs;
+ } else {
+ configMode |= AC_CM_ALLOC_MEM;
+ *bs = bsAnchor;
+ }
+
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = CLatmDemux_ReadStreamMuxConfig(
+ bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound,
+ configMode, configChanged))) {
+ goto bail;
+ }
+
+ if (ErrorStatus == TRANSPORTDEC_OK) {
+ if ((i == 0) && (pAsc->AacConfigChanged || pAsc->SbrConfigChanged ||
+ pAsc->SacConfigChanged)) {
+ int errC;
+
+ configChanged = 1;
+ errC = pTpDecCallbacks->cbFreeMem(pTpDecCallbacks->cbFreeMemData,
+ pAsc);
+ if (errC != 0) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* If there was no configuration read, its not possible to parse
+ * PayloadLengthInfo below. */
+ if (!*pfConfigFound) {
+ ErrorStatus = TRANSPORTDEC_SYNC_ERROR;
+ goto bail;
+ }
+
+ if (pLatmDemux->m_AudioMuxVersionA == 0) {
+ /* Do only once per call, because parsing and decoding is done in-line. */
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = CLatmDemux_ReadPayloadLengthInfo(bs, pLatmDemux))) {
+ *pfConfigFound = 0;
+ goto bail;
+ }
+ } else {
+ /* audioMuxVersionA > 0 is reserved for future extensions */
+ ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ *pfConfigFound = 0;
+ goto bail;
+ }
+
+bail:
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ pLatmDemux->applyAsc = 1;
+ }
+
+ return (ErrorStatus);
+}
+
+TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs,
+ CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt,
+ CSTpCallBacks *pTpDecCallbacks,
+ CSAudioSpecificConfig *pAsc,
+ int *pfConfigFound,
+ const INT ignoreBufferFullness) {
+ UINT cntBits;
+ UINT cmpBufferFullness;
+ UINT audioMuxLengthBytesLast = 0;
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+
+ cntBits = FDKgetValidBits(bs);
+
+ if ((INT)cntBits < MIN_LATM_HEADERLENGTH) {
+ return TRANSPORTDEC_NOT_ENOUGH_BITS;
+ }
+
+ if (TRANSPORTDEC_OK != (ErrorStatus = CLatmDemux_ReadAudioMuxElement(
+ bs, pLatmDemux, (tt != TT_MP4_LATM_MCP0),
+ pTpDecCallbacks, pAsc, pfConfigFound)))
+ return (ErrorStatus);
+
+ if (!ignoreBufferFullness) {
+ cmpBufferFullness =
+ 24 + audioMuxLengthBytesLast * 8 +
+ pLatmDemux->m_linfo[0][0].m_bufferFullness *
+ pAsc[TPDEC_TRACKINDEX(0, 0)].m_channelConfiguration * 32;
+
+ /* evaluate buffer fullness */
+
+ if (pLatmDemux->m_linfo[0][0].m_bufferFullness != 0xFF) {
+ if (!pLatmDemux->BufferFullnessAchieved) {
+ if (cntBits < cmpBufferFullness) {
+ /* condition for start of decoding is not fulfilled */
+
+ /* the current frame will not be decoded */
+ return TRANSPORTDEC_NOT_ENOUGH_BITS;
+ } else {
+ pLatmDemux->BufferFullnessAchieved = 1;
+ }
+ }
+ }
+ }
+
+ return (ErrorStatus);
+}
+
+TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig(
+ HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux,
+ CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
+ int *pfConfigFound, UCHAR configMode, UCHAR configChanged) {
+ CSAudioSpecificConfig ascDummy; /* the actual config is needed for flushing,
+ after that new config can be parsed */
+ CSAudioSpecificConfig *pAscDummy;
+ pAscDummy = &ascDummy;
+ pLatmDemux->usacExplicitCfgChanged = 0;
+ LATM_LAYER_INFO *p_linfo = NULL;
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ UCHAR updateConfig[1 * 1] = {0};
+
+ pLatmDemux->m_AudioMuxVersion = FDKreadBits(bs, 1);
+
+ if (pLatmDemux->m_AudioMuxVersion == 0) {
+ pLatmDemux->m_AudioMuxVersionA = 0;
+ } else {
+ pLatmDemux->m_AudioMuxVersionA = FDKreadBits(bs, 1);
+ }
+
+ if (pLatmDemux->m_AudioMuxVersionA == 0) {
+ if (pLatmDemux->m_AudioMuxVersion == 1) {
+ pLatmDemux->m_taraBufferFullness = CLatmDemux_GetValue(bs);
+ }
+ pLatmDemux->m_allStreamsSameTimeFraming = FDKreadBits(bs, 1);
+ pLatmDemux->m_noSubFrames = FDKreadBits(bs, 6) + 1;
+ pLatmDemux->m_numProgram = FDKreadBits(bs, 4) + 1;
+
+ if (pLatmDemux->m_numProgram > LATM_MAX_PROG) {
+ ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ goto bail;
+ }
+
+ int idCnt = 0;
+ for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
+ pLatmDemux->m_numLayer[prog] = FDKreadBits(bs, 3) + 1;
+ if (pLatmDemux->m_numLayer[prog] > LATM_MAX_LAYER) {
+ ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ goto bail;
+ }
+
+ for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
+ int useSameConfig;
+ p_linfo = &pLatmDemux->m_linfo[prog][lay];
+
+ p_linfo->m_streamID = idCnt++;
+ p_linfo->m_frameLengthInBits = 0;
+
+ if ((prog == 0) && (lay == 0)) {
+ useSameConfig = 0;
+ } else {
+ useSameConfig = FDKreadBits(bs, 1);
+ }
+
+ if (useSameConfig) {
+ if (lay > 0) {
+ FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)],
+ &pAsc[TPDEC_TRACKINDEX(prog, lay - 1)],
+ sizeof(CSAudioSpecificConfig));
+ } else {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ } else {
+ UINT usacConfigLengthPrev = 0;
+ UCHAR usacConfigPrev[TP_USAC_MAX_CONFIG_LEN];
+
+ if (!(pLatmDemux->applyAsc) &&
+ (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_USAC)) {
+ usacConfigLengthPrev =
+ (UINT)(pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfigBits +
+ 7) >>
+ 3; /* store previous USAC config length */
+ if (usacConfigLengthPrev > TP_USAC_MAX_CONFIG_LEN) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ FDKmemclear(usacConfigPrev, TP_USAC_MAX_CONFIG_LEN);
+ FDKmemcpy(
+ usacConfigPrev,
+ &pAsc[TPDEC_TRACKINDEX(prog, lay)].m_sc.m_usacConfig.UsacConfig,
+ usacConfigLengthPrev); /* store previous USAC config */
+ }
+ if (pLatmDemux->m_AudioMuxVersion == 1) {
+ FDK_BITSTREAM tmpBs;
+ UINT ascLen = 0;
+ ascLen = CLatmDemux_GetValue(bs);
+ /* The ascLen could be wrong, so check if validBits<=bufBits*/
+ if (ascLen > FDKgetValidBits(bs)) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ FDKsyncCache(bs);
+ tmpBs = *bs;
+ tmpBs.hBitBuf.ValidBits = ascLen;
+
+ /* Read ASC */
+ if (pLatmDemux->applyAsc) {
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = AudioSpecificConfig_Parse(
+ &pAsc[TPDEC_TRACKINDEX(prog, lay)], &tmpBs, 1,
+ pTpDecCallbacks, configMode, configChanged,
+ AOT_NULL_OBJECT)))
+ goto bail;
+ } else {
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = AudioSpecificConfig_Parse(
+ pAscDummy, &tmpBs, 1, pTpDecCallbacks, configMode,
+ configChanged, AOT_NULL_OBJECT)))
+ goto bail;
+ }
+
+ /* The field p_linfo->m_ascLen could be wrong, so check if */
+ if (0 > (INT)FDKgetValidBits(&tmpBs)) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ FDKpushFor(bs, ascLen); /* position bitstream after ASC */
+ } else {
+ /* Read ASC */
+ if (pLatmDemux->applyAsc) {
+ if (TRANSPORTDEC_OK != (ErrorStatus = AudioSpecificConfig_Parse(
+ &pAsc[TPDEC_TRACKINDEX(prog, lay)],
+ bs, 0, pTpDecCallbacks, configMode,
+ configChanged, AOT_NULL_OBJECT)))
+ goto bail;
+ } else {
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = AudioSpecificConfig_Parse(
+ pAscDummy, bs, 0, pTpDecCallbacks, configMode,
+ configChanged, AOT_NULL_OBJECT)))
+ goto bail;
+ }
+ }
+ if (!pLatmDemux->applyAsc) {
+ updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 0;
+ } else {
+ updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 1;
+ }
+
+ if (!pLatmDemux->applyAsc) {
+ if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)].m_aot ==
+ AOT_USAC) { /* flush in case SMC has changed */
+ const UINT usacConfigLength =
+ (UINT)(pAscDummy->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3;
+ if (usacConfigLength > TP_USAC_MAX_CONFIG_LEN) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ if (usacConfigLength != usacConfigLengthPrev) {
+ FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfig,
+ TP_USAC_MAX_CONFIG_LEN);
+ FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfig,
+ &pAscDummy->m_sc.m_usacConfig.UsacConfig,
+ usacConfigLength); /* store new USAC config */
+ pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfigBits =
+ pAscDummy->m_sc.m_usacConfig.UsacConfigBits;
+ pLatmDemux->usacExplicitCfgChanged = 1;
+ } else {
+ if (FDKmemcmp(usacConfigPrev,
+ pAscDummy->m_sc.m_usacConfig.UsacConfig,
+ usacConfigLengthPrev)) {
+ FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfig,
+ TP_USAC_MAX_CONFIG_LEN);
+ FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfig,
+ &pAscDummy->m_sc.m_usacConfig.UsacConfig,
+ usacConfigLength); /* store new USAC config */
+ pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfigBits =
+ pAscDummy->m_sc.m_usacConfig.UsacConfigBits;
+ pLatmDemux->usacExplicitCfgChanged = 1;
+ }
+ }
+
+ if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.m_usacNumElements) {
+ if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.element[0]
+ .extElement.usacExtElementHasAudioPreRoll) {
+ pLatmDemux->newCfgHasAudioPreRoll =
+ 1; /* if dummy parsed cfg has audioPreRoll we first flush
+ before applying new cfg */
+ }
+ }
+ }
+ }
+ }
+
+ p_linfo->m_frameLengthType = FDKreadBits(bs, 3);
+ switch (p_linfo->m_frameLengthType) {
+ case 0:
+ p_linfo->m_bufferFullness = FDKreadBits(bs, 8);
+
+ if (!pLatmDemux->m_allStreamsSameTimeFraming) {
+ if ((lay > 0) &&
+ (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_AAC_SCAL ||
+ pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot ==
+ AOT_ER_AAC_SCAL) &&
+ (pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot == AOT_CELP ||
+ pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot ==
+ AOT_ER_CELP)) { /* The layer maybe
+ ignored later so
+ read it anyway: */
+ /* coreFrameOffset = */ FDKreadBits(bs, 6);
+ }
+ }
+ break;
+ case 1:
+ p_linfo->m_frameLengthInBits = FDKreadBits(bs, 9);
+ break;
+ case 3:
+ case 4:
+ case 5:
+ /* CELP */
+ case 6:
+ case 7:
+ /* HVXC */
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ } /* switch framelengthtype*/
+
+ } /* layer loop */
+ } /* prog loop */
+
+ pLatmDemux->m_otherDataPresent = FDKreadBits(bs, 1);
+ pLatmDemux->m_otherDataLength = 0;
+
+ if (pLatmDemux->m_otherDataPresent) {
+ if (pLatmDemux->m_AudioMuxVersion == 1) {
+ pLatmDemux->m_otherDataLength = CLatmDemux_GetValue(bs);
+ } else {
+ int otherDataLenEsc = 0;
+ do {
+ pLatmDemux->m_otherDataLength <<= 8; // *= 256
+ otherDataLenEsc = FDKreadBits(bs, 1);
+ pLatmDemux->m_otherDataLength += FDKreadBits(bs, 8);
+ } while (otherDataLenEsc);
+ }
+ if (pLatmDemux->m_audioMuxLengthBytes <
+ (pLatmDemux->m_otherDataLength >> 3)) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ pLatmDemux->m_crcCheckPresent = FDKreadBits(bs, 1);
+
+ if (pLatmDemux->m_crcCheckPresent) {
+ FDKreadBits(bs, 8);
+ }
+
+ } else {
+ /* audioMuxVersionA > 0 is reserved for future extensions */
+ ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+
+ /* Configure source decoder: */
+ if (ErrorStatus == TRANSPORTDEC_OK) {
+ UINT prog;
+ for (prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
+ UINT lay;
+ for (lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
+ if (updateConfig[TPDEC_TRACKINDEX(prog, lay)] != 0) {
+ int cbError;
+ cbError = pTpDecCallbacks->cbUpdateConfig(
+ pTpDecCallbacks->cbUpdateConfigData,
+ &pAsc[TPDEC_TRACKINDEX(prog, lay)],
+ pAsc[TPDEC_TRACKINDEX(prog, lay)].configMode,
+ &pAsc[TPDEC_TRACKINDEX(prog, lay)].AacConfigChanged);
+ if (cbError == TRANSPORTDEC_NEED_TO_RESTART) {
+ *pfConfigFound = 0;
+ ErrorStatus = TRANSPORTDEC_NEED_TO_RESTART;
+ goto bail;
+ }
+ if (cbError != 0) {
+ *pfConfigFound = 0;
+ if (lay == 0) {
+ ErrorStatus = TRANSPORTDEC_SYNC_ERROR;
+ goto bail;
+ }
+ } else {
+ *pfConfigFound = 1;
+ }
+ } else {
+ *pfConfigFound = 1;
+ }
+ }
+ }
+ }
+
+bail:
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ UCHAR applyAsc = pLatmDemux->applyAsc;
+ FDKmemclear(pLatmDemux, sizeof(CLatmDemux)); /* reset structure */
+ pLatmDemux->applyAsc = applyAsc;
+ } else {
+ /* no error and config parsing is finished */
+ if (configMode == AC_CM_ALLOC_MEM) pLatmDemux->applyAsc = 0;
+ }
+
+ return (ErrorStatus);
+}
+
+TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,
+ CLatmDemux *pLatmDemux) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ int totalPayloadBits = 0;
+
+ if (pLatmDemux->m_allStreamsSameTimeFraming == 1) {
+ FDK_ASSERT(pLatmDemux->m_numProgram <= LATM_MAX_PROG);
+ for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
+ FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER);
+ for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
+ LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay];
+
+ switch (p_linfo->m_frameLengthType) {
+ case 0:
+ p_linfo->m_frameLengthInBits = CLatmDemux_ReadAuChunkLengthInfo(bs);
+ totalPayloadBits += p_linfo->m_frameLengthInBits;
+ break;
+ case 3:
+ case 5:
+ case 7:
+ default:
+ return TRANSPORTDEC_PARSE_ERROR; // AAC_DEC_LATM_INVALIDFRAMELENGTHTYPE;
+ }
+ }
+ }
+ } else {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR; // AAC_DEC_LATM_TIMEFRAMING;
+ }
+ if (pLatmDemux->m_audioMuxLengthBytes > (UINT)0 &&
+ totalPayloadBits > (int)pLatmDemux->m_audioMuxLengthBytes * 8) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ return (ErrorStatus);
+}
+
+int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) {
+ UCHAR endFlag;
+ int len = 0;
+
+ do {
+ UCHAR tmp = (UCHAR)FDKreadBits(bs, 8);
+ endFlag = (tmp < 255);
+
+ len += tmp;
+
+ } while (endFlag == 0);
+
+ len <<= 3; /* convert from bytes to bits */
+
+ return len;
+}
+
+UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog,
+ const UINT layer) {
+ UINT nFrameLenBits = 0;
+ if (prog < pLatmDemux->m_numProgram) {
+ if (layer < pLatmDemux->m_numLayer[prog]) {
+ nFrameLenBits = pLatmDemux->m_linfo[prog][layer].m_frameLengthInBits;
+ }
+ }
+ return nFrameLenBits;
+}
+
+UINT CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux) {
+ return pLatmDemux->m_otherDataPresent ? 1 : 0;
+}
+
+UINT CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux) {
+ return pLatmDemux->m_otherDataLength;
+}
+
+UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux) {
+ return pLatmDemux->m_noSubFrames;
+}
+
+UINT CLatmDemux_GetNrOfLayers(CLatmDemux *pLatmDemux, const UINT prog) {
+ UINT numLayer = 0;
+ if (prog < pLatmDemux->m_numProgram) {
+ numLayer = pLatmDemux->m_numLayer[prog];
+ }
+ return numLayer;
+}
diff --git a/fdk-aac/libMpegTPDec/src/tpdec_latm.h b/fdk-aac/libMpegTPDec/src/tpdec_latm.h
new file mode 100644
index 0000000..6af553d
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/src/tpdec_latm.h
@@ -0,0 +1,191 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ Author(s): Daniel Homm
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef TPDEC_LATM_H
+#define TPDEC_LATM_H
+
+#include "tpdec_lib.h"
+
+#include "FDK_bitstream.h"
+
+#define MIN_LATM_HEADERLENGTH 9
+#define MIN_LOAS_HEADERLENGTH MIN_LATM_HEADERLENGTH + 24 /* both in bits */
+#define MIN_TP_BUF_SIZE_LOAS (8194)
+
+enum {
+ LATM_MAX_PROG = 1,
+ LATM_MAX_LAYER = 1,
+ LATM_MAX_VAR_CHUNKS = 16,
+ LATM_MAX_ID = 16
+};
+
+typedef struct {
+ UINT m_frameLengthType;
+ UINT m_bufferFullness;
+ UINT m_streamID;
+ UINT m_frameLengthInBits;
+} LATM_LAYER_INFO;
+
+typedef struct {
+ LATM_LAYER_INFO m_linfo[LATM_MAX_PROG][LATM_MAX_LAYER];
+ UINT m_taraBufferFullness;
+ UINT m_otherDataLength;
+ UINT m_audioMuxLengthBytes; /* Length of LOAS payload */
+
+ UCHAR m_useSameStreamMux;
+ UCHAR m_AudioMuxVersion;
+ UCHAR m_AudioMuxVersionA;
+ UCHAR m_allStreamsSameTimeFraming;
+ UCHAR m_noSubFrames;
+ UCHAR m_numProgram;
+ UCHAR m_numLayer[LATM_MAX_PROG];
+
+ UCHAR m_otherDataPresent;
+ UCHAR m_crcCheckPresent;
+
+ SCHAR BufferFullnessAchieved;
+ UCHAR
+ usacExplicitCfgChanged; /* explicit config in case of USAC and LOAS/LATM
+ must be compared to IPF cfg */
+ UCHAR applyAsc; /* apply ASC immediate without flushing */
+ UCHAR newCfgHasAudioPreRoll; /* the new (dummy parsed) config has an
+ AudioPreRoll */
+} CLatmDemux;
+
+int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs);
+
+TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs,
+ CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt,
+ CSTpCallBacks *pTpDecCallbacks,
+ CSAudioSpecificConfig *pAsc,
+ int *pfConfigFound,
+ const INT ignoreBufferFullness);
+
+/**
+ * \brief Read StreamMuxConfig
+ * \param bs bit stream handle as data source
+ * \param pLatmDemux pointer to CLatmDemux struct of current LATM context
+ * \param pTpDecCallbacks Call back structure for configuration callbacks
+ * \param pAsc pointer to a ASC for configuration storage
+ * \param pfConfigFound pointer to a flag which is set to 1 if a configuration
+ * was found and processed successfully
+ * \param configMode Config modes: memory allocation mode or config change
+ * detection mode
+ * \param configChanged Indicates a config change
+ * \return error code
+ */
+TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig(
+ HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux,
+ CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
+ int *pfConfigFound, UCHAR configMode, UCHAR configChanged);
+
+TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,
+ CLatmDemux *pLatmDemux);
+
+UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog,
+ const UINT layer);
+UINT CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux);
+UINT CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux);
+UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux);
+UINT CLatmDemux_GetNrOfLayers(CLatmDemux *pLatmDemux, const UINT program);
+
+#endif /* TPDEC_LATM_H */
diff --git a/fdk-aac/libMpegTPDec/src/tpdec_lib.cpp b/fdk-aac/libMpegTPDec/src/tpdec_lib.cpp
new file mode 100644
index 0000000..1976cb9
--- /dev/null
+++ b/fdk-aac/libMpegTPDec/src/tpdec_lib.cpp
@@ -0,0 +1,1820 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format decoder library *********************
+
+ Author(s): Manuel Jander
+
+ Description: MPEG Transport decoder
+
+*******************************************************************************/
+
+#include "tpdec_lib.h"
+
+/* library version */
+#include "tp_version.h"
+
+#include "tp_data.h"
+
+#include "tpdec_adts.h"
+
+#include "tpdec_adif.h"
+
+#include "tpdec_latm.h"
+
+#include "tpdec_drm.h"
+
+#include "FDK_crc.h"
+
+#define MODULE_NAME "transportDec"
+
+typedef union {
+ STRUCT_ADTS adts;
+
+ CAdifHeader adif;
+
+ CLatmDemux latm;
+
+ STRUCT_DRM drm;
+
+} transportdec_parser_t;
+
+#define MHAS_CONFIG_PRESENT 0x001
+#define MHAS_UI_PRESENT 0x002
+
+struct TRANSPORTDEC {
+ TRANSPORT_TYPE transportFmt; /*!< MPEG4 transportDec type. */
+
+ CSTpCallBacks callbacks; /*!< Struct holding callback and its data */
+
+ FDK_BITSTREAM bitStream[1]; /* Bitstream reader */
+ UCHAR *bsBuffer; /* Internal bitstreamd data buffer */
+
+ transportdec_parser_t parser; /* Format specific parser structs. */
+
+ CSAudioSpecificConfig asc[(1 * 1) + 1]; /* Audio specific config from the last
+ config found. One additional
+ CSAudioSpecificConfig is used
+ temporarily for parsing. */
+ CCtrlCFGChange ctrlCFGChange[(1 * 1)]; /* Controls config change */
+
+ UINT globalFramePos; /* Global transport frame reference bit position. */
+ UINT accessUnitAnchor[1]; /* Current access unit start bit position. */
+ INT auLength[1]; /* Length of current access unit. */
+ INT numberOfRawDataBlocks; /* Current number of raw data blocks contained
+ remaining from the current transport frame. */
+ UINT avgBitRate; /* Average bit rate used for frame loss estimation. */
+ UINT lastValidBufferFullness; /* Last valid buffer fullness value for frame
+ loss estimation */
+ INT remainder; /* Reminder in division during lost access unit estimation. */
+ INT missingAccessUnits; /* Estimated missing access units. */
+ UINT burstPeriod; /* Data burst period in mili seconds. */
+ UINT holdOffFrames; /* Amount of frames that were already hold off due to
+ buffer fullness condition not being met. */
+ UINT flags; /* Flags. */
+ INT targetLayout; /* CICP target layout. */
+ UINT *pLoudnessInfoSetPosition; /* Reference and start position (bits) and
+ length (bytes) of loudnessInfoSet within
+ rsv603daConfig. */
+};
+
+/* Flag bitmasks for "flags" member of struct TRANSPORTDEC */
+#define TPDEC_SYNCOK 1
+#define TPDEC_MINIMIZE_DELAY 2
+#define TPDEC_IGNORE_BUFFERFULLNESS 4
+#define TPDEC_EARLY_CONFIG 8
+#define TPDEC_LOST_FRAMES_PENDING 16
+#define TPDEC_CONFIG_FOUND 32
+#define TPDEC_USE_ELEM_SKIPPING 64
+
+/* force config/content change */
+#define TPDEC_FORCE_CONFIG_CHANGE 1
+#define TPDEC_FORCE_CONTENT_CHANGE 2
+
+/* skip packet */
+#define TPDEC_SKIP_PACKET 1
+
+C_ALLOC_MEM(Ram_TransportDecoder, struct TRANSPORTDEC, 1)
+C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, (8192 * 4))
+
+HANDLE_TRANSPORTDEC transportDec_Open(const TRANSPORT_TYPE transportFmt,
+ const UINT flags, const UINT nrOfLayers) {
+ HANDLE_TRANSPORTDEC hInput;
+
+ hInput = GetRam_TransportDecoder(0);
+ if (hInput == NULL) {
+ return NULL;
+ }
+
+ /* Init transportDec struct. */
+ hInput->transportFmt = transportFmt;
+
+ switch (transportFmt) {
+ case TT_MP4_ADIF:
+ break;
+
+ case TT_MP4_ADTS:
+ if (flags & TP_FLAG_MPEG4)
+ hInput->parser.adts.decoderCanDoMpeg4 = 1;
+ else
+ hInput->parser.adts.decoderCanDoMpeg4 = 0;
+ adtsRead_CrcInit(&hInput->parser.adts);
+ hInput->parser.adts.BufferFullnesStartFlag = 1;
+ hInput->numberOfRawDataBlocks = 0;
+ break;
+
+ case TT_DRM:
+ drmRead_CrcInit(&hInput->parser.drm);
+ break;
+
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ hInput->parser.latm.usacExplicitCfgChanged = 0;
+ hInput->parser.latm.applyAsc = 1;
+ break;
+ case TT_MP4_LOAS:
+ hInput->parser.latm.usacExplicitCfgChanged = 0;
+ hInput->parser.latm.applyAsc = 1;
+ break;
+ case TT_MP4_RAW:
+ break;
+
+ default:
+ FreeRam_TransportDecoder(&hInput);
+ hInput = NULL;
+ break;
+ }
+
+ if (hInput != NULL) {
+ /* Create bitstream */
+ {
+ hInput->bsBuffer = GetRam_TransportDecoderBuffer(0);
+ if (hInput->bsBuffer == NULL) {
+ transportDec_Close(&hInput);
+ return NULL;
+ }
+ if (nrOfLayers > 1) {
+ transportDec_Close(&hInput);
+ return NULL;
+ }
+ for (UINT i = 0; i < nrOfLayers; i++) {
+ FDKinitBitStream(&hInput->bitStream[i], hInput->bsBuffer, (8192 * 4), 0,
+ BS_READER);
+ }
+ }
+ hInput->burstPeriod = 0;
+ }
+
+ return hInput;
+}
+
+TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp,
+ UCHAR *conf, const UINT length,
+ UINT layer) {
+ int i;
+
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+
+ FDK_BITSTREAM bs;
+ HANDLE_FDK_BITSTREAM hBs = &bs;
+
+ int fConfigFound = 0;
+
+ UCHAR configChanged = 0;
+ UCHAR configMode = AC_CM_DET_CFG_CHANGE;
+
+ UCHAR tmpConf[1024];
+ if (length > 1024) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ FDKmemcpy(tmpConf, conf, length);
+ FDKinitBitStream(hBs, tmpConf, 1024, length << 3, BS_READER);
+
+ for (i = 0; i < 2; i++) {
+ if (i > 0) {
+ FDKpushBack(hBs, (INT)length * 8 - (INT)FDKgetValidBits(hBs));
+ configMode = AC_CM_ALLOC_MEM;
+ }
+
+ /* config transport decoder */
+ switch (hTp->transportFmt) {
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LOAS: {
+ if (layer != 0) {
+ return TRANSPORTDEC_INVALID_PARAMETER;
+ }
+ CLatmDemux *pLatmDemux = &hTp->parser.latm;
+ err = CLatmDemux_ReadStreamMuxConfig(hBs, pLatmDemux, &hTp->callbacks,
+ hTp->asc, &fConfigFound,
+ configMode, configChanged);
+ if (err != TRANSPORTDEC_OK) {
+ return err;
+ }
+ } break;
+ default:
+ fConfigFound = 1;
+ err = AudioSpecificConfig_Parse(&hTp->asc[(1 * 1)], hBs, 1,
+ &hTp->callbacks, configMode,
+ configChanged, AOT_NULL_OBJECT);
+ if (err == TRANSPORTDEC_OK) {
+ int errC;
+
+ hTp->asc[layer] = hTp->asc[(1 * 1)];
+ errC = hTp->callbacks.cbUpdateConfig(
+ hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
+ hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ break;
+ case TT_DRM:
+ fConfigFound = 1;
+ err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs, &hTp->callbacks,
+ configMode, configChanged);
+ if (err == TRANSPORTDEC_OK) {
+ int errC;
+
+ errC = hTp->callbacks.cbUpdateConfig(
+ hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
+ hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ break;
+ }
+
+ if (err == TRANSPORTDEC_OK) {
+ if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
+ hTp->asc[layer].SbrConfigChanged ||
+ hTp->asc[layer].SacConfigChanged)) {
+ int errC;
+
+ configChanged = 1;
+ errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
+ &hTp->asc[layer]);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ }
+ }
+
+ if (err == TRANSPORTDEC_OK && fConfigFound) {
+ hTp->flags |= TPDEC_CONFIG_FOUND;
+ }
+
+ return err;
+}
+
+TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,
+ UCHAR *newConfig,
+ const UINT newConfigLength,
+ const UCHAR buildUpStatus,
+ UCHAR *configChanged, UINT layer,
+ UCHAR *implicitExplicitCfgDiff) {
+ int errC;
+ FDK_BITSTREAM bs;
+ HANDLE_FDK_BITSTREAM hBs = &bs;
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+ int fConfigFound = 0;
+ UCHAR configMode = AC_CM_ALLOC_MEM;
+ *implicitExplicitCfgDiff = 0;
+
+ FDK_ASSERT(hTp->asc->m_aot == AOT_USAC);
+
+ FDKinitBitStream(hBs, newConfig, TP_USAC_MAX_CONFIG_LEN, newConfigLength << 3,
+ BS_READER);
+
+ if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
+ (hTp->ctrlCFGChange[layer].buildUpStatus !=
+ TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
+ if (hTp->asc->m_aot == AOT_USAC) {
+ if ((UINT)(hTp->asc->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3 ==
+ newConfigLength) {
+ if (0 == FDKmemcmp(newConfig, hTp->asc->m_sc.m_usacConfig.UsacConfig,
+ newConfigLength)) {
+ if (hTp->parser.latm.usacExplicitCfgChanged) { /* configChange from
+ LOAS/LATM parser */
+ hTp->parser.latm.usacExplicitCfgChanged = 0;
+ hTp->ctrlCFGChange[layer].flushCnt = 0;
+ hTp->ctrlCFGChange[layer].flushStatus =
+ TPDEC_USAC_DASH_IPF_FLUSH_ON;
+ hTp->ctrlCFGChange[layer].buildUpCnt = 0;
+ hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
+ } else {
+ *configChanged = 0;
+ return err;
+ }
+ } else {
+ *implicitExplicitCfgDiff = 1;
+ }
+ } else {
+ *implicitExplicitCfgDiff = 1;
+ }
+ /* ISO/IEC 23003-3:2012/FDAM 3:2016(E) Annex F.2: explicit and implicit
+ * config shall be identical. */
+ if (*implicitExplicitCfgDiff) {
+ switch (hTp->transportFmt) {
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LOAS:
+ /* reset decoder to initial state to achieve definite behavior after
+ * error in config */
+ hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
+ &hTp->asc[layer]);
+ hTp->parser.latm.usacExplicitCfgChanged = 0;
+ hTp->parser.latm.applyAsc = 1;
+ err = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ {
+ if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
+ (hTp->ctrlCFGChange[layer].buildUpStatus !=
+ TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
+ hTp->ctrlCFGChange[layer].flushCnt = 0;
+ hTp->ctrlCFGChange[layer].buildUpCnt = 0;
+ hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
+ if (hTp->asc->m_aot == AOT_USAC) {
+ hTp->ctrlCFGChange[layer].flushStatus = TPDEC_USAC_DASH_IPF_FLUSH_ON;
+ }
+ }
+
+ if ((hTp->ctrlCFGChange[layer].flushStatus ==
+ TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
+ (hTp->ctrlCFGChange[layer].flushStatus ==
+ TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
+ SCHAR counter = 0;
+ if (hTp->asc->m_aot == AOT_USAC) {
+ counter = TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES;
+ }
+ if (hTp->ctrlCFGChange[layer].flushCnt >= counter) {
+ hTp->ctrlCFGChange[layer].flushCnt = 0;
+ hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
+ hTp->ctrlCFGChange[layer].forceCfgChange = 0;
+ if (hTp->asc->m_aot == AOT_USAC) {
+ hTp->ctrlCFGChange[layer].buildUpCnt =
+ TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES - 1;
+ hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_USAC_BUILD_UP_ON;
+ }
+ }
+
+ /* Activate flush mode. After that continue with build up mode in core */
+ if (hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
+ &hTp->ctrlCFGChange[layer]) != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ if ((hTp->ctrlCFGChange[layer].flushStatus ==
+ TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
+ (hTp->ctrlCFGChange[layer].flushStatus ==
+ TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
+ hTp->ctrlCFGChange[layer].flushCnt++;
+ return err;
+ }
+ }
+
+ if (hTp->asc->m_aot == AOT_USAC) {
+ fConfigFound = 1;
+
+ if (err == TRANSPORTDEC_OK) {
+ *configChanged = 0;
+ configMode = AC_CM_DET_CFG_CHANGE;
+
+ for (int i = 0; i < 2; i++) {
+ if (i > 0) {
+ FDKpushBack(hBs, newConfigLength * 8 - FDKgetValidBits(hBs));
+ configMode = AC_CM_ALLOC_MEM;
+ }
+ /* config transport decoder */
+ err = AudioSpecificConfig_Parse(
+ &hTp->asc[(1 * 1)], hBs, 0, &hTp->callbacks, configMode,
+ *configChanged, hTp->asc[layer].m_aot);
+ if (err == TRANSPORTDEC_OK) {
+ hTp->asc[layer] = hTp->asc[(1 * 1)];
+ errC = hTp->callbacks.cbUpdateConfig(
+ hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
+ hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+
+ if (err == TRANSPORTDEC_OK) {
+ if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
+ hTp->asc[layer].SbrConfigChanged ||
+ hTp->asc[layer].SacConfigChanged)) {
+ *configChanged = 1;
+ errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
+ &hTp->asc[layer]);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ }
+
+ /* if an error is detected terminate config parsing to avoid that an
+ * invalid config is accepted in the second pass */
+ if (err != TRANSPORTDEC_OK) {
+ break;
+ }
+ }
+ }
+ }
+
+ bail:
+ /* save new config */
+ if (err == TRANSPORTDEC_OK) {
+ if (hTp->asc->m_aot == AOT_USAC) {
+ hTp->asc->m_sc.m_usacConfig.UsacConfigBits = newConfigLength << 3;
+ FDKmemcpy(hTp->asc->m_sc.m_usacConfig.UsacConfig, newConfig,
+ newConfigLength);
+ /* in case of USAC reset transportDecoder variables here because
+ * otherwise without IPF they are not reset */
+ hTp->ctrlCFGChange[layer].flushCnt = 0;
+ hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
+ hTp->ctrlCFGChange[layer].buildUpCnt = 0;
+ hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
+ }
+ } else {
+ hTp->numberOfRawDataBlocks = 0;
+
+ /* If parsing error while config found, clear ctrlCFGChange-struct */
+ hTp->ctrlCFGChange[layer].flushCnt = 0;
+ hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
+ hTp->ctrlCFGChange[layer].buildUpCnt = 0;
+ hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
+ hTp->ctrlCFGChange[layer].cfgChanged = 0;
+ hTp->ctrlCFGChange[layer].contentChanged = 0;
+ hTp->ctrlCFGChange[layer].forceCfgChange = 0;
+
+ hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
+ &hTp->ctrlCFGChange[layer]);
+ }
+ }
+
+ if (err == TRANSPORTDEC_OK && fConfigFound) {
+ hTp->flags |= TPDEC_CONFIG_FOUND;
+ }
+
+ return err;
+}
+
+int transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbUpdateConfig_t cbUpdateConfig,
+ void *user_data) {
+ if (hTpDec == NULL) {
+ return -1;
+ }
+ hTpDec->callbacks.cbUpdateConfig = cbUpdateConfig;
+ hTpDec->callbacks.cbUpdateConfigData = user_data;
+ return 0;
+}
+
+int transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbFreeMem_t cbFreeMem,
+ void *user_data) {
+ if (hTpDec == NULL) {
+ return -1;
+ }
+ hTpDec->callbacks.cbFreeMem = cbFreeMem;
+ hTpDec->callbacks.cbFreeMemData = user_data;
+ return 0;
+}
+
+int transportDec_RegisterCtrlCFGChangeCallback(
+ HANDLE_TRANSPORTDEC hTpDec, const cbCtrlCFGChange_t cbCtrlCFGChange,
+ void *user_data) {
+ if (hTpDec == NULL) {
+ return -1;
+ }
+ hTpDec->callbacks.cbCtrlCFGChange = cbCtrlCFGChange;
+ hTpDec->callbacks.cbCtrlCFGChangeData = user_data;
+ return 0;
+}
+
+int transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbSsc_t cbSsc, void *user_data) {
+ if (hTpDec == NULL) {
+ return -1;
+ }
+ hTpDec->callbacks.cbSsc = cbSsc;
+ hTpDec->callbacks.cbSscData = user_data;
+ return 0;
+}
+
+int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbSbr_t cbSbr, void *user_data) {
+ if (hTpDec == NULL) {
+ return -1;
+ }
+ hTpDec->callbacks.cbSbr = cbSbr;
+ hTpDec->callbacks.cbSbrData = user_data;
+ return 0;
+}
+
+int transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbUsac_t cbUsac, void *user_data) {
+ if (hTpDec == NULL) {
+ return -1;
+ }
+ hTpDec->callbacks.cbUsac = cbUsac;
+ hTpDec->callbacks.cbUsacData = user_data;
+ return 0;
+}
+
+int transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbUniDrc_t cbUniDrc,
+ void *user_data,
+ UINT *pLoudnessInfoSetPosition) {
+ if (hTpDec == NULL) {
+ return -1;
+ }
+
+ hTpDec->callbacks.cbUniDrc = cbUniDrc;
+ hTpDec->callbacks.cbUniDrcData = user_data;
+
+ hTpDec->pLoudnessInfoSetPosition = pLoudnessInfoSetPosition;
+ return 0;
+}
+
+TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
+ UCHAR *pBuffer, const UINT bufferSize,
+ UINT *pBytesValid, const INT layer) {
+ HANDLE_FDK_BITSTREAM hBs;
+
+ if ((hTp == NULL) || (layer >= 1)) {
+ return TRANSPORTDEC_INVALID_PARAMETER;
+ }
+
+ /* set bitbuffer shortcut */
+ hBs = &hTp->bitStream[layer];
+
+ if (TT_IS_PACKET(hTp->transportFmt)) {
+ if (hTp->numberOfRawDataBlocks == 0) {
+ FDKresetBitbuffer(hBs);
+ FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
+ if (*pBytesValid != 0) {
+ return TRANSPORTDEC_TOO_MANY_BITS;
+ }
+ }
+ } else {
+ /* ... else feed bitbuffer with new stream data (append). */
+
+ if (*pBytesValid == 0) {
+ /* nothing to do */
+ return TRANSPORTDEC_OK;
+ }
+
+ if (hTp->numberOfRawDataBlocks <= 0) {
+ FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
+ }
+ }
+
+ return TRANSPORTDEC_OK;
+}
+
+HANDLE_FDK_BITSTREAM transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer) {
+ return &hTp->bitStream[layer];
+}
+
+TRANSPORT_TYPE transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp) {
+ return hTp->transportFmt;
+}
+
+INT transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp) {
+ INT bufferFullness = -1;
+
+ switch (hTp->transportFmt) {
+ case TT_MP4_ADTS:
+ if (hTp->parser.adts.bs.adts_fullness != 0x7ff) {
+ bufferFullness = hTp->parser.adts.bs.frame_length * 8 +
+ hTp->parser.adts.bs.adts_fullness * 32 *
+ getNumberOfEffectiveChannels(
+ hTp->parser.adts.bs.channel_config);
+ }
+ break;
+ case TT_MP4_LOAS:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ if (hTp->parser.latm.m_linfo[0][0].m_bufferFullness != 0xff) {
+ bufferFullness = hTp->parser.latm.m_linfo[0][0].m_bufferFullness;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return bufferFullness;
+}
+
+/**
+ * \brief adjust bit stream position and the end of an access unit.
+ * \param hTp transport decoder handle.
+ * \return error code.
+ */
+static TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(
+ HANDLE_TRANSPORTDEC hTp) {
+ HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+
+ switch (hTp->transportFmt) {
+ case TT_MP4_ADIF:
+ /* Do byte align at the end of raw_data_block() because UsacFrame() is not
+ * byte aligned. */
+ FDKbyteAlign(hBs, hTp->accessUnitAnchor[0]);
+ break;
+ case TT_MP4_LOAS:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ if (hTp->numberOfRawDataBlocks == 0) {
+ /* Do byte align at the end of AudioMuxElement. */
+ FDKbyteAlign(hBs, hTp->globalFramePos);
+
+ /* Check global frame length */
+ if (hTp->transportFmt == TT_MP4_LOAS &&
+ hTp->parser.latm.m_audioMuxLengthBytes > 0) {
+ int loasOffset;
+
+ loasOffset = ((INT)hTp->parser.latm.m_audioMuxLengthBytes * 8 +
+ (INT)FDKgetValidBits(hBs)) -
+ (INT)hTp->globalFramePos;
+ if (loasOffset != 0) {
+ FDKpushBiDirectional(hBs, loasOffset);
+ /* For ELD and other payloads there is an unknown amount of padding,
+ so ignore unread bits, but throw an error only if too many bits
+ where read. */
+ if (loasOffset < 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ }
+ }
+ break;
+
+ case TT_MP4_ADTS:
+ if (hTp->parser.adts.bs.protection_absent == 0) {
+ int offset;
+
+ /* Calculate offset to end of AU */
+ offset = hTp->parser.adts
+ .rawDataBlockDist[hTp->parser.adts.bs.num_raw_blocks -
+ hTp->numberOfRawDataBlocks]
+ << 3;
+ /* CAUTION: The PCE (if available) is declared to be a part of the
+ * header! */
+ offset -= (INT)hTp->accessUnitAnchor[0] - (INT)FDKgetValidBits(hBs) +
+ 16 + hTp->parser.adts.bs.num_pce_bits;
+ FDKpushBiDirectional(hBs, offset);
+ }
+ if (hTp->parser.adts.bs.num_raw_blocks > 0 &&
+ hTp->parser.adts.bs.protection_absent == 0) {
+ /* Note this CRC read currently happens twice because of
+ * transportDec_CrcCheck() */
+ hTp->parser.adts.crcReadValue = FDKreadBits(hBs, 16);
+ }
+ if (hTp->numberOfRawDataBlocks == 0) {
+ /* Check global frame length */
+ if (hTp->parser.adts.bs.protection_absent == 0) {
+ int offset;
+
+ offset = (hTp->parser.adts.bs.frame_length * 8 - ADTS_SYNCLENGTH +
+ (INT)FDKgetValidBits(hBs)) -
+ (INT)hTp->globalFramePos;
+ if (offset != 0) {
+ FDKpushBiDirectional(hBs, offset);
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return err;
+}
+
+/**
+ * \brief Determine additional buffer fullness contraint due to burst data
+ * reception. The parameter TPDEC_PARAM_BURSTPERIOD must have been set as a
+ * precondition.
+ * \param hTp transport decoder handle.
+ * \param bufferFullness the buffer fullness value of the first frame to be
+ * decoded.
+ * \param bitsAvail the amount of available bits at the end of the first frame
+ * to be decoded.
+ * \return error code
+ */
+static TRANSPORTDEC_ERROR additionalHoldOffNeeded(HANDLE_TRANSPORTDEC hTp,
+ INT bufferFullness,
+ INT bitsAvail) {
+ INT checkLengthBits, avgBitsPerFrame;
+ INT maxAU; /* maximum number of frames per Master Frame */
+ INT samplesPerFrame = hTp->asc->m_samplesPerFrame;
+ INT samplingFrequency = (INT)hTp->asc->m_samplingFrequency;
+
+ if ((hTp->avgBitRate == 0) || (hTp->burstPeriod == 0)) {
+ return TRANSPORTDEC_OK;
+ }
+ if ((samplesPerFrame == 0) || (samplingFrequency == 0)) {
+ return TRANSPORTDEC_NOT_ENOUGH_BITS;
+ }
+
+ /* One Master Frame is sent every hTp->burstPeriod ms */
+ maxAU = hTp->burstPeriod * samplingFrequency + (samplesPerFrame * 1000 - 1);
+ maxAU = maxAU / (samplesPerFrame * 1000);
+ /* Subtract number of frames which were already held off. */
+ maxAU -= hTp->holdOffFrames;
+
+ avgBitsPerFrame = hTp->avgBitRate * samplesPerFrame + (samplingFrequency - 1);
+ avgBitsPerFrame = avgBitsPerFrame / samplingFrequency;
+
+ /* Consider worst case of bufferFullness quantization. */
+ switch (hTp->transportFmt) {
+ case TT_MP4_ADIF:
+ case TT_MP4_ADTS:
+ case TT_MP4_LOAS:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ bufferFullness += 31;
+ break;
+ default: /* added to avoid compiler warning */
+ break; /* added to avoid compiler warning */
+ }
+
+ checkLengthBits = bufferFullness + (maxAU - 1) * avgBitsPerFrame;
+
+ /* Check if buffer is big enough to fullfill buffer fullness condition */
+ if ((checkLengthBits /*+headerBits*/) > (((8192 * 4) << 3) - 7)) {
+ return TRANSPORTDEC_SYNC_ERROR;
+ }
+
+ if (bitsAvail < checkLengthBits) {
+ return TRANSPORTDEC_NOT_ENOUGH_BITS;
+ } else {
+ return TRANSPORTDEC_OK;
+ }
+}
+
+static TRANSPORTDEC_ERROR transportDec_readHeader(
+ HANDLE_TRANSPORTDEC hTp, HANDLE_FDK_BITSTREAM hBs, int syncLength,
+ int ignoreBufferFullness, int *pRawDataBlockLength,
+ int *pfTraverseMoreFrames, int *pSyncLayerFrameBits, int *pfConfigFound,
+ int *pHeaderBits) {
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+ int rawDataBlockLength = *pRawDataBlockLength;
+ int fTraverseMoreFrames =
+ (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0;
+ int syncLayerFrameBits =
+ (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0;
+ int fConfigFound = (pfConfigFound != NULL) ? *pfConfigFound : 0;
+ int startPos;
+
+ startPos = (INT)FDKgetValidBits(hBs);
+
+ switch (hTp->transportFmt) {
+ case TT_MP4_ADTS:
+ if (hTp->numberOfRawDataBlocks <= 0) {
+ int i, errC;
+
+ hTp->globalFramePos = FDKgetValidBits(hBs);
+
+ UCHAR configChanged = 0;
+ UCHAR configMode = AC_CM_DET_CFG_CHANGE;
+
+ for (i = 0; i < 2; i++) {
+ if (i > 0) {
+ FDKpushBack(hBs,
+ (INT)hTp->globalFramePos - (INT)FDKgetValidBits(hBs));
+ configMode = AC_CM_ALLOC_MEM;
+ }
+
+ /* Parse ADTS header */
+ err = adtsRead_DecodeHeader(&hTp->parser.adts, &hTp->asc[0], hBs,
+ ignoreBufferFullness);
+ if (err != TRANSPORTDEC_OK) {
+ if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
+ err = TRANSPORTDEC_SYNC_ERROR;
+ }
+ } else {
+ errC = hTp->callbacks.cbUpdateConfig(
+ hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
+ &configChanged);
+ if (errC != 0) {
+ if (errC == TRANSPORTDEC_NEED_TO_RESTART) {
+ err = TRANSPORTDEC_NEED_TO_RESTART;
+ goto bail;
+ } else {
+ err = TRANSPORTDEC_SYNC_ERROR;
+ }
+ } else {
+ fConfigFound = 1;
+ hTp->numberOfRawDataBlocks =
+ hTp->parser.adts.bs.num_raw_blocks + 1;
+ }
+ }
+
+ if (err == TRANSPORTDEC_OK) {
+ if ((i == 0) && configChanged) {
+ errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
+ &hTp->asc[0]);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ }
+ }
+ } else {
+ /* Reset CRC because the next bits are the beginning of a
+ * raw_data_block() */
+ FDKcrcReset(&hTp->parser.adts.crcInfo);
+ hTp->parser.adts.bs.num_pce_bits = 0;
+ }
+ if (err == TRANSPORTDEC_OK) {
+ hTp->numberOfRawDataBlocks--;
+ rawDataBlockLength = adtsRead_GetRawDataBlockLength(
+ &hTp->parser.adts,
+ (hTp->parser.adts.bs.num_raw_blocks - hTp->numberOfRawDataBlocks));
+ if (rawDataBlockLength <= 0) {
+ /* No further frame traversal possible. */
+ fTraverseMoreFrames = 0;
+ }
+ syncLayerFrameBits = (hTp->parser.adts.bs.frame_length << 3) -
+ (startPos - (INT)FDKgetValidBits(hBs)) -
+ syncLength;
+ if (syncLayerFrameBits <= 0) {
+ err = TRANSPORTDEC_SYNC_ERROR;
+ }
+ } else {
+ hTp->numberOfRawDataBlocks = 0;
+ }
+ break;
+ case TT_MP4_LOAS:
+ if (hTp->numberOfRawDataBlocks <= 0) {
+ syncLayerFrameBits = (INT)FDKreadBits(hBs, 13);
+ hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
+ syncLayerFrameBits <<= 3;
+ }
+ FDK_FALLTHROUGH;
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LATM_MCP0:
+ if (hTp->numberOfRawDataBlocks <= 0) {
+ hTp->globalFramePos = FDKgetValidBits(hBs);
+
+ err = CLatmDemux_Read(hBs, &hTp->parser.latm, hTp->transportFmt,
+ &hTp->callbacks, hTp->asc, &fConfigFound,
+ ignoreBufferFullness);
+
+ if (err != TRANSPORTDEC_OK) {
+ if ((err != TRANSPORTDEC_NOT_ENOUGH_BITS) &&
+ !TPDEC_IS_FATAL_ERROR(err)) {
+ err = TRANSPORTDEC_SYNC_ERROR;
+ }
+ } else {
+ hTp->numberOfRawDataBlocks =
+ CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
+ if (hTp->transportFmt == TT_MP4_LOAS) {
+ syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13);
+ }
+ }
+ } else {
+ err = CLatmDemux_ReadPayloadLengthInfo(hBs, &hTp->parser.latm);
+ if (err != TRANSPORTDEC_OK) {
+ err = TRANSPORTDEC_SYNC_ERROR;
+ }
+ }
+ if (err == TRANSPORTDEC_OK) {
+ int layer;
+ rawDataBlockLength = 0;
+ for (layer = 0;
+ layer < (int)CLatmDemux_GetNrOfLayers(&hTp->parser.latm, 0);
+ layer += 1) {
+ rawDataBlockLength +=
+ CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm, 0, layer);
+ }
+ hTp->numberOfRawDataBlocks--;
+ } else {
+ hTp->numberOfRawDataBlocks = 0;
+ }
+ break;
+ default: { syncLayerFrameBits = 0; } break;
+ }
+
+bail:
+
+ *pRawDataBlockLength = rawDataBlockLength;
+
+ if (pHeaderBits != NULL) {
+ *pHeaderBits += startPos - (INT)FDKgetValidBits(hBs);
+ }
+
+ for (int i = 0; i < (1 * 1); i++) {
+ /* If parsing error while config found, clear ctrlCFGChange-struct */
+ if (hTp->ctrlCFGChange[i].cfgChanged && err != TRANSPORTDEC_OK) {
+ hTp->numberOfRawDataBlocks = 0;
+ hTp->ctrlCFGChange[i].flushCnt = 0;
+ hTp->ctrlCFGChange[i].flushStatus = TPDEC_FLUSH_OFF;
+ hTp->ctrlCFGChange[i].buildUpCnt = 0;
+ hTp->ctrlCFGChange[i].buildUpStatus = TPDEC_BUILD_UP_OFF;
+ hTp->ctrlCFGChange[i].cfgChanged = 0;
+ hTp->ctrlCFGChange[i].contentChanged = 0;
+ hTp->ctrlCFGChange[i].forceCfgChange = 0;
+
+ hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
+ &hTp->ctrlCFGChange[i]);
+ }
+ }
+
+ if (pfConfigFound != NULL) {
+ *pfConfigFound = fConfigFound;
+ }
+
+ if (pfTraverseMoreFrames != NULL) {
+ *pfTraverseMoreFrames = fTraverseMoreFrames;
+ }
+ if (pSyncLayerFrameBits != NULL) {
+ *pSyncLayerFrameBits = syncLayerFrameBits;
+ }
+
+ return err;
+}
+
+/* How many bits to advance for synchronization search. */
+#define TPDEC_SYNCSKIP 8
+
+static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
+ INT *pHeaderBits) {
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
+ HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
+
+ INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
+ INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
+ INT totalBits;
+ INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
+ INT numFramesTraversed = 0, fTraverseMoreFrames,
+ fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
+ INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious,
+ globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
+ INT ignoreBufferFullness =
+ hTp->flags &
+ (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS | TPDEC_SYNCOK);
+ UINT endTpFrameBitsPrevious = 0;
+
+ /* Synch parameters */
+ INT syncLength; /* Length of sync word in bits */
+ UINT syncWord; /* Sync word to be found */
+ UINT syncMask; /* Mask for sync word (for adding one bit, so comprising one
+ bit less) */
+ C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);
+
+ totalBits = (INT)FDKgetValidBits(hBs);
+
+ if (totalBits <= 0) {
+ err = TRANSPORTDEC_NOT_ENOUGH_BITS;
+ goto bail;
+ }
+
+ fTraverseMoreFrames =
+ (hTp->flags & (TPDEC_MINIMIZE_DELAY | TPDEC_EARLY_CONFIG)) &&
+ !(hTp->flags & TPDEC_SYNCOK);
+
+ /* Set transport specific sync parameters */
+ switch (hTp->transportFmt) {
+ case TT_MP4_ADTS:
+ syncWord = ADTS_SYNCWORD;
+ syncLength = ADTS_SYNCLENGTH;
+ break;
+ case TT_MP4_LOAS:
+ syncWord = 0x2B7;
+ syncLength = 11;
+ break;
+ default:
+ syncWord = 0;
+ syncLength = 0;
+ break;
+ }
+
+ syncMask = (1 << syncLength) - 1;
+
+ do {
+ INT bitsAvail = 0; /* Bits available in bitstream buffer */
+ INT checkLengthBits; /* Helper to check remaining bits and buffer boundaries
+ */
+ UINT synch; /* Current sync word read from bitstream */
+
+ headerBitsPrevious = headerBits;
+
+ bitsAvail = (INT)FDKgetValidBits(hBs);
+
+ if (hTp->numberOfRawDataBlocks == 0) {
+ /* search synchword */
+
+ FDK_ASSERT((bitsAvail % TPDEC_SYNCSKIP) == 0);
+
+ if ((bitsAvail - syncLength) < TPDEC_SYNCSKIP) {
+ err = TRANSPORTDEC_NOT_ENOUGH_BITS;
+ headerBits = 0;
+ } else {
+ synch = FDKreadBits(hBs, syncLength);
+
+ if (!(hTp->flags & TPDEC_SYNCOK)) {
+ for (; (bitsAvail - syncLength) >= TPDEC_SYNCSKIP;
+ bitsAvail -= TPDEC_SYNCSKIP) {
+ if (synch == syncWord) {
+ break;
+ }
+ synch = ((synch << TPDEC_SYNCSKIP) & syncMask) |
+ FDKreadBits(hBs, TPDEC_SYNCSKIP);
+ }
+ }
+ if (synch != syncWord) {
+ /* No correct syncword found. */
+ err = TRANSPORTDEC_SYNC_ERROR;
+ } else {
+ err = TRANSPORTDEC_OK;
+ }
+ headerBits = syncLength;
+ }
+ } else {
+ headerBits = 0;
+ }
+
+ /* Save previous raw data block data */
+ rawDataBlockLengthPrevious = rawDataBlockLength;
+ numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;
+
+ /* Parse transport header (raw data block granularity) */
+
+ if (err == TRANSPORTDEC_OK) {
+ err = transportDec_readHeader(hTp, hBs, syncLength, ignoreBufferFullness,
+ &rawDataBlockLength, &fTraverseMoreFrames,
+ &syncLayerFrameBits, &fConfigFound,
+ &headerBits);
+ if (TPDEC_IS_FATAL_ERROR(err)) {
+ /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
+ * next time. Ensure that the bit amount lands at a multiple of
+ * TPDEC_SYNCSKIP. */
+ FDKpushBiDirectional(
+ hBs, -headerBits + TPDEC_SYNCSKIP + (bitsAvail % TPDEC_SYNCSKIP));
+
+ goto bail;
+ }
+ }
+
+ bitsAvail -= headerBits;
+
+ checkLengthBits = syncLayerFrameBits;
+
+ /* Check if the whole frame would fit the bitstream buffer */
+ if (err == TRANSPORTDEC_OK) {
+ if ((checkLengthBits + headerBits) > (((8192 * 4) << 3) - 7)) {
+ /* We assume that the size of the transport bit buffer has been
+ chosen to meet all system requirements, thus this condition
+ is considered a synchronisation error. */
+ err = TRANSPORTDEC_SYNC_ERROR;
+ } else {
+ if (bitsAvail < checkLengthBits) {
+ err = TRANSPORTDEC_NOT_ENOUGH_BITS;
+ }
+ }
+ }
+
+ if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
+ /* Enforce reading of new data */
+ hTp->numberOfRawDataBlocks = 0;
+ break;
+ }
+
+ if (err == TRANSPORTDEC_SYNC_ERROR) {
+ int bits;
+
+ /* Enforce re-sync of transport headers. */
+ hTp->numberOfRawDataBlocks = 0;
+
+ /* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */
+ bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
+ /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
+ * next time. */
+ FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
+ headerBits = 0;
+ }
+
+ /* Frame traversal */
+ if (fTraverseMoreFrames) {
+ /* Save parser context for early config discovery "rewind all frames" */
+ if ((hTp->flags & TPDEC_EARLY_CONFIG) &&
+ !(hTp->flags & TPDEC_MINIMIZE_DELAY)) {
+ /* ignore buffer fullness if just traversing additional frames for ECD
+ */
+ ignoreBufferFullness = 1;
+
+ /* Save context in order to return later */
+ if (err == TRANSPORTDEC_OK && startPosFirstFrame == -1) {
+ startPosFirstFrame = FDKgetValidBits(hBs);
+ numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
+ globalFramePosFirstFrame = hTp->globalFramePos;
+ rawDataBlockLengthFirstFrame = rawDataBlockLength;
+ headerBitsFirstFrame = headerBits;
+ errFirstFrame = err;
+ FDKmemcpy(contextFirstFrame, &hTp->parser,
+ sizeof(transportdec_parser_t));
+ }
+
+ /* Break when config was found or it is not possible anymore to find a
+ * config */
+ if (startPosFirstFrame != -1 &&
+ (fConfigFound || err != TRANSPORTDEC_OK)) {
+ /* In case of ECD and sync error, do not rewind anywhere. */
+ if (err == TRANSPORTDEC_SYNC_ERROR) {
+ startPosFirstFrame = -1;
+ fConfigFound = 0;
+ numFramesTraversed = 0;
+ }
+ break;
+ }
+ }
+
+ if (err == TRANSPORTDEC_OK) {
+ FDKpushFor(hBs, rawDataBlockLength);
+ numFramesTraversed++;
+ endTpFrameBitsPrevious = (INT)FDKgetValidBits(hBs);
+ /* Ignore error here itentionally. */
+ transportDec_AdjustEndOfAccessUnit(hTp);
+ endTpFrameBitsPrevious -= FDKgetValidBits(hBs);
+ }
+ }
+ } while (fTraverseMoreFrames ||
+ (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));
+
+ /* Restore context in case of ECD frame traversal */
+ if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK)) {
+ FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
+ FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
+ hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
+ hTp->globalFramePos = globalFramePosFirstFrame;
+ rawDataBlockLength = rawDataBlockLengthFirstFrame;
+ headerBits = headerBitsFirstFrame;
+ err = errFirstFrame;
+ numFramesTraversed = 0;
+ }
+
+ /* Additional burst data mode buffer fullness check. */
+ if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
+ TPDEC_SYNCOK)) &&
+ err == TRANSPORTDEC_OK) {
+ err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
+ FDKgetValidBits(hBs) - syncLayerFrameBits);
+ if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
+ hTp->holdOffFrames++;
+ }
+ }
+
+ /* Rewind for retry because of not enough bits */
+ if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
+ FDKpushBack(hBs, headerBits);
+ headerBits = 0;
+ } else {
+ /* reset hold off frame counter */
+ hTp->holdOffFrames = 0;
+ }
+
+ /* Return to last good frame in case of frame traversal but not ECD. */
+ if (numFramesTraversed > 0) {
+ FDKpushBack(hBs, rawDataBlockLengthPrevious + endTpFrameBitsPrevious);
+ if (err != TRANSPORTDEC_OK) {
+ hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
+ headerBits = headerBitsPrevious;
+ rawDataBlockLength = rawDataBlockLengthPrevious;
+ }
+ err = TRANSPORTDEC_OK;
+ }
+
+bail:
+ hTp->auLength[0] = rawDataBlockLength;
+
+ /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, where the bit
+ buffer is already full, or no new burst packet fits. Recover by advancing
+ the bit buffer. */
+ if ((totalBits > 0) && (TRANSPORTDEC_NOT_ENOUGH_BITS == err) &&
+ (FDKgetValidBits(hBs) >=
+ (((8192 * 4) * 8 - ((hTp->avgBitRate * hTp->burstPeriod) / 1000)) -
+ 7))) {
+ FDKpushFor(hBs, TPDEC_SYNCSKIP);
+ err = TRANSPORTDEC_SYNC_ERROR;
+ }
+
+ if (err == TRANSPORTDEC_OK) {
+ hTp->flags |= TPDEC_SYNCOK;
+ }
+
+ if (fConfigFound) {
+ hTp->flags |= TPDEC_CONFIG_FOUND;
+ }
+
+ if (pHeaderBits != NULL) {
+ *pHeaderBits = headerBits;
+ }
+
+ if (err == TRANSPORTDEC_SYNC_ERROR) {
+ hTp->flags &= ~TPDEC_SYNCOK;
+ }
+
+ C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);
+
+ return err;
+}
+
+/**
+ * \brief Synchronize to stream and estimate the amount of missing access units
+ * due to a current synchronization error in case of constant average bit rate.
+ */
+static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp,
+ const UINT layer) {
+ TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
+ HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[layer];
+
+ INT headerBits;
+ INT bitDistance, bfDelta;
+
+ /* Obtain distance to next synch word */
+ bitDistance = (INT)FDKgetValidBits(hBs);
+ error = synchronization(hTp, &headerBits);
+ bitDistance -= (INT)FDKgetValidBits(hBs);
+
+ FDK_ASSERT(bitDistance >= 0);
+
+ INT nAU = -1;
+
+ if (error == TRANSPORTDEC_SYNC_ERROR ||
+ (hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
+ /* Check if estimating lost access units is feasible. */
+ if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 &&
+ hTp->asc[0].m_samplingFrequency > 0) {
+ if (error == TRANSPORTDEC_OK) {
+ int aj;
+
+ aj = transportDec_GetBufferFullness(hTp);
+ if (aj > 0) {
+ bfDelta = aj;
+ } else {
+ bfDelta = 0;
+ }
+ /* sync was ok: last of a series of bad access units. */
+ hTp->flags &= ~TPDEC_LOST_FRAMES_PENDING;
+ /* Add up bitDistance until end of the current frame. Later we substract
+ this frame from the grand total, since this current successfully
+ synchronized frame should not be skipped of course; but it must be
+ accounted into the bufferfulness math. */
+ bitDistance += hTp->auLength[0];
+ } else {
+ if (!(hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
+ /* sync not ok: one of many bad access units. */
+ hTp->flags |= TPDEC_LOST_FRAMES_PENDING;
+ bfDelta = -(INT)hTp->lastValidBufferFullness;
+ } else {
+ bfDelta = 0;
+ }
+ }
+
+ {
+ int num, denom;
+
+ /* Obtain estimate of number of lost frames */
+ num = (INT)hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) +
+ hTp->remainder;
+ denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame;
+ if (num > 0) {
+ nAU = num / denom;
+ hTp->remainder = num % denom;
+ } else {
+ hTp->remainder = num;
+ }
+
+ if (error == TRANSPORTDEC_OK) {
+ /* Final adjustment of remainder, taken -1 into account because
+ current frame should not be skipped, thus substract -1 or do
+ nothing instead of +1-1 accordingly. */
+ if ((denom - hTp->remainder) >= hTp->remainder) {
+ nAU--;
+ }
+
+ if (nAU < 0) {
+ /* There was one frame too much concealed, so unfortunately we will
+ * have to skip one good frame. */
+ transportDec_EndAccessUnit(hTp);
+ error = synchronization(hTp, &headerBits);
+ nAU = -1;
+ }
+ hTp->remainder = 0;
+ /* Enforce last missed frames to be concealed. */
+ if (nAU > 0) {
+ FDKpushBack(hBs, headerBits);
+ }
+ }
+ }
+ }
+ }
+
+ /* Be sure that lost frames are handled correctly. This is necessary due to
+ some sync error sequences where later it turns out that there is not enough
+ data, but the bits upto the sync word are discarded, thus causing a value
+ of nAU > 0 */
+ if (nAU > 0) {
+ error = TRANSPORTDEC_SYNC_ERROR;
+ }
+
+ hTp->missingAccessUnits = nAU;
+
+ return error;
+}
+
+/* returns error code */
+TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer) {
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+ HANDLE_FDK_BITSTREAM hBs;
+
+ if (!hTp) {
+ return TRANSPORTDEC_INVALID_PARAMETER;
+ }
+
+ hBs = &hTp->bitStream[layer];
+
+ if ((INT)FDKgetValidBits(hBs) <= 0) {
+ /* This is only relevant for RAW and ADIF cases.
+ * For streaming formats err will get overwritten. */
+ err = TRANSPORTDEC_NOT_ENOUGH_BITS;
+ hTp->numberOfRawDataBlocks = 0;
+ }
+
+ switch (hTp->transportFmt) {
+ case TT_MP4_ADIF:
+ /* Read header if not already done */
+ if (!(hTp->flags & TPDEC_CONFIG_FOUND)) {
+ int i;
+ CProgramConfig *pce;
+ INT bsStart = FDKgetValidBits(hBs);
+ UCHAR configChanged = 0;
+ UCHAR configMode = AC_CM_DET_CFG_CHANGE;
+
+ for (i = 0; i < 2; i++) {
+ if (i > 0) {
+ FDKpushBack(hBs, bsStart - FDKgetValidBits(hBs));
+ configMode = AC_CM_ALLOC_MEM;
+ }
+
+ AudioSpecificConfig_Init(&hTp->asc[0]);
+ pce = &hTp->asc[0].m_progrConfigElement;
+ err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs);
+ if (err) goto bail;
+
+ /* Map adif header to ASC */
+ hTp->asc[0].m_aot = (AUDIO_OBJECT_TYPE)(pce->Profile + 1);
+ hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex;
+ hTp->asc[0].m_samplingFrequency =
+ SamplingRateTable[pce->SamplingFrequencyIndex];
+ hTp->asc[0].m_channelConfiguration = 0;
+ hTp->asc[0].m_samplesPerFrame = 1024;
+ hTp->avgBitRate = hTp->parser.adif.BitRate;
+
+ /* Call callback to decoder. */
+ {
+ int errC;
+
+ errC = hTp->callbacks.cbUpdateConfig(
+ hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
+ &configChanged);
+ if (errC == 0) {
+ hTp->flags |= TPDEC_CONFIG_FOUND;
+ } else {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ if (err == TRANSPORTDEC_OK) {
+ if ((i == 0) && configChanged) {
+ int errC;
+ errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
+ &hTp->asc[0]);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ }
+ }
+ }
+ hTp->auLength[layer] = -1; /* Access Unit data length is unknown. */
+ break;
+
+ case TT_MP4_RAW:
+ case TT_DRM:
+ /* One Access Unit was filled into buffer.
+ So get the length out of the buffer. */
+ hTp->auLength[layer] = FDKgetValidBits(hBs);
+ hTp->flags |= TPDEC_SYNCOK;
+ break;
+
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ if (err == TRANSPORTDEC_OK) {
+ int fConfigFound = hTp->flags & TPDEC_CONFIG_FOUND;
+ err = transportDec_readHeader(hTp, hBs, 0, 1, &hTp->auLength[layer],
+ NULL, NULL, &fConfigFound, NULL);
+ if (fConfigFound) {
+ hTp->flags |= TPDEC_CONFIG_FOUND;
+ }
+ }
+ break;
+
+ case TT_MP4_ADTS:
+ case TT_MP4_LOAS:
+ err = transportDec_readStream(hTp, layer);
+ break;
+
+ default:
+ err = TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ break;
+ }
+
+ if (err == TRANSPORTDEC_OK) {
+ hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
+ } else {
+ hTp->accessUnitAnchor[layer] = 0;
+ }
+
+bail:
+ return err;
+}
+
+TRANSPORTDEC_ERROR transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer,
+ CSAudioSpecificConfig *asc) {
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+
+ if (hTp != NULL) {
+ *asc = hTp->asc[layer];
+ err = TRANSPORTDEC_OK;
+ } else {
+ err = TRANSPORTDEC_INVALID_PARAMETER;
+ }
+ return err;
+}
+
+INT transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer) {
+ INT bits;
+
+ if (hTp->accessUnitAnchor[layer] > 0 && hTp->auLength[layer] > 0) {
+ bits = (INT)FDKgetValidBits(&hTp->bitStream[layer]);
+ if (bits >= 0) {
+ bits = hTp->auLength[layer] - ((INT)hTp->accessUnitAnchor[layer] - bits);
+ }
+ } else {
+ bits = FDKgetValidBits(&hTp->bitStream[layer]);
+ }
+
+ return bits;
+}
+
+INT transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer) {
+ return hTp->auLength[layer];
+}
+
+TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount(
+ INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp) {
+ *pNAccessUnits = hTp->missingAccessUnits;
+
+ return TRANSPORTDEC_OK;
+}
+
+/* Inform the transportDec layer that reading of access unit has finished. */
+TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp) {
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+
+ switch (hTp->transportFmt) {
+ case TT_MP4_LOAS:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1: {
+ HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
+ if (hTp->numberOfRawDataBlocks == 0) {
+ /* Read other data if available. */
+ if (CLatmDemux_GetOtherDataPresentFlag(&hTp->parser.latm)) {
+ int otherDataLen = CLatmDemux_GetOtherDataLength(&hTp->parser.latm);
+
+ if ((INT)FDKgetValidBits(hBs) >= otherDataLen) {
+ FDKpushFor(hBs, otherDataLen);
+ } else {
+ /* Do byte align at the end of AudioMuxElement. */
+ if (hTp->numberOfRawDataBlocks == 0) {
+ FDKbyteAlign(hBs, hTp->globalFramePos);
+ }
+ return TRANSPORTDEC_NOT_ENOUGH_BITS;
+ }
+ }
+ } else {
+ /* If bit buffer has not more bits but hTp->numberOfRawDataBlocks > 0
+ then too many bits were read and obviously no more RawDataBlocks can
+ be read. Set numberOfRawDataBlocks to zero to attempt a new sync
+ attempt. */
+ if ((INT)FDKgetValidBits(hBs) <= 0) {
+ hTp->numberOfRawDataBlocks = 0;
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+
+ err = transportDec_AdjustEndOfAccessUnit(hTp);
+
+ switch (hTp->transportFmt) {
+ default:
+ break;
+ }
+
+ return err;
+}
+
+TRANSPORTDEC_ERROR transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,
+ const TPDEC_PARAM param,
+ const INT value) {
+ TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
+
+ if (hTp == NULL) {
+ return TRANSPORTDEC_INVALID_PARAMETER;
+ }
+
+ switch (param) {
+ case TPDEC_PARAM_MINIMIZE_DELAY:
+ if (value) {
+ hTp->flags |= TPDEC_MINIMIZE_DELAY;
+ } else {
+ hTp->flags &= ~TPDEC_MINIMIZE_DELAY;
+ }
+ break;
+ case TPDEC_PARAM_EARLY_CONFIG:
+ if (value) {
+ hTp->flags |= TPDEC_EARLY_CONFIG;
+ } else {
+ hTp->flags &= ~TPDEC_EARLY_CONFIG;
+ }
+ break;
+ case TPDEC_PARAM_IGNORE_BUFFERFULLNESS:
+ if (value) {
+ hTp->flags |= TPDEC_IGNORE_BUFFERFULLNESS;
+ } else {
+ hTp->flags &= ~TPDEC_IGNORE_BUFFERFULLNESS;
+ }
+ break;
+ case TPDEC_PARAM_SET_BITRATE:
+ hTp->avgBitRate = value;
+ break;
+ case TPDEC_PARAM_BURST_PERIOD:
+ hTp->burstPeriod = value;
+ break;
+ case TPDEC_PARAM_RESET: {
+ int i;
+
+ for (i = 0; i < (1 * 1); i++) {
+ FDKresetBitbuffer(&hTp->bitStream[i]);
+ hTp->auLength[i] = 0;
+ hTp->accessUnitAnchor[i] = 0;
+ }
+ hTp->flags &= ~(TPDEC_SYNCOK | TPDEC_LOST_FRAMES_PENDING);
+ if (hTp->transportFmt != TT_MP4_ADIF) {
+ hTp->flags &= ~TPDEC_CONFIG_FOUND;
+ }
+ hTp->remainder = 0;
+ hTp->avgBitRate = 0;
+ hTp->missingAccessUnits = 0;
+ hTp->numberOfRawDataBlocks = 0;
+ hTp->globalFramePos = 0;
+ hTp->holdOffFrames = 0;
+ } break;
+ case TPDEC_PARAM_TARGETLAYOUT:
+ hTp->targetLayout = value;
+ break;
+ case TPDEC_PARAM_FORCE_CONFIG_CHANGE:
+ hTp->ctrlCFGChange[value].forceCfgChange = TPDEC_FORCE_CONFIG_CHANGE;
+ break;
+ case TPDEC_PARAM_USE_ELEM_SKIPPING:
+ if (value) {
+ hTp->flags |= TPDEC_USE_ELEM_SKIPPING;
+ } else {
+ hTp->flags &= ~TPDEC_USE_ELEM_SKIPPING;
+ }
+ break;
+ }
+
+ return error;
+}
+
+UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp) {
+ UINT nSubFrames = 0;
+
+ if (hTp == NULL) return 0;
+
+ if (hTp->transportFmt == TT_MP4_LATM_MCP1 ||
+ hTp->transportFmt == TT_MP4_LATM_MCP0 || hTp->transportFmt == TT_MP4_LOAS)
+ nSubFrames = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
+ else if (hTp->transportFmt == TT_MP4_ADTS)
+ nSubFrames = hTp->parser.adts.bs.num_raw_blocks;
+
+ return nSubFrames;
+}
+
+void transportDec_Close(HANDLE_TRANSPORTDEC *phTp) {
+ if (phTp != NULL) {
+ if (*phTp != NULL) {
+ FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer);
+ FreeRam_TransportDecoder(phTp);
+ }
+ }
+}
+
+TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) {
+ int i;
+
+ if (info == NULL) {
+ return TRANSPORTDEC_UNKOWN_ERROR;
+ }
+
+ /* search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) return TRANSPORTDEC_UNKOWN_ERROR;
+ info += i;
+
+ info->module_id = FDK_TPDEC;
+#ifdef __ANDROID__
+ info->build_date = "";
+ info->build_time = "";
+#else
+ info->build_date = __DATE__;
+ info->build_time = __TIME__;
+#endif
+ info->title = TP_LIB_TITLE;
+ info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
+ LIB_VERSION_STRING(info);
+ info->flags = 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS |
+ CAPF_RAWPACKETS | CAPF_DRM;
+
+ return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */
+}
+
+int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) {
+ switch (pTp->transportFmt) {
+ case TT_MP4_ADTS:
+ return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
+ case TT_DRM:
+ return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
+ default:
+ return -1;
+ }
+}
+
+void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) {
+ switch (pTp->transportFmt) {
+ case TT_MP4_ADTS:
+ adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
+ break;
+ case TT_DRM:
+ drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
+ break;
+ default:
+ break;
+ }
+}
+
+TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) {
+ switch (pTp->transportFmt) {
+ case TT_MP4_ADTS:
+ if ((pTp->parser.adts.bs.num_raw_blocks > 0) &&
+ (pTp->parser.adts.bs.protection_absent == 0)) {
+ transportDec_AdjustEndOfAccessUnit(pTp);
+ }
+ return adtsRead_CrcCheck(&pTp->parser.adts);
+ case TT_DRM:
+ return drmRead_CrcCheck(&pTp->parser.drm);
+ default:
+ return TRANSPORTDEC_OK;
+ }
+}
+
+TRANSPORTDEC_ERROR transportDec_DrmRawSdcAudioConfig_Check(UCHAR *conf,
+ const UINT length) {
+ CSAudioSpecificConfig asc;
+ FDK_BITSTREAM bs;
+ HANDLE_FDK_BITSTREAM hBs = &bs;
+
+ FDKinitBitStream(hBs, conf, BUFSIZE_DUMMY_VALUE, length << 3, BS_READER);
+
+ TRANSPORTDEC_ERROR err =
+ DrmRawSdcAudioConfig_Parse(&asc, hBs, NULL, (UCHAR)AC_CM_ALLOC_MEM, 0);
+
+ return err;
+}
diff --git a/fdk-aac/libMpegTPEnc/include/tp_data.h b/fdk-aac/libMpegTPEnc/include/tp_data.h
new file mode 100644
index 0000000..00de356
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/include/tp_data.h
@@ -0,0 +1,466 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s): Manuel Jander
+
+ Description: MPEG Transport data tables
+
+*******************************************************************************/
+
+#ifndef TP_DATA_H
+#define TP_DATA_H
+
+#include "machine_type.h"
+#include "FDK_audio.h"
+#include "FDK_bitstream.h"
+
+/*
+ * Configuration
+ */
+
+#define TP_USAC_MAX_SPEAKERS (24)
+
+#define TP_USAC_MAX_EXT_ELEMENTS ((24))
+
+#define TP_USAC_MAX_ELEMENTS ((24) + TP_USAC_MAX_EXT_ELEMENTS)
+
+#define TP_USAC_MAX_CONFIG_LEN \
+ 512 /* next power of two of maximum of escapedValue(hBs, 4, 4, 8) in \
+ AudioPreRoll() (285) */
+
+#define TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES \
+ (1) /* Number of frames for config change in USAC */
+
+enum {
+ TPDEC_FLUSH_OFF = 0,
+ TPDEC_RSV60_CFG_CHANGE_ATSC_FLUSH_ON = 1,
+ TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON = 2,
+ TPDEC_USAC_DASH_IPF_FLUSH_ON = 3
+};
+
+enum {
+ TPDEC_BUILD_UP_OFF = 0,
+ TPDEC_RSV60_BUILD_UP_ON = 1,
+ TPDEC_RSV60_BUILD_UP_ON_IN_BAND = 2,
+ TPDEC_USAC_BUILD_UP_ON = 3,
+ TPDEC_RSV60_BUILD_UP_IDLE = 4,
+ TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND = 5
+};
+
+/**
+ * ProgramConfig struct.
+ */
+/* ISO/IEC 14496-3 4.4.1.1 Table 4.2 Program config element */
+#define PC_FSB_CHANNELS_MAX 16 /* Front/Side/Back channels */
+#define PC_LFE_CHANNELS_MAX 4
+#define PC_ASSOCDATA_MAX 8
+#define PC_CCEL_MAX 16 /* CC elements */
+#define PC_COMMENTLENGTH 256
+#define PC_NUM_HEIGHT_LAYER 3
+
+typedef struct {
+ /* PCE bitstream elements: */
+ UCHAR ElementInstanceTag;
+ UCHAR Profile;
+ UCHAR SamplingFrequencyIndex;
+ UCHAR NumFrontChannelElements;
+ UCHAR NumSideChannelElements;
+ UCHAR NumBackChannelElements;
+ UCHAR NumLfeChannelElements;
+ UCHAR NumAssocDataElements;
+ UCHAR NumValidCcElements;
+
+ UCHAR MonoMixdownPresent;
+ UCHAR MonoMixdownElementNumber;
+
+ UCHAR StereoMixdownPresent;
+ UCHAR StereoMixdownElementNumber;
+
+ UCHAR MatrixMixdownIndexPresent;
+ UCHAR MatrixMixdownIndex;
+ UCHAR PseudoSurroundEnable;
+
+ UCHAR FrontElementIsCpe[PC_FSB_CHANNELS_MAX];
+ UCHAR FrontElementTagSelect[PC_FSB_CHANNELS_MAX];
+ UCHAR FrontElementHeightInfo[PC_FSB_CHANNELS_MAX];
+
+ UCHAR SideElementIsCpe[PC_FSB_CHANNELS_MAX];
+ UCHAR SideElementTagSelect[PC_FSB_CHANNELS_MAX];
+ UCHAR SideElementHeightInfo[PC_FSB_CHANNELS_MAX];
+
+ UCHAR BackElementIsCpe[PC_FSB_CHANNELS_MAX];
+ UCHAR BackElementTagSelect[PC_FSB_CHANNELS_MAX];
+ UCHAR BackElementHeightInfo[PC_FSB_CHANNELS_MAX];
+
+ UCHAR LfeElementTagSelect[PC_LFE_CHANNELS_MAX];
+
+ UCHAR AssocDataElementTagSelect[PC_ASSOCDATA_MAX];
+
+ UCHAR CcElementIsIndSw[PC_CCEL_MAX];
+ UCHAR ValidCcElementTagSelect[PC_CCEL_MAX];
+
+ UCHAR CommentFieldBytes;
+ UCHAR Comment[PC_COMMENTLENGTH];
+
+ /* Helper variables for administration: */
+ UCHAR isValid; /*!< Flag showing if PCE has been read successfully. */
+ UCHAR
+ NumChannels; /*!< Amount of audio channels summing all channel elements
+ including LFEs */
+ UCHAR NumEffectiveChannels; /*!< Amount of audio channels summing only SCEs
+ and CPEs */
+ UCHAR elCounter;
+
+} CProgramConfig;
+
+typedef enum {
+ ASCEXT_UNKOWN = -1,
+ ASCEXT_SBR = 0x2b7,
+ ASCEXT_PS = 0x548,
+ ASCEXT_MPS = 0x76a,
+ ASCEXT_SAOC = 0x7cb,
+ ASCEXT_LDMPS = 0x7cc
+
+} TP_ASC_EXTENSION_ID;
+
+/**
+ * GaSpecificConfig struct
+ */
+typedef struct {
+ UINT m_frameLengthFlag;
+ UINT m_dependsOnCoreCoder;
+ UINT m_coreCoderDelay;
+
+ UINT m_extensionFlag;
+ UINT m_extensionFlag3;
+
+ UINT m_layer;
+ UINT m_numOfSubFrame;
+ UINT m_layerLength;
+
+} CSGaSpecificConfig;
+
+typedef enum {
+ ELDEXT_TERM = 0x0, /* Termination tag */
+ ELDEXT_SAOC = 0x1, /* SAOC config */
+ ELDEXT_LDSAC = 0x2, /* LD MPEG Surround config */
+ ELDEXT_DOWNSCALEINFO = 0x3 /* ELD sample rate adaptation */
+ /* reserved */
+} ASC_ELD_EXT_TYPE;
+
+typedef struct {
+ UCHAR m_frameLengthFlag;
+
+ UCHAR m_sbrPresentFlag;
+ UCHAR
+ m_useLdQmfTimeAlign; /* Use LD-MPS QMF in SBR to achive time alignment */
+ UCHAR m_sbrSamplingRate;
+ UCHAR m_sbrCrcFlag;
+ UINT m_downscaledSamplingFrequency;
+
+} CSEldSpecificConfig;
+
+typedef struct {
+ USAC_EXT_ELEMENT_TYPE usacExtElementType;
+ USHORT usacExtElementConfigLength;
+ USHORT usacExtElementDefaultLength;
+ UCHAR usacExtElementPayloadFrag;
+ UCHAR usacExtElementHasAudioPreRoll;
+} CSUsacExtElementConfig;
+
+typedef struct {
+ MP4_ELEMENT_ID usacElementType;
+ UCHAR m_noiseFilling;
+ UCHAR m_harmonicSBR;
+ UCHAR m_interTes;
+ UCHAR m_pvc;
+ UCHAR m_stereoConfigIndex;
+ CSUsacExtElementConfig extElement;
+} CSUsacElementConfig;
+
+typedef struct {
+ UCHAR m_frameLengthFlag;
+ UCHAR m_coreSbrFrameLengthIndex;
+ UCHAR m_sbrRatioIndex;
+ UCHAR m_nUsacChannels; /* number of audio channels signaled in
+ UsacDecoderConfig() / rsv603daDecoderConfig() via
+ numElements and usacElementType */
+ UCHAR m_channelConfigurationIndex;
+ UINT m_usacNumElements;
+ CSUsacElementConfig element[TP_USAC_MAX_ELEMENTS];
+
+ UCHAR numAudioChannels;
+ UCHAR m_usacConfigExtensionPresent;
+ UCHAR elementLengthPresent;
+ UCHAR UsacConfig[TP_USAC_MAX_CONFIG_LEN];
+ USHORT UsacConfigBits;
+} CSUsacConfig;
+
+/**
+ * Audio configuration struct, suitable for encoder and decoder configuration.
+ */
+typedef struct {
+ /* XYZ Specific Data */
+ union {
+ CSGaSpecificConfig
+ m_gaSpecificConfig; /**< General audio specific configuration. */
+ CSEldSpecificConfig m_eldSpecificConfig; /**< ELD specific configuration. */
+ CSUsacConfig m_usacConfig; /**< USAC specific configuration */
+ } m_sc;
+
+ /* Common ASC parameters */
+ CProgramConfig m_progrConfigElement; /**< Program configuration. */
+
+ AUDIO_OBJECT_TYPE m_aot; /**< Audio Object Type. */
+ UINT m_samplingFrequency; /**< Samplerate. */
+ UINT m_samplesPerFrame; /**< Amount of samples per frame. */
+ UINT m_directMapping; /**< Document this please !! */
+
+ AUDIO_OBJECT_TYPE m_extensionAudioObjectType; /**< Audio object type */
+ UINT m_extensionSamplingFrequency; /**< Samplerate */
+
+ SCHAR m_channelConfiguration; /**< Channel configuration index */
+
+ SCHAR m_epConfig; /**< Error protection index */
+ SCHAR m_vcb11Flag; /**< aacSectionDataResilienceFlag */
+ SCHAR m_rvlcFlag; /**< aacScalefactorDataResilienceFlag */
+ SCHAR m_hcrFlag; /**< aacSpectralDataResilienceFlag */
+
+ SCHAR m_sbrPresentFlag; /**< Flag indicating the presence of SBR data in the
+ bitstream */
+ SCHAR
+ m_psPresentFlag; /**< Flag indicating the presence of parametric stereo
+ data in the bitstream */
+ UCHAR m_samplingFrequencyIndex; /**< Samplerate index */
+ UCHAR m_extensionSamplingFrequencyIndex; /**< Samplerate index */
+ SCHAR m_extensionChannelConfiguration; /**< Channel configuration index */
+
+ UCHAR
+ configMode; /**< The flag indicates if the callback shall work in memory
+ allocation mode or in config change detection mode */
+ UCHAR AacConfigChanged; /**< The flag will be set if at least one aac config
+ parameter has changed that requires a memory
+ reconfiguration, otherwise it will be cleared */
+ UCHAR SbrConfigChanged; /**< The flag will be set if at least one sbr config
+ parameter has changed that requires a memory
+ reconfiguration, otherwise it will be cleared */
+ UCHAR SacConfigChanged; /**< The flag will be set if at least one sac config
+ parameter has changed that requires a memory
+ reconfiguration, otherwise it will be cleared */
+
+ UCHAR
+ config[TP_USAC_MAX_CONFIG_LEN]; /**< Configuration stored as bitstream */
+ UINT configBits; /**< Configuration length in bits */
+
+} CSAudioSpecificConfig;
+
+typedef struct {
+ SCHAR flushCnt; /**< Flush frame counter */
+ UCHAR flushStatus; /**< Flag indicates flush mode: on|off */
+ SCHAR buildUpCnt; /**< Build up frame counter */
+ UCHAR buildUpStatus; /**< Flag indicates build up mode: on|off */
+ UCHAR cfgChanged; /**< Flag indicates that the config changed and the decoder
+ needs to be initialized again via callback. Make sure
+ that memory is freed before initialization. */
+ UCHAR contentChanged; /**< Flag indicates that the content changed i.e. a
+ right truncation occured before */
+ UCHAR forceCfgChange; /**< Flag indicates if config change has to be forced
+ even if new config is the same */
+} CCtrlCFGChange;
+
+typedef INT (*cbUpdateConfig_t)(void *, const CSAudioSpecificConfig *,
+ const UCHAR configMode, UCHAR *configChanged);
+typedef INT (*cbFreeMem_t)(void *, const CSAudioSpecificConfig *);
+typedef INT (*cbCtrlCFGChange_t)(void *, const CCtrlCFGChange *);
+typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const INT samplingRate, const INT frameSize,
+ const INT stereoConfigIndex,
+ const INT coreSbrFrameLengthIndex, const INT configBytes,
+ const UCHAR configMode, UCHAR *configChanged);
+
+typedef INT (*cbSbr_t)(void *self, HANDLE_FDK_BITSTREAM hBs,
+ const INT sampleRateIn, const INT sampleRateOut,
+ const INT samplesPerFrame,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const MP4_ELEMENT_ID elementID, const INT elementIndex,
+ const UCHAR harmonicSbr, const UCHAR stereoConfigIndex,
+ const UCHAR configMode, UCHAR *configChanged,
+ const INT downscaleFactor);
+
+typedef INT (*cbUsac_t)(void *self, HANDLE_FDK_BITSTREAM hBs);
+
+typedef INT (*cbUniDrc_t)(void *self, HANDLE_FDK_BITSTREAM hBs,
+ const INT fullPayloadLength, const INT payloadType,
+ const INT subStreamIndex, const INT payloadStart,
+ const AUDIO_OBJECT_TYPE);
+
+typedef struct {
+ cbUpdateConfig_t cbUpdateConfig; /*!< Function pointer for Config change
+ notify callback. */
+ void *cbUpdateConfigData; /*!< User data pointer for Config change notify
+ callback. */
+ cbFreeMem_t cbFreeMem; /*!< Function pointer for free memory callback. */
+ void *cbFreeMemData; /*!< User data pointer for free memory callback. */
+ cbCtrlCFGChange_t cbCtrlCFGChange; /*!< Function pointer for config change
+ control callback. */
+ void *cbCtrlCFGChangeData; /*!< User data pointer for config change control
+ callback. */
+ cbSsc_t cbSsc; /*!< Function pointer for SSC parser callback. */
+ void *cbSscData; /*!< User data pointer for SSC parser callback. */
+ cbSbr_t cbSbr; /*!< Function pointer for SBR header parser callback. */
+ void *cbSbrData; /*!< User data pointer for SBR header parser callback. */
+ cbUsac_t cbUsac;
+ void *cbUsacData;
+ cbUniDrc_t cbUniDrc; /*!< Function pointer for uniDrcConfig and
+ loudnessInfoSet parser callback. */
+ void *cbUniDrcData; /*!< User data pointer for uniDrcConfig and
+ loudnessInfoSet parser callback. */
+} CSTpCallBacks;
+
+static const UINT SamplingRateTable[] = {
+ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025,
+ 8000, 7350, 0, 0, 57600, 51200, 40000, 38400, 34150, 28800, 25600,
+ 20000, 19200, 17075, 14400, 12800, 9600, 0, 0, 0, 0};
+
+static inline int getSamplingRateIndex(UINT samplingRate, UINT nBits) {
+ UINT sf_index;
+ UINT tableSize = (1 << nBits) - 1;
+
+ for (sf_index = 0; sf_index < tableSize; sf_index++) {
+ if (SamplingRateTable[sf_index] == samplingRate) break;
+ }
+
+ if (sf_index > tableSize) {
+ return tableSize - 1;
+ }
+
+ return sf_index;
+}
+
+/*
+ * Get Channel count from channel configuration
+ */
+static inline int getNumberOfTotalChannels(int channelConfig) {
+ switch (channelConfig) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ return channelConfig;
+ case 7:
+ case 12:
+ case 14:
+ return 8;
+ case 11:
+ return 7;
+ case 13:
+ return 24;
+ default:
+ return 0;
+ }
+}
+
+static inline int getNumberOfEffectiveChannels(
+ const int
+ channelConfig) { /* index: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 */
+ const int n[] = {0, 1, 2, 3, 4, 5, 5, 7, 0, 0, 0, 6, 7, 22, 7, 0};
+ return n[channelConfig];
+}
+
+#endif /* TP_DATA_H */
diff --git a/fdk-aac/libMpegTPEnc/include/tpenc_lib.h b/fdk-aac/libMpegTPEnc/include/tpenc_lib.h
new file mode 100644
index 0000000..4eb89a7
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/include/tpenc_lib.h
@@ -0,0 +1,339 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s): Manuel Jander
+
+ Description: MPEG Transport encode
+
+*******************************************************************************/
+
+#ifndef TPENC_LIB_H
+#define TPENC_LIB_H
+
+#include "tp_data.h"
+#include "FDK_bitstream.h"
+
+#define TRANSPORTENC_INBUF_SIZE 8192
+
+typedef enum {
+ TRANSPORTENC_OK = 0, /*!< All fine. */
+ TRANSPORTENC_NO_MEM, /*!< Out of memory. */
+ TRANSPORTENC_UNKOWN_ERROR = 1, /*!< Unknown error (embarrasing). */
+ TRANSPORTENC_INVALID_PARAMETER, /*!< An invalid parameter was passed to a
+ function . */
+ TRANSPORTENC_UNSUPPORTED_FORMAT, /*!< Unsupported transport format. */
+ TRANSPORTENC_NOT_ENOUGH_BITS, /*!< Out of bits. Provide more bits and try
+ again. */
+
+ TRANSPORTENC_INVALID_CONFIG, /*!< Error in configuration. */
+ TRANSPORTENC_LATM_INVALID_NR_OF_SUBFRAMES, /*!< LATM: number of subframes out
+ of range. */
+ TRANSPORTENC_LOAS_NOT_AVAILABLE, /*!< LOAS format not supported. */
+ TRANSPORTENC_INVALID_LATM_ALIGNMENT, /*!< AudioMuxElement length not aligned
+ to 1 byte. */
+
+ TRANSPORTENC_INVALID_TRANSMISSION_FRAME_LENGTH, /*!< Invalid transmission
+ frame length (< 0). */
+ TRANSPORTENC_INVALID_CELP_FRAME_LENGTH, /*!< Invalid CELP frame length found
+ (>= 62). */
+ TRANSPORTENC_INVALID_FRAME_BITS, /*!< Frame bits is not 40 and not 80. */
+ TRANSPORTENC_INVALID_AOT, /*!< Unknown AOT found. */
+ TRANSPORTENC_INVALID_AU_LENGTH /*!< Invalid Access Unit length (not
+ byte-aligned). */
+
+} TRANSPORTENC_ERROR;
+
+typedef struct TRANSPORTENC *HANDLE_TRANSPORTENC;
+
+/**
+ * \brief Determine a reasonable channel configuration on the basis
+ * of channel_mode.
+ * \param noChannels Number of audio channels.
+ * \return CHANNEL_MODE value that matches the given amount of audio
+ * channels.
+ */
+CHANNEL_MODE transportEnc_GetChannelMode(int noChannels);
+
+/**
+ * \brief Register SBR heaqder writer callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbUpdateConfig Pointer to a callback function to handle SBR header
+ * writing.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportEnc_RegisterSbrCallback(HANDLE_TRANSPORTENC hTpEnc,
+ const cbSbr_t cbSbr, void *user_data);
+
+/**
+ * \brief Register USAC SC writer callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbUpdateConfig Pointer to a callback function to handle USAC
+ * SCwriting.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportEnc_RegisterUsacCallback(HANDLE_TRANSPORTENC hTpEnc,
+ const cbUsac_t cbUsac, void *user_data);
+
+/**
+ * \brief Register SSC writer callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbUpdateConfig Pointer to a callback function to handle SSC writing.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportEnc_RegisterSscCallback(HANDLE_TRANSPORTENC hTpEnc,
+ const cbSsc_t cbSsc, void *user_data);
+
+/**
+ * \brief Write ASC from given parameters.
+ * \param asc A HANDLE_FDK_BITSTREAM where the ASC is written to.
+ * \param config Structure containing the codec configuration settings.
+ * \param cb callback information structure.
+ * \return 0 on success.
+ */
+int transportEnc_writeASC(HANDLE_FDK_BITSTREAM asc, CODER_CONFIG *config,
+ CSTpCallBacks *cb);
+
+/* Defintion of flags that can be passed to transportEnc_Open() */
+#define TP_FLAG_MPEG4 1 /** MPEG4 (instead of MPEG2) */
+#define TP_FLAG_LATM_AMV 2 /** LATM AudioMuxVersion */
+#define TP_FLAG_LATM_AMVA 4 /** LATM AudioMuxVersionA */
+
+/**
+ * \brief Allocate transport encoder.
+ * \param phTpEnc Pointer to transport encoder handle.
+ * \return Error code.
+ */
+TRANSPORTENC_ERROR transportEnc_Open(HANDLE_TRANSPORTENC *phTpEnc);
+
+/**
+ * \brief Init transport encoder.
+ * \param bsBuffer Pointer to transport encoder.
+ * \param bsBuffer Pointer to bitstream buffer.
+ * \param bsBufferSize Size in bytes of bsBuffer.
+ * \param transportFmt Format of the transport to be written.
+ * \param config Pointer to a valid CODER_CONFIG struct.
+ * \param flags Transport encoder flags.
+ * \return Error code.
+ */
+TRANSPORTENC_ERROR transportEnc_Init(HANDLE_TRANSPORTENC hTpEnc,
+ UCHAR *bsBuffer, INT bsBufferSize,
+ TRANSPORT_TYPE transportFmt,
+ CODER_CONFIG *config, UINT flags);
+
+/**
+ * \brief Write additional bits in transport encoder.
+ * \param config Pointer to a valid CODER_CONFIG struct.
+ * \param nBits Number of additional bits.
+ * \return Error code.
+ */
+TRANSPORTENC_ERROR transportEnc_AddOtherDataBits(HANDLE_TRANSPORTENC hTpEnc,
+ const int nBits);
+
+/**
+ * \brief Get transport encoder bitstream.
+ * \param hTp Pointer to a transport encoder handle.
+ * \return The handle to the requested FDK bitstream.
+ */
+HANDLE_FDK_BITSTREAM transportEnc_GetBitstream(HANDLE_TRANSPORTENC hTp);
+
+/**
+ * \brief Get amount of bits required by the transport headers.
+ * \param hTp Handle of transport encoder.
+ * \param auBits Amount of payload bits required for the current subframe.
+ * \return Error code.
+ */
+INT transportEnc_GetStaticBits(HANDLE_TRANSPORTENC hTp, int auBits);
+
+/**
+ * \brief Close transport encoder. This function assures that all
+ * allocated memory is freed.
+ * \param phTp Pointer to a previously allocated transport encoder handle.
+ */
+void transportEnc_Close(HANDLE_TRANSPORTENC *phTp);
+
+/**
+ * \brief Write one access unit.
+ * \param hTp Handle of transport encoder.
+ * \param total_bits Amount of total access unit bits.
+ * \param bufferFullness Value of current buffer fullness in bits.
+ * \param noConsideredChannels Number of bitrate wise considered channels (all
+ * minus LFE channels).
+ * \return Error code.
+ */
+TRANSPORTENC_ERROR transportEnc_WriteAccessUnit(HANDLE_TRANSPORTENC hTp,
+ INT total_bits,
+ int bufferFullness,
+ int noConsideredChannels);
+
+/**
+ * \brief Inform the transportEnc layer that writing of access unit has
+ * finished. This function is required to be called when the encoder has
+ * finished writing one Access one Access Unit for bitstream
+ * housekeeping.
+ * \param hTp Transport handle.
+ * \param pBits Pointer to an int, where the current amount of frame bits is
+ * passed and where the current amount of subframe bits is returned.
+ *
+ * OR: This integer is modified by the amount of extra bit alignment that may
+ * occurr.
+ *
+ * \return Error code.
+ */
+TRANSPORTENC_ERROR transportEnc_EndAccessUnit(HANDLE_TRANSPORTENC hTp,
+ int *pBits);
+
+/*
+ * \brief Get a payload frame.
+ * \param hTpEnc Transport encoder handle.
+ * \param nBytes Pointer to an int to hold the frame size in bytes. Returns
+ * zero if currently there is no complete frame for output (number of sub frames
+ * > 1).
+ * \return Error code.
+ */
+TRANSPORTENC_ERROR transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc,
+ int *nbytes);
+
+/* ADTS CRC support */
+
+/**
+ * \brief Set current bitstream position as start of a new data region.
+ * \param hTpEnc Transport encoder handle.
+ * \param mBits Size in bits of the data region. Set to 0 if it should not be
+ * of a fixed size.
+ * \return Data region ID, which should be used when calling
+ * transportEnc_CrcEndReg().
+ */
+int transportEnc_CrcStartReg(HANDLE_TRANSPORTENC hTpEnc, int mBits);
+
+/**
+ * \brief Set end of data region.
+ * \param hTpEnc Transport encoder handle.
+ * \param reg Data region ID, opbtained from transportEnc_CrcStartReg().
+ * \return void
+ */
+void transportEnc_CrcEndReg(HANDLE_TRANSPORTENC hTpEnc, int reg);
+
+/**
+ * \brief Get AudioSpecificConfig or StreamMuxConfig from transport
+ * encoder handle and write it to dataBuffer.
+ * \param hTpEnc Transport encoder handle.
+ * \param cc Pointer to the current and valid configuration contained
+ * in a CODER_CONFIG struct.
+ * \param dataBuffer Bitbuffer holding binary configuration.
+ * \param confType Pointer to an UINT where the configuration type is
+ * returned (0:ASC, 1:SMC).
+ * \return Error code.
+ */
+TRANSPORTENC_ERROR transportEnc_GetConf(HANDLE_TRANSPORTENC hTpEnc,
+ CODER_CONFIG *cc,
+ FDK_BITSTREAM *dataBuffer,
+ UINT *confType);
+
+/**
+ * \brief Get information (version among other things) of the transport
+ * encoder library.
+ * \param info Pointer to an allocated LIB_INFO struct.
+ * \return Error code.
+ */
+TRANSPORTENC_ERROR transportEnc_GetLibInfo(LIB_INFO *info);
+
+#endif /* #ifndef TPENC_LIB_H */
diff --git a/fdk-aac/libMpegTPEnc/src/tp_version.h b/fdk-aac/libMpegTPEnc/src/tp_version.h
new file mode 100644
index 0000000..9f1aa22
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tp_version.h
@@ -0,0 +1,118 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#if !defined(TP_VERSION_H)
+#define TP_VERSION_H
+
+/* library info */
+#define TP_LIB_VL0 3
+#define TP_LIB_VL1 0
+#define TP_LIB_VL2 0
+#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_TIME __TIME__
+#endif
+#endif /* !defined(TP_VERSION_H) */
diff --git a/fdk-aac/libMpegTPEnc/src/tpenc_adif.cpp b/fdk-aac/libMpegTPEnc/src/tpenc_adif.cpp
new file mode 100644
index 0000000..b281eff
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tpenc_adif.cpp
@@ -0,0 +1,186 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s):
+
+ Description: ADIF Transport Headers writing
+
+*******************************************************************************/
+
+#include "tpenc_adif.h"
+
+#include "tpenc_lib.h"
+#include "tpenc_asc.h"
+
+int adifWrite_EncodeHeader(ADIF_INFO *adif, HANDLE_FDK_BITSTREAM hBs,
+ INT adif_buffer_fullness) {
+ /* ADIF/PCE/ADTS definitions */
+ const char adifId[5] = "ADIF";
+ const int copyRightIdPresent = 0;
+ const int originalCopy = 0;
+ const int home = 0;
+ int err = 0;
+
+ int i;
+
+ INT totalBitRate = adif->bitRate;
+
+ if (adif->headerWritten) return 0;
+
+ /* Align inside PCE with respect to the first bit of the header */
+ UINT alignAnchor = FDKgetValidBits(hBs);
+
+ /* Signal variable bitrate if buffer fullnes exceeds 20 bit */
+ adif->bVariableRate = (adif_buffer_fullness >= (INT)(0x1 << 20)) ? 1 : 0;
+
+ FDKwriteBits(hBs, adifId[0], 8);
+ FDKwriteBits(hBs, adifId[1], 8);
+ FDKwriteBits(hBs, adifId[2], 8);
+ FDKwriteBits(hBs, adifId[3], 8);
+
+ FDKwriteBits(hBs, copyRightIdPresent ? 1 : 0, 1);
+
+ if (copyRightIdPresent) {
+ for (i = 0; i < 72; i++) {
+ FDKwriteBits(hBs, 0, 1);
+ }
+ }
+ FDKwriteBits(hBs, originalCopy ? 1 : 0, 1);
+ FDKwriteBits(hBs, home ? 1 : 0, 1);
+ FDKwriteBits(hBs, adif->bVariableRate ? 1 : 0, 1);
+ FDKwriteBits(hBs, totalBitRate, 23);
+
+ /* we write only one PCE at the moment */
+ FDKwriteBits(hBs, 0, 4);
+
+ if (!adif->bVariableRate) {
+ FDKwriteBits(hBs, adif_buffer_fullness, 20);
+ }
+ /* Write PCE */
+ transportEnc_writePCE(hBs, adif->cm, adif->samplingRate, adif->instanceTag,
+ adif->profile, adif->matrixMixdownA,
+ (adif->pseudoSurroundEnable) ? 1 : 0, alignAnchor);
+
+ return err;
+}
+
+int adifWrite_GetHeaderBits(ADIF_INFO *adif) {
+ /* ADIF definitions */
+ const int copyRightIdPresent = 0;
+
+ if (adif->headerWritten) return 0;
+
+ int bits = 0;
+
+ bits += 8 * 4; /* ADIF ID */
+
+ bits += 1; /* Copyright present */
+
+ if (copyRightIdPresent) bits += 72; /* Copyright ID */
+
+ bits += 26;
+
+ bits += 4; /* Number of PCE's */
+
+ if (!adif->bVariableRate) {
+ bits += 20;
+ }
+
+ /* write PCE */
+ bits = transportEnc_GetPCEBits(adif->cm, adif->matrixMixdownA, bits);
+
+ return bits;
+}
diff --git a/fdk-aac/libMpegTPEnc/src/tpenc_adif.h b/fdk-aac/libMpegTPEnc/src/tpenc_adif.h
new file mode 100644
index 0000000..e001afc
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tpenc_adif.h
@@ -0,0 +1,146 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s): Alex Goeschel
+
+ Description: Transport Headers support
+
+*******************************************************************************/
+
+#ifndef TPENC_ADIF_H
+#define TPENC_ADIF_H
+
+#include "machine_type.h"
+#include "FDK_bitstream.h"
+
+#include "tp_data.h"
+
+typedef struct {
+ CHANNEL_MODE cm;
+ INT samplingRate;
+ INT bitRate;
+ int profile;
+ int bVariableRate;
+ int instanceTag;
+ int headerWritten;
+ int matrixMixdownA;
+ int pseudoSurroundEnable;
+
+} ADIF_INFO;
+
+/**
+ * \brief encodes ADIF Header
+ *
+ * \param adif pointer to ADIF_INFO structure
+ * \param hBitStream handle of bitstream, where the ADIF header is written into
+ * \param adif_buffer_fullness buffer fullness value for the ADIF header
+ *
+ * \return 0 on success
+ */
+int adifWrite_EncodeHeader(ADIF_INFO *adif, HANDLE_FDK_BITSTREAM hBitStream,
+ INT adif_buffer_fullness);
+
+/**
+ * \brief Get bit demand of a ADIF header
+ *
+ * \param adif pointer to ADIF_INFO structure
+ *
+ * \return amount of bits required to write the ADIF header according to the
+ * data contained in the adif parameter
+ */
+int adifWrite_GetHeaderBits(ADIF_INFO *adif);
+
+#endif /* TPENC_ADIF_H */
diff --git a/fdk-aac/libMpegTPEnc/src/tpenc_adts.cpp b/fdk-aac/libMpegTPEnc/src/tpenc_adts.cpp
new file mode 100644
index 0000000..3f7e62c
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tpenc_adts.cpp
@@ -0,0 +1,319 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s): Alex Groeschel
+
+ Description: ADTS Transport Headers support
+
+*******************************************************************************/
+
+#include "tpenc_adts.h"
+
+#include "tpenc_lib.h"
+#include "tpenc_asc.h"
+
+int adtsWrite_CrcStartReg(
+ HANDLE_ADTS pAdts, /*!< pointer to adts stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int mBits /*!< number of bits in crc region */
+) {
+ if (pAdts->protection_absent) {
+ return 0;
+ }
+ return (FDKcrcStartReg(&pAdts->crcInfo, hBs, mBits));
+}
+
+void adtsWrite_CrcEndReg(
+ HANDLE_ADTS pAdts, /*!< pointer to adts crc info stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int reg /*!< crc region */
+) {
+ if (pAdts->protection_absent == 0) {
+ FDKcrcEndReg(&pAdts->crcInfo, hBs, reg);
+ }
+}
+
+int adtsWrite_GetHeaderBits(HANDLE_ADTS hAdts) {
+ int bits = 0;
+
+ if (hAdts->currentBlock == 0) {
+ /* Static and variable header bits */
+ bits = 56;
+ if (!hAdts->protection_absent) {
+ /* Add header/ single raw data block CRC bits */
+ bits += 16;
+ if (hAdts->num_raw_blocks > 0) {
+ /* Add bits of raw data block position markers */
+ bits += (hAdts->num_raw_blocks) * 16;
+ }
+ }
+ }
+ if (!hAdts->protection_absent && hAdts->num_raw_blocks > 0) {
+ /* Add raw data block CRC bits. Not really part of the header, put they
+ * cause bit overhead to be accounted. */
+ bits += 16;
+ }
+
+ hAdts->headerBits = bits;
+
+ return bits;
+}
+
+INT adtsWrite_Init(HANDLE_ADTS hAdts, CODER_CONFIG *config) {
+ /* Sanity checks */
+ if (config->nSubFrames < 1 || config->nSubFrames > 4 ||
+ (int)config->aot > 4 || (int)config->aot < 1) {
+ return -1;
+ }
+
+ /* fixed header */
+ if (config->flags & CC_MPEG_ID) {
+ hAdts->mpeg_id = 0; /* MPEG 4 */
+ } else {
+ hAdts->mpeg_id = 1; /* MPEG 2 */
+ }
+ hAdts->layer = 0;
+ hAdts->protection_absent = !(config->flags & CC_PROTECTION);
+ hAdts->profile = ((int)config->aot) - 1;
+ hAdts->sample_freq_index = getSamplingRateIndex(config->samplingRate, 4);
+ hAdts->sample_freq = config->samplingRate;
+ hAdts->private_bit = 0;
+ hAdts->channel_mode = config->channelMode;
+ hAdts->original = 0;
+ hAdts->home = 0;
+ /* variable header */
+ hAdts->copyright_id = 0;
+ hAdts->copyright_start = 0;
+
+ hAdts->num_raw_blocks = config->nSubFrames - 1; /* 0 means 1 raw data block */
+
+ hAdts->channel_config_zero = config->channelConfigZero;
+
+ FDKcrcInit(&hAdts->crcInfo, 0x8005, 0xFFFF, 16);
+
+ hAdts->currentBlock = 0;
+
+ return 0;
+}
+
+int adtsWrite_EncodeHeader(HANDLE_ADTS hAdts, HANDLE_FDK_BITSTREAM hBitStream,
+ int buffer_fullness, int frame_length) {
+ INT crcIndex = 0;
+
+ hAdts->headerBits = adtsWrite_GetHeaderBits(hAdts);
+
+ FDK_ASSERT(((frame_length + hAdts->headerBits) / 8) < 0x2000); /*13 bit*/
+ FDK_ASSERT(buffer_fullness < 0x800); /* 11 bit */
+
+ if (!hAdts->protection_absent) {
+ FDKcrcReset(&hAdts->crcInfo);
+ }
+
+ if (hAdts->currentBlock == 0) {
+ FDKresetBitbuffer(hBitStream, BS_WRITER);
+ }
+
+ hAdts->subFrameStartBit = FDKgetValidBits(hBitStream);
+
+ /* Skip new header if this is raw data block 1..n */
+ if (hAdts->currentBlock == 0) {
+ FDKresetBitbuffer(hBitStream, BS_WRITER);
+
+ if (hAdts->num_raw_blocks == 0) {
+ crcIndex = adtsWrite_CrcStartReg(hAdts, hBitStream, 0);
+ }
+
+ /* fixed header */
+ FDKwriteBits(hBitStream, 0xFFF, 12);
+ FDKwriteBits(hBitStream, hAdts->mpeg_id, 1);
+ FDKwriteBits(hBitStream, hAdts->layer, 2);
+ FDKwriteBits(hBitStream, hAdts->protection_absent, 1);
+ FDKwriteBits(hBitStream, hAdts->profile, 2);
+ FDKwriteBits(hBitStream, hAdts->sample_freq_index, 4);
+ FDKwriteBits(hBitStream, hAdts->private_bit, 1);
+ FDKwriteBits(
+ hBitStream,
+ getChannelConfig(hAdts->channel_mode, hAdts->channel_config_zero), 3);
+ FDKwriteBits(hBitStream, hAdts->original, 1);
+ FDKwriteBits(hBitStream, hAdts->home, 1);
+ /* variable header */
+ FDKwriteBits(hBitStream, hAdts->copyright_id, 1);
+ FDKwriteBits(hBitStream, hAdts->copyright_start, 1);
+ FDKwriteBits(hBitStream, (frame_length + hAdts->headerBits) >> 3, 13);
+ FDKwriteBits(hBitStream, buffer_fullness, 11);
+ FDKwriteBits(hBitStream, hAdts->num_raw_blocks, 2);
+
+ if (!hAdts->protection_absent) {
+ int i;
+
+ /* End header CRC portion for single raw data block and write dummy zero
+ * values for unknown fields. */
+ if (hAdts->num_raw_blocks == 0) {
+ adtsWrite_CrcEndReg(hAdts, hBitStream, crcIndex);
+ } else {
+ for (i = 0; i < hAdts->num_raw_blocks; i++) {
+ FDKwriteBits(hBitStream, 0, 16);
+ }
+ }
+ FDKwriteBits(hBitStream, 0, 16);
+ }
+ } /* End of ADTS header */
+
+ return 0;
+}
+
+void adtsWrite_EndRawDataBlock(HANDLE_ADTS hAdts, HANDLE_FDK_BITSTREAM hBs,
+ int *pBits) {
+ if (!hAdts->protection_absent) {
+ FDK_BITSTREAM bsWriter;
+
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0,
+ BS_WRITER);
+ FDKpushFor(&bsWriter, 56);
+
+ if (hAdts->num_raw_blocks == 0) {
+ FDKwriteBits(&bsWriter, FDKcrcGetCRC(&hAdts->crcInfo), 16);
+ } else {
+ int distance;
+
+ /* Write CRC of current raw data block */
+ FDKwriteBits(hBs, FDKcrcGetCRC(&hAdts->crcInfo), 16);
+
+ /* Write distance to current data block */
+ if (hAdts->currentBlock < hAdts->num_raw_blocks) {
+ FDKpushFor(&bsWriter, hAdts->currentBlock * 16);
+ distance =
+ FDKgetValidBits(hBs) - (56 + (hAdts->num_raw_blocks) * 16 + 16);
+ FDKwriteBits(&bsWriter, distance >> 3, 16);
+ }
+ }
+ FDKsyncCache(&bsWriter);
+ }
+
+ /* Write total frame lenth for multiple raw data blocks and header CRC */
+ if (hAdts->num_raw_blocks > 0 &&
+ hAdts->currentBlock == hAdts->num_raw_blocks) {
+ FDK_BITSTREAM bsWriter;
+ int crcIndex = 0;
+
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0,
+ BS_WRITER);
+
+ if (!hAdts->protection_absent) {
+ FDKcrcReset(&hAdts->crcInfo);
+ crcIndex = FDKcrcStartReg(&hAdts->crcInfo, &bsWriter, 0);
+ }
+ /* Write total frame length */
+ FDKpushFor(&bsWriter, 56 - 28 + 2);
+ FDKwriteBits(&bsWriter, FDKgetValidBits(hBs) >> 3, 13);
+
+ /* Write header CRC */
+ if (!hAdts->protection_absent) {
+ FDKpushFor(&bsWriter, 11 + 2 + (hAdts->num_raw_blocks) * 16);
+ FDKcrcEndReg(&hAdts->crcInfo, &bsWriter, crcIndex);
+ FDKwriteBits(&bsWriter, FDKcrcGetCRC(&hAdts->crcInfo), 16);
+ }
+ FDKsyncCache(&bsWriter);
+ }
+
+ /* Correct *pBits to reflect the amount of bits of the current subframe */
+ *pBits -= hAdts->subFrameStartBit;
+ if (!hAdts->protection_absent && hAdts->num_raw_blocks > 0) {
+ /* Fixup CRC bits, since they come after each raw data block */
+ *pBits += 16;
+ }
+ hAdts->currentBlock++;
+}
diff --git a/fdk-aac/libMpegTPEnc/src/tpenc_adts.h b/fdk-aac/libMpegTPEnc/src/tpenc_adts.h
new file mode 100644
index 0000000..fe86306
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tpenc_adts.h
@@ -0,0 +1,208 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s): Alex Groeschel
+
+ Description: ADTS Transport writer
+
+*******************************************************************************/
+
+#ifndef TPENC_ADTS_H
+#define TPENC_ADTS_H
+
+#include "tp_data.h"
+
+#include "FDK_crc.h"
+
+typedef struct {
+ INT sample_freq;
+ CHANNEL_MODE channel_mode;
+ UCHAR decoderCanDoMpeg4;
+ UCHAR mpeg_id;
+ UCHAR layer;
+ UCHAR protection_absent;
+ UCHAR profile;
+ UCHAR sample_freq_index;
+ UCHAR private_bit;
+ UCHAR original;
+ UCHAR home;
+ UCHAR copyright_id;
+ UCHAR copyright_start;
+ USHORT frame_length;
+ UCHAR num_raw_blocks;
+ UCHAR BufferFullnesStartFlag;
+ UCHAR channel_config_zero;
+ int headerBits; /*!< Header bit demand for the current raw data block */
+ int currentBlock; /*!< Index of current raw data block */
+ int subFrameStartBit; /*!< Bit position where the current raw data block
+ begins */
+ FDK_CRCINFO crcInfo;
+} STRUCT_ADTS;
+
+typedef STRUCT_ADTS *HANDLE_ADTS;
+
+/**
+ * \brief Initialize ADTS data structure
+ *
+ * \param hAdts ADTS data handle
+ * \param config a valid CODER_CONFIG struct from where the required
+ * information for the ADTS header is extrated from
+ *
+ * \return 0 in case of success.
+ */
+INT adtsWrite_Init(HANDLE_ADTS hAdts, CODER_CONFIG *config);
+
+/**
+ * \brief Get the total bit overhead caused by ADTS
+ *
+ * \hAdts handle to ADTS data
+ *
+ * \return Amount of additional bits required for the current raw data block
+ */
+int adtsWrite_GetHeaderBits(HANDLE_ADTS hAdts);
+
+/**
+ * \brief Write an ADTS header into the given bitstream. May not write a header
+ * in case of multiple raw data blocks.
+ *
+ * \param hAdts ADTS data handle
+ * \param hBitStream bitstream handle into which the ADTS may be written into
+ * \param buffer_fullness the buffer fullness value for the ADTS header
+ * \param the current raw data block length
+ *
+ * \return 0 in case of success.
+ */
+INT adtsWrite_EncodeHeader(HANDLE_ADTS hAdts, HANDLE_FDK_BITSTREAM hBitStream,
+ int bufferFullness, int frame_length);
+/**
+ * \brief Finish a ADTS raw data block
+ *
+ * \param hAdts ADTS data handle
+ * \param hBs bitstream handle into which the ADTS may be written into
+ * \param pBits a pointer to a integer holding the current bitstream buffer bit
+ * count, which is corrected to the current raw data block boundary.
+ *
+ */
+void adtsWrite_EndRawDataBlock(HANDLE_ADTS hAdts, HANDLE_FDK_BITSTREAM hBs,
+ int *bits);
+
+/**
+ * \brief Start 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 pAdts ADTS data handle
+ * \param hBs bitstream handle of which the CRC region ends
+ * \param mBits limit of number of bits to be considered for the requested CRC
+ * region
+ *
+ * \return ID for the created region, -1 in case of an error
+ */
+int adtsWrite_CrcStartReg(HANDLE_ADTS pAdts, HANDLE_FDK_BITSTREAM hBs,
+ int mBits);
+
+/**
+ * \brief Ends CRC region identified by reg
+ *
+ * \param pAdts ADTS data handle
+ * \param hBs bitstream handle of which the CRC region ends
+ * \param reg a CRC region ID returned previously by adtsWrite_CrcStartReg()
+ */
+void adtsWrite_CrcEndReg(HANDLE_ADTS pAdts, HANDLE_FDK_BITSTREAM hBs, int reg);
+
+#endif /* TPENC_ADTS_H */
diff --git a/fdk-aac/libMpegTPEnc/src/tpenc_asc.cpp b/fdk-aac/libMpegTPEnc/src/tpenc_asc.cpp
new file mode 100644
index 0000000..0b484a0
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tpenc_asc.cpp
@@ -0,0 +1,996 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "tp_data.h"
+
+#include "tpenc_lib.h"
+#include "tpenc_asc.h"
+#include "FDK_bitstream.h"
+#include "genericStds.h"
+
+#include "FDK_crc.h"
+
+#define PCE_HEIGHT_EXT_SYNC (0xAC)
+#define HEIGHT_NORMAL 0
+#define HEIGHT_TOP 1
+#define HEIGHT_BOTTOM 2
+#define MAX_FRONT_ELEMENTS 8
+#define MAX_SIDE_ELEMENTS 3
+#define MAX_BACK_ELEMENTS 4
+
+/**
+ * Describe additional PCE height information for front, side and back channel
+ * elements.
+ */
+typedef struct {
+ UCHAR
+ num_front_height_channel_elements[2]; /*!< Number of front channel
+ elements in top [0] and bottom
+ [1] plane. */
+ UCHAR num_side_height_channel_elements[2]; /*!< Number of side channel
+ elements in top [0] and bottom
+ [1] plane. */
+ UCHAR num_back_height_channel_elements[2]; /*!< Number of back channel
+ elements in top [0] and bottom
+ [1] plane. */
+} PCE_HEIGHT_NUM;
+
+/**
+ * Describe a PCE based on placed channel elements and element type sequence.
+ */
+typedef struct {
+ UCHAR num_front_channel_elements; /*!< Number of front channel elements. */
+ UCHAR num_side_channel_elements; /*!< Number of side channel elements. */
+ UCHAR num_back_channel_elements; /*!< Number of back channel elements. */
+ UCHAR num_lfe_channel_elements; /*!< Number of lfe channel elements. */
+ const MP4_ELEMENT_ID
+ *pEl_type; /*!< List contains sequence describing the elements
+ in present channel mode. (MPEG order) */
+ const PCE_HEIGHT_NUM *pHeight_num;
+} PCE_CONFIGURATION;
+
+/**
+ * Map an incoming channel mode to a existing PCE configuration entry.
+ */
+typedef struct {
+ CHANNEL_MODE channel_mode; /*!< Present channel mode. */
+ PCE_CONFIGURATION
+ pce_configuration; /*!< Program config element description. */
+
+} CHANNEL_CONFIGURATION;
+
+/**
+ * The following arrays provide the IDs of the consecutive elements for each
+ * mode.
+ */
+static const MP4_ELEMENT_ID elType_1[] = {ID_SCE};
+static const MP4_ELEMENT_ID elType_2[] = {ID_CPE};
+static const MP4_ELEMENT_ID elType_1_2[] = {ID_SCE, ID_CPE};
+static const MP4_ELEMENT_ID elType_1_2_1[] = {ID_SCE, ID_CPE, ID_SCE};
+static const MP4_ELEMENT_ID elType_1_2_2[] = {ID_SCE, ID_CPE, ID_CPE};
+static const MP4_ELEMENT_ID elType_1_2_2_1[] = {ID_SCE, ID_CPE, ID_CPE, ID_LFE};
+static const MP4_ELEMENT_ID elType_1_2_2_2_1[] = {ID_SCE, ID_CPE, ID_CPE,
+ ID_CPE, ID_LFE};
+static const MP4_ELEMENT_ID elType_6_1[] = {ID_SCE, ID_CPE, ID_CPE, ID_SCE,
+ ID_LFE};
+static const MP4_ELEMENT_ID elType_7_1_back[] = {ID_SCE, ID_CPE, ID_CPE, ID_CPE,
+ ID_LFE};
+static const MP4_ELEMENT_ID elType_7_1_top_front[] = {ID_SCE, ID_CPE, ID_CPE,
+ ID_LFE, ID_CPE};
+static const MP4_ELEMENT_ID elType_7_1_rear_surround[] = {
+ ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE};
+static const MP4_ELEMENT_ID elType_7_1_front_center[] = {ID_SCE, ID_CPE, ID_CPE,
+ ID_CPE, ID_LFE};
+
+/**
+ * The following arrays provide information on how many front, side and back
+ * elements are assigned to the top or bottom plane for each mode that comprises
+ * height information.
+ */
+static const PCE_HEIGHT_NUM heightNum_7_1_top_front = {{1, 0}, {0, 0}, {0, 0}};
+
+/**
+ * \brief Table contains all supported channel modes and according PCE
+ configuration description.
+ *
+ * The mode identifier is followed by the number of front, side, back, and LFE
+ elements.
+ * These are followed by a pointer to the IDs of the consecutive elements
+ (ID_SCE, ID_CPE, ID_LFE).
+ *
+ * For some modes (MODE_7_1_TOP_FRONT and MODE_22_2) additional height
+ information is transmitted.
+ * In this case the additional pointer provides information on how many front,
+ side and back elements
+ * are assigned to the top or bottom plane.The elements are arranged in the
+ following order: normal height (front, side, back, LFE), top height (front,
+ side, back), bottom height (front, side, back).
+ *
+ *
+ * E.g. MODE_7_1_TOP_FRONT means:
+ * - 3 elements are front channel elements.
+ * - 0 elements are side channel elements.
+ * - 1 element is back channel element.
+ * - 1 element is an LFE channel element.
+ * - the element order is ID_SCE, ID_CPE, ID_CPE,
+ ID_LFE, ID_CPE.
+ * - 1 of the front elements is in the top plane.
+ *
+ * This leads to the following mapping for the cconsecutive elements in the
+ MODE_7_1_TOP_FRONT bitstream:
+ * - ID_SCE -> normal height front,
+ - ID_CPE -> normal height front,
+ - ID_CPE -> normal height back,
+ - ID_LFE -> normal height LFE,
+ - ID_CPE -> top height front.
+ */
+static const CHANNEL_CONFIGURATION pceConfigTab[] = {
+ {MODE_1,
+ {1, 0, 0, 0, elType_1,
+ NULL}}, /* don't transmit height information in this mode */
+ {MODE_2,
+ {1, 0, 0, 0, elType_2,
+ NULL}}, /* don't transmit height information in this mode */
+ {MODE_1_2,
+ {2, 0, 0, 0, elType_1_2,
+ NULL}}, /* don't transmit height information in this mode */
+ {MODE_1_2_1,
+ {2, 0, 1, 0, elType_1_2_1,
+ NULL}}, /* don't transmit height information in this mode */
+ {MODE_1_2_2,
+ {2, 0, 1, 0, elType_1_2_2,
+ NULL}}, /* don't transmit height information in this mode */
+ {MODE_1_2_2_1,
+ {2, 0, 1, 1, elType_1_2_2_1,
+ NULL}}, /* don't transmit height information in this mode */
+ {MODE_1_2_2_2_1,
+ {3, 0, 1, 1, elType_1_2_2_2_1,
+ NULL}}, /* don't transmit height information in this mode */
+
+ {MODE_6_1,
+ {2, 0, 2, 1, elType_6_1,
+ NULL}}, /* don't transmit height information in this mode */
+ {MODE_7_1_BACK,
+ {2, 0, 2, 1, elType_7_1_back,
+ NULL}}, /* don't transmit height information in this mode */
+ {MODE_7_1_TOP_FRONT,
+ {3, 0, 1, 1, elType_7_1_top_front, &heightNum_7_1_top_front}},
+
+ {MODE_7_1_REAR_SURROUND,
+ {2, 0, 2, 1, elType_7_1_rear_surround,
+ NULL}}, /* don't transmit height information in this mode */
+ {MODE_7_1_FRONT_CENTER,
+ {3, 0, 1, 1, elType_7_1_front_center,
+ NULL}} /* don't transmit height information in this mode */
+};
+
+/**
+ * \brief Get program config element description for existing channel mode.
+ *
+ * \param channel_mode Current channel mode.
+ *
+ * \return
+ * - Pointer to PCE_CONFIGURATION entry, on success.
+ * - NULL, on failure.
+ */
+static const PCE_CONFIGURATION *getPceEntry(const CHANNEL_MODE channel_mode) {
+ UINT i;
+ const PCE_CONFIGURATION *pce_config = NULL;
+
+ for (i = 0; i < (sizeof(pceConfigTab) / sizeof(CHANNEL_CONFIGURATION)); i++) {
+ if (pceConfigTab[i].channel_mode == channel_mode) {
+ pce_config = &pceConfigTab[i].pce_configuration;
+ break;
+ }
+ }
+
+ return pce_config;
+}
+
+int getChannelConfig(const CHANNEL_MODE channel_mode,
+ const UCHAR channel_config_zero) {
+ INT chan_config = 0;
+
+ if (channel_config_zero != 0) {
+ chan_config = 0;
+ } else {
+ switch (channel_mode) {
+ case MODE_1:
+ chan_config = 1;
+ break;
+ case MODE_2:
+ chan_config = 2;
+ break;
+ case MODE_1_2:
+ chan_config = 3;
+ break;
+ case MODE_1_2_1:
+ chan_config = 4;
+ break;
+ case MODE_1_2_2:
+ chan_config = 5;
+ break;
+ case MODE_1_2_2_1:
+ chan_config = 6;
+ break;
+ case MODE_1_2_2_2_1:
+ chan_config = 7;
+ break;
+ case MODE_6_1:
+ chan_config = 11;
+ break;
+ case MODE_7_1_BACK:
+ chan_config = 12;
+ break;
+ case MODE_7_1_TOP_FRONT:
+ chan_config = 14;
+ break;
+ default:
+ chan_config = 0;
+ }
+ }
+
+ return chan_config;
+}
+
+CHANNEL_MODE transportEnc_GetChannelMode(int noChannels) {
+ CHANNEL_MODE chMode;
+
+ if (noChannels <= 8 && noChannels > 0)
+ chMode = (CHANNEL_MODE)(
+ (noChannels == 8) ? 7
+ : noChannels); /* see : iso/mpeg4 v1 audio subpart1*/
+ else
+ chMode = MODE_UNKNOWN;
+
+ return chMode;
+}
+
+int transportEnc_writePCE(HANDLE_FDK_BITSTREAM hBs, CHANNEL_MODE channelMode,
+ INT sampleRate, int instanceTagPCE, int profile,
+ int matrixMixdownA, int pseudoSurroundEnable,
+ UINT alignAnchor) {
+ int sampleRateIndex, i;
+ const PCE_CONFIGURATION *config = NULL;
+ const MP4_ELEMENT_ID *pEl_list = NULL;
+ UCHAR cpeCnt = 0, sceCnt = 0, lfeCnt = 0, frntCnt = 0, sdCnt = 0, bckCnt = 0,
+ isCpe = 0, tag = 0, normalFrontEnd = 0, normalSideEnd = 0,
+ normalBackEnd = 0, topFrontEnd = 0, topSideEnd = 0, topBackEnd = 0,
+ bottomFrontEnd = 0, bottomSideEnd = 0;
+#ifdef FDK_ASSERT_ENABLE
+ UCHAR bottomBackEnd = 0;
+#endif
+ enum elementDepth { FRONT, SIDE, BACK } elDepth;
+
+ sampleRateIndex = getSamplingRateIndex(sampleRate, 4);
+ if (sampleRateIndex == 15) {
+ return -1;
+ }
+
+ if ((config = getPceEntry(channelMode)) == NULL) {
+ return -1;
+ }
+
+ FDK_ASSERT(config->num_front_channel_elements <= MAX_FRONT_ELEMENTS);
+ FDK_ASSERT(config->num_side_channel_elements <= MAX_SIDE_ELEMENTS);
+ FDK_ASSERT(config->num_back_channel_elements <= MAX_BACK_ELEMENTS);
+
+ UCHAR frontIsCpe[MAX_FRONT_ELEMENTS] = {0},
+ frontTag[MAX_FRONT_ELEMENTS] = {0}, sideIsCpe[MAX_SIDE_ELEMENTS] = {0},
+ sideTag[MAX_SIDE_ELEMENTS] = {0}, backIsCpe[MAX_BACK_ELEMENTS] = {0},
+ backTag[MAX_BACK_ELEMENTS] = {0};
+
+ /* Write general information */
+
+ FDKwriteBits(hBs, instanceTagPCE, 4); /* Element instance tag */
+ FDKwriteBits(hBs, profile, 2); /* Object type */
+ FDKwriteBits(hBs, sampleRateIndex, 4); /* Sample rate index*/
+
+ FDKwriteBits(hBs, config->num_front_channel_elements,
+ 4); /* Front channel Elements */
+ FDKwriteBits(hBs, config->num_side_channel_elements,
+ 4); /* No Side Channel Elements */
+ FDKwriteBits(hBs, config->num_back_channel_elements,
+ 4); /* No Back channel Elements */
+ FDKwriteBits(hBs, config->num_lfe_channel_elements,
+ 2); /* No Lfe channel elements */
+
+ FDKwriteBits(hBs, 0, 3); /* No assoc data elements */
+ FDKwriteBits(hBs, 0, 4); /* No valid cc elements */
+ FDKwriteBits(hBs, 0, 1); /* Mono mixdown present */
+ FDKwriteBits(hBs, 0, 1); /* Stereo mixdown present */
+
+ if (matrixMixdownA != 0 &&
+ ((channelMode == MODE_1_2_2) || (channelMode == MODE_1_2_2_1))) {
+ FDKwriteBits(hBs, 1, 1); /* Matrix mixdown present */
+ FDKwriteBits(hBs, (matrixMixdownA - 1) & 0x3, 2); /* matrix_mixdown_idx */
+ FDKwriteBits(hBs, (pseudoSurroundEnable) ? 1 : 0,
+ 1); /* pseudo_surround_enable */
+ } else {
+ FDKwriteBits(hBs, 0, 1); /* Matrix mixdown not present */
+ }
+
+ if (config->pHeight_num != NULL) {
+ /* we have up to three different height levels, and in each height level we
+ * may have front, side and back channels. We need to know where each
+ * section ends to correctly count the tags */
+ normalFrontEnd = config->num_front_channel_elements -
+ config->pHeight_num->num_front_height_channel_elements[0] -
+ config->pHeight_num->num_front_height_channel_elements[1];
+ normalSideEnd = normalFrontEnd + config->num_side_channel_elements -
+ config->pHeight_num->num_side_height_channel_elements[0] -
+ config->pHeight_num->num_side_height_channel_elements[1];
+ normalBackEnd = normalSideEnd + config->num_back_channel_elements -
+ config->pHeight_num->num_back_height_channel_elements[0] -
+ config->pHeight_num->num_back_height_channel_elements[1];
+
+ topFrontEnd =
+ normalBackEnd + config->num_lfe_channel_elements +
+ config->pHeight_num->num_front_height_channel_elements[0]; /* only
+ normal
+ height
+ LFEs
+ assumed */
+ topSideEnd =
+ topFrontEnd + config->pHeight_num->num_side_height_channel_elements[0];
+ topBackEnd =
+ topSideEnd + config->pHeight_num->num_back_height_channel_elements[0];
+
+ bottomFrontEnd =
+ topBackEnd + config->pHeight_num->num_front_height_channel_elements[1];
+ bottomSideEnd = bottomFrontEnd +
+ config->pHeight_num->num_side_height_channel_elements[1];
+#ifdef FDK_ASSERT_ENABLE
+ bottomBackEnd = bottomSideEnd +
+ config->pHeight_num->num_back_height_channel_elements[1];
+#endif
+
+ } else {
+ /* we have only one height level, so we don't care about top or bottom */
+ normalFrontEnd = config->num_front_channel_elements;
+ normalSideEnd = normalFrontEnd + config->num_side_channel_elements;
+ normalBackEnd = normalSideEnd + config->num_back_channel_elements;
+ }
+
+ /* assign cpe and tag information to either front, side or back channels */
+
+ pEl_list = config->pEl_type;
+
+ for (i = 0; i < config->num_front_channel_elements +
+ config->num_side_channel_elements +
+ config->num_back_channel_elements +
+ config->num_lfe_channel_elements;
+ i++) {
+ if (*pEl_list == ID_LFE) {
+ pEl_list++;
+ continue;
+ }
+ isCpe = (*pEl_list++ == ID_CPE) ? 1 : 0;
+ tag = (isCpe) ? cpeCnt++ : sceCnt++;
+
+ if (i < normalFrontEnd)
+ elDepth = FRONT;
+ else if (i < normalSideEnd)
+ elDepth = SIDE;
+ else if (i < normalBackEnd)
+ elDepth = BACK;
+ else if (i < topFrontEnd)
+ elDepth = FRONT;
+ else if (i < topSideEnd)
+ elDepth = SIDE;
+ else if (i < topBackEnd)
+ elDepth = BACK;
+ else if (i < bottomFrontEnd)
+ elDepth = FRONT;
+ else if (i < bottomSideEnd)
+ elDepth = SIDE;
+ else {
+ elDepth = BACK;
+ FDK_ASSERT(i < bottomBackEnd); /* won't fail if implementation of pce
+ configuration table is correct */
+ }
+
+ switch (elDepth) {
+ case FRONT:
+ FDK_ASSERT(frntCnt < config->num_front_channel_elements);
+ frontIsCpe[frntCnt] = isCpe;
+ frontTag[frntCnt++] = tag;
+ break;
+ case SIDE:
+ FDK_ASSERT(sdCnt < config->num_side_channel_elements);
+ sideIsCpe[sdCnt] = isCpe;
+ sideTag[sdCnt++] = tag;
+ break;
+ case BACK:
+ FDK_ASSERT(bckCnt < config->num_back_channel_elements);
+ backIsCpe[bckCnt] = isCpe;
+ backTag[bckCnt++] = tag;
+ break;
+ }
+ }
+
+ /* Write front channel isCpe and tags */
+ for (i = 0; i < config->num_front_channel_elements; i++) {
+ FDKwriteBits(hBs, frontIsCpe[i], 1);
+ FDKwriteBits(hBs, frontTag[i], 4);
+ }
+ /* Write side channel isCpe and tags */
+ for (i = 0; i < config->num_side_channel_elements; i++) {
+ FDKwriteBits(hBs, sideIsCpe[i], 1);
+ FDKwriteBits(hBs, sideTag[i], 4);
+ }
+ /* Write back channel isCpe and tags */
+ for (i = 0; i < config->num_back_channel_elements; i++) {
+ FDKwriteBits(hBs, backIsCpe[i], 1);
+ FDKwriteBits(hBs, backTag[i], 4);
+ }
+ /* Write LFE information */
+ for (i = 0; i < config->num_lfe_channel_elements; i++) {
+ FDKwriteBits(hBs, lfeCnt++, 4); /* LFE channel Instance Tag. */
+ }
+
+ /* - num_valid_cc_elements always 0.
+ - num_assoc_data_elements always 0. */
+
+ /* Byte alignment: relative to alignAnchor
+ ADTS: align with respect to the first bit of the raw_data_block()
+ ADIF: align with respect to the first bit of the header
+ LATM: align with respect to the first bit of the ASC */
+ FDKbyteAlign(hBs, alignAnchor); /* Alignment */
+
+ /* Write comment information */
+
+ if (config->pHeight_num != NULL) {
+ /* embed height information in comment field */
+
+ INT commentBytes =
+ 1 /* PCE_HEIGHT_EXT_SYNC */
+ + ((((config->num_front_channel_elements +
+ config->num_side_channel_elements +
+ config->num_back_channel_elements)
+ << 1) +
+ 7) >>
+ 3) /* 2 bit height info per element, round up to full bytes */
+ + 1; /* CRC */
+
+ FDKwriteBits(hBs, commentBytes, 8); /* comment size. */
+
+ FDK_CRCINFO crcInfo; /* CRC state info */
+ INT crcReg;
+
+ FDKcrcInit(&crcInfo, 0x07, 0xFF, 8);
+ crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
+
+ FDKwriteBits(hBs, PCE_HEIGHT_EXT_SYNC, 8); /* indicate height extension */
+
+ /* front channel height information */
+ for (i = 0;
+ i < config->num_front_channel_elements -
+ config->pHeight_num->num_front_height_channel_elements[0] -
+ config->pHeight_num->num_front_height_channel_elements[1];
+ i++)
+ FDKwriteBits(hBs, HEIGHT_NORMAL, 2);
+ for (i = 0; i < config->pHeight_num->num_front_height_channel_elements[0];
+ i++)
+ FDKwriteBits(hBs, HEIGHT_TOP, 2);
+ for (i = 0; i < config->pHeight_num->num_front_height_channel_elements[1];
+ i++)
+ FDKwriteBits(hBs, HEIGHT_BOTTOM, 2);
+
+ /* side channel height information */
+ for (i = 0;
+ i < config->num_side_channel_elements -
+ config->pHeight_num->num_side_height_channel_elements[0] -
+ config->pHeight_num->num_side_height_channel_elements[1];
+ i++)
+ FDKwriteBits(hBs, HEIGHT_NORMAL, 2);
+ for (i = 0; i < config->pHeight_num->num_side_height_channel_elements[0];
+ i++)
+ FDKwriteBits(hBs, HEIGHT_TOP, 2);
+ for (i = 0; i < config->pHeight_num->num_side_height_channel_elements[1];
+ i++)
+ FDKwriteBits(hBs, HEIGHT_BOTTOM, 2);
+
+ /* back channel height information */
+ for (i = 0;
+ i < config->num_back_channel_elements -
+ config->pHeight_num->num_back_height_channel_elements[0] -
+ config->pHeight_num->num_back_height_channel_elements[1];
+ i++)
+ FDKwriteBits(hBs, HEIGHT_NORMAL, 2);
+ for (i = 0; i < config->pHeight_num->num_back_height_channel_elements[0];
+ i++)
+ FDKwriteBits(hBs, HEIGHT_TOP, 2);
+ for (i = 0; i < config->pHeight_num->num_back_height_channel_elements[1];
+ i++)
+ FDKwriteBits(hBs, HEIGHT_BOTTOM, 2);
+
+ FDKbyteAlign(hBs, alignAnchor); /* Alignment */
+
+ FDKcrcEndReg(&crcInfo, hBs, crcReg);
+ FDKwriteBits(hBs, FDKcrcGetCRC(&crcInfo), 8);
+
+ } else {
+ FDKwriteBits(hBs, 0,
+ 8); /* Do no write any comment or height information. */
+ }
+
+ return 0;
+}
+
+int transportEnc_GetPCEBits(CHANNEL_MODE channelMode, int matrixMixdownA,
+ int bits) {
+ const PCE_CONFIGURATION *config = NULL;
+
+ if ((config = getPceEntry(channelMode)) == NULL) {
+ return -1; /* unsupported channelmapping */
+ }
+
+ bits +=
+ 4 + 2 + 4; /* Element instance tag + Object type + Sample rate index */
+ bits += 4 + 4 + 4 + 2; /* No (front + side + back + lfe channel) elements */
+ bits += 3 + 4; /* No (assoc data + valid cc) elements */
+ bits += 1 + 1 + 1; /* Mono + Stereo + Matrix mixdown present */
+
+ if (matrixMixdownA != 0 &&
+ ((channelMode == MODE_1_2_2) || (channelMode == MODE_1_2_2_1))) {
+ bits += 3; /* matrix_mixdown_idx + pseudo_surround_enable */
+ }
+
+ bits += (1 + 4) * (INT)config->num_front_channel_elements;
+ bits += (1 + 4) * (INT)config->num_side_channel_elements;
+ bits += (1 + 4) * (INT)config->num_back_channel_elements;
+ bits += (4) * (INT)config->num_lfe_channel_elements;
+
+ /* - num_valid_cc_elements always 0.
+ - num_assoc_data_elements always 0. */
+
+ if ((bits % 8) != 0) {
+ bits += (8 - (bits % 8)); /* Alignment */
+ }
+
+ bits += 8; /* Comment field bytes */
+
+ if (config->pHeight_num != NULL) {
+ /* Comment field (height extension) */
+
+ bits +=
+ 8 /* PCE_HEIGHT_EXT_SYNC */
+ +
+ ((config->num_front_channel_elements +
+ config->num_side_channel_elements + config->num_back_channel_elements)
+ << 1) /* 2 bit height info per element */
+ + 8; /* CRC */
+
+ if ((bits % 8) != 0) {
+ bits += (8 - (bits % 8)); /* Alignment */
+ }
+ }
+
+ return bits;
+}
+
+static void writeAot(HANDLE_FDK_BITSTREAM hBitstreamBuffer,
+ AUDIO_OBJECT_TYPE aot) {
+ int tmp = (int)aot;
+
+ if (tmp > 31) {
+ FDKwriteBits(hBitstreamBuffer, AOT_ESCAPE, 5);
+ FDKwriteBits(hBitstreamBuffer, tmp - 32, 6); /* AudioObjectType */
+ } else {
+ FDKwriteBits(hBitstreamBuffer, tmp, 5);
+ }
+}
+
+static void writeSampleRate(HANDLE_FDK_BITSTREAM hBs, int sampleRate,
+ int nBits) {
+ int srIdx = getSamplingRateIndex(sampleRate, nBits);
+
+ FDKwriteBits(hBs, srIdx, nBits);
+ if (srIdx == (1 << nBits) - 1) {
+ FDKwriteBits(hBs, sampleRate, 24);
+ }
+}
+
+static int transportEnc_writeGASpecificConfig(HANDLE_FDK_BITSTREAM asc,
+ CODER_CONFIG *config, int extFlg,
+ UINT alignAnchor) {
+ int aot = config->aot;
+ int samplesPerFrame = config->samplesPerFrame;
+
+ /* start of GASpecificConfig according to ISO/IEC 14496-3 Subpart 4, 4.4.1 */
+ FDKwriteBits(asc,
+ ((samplesPerFrame == 960 || samplesPerFrame == 480) ? 1 : 0),
+ 1); /* frameLengthFlag: 1 for a 960/480 (I)MDCT, 0 for a 1024/512
+ (I)MDCT*/
+ FDKwriteBits(asc, 0,
+ 1); /* dependsOnCoreCoder: Sampling Rate Coder Specific, see in
+ ISO/IEC 14496-3 Subpart 4, 4.4.1 */
+ FDKwriteBits(asc, extFlg,
+ 1); /* Extension Flag: Shall be 1 for aot = 17,19,20,21,22,23 */
+
+ /* Write PCE if channel config is not 1-7 */
+ if (getChannelConfig(config->channelMode, config->channelConfigZero) == 0) {
+ transportEnc_writePCE(asc, config->channelMode, config->samplingRate, 0, 1,
+ config->matrixMixdownA,
+ (config->flags & CC_PSEUDO_SURROUND) ? 1 : 0,
+ alignAnchor);
+ }
+ if ((aot == AOT_AAC_SCAL) || (aot == AOT_ER_AAC_SCAL)) {
+ FDKwriteBits(asc, 0, 3); /* layerNr */
+ }
+ if (extFlg) {
+ if (aot == AOT_ER_BSAC) {
+ FDKwriteBits(asc, config->BSACnumOfSubFrame, 5); /* numOfSubFrame */
+ FDKwriteBits(asc, config->BSAClayerLength, 11); /* layer_length */
+ }
+ if ((aot == AOT_ER_AAC_LC) || (aot == AOT_ER_AAC_LTP) ||
+ (aot == AOT_ER_AAC_SCAL) || (aot == AOT_ER_AAC_LD)) {
+ FDKwriteBits(asc, (config->flags & CC_VCB11) ? 1 : 0,
+ 1); /* aacSectionDataResillienceFlag */
+ FDKwriteBits(asc, (config->flags & CC_RVLC) ? 1 : 0,
+ 1); /* aacScaleFactorDataResillienceFlag */
+ FDKwriteBits(asc, (config->flags & CC_HCR) ? 1 : 0,
+ 1); /* aacSpectralDataResillienceFlag */
+ }
+ FDKwriteBits(asc, 0, 1); /* extensionFlag3: reserved. Shall be '0' */
+ }
+ return 0;
+}
+
+static int transportEnc_writeELDSpecificConfig(HANDLE_FDK_BITSTREAM hBs,
+ CODER_CONFIG *config,
+ int epConfig,
+ CSTpCallBacks *cb) {
+ UINT frameLengthFlag = 0;
+ switch (config->samplesPerFrame) {
+ case 512:
+ case 256:
+ case 128:
+ case 64:
+ frameLengthFlag = 0;
+ break;
+ case 480:
+ case 240:
+ case 160:
+ case 120:
+ case 60:
+ frameLengthFlag = 1;
+ break;
+ }
+
+ FDKwriteBits(hBs, frameLengthFlag, 1);
+
+ FDKwriteBits(hBs, (config->flags & CC_VCB11) ? 1 : 0, 1);
+ FDKwriteBits(hBs, (config->flags & CC_RVLC) ? 1 : 0, 1);
+ FDKwriteBits(hBs, (config->flags & CC_HCR) ? 1 : 0, 1);
+
+ FDKwriteBits(hBs, (config->flags & CC_SBR) ? 1 : 0, 1); /* SBR header flag */
+ if ((config->flags & CC_SBR)) {
+ FDKwriteBits(hBs, (config->samplingRate == config->extSamplingRate) ? 0 : 1,
+ 1); /* Samplerate Flag */
+ FDKwriteBits(hBs, (config->flags & CC_SBRCRC) ? 1 : 0, 1); /* SBR CRC flag*/
+
+ if (cb->cbSbr != NULL) {
+ const PCE_CONFIGURATION *pPce;
+ int e, sbrElementIndex = 0;
+
+ pPce = getPceEntry(config->channelMode);
+
+ for (e = 0; e < pPce->num_front_channel_elements +
+ pPce->num_side_channel_elements +
+ pPce->num_back_channel_elements +
+ pPce->num_lfe_channel_elements;
+ e++) {
+ if ((pPce->pEl_type[e] == ID_SCE) || (pPce->pEl_type[e] == ID_CPE)) {
+ cb->cbSbr(cb->cbSbrData, hBs, 0, 0, 0, config->aot, pPce->pEl_type[e],
+ sbrElementIndex, 0, 0, 0, NULL, 1);
+ sbrElementIndex++;
+ }
+ }
+ }
+ }
+
+ if ((config->flags & CC_SAC) && (cb->cbSsc != NULL)) {
+ FDKwriteBits(hBs, ELDEXT_LDSAC, 4);
+
+ const INT eldExtLen =
+ (cb->cbSsc(cb->cbSscData, NULL, config->aot, config->extSamplingRate, 0,
+ 0, 0, 0, 0, NULL) +
+ 7) >>
+ 3;
+ INT cnt = eldExtLen;
+
+ if (cnt < 0xF) {
+ FDKwriteBits(hBs, cnt, 4);
+ } else {
+ FDKwriteBits(hBs, 0xF, 4);
+ cnt -= 0xF;
+
+ if (cnt < 0xFF) {
+ FDKwriteBits(hBs, cnt, 8);
+ } else {
+ FDKwriteBits(hBs, 0xFF, 8);
+ cnt -= 0xFF;
+
+ FDK_ASSERT(cnt <= 0xFFFF);
+ FDKwriteBits(hBs, cnt, 16);
+ }
+ }
+
+ cb->cbSsc(cb->cbSscData, hBs, config->aot, config->extSamplingRate, 0, 0, 0,
+ 0, 0, NULL);
+ }
+
+ if (config->downscaleSamplingRate != 0 &&
+ config->downscaleSamplingRate != config->extSamplingRate) {
+ /* downscale active */
+
+ /* eldExtLenDsc: Number of bytes for the ELD downscale extension (srIdx
+ needs 1 byte
+ + downscaleSamplingRate needs additional 3 bytes) */
+ int eldExtLenDsc = 1;
+ int downscaleSamplingRate = config->downscaleSamplingRate;
+ FDKwriteBits(hBs, ELDEXT_DOWNSCALEINFO, 4); /* ELDEXT_DOWNSCALEINFO */
+
+ if ((downscaleSamplingRate != 96000) && (downscaleSamplingRate != 88200) &&
+ (downscaleSamplingRate != 64000) && (downscaleSamplingRate != 48000) &&
+ (downscaleSamplingRate != 44100) && (downscaleSamplingRate != 32000) &&
+ (downscaleSamplingRate != 24000) && (downscaleSamplingRate != 22050) &&
+ (downscaleSamplingRate != 16000) && (downscaleSamplingRate != 12000) &&
+ (downscaleSamplingRate != 11025) && (downscaleSamplingRate != 8000) &&
+ (downscaleSamplingRate != 7350)) {
+ eldExtLenDsc = 4; /* length extends to 4 if downscaleSamplingRate's value
+ is not one of the listed values */
+ }
+
+ FDKwriteBits(hBs, eldExtLenDsc, 4);
+ writeSampleRate(hBs, downscaleSamplingRate, 4);
+ FDKwriteBits(hBs, 0x0, 4); /* fill_nibble */
+ }
+
+ FDKwriteBits(hBs, ELDEXT_TERM, 4); /* ELDEXT_TERM */
+
+ return 0;
+}
+
+static int transportEnc_writeUsacSpecificConfig(HANDLE_FDK_BITSTREAM hBs,
+ int extFlag, CODER_CONFIG *cc,
+ CSTpCallBacks *cb) {
+ FDK_BITSTREAM usacConf;
+ int usacConfigBits = cc->rawConfigBits;
+
+ if ((usacConfigBits <= 0) ||
+ ((usacConfigBits + 7) / 8 > (int)sizeof(cc->rawConfig))) {
+ return TRANSPORTENC_UNSUPPORTED_FORMAT;
+ }
+ FDKinitBitStream(&usacConf, cc->rawConfig, BUFSIZE_DUMMY_VALUE,
+ usacConfigBits, BS_READER);
+
+ for (; usacConfigBits > 0; usacConfigBits--) {
+ UINT tmp = FDKreadBit(&usacConf);
+ FDKwriteBits(hBs, tmp, 1);
+ }
+ FDKsyncCache(hBs);
+
+ return TRANSPORTENC_OK;
+}
+
+int transportEnc_writeASC(HANDLE_FDK_BITSTREAM asc, CODER_CONFIG *config,
+ CSTpCallBacks *cb) {
+ UINT extFlag = 0;
+ int err;
+ int epConfig = 0;
+
+ /* Required for the PCE. */
+ UINT alignAnchor = FDKgetValidBits(asc);
+
+ /* Extension Flag: Shall be 1 for aot = 17,19,20,21,22,23,39 */
+ switch (config->aot) {
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LTP:
+ case AOT_ER_AAC_SCAL:
+ case AOT_ER_TWIN_VQ:
+ case AOT_ER_BSAC:
+ case AOT_ER_AAC_LD:
+ case AOT_ER_AAC_ELD:
+ case AOT_USAC:
+ extFlag = 1;
+ break;
+ default:
+ break;
+ }
+
+ if (config->sbrSignaling == SIG_EXPLICIT_HIERARCHICAL && config->sbrPresent)
+ writeAot(asc, config->extAOT);
+ else
+ writeAot(asc, config->aot);
+
+ /* In case of USAC it is the output not the core sampling rate */
+ writeSampleRate(asc, config->samplingRate, 4);
+
+ /* Try to guess a reasonable channel mode if not given */
+ if (config->channelMode == MODE_INVALID) {
+ config->channelMode = transportEnc_GetChannelMode(config->noChannels);
+ if (config->channelMode == MODE_INVALID) return -1;
+ }
+
+ FDKwriteBits(
+ asc, getChannelConfig(config->channelMode, config->channelConfigZero), 4);
+
+ if (config->sbrSignaling == SIG_EXPLICIT_HIERARCHICAL && config->sbrPresent) {
+ writeSampleRate(asc, config->extSamplingRate, 4);
+ writeAot(asc, config->aot);
+ }
+
+ switch (config->aot) {
+ case AOT_AAC_MAIN:
+ case AOT_AAC_LC:
+ case AOT_AAC_SSR:
+ case AOT_AAC_LTP:
+ case AOT_AAC_SCAL:
+ case AOT_TWIN_VQ:
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LTP:
+ case AOT_ER_AAC_SCAL:
+ case AOT_ER_TWIN_VQ:
+ case AOT_ER_BSAC:
+ case AOT_ER_AAC_LD:
+ err =
+ transportEnc_writeGASpecificConfig(asc, config, extFlag, alignAnchor);
+ if (err) return err;
+ break;
+ case AOT_ER_AAC_ELD:
+ err = transportEnc_writeELDSpecificConfig(asc, config, epConfig, cb);
+ if (err) return err;
+ break;
+ case AOT_USAC:
+ err = transportEnc_writeUsacSpecificConfig(asc, extFlag, config, cb);
+ if (err) {
+ return err;
+ }
+ break;
+ default:
+ return -1;
+ }
+
+ switch (config->aot) {
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LTP:
+ case AOT_ER_AAC_SCAL:
+ case AOT_ER_TWIN_VQ:
+ case AOT_ER_BSAC:
+ case AOT_ER_AAC_LD:
+ case AOT_ER_CELP:
+ case AOT_ER_HVXC:
+ case AOT_ER_HILN:
+ case AOT_ER_PARA:
+ case AOT_ER_AAC_ELD:
+ FDKwriteBits(asc, 0, 2); /* epconfig 0 */
+ break;
+ default:
+ break;
+ }
+
+ /* backward compatible explicit signaling of extension AOT */
+ if (config->sbrSignaling == SIG_EXPLICIT_BW_COMPATIBLE) {
+ TP_ASC_EXTENSION_ID ascExtId = ASCEXT_UNKOWN;
+
+ if (config->sbrPresent) {
+ ascExtId = ASCEXT_SBR;
+ FDKwriteBits(asc, ascExtId, 11);
+ writeAot(asc, config->extAOT);
+ FDKwriteBits(asc, 1, 1); /* sbrPresentFlag=1 */
+ writeSampleRate(asc, config->extSamplingRate, 4);
+ if (config->psPresent) {
+ ascExtId = ASCEXT_PS;
+ FDKwriteBits(asc, ascExtId, 11);
+ FDKwriteBits(asc, 1, 1); /* psPresentFlag=1 */
+ }
+ }
+ }
+
+ /* Make sure all bits are sync'ed */
+ FDKsyncCache(asc);
+
+ return 0;
+}
diff --git a/fdk-aac/libMpegTPEnc/src/tpenc_asc.h b/fdk-aac/libMpegTPEnc/src/tpenc_asc.h
new file mode 100644
index 0000000..5f5621e
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tpenc_asc.h
@@ -0,0 +1,147 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s): Manuel Jander
+
+ Description: Audio Specific Config writer
+
+*******************************************************************************/
+
+#ifndef TPENC_ASC_H
+#define TPENC_ASC_H
+
+/**
+ * \brief Get channel config from channel mode.
+ *
+ * \param channel_mode channel mode
+ * \param channel_config_zero no standard channel configuration
+ *
+ * \return chanel config
+ */
+int getChannelConfig(const CHANNEL_MODE channel_mode,
+ const UCHAR channel_config_zero);
+
+/**
+ * \brief Write a Program Config Element.
+ *
+ * \param hBs bitstream handle into which the PCE is appended
+ * \param channelMode the channel mode to be used
+ * \param sampleRate the sample rate
+ * \param instanceTagPCE the instance tag of the Program Config Element
+ * \param profile the MPEG Audio profile to be used
+ * \param matrix mixdown gain
+ * \param pseudo surround indication
+ * \param reference bitstream position for alignment
+ * \return zero on success, non-zero on failure.
+ */
+int transportEnc_writePCE(HANDLE_FDK_BITSTREAM hBs, CHANNEL_MODE channelMode,
+ INT sampleRate, int instanceTagPCE, int profile,
+ int matrixMixdownA, int pseudoSurroundEnable,
+ UINT alignAnchor);
+
+/**
+ * \brief Get the bit count required by a Program Config Element
+ *
+ * \param channelMode the channel mode to be used
+ * \param matrix mixdown gain
+ * \param bit offset at which the PCE would start
+ * \return the amount of bits required for the PCE including the given bit
+ * offset.
+ */
+int transportEnc_GetPCEBits(CHANNEL_MODE channelMode, int matrixMixdownA,
+ int bits);
+
+#endif /* TPENC_ASC_H */
diff --git a/fdk-aac/libMpegTPEnc/src/tpenc_dab.cpp b/fdk-aac/libMpegTPEnc/src/tpenc_dab.cpp
new file mode 100644
index 0000000..202fecf
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tpenc_dab.cpp
@@ -0,0 +1,467 @@
+
+/* -----------------------------------------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+� Copyright 1995 - 2012 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 Audio Encoder **************************
+
+ Initial author: serge
+ contents/description: DAB Transport Headers support
+
+******************************************************************************/
+#include <stdio.h>
+#include "FDK_audio.h"
+#include "tpenc_dab.h"
+
+
+#include "tpenc_lib.h"
+#include "tpenc_asc.h"
+
+#include "common_fix.h"
+
+int dabWrite_CrcStartReg(
+ HANDLE_DAB pDab, /*!< pointer to dab stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int mBits /*!< number of bits in crc region */
+ )
+{
+ //fprintf(stderr, "dabWrite_CrcStartReg(%p): bits in crc region=%d\n", hBs, mBits);
+ return ( FDKcrcStartReg(&pDab->crcInfo2, hBs, mBits) );
+}
+
+void dabWrite_CrcEndReg(
+ HANDLE_DAB pDab, /*!< pointer to dab crc info stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int reg /*!< crc region */
+ )
+{
+ //fprintf(stderr, "dabWrite_CrcEndReg(%p): crc region=%d\n", hBs, reg);
+ FDKcrcEndReg(&pDab->crcInfo2, hBs, reg);
+}
+
+int dabWrite_GetHeaderBits( HANDLE_DAB hDab )
+{
+ int bits = 0;
+
+ if (hDab->currentBlock == 0) {
+ /* Static and variable header bits */
+ bits += 16; //header_firecode 16
+ bits += 8; //rfa=1, dac_rate=1, sbr_flag=1, aac_channel_mode=1, ps_flag=1, mpeg_surround_config=3
+ bits += 12 * hDab->num_raw_blocks; //au_start[1...num_aus] 12 bit AU start position markers
+
+ //4 byte alignment
+ if (hDab->dac_rate == 0 || hDab->sbr_flag == 0)
+ bits+=4;
+ //16sbr => 16 + 5 + 3 + 12*(2-1) => 36 => 40 bits 5
+ //24sbr => 16 + 5 + 3 + 12*(3-1) => 48 ok 6
+ //32sbr => 16 + 5 + 3 + 12*(4-1) => 60 => 64 bits 8
+ //48sbr => 16 + 5 + 3 + 12*(6-1) => 84 => 88 bits 11
+ }
+
+ /* Add raw data block CRC bits. Not really part of the header, put they cause bit overhead to be accounted. */
+ bits += 16;
+
+
+ return bits;
+}
+
+
+int dabWrite_CountTotalBitDemandHeader( HANDLE_DAB hDab, unsigned int streamDataLength )
+{
+ //fprintf(stderr, "streamDataLength=%d (%d bytes)\n", streamDataLength, streamDataLength >> 3);
+ return dabWrite_GetHeaderBits(hDab);
+}
+
+
+INT dabWrite_Init(HANDLE_DAB hDab, CODER_CONFIG *config)
+{
+ /* Sanity checks */
+ if((int)config->aot > 4
+ || (int)config->aot < 1 ) {
+ return -1;
+ }
+
+ /* Sanity checks DAB-specific */
+ if ( !(config->nSubFrames == 2 && config->samplingRate == 16000 && (config->flags & CC_SBR)) &&
+ !(config->nSubFrames == 3 && config->samplingRate == 24000 && (config->flags & CC_SBR)) &&
+ !(config->nSubFrames == 4 && config->samplingRate == 32000) &&
+ !(config->nSubFrames == 6 && config->samplingRate == 48000)) {
+ return -1;
+ }
+
+ hDab->dac_rate = 0;
+ hDab->aac_channel_mode=0;
+ hDab->sbr_flag = 0;
+ hDab->ps_flag = 0;
+ hDab->mpeg_surround_config=0;
+ hDab->subchannels_num=config->bitRate/8000;
+
+
+ if(config->samplingRate == 24000 || config->samplingRate == 48000)
+ hDab->dac_rate = 1;
+
+ if (config->extAOT==AOT_SBR || config->extAOT == AOT_PS)
+ hDab->sbr_flag = 1;
+
+ if(config->extAOT == AOT_PS)
+ hDab->ps_flag = 1;
+
+
+ if(config->channelMode == MODE_2)
+ hDab->aac_channel_mode = 1;
+
+ //fprintf(stderr, "hDab->dac_rate=%d\n", hDab->dac_rate);
+ //fprintf(stderr, "hDab->sbr_flag=%d\n", hDab->sbr_flag);
+ //fprintf(stderr, "hDab->ps_flag=%d\n", hDab->ps_flag);
+ //fprintf(stderr, "hDab->aac_channel_mode=%d\n", hDab->aac_channel_mode);
+ //fprintf(stderr, "hDab->subchannels_num=%d\n", hDab->subchannels_num);
+ //fprintf(stderr, "cc->nSubFrames=%d\n", config->nSubFrames);
+
+ hDab->num_raw_blocks=config->nSubFrames-1; /* 0 means 1 raw data block */
+
+ FDKcrcInit(&hDab->crcInfo, 0x1021, 0xFFFF, 16);
+ FDKcrcInit(&hDab->crcFire, 0x782d, 0, 16);
+ FDKcrcInit(&hDab->crcInfo2, 0x8005, 0xFFFF, 16);
+
+ hDab->currentBlock = 0;
+ hDab->headerBits = dabWrite_GetHeaderBits(hDab);
+
+ return 0;
+}
+
+int dabWrite_EncodeHeader(HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ int buffer_fullness,
+ int frame_length)
+{
+ INT crcIndex = 0;
+
+
+ FDK_ASSERT(((frame_length+hDab->headerBits)/8)<0x2000); /*13 bit*/
+ FDK_ASSERT(buffer_fullness<0x800); /* 11 bit */
+
+ FDKcrcReset(&hDab->crcInfo);
+
+
+// fprintf(stderr, "dabWrite_EncodeHeader() hDab->currentBlock=%d, frame_length=%d, buffer_fullness=%d\n",
+// hDab->currentBlock, frame_length, buffer_fullness);
+
+// if (hDab->currentBlock == 0) {
+// //hDab->subFrameStartPrev=dabWrite_GetHeaderBits(hDab);
+// fprintf(stderr, "header bits[%d] [%d]\n", hDab->subFrameStartPrev, hDab->subFrameStartPrev >> 3);
+// FDKresetBitbuffer(hBitStream, BS_WRITER);
+// }
+
+ //hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
+// fprintf(stderr, "dabWrite_EncodeHeader() hDab->subFrameStartBit=%d [%d]\n", hDab->subFrameStartBit, hDab->subFrameStartBit >> 3);
+
+ //hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
+ /* Skip new header if this is raw data block 1..n */
+ if (hDab->currentBlock == 0)
+ {
+ FDKresetBitbuffer(hBitStream, BS_WRITER);
+// fprintf(stderr, "dabWrite_EncodeHeader() after FDKresetBitbuffer=%d [%d]\n", FDKgetValidBits(hBitStream), FDKgetValidBits(hBitStream) >> 3);
+
+ /* fixed header */
+ FDKwriteBits(hBitStream, 0, 16); //header_firecode
+ FDKwriteBits(hBitStream, 0, 1); //rfa
+ FDKwriteBits(hBitStream, hDab->dac_rate, 1);
+ FDKwriteBits(hBitStream, hDab->sbr_flag, 1);
+ FDKwriteBits(hBitStream, hDab->aac_channel_mode, 1);
+ FDKwriteBits(hBitStream, hDab->ps_flag, 1);
+ FDKwriteBits(hBitStream, hDab->mpeg_surround_config, 3);
+ /* variable header */
+ int i;
+ for(i=0; i<hDab->num_raw_blocks; i++)
+ FDKwriteBits(hBitStream, 0, 12);
+ /* padding */
+ if (hDab->dac_rate == 0 || hDab->sbr_flag == 0) {
+ FDKwriteBits(hBitStream, 0, 4);
+ }
+ } /* End of DAB header */
+
+ hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
+ FDK_ASSERT(FDKgetValidBits(hBitStream) % 8 == 0); //only aligned header
+
+// fprintf(stderr, "dabWrite_EncodeHeader() FDKgetValidBits(hBitStream)=%d [%d]\n", FDKgetValidBits(hBitStream), FDKgetValidBits(hBitStream) >> 3);
+ return 0;
+}
+
+int dabWrite_writeExtensionFillPayload(HANDLE_FDK_BITSTREAM hBitStream, int extPayloadBits)
+{
+#define EXT_TYPE_BITS ( 4 )
+#define DATA_EL_VERSION_BITS ( 4 )
+#define FILL_NIBBLE_BITS ( 4 )
+
+#define EXT_TYPE_BITS ( 4 )
+#define DATA_EL_VERSION_BITS ( 4 )
+#define FILL_NIBBLE_BITS ( 4 )
+
+ INT extBitsUsed = 0;
+ INT extPayloadType = EXT_FIL;
+ //fprintf(stderr, "FDKaacEnc_writeExtensionPayload() extPayloadType=%d\n", extPayloadType);
+ if (extPayloadBits >= EXT_TYPE_BITS)
+ {
+ UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */
+
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS);
+ }
+ extBitsUsed += EXT_TYPE_BITS;
+
+ switch (extPayloadType) {
+ case EXT_FILL_DATA:
+ fillByte = 0xA5;
+ case EXT_FIL:
+ default:
+ if (hBitStream != NULL) {
+ int writeBits = extPayloadBits;
+ FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS);
+ writeBits -= 8; /* acount for the extension type and the fill nibble */
+ while (writeBits >= 8) {
+ FDKwriteBits(hBitStream, fillByte, 8);
+ writeBits -= 8;
+ }
+ }
+ extBitsUsed += FILL_NIBBLE_BITS + (extPayloadBits & ~0x7) - 8;
+ break;
+ }
+ }
+
+ return (extBitsUsed);
+}
+
+void dabWrite_FillRawDataBlock(HANDLE_FDK_BITSTREAM hBitStream, int payloadBits)
+{
+ INT extBitsUsed = 0;
+#define EL_ID_BITS ( 3 )
+#define FILL_EL_COUNT_BITS ( 4 )
+#define FILL_EL_ESC_COUNT_BITS ( 8 )
+#define MAX_FILL_DATA_BYTES ( 269 )
+ while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) {
+ INT cnt, esc_count=-1, alignBits=7;
+
+ payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS;
+ if (payloadBits >= 15*8) {
+ payloadBits -= FILL_EL_ESC_COUNT_BITS;
+ esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */
+ }
+ alignBits = 0;
+
+ cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits+alignBits)>>3);
+
+ if (cnt >= 15) {
+ esc_count = cnt - 15 + 1;
+ }
+
+ if (hBitStream != NULL) {
+ /* write bitstream */
+ FDKwriteBits(hBitStream, ID_FIL, EL_ID_BITS);
+ if (esc_count >= 0) {
+ FDKwriteBits(hBitStream, 15, FILL_EL_COUNT_BITS);
+ FDKwriteBits(hBitStream, esc_count, FILL_EL_ESC_COUNT_BITS);
+ } else {
+ FDKwriteBits(hBitStream, cnt, FILL_EL_COUNT_BITS);
+ }
+ }
+
+ extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS + ((esc_count>=0) ? FILL_EL_ESC_COUNT_BITS : 0);
+
+ cnt = fixMin(cnt*8, payloadBits); /* convert back to bits */
+#if 0
+ extBitsUsed += FDKaacEnc_writeExtensionPayload( hBitStream,
+ pExtension->type,
+ pExtension->pPayload,
+ cnt );
+#else
+ extBitsUsed += dabWrite_writeExtensionFillPayload(hBitStream, cnt);
+#endif
+ payloadBits -= cnt;
+ }
+}
+
+void dabWrite_EndRawDataBlock(HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int *pBits)
+{
+ FDK_BITSTREAM bsWriter;
+ INT crcIndex = 0;
+ USHORT crcData;
+ INT writeBits=0;
+ INT writeBitsNonLastBlock=0;
+ INT writeBitsLastBlock=0;
+#if 1
+ if (hDab->currentBlock == hDab->num_raw_blocks) {
+ //calculate byte-alignment before writing ID_FIL
+ if((FDKgetValidBits(hBs)+3) % 8){
+ writeBits = 8 - ((FDKgetValidBits(hBs)+3) % 8);
+ }
+
+ INT offset_end = hDab->subchannels_num*110*8 - 2*8 - 3;
+ writeBitsLastBlock = offset_end - FDKgetValidBits(hBs);
+ dabWrite_FillRawDataBlock(hBs, writeBitsLastBlock);
+ FDKsyncCache(hBs);
+ //fprintf(stderr, "FIL-element written=%d\n", writeBitsLastBlock);
+ writeBitsLastBlock=writeBits;
+ }
+#endif
+ FDKwriteBits(hBs, 7, 3); //finalize AU: ID_END
+ FDKsyncCache(hBs);
+ //byte-align (if ID_FIL doesn't align it).
+ if(FDKgetValidBits(hBs) % 8){
+ writeBits = 8 - (FDKgetValidBits(hBs) % 8);
+ FDKwriteBits(hBs, 0x00, writeBits);
+ FDKsyncCache(hBs);
+ }
+
+ //fake-written bits alignment for last AU
+ if (hDab->currentBlock == hDab->num_raw_blocks)
+ writeBits=writeBitsLastBlock;
+
+ INT frameLen = (FDKgetValidBits(hBs) - hDab->subFrameStartBit) >> 3;
+ //fprintf(stderr, "frame=%d, offset writeBits=%d\n", frameLen, writeBits);
+
+ FDK_ASSERT(FDKgetValidBits(hBs) % 8 == 0); //only aligned au's
+ FDK_ASSERT(hDab->subchannels_num*110*8 >= FDKgetValidBits(hBs)+2*8); //don't overlap superframe
+
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKpushFor(&bsWriter, hDab->subFrameStartBit);
+ FDKcrcReset(&hDab->crcInfo);
+ hDab->crcIndex = FDKcrcStartReg(&hDab->crcInfo, &bsWriter, 0);
+#if 0
+ if (hDab->currentBlock == hDab->num_raw_blocks) {
+ INT offset_size = hDab->subchannels_num*110*8 - 2*8 - FDKgetValidBits(hBs);
+ //fprintf(stderr, "offset_size=%d\n", offset_size >> 3);
+ FDKpushFor(hBs, offset_size);
+ }
+#endif
+
+ FDKpushFor(&bsWriter, FDKgetValidBits(hBs) - hDab->subFrameStartBit);
+ FDKcrcEndReg(&hDab->crcInfo, &bsWriter, hDab->crcIndex);
+ crcData = FDKcrcGetCRC(&hDab->crcInfo);
+ //fprintf(stderr, "crcData = %04x\n", crcData);
+ /* Write inverted CRC of current raw data block */
+ FDKwriteBits(hBs, crcData ^ 0xffff, 16);
+ FDKsyncCache(hBs);
+
+
+ /* Write distance to current data block */
+ if(hDab->currentBlock) {
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKpushFor(&bsWriter, 24 + (hDab->currentBlock-1)*12);
+ //fprintf(stderr, "FDKwriteBits() = %d\n", hDab->subFrameStartBit>>3);
+ FDKwriteBits(&bsWriter, (hDab->subFrameStartBit>>3), 12);
+ FDKsyncCache(&bsWriter);
+ }
+
+ /* Write FireCode */
+ if (hDab->currentBlock == hDab->num_raw_blocks) {
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKpushFor(&bsWriter, 16);
+
+ FDKcrcReset(&hDab->crcFire);
+ crcIndex = FDKcrcStartReg(&hDab->crcFire, &bsWriter, 72);
+ FDKpushFor(&bsWriter, 9*8); //9bytes
+ FDKcrcEndReg(&hDab->crcFire, &bsWriter, crcIndex);
+
+ crcData = FDKcrcGetCRC(&hDab->crcFire);
+ //fprintf(stderr, "Firecode: %04x\n", crcData);
+
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKwriteBits(&bsWriter, crcData, 16);
+ FDKsyncCache(&bsWriter);
+ }
+
+ if (hDab->currentBlock == 0)
+ *pBits += hDab->headerBits;
+ else
+ *pBits += 16;
+
+ *pBits += writeBits + 3; //size: ID_END + alignment
+
+ /* Correct *pBits to reflect the amount of bits of the current subframe */
+ *pBits -= hDab->subFrameStartBit;
+ /* Fixup CRC bits, since they come after each raw data block */
+
+ hDab->currentBlock++;
+ //fprintf(stderr, "dabWrite_EndRawDataBlock() *pBits=%d (%d)\n", *pBits, *pBits >> 3);
+}
+
diff --git a/fdk-aac/libMpegTPEnc/src/tpenc_dab.h b/fdk-aac/libMpegTPEnc/src/tpenc_dab.h
new file mode 100644
index 0000000..17b83c6
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tpenc_dab.h
@@ -0,0 +1,217 @@
+
+/* -----------------------------------------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+� Copyright 1995 - 2012 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 Audio Encoder **************************
+
+ Initial author: serge
+ contents/description: DAB Transport writer
+
+******************************************************************************/
+
+#ifndef TPENC_DAB_H
+#define TPENC_DAB_H
+
+
+
+#include "tp_data.h"
+
+#include "FDK_crc.h"
+
+typedef struct {
+ USHORT frame_length;
+ UCHAR dac_rate;
+ UCHAR aac_channel_mode;
+ UCHAR sbr_flag;
+ UCHAR ps_flag;
+ UCHAR mpeg_surround_config;
+ UCHAR num_raw_blocks;
+ UCHAR BufferFullnesStartFlag;
+ int subchannels_num;
+ int headerBits; /*!< Header bit demand for the current raw data block */
+ int currentBlock; /*!< Index of current raw data block */
+ int subFrameStartBit; /*!< Bit position where the current raw data block begins */
+ //int subFrameStartPrev; /*!< Bit position where the previous raw data block begins */
+ int crcIndex;
+ FDK_CRCINFO crcInfo;
+ FDK_CRCINFO crcFire;
+ FDK_CRCINFO crcInfo2;
+ USHORT tab[256];
+} STRUCT_DAB;
+
+typedef STRUCT_DAB *HANDLE_DAB;
+
+/**
+ * \brief Initialize DAB data structure
+ *
+ * \param hDab DAB data handle
+ * \param config a valid CODER_CONFIG struct from where the required
+ * information for the DAB header is extrated from
+ *
+ * \return 0 in case of success.
+ */
+INT dabWrite_Init(
+ HANDLE_DAB hDab,
+ CODER_CONFIG *config
+ );
+
+/**
+ * \brief Get the total bit overhead caused by DAB
+ *
+ * \hDab handle to DAB data
+ *
+ * \return Amount of additional bits required for the current raw data block
+ */
+int dabWrite_GetHeaderBits( HANDLE_DAB hDab );
+int dabWrite_CountTotalBitDemandHeader( HANDLE_DAB hDab, unsigned int streamDataLength );
+
+/**
+ * \brief Write an DAB header into the given bitstream. May not write a header
+ * in case of multiple raw data blocks.
+ *
+ * \param hDab DAB data handle
+ * \param hBitStream bitstream handle into which the DAB may be written into
+ * \param buffer_fullness the buffer fullness value for the DAB header
+ * \param the current raw data block length
+ *
+ * \return 0 in case of success.
+ */
+INT dabWrite_EncodeHeader(
+ HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ int bufferFullness,
+ int frame_length
+ );
+/**
+ * \brief Finish a DAB raw data block
+ *
+ * \param hDab DAB data handle
+ * \param hBs bitstream handle into which the DAB may be written into
+ * \param pBits a pointer to a integer holding the current bitstream buffer bit count,
+ * which is corrected to the current raw data block boundary.
+ *
+ */
+void dabWrite_EndRawDataBlock(
+ HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int *bits
+ );
+
+
+/**
+ * \brief Start 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 pDab DAB data handle
+ * \param hBs bitstream handle of which the CRC region ends
+ * \param mBits limit of number of bits to be considered for the requested CRC region
+ *
+ * \return ID for the created region, -1 in case of an error
+ */
+int dabWrite_CrcStartReg(
+ HANDLE_DAB pDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int mBits
+ );
+
+/**
+ * \brief Ends CRC region identified by reg
+ *
+ * \param pDab DAB data handle
+ * \param hBs bitstream handle of which the CRC region ends
+ * \param reg a CRC region ID returned previously by dabWrite_CrcStartReg()
+ */
+void dabWrite_CrcEndReg(
+ HANDLE_DAB pDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int reg
+ );
+
+
+
+
+#endif /* TPENC_DAB_H */
+
diff --git a/fdk-aac/libMpegTPEnc/src/tpenc_latm.cpp b/fdk-aac/libMpegTPEnc/src/tpenc_latm.cpp
new file mode 100644
index 0000000..2d35d48
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tpenc_latm.cpp
@@ -0,0 +1,850 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "tpenc_latm.h"
+
+#include "genericStds.h"
+
+static const short celpFrameLengthTable[64] = {
+ 154, 170, 186, 147, 156, 165, 114, 120, 186, 126, 132, 138, 142,
+ 146, 154, 166, 174, 182, 190, 198, 206, 210, 214, 110, 114, 118,
+ 120, 122, 218, 230, 242, 254, 266, 278, 286, 294, 318, 342, 358,
+ 374, 390, 406, 422, 136, 142, 148, 154, 160, 166, 170, 174, 186,
+ 198, 206, 214, 222, 230, 238, 216, 160, 280, 338, 0, 0};
+
+/*******
+ write value to transport stream
+ first two bits define the size of the value itself
+ then the value itself, with a size of 0-3 bytes
+*******/
+static UINT transportEnc_LatmWriteValue(HANDLE_FDK_BITSTREAM hBs, int value) {
+ UCHAR valueBytes = 4;
+ unsigned int bitsWritten = 0;
+ int i;
+
+ if (value < (1 << 8)) {
+ valueBytes = 1;
+ } else if (value < (1 << 16)) {
+ valueBytes = 2;
+ } else if (value < (1 << 24)) {
+ valueBytes = 3;
+ } else {
+ valueBytes = 4;
+ }
+
+ FDKwriteBits(hBs, valueBytes - 1, 2); /* size of value in Bytes */
+ for (i = 0; i < valueBytes; i++) {
+ /* write most significant Byte first */
+ FDKwriteBits(hBs, (UCHAR)(value >> ((valueBytes - 1 - i) << 3)), 8);
+ }
+
+ bitsWritten = (valueBytes << 3) + 2;
+
+ return bitsWritten;
+}
+
+static UINT transportEnc_LatmCountFixBitDemandHeader(HANDLE_LATM_STREAM hAss) {
+ int bitDemand = 0;
+ int insertSetupData = 0;
+
+ /* only if start of new latm frame */
+ if (hAss->subFrameCnt == 0) {
+ /* AudioSyncStream */
+
+ if (hAss->tt == TT_MP4_LOAS) {
+ bitDemand += 11; /* syncword */
+ bitDemand += 13; /* audioMuxLengthBytes */
+ }
+
+ /* AudioMuxElement*/
+
+ /* AudioMuxElement::Stream Mux Config */
+ if (hAss->muxConfigPeriod > 0) {
+ insertSetupData = (hAss->latmFrameCounter == 0);
+ } else {
+ insertSetupData = 0;
+ }
+
+ if (hAss->tt != TT_MP4_LATM_MCP0) {
+ /* AudioMuxElement::useSameStreamMux Flag */
+ bitDemand += 1;
+
+ if (insertSetupData) {
+ bitDemand += hAss->streamMuxConfigBits;
+ }
+ }
+
+ /* AudioMuxElement::otherDataBits */
+ bitDemand += hAss->otherDataLenBits;
+
+ /* AudioMuxElement::ByteAlign */
+ if (bitDemand % 8) {
+ hAss->fillBits = 8 - (bitDemand % 8);
+ bitDemand += hAss->fillBits;
+ } else {
+ hAss->fillBits = 0;
+ }
+ }
+
+ return bitDemand;
+}
+
+static UINT transportEnc_LatmCountVarBitDemandHeader(
+ HANDLE_LATM_STREAM hAss, unsigned int streamDataLength) {
+ int bitDemand = 0;
+ int prog, layer;
+
+ /* Payload Length Info*/
+ if (hAss->allStreamsSameTimeFraming) {
+ for (prog = 0; prog < hAss->noProgram; prog++) {
+ for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
+ LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
+
+ if (p_linfo->streamID >= 0) {
+ switch (p_linfo->frameLengthType) {
+ case 0:
+ if (streamDataLength > 0) {
+ streamDataLength -= bitDemand;
+ while (streamDataLength >= (255 << 3)) {
+ bitDemand += 8;
+ streamDataLength -= (255 << 3);
+ }
+ bitDemand += 8;
+ }
+ break;
+
+ case 1:
+ case 4:
+ case 6:
+ bitDemand += 2;
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ }
+ }
+ } else {
+ /* there are many possibilities to use this mechanism. */
+ switch (hAss->varMode) {
+ case LATMVAR_SIMPLE_SEQUENCE: {
+ /* Use the sequence generated by the encoder */
+ // int streamCntPosition = transportEnc_SetWritePointer(
+ // hAss->hAssemble, 0 ); int streamCntPosition = FDKgetValidBits(
+ // hAss->hAssemble );
+ bitDemand += 4;
+
+ hAss->varStreamCnt = 0;
+ for (prog = 0; prog < hAss->noProgram; prog++) {
+ for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
+ LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
+
+ if (p_linfo->streamID >= 0) {
+ bitDemand += 4; /* streamID */
+ switch (p_linfo->frameLengthType) {
+ case 0:
+ streamDataLength -= bitDemand;
+ while (streamDataLength >= (255 << 3)) {
+ bitDemand += 8;
+ streamDataLength -= (255 << 3);
+ }
+
+ bitDemand += 8;
+ break;
+ /*bitDemand += 1; endFlag
+ break;*/
+
+ case 1:
+ case 4:
+ case 6:
+
+ break;
+
+ default:
+ return 0;
+ }
+ hAss->varStreamCnt++;
+ }
+ }
+ }
+ bitDemand += 4;
+ // transportEnc_UpdateBitstreamField( hAss->hAssemble,
+ // streamCntPosition, hAss->varStreamCnt-1, 4 ); UINT pos =
+ // streamCntPosition-FDKgetValidBits(hAss->hAssemble); FDKpushBack(
+ // hAss->hAssemble, pos); FDKwriteBits( hAss->hAssemble,
+ // hAss->varStreamCnt-1, 4); FDKpushFor( hAss->hAssemble, pos-4);
+ } break;
+
+ default:
+ return 0;
+ }
+ }
+
+ return bitDemand;
+}
+
+TRANSPORTENC_ERROR
+CreateStreamMuxConfig(HANDLE_LATM_STREAM hAss, HANDLE_FDK_BITSTREAM hBs,
+ int bufferFullness, CSTpCallBacks *cb) {
+ INT streamIDcnt, tmp;
+ int layer, prog;
+
+ USHORT coreFrameOffset = 0;
+
+ hAss->taraBufferFullness = 0xFF;
+ hAss->audioMuxVersionA = 0; /* for future extensions */
+ hAss->streamMuxConfigBits = 0;
+
+ FDKwriteBits(hBs, hAss->audioMuxVersion, 1); /* audioMuxVersion */
+ hAss->streamMuxConfigBits += 1;
+
+ if (hAss->audioMuxVersion == 1) {
+ FDKwriteBits(hBs, hAss->audioMuxVersionA, 1); /* audioMuxVersionA */
+ hAss->streamMuxConfigBits += 1;
+ }
+
+ if (hAss->audioMuxVersionA == 0) {
+ if (hAss->audioMuxVersion == 1) {
+ hAss->streamMuxConfigBits += transportEnc_LatmWriteValue(
+ hBs, hAss->taraBufferFullness); /* taraBufferFullness */
+ }
+ FDKwriteBits(hBs, hAss->allStreamsSameTimeFraming ? 1 : 0,
+ 1); /* allStreamsSameTimeFraming */
+ FDKwriteBits(hBs, hAss->noSubframes - 1, 6); /* Number of Subframes */
+ FDKwriteBits(hBs, hAss->noProgram - 1, 4); /* Number of Programs */
+
+ hAss->streamMuxConfigBits += 11;
+
+ streamIDcnt = 0;
+ for (prog = 0; prog < hAss->noProgram; prog++) {
+ int transLayer = 0;
+
+ FDKwriteBits(hBs, hAss->noLayer[prog] - 1, 3);
+ hAss->streamMuxConfigBits += 3;
+
+ for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
+ LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
+ CODER_CONFIG *p_lci = hAss->config[prog][layer];
+
+ p_linfo->streamID = -1;
+
+ if (hAss->config[prog][layer] != NULL) {
+ int useSameConfig = 0;
+
+ if (transLayer > 0) {
+ FDKwriteBits(hBs, useSameConfig ? 1 : 0, 1);
+ hAss->streamMuxConfigBits += 1;
+ }
+ if ((useSameConfig == 0) || (transLayer == 0)) {
+ const UINT alignAnchor = FDKgetValidBits(hBs);
+
+ if (0 !=
+ (transportEnc_writeASC(hBs, hAss->config[prog][layer], cb))) {
+ return TRANSPORTENC_UNKOWN_ERROR;
+ }
+
+ if (hAss->audioMuxVersion == 1) {
+ UINT ascLen = transportEnc_LatmWriteValue(hBs, 0);
+ FDKbyteAlign(hBs, alignAnchor);
+ ascLen = FDKgetValidBits(hBs) - alignAnchor - ascLen;
+ FDKpushBack(hBs, FDKgetValidBits(hBs) - alignAnchor);
+
+ transportEnc_LatmWriteValue(hBs, ascLen);
+
+ if (0 !=
+ (transportEnc_writeASC(hBs, hAss->config[prog][layer], cb))) {
+ return TRANSPORTENC_UNKOWN_ERROR;
+ }
+
+ FDKbyteAlign(hBs, alignAnchor); /* asc length fillbits */
+ }
+
+ hAss->streamMuxConfigBits +=
+ FDKgetValidBits(hBs) -
+ alignAnchor; /* add asc length to smc summary */
+ }
+ transLayer++;
+
+ if (!hAss->allStreamsSameTimeFraming) {
+ if (streamIDcnt >= LATM_MAX_STREAM_ID)
+ return TRANSPORTENC_INVALID_CONFIG;
+ }
+ p_linfo->streamID = streamIDcnt++;
+
+ switch (p_lci->aot) {
+ case AOT_AAC_MAIN:
+ case AOT_AAC_LC:
+ case AOT_AAC_SSR:
+ case AOT_AAC_LTP:
+ case AOT_AAC_SCAL:
+ case AOT_ER_AAC_LD:
+ case AOT_ER_AAC_ELD:
+ case AOT_USAC:
+ p_linfo->frameLengthType = 0;
+
+ FDKwriteBits(hBs, p_linfo->frameLengthType,
+ 3); /* frameLengthType */
+ FDKwriteBits(hBs, bufferFullness, 8); /* bufferFullness */
+ hAss->streamMuxConfigBits += 11;
+
+ if (!hAss->allStreamsSameTimeFraming) {
+ CODER_CONFIG *p_lci_prev = hAss->config[prog][layer - 1];
+ if (((p_lci->aot == AOT_AAC_SCAL) ||
+ (p_lci->aot == AOT_ER_AAC_SCAL)) &&
+ ((p_lci_prev->aot == AOT_CELP) ||
+ (p_lci_prev->aot == AOT_ER_CELP))) {
+ FDKwriteBits(hBs, coreFrameOffset, 6); /* coreFrameOffset */
+ hAss->streamMuxConfigBits += 6;
+ }
+ }
+ break;
+
+ case AOT_TWIN_VQ:
+ p_linfo->frameLengthType = 1;
+ tmp = ((p_lci->bitsFrame + 7) >> 3) -
+ 20; /* transmission frame length in bytes */
+ if ((tmp < 0)) {
+ return TRANSPORTENC_INVALID_TRANSMISSION_FRAME_LENGTH;
+ }
+ FDKwriteBits(hBs, p_linfo->frameLengthType,
+ 3); /* frameLengthType */
+ FDKwriteBits(hBs, tmp, 9);
+ hAss->streamMuxConfigBits += 12;
+
+ p_linfo->frameLengthBits = (tmp + 20) << 3;
+ break;
+
+ case AOT_CELP:
+ p_linfo->frameLengthType = 4;
+ FDKwriteBits(hBs, p_linfo->frameLengthType,
+ 3); /* frameLengthType */
+ hAss->streamMuxConfigBits += 3;
+ {
+ int i;
+ for (i = 0; i < 62; i++) {
+ if (celpFrameLengthTable[i] == p_lci->bitsFrame) break;
+ }
+ if (i >= 62) {
+ return TRANSPORTENC_INVALID_CELP_FRAME_LENGTH;
+ }
+
+ FDKwriteBits(hBs, i, 6); /* CELPframeLengthTabelIndex */
+ hAss->streamMuxConfigBits += 6;
+ }
+ p_linfo->frameLengthBits = p_lci->bitsFrame;
+ break;
+
+ case AOT_HVXC:
+ p_linfo->frameLengthType = 6;
+ FDKwriteBits(hBs, p_linfo->frameLengthType,
+ 3); /* frameLengthType */
+ hAss->streamMuxConfigBits += 3;
+ {
+ int i;
+
+ if (p_lci->bitsFrame == 40) {
+ i = 0;
+ } else if (p_lci->bitsFrame == 80) {
+ i = 1;
+ } else {
+ return TRANSPORTENC_INVALID_FRAME_BITS;
+ }
+ FDKwriteBits(hBs, i, 1); /* HVXCframeLengthTableIndex */
+ hAss->streamMuxConfigBits += 1;
+ }
+ p_linfo->frameLengthBits = p_lci->bitsFrame;
+ break;
+
+ case AOT_NULL_OBJECT:
+ default:
+ return TRANSPORTENC_INVALID_AOT;
+ }
+ }
+ }
+ }
+
+ FDKwriteBits(hBs, (hAss->otherDataLenBits > 0) ? 1 : 0,
+ 1); /* otherDataPresent */
+ hAss->streamMuxConfigBits += 1;
+
+ if (hAss->otherDataLenBits > 0) {
+ FDKwriteBits(hBs, 0, 1);
+ FDKwriteBits(hBs, hAss->otherDataLenBits, 8);
+ hAss->streamMuxConfigBits += 9;
+ }
+
+ FDKwriteBits(hBs, 0, 1); /* crcCheckPresent=0 */
+ hAss->streamMuxConfigBits += 1;
+
+ } else { /* if ( audioMuxVersionA == 0 ) */
+
+ /* for future extensions */
+ }
+
+ return TRANSPORTENC_OK;
+}
+
+static TRANSPORTENC_ERROR WriteAuPayloadLengthInfo(
+ HANDLE_FDK_BITSTREAM hBitStream, int AuLengthBits) {
+ int restBytes;
+
+ if (AuLengthBits % 8) return TRANSPORTENC_INVALID_AU_LENGTH;
+
+ while (AuLengthBits >= 255 * 8) {
+ FDKwriteBits(hBitStream, 255, 8); /* 255 shows incomplete AU */
+ AuLengthBits -= (255 * 8);
+ }
+
+ restBytes = (AuLengthBits) >> 3;
+ FDKwriteBits(hBitStream, restBytes, 8);
+
+ return TRANSPORTENC_OK;
+}
+
+static TRANSPORTENC_ERROR transportEnc_LatmSetNrOfSubframes(
+ HANDLE_LATM_STREAM hAss, INT noSubframes_next) /* nr of access units /
+ payloads within a latm
+ frame */
+{
+ /* sanity chk */
+ if (noSubframes_next < 1 || noSubframes_next > MAX_NR_OF_SUBFRAMES) {
+ return TRANSPORTENC_LATM_INVALID_NR_OF_SUBFRAMES;
+ }
+
+ hAss->noSubframes_next = noSubframes_next;
+
+ /* if at start then we can take over the value immediately, otherwise we have
+ * to wait for the next SMC */
+ if ((hAss->subFrameCnt == 0) && (hAss->latmFrameCounter == 0)) {
+ hAss->noSubframes = noSubframes_next;
+ }
+
+ return TRANSPORTENC_OK;
+}
+
+static int allStreamsSameTimeFraming(HANDLE_LATM_STREAM hAss, UCHAR noProgram,
+ UCHAR noLayer[] /* return */) {
+ int prog, layer;
+
+ signed int lastNoSamples = -1;
+ signed int minFrameSamples = FDK_INT_MAX;
+ signed int maxFrameSamples = 0;
+
+ signed int highestSamplingRate = -1;
+
+ for (prog = 0; prog < noProgram; prog++) {
+ noLayer[prog] = 0;
+
+ for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
+ if (hAss->config[prog][layer] != NULL) {
+ INT hsfSamplesFrame;
+
+ noLayer[prog]++;
+
+ if (highestSamplingRate < 0)
+ highestSamplingRate = hAss->config[prog][layer]->samplingRate;
+
+ hsfSamplesFrame = hAss->config[prog][layer]->samplesPerFrame *
+ highestSamplingRate /
+ hAss->config[prog][layer]->samplingRate;
+
+ if (hsfSamplesFrame <= minFrameSamples)
+ minFrameSamples = hsfSamplesFrame;
+ if (hsfSamplesFrame >= maxFrameSamples)
+ maxFrameSamples = hsfSamplesFrame;
+
+ if (lastNoSamples == -1) {
+ lastNoSamples = hsfSamplesFrame;
+ } else {
+ if (hsfSamplesFrame != lastNoSamples) {
+ return 0;
+ }
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+/**
+ * Initialize LATM/LOAS Stream and add layer 0 at program 0.
+ */
+static TRANSPORTENC_ERROR transportEnc_InitLatmStream(
+ HANDLE_LATM_STREAM hAss, int fractDelayPresent,
+ signed int
+ muxConfigPeriod, /* insert setup data every muxConfigPeriod frames */
+ UINT audioMuxVersion, TRANSPORT_TYPE tt) {
+ TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
+
+ if (hAss == NULL) return TRANSPORTENC_INVALID_PARAMETER;
+
+ hAss->tt = tt;
+
+ hAss->noProgram = 1;
+
+ hAss->audioMuxVersion = audioMuxVersion;
+
+ /* Fill noLayer array using hAss->config */
+ hAss->allStreamsSameTimeFraming =
+ allStreamsSameTimeFraming(hAss, hAss->noProgram, hAss->noLayer);
+ /* Only allStreamsSameTimeFraming==1 is supported */
+ FDK_ASSERT(hAss->allStreamsSameTimeFraming);
+
+ hAss->fractDelayPresent = fractDelayPresent;
+ hAss->otherDataLenBits = 0;
+
+ hAss->varMode = LATMVAR_SIMPLE_SEQUENCE;
+
+ /* initialize counters */
+ hAss->subFrameCnt = 0;
+ hAss->noSubframes = DEFAULT_LATM_NR_OF_SUBFRAMES;
+ hAss->noSubframes_next = DEFAULT_LATM_NR_OF_SUBFRAMES;
+
+ /* sync layer related */
+ hAss->audioMuxLengthBytes = 0;
+
+ hAss->latmFrameCounter = 0;
+ hAss->muxConfigPeriod = muxConfigPeriod;
+
+ return ErrorStatus;
+}
+
+/**
+ *
+ */
+UINT transportEnc_LatmCountTotalBitDemandHeader(HANDLE_LATM_STREAM hAss,
+ unsigned int streamDataLength) {
+ UINT bitDemand = 0;
+
+ switch (hAss->tt) {
+ case TT_MP4_LOAS:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ if (hAss->subFrameCnt == 0) {
+ bitDemand = transportEnc_LatmCountFixBitDemandHeader(hAss);
+ }
+ bitDemand += transportEnc_LatmCountVarBitDemandHeader(
+ hAss, streamDataLength /*- bitDemand*/);
+ break;
+ default:
+ break;
+ }
+
+ return bitDemand;
+}
+
+static TRANSPORTENC_ERROR AdvanceAudioMuxElement(HANDLE_LATM_STREAM hAss,
+ HANDLE_FDK_BITSTREAM hBs,
+ int auBits, int bufferFullness,
+ CSTpCallBacks *cb) {
+ TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
+ int insertMuxSetup;
+
+ /* Insert setup data to assemble Buffer */
+ if (hAss->subFrameCnt == 0) {
+ if (hAss->muxConfigPeriod > 0) {
+ insertMuxSetup = (hAss->latmFrameCounter == 0);
+ } else {
+ insertMuxSetup = 0;
+ }
+
+ if (hAss->tt != TT_MP4_LATM_MCP0) {
+ if (insertMuxSetup) {
+ FDKwriteBits(hBs, 0, 1); /* useSameStreamMux useNewStreamMux */
+ if (TRANSPORTENC_OK != (ErrorStatus = CreateStreamMuxConfig(
+ hAss, hBs, bufferFullness, cb))) {
+ return ErrorStatus;
+ }
+ } else {
+ FDKwriteBits(hBs, 1, 1); /* useSameStreamMux */
+ }
+ }
+ }
+
+ /* PayloadLengthInfo */
+ {
+ int prog, layer;
+
+ for (prog = 0; prog < hAss->noProgram; prog++) {
+ for (layer = 0; layer < hAss->noLayer[prog]; layer++) {
+ ErrorStatus = WriteAuPayloadLengthInfo(hBs, auBits);
+ if (ErrorStatus != TRANSPORTENC_OK) return ErrorStatus;
+ }
+ }
+ }
+ /* At this point comes the access unit. */
+
+ return TRANSPORTENC_OK;
+}
+
+TRANSPORTENC_ERROR
+transportEnc_LatmWrite(HANDLE_LATM_STREAM hAss, HANDLE_FDK_BITSTREAM hBs,
+ int auBits, int bufferFullness, CSTpCallBacks *cb) {
+ TRANSPORTENC_ERROR ErrorStatus;
+
+ if (hAss->subFrameCnt == 0) {
+ /* Start new frame */
+ FDKresetBitbuffer(hBs, BS_WRITER);
+ }
+
+ hAss->latmSubframeStart = FDKgetValidBits(hBs);
+
+ /* Insert syncword and syncword distance
+ - only if loas
+ - we must update the syncword distance (=audiomuxlengthbytes) later
+ */
+ if (hAss->tt == TT_MP4_LOAS && hAss->subFrameCnt == 0) {
+ /* Start new LOAS frame */
+ FDKwriteBits(hBs, 0x2B7, 11);
+ hAss->audioMuxLengthBytes = 0;
+ hAss->audioMuxLengthBytesPos =
+ FDKgetValidBits(hBs); /* store read pointer position */
+ FDKwriteBits(hBs, hAss->audioMuxLengthBytes, 13);
+ }
+
+ ErrorStatus = AdvanceAudioMuxElement(hAss, hBs, auBits, bufferFullness, cb);
+
+ if (ErrorStatus != TRANSPORTENC_OK) return ErrorStatus;
+
+ return ErrorStatus;
+}
+
+void transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM hAss, int *bits) {
+ /* Substract bits from possible previous subframe */
+ *bits -= hAss->latmSubframeStart;
+ /* Add fill bits */
+ if (hAss->subFrameCnt == 0) {
+ *bits += hAss->otherDataLenBits;
+ *bits += hAss->fillBits;
+ }
+}
+
+TRANSPORTENC_ERROR transportEnc_LatmGetFrame(HANDLE_LATM_STREAM hAss,
+ HANDLE_FDK_BITSTREAM hBs,
+ int *pBytes) {
+ TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
+
+ hAss->subFrameCnt++;
+ if (hAss->subFrameCnt >= hAss->noSubframes) {
+ /* Add LOAS frame length if required. */
+ if (hAss->tt == TT_MP4_LOAS) {
+ FDK_BITSTREAM tmpBuf;
+
+ /* Determine frame length info */
+ hAss->audioMuxLengthBytes =
+ ((FDKgetValidBits(hBs) + hAss->otherDataLenBits + 7) >> 3) -
+ 3; /* 3=Syncword + length */
+
+ /* Check frame length info */
+ if (hAss->audioMuxLengthBytes >= (1 << 13)) {
+ ErrorStatus = TRANSPORTENC_INVALID_AU_LENGTH;
+ goto bail;
+ }
+
+ /* Write length info into assembler buffer */
+ FDKinitBitStream(&tmpBuf, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0,
+ BS_WRITER);
+ FDKpushFor(&tmpBuf, hAss->audioMuxLengthBytesPos);
+ FDKwriteBits(&tmpBuf, hAss->audioMuxLengthBytes, 13);
+ FDKsyncCache(&tmpBuf);
+ }
+
+ /* Write AudioMuxElement other data bits */
+ FDKwriteBits(hBs, 0, hAss->otherDataLenBits);
+
+ /* Write AudioMuxElement byte alignment fill bits */
+ FDKwriteBits(hBs, 0, hAss->fillBits);
+
+ FDK_ASSERT((FDKgetValidBits(hBs) % 8) == 0);
+
+ hAss->subFrameCnt = 0;
+
+ FDKsyncCache(hBs);
+ *pBytes = (FDKgetValidBits(hBs) + 7) >> 3;
+
+ if (hAss->muxConfigPeriod > 0) {
+ hAss->latmFrameCounter++;
+
+ if (hAss->latmFrameCounter >= hAss->muxConfigPeriod) {
+ hAss->latmFrameCounter = 0;
+ hAss->noSubframes = hAss->noSubframes_next;
+ }
+ }
+ } else {
+ /* No data this time */
+ *pBytes = 0;
+ }
+
+bail:
+ return ErrorStatus;
+}
+
+/**
+ * Init LATM/LOAS
+ */
+TRANSPORTENC_ERROR transportEnc_Latm_Init(HANDLE_LATM_STREAM hAss,
+ HANDLE_FDK_BITSTREAM hBs,
+ CODER_CONFIG *layerConfig,
+ UINT audioMuxVersion,
+ TRANSPORT_TYPE tt,
+ CSTpCallBacks *cb) {
+ TRANSPORTENC_ERROR ErrorStatus;
+ int fractDelayPresent = 0;
+ int prog, layer;
+
+ int setupDataDistanceFrames = layerConfig->headerPeriod;
+
+ FDK_ASSERT(setupDataDistanceFrames >= 0);
+
+ for (prog = 0; prog < LATM_MAX_PROGRAMS; prog++) {
+ for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
+ hAss->config[prog][layer] = NULL;
+ hAss->m_linfo[prog][layer].streamID = -1;
+ }
+ }
+
+ hAss->config[0][0] = layerConfig;
+ hAss->m_linfo[0][0].streamID = 0;
+
+ ErrorStatus = transportEnc_InitLatmStream(hAss, fractDelayPresent,
+ setupDataDistanceFrames,
+ (audioMuxVersion) ? 1 : 0, tt);
+ if (ErrorStatus != TRANSPORTENC_OK) goto bail;
+
+ ErrorStatus =
+ transportEnc_LatmSetNrOfSubframes(hAss, layerConfig->nSubFrames);
+ if (ErrorStatus != TRANSPORTENC_OK) goto bail;
+
+ /* Get the size of the StreamMuxConfig somehow */
+ if (TRANSPORTENC_OK !=
+ (ErrorStatus = AdvanceAudioMuxElement(hAss, hBs, 0, 0, cb))) {
+ goto bail;
+ }
+
+ // CreateStreamMuxConfig(hAss, hBs, 0);
+
+bail:
+ return ErrorStatus;
+}
+
+TRANSPORTENC_ERROR transportEnc_LatmAddOtherDataBits(HANDLE_LATM_STREAM hAss,
+ const int otherDataBits) {
+ TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
+
+ if ((hAss->otherDataLenBits != 0) || (otherDataBits % 8 != 0)) {
+ /* This implementation allows to add other data bits only once.
+ To keep existing alignment only whole bytes are allowed. */
+ ErrorStatus = TRANSPORTENC_UNKOWN_ERROR;
+ } else {
+ /* Ensure correct addional bits in payload. */
+ if (hAss->tt == TT_MP4_LATM_MCP0) {
+ hAss->otherDataLenBits = otherDataBits;
+ } else {
+ hAss->otherDataLenBits = otherDataBits - 9;
+ hAss->streamMuxConfigBits += 9;
+ }
+ }
+
+ return ErrorStatus;
+}
diff --git a/fdk-aac/libMpegTPEnc/src/tpenc_latm.h b/fdk-aac/libMpegTPEnc/src/tpenc_latm.h
new file mode 100644
index 0000000..d650357
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tpenc_latm.h
@@ -0,0 +1,274 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef TPENC_LATM_H
+#define TPENC_LATM_H
+
+#include "tpenc_lib.h"
+#include "FDK_bitstream.h"
+
+#define DEFAULT_LATM_NR_OF_SUBFRAMES 1
+#define DEFAULT_LATM_SMC_REPEAT 8
+
+#define MAX_AAC_LAYERS 9
+
+#define LATM_MAX_PROGRAMS 1
+#define LATM_MAX_STREAM_ID 16
+
+#define LATM_MAX_LAYERS 1 /*MAX_AAC_LAYERS*/
+
+#define MAX_NR_OF_SUBFRAMES \
+ 2 /* set this carefully to avoid buffer overflows \
+ */
+
+typedef enum { LATMVAR_SIMPLE_SEQUENCE } LATM_VAR_MODE;
+
+typedef struct {
+ signed int frameLengthType;
+ signed int frameLengthBits;
+ signed int varFrameLengthTable[4];
+ signed int streamID;
+} LATM_LAYER_INFO;
+
+typedef struct {
+ LATM_LAYER_INFO m_linfo[LATM_MAX_PROGRAMS][LATM_MAX_LAYERS];
+ CODER_CONFIG *config[LATM_MAX_PROGRAMS][LATM_MAX_LAYERS];
+
+ LATM_VAR_MODE varMode;
+ TRANSPORT_TYPE tt;
+
+ int audioMuxLengthBytes;
+
+ int audioMuxLengthBytesPos;
+ int taraBufferFullness; /* state of the bit reservoir */
+ int varStreamCnt;
+
+ UCHAR
+ latmFrameCounter; /* Current frame number. Counts modulo muxConfigPeriod
+ */
+ UCHAR muxConfigPeriod; /* Distance in frames between MuxConfig */
+
+ UCHAR
+ audioMuxVersion; /* AMV1 supports transmission of taraBufferFullness and
+ ASC lengths */
+ UCHAR audioMuxVersionA; /* for future extensions */
+
+ UCHAR noProgram;
+ UCHAR noLayer[LATM_MAX_PROGRAMS];
+ UCHAR fractDelayPresent;
+
+ UCHAR allStreamsSameTimeFraming;
+ UCHAR subFrameCnt; /* Current Subframe frame */
+ UCHAR noSubframes; /* Number of subframes */
+ UINT latmSubframeStart; /* Position of current subframe start */
+ UCHAR noSubframes_next;
+
+ UCHAR otherDataLenBits; /* AudioMuxElement other data bits */
+ UCHAR fillBits; /* AudioMuxElement fill bits */
+ UINT streamMuxConfigBits;
+
+} LATM_STREAM;
+
+typedef LATM_STREAM *HANDLE_LATM_STREAM;
+
+/**
+ * \brief Initialize LATM_STREAM Handle. Creates automatically one program with
+ * one layer with the given layerConfig. The layerConfig must be persisten
+ * because references to this pointer are made at any time again. Use
+ * transportEnc_Latm_AddLayer() to add more programs/layers.
+ *
+ * \param hLatmStreamInfo HANDLE_LATM_STREAM handle
+ * \param hBs Bitstream handle
+ * \param layerConfig a valid CODER_CONFIG struct containing the current audio
+ * configuration parameters
+ * \param audioMuxVersion the LATM audioMuxVersion to be used
+ * \param tt the specific TRANSPORT_TYPE to be used, either TT_MP4_LOAS,
+ * TT_MP4_LATM_MCP1 or TT_MP4_LATM_MCP0 LOAS
+ * \param cb callback information structure.
+ *
+ * \return an TRANSPORTENC_ERROR error code
+ */
+TRANSPORTENC_ERROR transportEnc_Latm_Init(HANDLE_LATM_STREAM hLatmStreamInfo,
+ HANDLE_FDK_BITSTREAM hBs,
+ CODER_CONFIG *layerConfig,
+ UINT audioMuxVersion,
+ TRANSPORT_TYPE tt, CSTpCallBacks *cb);
+
+/**
+ * \brief Write addional other data bits in AudioMuxElement
+ *
+ * \param hAss HANDLE_LATM_STREAM handle
+ * \param otherDataBits number of other data bits to be written
+ *
+ * \return an TRANSPORTENC_ERROR error code
+ */
+TRANSPORTENC_ERROR transportEnc_LatmAddOtherDataBits(HANDLE_LATM_STREAM hAss,
+ const int otherDataBits);
+
+/**
+ * \brief Get bit demand of next LATM/LOAS header
+ *
+ * \param hAss HANDLE_LATM_STREAM handle
+ * \param streamDataLength the length of the payload
+ *
+ * \return the number of bits required by the LATM/LOAS headers
+ */
+unsigned int transportEnc_LatmCountTotalBitDemandHeader(
+ HANDLE_LATM_STREAM hAss, unsigned int streamDataLength);
+
+/**
+ * \brief Write LATM/LOAS header into given bitstream handle
+ *
+ * \param hLatmStreamInfo HANDLE_LATM_STREAM handle
+ * \param hBitstream Bitstream handle
+ * \param auBits amount of current payload bits
+ * \param bufferFullness LATM buffer fullness value
+ * \param cb callback information structure.
+ *
+ * \return an TRANSPORTENC_ERROR error code
+ */
+TRANSPORTENC_ERROR
+transportEnc_LatmWrite(HANDLE_LATM_STREAM hAss, HANDLE_FDK_BITSTREAM hBitstream,
+ int auBits, int bufferFullness, CSTpCallBacks *cb);
+
+/**
+ * \brief Adjust bit count relative to current subframe
+ *
+ * \param hAss HANDLE_LATM_STREAM handle
+ * \param pBits pointer to an int, where the current frame bit count is
+ * contained, and where the subframe relative bit count will be returned into
+ *
+ * \return void
+ */
+void transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM hAss, int *pBits);
+
+/**
+ * \brief Request an LATM frame, which may, or may not be available
+ *
+ * \param hAss HANDLE_LATM_STREAM handle
+ * \param hBs Bitstream handle
+ * \param pBytes pointer to an int, where the current frame byte count stored
+ * into. A return value of zero means that currently no LATM/LOAS frame can be
+ * returned. The latter is expected in case of multiple subframes being
+ * used.
+ *
+ * \return an TRANSPORTENC_ERROR error code
+ */
+TRANSPORTENC_ERROR transportEnc_LatmGetFrame(HANDLE_LATM_STREAM hAss,
+ HANDLE_FDK_BITSTREAM hBs,
+ int *pBytes);
+
+/**
+ * \brief Write a StreamMuxConfig into the given bitstream handle
+ *
+ * \param hAss HANDLE_LATM_STREAM handle
+ * \param hBs Bitstream handle
+ * \param bufferFullness LATM buffer fullness value
+ * \param cb callback information structure.
+ *
+ * \return void
+ */
+TRANSPORTENC_ERROR
+CreateStreamMuxConfig(HANDLE_LATM_STREAM hAss, HANDLE_FDK_BITSTREAM hBs,
+ int bufferFullness, CSTpCallBacks *cb);
+
+#endif /* TPENC_LATM_H */
diff --git a/fdk-aac/libMpegTPEnc/src/tpenc_lib.cpp b/fdk-aac/libMpegTPEnc/src/tpenc_lib.cpp
new file mode 100644
index 0000000..316c6e0
--- /dev/null
+++ b/fdk-aac/libMpegTPEnc/src/tpenc_lib.cpp
@@ -0,0 +1,713 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 transport format encoder library *********************
+
+ Author(s): Manuel Jander
+
+ Description: MPEG Transport encode
+
+*******************************************************************************/
+
+#include "tpenc_lib.h"
+
+/* library info */
+#include "tp_version.h"
+
+#define MODULE_NAME "transportEnc"
+
+#include "tpenc_asc.h"
+
+#include "tpenc_adts.h"
+
+#include "tpenc_adif.h"
+
+#include "tpenc_dab.h"
+
+#include "tpenc_latm.h"
+
+typedef struct {
+ int curSubFrame;
+ int nSubFrames;
+ int prevBits;
+} RAWPACKETS_INFO;
+
+struct TRANSPORTENC {
+ CODER_CONFIG config;
+ TRANSPORT_TYPE transportFmt; /*!< MPEG4 transport type. */
+
+ FDK_BITSTREAM bitStream;
+ UCHAR *bsBuffer;
+ INT bsBufferSize;
+
+ INT pceFrameCounter; /*!< Indicates frame period when PCE must be written in
+ raw_data_block. -1 means not to write a PCE in
+ raw_dat_block. */
+ union {
+ STRUCT_ADTS adts;
+
+ ADIF_INFO adif;
+
+ STRUCT_DAB dab;
+
+ LATM_STREAM latm;
+
+ RAWPACKETS_INFO raw;
+
+ } writer;
+
+ CSTpCallBacks callbacks;
+};
+
+typedef struct _TRANSPORTENC_STRUCT TRANSPORTENC_STRUCT;
+
+/*
+ * MEMORY Declaration
+ */
+
+C_ALLOC_MEM(Ram_TransportEncoder, struct TRANSPORTENC, 1)
+
+TRANSPORTENC_ERROR transportEnc_Open(HANDLE_TRANSPORTENC *phTpEnc) {
+ HANDLE_TRANSPORTENC hTpEnc;
+
+ if (phTpEnc == NULL) {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+
+ hTpEnc = GetRam_TransportEncoder(0);
+
+ if (hTpEnc == NULL) {
+ return TRANSPORTENC_NO_MEM;
+ }
+
+ *phTpEnc = hTpEnc;
+ return TRANSPORTENC_OK;
+}
+
+/**
+ * \brief Get frame period of PCE in raw_data_block.
+ *
+ * - Write PCE only if necessary. PCE can be part of the ASC if chConfig==0
+ * whererfore no additonal PCE will be written in raw_data_block.
+ * - A matrixMixdown coefficient can only be written if chConfig is 5.0 or 5.1.
+ * - The PCE repetition rate in raw_data_block can be controlled via
+ * headerPeriod parameter.
+ *
+ * \param channelMode Encoder Channel Mode.
+ * \param channelConfigZero No standard channel configuration.
+ * \param transportFmt Format of the transport to be written.
+ * \param headerPeriod Chosen PCE frame repetition rate.
+ * \param matrixMixdownA Indicates if a valid Matrix Mixdown coefficient
+ * is available.
+ *
+ * \return PCE frame repetition rate. -1 means no PCE present in
+ * raw_data_block.
+ */
+static INT getPceRepetitionRate(const CHANNEL_MODE channelMode,
+ const int channelConfigZero,
+ const TRANSPORT_TYPE transportFmt,
+ const int headerPeriod,
+ const int matrixMixdownA) {
+ INT pceFrameCounter = -1; /* variable to be returned */
+
+ if (headerPeriod > 0) {
+ switch (getChannelConfig(channelMode, channelConfigZero)) {
+ case 0:
+ switch (transportFmt) {
+ case TT_MP4_ADTS:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_RAW:
+ pceFrameCounter = headerPeriod;
+ break;
+ case TT_MP4_ADIF: /* ADIF header comprises PCE */
+ if ((channelMode == MODE_1_2_2) || (channelMode == MODE_1_2_2_1)) {
+ pceFrameCounter = headerPeriod; /* repeating pce only meaningful
+ for potential matrix mixdown */
+ break;
+ }
+ FDK_FALLTHROUGH;
+ case TT_MP4_LOAS: /* PCE in ASC if chChonfig==0 */
+ case TT_MP4_LATM_MCP1: /* PCE in ASC if chChonfig==0 */
+ case TT_DABPLUS:
+ default:
+ pceFrameCounter = -1; /* no PCE in raw_data_block */
+ }
+ break;
+ case 5: /* MODE_1_2_2 */
+ case 6: /* MODE_1_2_2_1 */
+ /* matrixMixdownCoefficient can only be written if 5.0 and 5.1 config
+ * present. */
+ if (matrixMixdownA != 0) {
+ switch (transportFmt) {
+ case TT_MP4_ADIF: /* ADIF header comprises PCE */
+ case TT_MP4_ADTS:
+ case TT_MP4_LOAS: /* no PCE in ASC because chConfig!=0 */
+ case TT_MP4_LATM_MCP1: /* no PCE in ASC because chConfig!=0 */
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_RAW:
+ pceFrameCounter = headerPeriod;
+ break;
+ case TT_DABPLUS:
+ default:
+ pceFrameCounter = -1; /* no PCE in raw_data_block */
+ } /* switch transportFmt */
+ } /* if matrixMixdownA!=0 */
+ break;
+ default:
+ pceFrameCounter = -1; /* no PCE in raw_data_block */
+ } /* switch getChannelConfig() */
+ } /* if headerPeriod>0 */
+ else {
+ pceFrameCounter = -1; /* no PCE in raw_data_block */
+ }
+
+ return pceFrameCounter;
+}
+
+TRANSPORTENC_ERROR transportEnc_Init(HANDLE_TRANSPORTENC hTpEnc,
+ UCHAR *bsBuffer, INT bsBufferSize,
+ TRANSPORT_TYPE transportFmt,
+ CODER_CONFIG *cconfig, UINT flags) {
+ /* Copy configuration structure */
+ FDKmemcpy(&hTpEnc->config, cconfig, sizeof(CODER_CONFIG));
+
+ /* Init transportEnc struct. */
+ hTpEnc->transportFmt = transportFmt;
+
+ hTpEnc->bsBuffer = bsBuffer;
+ hTpEnc->bsBufferSize = bsBufferSize;
+
+ FDKinitBitStream(&hTpEnc->bitStream, hTpEnc->bsBuffer, hTpEnc->bsBufferSize,
+ 0, BS_WRITER);
+
+ switch (transportFmt) {
+ case TT_MP4_ADIF:
+ /* Sanity checks */
+ if ((hTpEnc->config.aot != AOT_AAC_LC) ||
+ (hTpEnc->config.samplesPerFrame != 1024)) {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+ hTpEnc->writer.adif.headerWritten = 0;
+ hTpEnc->writer.adif.samplingRate = hTpEnc->config.samplingRate;
+ hTpEnc->writer.adif.bitRate = hTpEnc->config.bitRate;
+ hTpEnc->writer.adif.profile = ((int)hTpEnc->config.aot) - 1;
+ hTpEnc->writer.adif.cm = hTpEnc->config.channelMode;
+ hTpEnc->writer.adif.bVariableRate = 0;
+ hTpEnc->writer.adif.instanceTag = 0;
+ hTpEnc->writer.adif.matrixMixdownA = hTpEnc->config.matrixMixdownA;
+ hTpEnc->writer.adif.pseudoSurroundEnable =
+ (hTpEnc->config.flags & CC_PSEUDO_SURROUND) ? 1 : 0;
+ break;
+
+ case TT_MP4_ADTS:
+ /* Sanity checks */
+ if ((hTpEnc->config.aot != AOT_AAC_LC) ||
+ (hTpEnc->config.samplesPerFrame != 1024)) {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+ if (adtsWrite_Init(&hTpEnc->writer.adts, &hTpEnc->config) != 0) {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+ break;
+
+ case TT_DABPLUS:
+ /* Sanity checks */
+ if ( ( hTpEnc->config.aot != AOT_AAC_LC)
+ ||(hTpEnc->config.samplesPerFrame != 960) )
+ {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+ if ( dabWrite_Init(&hTpEnc->writer.dab, &hTpEnc->config) != 0) {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+ break;
+
+ case TT_MP4_LOAS:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1: {
+ TRANSPORTENC_ERROR error;
+
+ error = transportEnc_Latm_Init(&hTpEnc->writer.latm, &hTpEnc->bitStream,
+ &hTpEnc->config, flags & TP_FLAG_LATM_AMV,
+ transportFmt, &hTpEnc->callbacks);
+ if (error != TRANSPORTENC_OK) {
+ return error;
+ }
+ } break;
+
+ case TT_MP4_RAW:
+ hTpEnc->writer.raw.curSubFrame = 0;
+ hTpEnc->writer.raw.nSubFrames = hTpEnc->config.nSubFrames;
+ break;
+
+ default:
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+
+ /* pceFrameCounter indicates if PCE must be written in raw_data_block. */
+ hTpEnc->pceFrameCounter = getPceRepetitionRate(
+ hTpEnc->config.channelMode, hTpEnc->config.channelConfigZero,
+ transportFmt, hTpEnc->config.headerPeriod, hTpEnc->config.matrixMixdownA);
+
+ return TRANSPORTENC_OK;
+}
+
+TRANSPORTENC_ERROR transportEnc_AddOtherDataBits(HANDLE_TRANSPORTENC hTpEnc,
+ const int nBits) {
+ TRANSPORTENC_ERROR tpErr = TRANSPORTENC_OK;
+
+ switch (hTpEnc->transportFmt) {
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LOAS:
+ tpErr = transportEnc_LatmAddOtherDataBits(&hTpEnc->writer.latm, nBits);
+ break;
+ case TT_MP4_ADTS:
+ case TT_MP4_ADIF:
+ case TT_MP4_RAW:
+ default:
+ tpErr = TRANSPORTENC_UNKOWN_ERROR;
+ }
+
+ return tpErr;
+}
+
+HANDLE_FDK_BITSTREAM transportEnc_GetBitstream(HANDLE_TRANSPORTENC hTp) {
+ return &hTp->bitStream;
+}
+
+int transportEnc_RegisterSbrCallback(HANDLE_TRANSPORTENC hTpEnc,
+ const cbSbr_t cbSbr, void *user_data) {
+ if (hTpEnc == NULL) {
+ return -1;
+ }
+ hTpEnc->callbacks.cbSbr = cbSbr;
+ hTpEnc->callbacks.cbSbrData = user_data;
+ return 0;
+}
+int transportEnc_RegisterUsacCallback(HANDLE_TRANSPORTENC hTpEnc,
+ const cbUsac_t cbUsac, void *user_data) {
+ if (hTpEnc == NULL) {
+ return -1;
+ }
+ hTpEnc->callbacks.cbUsac = cbUsac;
+ hTpEnc->callbacks.cbUsacData = user_data;
+ return 0;
+}
+
+int transportEnc_RegisterSscCallback(HANDLE_TRANSPORTENC hTpEnc,
+ const cbSsc_t cbSsc, void *user_data) {
+ if (hTpEnc == NULL) {
+ return -1;
+ }
+ hTpEnc->callbacks.cbSsc = cbSsc;
+ hTpEnc->callbacks.cbSscData = user_data;
+ return 0;
+}
+
+TRANSPORTENC_ERROR transportEnc_WriteAccessUnit(HANDLE_TRANSPORTENC hTp,
+ INT frameUsedBits,
+ int bufferFullness, int ncc) {
+ TRANSPORTENC_ERROR err = TRANSPORTENC_OK;
+
+ if (!hTp) {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+ HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream;
+
+ /* In case of writing PCE in raw_data_block frameUsedBits must be adapted. */
+ if (hTp->pceFrameCounter >= hTp->config.headerPeriod) {
+ frameUsedBits += transportEnc_GetPCEBits(
+ hTp->config.channelMode, hTp->config.matrixMixdownA,
+ 3); /* Consider 3 bits ID signalling in alignment */
+ }
+
+ switch (hTp->transportFmt) {
+ case TT_MP4_ADIF:
+ FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0,
+ BS_WRITER);
+ if (0 != adifWrite_EncodeHeader(&hTp->writer.adif, hBs, bufferFullness)) {
+ err = TRANSPORTENC_INVALID_CONFIG;
+ }
+ break;
+ case TT_MP4_ADTS:
+ bufferFullness /= ncc; /* Number of Considered Channels */
+ bufferFullness /= 32;
+ bufferFullness = FDKmin(0x7FF, bufferFullness); /* Signal variable rate */
+ adtsWrite_EncodeHeader(&hTp->writer.adts, &hTp->bitStream, bufferFullness,
+ frameUsedBits);
+ break;
+ case TT_DABPLUS:
+ bufferFullness /= ncc; /* Number of Considered Channels */
+ bufferFullness /= 32;
+ bufferFullness = FDKmin(0x7FF, bufferFullness); /* Signal variable rate */
+ dabWrite_EncodeHeader(
+ &hTp->writer.dab,
+ &hTp->bitStream,
+ bufferFullness,
+ frameUsedBits
+ );
+ break;
+ case TT_MP4_LOAS:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ bufferFullness /= ncc; /* Number of Considered Channels */
+ bufferFullness /= 32;
+ bufferFullness = FDKmin(0xFF, bufferFullness); /* Signal variable rate */
+ transportEnc_LatmWrite(&hTp->writer.latm, hBs, frameUsedBits,
+ bufferFullness, &hTp->callbacks);
+ break;
+ case TT_MP4_RAW:
+ if (hTp->writer.raw.curSubFrame >= hTp->writer.raw.nSubFrames) {
+ hTp->writer.raw.curSubFrame = 0;
+ FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0,
+ BS_WRITER);
+ }
+ hTp->writer.raw.prevBits = FDKgetValidBits(hBs);
+ break;
+ default:
+ err = TRANSPORTENC_UNSUPPORTED_FORMAT;
+ break;
+ }
+
+ /* Write PCE in raw_data_block if required */
+ if (hTp->pceFrameCounter >= hTp->config.headerPeriod) {
+ INT crcIndex = 0;
+ /* Align inside PCE with repsect to the first bit of the raw_data_block() */
+ UINT alignAnchor = FDKgetValidBits(&hTp->bitStream);
+
+ /* Write PCE element ID bits */
+ FDKwriteBits(&hTp->bitStream, ID_PCE, 3);
+
+ if ((hTp->transportFmt == TT_MP4_ADTS) &&
+ !hTp->writer.adts.protection_absent) {
+ crcIndex = adtsWrite_CrcStartReg(&hTp->writer.adts, &hTp->bitStream, 0);
+ }
+
+ /* Write PCE as first raw_data_block element */
+ transportEnc_writePCE(
+ &hTp->bitStream, hTp->config.channelMode, hTp->config.samplingRate, 0,
+ 1, hTp->config.matrixMixdownA,
+ (hTp->config.flags & CC_PSEUDO_SURROUND) ? 1 : 0, alignAnchor);
+
+ if ((hTp->transportFmt == TT_MP4_ADTS) &&
+ !hTp->writer.adts.protection_absent) {
+ adtsWrite_CrcEndReg(&hTp->writer.adts, &hTp->bitStream, crcIndex);
+ }
+ hTp->pceFrameCounter = 0; /* reset pce frame counter */
+ }
+
+ if (hTp->pceFrameCounter != -1) {
+ hTp->pceFrameCounter++; /* Update pceFrameCounter only if PCE writing is
+ active. */
+ }
+
+ return err;
+}
+
+TRANSPORTENC_ERROR transportEnc_EndAccessUnit(HANDLE_TRANSPORTENC hTp,
+ int *bits) {
+ switch (hTp->transportFmt) {
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LOAS:
+ transportEnc_LatmAdjustSubframeBits(&hTp->writer.latm, bits);
+ break;
+ case TT_MP4_ADTS:
+ adtsWrite_EndRawDataBlock(&hTp->writer.adts, &hTp->bitStream, bits);
+ break;
+ case TT_DABPLUS:
+ dabWrite_EndRawDataBlock(&hTp->writer.dab, &hTp->bitStream, bits);
+ break;
+ case TT_MP4_ADIF:
+ /* Substract ADIF header from AU bits, not to be considered. */
+ *bits -= adifWrite_GetHeaderBits(&hTp->writer.adif);
+ hTp->writer.adif.headerWritten = 1;
+ break;
+ case TT_MP4_RAW:
+ *bits -= hTp->writer.raw.prevBits;
+ break;
+ default:
+ break;
+ }
+
+ return TRANSPORTENC_OK;
+}
+
+TRANSPORTENC_ERROR transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc,
+ int *nbytes) {
+ TRANSPORTENC_ERROR tpErr = TRANSPORTENC_OK;
+ HANDLE_FDK_BITSTREAM hBs = &hTpEnc->bitStream;
+
+ switch (hTpEnc->transportFmt) {
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LOAS:
+ *nbytes = hTpEnc->bsBufferSize;
+ tpErr = transportEnc_LatmGetFrame(&hTpEnc->writer.latm, hBs, nbytes);
+ break;
+ case TT_MP4_ADTS:
+ if (hTpEnc->writer.adts.currentBlock >=
+ hTpEnc->writer.adts.num_raw_blocks + 1) {
+ *nbytes = (FDKgetValidBits(hBs) + 7) >> 3;
+ hTpEnc->writer.adts.currentBlock = 0;
+ } else {
+ *nbytes = 0;
+ }
+ break;
+ case TT_DABPLUS:
+ if (hTpEnc->writer.dab.currentBlock >= hTpEnc->writer.dab.num_raw_blocks+1) {
+ *nbytes = (FDKgetValidBits(hBs) + 7)>>3;
+ hTpEnc->writer.dab.currentBlock = 0;
+ } else {
+ *nbytes = 0;
+ }
+ break;
+ case TT_MP4_ADIF:
+ FDK_ASSERT((INT)FDKgetValidBits(hBs) >= 0);
+ *nbytes = (FDKgetValidBits(hBs) + 7) >> 3;
+ break;
+ case TT_MP4_RAW:
+ FDKsyncCache(hBs);
+ hTpEnc->writer.raw.curSubFrame++;
+ *nbytes = ((FDKgetValidBits(hBs) - hTpEnc->writer.raw.prevBits) + 7) >> 3;
+ break;
+ default:
+ break;
+ }
+
+ return tpErr;
+}
+
+INT transportEnc_GetStaticBits(HANDLE_TRANSPORTENC hTp, int auBits) {
+ INT nbits = 0, nPceBits = 0;
+
+ /* Write PCE within raw_data_block in transport lib. */
+ if (hTp->pceFrameCounter >= hTp->config.headerPeriod) {
+ nPceBits = transportEnc_GetPCEBits(
+ hTp->config.channelMode, hTp->config.matrixMixdownA,
+ 3); /* Consider 3 bits ID signalling in alignment */
+ auBits += nPceBits; /* Adapt required raw_data_block bit consumtpion for AU
+ length information e.g. in LATM/LOAS configuration.
+ */
+ }
+
+ switch (hTp->transportFmt) {
+ case TT_MP4_ADIF:
+ case TT_MP4_RAW:
+ nbits = 0; /* Do not consider the ADIF header into the total bitrate */
+ break;
+ case TT_MP4_ADTS:
+ nbits = adtsWrite_GetHeaderBits(&hTp->writer.adts);
+ break;
+ case TT_DABPLUS:
+ nbits = dabWrite_CountTotalBitDemandHeader(&hTp->writer.dab, auBits);
+ break;
+ case TT_MP4_LOAS:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ nbits =
+ transportEnc_LatmCountTotalBitDemandHeader(&hTp->writer.latm, auBits);
+ break;
+ default:
+ nbits = 0;
+ break;
+ }
+
+ /* PCE is written in the transport library therefore the bit consumption is
+ * part of the transport static bits. */
+ nbits += nPceBits;
+
+ return nbits;
+}
+
+void transportEnc_Close(HANDLE_TRANSPORTENC *phTp) {
+ if (phTp != NULL) {
+ if (*phTp != NULL) {
+ FreeRam_TransportEncoder(phTp);
+ }
+ }
+}
+
+int transportEnc_CrcStartReg(HANDLE_TRANSPORTENC hTpEnc, int mBits) {
+ int crcReg = 0;
+
+ switch (hTpEnc->transportFmt) {
+ case TT_MP4_ADTS:
+ crcReg = adtsWrite_CrcStartReg(&hTpEnc->writer.adts, &hTpEnc->bitStream,
+ mBits);
+ break;
+ case TT_DABPLUS:
+ crcReg = dabWrite_CrcStartReg(&hTpEnc->writer.dab, &hTpEnc->bitStream, mBits);
+ break;
+ default:
+ break;
+ }
+
+ return crcReg;
+}
+
+void transportEnc_CrcEndReg(HANDLE_TRANSPORTENC hTpEnc, int reg) {
+ switch (hTpEnc->transportFmt) {
+ case TT_MP4_ADTS:
+ adtsWrite_CrcEndReg(&hTpEnc->writer.adts, &hTpEnc->bitStream, reg);
+ break;
+ case TT_DABPLUS:
+ dabWrite_CrcEndReg(&hTpEnc->writer.dab, &hTpEnc->bitStream, reg);
+ break;
+ default:
+ break;
+ }
+}
+
+TRANSPORTENC_ERROR transportEnc_GetConf(HANDLE_TRANSPORTENC hTpEnc,
+ CODER_CONFIG *cc,
+ FDK_BITSTREAM *dataBuffer,
+ UINT *confType) {
+ TRANSPORTENC_ERROR tpErr = TRANSPORTENC_OK;
+ HANDLE_LATM_STREAM hLatmConfig = &hTpEnc->writer.latm;
+
+ *confType = 0; /* set confType variable to default */
+
+ /* write StreamMuxConfig or AudioSpecificConfig depending on format used */
+ switch (hTpEnc->transportFmt) {
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LOAS:
+ tpErr =
+ CreateStreamMuxConfig(hLatmConfig, dataBuffer, 0, &hTpEnc->callbacks);
+ *confType = 1; /* config is SMC */
+ break;
+ default:
+ if (transportEnc_writeASC(dataBuffer, cc, &hTpEnc->callbacks) != 0) {
+ tpErr = TRANSPORTENC_UNKOWN_ERROR;
+ }
+ }
+
+ return tpErr;
+}
+
+TRANSPORTENC_ERROR transportEnc_GetLibInfo(LIB_INFO *info) {
+ int i;
+
+ if (info == NULL) {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+ /* search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) {
+ return TRANSPORTENC_UNKOWN_ERROR;
+ }
+ info += i;
+
+ info->module_id = FDK_TPENC;
+ info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
+ LIB_VERSION_STRING(info);
+#ifdef __ANDROID__
+ info->build_date = "";
+ info->build_time = "";
+#else
+ info->build_date = __DATE__;
+ info->build_time = __TIME__;
+#endif
+ info->title = TP_LIB_TITLE;
+
+ /* Set flags */
+ info->flags =
+ 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS | CAPF_RAWPACKETS | CAPF_DAB_AAC;
+
+ return TRANSPORTENC_OK;
+}
diff --git a/fdk-aac/libPCMutils/include/limiter.h b/fdk-aac/libPCMutils/include/limiter.h
new file mode 100644
index 0000000..fab7226
--- /dev/null
+++ b/fdk-aac/libPCMutils/include/limiter.h
@@ -0,0 +1,281 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** PCM utility library ******************************
+
+ Author(s): Matthias Neusinger
+
+ Description: Hard limiter for clipping prevention
+
+*******************************************************************************/
+
+#ifndef LIMITER_H
+#define LIMITER_H
+
+#include "common_fix.h"
+#include "FDK_audio.h"
+
+#define TDL_ATTACK_DEFAULT_MS (15) /* default attack time in ms */
+#define TDL_RELEASE_DEFAULT_MS (50) /* default release time in ms */
+
+#define TDL_GAIN_SCALING (15) /* scaling of gain value. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct TDLimiter {
+ unsigned int attack;
+ FIXP_DBL attackConst, releaseConst;
+ unsigned int attackMs, releaseMs, maxAttackMs;
+ FIXP_DBL threshold;
+ unsigned int channels, maxChannels;
+ UINT sampleRate, maxSampleRate;
+ FIXP_DBL cor, max;
+ FIXP_DBL* maxBuf;
+ FIXP_DBL* delayBuf;
+ unsigned int maxBufIdx, delayBufIdx;
+ FIXP_DBL smoothState0;
+ FIXP_DBL minGain;
+
+ FIXP_DBL additionalGainPrev;
+ FIXP_DBL additionalGainFilterState;
+ FIXP_DBL additionalGainFilterState1;
+};
+
+typedef enum {
+ TDLIMIT_OK = 0,
+ TDLIMIT_UNKNOWN = -1,
+
+ __error_codes_start = -100,
+
+ TDLIMIT_INVALID_HANDLE,
+ TDLIMIT_INVALID_PARAMETER,
+
+ __error_codes_end
+} TDLIMITER_ERROR;
+
+struct TDLimiter;
+typedef struct TDLimiter* TDLimiterPtr;
+
+#define PCM_LIM LONG
+#define FIXP_DBL2PCM_LIM(x) (x)
+#define PCM_LIM2FIXP_DBL(x) (x)
+#define PCM_LIM_BITS 32
+#define FIXP_PCM_LIM FIXP_DBL
+
+#define SAMPLE_BITS_LIM DFRACT_BITS
+
+/******************************************************************************
+ * pcmLimiter_Reset *
+ * limiter: limiter handle *
+ * returns: error code *
+ ******************************************************************************/
+TDLIMITER_ERROR pcmLimiter_Reset(TDLimiterPtr limiter);
+
+/******************************************************************************
+ * pcmLimiter_Destroy *
+ * limiter: limiter handle *
+ * returns: error code *
+ ******************************************************************************/
+TDLIMITER_ERROR pcmLimiter_Destroy(TDLimiterPtr limiter);
+
+/******************************************************************************
+ * pcmLimiter_GetDelay *
+ * limiter: limiter handle *
+ * returns: exact delay caused by the limiter in samples per channel *
+ ******************************************************************************/
+unsigned int pcmLimiter_GetDelay(TDLimiterPtr limiter);
+
+/******************************************************************************
+ * pcmLimiter_GetMaxGainReduction *
+ * limiter: limiter handle *
+ * returns: maximum gain reduction in last processed block in dB *
+ ******************************************************************************/
+INT pcmLimiter_GetMaxGainReduction(TDLimiterPtr limiter);
+
+/******************************************************************************
+ * pcmLimiter_SetNChannels *
+ * limiter: limiter handle *
+ * nChannels: number of channels ( <= maxChannels specified on create) *
+ * returns: error code *
+ ******************************************************************************/
+TDLIMITER_ERROR pcmLimiter_SetNChannels(TDLimiterPtr limiter,
+ unsigned int nChannels);
+
+/******************************************************************************
+ * pcmLimiter_SetSampleRate *
+ * limiter: limiter handle *
+ * sampleRate: sampling rate in Hz ( <= maxSampleRate specified on create) *
+ * returns: error code *
+ ******************************************************************************/
+TDLIMITER_ERROR pcmLimiter_SetSampleRate(TDLimiterPtr limiter, UINT sampleRate);
+
+/******************************************************************************
+ * pcmLimiter_SetAttack *
+ * limiter: limiter handle *
+ * attackMs: attack time in ms ( <= maxAttackMs specified on create) *
+ * returns: error code *
+ ******************************************************************************/
+TDLIMITER_ERROR pcmLimiter_SetAttack(TDLimiterPtr limiter,
+ unsigned int attackMs);
+
+/******************************************************************************
+ * pcmLimiter_SetRelease *
+ * limiter: limiter handle *
+ * releaseMs: release time in ms *
+ * returns: error code *
+ ******************************************************************************/
+TDLIMITER_ERROR pcmLimiter_SetRelease(TDLimiterPtr limiter,
+ unsigned int releaseMs);
+
+/******************************************************************************
+ * pcmLimiter_GetLibInfo *
+ * info: pointer to an allocated and initialized LIB_INFO structure *
+ * returns: error code *
+ ******************************************************************************/
+TDLIMITER_ERROR pcmLimiter_GetLibInfo(LIB_INFO* info);
+
+#ifdef __cplusplus
+}
+#endif
+
+/******************************************************************************
+ * pcmLimiter_Create *
+ * maxAttackMs: maximum and initial attack/lookahead time in milliseconds *
+ * releaseMs: release time in milliseconds (90% time constant) *
+ * threshold: limiting threshold *
+ * maxChannels: maximum and initial number of channels *
+ * maxSampleRate: maximum and initial sampling rate in Hz *
+ * returns: limiter handle *
+ ******************************************************************************/
+TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs,
+ FIXP_DBL threshold, unsigned int maxChannels,
+ UINT maxSampleRate);
+
+/******************************************************************************
+ * pcmLimiter_SetThreshold *
+ * limiter: limiter handle *
+ * threshold: limiter threshold *
+ * returns: error code *
+ ******************************************************************************/
+TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter,
+ FIXP_DBL threshold);
+
+/******************************************************************************
+ * pcmLimiter_Apply *
+ * limiter: limiter handle *
+ * pGain : pointer to gains to be applied to the signal before limiting, *
+ * which are downscaled by TDL_GAIN_SCALING bit. *
+ * These gains are delayed by gain_delay, and smoothed. *
+ * Smoothing is done by a butterworth lowpass filter with a cutoff *
+ * frequency which is fixed with respect to the sampling rate. *
+ * It is a substitute for the smoothing due to windowing and *
+ * overlap/add, if a gain is applied in frequency domain. *
+ * gain_scale: pointer to scaling exponents to be applied to the signal before *
+ * limiting, without delay and without smoothing *
+ * gain_size: number of elements in pGain, currently restricted to 1 *
+ * gain_delay: delay [samples] with which the gains in pGain shall be applied *
+ * gain_delay <= nSamples *
+ * samples: input/output buffer containing interleaved samples *
+ * precision of output will be DFRACT_BITS-TDL_GAIN_SCALING bits *
+ * nSamples: number of samples per channel *
+ * returns: error code *
+ ******************************************************************************/
+TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
+ INT_PCM* samplesOut, FIXP_DBL* pGain,
+ const INT* gain_scale, const UINT gain_size,
+ const UINT gain_delay, const UINT nSamples);
+
+#endif /* #ifndef LIMITER_H */
diff --git a/fdk-aac/libPCMutils/include/pcm_utils.h b/fdk-aac/libPCMutils/include/pcm_utils.h
new file mode 100644
index 0000000..073bcfc
--- /dev/null
+++ b/fdk-aac/libPCMutils/include/pcm_utils.h
@@ -0,0 +1,131 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** PCM utility library ******************************
+
+ Author(s): Alfonso Pino Garcia
+
+ Description: Functions that perform (de)interleaving combined with format
+change
+
+*******************************************************************************/
+
+#if !defined(PCM_UTILS_H)
+#define PCM_UTILS_H
+
+#include "common_fix.h"
+
+void FDK_interleave(const FIXP_DBL *RESTRICT pIn, LONG *RESTRICT pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length);
+void FDK_interleave(const FIXP_DBL *RESTRICT pIn, SHORT *RESTRICT pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length);
+void FDK_interleave(const FIXP_SGL *RESTRICT pIn, SHORT *RESTRICT pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length);
+
+void FDK_deinterleave(const LONG *RESTRICT pIn, SHORT *RESTRICT pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length);
+void FDK_deinterleave(const LONG *RESTRICT pIn, LONG *RESTRICT pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length);
+void FDK_deinterleave(const SHORT *RESTRICT pIn, SHORT *RESTRICT pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length);
+void FDK_deinterleave(const SHORT *RESTRICT pIn, LONG *RESTRICT pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length);
+#endif /* !defined(PCM_UTILS_H) */
diff --git a/fdk-aac/libPCMutils/include/pcmdmx_lib.h b/fdk-aac/libPCMutils/include/pcmdmx_lib.h
new file mode 100644
index 0000000..d37a851
--- /dev/null
+++ b/fdk-aac/libPCMutils/include/pcmdmx_lib.h
@@ -0,0 +1,460 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** PCM utility library ******************************
+
+ Author(s): Christian Griebel
+
+ Description:
+
+*******************************************************************************/
+
+/**
+ * \file pcmdmx_lib.h
+ * \brief FDK PCM audio mixdown library interface header file.
+
+ \page INTRO Introduction
+
+
+ \section SCOPE Scope
+
+ This document describes the high-level application interface and usage of the
+ FDK PCM audio mixdown module library developed by the Fraunhofer Institute for
+ Integrated Circuits (IIS). Depending on the library configuration, the module
+ can manipulate the number of audio channels of a given PCM signal. It can
+ create for example a two channel stereo audio signal from a given multi-channel
+ configuration (e.g. 5.1 channels).
+
+
+ \page ABBREV List of abbreviations
+
+ \li \b AAC - Advanced Audio Coding\n
+ Is an audio coding standard for lossy digital audio compression standardized
+ by ISO and IEC, as part of the MPEG-2 (ISO/IEC 13818-7:2006) and MPEG-4
+ (ISO/IEC 14496-3:2009) specifications.
+
+ \li \b DSE - Data Stream Element\n
+ A syntactical element of the MPEG-2/4 Advanced Audio Coding bitstream
+ standardized in ISO/IEC 14496-3:2009. It can convey any kind of data associated
+ to one program.
+
+ \li \b PCE - Program Config Element\n
+ A syntactical element of the MPEG-2/4 Advanced Audio Coding bitstream
+ standardized in ISO/IEC 14496-3:2009 that can define the stream configuration
+ for a single program. In addition it can comprise simple downmix meta data.
+
+ */
+
+#ifndef PCMDMX_LIB_H
+#define PCMDMX_LIB_H
+
+#include "machine_type.h"
+#include "common_fix.h"
+#include "FDK_audio.h"
+#include "FDK_bitstream.h"
+
+/**
+ * \enum PCMDMX_ERROR
+ *
+ * Error codes that can be returned by module interface functions.
+ */
+typedef enum {
+ PCMDMX_OK = 0x0, /*!< No error happened. */
+ PCMDMX_UNSUPPORTED =
+ 0x1, /*!< The requested feature/service is unavailable. This can
+ occur if the module was built for a wrong configuration. */
+ pcm_dmx_fatal_error_start,
+ PCMDMX_OUT_OF_MEMORY, /*!< Not enough memory to set up an instance of the
+ module. */
+ pcm_dmx_fatal_error_end,
+
+ PCMDMX_INVALID_HANDLE, /*!< The given instance handle is not valid. */
+ PCMDMX_INVALID_ARGUMENT, /*!< One of the parameters handed over is invalid. */
+ PCMDMX_INVALID_CH_CONFIG, /*!< The given channel configuration is not
+ supported and thus no processing was performed.
+ */
+ PCMDMX_INVALID_MODE, /*!< The set configuration/mode is not applicable. */
+ PCMDMX_UNKNOWN_PARAM, /*!< The handed parameter is not known/supported. */
+ PCMDMX_UNABLE_TO_SET_PARAM, /*!< Unable to set the specific parameter. Most
+ probably the value ist out of range.
+ */
+ PCMDMX_CORRUPT_ANC_DATA, /*!< The read ancillary data was corrupt. */
+ PCMDMX_OUTPUT_BUFFER_TOO_SMALL /*!< The size of pcm output buffer is too
+ small. */
+
+} PCMDMX_ERROR;
+
+/** Macro to identify fatal errors. */
+#define PCMDMX_IS_FATAL_ERROR(err) \
+ ((((err) >= pcm_dmx_fatal_error_start) && \
+ ((err) <= pcm_dmx_fatal_error_end)) \
+ ? 1 \
+ : 0)
+
+/**
+ * \enum PCMDMX_PARAM
+ *
+ * Modules dynamic runtime parameters that can be handed to function
+ * pcmDmx_SetParam() and pcmDmx_GetParam().
+ */
+typedef enum {
+ DMX_PROFILE_SETTING =
+ 0x01, /*!< Defines which equations, coefficients and default/
+ fallback values used for downmixing. See
+ ::DMX_PROFILE_TYPE type for details. */
+ DMX_BS_DATA_EXPIRY_FRAME =
+ 0x10, /*!< The number of frames without new metadata that
+ have to go by before the bitstream data expires.
+ The value 0 disables expiry. */
+ DMX_BS_DATA_DELAY =
+ 0x11, /*!< The number of delay frames of the output samples
+ compared to the bitstream data. */
+ MIN_NUMBER_OF_OUTPUT_CHANNELS =
+ 0x20, /*!< The minimum number of output channels. For all
+ input configurations that have less than the given
+ channels the module will modify the output
+ automatically to obtain the given number of output
+ channels. Mono signals will be duplicated. If more
+ than two output channels are desired the module
+ just adds empty channels. The parameter value must
+ be either -1, 0, 1, 2, 6 or 8. If the value is
+ greater than zero and exceeds the value of
+ parameter ::MAX_NUMBER_OF_OUTPUT_CHANNELS the
+ latter will be set to the same value. Both values
+ -1 and 0 disable the feature. */
+ MAX_NUMBER_OF_OUTPUT_CHANNELS =
+ 0x21, /*!< The maximum number of output channels. For all
+ input configurations that have more than the given
+ channels the module will apply a mixdown
+ automatically to obtain the given number of output
+ channels. The value must be either -1, 0, 1, 2, 6
+ or 8. If it's greater than zero and lower or equal
+ than the value of ::MIN_NUMBER_OF_OUTPUT_CHANNELS
+ parameter the latter will be set to the same value.
+ The values -1 and 0 disable the feature. */
+ DMX_DUAL_CHANNEL_MODE =
+ 0x30, /*!< Downmix mode for two channel audio data. See type
+ ::DUAL_CHANNEL_MODE for details. */
+ DMX_PSEUDO_SURROUND_MODE =
+ 0x31 /*!< Defines how module handles pseudo surround
+ compatible signals. See ::PSEUDO_SURROUND_MODE
+ type for details. */
+} PCMDMX_PARAM;
+
+/**
+ * \enum DMX_PROFILE_TYPE
+ *
+ * Valid value list for parameter ::DMX_PROFILE_SETTING.
+ */
+typedef enum {
+ DMX_PRFL_STANDARD =
+ 0x0, /*!< The standard profile creates mixdown signals based on
+ the advanced downmix metadata (from a DSE), equations
+ and default values defined in ISO/IEC 14496:3
+ Ammendment 4. Any other (legacy) downmix metadata will
+ be ignored. */
+ DMX_PRFL_MATRIX_MIX =
+ 0x1, /*!< This profile behaves just as the standard profile if
+ advanced downmix metadata (from a DSE) is available. If
+ not, the matrix_mixdown information embedded in the
+ program configuration element (PCE) will be applied. If
+ neither is the case the module creates a mixdown using
+ the default coefficients defined in MPEG-4 Ammendment 4.
+ The profile can be used e.g. to support legacy digital
+ TV (e.g. DVB) streams. */
+ DMX_PRFL_FORCE_MATRIX_MIX =
+ 0x2, /*!< Similar to the ::DMX_PRFL_MATRIX_MIX profile but if both
+ the advanced (DSE) and the legacy (PCE) MPEG downmix
+ metadata are available the latter will be applied. */
+ DMX_PRFL_ARIB_JAPAN =
+ 0x3 /*!< Downmix creation as described in ABNT NBR 15602-2. But
+ if advanced downmix metadata is available it will be
+ prefered. */
+} DMX_PROFILE_TYPE;
+
+/**
+ * \enum PSEUDO_SURROUND_MODE
+ *
+ * Valid value list for parameter ::DMX_PSEUDO_SURROUND_MODE.
+ */
+typedef enum {
+ NEVER_DO_PS_DMX =
+ -1, /*!< Ignore any metadata and do never create a pseudo surround
+ compatible downmix. (Default) */
+ AUTO_PS_DMX = 0, /*!< Create a pseudo surround compatible downmix only if
+ signalled in bitstreams meta data. */
+ FORCE_PS_DMX =
+ 1 /*!< Always create a pseudo surround compatible downmix.
+ CAUTION: This can lead to excessive signal cancellations
+ and signal level differences for non-compatible signals. */
+} PSEUDO_SURROUND_MODE;
+
+/**
+ * \enum DUAL_CHANNEL_MODE
+ *
+ * Valid value list for parameter ::DMX_DUAL_CHANNEL_MODE.
+ */
+typedef enum {
+ STEREO_MODE = 0x0, /*!< Leave stereo signals as they are. */
+ CH1_MODE = 0x1, /*!< Create a dual mono output signal from channel 1. */
+ CH2_MODE = 0x2, /*!< Create a dual mono output signal from channel 2. */
+ MIXED_MODE = 0x3 /*!< Create a dual mono output signal by mixing the two
+ channels. */
+} DUAL_CHANNEL_MODE;
+
+#define DMX_PCM FIXP_DBL
+#define DMX_PCMF FIXP_DBL
+#define DMX_PCM_BITS DFRACT_BITS
+#define FX_DMX2FX_PCM(x) FX_DBL2FX_PCM((FIXP_DBL)(x))
+
+/* ------------------------ *
+ * MODULES INTERFACE: *
+ * ------------------------ */
+typedef struct PCM_DMX_INSTANCE *HANDLE_PCM_DOWNMIX;
+
+/*! \addtogroup pcmDmxResetFlags Modules reset flags
+ * Macros that can be used as parameter for function pcmDmx_Reset() to specify
+ * which parts of the module shall be reset.
+ * @{
+ *
+ * \def PCMDMX_RESET_PARAMS
+ * Only reset the user specific parameters that have been modified with
+ * pcmDmx_SetParam().
+ *
+ * \def PCMDMX_RESET_BS_DATA
+ * Delete the meta data that has been fed with the appropriate interface
+ * functions.
+ *
+ * \def PCMDMX_RESET_FULL
+ * Reset the complete module instance to the state after pcmDmx_Open() had been
+ * called.
+ */
+#define PCMDMX_RESET_PARAMS (1)
+#define PCMDMX_RESET_BS_DATA (2)
+#define PCMDMX_RESET_FULL (PCMDMX_RESET_PARAMS | PCMDMX_RESET_BS_DATA)
+/*! @} */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Open and initialize an instance of the PCM downmix module
+ * @param[out] pSelf Pointer to a buffer receiving the handle of the new
+ *instance.
+ * @returns Returns an error code of type ::PCMDMX_ERROR.
+ **/
+PCMDMX_ERROR pcmDmx_Open(HANDLE_PCM_DOWNMIX *pSelf);
+
+/** Set one parameter for a single instance of the PCM downmix module.
+ * @param[in] self Handle of PCM downmix instance.
+ * @param[in] param Parameter to be set. Can be one from the ::PCMDMX_PARAM
+ *list.
+ * @param[in] value Parameter value.
+ * @returns Returns an error code of type ::PCMDMX_ERROR.
+ **/
+PCMDMX_ERROR pcmDmx_SetParam(HANDLE_PCM_DOWNMIX self, const PCMDMX_PARAM param,
+ const INT value);
+
+/** Get one parameter value of a single PCM downmix module instance.
+ * @param[in] self Handle of PCM downmix module instance.
+ * @param[in] param Parameter to query. Can be one from the ::PCMDMX_PARAM
+ *list.
+ * @param[out] pValue Pointer to buffer receiving the parameter value.
+ * @returns Returns an error code of type ::PCMDMX_ERROR.
+ **/
+PCMDMX_ERROR pcmDmx_GetParam(HANDLE_PCM_DOWNMIX self, const PCMDMX_PARAM param,
+ INT *const pValue);
+
+/** \cond
+ * Extract relevant downmix meta-data directly from a given bitstream. The
+ *function can handle both data specified in ETSI TS 101 154 or ISO/IEC
+ *14496-3:2009/Amd.4:2013.
+ * @param[in] self Handle of PCM downmix instance.
+ * @param[in] hBitStream Handle of FDK bitstream buffer.
+ * @param[in] ancDataBits Length of ancillary data in bits.
+ * @param[in] isMpeg2 Flag indicating wheter the ancillary data is from a
+ *MPEG-1/2 or a MPEG-4 stream.
+ * @returns Returns an error code of type ::PCMDMX_ERROR.
+ **/
+PCMDMX_ERROR pcmDmx_Parse(HANDLE_PCM_DOWNMIX self,
+ HANDLE_FDK_BITSTREAM hBitStream, UINT ancDataBits,
+ int isMpeg2);
+/** \endcond */
+
+/** Read from a given ancillary data buffer and extract the relevant downmix
+ *meta-data. The function can handle both data specified in ETSI TS 101 154 or
+ *ISO/IEC 14496-3:2009/Amd.4:2013.
+ * @param[in] self Handle of PCM downmix instance.
+ * @param[in] pAncDataBuf Pointer to ancillary buffer holding the data.
+ * @param[in] ancDataBytes Size of ancillary data in bytes.
+ * @param[in] isMpeg2 Flag indicating wheter the ancillary data is from a
+ *MPEG-1/2 or a MPEG-4 stream.
+ * @returns Returns an error code of type ::PCMDMX_ERROR.
+ **/
+PCMDMX_ERROR pcmDmx_ReadDvbAncData(HANDLE_PCM_DOWNMIX self, UCHAR *pAncDataBuf,
+ UINT ancDataBytes, int isMpeg2);
+
+/** Set the matrix mixdown information extracted from the PCE of an AAC
+ *bitstream.
+ * @param[in] self Handle of PCM downmix instance.
+ * @param[in] matrixMixdownPresent Matrix mixdown index present flag extracted
+ *from PCE.
+ * @param[in] matrixMixdownIdx The 2 bit matrix mixdown index extracted
+ *from PCE.
+ * @param[in] pseudoSurroundEnable The pseudo surround enable flag extracted
+ *from PCE.
+ * @returns Returns an error code of type
+ *::PCMDMX_ERROR.
+ **/
+PCMDMX_ERROR pcmDmx_SetMatrixMixdownFromPce(HANDLE_PCM_DOWNMIX self,
+ int matrixMixdownPresent,
+ int matrixMixdownIdx,
+ int pseudoSurroundEnable);
+
+/** Reset the module.
+ * @param[in] self Handle of PCM downmix instance.
+ * @param[in] flags Flags telling which parts of the module shall be reset.
+ * See \ref pcmDmxResetFlags for details.
+ * @returns Returns an error code of type ::PCMDMX_ERROR.
+ **/
+PCMDMX_ERROR pcmDmx_Reset(HANDLE_PCM_DOWNMIX self, UINT flags);
+
+/** Create a mixdown, bypass or extend the output signal depending on the
+ *modules settings and the respective given input configuration.
+ *
+ * \param[in] self Handle of PCM downmix module instance.
+ * \param[in,out] pPcmBuf Pointer to time buffer with PCM samples.
+ * \param[in] pcmBufSize Size of pPcmBuf buffer.
+ * \param[in] frameSize The I/O block size which is the number of samples per channel.
+ * \param[in,out] nChannels Pointer to buffer that holds the number of input channels and
+ * where the amount of output channels is written
+ *to.
+ * \param[in] fInterleaved Input and output samples are processed interleaved.
+ * \param[in,out] channelType Array were the corresponding channel type for each output audio
+ * channel is stored into.
+ * \param[in,out] channelIndices Array were the corresponding channel type index for each output
+ * audio channel is stored into.
+ * \param[in] mapDescr Pointer to a FDK channel mapping descriptor that contains the
+ * channel mapping to be used.
+ * \param[out] pDmxOutScale Pointer on a field receiving the scale factor that has to be
+ * applied on all samples afterwards. If the
+ *handed pointer is NULL the final scaling is done internally.
+ * @returns Returns an error code of type ::PCMDMX_ERROR.
+ **/
+PCMDMX_ERROR pcmDmx_ApplyFrame(HANDLE_PCM_DOWNMIX self, DMX_PCM *pPcmBuf,
+ const int pcmBufSize, UINT frameSize,
+ INT *nChannels, INT fInterleaved,
+ AUDIO_CHANNEL_TYPE channelType[],
+ UCHAR channelIndices[],
+ const FDK_channelMapDescr *const mapDescr,
+ INT *pDmxOutScale);
+
+/** Close an instance of the PCM downmix module.
+ * @param[in,out] pSelf Pointer to a buffer containing the handle of the
+ *instance.
+ * @returns Returns an error code of type ::PCMDMX_ERROR.
+ **/
+PCMDMX_ERROR pcmDmx_Close(HANDLE_PCM_DOWNMIX *pSelf);
+
+/** Get library info for this module.
+ * @param[out] info Pointer to an allocated LIB_INFO structure.
+ * @returns Returns an error code of type ::PCMDMX_ERROR.
+ */
+PCMDMX_ERROR pcmDmx_GetLibInfo(LIB_INFO *info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PCMDMX_LIB_H */
diff --git a/fdk-aac/libPCMutils/src/limiter.cpp b/fdk-aac/libPCMutils/src/limiter.cpp
new file mode 100644
index 0000000..a799a51
--- /dev/null
+++ b/fdk-aac/libPCMutils/src/limiter.cpp
@@ -0,0 +1,570 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** PCM utility library ******************************
+
+ Author(s): Matthias Neusinger
+
+ Description: Hard limiter for clipping prevention
+
+*******************************************************************************/
+
+#include "limiter.h"
+#include "FDK_core.h"
+
+/* library version */
+#include "version.h"
+/* library title */
+#define TDLIMIT_LIB_TITLE "TD Limiter Lib"
+
+/* create limiter */
+TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs,
+ FIXP_DBL threshold, unsigned int maxChannels,
+ UINT maxSampleRate) {
+ TDLimiterPtr limiter = NULL;
+ unsigned int attack, release;
+ FIXP_DBL attackConst, releaseConst, exponent;
+ INT e_ans;
+
+ /* calc attack and release time in samples */
+ attack = (unsigned int)(maxAttackMs * maxSampleRate / 1000);
+ release = (unsigned int)(releaseMs * maxSampleRate / 1000);
+
+ /* alloc limiter struct */
+ limiter = (TDLimiterPtr)FDKcalloc(1, sizeof(struct TDLimiter));
+ if (!limiter) return NULL;
+
+ /* alloc max and delay buffers */
+ limiter->maxBuf = (FIXP_DBL*)FDKcalloc(attack + 1, sizeof(FIXP_DBL));
+ limiter->delayBuf =
+ (FIXP_DBL*)FDKcalloc(attack * maxChannels, sizeof(FIXP_DBL));
+
+ if (!limiter->maxBuf || !limiter->delayBuf) {
+ pcmLimiter_Destroy(limiter);
+ return NULL;
+ }
+
+ /* attackConst = pow(0.1, 1.0 / (attack + 1)) */
+ exponent = invFixp(attack + 1);
+ attackConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
+ attackConst = scaleValue(attackConst, e_ans);
+
+ /* releaseConst = (float)pow(0.1, 1.0 / (release + 1)) */
+ exponent = invFixp(release + 1);
+ releaseConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
+ releaseConst = scaleValue(releaseConst, e_ans);
+
+ /* init parameters */
+ limiter->attackMs = maxAttackMs;
+ limiter->maxAttackMs = maxAttackMs;
+ limiter->releaseMs = releaseMs;
+ limiter->attack = attack;
+ limiter->attackConst = attackConst;
+ limiter->releaseConst = releaseConst;
+ limiter->threshold = threshold >> TDL_GAIN_SCALING;
+ limiter->channels = maxChannels;
+ limiter->maxChannels = maxChannels;
+ limiter->sampleRate = maxSampleRate;
+ limiter->maxSampleRate = maxSampleRate;
+
+ pcmLimiter_Reset(limiter);
+
+ return limiter;
+}
+
+/* apply limiter */
+TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
+ INT_PCM* samplesOut, FIXP_DBL* RESTRICT pGain,
+ const INT* RESTRICT gain_scale,
+ const UINT gain_size, const UINT gain_delay,
+ const UINT nSamples) {
+ unsigned int i, j;
+ FIXP_DBL tmp1;
+ FIXP_DBL tmp2;
+ FIXP_DBL tmp, old, gain, additionalGain = 0, additionalGainUnfiltered;
+ FIXP_DBL minGain = FL2FXCONST_DBL(1.0f / (1 << 1));
+
+ FDK_ASSERT(gain_size == 1);
+ FDK_ASSERT(gain_delay <= nSamples);
+
+ if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
+
+ {
+ unsigned int channels = limiter->channels;
+ unsigned int attack = limiter->attack;
+ FIXP_DBL attackConst = limiter->attackConst;
+ FIXP_DBL releaseConst = limiter->releaseConst;
+ FIXP_DBL threshold = limiter->threshold;
+
+ FIXP_DBL max = limiter->max;
+ FIXP_DBL* maxBuf = limiter->maxBuf;
+ unsigned int maxBufIdx = limiter->maxBufIdx;
+ FIXP_DBL cor = limiter->cor;
+ FIXP_DBL* delayBuf = limiter->delayBuf;
+ unsigned int delayBufIdx = limiter->delayBufIdx;
+
+ FIXP_DBL smoothState0 = limiter->smoothState0;
+ FIXP_DBL additionalGainSmoothState = limiter->additionalGainFilterState;
+ FIXP_DBL additionalGainSmoothState1 = limiter->additionalGainFilterState1;
+
+ if (!gain_delay) {
+ additionalGain = pGain[0];
+ if (gain_scale[0] > 0) {
+ additionalGain <<= gain_scale[0];
+ } else {
+ additionalGain >>= -gain_scale[0];
+ }
+ }
+
+ for (i = 0; i < nSamples; i++) {
+ if (gain_delay) {
+ if (i < gain_delay) {
+ additionalGainUnfiltered = limiter->additionalGainPrev;
+ } else {
+ additionalGainUnfiltered = pGain[0];
+ }
+
+ /* Smooth additionalGain */
+ /* [b,a] = butter(1, 0.01) */
+ static const FIXP_SGL b[] = {FL2FXCONST_SGL(0.015466 * 2.0),
+ FL2FXCONST_SGL(0.015466 * 2.0)};
+ static const FIXP_SGL a[] = {(FIXP_SGL)MAXVAL_SGL,
+ FL2FXCONST_SGL(-0.96907)};
+ additionalGain = -fMult(additionalGainSmoothState, a[1]) +
+ fMultDiv2(additionalGainUnfiltered, b[0]) +
+ fMultDiv2(additionalGainSmoothState1, b[1]);
+ additionalGainSmoothState1 = additionalGainUnfiltered;
+ additionalGainSmoothState = additionalGain;
+
+ /* Apply the additional scaling that has no delay and no smoothing */
+ if (gain_scale[0] > 0) {
+ additionalGain <<= gain_scale[0];
+ } else {
+ additionalGain >>= -gain_scale[0];
+ }
+ }
+ /* get maximum absolute sample value of all channels, including the
+ * additional gain. */
+ tmp1 = (FIXP_DBL)0;
+ for (j = 0; j < channels; j++) {
+ tmp2 = PCM_LIM2FIXP_DBL(samplesIn[j]);
+ tmp2 = fAbs(tmp2);
+ tmp2 = FIXP_DBL(INT(tmp2) ^ INT((tmp2 >> (SAMPLE_BITS_LIM - 1))));
+ tmp1 = fMax(tmp1, tmp2);
+ }
+ tmp = fMult(tmp1, additionalGain);
+
+ /* set threshold as lower border to save calculations in running maximum
+ * algorithm */
+ tmp = fMax(tmp, threshold);
+
+ /* running maximum */
+ old = maxBuf[maxBufIdx];
+ maxBuf[maxBufIdx] = tmp;
+
+ if (tmp >= max) {
+ /* new sample is greater than old maximum, so it is the new maximum */
+ max = tmp;
+ } else if (old < max) {
+ /* maximum does not change, as the sample, which has left the window was
+ not the maximum */
+ } else {
+ /* the old maximum has left the window, we have to search the complete
+ buffer for the new max */
+ max = maxBuf[0];
+ for (j = 1; j <= attack; j++) {
+ max = fMax(max, maxBuf[j]);
+ }
+ }
+ maxBufIdx++;
+ if (maxBufIdx >= attack + 1) maxBufIdx = 0;
+
+ /* calc gain */
+ /* gain is downscaled by one, so that gain = 1.0 can be represented */
+ if (max > threshold) {
+ gain = fDivNorm(threshold, max) >> 1;
+ } else {
+ gain = FL2FXCONST_DBL(1.0f / (1 << 1));
+ }
+
+ /* gain smoothing, method: TDL_EXPONENTIAL */
+ /* first order IIR filter with attack correction to avoid overshoots */
+
+ /* correct the 'aiming' value of the exponential attack to avoid the
+ * remaining overshoot */
+ if (gain < smoothState0) {
+ cor = fMin(cor,
+ fMultDiv2((gain - fMultDiv2(FL2FXCONST_SGL(0.1f * (1 << 1)),
+ smoothState0)),
+ FL2FXCONST_SGL(1.11111111f / (1 << 1)))
+ << 2);
+ } else {
+ cor = gain;
+ }
+
+ /* smoothing filter */
+ if (cor < smoothState0) {
+ smoothState0 =
+ fMult(attackConst, (smoothState0 - cor)) + cor; /* attack */
+ smoothState0 = fMax(smoothState0, gain); /* avoid overshooting target */
+ } else {
+ /* sign inversion twice to round towards +infinity,
+ so that gain can converge to 1.0 again,
+ for bit-identical output when limiter is not active */
+ smoothState0 =
+ -fMult(releaseConst, -(smoothState0 - cor)) + cor; /* release */
+ }
+
+ gain = smoothState0;
+
+ FIXP_DBL* p_delayBuf = &delayBuf[delayBufIdx * channels + 0];
+ if (gain < FL2FXCONST_DBL(1.0f / (1 << 1))) {
+ gain <<= 1;
+ /* lookahead delay, apply gain */
+ for (j = 0; j < channels; j++) {
+ tmp = p_delayBuf[j];
+ p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
+
+ /* Apply gain to delayed signal */
+ tmp = fMultDiv2(tmp, gain);
+
+ samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT(
+ tmp, TDL_GAIN_SCALING + 1, DFRACT_BITS));
+ }
+ gain >>= 1;
+ } else {
+ /* lookahead delay, apply gain=1.0f */
+ for (j = 0; j < channels; j++) {
+ tmp = p_delayBuf[j];
+ p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain);
+ samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT(
+ tmp, TDL_GAIN_SCALING, DFRACT_BITS));
+ }
+ }
+
+ delayBufIdx++;
+ if (delayBufIdx >= attack) {
+ delayBufIdx = 0;
+ }
+
+ /* save minimum gain factor */
+ if (gain < minGain) {
+ minGain = gain;
+ }
+
+ /* advance sample pointer by <channel> samples */
+ samplesIn += channels;
+ samplesOut += channels;
+ }
+
+ limiter->max = max;
+ limiter->maxBufIdx = maxBufIdx;
+ limiter->cor = cor;
+ limiter->delayBufIdx = delayBufIdx;
+
+ limiter->smoothState0 = smoothState0;
+ limiter->additionalGainFilterState = additionalGainSmoothState;
+ limiter->additionalGainFilterState1 = additionalGainSmoothState1;
+
+ limiter->minGain = minGain;
+
+ limiter->additionalGainPrev = pGain[0];
+
+ return TDLIMIT_OK;
+ }
+}
+
+/* set limiter threshold */
+TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter,
+ FIXP_DBL threshold) {
+ if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
+
+ limiter->threshold = threshold >> TDL_GAIN_SCALING;
+
+ return TDLIMIT_OK;
+}
+
+/* reset limiter */
+TDLIMITER_ERROR pcmLimiter_Reset(TDLimiterPtr limiter) {
+ if (limiter != NULL) {
+ limiter->maxBufIdx = 0;
+ limiter->delayBufIdx = 0;
+ limiter->max = (FIXP_DBL)0;
+ limiter->cor = FL2FXCONST_DBL(1.0f / (1 << 1));
+ limiter->smoothState0 = FL2FXCONST_DBL(1.0f / (1 << 1));
+ limiter->minGain = FL2FXCONST_DBL(1.0f / (1 << 1));
+
+ limiter->additionalGainPrev =
+ FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING));
+ limiter->additionalGainFilterState =
+ FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING));
+ limiter->additionalGainFilterState1 =
+ FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING));
+
+ FDKmemset(limiter->maxBuf, 0, (limiter->attack + 1) * sizeof(FIXP_DBL));
+ FDKmemset(limiter->delayBuf, 0,
+ limiter->attack * limiter->channels * sizeof(FIXP_DBL));
+ } else {
+ return TDLIMIT_INVALID_HANDLE;
+ }
+
+ return TDLIMIT_OK;
+}
+
+/* destroy limiter */
+TDLIMITER_ERROR pcmLimiter_Destroy(TDLimiterPtr limiter) {
+ if (limiter != NULL) {
+ FDKfree(limiter->maxBuf);
+ FDKfree(limiter->delayBuf);
+
+ FDKfree(limiter);
+ } else {
+ return TDLIMIT_INVALID_HANDLE;
+ }
+ return TDLIMIT_OK;
+}
+
+/* get delay in samples */
+unsigned int pcmLimiter_GetDelay(TDLimiterPtr limiter) {
+ FDK_ASSERT(limiter != NULL);
+ return limiter->attack;
+}
+
+/* get maximum gain reduction of last processed block */
+INT pcmLimiter_GetMaxGainReduction(TDLimiterPtr limiter) {
+ /* maximum gain reduction in dB = -20 * log10(limiter->minGain)
+ = -20 * log2(limiter->minGain)/log2(10) = -6.0206*log2(limiter->minGain) */
+ int e_ans;
+ FIXP_DBL loggain, maxGainReduction;
+
+ FDK_ASSERT(limiter != NULL);
+
+ loggain = fLog2(limiter->minGain, 1, &e_ans);
+
+ maxGainReduction = fMult(loggain, FL2FXCONST_DBL(-6.0206f / (1 << 3)));
+
+ return fixp_roundToInt(maxGainReduction, (e_ans + 3));
+}
+
+/* set number of channels */
+TDLIMITER_ERROR pcmLimiter_SetNChannels(TDLimiterPtr limiter,
+ unsigned int nChannels) {
+ if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
+
+ if (nChannels > limiter->maxChannels) return TDLIMIT_INVALID_PARAMETER;
+
+ limiter->channels = nChannels;
+ // pcmLimiter_Reset(limiter);
+
+ return TDLIMIT_OK;
+}
+
+/* set sampling rate */
+TDLIMITER_ERROR pcmLimiter_SetSampleRate(TDLimiterPtr limiter,
+ UINT sampleRate) {
+ unsigned int attack, release;
+ FIXP_DBL attackConst, releaseConst, exponent;
+ INT e_ans;
+
+ if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
+
+ if (sampleRate > limiter->maxSampleRate) return TDLIMIT_INVALID_PARAMETER;
+
+ /* update attack and release time in samples */
+ attack = (unsigned int)(limiter->attackMs * sampleRate / 1000);
+ release = (unsigned int)(limiter->releaseMs * sampleRate / 1000);
+
+ /* attackConst = pow(0.1, 1.0 / (attack + 1)) */
+ exponent = invFixp(attack + 1);
+ attackConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
+ attackConst = scaleValue(attackConst, e_ans);
+
+ /* releaseConst = (float)pow(0.1, 1.0 / (release + 1)) */
+ exponent = invFixp(release + 1);
+ releaseConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
+ releaseConst = scaleValue(releaseConst, e_ans);
+
+ limiter->attack = attack;
+ limiter->attackConst = attackConst;
+ limiter->releaseConst = releaseConst;
+ limiter->sampleRate = sampleRate;
+
+ /* reset */
+ // pcmLimiter_Reset(limiter);
+
+ return TDLIMIT_OK;
+}
+
+/* set attack time */
+TDLIMITER_ERROR pcmLimiter_SetAttack(TDLimiterPtr limiter,
+ unsigned int attackMs) {
+ unsigned int attack;
+ FIXP_DBL attackConst, exponent;
+ INT e_ans;
+
+ if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
+
+ if (attackMs > limiter->maxAttackMs) return TDLIMIT_INVALID_PARAMETER;
+
+ /* calculate attack time in samples */
+ attack = (unsigned int)(attackMs * limiter->sampleRate / 1000);
+
+ /* attackConst = pow(0.1, 1.0 / (attack + 1)) */
+ exponent = invFixp(attack + 1);
+ attackConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
+ attackConst = scaleValue(attackConst, e_ans);
+
+ limiter->attack = attack;
+ limiter->attackConst = attackConst;
+ limiter->attackMs = attackMs;
+
+ return TDLIMIT_OK;
+}
+
+/* set release time */
+TDLIMITER_ERROR pcmLimiter_SetRelease(TDLimiterPtr limiter,
+ unsigned int releaseMs) {
+ unsigned int release;
+ FIXP_DBL releaseConst, exponent;
+ INT e_ans;
+
+ if (limiter == NULL) return TDLIMIT_INVALID_HANDLE;
+
+ /* calculate release time in samples */
+ release = (unsigned int)(releaseMs * limiter->sampleRate / 1000);
+
+ /* releaseConst = (float)pow(0.1, 1.0 / (release + 1)) */
+ exponent = invFixp(release + 1);
+ releaseConst = fPow(FL2FXCONST_DBL(0.1f), 0, exponent, 0, &e_ans);
+ releaseConst = scaleValue(releaseConst, e_ans);
+
+ limiter->releaseConst = releaseConst;
+ limiter->releaseMs = releaseMs;
+
+ return TDLIMIT_OK;
+}
+
+/* Get library info for this module. */
+TDLIMITER_ERROR pcmLimiter_GetLibInfo(LIB_INFO* info) {
+ int i;
+
+ if (info == NULL) {
+ return TDLIMIT_INVALID_PARAMETER;
+ }
+
+ /* Search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) {
+ return TDLIMIT_UNKNOWN;
+ }
+
+ /* Add the library info */
+ info[i].module_id = FDK_TDLIMIT;
+ info[i].version =
+ LIB_VERSION(PCMUTIL_LIB_VL0, PCMUTIL_LIB_VL1, PCMUTIL_LIB_VL2);
+ LIB_VERSION_STRING(info + i);
+ info[i].build_date = PCMUTIL_LIB_BUILD_DATE;
+ info[i].build_time = PCMUTIL_LIB_BUILD_TIME;
+ info[i].title = TDLIMIT_LIB_TITLE;
+
+ /* Set flags */
+ info[i].flags = CAPF_LIMITER;
+
+ /* Add lib info for FDK tools (if not yet done). */
+ FDK_toolsGetLibInfo(info);
+
+ return TDLIMIT_OK;
+}
diff --git a/fdk-aac/libPCMutils/src/pcm_utils.cpp b/fdk-aac/libPCMutils/src/pcm_utils.cpp
new file mode 100644
index 0000000..5dd18d9
--- /dev/null
+++ b/fdk-aac/libPCMutils/src/pcm_utils.cpp
@@ -0,0 +1,195 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** PCM utility library ******************************
+
+ Author(s): Arthur Tritthart, Alfonso Pino Garcia
+
+ Description: Functions that perform (de)interleaving combined with format
+change
+
+*******************************************************************************/
+
+#include "pcm_utils.h"
+
+/* library version */
+#include "version.h"
+
+void FDK_interleave(const FIXP_DBL *RESTRICT pIn, LONG *RESTRICT pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length) {
+ for (UINT sample = 0; sample < length; sample++) {
+ const FIXP_DBL *In = &pIn[sample];
+ for (UINT ch = 0; ch < channels; ch++) {
+ *pOut++ = (LONG)In[0];
+ In += frameSize;
+ }
+ }
+}
+
+void FDK_interleave(const FIXP_DBL *RESTRICT pIn, SHORT *RESTRICT pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length) {
+ for (UINT sample = 0; sample < length; sample++) {
+ const FIXP_DBL *In = &pIn[sample];
+ for (UINT ch = 0; ch < channels; ch++) {
+ *pOut++ = (SHORT)FX_DBL2FX_SGL(In[0]);
+ In += frameSize;
+ }
+ }
+}
+
+void FDK_interleave(const FIXP_SGL *RESTRICT pIn, SHORT *RESTRICT pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length) {
+ for (UINT sample = 0; sample < length; sample++) {
+ const FIXP_SGL *In = &pIn[sample];
+ for (UINT ch = 0; ch < channels; ch++) {
+ *pOut++ = (SHORT)In[0];
+ In += frameSize;
+ }
+ }
+}
+
+void FDK_deinterleave(const LONG *RESTRICT pIn, SHORT *RESTRICT _pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length) {
+ for (UINT ch = 0; ch < channels; ch++) {
+ SHORT *pOut = _pOut + length * ch;
+ const LONG *In = &pIn[ch];
+ for (UINT sample = 0; sample < frameSize; sample++) {
+ *pOut++ = (SHORT)(In[0] >> 16);
+ In += channels;
+ }
+ }
+}
+
+void FDK_deinterleave(const LONG *RESTRICT pIn, LONG *RESTRICT _pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length) {
+ for (UINT ch = 0; ch < channels; ch++) {
+ LONG *pOut = _pOut + length * ch;
+ const LONG *In = &pIn[ch];
+ for (UINT sample = 0; sample < frameSize; sample++) {
+ *pOut++ = In[0];
+ In += channels;
+ }
+ }
+}
+
+void FDK_deinterleave(const SHORT *RESTRICT pIn, SHORT *RESTRICT _pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length) {
+ for (UINT ch = 0; ch < channels; ch++) {
+ SHORT *pOut = _pOut + length * ch;
+ const SHORT *In = &pIn[ch];
+ for (UINT sample = 0; sample < frameSize; sample++) {
+ *pOut++ = In[0];
+ In += channels;
+ }
+ }
+}
+
+void FDK_deinterleave(const SHORT *RESTRICT pIn, LONG *RESTRICT _pOut,
+ const UINT channels, const UINT frameSize,
+ const UINT length) {
+ for (UINT ch = 0; ch < channels; ch++) {
+ LONG *pOut = _pOut + length * ch;
+ const SHORT *In = &pIn[ch];
+ for (UINT sample = 0; sample < frameSize; sample++) {
+ *pOut++ = (LONG)In[0] << 16;
+ In += channels;
+ }
+ }
+}
diff --git a/fdk-aac/libPCMutils/src/pcmdmx_lib.cpp b/fdk-aac/libPCMutils/src/pcmdmx_lib.cpp
new file mode 100644
index 0000000..2070dbc
--- /dev/null
+++ b/fdk-aac/libPCMutils/src/pcmdmx_lib.cpp
@@ -0,0 +1,2662 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** PCM utility library ******************************
+
+ Author(s): Christian Griebel
+
+ Description: Defines functions that perform downmixing or a simple channel
+ expansion in the PCM time domain.
+
+*******************************************************************************/
+
+#include "pcmdmx_lib.h"
+
+#include "genericStds.h"
+#include "fixpoint_math.h"
+#include "FDK_core.h"
+
+/* library version */
+#include "version.h"
+/* library title */
+#define PCMDMX_LIB_TITLE "PCM Downmix Lib"
+
+#define FALSE 0
+#define TRUE 1
+#define IN 0
+#define OUT 1
+
+/* Type definitions: */
+#define FIXP_DMX FIXP_SGL
+#define FX_DMX2FX_DBL(x) FX_SGL2FX_DBL((FIXP_SGL)(x))
+#define FX_DBL2FX_DMX(x) FX_DBL2FX_SGL(x)
+#define FL2FXCONST_DMX(x) FL2FXCONST_SGL(x)
+#define MAXVAL_DMX MAXVAL_SGL
+#define FX_DMX2SHRT(x) ((SHORT)(x))
+#define FX_DMX2FL(x) FX_DBL2FL(FX_DMX2FX_DBL(x))
+
+/* Fixed and unique channel group indices.
+ * The last group index has to be smaller than ( 4 ). */
+#define CH_GROUP_FRONT (0)
+#define CH_GROUP_SIDE (1)
+#define CH_GROUP_REAR (2)
+#define CH_GROUP_LFE (3)
+
+/* Fixed and unique channel plain indices. */
+#define CH_PLAIN_NORMAL (0)
+#define CH_PLAIN_TOP (1)
+#define CH_PLAIN_BOTTOM (2)
+
+/* The ordering of the following fixed channel labels has to be in MPEG-4 style.
+ * From the center to the back with left and right channel interleaved (starting
+ * with left). The last channel label index has to be smaller than ( 8 ). */
+#define CENTER_FRONT_CHANNEL (0) /* C */
+#define LEFT_FRONT_CHANNEL (1) /* L */
+#define RIGHT_FRONT_CHANNEL (2) /* R */
+#define LEFT_REAR_CHANNEL \
+ (3) /* Lr (aka left back channel) or center back channel */
+#define RIGHT_REAR_CHANNEL (4) /* Rr (aka right back channel) */
+#define LOW_FREQUENCY_CHANNEL (5) /* Lf */
+#define LEFT_MULTIPRPS_CHANNEL (6) /* Left multipurpose channel */
+#define RIGHT_MULTIPRPS_CHANNEL (7) /* Right multipurpose channel */
+
+/* 22.2 channel specific fixed channel lables: */
+#define LEFT_SIDE_CHANNEL (8) /* Lss */
+#define RIGHT_SIDE_CHANNEL (9) /* Rss */
+#define CENTER_REAR_CHANNEL (10) /* Cs */
+#define CENTER_FRONT_CHANNEL_TOP (11) /* Cv */
+#define LEFT_FRONT_CHANNEL_TOP (12) /* Lv */
+#define RIGHT_FRONT_CHANNEL_TOP (13) /* Rv */
+#define LEFT_SIDE_CHANNEL_TOP (14) /* Lvss */
+#define RIGHT_SIDE_CHANNEL_TOP (15) /* Rvss */
+#define CENTER_SIDE_CHANNEL_TOP (16) /* Ts */
+#define LEFT_REAR_CHANNEL_TOP (17) /* Lvr */
+#define RIGHT_REAR_CHANNEL_TOP (18) /* Rvr */
+#define CENTER_REAR_CHANNEL_TOP (19) /* Cvr */
+#define CENTER_FRONT_CHANNEL_BOTTOM (20) /* Cb */
+#define LEFT_FRONT_CHANNEL_BOTTOM (21) /* Lb */
+#define RIGHT_FRONT_CHANNEL_BOTTOM (22) /* Rb */
+#define LOW_FREQUENCY_CHANNEL_2 (23) /* LFE2 */
+
+/* More constants */
+#define ONE_CHANNEL (1)
+#define TWO_CHANNEL (2)
+#define SIX_CHANNEL (6)
+#define EIGHT_CHANNEL (8)
+#define TWENTY_FOUR_CHANNEL (24)
+
+#define PCMDMX_THRESHOLD_MAP_HEAT_1 (0) /* Store only exact matches */
+#define PCMDMX_THRESHOLD_MAP_HEAT_2 (20)
+#define PCMDMX_THRESHOLD_MAP_HEAT_3 \
+ (256) /* Do not assign normal channels to LFE */
+
+#define SP_Z_NRM (0)
+#define SP_Z_TOP (2)
+#define SP_Z_BOT (-2)
+#define SP_Z_LFE (-18)
+#define SP_Z_MUL (8) /* Should be smaller than SP_Z_LFE */
+
+typedef struct {
+ SCHAR x; /* horizontal position: center (0), left (-), right (+) */
+ SCHAR y; /* deepth position: front, side, back, position */
+ SCHAR z; /* heigth positions: normal, top, bottom, lfe */
+} PCM_DMX_SPEAKER_POSITION;
+
+/* CAUTION: The maximum x-value should be less or equal to
+ * PCMDMX_SPKR_POS_X_MAX_WIDTH. */
+static const PCM_DMX_SPEAKER_POSITION spkrSlotPos[] = {
+ /* x, y, z */
+ {0, 0, SP_Z_NRM}, /* 0 CENTER_FRONT_CHANNEL */
+ {-2, 0, SP_Z_NRM}, /* 1 LEFT_FRONT_CHANNEL */
+ {2, 0, SP_Z_NRM}, /* 2 RIGHT_FRONT_CHANNEL */
+ {-3, 4, SP_Z_NRM}, /* 3 LEFT_REAR_CHANNEL */
+ {3, 4, SP_Z_NRM}, /* 4 RIGHT_REAR_CHANNEL */
+ {0, 0, SP_Z_LFE}, /* 5 LOW_FREQUENCY_CHANNEL */
+ {-2, 2, SP_Z_MUL}, /* 6 LEFT_MULTIPRPS_CHANNEL */
+ {2, 2, SP_Z_MUL} /* 7 RIGHT_MULTIPRPS_CHANNEL */
+};
+
+/* List of packed channel modes */
+typedef enum { /* CH_MODE_<numFrontCh>_<numSideCh>_<numBackCh>_<numLfCh> */
+ CH_MODE_UNDEFINED = 0x0000,
+ /* 1 channel */
+ CH_MODE_1_0_0_0 = 0x0001, /* chCfg 1 */
+ /* 2 channels */
+ CH_MODE_2_0_0_0 = 0x0002 /* chCfg 2 */
+ /* 3 channels */
+ ,
+ CH_MODE_3_0_0_0 = 0x0003, /* chCfg 3 */
+ CH_MODE_2_0_1_0 = 0x0102,
+ CH_MODE_2_0_0_1 = 0x1002,
+ /* 4 channels */
+ CH_MODE_3_0_1_0 = 0x0103, /* chCfg 4 */
+ CH_MODE_2_0_2_0 = 0x0202,
+ CH_MODE_2_0_1_1 = 0x1102,
+ CH_MODE_4_0_0_0 = 0x0004,
+ /* 5 channels */
+ CH_MODE_3_0_2_0 = 0x0203, /* chCfg 5 */
+ CH_MODE_2_0_2_1 = 0x1202,
+ CH_MODE_3_0_1_1 = 0x1103,
+ CH_MODE_3_2_0_0 = 0x0023,
+ CH_MODE_5_0_0_0 = 0x0005,
+ /* 6 channels */
+ CH_MODE_3_0_2_1 = 0x1203, /* chCfg 6 */
+ CH_MODE_3_2_0_1 = 0x1023,
+ CH_MODE_3_2_1_0 = 0x0123,
+ CH_MODE_5_0_1_0 = 0x0105,
+ CH_MODE_6_0_0_0 = 0x0006,
+ /* 7 channels */
+ CH_MODE_2_2_2_1 = 0x1222,
+ CH_MODE_3_0_3_1 = 0x1303, /* chCfg 11 */
+ CH_MODE_3_2_1_1 = 0x1123,
+ CH_MODE_3_2_2_0 = 0x0223,
+ CH_MODE_3_0_2_2 = 0x2203,
+ CH_MODE_5_0_2_0 = 0x0205,
+ CH_MODE_5_0_1_1 = 0x1105,
+ CH_MODE_7_0_0_0 = 0x0007,
+ /* 8 channels */
+ CH_MODE_3_2_2_1 = 0x1223,
+ CH_MODE_3_0_4_1 = 0x1403, /* chCfg 12 */
+ CH_MODE_5_0_2_1 = 0x1205, /* chCfg 7 + 14 */
+ CH_MODE_5_2_1_0 = 0x0125,
+ CH_MODE_3_2_1_2 = 0x2123,
+ CH_MODE_2_2_2_2 = 0x2222,
+ CH_MODE_3_0_3_2 = 0x2303,
+ CH_MODE_8_0_0_0 = 0x0008
+
+} PCM_DMX_CHANNEL_MODE;
+
+/* These are the channel configurations linked to
+ the number of output channels give by the user: */
+static const PCM_DMX_CHANNEL_MODE outChModeTable[(8) + 1] = {
+ CH_MODE_UNDEFINED,
+ CH_MODE_1_0_0_0, /* 1 channel */
+ CH_MODE_2_0_0_0 /* 2 channels */
+ ,
+ CH_MODE_3_0_0_0, /* 3 channels */
+ CH_MODE_3_0_1_0, /* 4 channels */
+ CH_MODE_3_0_2_0, /* 5 channels */
+ CH_MODE_3_0_2_1 /* 6 channels */
+ ,
+ CH_MODE_3_0_3_1, /* 7 channels */
+ CH_MODE_3_0_4_1 /* 8 channels */
+};
+
+static const FIXP_DMX abMixLvlValueTab[8] = {
+ FL2FXCONST_DMX(0.500f), /* scaled by 1 */
+ FL2FXCONST_DMX(0.841f), FL2FXCONST_DMX(0.707f), FL2FXCONST_DMX(0.596f),
+ FL2FXCONST_DMX(0.500f), FL2FXCONST_DMX(0.422f), FL2FXCONST_DMX(0.355f),
+ FL2FXCONST_DMX(0.0f)};
+
+static const FIXP_DMX lfeMixLvlValueTab[16] = {
+ /* value, scale */
+ FL2FXCONST_DMX(0.7905f), /* 2 */
+ FL2FXCONST_DMX(0.5000f), /* 2 */
+ FL2FXCONST_DMX(0.8395f), /* 1 */
+ FL2FXCONST_DMX(0.7065f), /* 1 */
+ FL2FXCONST_DMX(0.5945f), /* 1 */
+ FL2FXCONST_DMX(0.500f), /* 1 */
+ FL2FXCONST_DMX(0.841f), /* 0 */
+ FL2FXCONST_DMX(0.707f), /* 0 */
+ FL2FXCONST_DMX(0.596f), /* 0 */
+ FL2FXCONST_DMX(0.500f), /* 0 */
+ FL2FXCONST_DMX(0.316f), /* 0 */
+ FL2FXCONST_DMX(0.178f), /* 0 */
+ FL2FXCONST_DMX(0.100f), /* 0 */
+ FL2FXCONST_DMX(0.032f), /* 0 */
+ FL2FXCONST_DMX(0.010f), /* 0 */
+ FL2FXCONST_DMX(0.000f) /* 0 */
+};
+
+/* MPEG matrix mixdown:
+ Set 1: L' = (1 + 2^-0.5 + A )^-1 * [L + C * 2^-0.5 + A * Ls];
+ R' = (1 + 2^-0.5 + A )^-1 * [R + C * 2^-0.5 + A * Rs];
+
+ Set 2: L' = (1 + 2^-0.5 + 2A )^-1 * [L + C * 2^-0.5 - A * (Ls + Rs)];
+ R' = (1 + 2^-0.5 + 2A )^-1 * [R + C * 2^-0.5 + A * (Ls + Rs)];
+
+ M = (3 + 2A)^-1 * [L + C + R + A*(Ls + Rs)];
+*/
+static const FIXP_DMX mpegMixDownIdx2Coef[4] = {
+ FL2FXCONST_DMX(0.70710678f), FL2FXCONST_DMX(0.5f),
+ FL2FXCONST_DMX(0.35355339f), FL2FXCONST_DMX(0.0f)};
+
+static const FIXP_DMX mpegMixDownIdx2PreFact[3][4] = {
+ {/* Set 1: */
+ FL2FXCONST_DMX(0.4142135623730950f), FL2FXCONST_DMX(0.4530818393219728f),
+ FL2FXCONST_DMX(0.4852813742385703f), FL2FXCONST_DMX(0.5857864376269050f)},
+ {/* Set 2: */
+ FL2FXCONST_DMX(0.3203772410170407f), FL2FXCONST_DMX(0.3693980625181293f),
+ FL2FXCONST_DMX(0.4142135623730950f), FL2FXCONST_DMX(0.5857864376269050f)},
+ {/* Mono DMX set: */
+ FL2FXCONST_DMX(0.2265409196609864f), FL2FXCONST_DMX(0.25f),
+ FL2FXCONST_DMX(0.2697521433898179f), FL2FXCONST_DMX(0.3333333333333333f)}};
+
+#define TYPE_NONE (0x00)
+#define TYPE_PCE_DATA (0x01)
+#define TYPE_DSE_CLEV_DATA (0x02)
+#define TYPE_DSE_SLEV_DATA (0x04)
+#define TYPE_DSE_DMIX_AB_DATA (0x08)
+#define TYPE_DSE_DMIX_LFE_DATA (0x10)
+#define TYPE_DSE_DMX_GAIN_DATA (0x20)
+#define TYPE_DSE_DMX_CGL_DATA (0x40)
+#define TYPE_DSE_DATA (0x7E)
+
+typedef struct {
+ UINT typeFlags;
+ /* From DSE */
+ UCHAR cLevIdx;
+ UCHAR sLevIdx;
+ UCHAR dmixIdxA;
+ UCHAR dmixIdxB;
+ UCHAR dmixIdxLfe;
+ UCHAR dmxGainIdx2;
+ UCHAR dmxGainIdx5;
+ /* From PCE */
+ UCHAR matrixMixdownIdx;
+ /* Attributes: */
+ SCHAR pseudoSurround; /*!< If set to 1 the signal is pseudo surround
+ compatible. The value 0 tells that it is not. If the
+ value is -1 the information is not available. */
+ UINT expiryCount; /*!< Counter to monitor the life time of a meta data set. */
+
+} DMX_BS_META_DATA;
+
+/* Default metadata */
+static const DMX_BS_META_DATA dfltMetaData = {0, 2, 2, 2, 2, 15,
+ 0, 0, 0, -1, 0};
+
+/* Dynamic (user) params:
+ See the definition of PCMDMX_PARAM for details on the specific fields. */
+typedef struct {
+ DMX_PROFILE_TYPE dmxProfile; /*!< Linked to DMX_PRFL_STANDARD */
+ UINT expiryFrame; /*!< Linked to DMX_BS_DATA_EXPIRY_FRAME */
+ DUAL_CHANNEL_MODE dualChannelMode; /*!< Linked to DMX_DUAL_CHANNEL_MODE */
+ PSEUDO_SURROUND_MODE
+ pseudoSurrMode; /*!< Linked to DMX_PSEUDO_SURROUND_MODE */
+ SHORT numOutChannelsMin; /*!< Linked to MIN_NUMBER_OF_OUTPUT_CHANNELS */
+ SHORT numOutChannelsMax; /*!< Linked to MAX_NUMBER_OF_OUTPUT_CHANNELS */
+ UCHAR frameDelay; /*!< Linked to DMX_BS_DATA_DELAY */
+
+} PCM_DMX_USER_PARAMS;
+
+/* Modules main data structure: */
+struct PCM_DMX_INSTANCE {
+ /* Metadata */
+ DMX_BS_META_DATA bsMetaData[(1) + 1];
+ PCM_DMX_USER_PARAMS userParams;
+
+ UCHAR applyProcessing; /*!< Flag to en-/disable modules processing.
+ The max channel limiting is done independently. */
+};
+
+/* Memory allocation macro */
+C_ALLOC_MEM(PcmDmxInstance, struct PCM_DMX_INSTANCE, 1)
+
+static UINT getSpeakerDistance(PCM_DMX_SPEAKER_POSITION posA,
+ PCM_DMX_SPEAKER_POSITION posB) {
+ PCM_DMX_SPEAKER_POSITION diff;
+
+ diff.x = posA.x - posB.x;
+ diff.y = posA.y - posB.y;
+ diff.z = posA.z - posB.z;
+
+ return ((diff.x * diff.x) + (diff.y * diff.y) + (diff.z * diff.z));
+}
+
+static PCM_DMX_SPEAKER_POSITION getSpeakerPos(AUDIO_CHANNEL_TYPE chType,
+ UCHAR chIndex, UCHAR numChInGrp) {
+#define PCMDMX_SPKR_POS_X_MAX_WIDTH (3)
+#define PCMDMX_SPKR_POS_Y_SPREAD (2)
+#define PCMDMX_SPKR_POS_Z_SPREAD (2)
+
+ PCM_DMX_SPEAKER_POSITION spkrPos = {0, 0, 0};
+ AUDIO_CHANNEL_TYPE chGrp = (AUDIO_CHANNEL_TYPE)(chType & 0x0F);
+ unsigned fHasCenter = numChInGrp & 0x1;
+ unsigned chGrpWidth = numChInGrp >> 1;
+ unsigned fIsCenter = 0;
+ unsigned fIsLfe = (chType == ACT_LFE) ? 1 : 0;
+ int offset = 0;
+
+ FDK_ASSERT(chIndex < numChInGrp);
+
+ if ((chGrp == ACT_FRONT) && fHasCenter) {
+ if (chIndex == 0) fIsCenter = 1;
+ chIndex = (UCHAR)fMax(0, chIndex - 1);
+ } else if (fHasCenter && (chIndex == numChInGrp - 1)) {
+ fIsCenter = 1;
+ }
+ /* now all even indices are left (-) */
+ if (!fIsCenter) {
+ offset = chIndex >> 1;
+ if ((chGrp > ACT_FRONT) && (chType != ACT_SIDE) && !fIsLfe) {
+ /* the higher the index the lower the distance to the center position */
+ offset = chGrpWidth - fHasCenter - offset;
+ }
+ if ((chIndex & 0x1) == 0) { /* even */
+ offset = -(offset + 1);
+ } else {
+ offset += 1;
+ }
+ }
+ /* apply the offset */
+ if (chType == ACT_SIDE) {
+ spkrPos.x = (offset < 0) ? -PCMDMX_SPKR_POS_X_MAX_WIDTH
+ : PCMDMX_SPKR_POS_X_MAX_WIDTH;
+ spkrPos.y = /* 1x */ PCMDMX_SPKR_POS_Y_SPREAD + (SCHAR)fAbs(offset) - 1;
+ spkrPos.z = 0;
+ } else {
+ unsigned spread =
+ ((chGrpWidth == 1) && (!fIsLfe)) ? PCMDMX_SPKR_POS_X_MAX_WIDTH - 1 : 1;
+ spkrPos.x = (SCHAR)offset * (SCHAR)spread;
+ if (fIsLfe) {
+ spkrPos.y = 0;
+ spkrPos.z = SP_Z_LFE;
+ } else {
+ spkrPos.y = (SCHAR)fMax((SCHAR)chGrp - 1, 0) * PCMDMX_SPKR_POS_Y_SPREAD;
+ spkrPos.z = (SCHAR)chType >> 4;
+ if (spkrPos.z == 2) { /* ACT_BOTTOM */
+ spkrPos.z = -1;
+ }
+ spkrPos.z *= PCMDMX_SPKR_POS_Z_SPREAD;
+ }
+ }
+ return spkrPos;
+}
+
+/** Return the channel mode of a given horizontal channel plain (normal, top,
+ *bottom) for a given channel configuration. NOTE: This function shall get
+ *obsolete once the channel mode has been changed to be nonambiguous.
+ * @param [in] Index of the requested channel plain.
+ * @param [in] The packed channel mode for the complete channel configuration
+ *(all plains).
+ * @param [in] The MPEG-4 channel configuration index which is necessary in
+ *cases where the (packed) channel mode is ambiguous.
+ * @returns Returns the packed channel mode of the requested channel plain.
+ **/
+static PCM_DMX_CHANNEL_MODE getChMode4Plain(
+ const int plainIndex, const PCM_DMX_CHANNEL_MODE totChMode,
+ const int chCfg) {
+ PCM_DMX_CHANNEL_MODE plainChMode = totChMode;
+
+ switch (totChMode) {
+ case CH_MODE_5_0_2_1:
+ if (chCfg == 14) {
+ switch (plainIndex) {
+ case CH_PLAIN_BOTTOM:
+ plainChMode = (PCM_DMX_CHANNEL_MODE)0x0000;
+ break;
+ case CH_PLAIN_TOP:
+ plainChMode = CH_MODE_2_0_0_0;
+ break;
+ case CH_PLAIN_NORMAL:
+ default:
+ plainChMode = CH_MODE_3_0_2_1;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return plainChMode;
+}
+
+static inline UINT getIdxSum(UCHAR numCh) {
+ UINT result = 0;
+ int i;
+ for (i = 1; i < numCh; i += 1) {
+ result += i;
+ }
+ return result;
+}
+
+/** Evaluate a given channel configuration and extract a packed channel mode. In
+ *addition the function generates a channel offset table for the mapping to the
+ *internal representation. This function is the inverse to the
+ *getChannelDescription() routine.
+ * @param [in] The total number of channels of the given configuration.
+ * @param [in] Array holding the corresponding channel types for each channel.
+ * @param [in] Array holding the corresponding channel type indices for each
+ *channel.
+ * @param [out] Array where the buffer offsets for each channel are stored into.
+ * @param [out] The generated packed channel mode that represents the given
+ *input configuration.
+ * @returns Returns an error code.
+ **/
+static PCMDMX_ERROR getChannelMode(
+ const UINT numChannels, /* in */
+ const AUDIO_CHANNEL_TYPE channelType[], /* in */
+ UCHAR channelIndices[], /* in */
+ UCHAR offsetTable[(8)], /* out */
+ PCM_DMX_CHANNEL_MODE *chMode /* out */
+) {
+ UINT idxSum[(3)][(4)];
+ UCHAR numCh[(3)][(4)];
+ UCHAR mapped[(8)];
+ PCM_DMX_SPEAKER_POSITION spkrPos[(8)];
+ PCMDMX_ERROR err = PCMDMX_OK;
+ unsigned ch, numMappedInChs = 0;
+ unsigned startSlot;
+ unsigned stopSlot = LOW_FREQUENCY_CHANNEL;
+
+ FDK_ASSERT(channelType != NULL);
+ FDK_ASSERT(channelIndices != NULL);
+ FDK_ASSERT(offsetTable != NULL);
+ FDK_ASSERT(chMode != NULL);
+
+ /* For details see ISO/IEC 13818-7:2005(E), 8.5.3 Channel configuration */
+ FDKmemclear(idxSum, (3) * (4) * sizeof(UINT));
+ FDKmemclear(numCh, (3) * (4) * sizeof(UCHAR));
+ FDKmemclear(mapped, (8) * sizeof(UCHAR));
+ FDKmemclear(spkrPos, (8) * sizeof(PCM_DMX_SPEAKER_POSITION));
+ /* Init output */
+ FDKmemset(offsetTable, 255, (8) * sizeof(UCHAR));
+ *chMode = CH_MODE_UNDEFINED;
+
+ /* Determine how many channels are assigned to each channels each group: */
+ for (ch = 0; ch < numChannels; ch += 1) {
+ unsigned chGrp = fMax(
+ (channelType[ch] & 0x0F) - 1,
+ 0); /* Assign all undefined channels (ACT_NONE) to front channels. */
+ numCh[channelType[ch] >> 4][chGrp] += 1;
+ idxSum[channelType[ch] >> 4][chGrp] += channelIndices[ch];
+ }
+ if (numChannels > TWO_CHANNEL) {
+ int chGrp;
+ /* Sanity check on the indices */
+ for (chGrp = 0; chGrp < (4); chGrp += 1) {
+ int plane;
+ for (plane = 0; plane < (3); plane += 1) {
+ if (idxSum[plane][chGrp] != getIdxSum(numCh[plane][chGrp])) {
+ unsigned idxCnt = 0;
+ for (ch = 0; ch < numChannels; ch += 1) {
+ if (channelType[ch] ==
+ (AUDIO_CHANNEL_TYPE)((plane << 4) | ((chGrp + 1) & 0xF))) {
+ channelIndices[ch] = idxCnt++;
+ }
+ }
+ err = PCMDMX_INVALID_CH_CONFIG;
+ }
+ }
+ }
+ }
+ /* Mapping HEAT 1:
+ * Determine the speaker position of each input channel and map it to a
+ * internal slot if it matches exactly (with zero distance). */
+ for (ch = 0; ch < numChannels; ch += 1) {
+ UINT mapDist = (unsigned)-1;
+ unsigned mapCh, mapPos = (unsigned)-1;
+ unsigned chGrp = fMax(
+ (channelType[ch] & 0x0F) - 1,
+ 0); /* Assign all undefined channels (ACT_NONE) to front channels. */
+
+ spkrPos[ch] = getSpeakerPos(channelType[ch], channelIndices[ch],
+ numCh[channelType[ch] >> 4][chGrp]);
+
+ for (mapCh = 0; mapCh <= stopSlot; mapCh += 1) {
+ if (offsetTable[mapCh] == 255) {
+ UINT dist = getSpeakerDistance(spkrPos[ch], spkrSlotPos[mapCh]);
+ if (dist < mapDist) {
+ mapPos = mapCh;
+ mapDist = dist;
+ }
+ }
+ }
+ if (mapDist <= PCMDMX_THRESHOLD_MAP_HEAT_1) {
+ offsetTable[mapPos] = (UCHAR)ch;
+ mapped[ch] = 1;
+ numMappedInChs += 1;
+ }
+ }
+
+ /* Mapping HEAT 2:
+ * Go through the unmapped input channels and assign them to the internal
+ * slots that matches best (least distance). But assign center channels to
+ * center slots only. */
+ startSlot =
+ ((numCh[CH_PLAIN_NORMAL][CH_GROUP_FRONT] & 0x1) || (numChannels >= (8)))
+ ? 0
+ : 1;
+ for (ch = 0; ch < (unsigned)numChannels; ch += 1) {
+ if (!mapped[ch]) {
+ UINT mapDist = (unsigned)-1;
+ unsigned mapCh, mapPos = (unsigned)-1;
+
+ for (mapCh = startSlot; mapCh <= stopSlot; mapCh += 1) {
+ if (offsetTable[mapCh] == 255) {
+ UINT dist = getSpeakerDistance(spkrPos[ch], spkrSlotPos[mapCh]);
+ if (dist < mapDist) {
+ mapPos = mapCh;
+ mapDist = dist;
+ }
+ }
+ }
+ if ((mapPos <= stopSlot) && (mapDist < PCMDMX_THRESHOLD_MAP_HEAT_2) &&
+ (((spkrPos[ch].x != 0) && (spkrSlotPos[mapPos].x != 0)) /* XOR */
+ || ((spkrPos[ch].x == 0) &&
+ (spkrSlotPos[mapPos].x ==
+ 0)))) { /* Assign center channels to center slots only. */
+ offsetTable[mapPos] = (UCHAR)ch;
+ mapped[ch] = 1;
+ numMappedInChs += 1;
+ }
+ }
+ }
+
+ /* Mapping HEAT 3:
+ * Assign the rest by searching for the nearest input channel for each
+ * internal slot. */
+ for (ch = startSlot; (ch < (8)) && (numMappedInChs < numChannels); ch += 1) {
+ if (offsetTable[ch] == 255) {
+ UINT mapDist = (unsigned)-1;
+ unsigned mapCh, mapPos = (unsigned)-1;
+
+ for (mapCh = 0; mapCh < (unsigned)numChannels; mapCh += 1) {
+ if (!mapped[mapCh]) {
+ UINT dist = getSpeakerDistance(spkrPos[mapCh], spkrSlotPos[ch]);
+ if (dist < mapDist) {
+ mapPos = mapCh;
+ mapDist = dist;
+ }
+ }
+ }
+ if (mapDist < PCMDMX_THRESHOLD_MAP_HEAT_3) {
+ offsetTable[ch] = (UCHAR)mapPos;
+ mapped[mapPos] = 1;
+ numMappedInChs += 1;
+ if ((spkrPos[mapPos].x == 0) && (spkrSlotPos[ch].x != 0) &&
+ (numChannels <
+ (8))) { /* Skip the paired slot if we assigned a center channel. */
+ ch += 1;
+ }
+ }
+ }
+ }
+
+ /* Finaly compose the channel mode */
+ for (ch = 0; ch < (4); ch += 1) {
+ int plane, numChInGrp = 0;
+ for (plane = 0; plane < (3); plane += 1) {
+ numChInGrp += numCh[plane][ch];
+ }
+ *chMode = (PCM_DMX_CHANNEL_MODE)(*chMode | (numChInGrp << (ch * 4)));
+ }
+
+ return err;
+}
+
+/** Generate a channel offset table and complete channel description for a given
+ *(packed) channel mode. This function is the inverse to the getChannelMode()
+ *routine but does not support weird channel configurations.
+ * @param [in] The packed channel mode of the configuration to be processed.
+ * @param [in] Array containing the channel mapping to be used (From MPEG PCE
+ *ordering to whatever is required).
+ * @param [out] Array where corresponding channel types for each channels are
+ *stored into.
+ * @param [out] Array where corresponding channel type indices for each output
+ *channel are stored into.
+ * @param [out] Array where the buffer offsets for each channel are stored into.
+ * @returns None.
+ **/
+static void getChannelDescription(
+ const PCM_DMX_CHANNEL_MODE chMode, /* in */
+ const FDK_channelMapDescr *const mapDescr, /* in */
+ AUDIO_CHANNEL_TYPE channelType[], /* out */
+ UCHAR channelIndices[], /* out */
+ UCHAR offsetTable[(8)] /* out */
+) {
+ int grpIdx, plainIdx, numPlains = 1, numTotalChannels = 0;
+ int chCfg, ch = 0;
+
+ FDK_ASSERT(channelType != NULL);
+ FDK_ASSERT(channelIndices != NULL);
+ FDK_ASSERT(mapDescr != NULL);
+ FDK_ASSERT(offsetTable != NULL);
+
+ /* Init output arrays */
+ FDKmemclear(channelType, (8) * sizeof(AUDIO_CHANNEL_TYPE));
+ FDKmemclear(channelIndices, (8) * sizeof(UCHAR));
+ FDKmemset(offsetTable, 255, (8) * sizeof(UCHAR));
+
+ /* Summerize to get the total number of channels */
+ for (grpIdx = 0; grpIdx < (4); grpIdx += 1) {
+ numTotalChannels += (chMode >> (grpIdx * 4)) & 0xF;
+ }
+
+ /* Get the appropriate channel map */
+ switch (chMode) {
+ case CH_MODE_1_0_0_0:
+ case CH_MODE_2_0_0_0:
+ case CH_MODE_3_0_0_0:
+ case CH_MODE_3_0_1_0:
+ case CH_MODE_3_0_2_0:
+ case CH_MODE_3_0_2_1:
+ chCfg = numTotalChannels;
+ break;
+ case CH_MODE_3_0_3_1:
+ chCfg = 11;
+ break;
+ case CH_MODE_3_0_4_1:
+ chCfg = 12;
+ break;
+ case CH_MODE_5_0_2_1:
+ chCfg = 7;
+ break;
+ default:
+ /* fallback */
+ chCfg = 0;
+ break;
+ }
+
+ /* Compose channel offset table */
+
+ for (plainIdx = 0; plainIdx < numPlains; plainIdx += 1) {
+ PCM_DMX_CHANNEL_MODE plainChMode;
+ UCHAR numChInGrp[(4)];
+
+ plainChMode = getChMode4Plain(plainIdx, chMode, chCfg);
+
+ /* Extract the number of channels per group */
+ numChInGrp[CH_GROUP_FRONT] = plainChMode & 0xF;
+ numChInGrp[CH_GROUP_SIDE] = (plainChMode >> 4) & 0xF;
+ numChInGrp[CH_GROUP_REAR] = (plainChMode >> 8) & 0xF;
+ numChInGrp[CH_GROUP_LFE] = (plainChMode >> 12) & 0xF;
+
+ /* Non-symmetric channels */
+ if ((numChInGrp[CH_GROUP_FRONT] & 0x1) && (plainIdx == CH_PLAIN_NORMAL)) {
+ /* Odd number of front channels -> we have a center channel.
+ In MPEG-4 the center has the index 0. */
+ int mappedIdx = FDK_chMapDescr_getMapValue(mapDescr, (UCHAR)ch, chCfg);
+ offsetTable[CENTER_FRONT_CHANNEL] = (UCHAR)mappedIdx;
+ channelType[mappedIdx] = ACT_FRONT;
+ channelIndices[mappedIdx] = 0;
+ ch += 1;
+ }
+
+ for (grpIdx = 0; grpIdx < (4); grpIdx += 1) {
+ AUDIO_CHANNEL_TYPE type = ACT_NONE;
+ int chMapPos = 0, maxChannels = 0;
+ int chIdx = 0; /* Index of channel within the specific group */
+
+ switch (grpIdx) {
+ case CH_GROUP_FRONT:
+ type = (AUDIO_CHANNEL_TYPE)((plainIdx << 4) | ACT_FRONT);
+ switch (plainIdx) {
+ default:
+ chMapPos = LEFT_FRONT_CHANNEL;
+ chIdx = numChInGrp[grpIdx] & 0x1;
+ break;
+ }
+ maxChannels = 3;
+ break;
+ case CH_GROUP_SIDE:
+ /* Always map side channels to the multipurpose group. */
+ type = (AUDIO_CHANNEL_TYPE)((plainIdx << 4) | ACT_SIDE);
+ if (plainIdx == CH_PLAIN_TOP) {
+ chMapPos = LEFT_SIDE_CHANNEL_TOP;
+ maxChannels = 3;
+ } else {
+ chMapPos = LEFT_MULTIPRPS_CHANNEL;
+ maxChannels = 2;
+ }
+ break;
+ case CH_GROUP_REAR:
+ type = (AUDIO_CHANNEL_TYPE)((plainIdx << 4) | ACT_BACK);
+ if (plainIdx == CH_PLAIN_TOP) {
+ chMapPos = LEFT_REAR_CHANNEL_TOP;
+ maxChannels = 3;
+ } else {
+ chMapPos = LEFT_REAR_CHANNEL;
+ maxChannels = 2;
+ }
+ break;
+ case CH_GROUP_LFE:
+ if (plainIdx == CH_PLAIN_NORMAL) {
+ type = ACT_LFE;
+ chMapPos = LOW_FREQUENCY_CHANNEL;
+ maxChannels = 1;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Map all channels in this group */
+ for (; chIdx < numChInGrp[grpIdx]; chIdx += 1) {
+ int mappedIdx = FDK_chMapDescr_getMapValue(mapDescr, (UCHAR)ch, chCfg);
+ if ((chIdx == maxChannels) || (offsetTable[chMapPos] < 255)) {
+ /* No space left in this channel group! */
+ if (offsetTable[LEFT_MULTIPRPS_CHANNEL] ==
+ 255) { /* Use the multipurpose group: */
+ chMapPos = LEFT_MULTIPRPS_CHANNEL;
+ } else {
+ FDK_ASSERT(0);
+ }
+ }
+ offsetTable[chMapPos] = (UCHAR)mappedIdx;
+ channelType[mappedIdx] = type;
+ channelIndices[mappedIdx] = (UCHAR)chIdx;
+ chMapPos += 1;
+ ch += 1;
+ }
+ }
+ }
+}
+
+/** Private helper function for downmix matrix manipulation that initializes
+ * one row in a given downmix matrix (corresponding to one output channel).
+ * @param [inout] Pointer to fixed-point parts of the downmix matrix.
+ * @param [inout] Pointer to scale factor matrix associated to the downmix
+ *factors.
+ * @param [in] Index of channel (row) to be initialized.
+ * @returns Nothing to return.
+ **/
+static void dmxInitChannel(FIXP_DMX mixFactors[(8)][(8)],
+ INT mixScales[(8)][(8)], const unsigned int outCh) {
+ unsigned int inCh;
+ for (inCh = 0; inCh < (8); inCh += 1) {
+ if (inCh == outCh) {
+ mixFactors[outCh][inCh] = FL2FXCONST_DMX(0.5f);
+ mixScales[outCh][inCh] = 1;
+ } else {
+ mixFactors[outCh][inCh] = FL2FXCONST_DMX(0.0f);
+ mixScales[outCh][inCh] = 0;
+ }
+ }
+}
+
+/** Private helper function for downmix matrix manipulation that does a reset
+ * of one row in a given downmix matrix (corresponding to one output channel).
+ * @param [inout] Pointer to fixed-point parts of the downmix matrix.
+ * @param [inout] Pointer to scale factor matrix associated to the downmix
+ *factors.
+ * @param [in] Index of channel (row) to be cleared/reset.
+ * @returns Nothing to return.
+ **/
+static void dmxClearChannel(FIXP_DMX mixFactors[(8)][(8)],
+ INT mixScales[(8)][(8)], const unsigned int outCh) {
+ FDK_ASSERT((outCh >= 0) && (outCh < (8)));
+ FDKmemclear(&mixFactors[outCh], (8) * sizeof(FIXP_DMX));
+ FDKmemclear(&mixScales[outCh], (8) * sizeof(INT));
+}
+
+/** Private helper function for downmix matrix manipulation that applies a
+ *source channel (row) scaled by a given mix factor to a destination channel
+ *(row) in a given downmix matrix. Existing mix factors of the destination
+ *channel (row) will get overwritten.
+ * @param [inout] Pointer to fixed-point parts of the downmix matrix.
+ * @param [inout] Pointer to scale factor matrix associated to the downmix
+ *factors.
+ * @param [in] Index of source channel (row).
+ * @param [in] Index of destination channel (row).
+ * @param [in] Fixed-point part of mix factor to be applied.
+ * @param [in] Scale factor of mix factor to be applied.
+ * @returns Nothing to return.
+ **/
+static void dmxSetChannel(FIXP_DMX mixFactors[(8)][(8)],
+ INT mixScales[(8)][(8)], const unsigned int dstCh,
+ const unsigned int srcCh, const FIXP_DMX factor,
+ const INT scale) {
+ int ch;
+ for (ch = 0; ch < (8); ch += 1) {
+ if (mixFactors[srcCh][ch] != (FIXP_DMX)0) {
+ mixFactors[dstCh][ch] =
+ FX_DBL2FX_DMX(fMult(mixFactors[srcCh][ch], factor));
+ mixScales[dstCh][ch] = mixScales[srcCh][ch] + scale;
+ }
+ }
+}
+
+/** Private helper function for downmix matrix manipulation that adds a source
+ *channel (row) scaled by a given mix factor to a destination channel (row) in a
+ *given downmix matrix.
+ * @param [inout] Pointer to fixed-point parts of the downmix matrix.
+ * @param [inout] Pointer to scale factor matrix associated to the downmix
+ *factors.
+ * @param [in] Index of source channel (row).
+ * @param [in] Index of destination channel (row).
+ * @param [in] Fixed-point part of mix factor to be applied.
+ * @param [in] Scale factor of mix factor to be applied.
+ * @returns Nothing to return.
+ **/
+static void dmxAddChannel(FIXP_DMX mixFactors[(8)][(8)],
+ INT mixScales[(8)][(8)], const unsigned int dstCh,
+ const unsigned int srcCh, const FIXP_DMX factor,
+ const INT scale) {
+ int ch;
+ for (ch = 0; ch < (8); ch += 1) {
+ FIXP_DBL addFact = fMult(mixFactors[srcCh][ch], factor);
+ if (addFact != (FIXP_DMX)0) {
+ INT newScale = mixScales[srcCh][ch] + scale;
+ if (mixFactors[dstCh][ch] != (FIXP_DMX)0) {
+ if (newScale > mixScales[dstCh][ch]) {
+ mixFactors[dstCh][ch] >>= newScale - mixScales[dstCh][ch];
+ } else {
+ addFact >>= mixScales[dstCh][ch] - newScale;
+ newScale = mixScales[dstCh][ch];
+ }
+ }
+ mixFactors[dstCh][ch] += FX_DBL2FX_DMX(addFact);
+ mixScales[dstCh][ch] = newScale;
+ }
+ }
+}
+
+/** Private function that creates a downmix factor matrix depending on the input
+ and output
+ * configuration, the user parameters as well as the given metadata. This
+ function is the modules
+ * brain and hold all downmix algorithms.
+ * @param [in] Flag that indicates if inChMode holds a real (packed) channel
+ mode or has been converted to a MPEG-4 channel configuration index.
+ * @param [in] Dependent on the inModeIsCfg flag this field hands in a (packed)
+ channel mode or the corresponding MPEG-4 channel configuration index.of the
+ input configuration.
+ * @param [in] The (packed) channel mode of the output configuration.
+ * @param [in] Pointer to structure holding all current user parameter.
+ * @param [in] Pointer to field holding all current meta data.
+ * @param [out] Pointer to fixed-point parts of the downmix matrix. Normalized
+ to one scale factor.
+ * @param [out] The common scale factor of the downmix matrix.
+ * @returns An error code.
+ **/
+static PCMDMX_ERROR getMixFactors(const UCHAR inModeIsCfg,
+ PCM_DMX_CHANNEL_MODE inChMode,
+ const PCM_DMX_CHANNEL_MODE outChMode,
+ const PCM_DMX_USER_PARAMS *pParams,
+ const DMX_BS_META_DATA *pMetaData,
+ FIXP_DMX mixFactors[(8)][(8)],
+ INT *pOutScale) {
+ PCMDMX_ERROR err = PCMDMX_OK;
+ INT mixScales[(8)][(8)];
+ INT maxScale = 0;
+ int numInChannel;
+ int numOutChannel;
+ int dmxMethod;
+ unsigned int outCh, inChCfg = 0;
+ unsigned int valid[(8)] = {0};
+
+ FDK_ASSERT(pMetaData != NULL);
+ FDK_ASSERT(mixFactors != NULL);
+ /* Check on a supported output configuration.
+ Add new one only after extensive testing! */
+ if (!((outChMode == CH_MODE_1_0_0_0) || (outChMode == CH_MODE_2_0_0_0) ||
+ (outChMode == CH_MODE_3_0_2_1) || (outChMode == CH_MODE_3_0_4_1) ||
+ (outChMode == CH_MODE_5_0_2_1))) {
+ FDK_ASSERT(0);
+ }
+
+ if (inModeIsCfg) {
+ /* Convert channel config to channel mode: */
+ inChCfg = (unsigned int)inChMode;
+ switch (inChCfg) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ inChMode = outChModeTable[inChCfg];
+ break;
+ case 11:
+ inChMode = CH_MODE_3_0_3_1;
+ break;
+ case 12:
+ inChMode = CH_MODE_3_0_4_1;
+ break;
+ case 7:
+ case 14:
+ inChMode = CH_MODE_5_0_2_1;
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+ }
+
+ /* Extract the total number of input channels */
+ numInChannel = (inChMode & 0xF) + ((inChMode >> 4) & 0xF) +
+ ((inChMode >> 8) & 0xF) + ((inChMode >> 12) & 0xF);
+ /* Extract the total number of output channels */
+ numOutChannel = (outChMode & 0xF) + ((outChMode >> 4) & 0xF) +
+ ((outChMode >> 8) & 0xF) + ((outChMode >> 12) & 0xF);
+
+ /* MPEG ammendment 4 aka ETSI metadata and fallback mode: */
+
+ /* Create identity DMX matrix: */
+ for (outCh = 0; outCh < (8); outCh += 1) {
+ dmxInitChannel(mixFactors, mixScales, outCh);
+ }
+ if (((inChMode >> 12) & 0xF) == 0) {
+ /* Clear empty or wrongly mapped input channel */
+ dmxClearChannel(mixFactors, mixScales, LOW_FREQUENCY_CHANNEL);
+ }
+
+ /* FIRST STAGE: */
+ if (numInChannel > SIX_CHANNEL) { /* Always use MPEG equations either with
+ meta data or with default values. */
+ FIXP_DMX dMixFactA, dMixFactB;
+ INT dMixScaleA, dMixScaleB;
+ int isValidCfg = TRUE;
+
+ /* Get factors from meta data */
+ dMixFactA = abMixLvlValueTab[pMetaData->dmixIdxA];
+ dMixScaleA = (pMetaData->dmixIdxA == 0) ? 1 : 0;
+ dMixFactB = abMixLvlValueTab[pMetaData->dmixIdxB];
+ dMixScaleB = (pMetaData->dmixIdxB == 0) ? 1 : 0;
+
+ /* Check if input is in the list of supported configurations */
+ switch (inChMode) {
+ case CH_MODE_3_2_1_1: /* chCfg 11 but with side channels */
+ case CH_MODE_3_2_1_0:
+ isValidCfg = FALSE;
+ err = PCMDMX_INVALID_MODE;
+ FDK_FALLTHROUGH;
+ case CH_MODE_3_0_3_1: /* chCfg 11 */
+ /* 6.1ch: C' = C; L' = L; R' = R; LFE' = LFE;
+ Ls' = Ls*dmix_a_idx + Cs*dmix_b_idx;
+ Rs' = Rs*dmix_a_idx + Cs*dmix_b_idx; */
+ dmxClearChannel(
+ mixFactors, mixScales,
+ RIGHT_MULTIPRPS_CHANNEL); /* clear empty input channel */
+ dmxSetChannel(mixFactors, mixScales, LEFT_REAR_CHANNEL,
+ LEFT_REAR_CHANNEL, dMixFactA, dMixScaleA);
+ dmxSetChannel(mixFactors, mixScales, LEFT_REAR_CHANNEL,
+ LEFT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_REAR_CHANNEL,
+ RIGHT_REAR_CHANNEL, dMixFactA, dMixScaleA);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_REAR_CHANNEL,
+ LEFT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB);
+ break;
+ case CH_MODE_3_0_4_1: /* chCfg 12 */
+ /* 7.1ch Surround Back: C' = C; L' = L; R' = R; LFE' = LFE;
+ Ls' = Ls*dmix_a_idx + Lsr*dmix_b_idx;
+ Rs' = Rs*dmix_a_idx + Rsr*dmix_b_idx; */
+ dmxSetChannel(mixFactors, mixScales, LEFT_REAR_CHANNEL,
+ LEFT_REAR_CHANNEL, dMixFactA, dMixScaleA);
+ dmxSetChannel(mixFactors, mixScales, LEFT_REAR_CHANNEL,
+ LEFT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_REAR_CHANNEL,
+ RIGHT_REAR_CHANNEL, dMixFactA, dMixScaleA);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_REAR_CHANNEL,
+ RIGHT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB);
+ break;
+ case CH_MODE_5_0_1_0:
+ case CH_MODE_5_0_1_1:
+ dmxClearChannel(mixFactors, mixScales,
+ RIGHT_REAR_CHANNEL); /* clear empty input channel */
+ dmxSetChannel(mixFactors, mixScales, RIGHT_REAR_CHANNEL,
+ LEFT_REAR_CHANNEL, FL2FXCONST_DMX(0.5f), 1);
+ dmxSetChannel(mixFactors, mixScales, LEFT_REAR_CHANNEL,
+ LEFT_REAR_CHANNEL, FL2FXCONST_DMX(0.5f), 1);
+ FDK_FALLTHROUGH;
+ case CH_MODE_5_2_1_0:
+ isValidCfg = FALSE;
+ err = PCMDMX_INVALID_MODE;
+ FDK_FALLTHROUGH;
+ case CH_MODE_5_0_2_1: /* chCfg 7 || 14 */
+ if (inChCfg == 14) {
+ /* 7.1ch Front Height: C' = C; Ls' = Ls; Rs' = Rs; LFE' = LFE;
+ L' = L*dmix_a_idx + Lv*dmix_b_idx;
+ R' = R*dmix_a_idx + Rv*dmix_b_idx; */
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, dMixFactA, dMixScaleA);
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, dMixFactA, dMixScaleA);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB);
+ } else {
+ /* 7.1ch Front: Ls' = Ls; Rs' = Rs; LFE' = LFE;
+ C' = C + (Lc+Rc)*dmix_a_idx;
+ L' = L + Lc*dmix_b_idx;
+ R' = R + Rc*dmix_b_idx; */
+ dmxSetChannel(mixFactors, mixScales, CENTER_FRONT_CHANNEL,
+ LEFT_MULTIPRPS_CHANNEL, dMixFactA, dMixScaleA);
+ dmxSetChannel(mixFactors, mixScales, CENTER_FRONT_CHANNEL,
+ RIGHT_MULTIPRPS_CHANNEL, dMixFactA, dMixScaleA);
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB);
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.5f), 1);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.5f), 1);
+ }
+ break;
+ default:
+ /* Nothing to do. Just use the identity matrix. */
+ isValidCfg = FALSE;
+ err = PCMDMX_INVALID_MODE;
+ break;
+ }
+
+ /* Add additional DMX gain */
+ if ((isValidCfg == TRUE) &&
+ (pMetaData->dmxGainIdx5 != 0)) { /* Apply DMX gain 5 */
+ FIXP_DMX dmxGain;
+ INT dmxScale;
+ INT sign = (pMetaData->dmxGainIdx5 & 0x40) ? -1 : 1;
+ INT val = pMetaData->dmxGainIdx5 & 0x3F;
+
+ /* 10^(dmx_gain_5/80) */
+ dmxGain = FX_DBL2FX_DMX(
+ fLdPow(FL2FXCONST_DBL(0.830482023721841f), 2, /* log2(10) */
+ (FIXP_DBL)(sign * val * (LONG)FL2FXCONST_DBL(0.0125f)), 0,
+ &dmxScale));
+ /* Currently only positive scale factors supported! */
+ if (dmxScale < 0) {
+ dmxGain >>= -dmxScale;
+ dmxScale = 0;
+ }
+
+ dmxSetChannel(mixFactors, mixScales, CENTER_FRONT_CHANNEL,
+ CENTER_FRONT_CHANNEL, dmxGain, dmxScale);
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, dmxGain, dmxScale);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, dmxGain, dmxScale);
+ dmxSetChannel(mixFactors, mixScales, LEFT_REAR_CHANNEL, LEFT_REAR_CHANNEL,
+ dmxGain, dmxScale);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_REAR_CHANNEL,
+ RIGHT_REAR_CHANNEL, dmxGain, dmxScale);
+ dmxSetChannel(mixFactors, mixScales, LOW_FREQUENCY_CHANNEL,
+ LOW_FREQUENCY_CHANNEL, dmxGain, dmxScale);
+ }
+
+ /* Mark the output channels */
+ valid[CENTER_FRONT_CHANNEL] = 1;
+ valid[LEFT_FRONT_CHANNEL] = 1;
+ valid[RIGHT_FRONT_CHANNEL] = 1;
+ valid[LEFT_REAR_CHANNEL] = 1;
+ valid[RIGHT_REAR_CHANNEL] = 1;
+ valid[LOW_FREQUENCY_CHANNEL] = 1;
+
+ /* Update channel mode for the next stage */
+ inChMode = CH_MODE_3_0_2_1;
+ }
+
+ /* For the X (> 6) to 6 channel downmix we had no choice.
+ To mix from 6 to 2 (or 1) channel(s) we have several possibilities (MPEG
+ DSE | MPEG PCE | ITU | ARIB | DLB). Use profile and the metadata
+ available flags to determine which equation to use: */
+
+#define DMX_METHOD_MPEG_AMD4 1
+#define DMX_METHOD_MPEG_LEGACY 2
+#define DMX_METHOD_ARIB_JAPAN 4
+#define DMX_METHOD_ITU_RECOM 8
+#define DMX_METHOD_CUSTOM 16
+
+ dmxMethod = DMX_METHOD_MPEG_AMD4; /* default */
+
+ if ((pParams->dmxProfile == DMX_PRFL_FORCE_MATRIX_MIX) &&
+ (pMetaData->typeFlags & TYPE_PCE_DATA)) {
+ dmxMethod = DMX_METHOD_MPEG_LEGACY;
+ } else if (!(pMetaData->typeFlags &
+ (TYPE_DSE_CLEV_DATA | TYPE_DSE_SLEV_DATA))) {
+ switch (pParams->dmxProfile) {
+ default:
+ case DMX_PRFL_STANDARD:
+ /* dmxMethod = DMX_METHOD_MPEG_AMD4; */
+ break;
+ case DMX_PRFL_MATRIX_MIX:
+ case DMX_PRFL_FORCE_MATRIX_MIX:
+ if (pMetaData->typeFlags & TYPE_PCE_DATA) {
+ dmxMethod = DMX_METHOD_MPEG_LEGACY;
+ }
+ break;
+ case DMX_PRFL_ARIB_JAPAN:
+ dmxMethod = DMX_METHOD_ARIB_JAPAN;
+ break;
+ }
+ }
+
+ /* SECOND STAGE: */
+ if (numOutChannel <= TWO_CHANNEL) {
+ /* Create DMX matrix according to input configuration */
+ switch (inChMode) {
+ case CH_MODE_2_0_0_0: /* chCfg 2 */
+ /* Apply the dual channel mode. */
+ switch (pParams->dualChannelMode) {
+ case CH1_MODE: /* L' = 0.707 * Ch1;
+ R' = 0.707 * Ch1; */
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0);
+ break;
+ case CH2_MODE: /* L' = 0.707 * Ch2;
+ R' = 0.707 * Ch2; */
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0);
+ break;
+ case MIXED_MODE: /* L' = 0.5*Ch1 + 0.5*Ch2;
+ R' = 0.5*Ch1 + 0.5*Ch2; */
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.5f), 0);
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.5f), 0);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.5f), 0);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.5f), 0);
+ break;
+ default:
+ case STEREO_MODE:
+ /* Nothing to do */
+ break;
+ }
+ break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ * - - - - - - - - - - - - - - - - - - - */
+ case CH_MODE_2_0_1_0: {
+ FIXP_DMX sMixLvl;
+ if (dmxMethod == DMX_METHOD_ARIB_JAPAN) {
+ /* L' = 0.707*L + 0.5*S; R' = 0.707*R + 0.5*S; */
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0);
+ sMixLvl = FL2FXCONST_DMX(0.5f);
+ } else { /* L' = L + 0.707*S; R' = R + 0.707*S; */
+ sMixLvl = FL2FXCONST_DMX(0.707f);
+ }
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_REAR_CHANNEL, sMixLvl, 0);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ LEFT_REAR_CHANNEL, sMixLvl, 0);
+ } break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ * - - - - - - - - - - - - - - - - - - - */
+ case CH_MODE_3_0_0_0: /* chCfg 3 */
+ {
+ FIXP_DMX cMixLvl;
+ if (dmxMethod == DMX_METHOD_ARIB_JAPAN) {
+ /* L' = 0.707*L + 0.5*C; R' = 0.707*R + 0.5*C; */
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0);
+ cMixLvl = FL2FXCONST_DMX(0.5f);
+ } else { /* L' = L + 0.707*C; R' = R + 0.707*C; */
+ cMixLvl = FL2FXCONST_DMX(0.707f);
+ }
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ CENTER_FRONT_CHANNEL, cMixLvl, 0);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ CENTER_FRONT_CHANNEL, cMixLvl, 0);
+ } break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ * - - - - - - - - - - - - - - - - - - - */
+ case CH_MODE_3_0_1_0: /* chCfg 4 */
+ {
+ FIXP_DMX csMixLvl;
+ if (dmxMethod == DMX_METHOD_ARIB_JAPAN) {
+ /* L' = 0.707*L + 0.5*C + 0.5*S; R' = 0.707*R + 0.5*C + 0.5*S; */
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0);
+ csMixLvl = FL2FXCONST_DMX(0.5f);
+ } else { /* L' = L + 0.707*C + 0.707*S;
+ R' = R + 0.707*C + 0.707*S; */
+ csMixLvl = FL2FXCONST_DMX(0.707f);
+ }
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ CENTER_FRONT_CHANNEL, csMixLvl, 0);
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_REAR_CHANNEL, csMixLvl, 0);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ CENTER_FRONT_CHANNEL, csMixLvl, 0);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ LEFT_REAR_CHANNEL, csMixLvl, 0);
+ } break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ * - - - - - - - - - - - - - - - - - - - */
+ case CH_MODE_3_0_2_0: /* chCfg 5 */
+ case CH_MODE_3_0_2_1: /* chCfg 6 */
+ {
+ switch (dmxMethod) {
+ default:
+ case DMX_METHOD_MPEG_AMD4: {
+ FIXP_DMX cMixLvl, sMixLvl, lMixLvl;
+ INT cMixScale, sMixScale, lMixScale;
+
+ /* Get factors from meta data */
+ cMixLvl = abMixLvlValueTab[pMetaData->cLevIdx];
+ cMixScale = (pMetaData->cLevIdx == 0) ? 1 : 0;
+ sMixLvl = abMixLvlValueTab[pMetaData->sLevIdx];
+ sMixScale = (pMetaData->sLevIdx == 0) ? 1 : 0;
+ lMixLvl = lfeMixLvlValueTab[pMetaData->dmixIdxLfe];
+ if (pMetaData->dmixIdxLfe <= 1) {
+ lMixScale = 2;
+ } else if (pMetaData->dmixIdxLfe <= 5) {
+ lMixScale = 1;
+ } else {
+ lMixScale = 0;
+ }
+ /* Setup the DMX matrix */
+ if ((pParams->pseudoSurrMode == FORCE_PS_DMX) ||
+ ((pParams->pseudoSurrMode == AUTO_PS_DMX) &&
+ (pMetaData->pseudoSurround ==
+ 1))) { /* L' = L + C*clev - (Ls+Rs)*slev + LFE*lflev;
+ R' = R + C*clev + (Ls+Rs)*slev + LFE*lflev; */
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ CENTER_FRONT_CHANNEL, cMixLvl, cMixScale);
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_REAR_CHANNEL, -sMixLvl, sMixScale);
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ RIGHT_REAR_CHANNEL, -sMixLvl, sMixScale);
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LOW_FREQUENCY_CHANNEL, lMixLvl, lMixScale);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ CENTER_FRONT_CHANNEL, cMixLvl, cMixScale);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ LEFT_REAR_CHANNEL, sMixLvl, sMixScale);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_REAR_CHANNEL, sMixLvl, sMixScale);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ LOW_FREQUENCY_CHANNEL, lMixLvl, lMixScale);
+ } else { /* L' = L + C*clev + Ls*slev + LFE*llev;
+ R' = R + C*clev + Rs*slev + LFE*llev; */
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ CENTER_FRONT_CHANNEL, cMixLvl, cMixScale);
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_REAR_CHANNEL, sMixLvl, sMixScale);
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LOW_FREQUENCY_CHANNEL, lMixLvl, lMixScale);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ CENTER_FRONT_CHANNEL, cMixLvl, cMixScale);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_REAR_CHANNEL, sMixLvl, sMixScale);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ LOW_FREQUENCY_CHANNEL, lMixLvl, lMixScale);
+ }
+
+ /* Add additional DMX gain */
+ if (pMetaData->dmxGainIdx2 != 0) { /* Apply DMX gain 2 */
+ FIXP_DMX dmxGain;
+ INT dmxScale;
+ INT sign = (pMetaData->dmxGainIdx2 & 0x40) ? -1 : 1;
+ INT val = pMetaData->dmxGainIdx2 & 0x3F;
+
+ /* 10^(dmx_gain_2/80) */
+ dmxGain = FX_DBL2FX_DMX(
+ fLdPow(FL2FXCONST_DBL(0.830482023721841f), 2, /* log2(10) */
+ (FIXP_DBL)(sign * val * (LONG)FL2FXCONST_DBL(0.0125f)),
+ 0, &dmxScale));
+ /* Currently only positive scale factors supported! */
+ if (dmxScale < 0) {
+ dmxGain >>= -dmxScale;
+ dmxScale = 0;
+ }
+
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, dmxGain, dmxScale);
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, dmxGain, dmxScale);
+ }
+ } break;
+ case DMX_METHOD_ARIB_JAPAN:
+ case DMX_METHOD_MPEG_LEGACY: {
+ FIXP_DMX flev, clev, slevLL, slevLR, slevRL, slevRR;
+ FIXP_DMX mtrxMixDwnCoef =
+ mpegMixDownIdx2Coef[pMetaData->matrixMixdownIdx];
+
+ if ((pParams->pseudoSurrMode == FORCE_PS_DMX) ||
+ ((pParams->pseudoSurrMode == AUTO_PS_DMX) &&
+ (pMetaData->pseudoSurround == 1))) {
+ if (dmxMethod == DMX_METHOD_ARIB_JAPAN) {
+ /* 3/2 input: L' = 0.707 * [L+0.707*C-k*Ls-k*Rs];
+ R' = 0.707 * [R+0.707*C+k*Ls+k*Rs]; */
+ flev = mpegMixDownIdx2Coef[0]; /* a = 0.707 */
+ } else { /* 3/2 input: L' = (1.707+2*A)^-1 *
+ [L+0.707*C-A*Ls-A*Rs]; R' = (1.707+2*A)^-1 *
+ [R+0.707*C+A*Ls+A*Rs]; */
+ flev = mpegMixDownIdx2PreFact[1][pMetaData->matrixMixdownIdx];
+ }
+ slevRR = slevRL = FX_DBL2FX_DMX(fMult(flev, mtrxMixDwnCoef));
+ slevLL = slevLR = -slevRL;
+ } else {
+ if (dmxMethod == DMX_METHOD_ARIB_JAPAN) {
+ /* 3/2 input: L' = 0.707 * [L+0.707*C+k*Ls];
+ R' = 0.707 * [R+0.707*C+k*Rs]; */
+ flev = mpegMixDownIdx2Coef[0]; /* a = 0.707 */
+ } else { /* 3/2 input: L' = (1.707+A)^-1 * [L+0.707*C+A*Ls];
+ R' = (1.707+A)^-1 * [R+0.707*C+A*Rs]; */
+ flev = mpegMixDownIdx2PreFact[0][pMetaData->matrixMixdownIdx];
+ }
+ slevRR = slevLL = FX_DBL2FX_DMX(fMult(flev, mtrxMixDwnCoef));
+ slevLR = slevRL = (FIXP_DMX)0;
+ }
+ /* common factor */
+ clev =
+ FX_DBL2FX_DMX(fMult(flev, mpegMixDownIdx2Coef[0] /* 0.707 */));
+
+ dmxSetChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, flev, 0);
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ CENTER_FRONT_CHANNEL, clev, 0);
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ LEFT_REAR_CHANNEL, slevLL, 0);
+ dmxAddChannel(mixFactors, mixScales, LEFT_FRONT_CHANNEL,
+ RIGHT_REAR_CHANNEL, slevLR, 0);
+
+ dmxSetChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, flev, 0);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ CENTER_FRONT_CHANNEL, clev, 0);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ LEFT_REAR_CHANNEL, slevRL, 0);
+ dmxAddChannel(mixFactors, mixScales, RIGHT_FRONT_CHANNEL,
+ RIGHT_REAR_CHANNEL, slevRR, 0);
+ } break;
+ } /* switch (dmxMethod) */
+ } break;
+ default:
+ /* This configuration does not fit to any known downmix equation! */
+ err = PCMDMX_INVALID_MODE;
+ break;
+ } /* switch (inChMode) */
+
+ /* Mark the output channels */
+ FDKmemclear(valid, (8) * sizeof(unsigned int));
+ valid[LEFT_FRONT_CHANNEL] = 1;
+ valid[RIGHT_FRONT_CHANNEL] = 1;
+ }
+
+ if (numOutChannel == ONE_CHANNEL) {
+ FIXP_DMX monoMixLevel;
+ INT monoMixScale = 0;
+
+ dmxClearChannel(mixFactors, mixScales,
+ CENTER_FRONT_CHANNEL); /* C is not in the mix */
+
+ if (dmxMethod ==
+ DMX_METHOD_MPEG_LEGACY) { /* C' = (3+2*A)^-1 * [C+L+R+A*Ls+A+Rs]; */
+ monoMixLevel = mpegMixDownIdx2PreFact[2][pMetaData->matrixMixdownIdx];
+
+ mixFactors[CENTER_FRONT_CHANNEL][CENTER_FRONT_CHANNEL] = monoMixLevel;
+ mixFactors[CENTER_FRONT_CHANNEL][LEFT_FRONT_CHANNEL] = monoMixLevel;
+ mixFactors[CENTER_FRONT_CHANNEL][RIGHT_FRONT_CHANNEL] = monoMixLevel;
+ monoMixLevel = FX_DBL2FX_DMX(fMult(
+ monoMixLevel, mpegMixDownIdx2Coef[pMetaData->matrixMixdownIdx]));
+ mixFactors[CENTER_FRONT_CHANNEL][LEFT_REAR_CHANNEL] = monoMixLevel;
+ mixFactors[CENTER_FRONT_CHANNEL][RIGHT_REAR_CHANNEL] = monoMixLevel;
+ } else {
+ switch (dmxMethod) {
+ case DMX_METHOD_MPEG_AMD4:
+ /* C' = L + R; */
+ monoMixLevel = FL2FXCONST_DMX(0.5f);
+ monoMixScale = 1;
+ break;
+ default:
+ /* C' = 0.5*L + 0.5*R; */
+ monoMixLevel = FL2FXCONST_DMX(0.5f);
+ monoMixScale = 0;
+ break;
+ }
+ dmxSetChannel(mixFactors, mixScales, CENTER_FRONT_CHANNEL,
+ LEFT_FRONT_CHANNEL, monoMixLevel, monoMixScale);
+ dmxAddChannel(mixFactors, mixScales, CENTER_FRONT_CHANNEL,
+ RIGHT_FRONT_CHANNEL, monoMixLevel, monoMixScale);
+ }
+
+ /* Mark the output channel */
+ FDKmemclear(valid, (8) * sizeof(unsigned int));
+ valid[CENTER_FRONT_CHANNEL] = 1;
+ }
+
+#define MAX_SEARCH_START_VAL (-7)
+
+ {
+ LONG chSum[(8)];
+ INT chSumMax = MAX_SEARCH_START_VAL;
+
+ /* Determine the current maximum scale factor */
+ for (outCh = 0; outCh < (8); outCh += 1) {
+ if (valid[outCh] != 0) {
+ unsigned int inCh;
+ for (inCh = 0; inCh < (8); inCh += 1) {
+ if (mixScales[outCh][inCh] > maxScale) { /* Store the new maximum */
+ maxScale = mixScales[outCh][inCh];
+ }
+ }
+ }
+ }
+
+ /* Individualy analyse output chanal levels */
+ for (outCh = 0; outCh < (8); outCh += 1) {
+ chSum[outCh] = MAX_SEARCH_START_VAL;
+ if (valid[outCh] != 0) {
+ int ovrflwProtScale = 0;
+ unsigned int inCh;
+
+ /* Accumulate all factors for each output channel */
+ chSum[outCh] = 0;
+ for (inCh = 0; inCh < (8); inCh += 1) {
+ SHORT addFact = FX_DMX2SHRT(mixFactors[outCh][inCh]);
+ if (mixScales[outCh][inCh] <= maxScale) {
+ addFact >>= maxScale - mixScales[outCh][inCh];
+ } else {
+ addFact <<= mixScales[outCh][inCh] - maxScale;
+ }
+ chSum[outCh] += addFact;
+ }
+ if (chSum[outCh] > (LONG)MAXVAL_SGL) {
+ while (chSum[outCh] > (LONG)MAXVAL_SGL) {
+ ovrflwProtScale += 1;
+ chSum[outCh] >>= 1;
+ }
+ } else if (chSum[outCh] > 0) {
+ while ((chSum[outCh] << 1) <= (LONG)MAXVAL_SGL) {
+ ovrflwProtScale -= 1;
+ chSum[outCh] <<= 1;
+ }
+ }
+ /* Store the differential scaling in the same array */
+ chSum[outCh] = ovrflwProtScale;
+ }
+ }
+
+ for (outCh = 0; outCh < (8); outCh += 1) {
+ if ((valid[outCh] != 0) &&
+ (chSum[outCh] > chSumMax)) { /* Store the new maximum */
+ chSumMax = chSum[outCh];
+ }
+ }
+ maxScale = fMax(maxScale + chSumMax, 0);
+
+ /* Normalize all factors */
+ for (outCh = 0; outCh < (8); outCh += 1) {
+ if (valid[outCh] != 0) {
+ unsigned int inCh;
+ for (inCh = 0; inCh < (8); inCh += 1) {
+ if (mixFactors[outCh][inCh] != (FIXP_DMX)0) {
+ if (mixScales[outCh][inCh] <= maxScale) {
+ mixFactors[outCh][inCh] >>= maxScale - mixScales[outCh][inCh];
+ } else {
+ mixFactors[outCh][inCh] <<= mixScales[outCh][inCh] - maxScale;
+ }
+ mixScales[outCh][inCh] = maxScale;
+ }
+ }
+ }
+ }
+ }
+
+ /* return the scale factor */
+ *pOutScale = maxScale;
+
+ return (err);
+}
+
+/** Open and initialize an instance of the PCM downmix module
+ * @param [out] Pointer to a buffer receiving the handle of the new instance.
+ * @returns Returns an error code.
+ **/
+PCMDMX_ERROR pcmDmx_Open(HANDLE_PCM_DOWNMIX *pSelf) {
+ HANDLE_PCM_DOWNMIX self;
+
+ if (pSelf == NULL) {
+ return (PCMDMX_INVALID_HANDLE);
+ }
+
+ *pSelf = NULL;
+
+ self = (HANDLE_PCM_DOWNMIX)GetPcmDmxInstance(0);
+ if (self == NULL) {
+ return (PCMDMX_OUT_OF_MEMORY);
+ }
+
+ /* Reset the full instance */
+ pcmDmx_Reset(self, PCMDMX_RESET_FULL);
+
+ *pSelf = self;
+
+ return (PCMDMX_OK);
+}
+
+/** Reset all static values like e.g. mixdown coefficients.
+ * @param [in] Handle of PCM downmix module instance.
+ * @param [in] Flags telling which parts of the module shall be reset.
+ * @returns Returns an error code.
+ **/
+PCMDMX_ERROR pcmDmx_Reset(HANDLE_PCM_DOWNMIX self, UINT flags) {
+ if (self == NULL) {
+ return (PCMDMX_INVALID_HANDLE);
+ }
+
+ if (flags & PCMDMX_RESET_PARAMS) {
+ PCM_DMX_USER_PARAMS *pParams = &self->userParams;
+
+ pParams->dualChannelMode = STEREO_MODE;
+ pParams->pseudoSurrMode = NEVER_DO_PS_DMX;
+ pParams->numOutChannelsMax = (6);
+ pParams->numOutChannelsMin = (0);
+ pParams->frameDelay = 0;
+ pParams->expiryFrame = (0);
+
+ self->applyProcessing = 0;
+ }
+
+ if (flags & PCMDMX_RESET_BS_DATA) {
+ int slot;
+ /* Init all slots with a default set */
+ for (slot = 0; slot <= (1); slot += 1) {
+ FDKmemcpy(&self->bsMetaData[slot], &dfltMetaData,
+ sizeof(DMX_BS_META_DATA));
+ }
+ }
+
+ return (PCMDMX_OK);
+}
+
+/** Set one parameter for one instance of the PCM downmix module.
+ * @param [in] Handle of PCM downmix module instance.
+ * @param [in] Parameter to be set.
+ * @param [in] Parameter value.
+ * @returns Returns an error code.
+ **/
+PCMDMX_ERROR pcmDmx_SetParam(HANDLE_PCM_DOWNMIX self, const PCMDMX_PARAM param,
+ const INT value) {
+ switch (param) {
+ case DMX_PROFILE_SETTING:
+ switch ((DMX_PROFILE_TYPE)value) {
+ case DMX_PRFL_STANDARD:
+ case DMX_PRFL_MATRIX_MIX:
+ case DMX_PRFL_FORCE_MATRIX_MIX:
+ case DMX_PRFL_ARIB_JAPAN:
+ break;
+ default:
+ return (PCMDMX_UNABLE_TO_SET_PARAM);
+ }
+ if (self == NULL) return (PCMDMX_INVALID_HANDLE);
+ self->userParams.dmxProfile = (DMX_PROFILE_TYPE)value;
+ break;
+
+ case DMX_BS_DATA_EXPIRY_FRAME:
+ if (self == NULL) return (PCMDMX_INVALID_HANDLE);
+ self->userParams.expiryFrame = (value > 0) ? (UINT)value : 0;
+ break;
+
+ case DMX_BS_DATA_DELAY:
+ if ((value > (1)) || (value < 0)) {
+ return (PCMDMX_UNABLE_TO_SET_PARAM);
+ }
+ if (self == NULL) {
+ return (PCMDMX_INVALID_HANDLE);
+ }
+ self->userParams.frameDelay = (UCHAR)value;
+ break;
+
+ case MIN_NUMBER_OF_OUTPUT_CHANNELS:
+ switch (value) { /* supported output channels */
+ case -1:
+ case 0:
+ case ONE_CHANNEL:
+ case TWO_CHANNEL:
+ case SIX_CHANNEL:
+ case EIGHT_CHANNEL:
+ break;
+ default:
+ return (PCMDMX_UNABLE_TO_SET_PARAM);
+ }
+ if (self == NULL) return (PCMDMX_INVALID_HANDLE);
+ /* Store the new value */
+ self->userParams.numOutChannelsMin = (value > 0) ? (SHORT)value : -1;
+ if ((value > 0) && (self->userParams.numOutChannelsMax > 0) &&
+ (value > self->userParams
+ .numOutChannelsMax)) { /* MIN > MAX would be an invalid
+ state. Thus set MAX = MIN in
+ this case. */
+ self->userParams.numOutChannelsMax = self->userParams.numOutChannelsMin;
+ }
+ break;
+
+ case MAX_NUMBER_OF_OUTPUT_CHANNELS:
+ switch (value) { /* supported output channels */
+ case -1:
+ case 0:
+ case ONE_CHANNEL:
+ case TWO_CHANNEL:
+ case SIX_CHANNEL:
+ case EIGHT_CHANNEL:
+ break;
+ default:
+ return (PCMDMX_UNABLE_TO_SET_PARAM);
+ }
+ if (self == NULL) return (PCMDMX_INVALID_HANDLE);
+ /* Store the new value */
+ self->userParams.numOutChannelsMax = (value > 0) ? (SHORT)value : -1;
+ if ((value > 0) &&
+ (value < self->userParams
+ .numOutChannelsMin)) { /* MAX < MIN would be an invalid
+ state. Thus set MIN = MAX in
+ this case. */
+ self->userParams.numOutChannelsMin = self->userParams.numOutChannelsMax;
+ }
+ break;
+
+ case DMX_DUAL_CHANNEL_MODE:
+ switch ((DUAL_CHANNEL_MODE)value) {
+ case STEREO_MODE:
+ case CH1_MODE:
+ case CH2_MODE:
+ case MIXED_MODE:
+ break;
+ default:
+ return (PCMDMX_UNABLE_TO_SET_PARAM);
+ }
+ if (self == NULL) return (PCMDMX_INVALID_HANDLE);
+ self->userParams.dualChannelMode = (DUAL_CHANNEL_MODE)value;
+ self->applyProcessing = ((DUAL_CHANNEL_MODE)value != STEREO_MODE)
+ ? 1
+ : 0; /* Force processing if necessary. */
+ break;
+
+ case DMX_PSEUDO_SURROUND_MODE:
+ switch ((PSEUDO_SURROUND_MODE)value) {
+ case NEVER_DO_PS_DMX:
+ case AUTO_PS_DMX:
+ case FORCE_PS_DMX:
+ break;
+ default:
+ return (PCMDMX_UNABLE_TO_SET_PARAM);
+ }
+ if (self == NULL) return (PCMDMX_INVALID_HANDLE);
+ self->userParams.pseudoSurrMode = (PSEUDO_SURROUND_MODE)value;
+ break;
+
+ default:
+ return (PCMDMX_UNKNOWN_PARAM);
+ }
+
+ return (PCMDMX_OK);
+}
+
+/** Get one parameter value of one PCM downmix module instance.
+ * @param [in] Handle of PCM downmix module instance.
+ * @param [in] Parameter to be set.
+ * @param [out] Pointer to buffer receiving the parameter value.
+ * @returns Returns an error code.
+ **/
+PCMDMX_ERROR pcmDmx_GetParam(HANDLE_PCM_DOWNMIX self, const PCMDMX_PARAM param,
+ INT *const pValue) {
+ PCM_DMX_USER_PARAMS *pUsrParams;
+
+ if ((self == NULL) || (pValue == NULL)) {
+ return (PCMDMX_INVALID_HANDLE);
+ }
+ pUsrParams = &self->userParams;
+
+ switch (param) {
+ case DMX_PROFILE_SETTING:
+ *pValue = (INT)pUsrParams->dmxProfile;
+ break;
+ case DMX_BS_DATA_EXPIRY_FRAME:
+ *pValue = (INT)pUsrParams->expiryFrame;
+ break;
+ case DMX_BS_DATA_DELAY:
+ *pValue = (INT)pUsrParams->frameDelay;
+ break;
+ case MIN_NUMBER_OF_OUTPUT_CHANNELS:
+ *pValue = (INT)pUsrParams->numOutChannelsMin;
+ break;
+ case MAX_NUMBER_OF_OUTPUT_CHANNELS:
+ *pValue = (INT)pUsrParams->numOutChannelsMax;
+ break;
+ case DMX_DUAL_CHANNEL_MODE:
+ *pValue = (INT)pUsrParams->dualChannelMode;
+ break;
+ case DMX_PSEUDO_SURROUND_MODE:
+ *pValue = (INT)pUsrParams->pseudoSurrMode;
+ break;
+ default:
+ return (PCMDMX_UNKNOWN_PARAM);
+ }
+
+ return (PCMDMX_OK);
+}
+
+/*
+ * Read DMX meta-data from a data stream element.
+ */
+PCMDMX_ERROR pcmDmx_Parse(HANDLE_PCM_DOWNMIX self, HANDLE_FDK_BITSTREAM hBs,
+ UINT ancDataBits, int isMpeg2) {
+ PCMDMX_ERROR errorStatus = PCMDMX_OK;
+
+#define MAX_DSE_ANC_BYTES (16) /* 15 bytes */
+#define ANC_DATA_SYNC_BYTE (0xBC) /* ancillary data sync byte. */
+
+ DMX_BS_META_DATA *pBsMetaData;
+
+ int skip4Dmx = 0, skip4Ext = 0;
+ int dmxLvlAvail = 0, extDataAvail = 0;
+ UINT foundNewData = 0;
+ UINT minAncBits = ((isMpeg2) ? 5 : 3) * 8;
+
+ if ((self == NULL) || (hBs == NULL)) {
+ return (PCMDMX_INVALID_HANDLE);
+ }
+
+ /* sanity checks */
+ if ((ancDataBits < minAncBits) || (ancDataBits > FDKgetValidBits(hBs))) {
+ return (PCMDMX_CORRUPT_ANC_DATA);
+ }
+
+ pBsMetaData = &self->bsMetaData[0];
+
+ if (isMpeg2) {
+ /* skip DVD ancillary data */
+ FDKpushFor(hBs, 16);
+ }
+
+ /* check sync word */
+ if (FDKreadBits(hBs, 8) != ANC_DATA_SYNC_BYTE) {
+ return (PCMDMX_CORRUPT_ANC_DATA);
+ }
+
+ /* skip MPEG audio type and Dolby surround mode */
+ FDKpushFor(hBs, 4);
+
+ if (isMpeg2) {
+ /* int numAncBytes = */ FDKreadBits(hBs, 4);
+ /* advanced dynamic range control */
+ if (FDKreadBit(hBs)) skip4Dmx += 24;
+ /* dialog normalization */
+ if (FDKreadBit(hBs)) skip4Dmx += 8;
+ /* reproduction_level */
+ if (FDKreadBit(hBs)) skip4Dmx += 8;
+ } else {
+ FDKpushFor(hBs, 2); /* drc presentation mode */
+ pBsMetaData->pseudoSurround = (SCHAR)FDKreadBit(hBs);
+ FDKpushFor(hBs, 4); /* reserved bits */
+ }
+
+ /* downmixing levels MPEGx status */
+ dmxLvlAvail = FDKreadBit(hBs);
+
+ if (isMpeg2) {
+ /* scale factor CRC status */
+ if (FDKreadBit(hBs)) skip4Ext += 16;
+ } else {
+ /* ancillary data extension status */
+ extDataAvail = FDKreadBit(hBs);
+ }
+
+ /* audio coding and compression status */
+ if (FDKreadBit(hBs)) skip4Ext += 16;
+ /* coarse grain timecode status */
+ if (FDKreadBit(hBs)) skip4Ext += 16;
+ /* fine grain timecode status */
+ if (FDKreadBit(hBs)) skip4Ext += 16;
+
+ /* skip the useless data to get to the DMX levels */
+ FDKpushFor(hBs, skip4Dmx);
+
+ /* downmix_levels_MPEGX */
+ if (dmxLvlAvail) {
+ if (FDKreadBit(hBs)) { /* center_mix_level_on */
+ pBsMetaData->cLevIdx = (UCHAR)FDKreadBits(hBs, 3);
+ foundNewData |= TYPE_DSE_CLEV_DATA;
+ } else {
+ FDKreadBits(hBs, 3);
+ }
+ if (FDKreadBit(hBs)) { /* surround_mix_level_on */
+ pBsMetaData->sLevIdx = (UCHAR)FDKreadBits(hBs, 3);
+ foundNewData |= TYPE_DSE_SLEV_DATA;
+ } else {
+ FDKreadBits(hBs, 3);
+ }
+ }
+
+ /* skip the useless data to get to the ancillary data extension */
+ FDKpushFor(hBs, skip4Ext);
+
+ /* anc data extension (MPEG-4 only) */
+ if (extDataAvail) {
+ int extDmxLvlSt, extDmxGainSt, extDmxLfeSt;
+
+ FDKreadBit(hBs); /* reserved bit */
+ extDmxLvlSt = FDKreadBit(hBs);
+ extDmxGainSt = FDKreadBit(hBs);
+ extDmxLfeSt = FDKreadBit(hBs);
+ FDKreadBits(hBs, 4); /* reserved bits */
+
+ if (extDmxLvlSt) {
+ pBsMetaData->dmixIdxA = (UCHAR)FDKreadBits(hBs, 3);
+ pBsMetaData->dmixIdxB = (UCHAR)FDKreadBits(hBs, 3);
+ FDKreadBits(hBs, 2); /* reserved bits */
+ foundNewData |= TYPE_DSE_DMIX_AB_DATA;
+ }
+ if (extDmxGainSt) {
+ pBsMetaData->dmxGainIdx5 = (UCHAR)FDKreadBits(hBs, 7);
+ FDKreadBit(hBs); /* reserved bit */
+ pBsMetaData->dmxGainIdx2 = (UCHAR)FDKreadBits(hBs, 7);
+ FDKreadBit(hBs); /* reserved bit */
+ foundNewData |= TYPE_DSE_DMX_GAIN_DATA;
+ }
+ if (extDmxLfeSt) {
+ pBsMetaData->dmixIdxLfe = (UCHAR)FDKreadBits(hBs, 4);
+ FDKreadBits(hBs, 4); /* reserved bits */
+ foundNewData |= TYPE_DSE_DMIX_LFE_DATA;
+ }
+ }
+
+ /* final sanity check on the amount of read data */
+ if ((INT)FDKgetValidBits(hBs) < 0) {
+ errorStatus = PCMDMX_CORRUPT_ANC_DATA;
+ }
+
+ if ((errorStatus == PCMDMX_OK) && (foundNewData != 0)) {
+ /* announce new data */
+ pBsMetaData->typeFlags |= foundNewData;
+ /* reset expiry counter */
+ pBsMetaData->expiryCount = 0;
+ }
+
+ return (errorStatus);
+}
+
+/*
+ * Read DMX meta-data from a data stream element.
+ */
+PCMDMX_ERROR pcmDmx_ReadDvbAncData(HANDLE_PCM_DOWNMIX self, UCHAR *pAncDataBuf,
+ UINT ancDataBytes, int isMpeg2) {
+ PCMDMX_ERROR errorStatus = PCMDMX_OK;
+ FDK_BITSTREAM bs;
+ HANDLE_FDK_BITSTREAM hBs = &bs;
+
+ if (self == NULL) {
+ return (PCMDMX_INVALID_HANDLE);
+ }
+
+ /* sanity checks */
+ if ((pAncDataBuf == NULL) || (ancDataBytes == 0)) {
+ return (PCMDMX_CORRUPT_ANC_DATA);
+ }
+
+ FDKinitBitStream(hBs, pAncDataBuf, MAX_DSE_ANC_BYTES, ancDataBytes * 8,
+ BS_READER);
+
+ errorStatus = pcmDmx_Parse(self, hBs, ancDataBytes * 8, isMpeg2);
+
+ return (errorStatus);
+}
+
+/** Set the matrix mixdown information extracted from the PCE of an AAC
+ *bitstream. Note: Call only if matrix_mixdown_idx_present is true.
+ * @param [in] Handle of PCM downmix module instance.
+ * @param [in] The 2 bit matrix mixdown index extracted from PCE.
+ * @param [in] The pseudo surround enable flag extracted from PCE.
+ * @returns Returns an error code.
+ **/
+PCMDMX_ERROR pcmDmx_SetMatrixMixdownFromPce(HANDLE_PCM_DOWNMIX self,
+ int matrixMixdownPresent,
+ int matrixMixdownIdx,
+ int pseudoSurroundEnable) {
+ if (self == NULL) {
+ return (PCMDMX_INVALID_HANDLE);
+ }
+
+ {
+ DMX_BS_META_DATA *pBsMetaData = &self->bsMetaData[0];
+
+ if (matrixMixdownPresent) {
+ pBsMetaData->pseudoSurround = (pseudoSurroundEnable) ? 1 : 0;
+ pBsMetaData->matrixMixdownIdx = matrixMixdownIdx & 0x03;
+ pBsMetaData->typeFlags |= TYPE_PCE_DATA;
+ /* Reset expiry counter */
+ pBsMetaData->expiryCount = 0;
+ }
+ }
+
+ return (PCMDMX_OK);
+}
+
+/** Apply down or up mixing.
+ * @param [in] Handle of PCM downmix module instance.
+ * @param [inout] Pointer to buffer that hold the time domain signal.
+ * @param [in] Pointer where the amount of output samples is returned into.
+ * @param [in] Size of pPcmBuf.
+ * @param [inout] Pointer where the amount of output channels is returned into.
+ * @param [in] Input and output samples are processed interleaved.
+ * @param [inout] Array where the corresponding channel type for each output
+ *audio channel is stored into.
+ * @param [inout] Array where the corresponding channel type index for each
+ *output audio channel is stored into.
+ * @param [in] Array containing the out channel mapping to be used (From MPEG
+ *PCE ordering to whatever is required).
+ * @param [out] Pointer on a field receiving the scale factor that has to be
+ *applied on all samples afterwards. If the handed pointer is NULL scaling is
+ *done internally.
+ * @returns Returns an error code.
+ **/
+PCMDMX_ERROR pcmDmx_ApplyFrame(HANDLE_PCM_DOWNMIX self, DMX_PCM *pPcmBuf,
+ const int pcmBufSize, UINT frameSize,
+ INT *nChannels, INT fInterleaved,
+ AUDIO_CHANNEL_TYPE channelType[],
+ UCHAR channelIndices[],
+ const FDK_channelMapDescr *const mapDescr,
+ INT *pDmxOutScale) {
+ PCM_DMX_USER_PARAMS *pParam = NULL;
+ PCMDMX_ERROR errorStatus = PCMDMX_OK;
+ DUAL_CHANNEL_MODE dualChannelMode;
+ PCM_DMX_CHANNEL_MODE inChMode;
+ PCM_DMX_CHANNEL_MODE outChMode;
+ INT devNull; /* Just a dummy to avoid a lot of branches in the code */
+ int numOutChannels, numInChannels;
+ int inStride, outStride, offset;
+ int dmxMaxScale, dmxScale;
+ int slot;
+ UCHAR inOffsetTable[(8)];
+
+ DMX_BS_META_DATA bsMetaData;
+
+ if ((self == NULL) || (nChannels == NULL) || (channelType == NULL) ||
+ (channelIndices == NULL) || (!FDK_chMapDescr_isValid(mapDescr))) {
+ return (PCMDMX_INVALID_HANDLE);
+ }
+
+ /* Init the output scaling */
+ dmxScale = 0;
+ if (pDmxOutScale != NULL) {
+ /* Avoid final scaling internally and hand it to the outside world. */
+ *pDmxOutScale = 0;
+ dmxMaxScale = (3);
+ } else {
+ /* Apply the scaling internally. */
+ pDmxOutScale = &devNull; /* redirect to temporal stack memory */
+ dmxMaxScale = 0;
+ }
+
+ pParam = &self->userParams;
+ numInChannels = *nChannels;
+
+ /* Perform some input sanity checks */
+ if (pPcmBuf == NULL) {
+ return (PCMDMX_INVALID_ARGUMENT);
+ }
+ if (frameSize == 0) {
+ return (PCMDMX_INVALID_ARGUMENT);
+ }
+ if (numInChannels == 0) {
+ return (PCMDMX_INVALID_ARGUMENT);
+ }
+ if (numInChannels > (8)) {
+ return (PCMDMX_INVALID_CH_CONFIG);
+ }
+
+ /* Check on misconfiguration */
+ FDK_ASSERT((pParam->numOutChannelsMax <= 0) ||
+ (pParam->numOutChannelsMax >= pParam->numOutChannelsMin));
+
+ /* Determine if the module has to do processing */
+ if ((self->applyProcessing == 0) &&
+ ((pParam->numOutChannelsMax <= 0) ||
+ (pParam->numOutChannelsMax >= numInChannels)) &&
+ (pParam->numOutChannelsMin <= numInChannels)) {
+ /* Nothing to do */
+ return (errorStatus);
+ }
+
+ /* Determine the number of output channels */
+ if ((pParam->numOutChannelsMax > 0) &&
+ (numInChannels > pParam->numOutChannelsMax)) {
+ numOutChannels = pParam->numOutChannelsMax;
+ } else if (numInChannels < pParam->numOutChannelsMin) {
+ numOutChannels = pParam->numOutChannelsMin;
+ } else {
+ numOutChannels = numInChannels;
+ }
+
+ /* Check I/O buffer size */
+ if ((UINT)pcmBufSize < (UINT)numOutChannels * frameSize) {
+ return (PCMDMX_OUTPUT_BUFFER_TOO_SMALL);
+ }
+
+ dualChannelMode = pParam->dualChannelMode;
+
+ /* Analyse input channel configuration and get channel offset
+ * table that can be accessed with the fixed channel labels. */
+ errorStatus = getChannelMode(numInChannels, channelType, channelIndices,
+ inOffsetTable, &inChMode);
+ if (PCMDMX_IS_FATAL_ERROR(errorStatus) || (inChMode == CH_MODE_UNDEFINED)) {
+ /* We don't need to restore because the channel
+ configuration has not been changed. Just exit. */
+ return (PCMDMX_INVALID_CH_CONFIG);
+ }
+
+ /* Set input stride and offset */
+ if (fInterleaved) {
+ inStride = numInChannels;
+ offset = 1; /* Channel specific offset factor */
+ } else {
+ inStride = 1;
+ offset = frameSize; /* Channel specific offset factor */
+ }
+
+ /* Reset downmix meta data if necessary */
+ if ((pParam->expiryFrame > 0) &&
+ (++self->bsMetaData[0].expiryCount >
+ pParam
+ ->expiryFrame)) { /* The metadata read from bitstream is too old. */
+#ifdef FDK_ASSERT_ENABLE
+ PCMDMX_ERROR err = pcmDmx_Reset(self, PCMDMX_RESET_BS_DATA);
+ FDK_ASSERT(err == PCMDMX_OK);
+#else
+ pcmDmx_Reset(self, PCMDMX_RESET_BS_DATA);
+#endif
+ }
+ FDKmemcpy(&bsMetaData, &self->bsMetaData[pParam->frameDelay],
+ sizeof(DMX_BS_META_DATA));
+ /* Maintain delay line */
+ for (slot = pParam->frameDelay; slot > 0; slot -= 1) {
+ FDKmemcpy(&self->bsMetaData[slot], &self->bsMetaData[slot - 1],
+ sizeof(DMX_BS_META_DATA));
+ }
+
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ * - - - - - - - - - - - - - - - - - - */
+ if (numInChannels > numOutChannels) { /* Apply downmix */
+ DMX_PCM *pInPcm[(8)] = {NULL};
+ DMX_PCM *pOutPcm[(8)] = {NULL};
+ FIXP_DMX mixFactors[(8)][(8)];
+ UCHAR outOffsetTable[(8)];
+ UINT sample;
+ int chCfg = 0;
+ int bypScale = 0;
+
+ if (numInChannels > SIX_CHANNEL) {
+ AUDIO_CHANNEL_TYPE multiPurposeChType[2];
+
+ /* Get the type of the multipurpose channels */
+ multiPurposeChType[0] =
+ channelType[inOffsetTable[LEFT_MULTIPRPS_CHANNEL]];
+ multiPurposeChType[1] =
+ channelType[inOffsetTable[RIGHT_MULTIPRPS_CHANNEL]];
+
+ /* Check if the input configuration is one defined in the standard. */
+ switch (inChMode) {
+ case CH_MODE_5_0_2_1: /* chCfg 7 || 14 */
+ /* Further analyse the input config to distinguish the two
+ * CH_MODE_5_0_2_1 configs. */
+ if ((multiPurposeChType[0] == ACT_FRONT_TOP) &&
+ (multiPurposeChType[1] == ACT_FRONT_TOP)) {
+ chCfg = 14;
+ } else {
+ chCfg = 7;
+ }
+ break;
+ case CH_MODE_3_0_3_1: /* chCfg 11 */
+ chCfg = 11;
+ break;
+ case CH_MODE_3_0_4_1: /* chCfg 12 */
+ chCfg = 12;
+ break;
+ default:
+ chCfg = 0; /* Not a known config */
+ break;
+ }
+ }
+
+ /* Set this stages output stride and channel mode: */
+ outStride = (fInterleaved) ? numOutChannels : 1;
+ outChMode = outChModeTable[numOutChannels];
+ FDK_ASSERT(outChMode != CH_MODE_UNDEFINED);
+
+ /* Get channel description and channel mapping for the desired output
+ * configuration. */
+ getChannelDescription(outChMode, mapDescr, channelType, channelIndices,
+ outOffsetTable);
+ /* Now there is no way back because we modified the channel configuration!
+ */
+
+ /* Create the DMX matrix */
+ errorStatus =
+ getMixFactors((chCfg > 0) ? 1 : 0,
+ (chCfg > 0) ? (PCM_DMX_CHANNEL_MODE)chCfg : inChMode,
+ outChMode, pParam, &bsMetaData, mixFactors, &dmxScale);
+ /* No fatal errors can occur here. The function is designed to always return
+ a valid matrix. The error code is used to signal configurations and
+ matrices that are not conform to any standard. */
+
+ /* Determine the final scaling */
+ bypScale = fMin(dmxMaxScale, dmxScale);
+ *pDmxOutScale += bypScale;
+ dmxScale -= bypScale;
+
+ { /* Set channel pointer for input. Remove empty cols. */
+ int inCh, outCh, map[(8)];
+ int ch = 0;
+ for (inCh = 0; inCh < (8); inCh += 1) {
+ if (inOffsetTable[inCh] < (UCHAR)numInChannels) {
+ pInPcm[ch] = &pPcmBuf[inOffsetTable[inCh] * offset];
+ map[ch++] = inCh;
+ }
+ }
+ for (; ch < (8); ch += 1) {
+ map[ch] = ch;
+ }
+
+ /* Remove unused cols from factor matrix */
+ for (inCh = 0; inCh < numInChannels; inCh += 1) {
+ if (inCh != map[inCh]) {
+ for (outCh = 0; outCh < (8); outCh += 1) {
+ mixFactors[outCh][inCh] = mixFactors[outCh][map[inCh]];
+ }
+ }
+ }
+
+ /* Set channel pointer for output. Remove empty cols. */
+ ch = 0;
+ for (outCh = 0; outCh < (8); outCh += 1) {
+ if (outOffsetTable[outCh] < (UCHAR)numOutChannels) {
+ pOutPcm[ch] = &pPcmBuf[outOffsetTable[outCh] * offset];
+ map[ch++] = outCh;
+ }
+ }
+ for (; ch < (8); ch += 1) {
+ map[ch] = ch;
+ }
+
+ /* Remove unused rows from factor matrix */
+ for (outCh = 0; outCh < numOutChannels; outCh += 1) {
+ if (outCh != map[outCh]) {
+ FDKmemcpy(&mixFactors[outCh], &mixFactors[map[outCh]],
+ (8) * sizeof(FIXP_DMX));
+ }
+ }
+ }
+
+ /* Sample processing loop */
+ for (sample = 0; sample < frameSize; sample++) {
+ DMX_PCM tIn[(8)] = {0};
+ FIXP_DBL tOut[(8)] = {(FIXP_DBL)0};
+ int inCh, outCh;
+
+ /* Preload all input samples */
+ for (inCh = 0; inCh < numInChannels; inCh += 1) {
+ if (pInPcm[inCh] != NULL) {
+ tIn[inCh] = *pInPcm[inCh];
+ pInPcm[inCh] += inStride;
+ } else {
+ tIn[inCh] = (DMX_PCM)0;
+ }
+ }
+ /* Apply downmix coefficients to input samples and accumulate for output
+ */
+ for (outCh = 0; outCh < numOutChannels; outCh += 1) {
+ for (inCh = 0; inCh < numInChannels; inCh += 1) {
+ tOut[outCh] += fMult((DMX_PCMF)tIn[inCh], mixFactors[outCh][inCh]);
+ }
+ FDK_ASSERT(pOutPcm[outCh] >= pPcmBuf);
+ FDK_ASSERT(pOutPcm[outCh] < &pPcmBuf[pcmBufSize]);
+ /* Write sample */
+ *pOutPcm[outCh] = (DMX_PCM)SATURATE_SHIFT(
+ tOut[outCh], DFRACT_BITS - DMX_PCM_BITS - dmxScale, DMX_PCM_BITS);
+ pOutPcm[outCh] += outStride;
+ }
+ }
+
+ /* Update the number of output channels */
+ *nChannels = numOutChannels;
+
+ } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ - - - - - - - - - - - - - - - - - - */
+ else if (numInChannels < numOutChannels) { /* Apply rudimentary upmix */
+ /* Set up channel pointer */
+ UCHAR outOffsetTable[(8)];
+
+ /* FIRST STAGE
+ Create a stereo/dual channel signal */
+ if (numInChannels == ONE_CHANNEL) {
+ DMX_PCM *pInPcm[(8)];
+ DMX_PCM *pOutLF, *pOutRF;
+ UINT sample;
+
+ /* Set this stages output stride and channel mode: */
+ outStride = (fInterleaved) ? TWO_CHANNEL : 1;
+ outChMode = outChModeTable[TWO_CHANNEL];
+
+ /* Get channel description and channel mapping for this
+ * stages number of output channels (always STEREO). */
+ getChannelDescription(outChMode, mapDescr, channelType, channelIndices,
+ outOffsetTable);
+ /* Now there is no way back because we modified the channel configuration!
+ */
+
+ /* Set input channel pointer. The first channel is always at index 0. */
+ pInPcm[CENTER_FRONT_CHANNEL] =
+ &pPcmBuf[(frameSize - 1) *
+ inStride]; /* Considering input mapping could lead to a
+ invalid pointer here if the channel is not
+ declared to be a front channel. */
+
+ /* Set output channel pointer (for this stage). */
+ pOutLF = &pPcmBuf[outOffsetTable[LEFT_FRONT_CHANNEL] * offset +
+ (frameSize - 1) * outStride];
+ pOutRF = &pPcmBuf[outOffsetTable[RIGHT_FRONT_CHANNEL] * offset +
+ (frameSize - 1) * outStride];
+
+ /* 1/0 input: */
+ for (sample = 0; sample < frameSize; sample++) {
+ /* L' = C; R' = C; */
+ *pOutLF = *pOutRF = *pInPcm[CENTER_FRONT_CHANNEL];
+
+ pInPcm[CENTER_FRONT_CHANNEL] -= inStride;
+ pOutLF -= outStride;
+ pOutRF -= outStride;
+ }
+
+ /* Prepare for next stage: */
+ inStride = outStride;
+ inChMode = outChMode;
+ FDKmemcpy(inOffsetTable, outOffsetTable, (8) * sizeof(UCHAR));
+ }
+
+ /* SECOND STAGE
+ Extend with zero channels to achieved the desired number of output
+ channels. */
+ if (numOutChannels > TWO_CHANNEL) {
+ DMX_PCM *pIn[(8)] = {NULL};
+ DMX_PCM *pOut[(8)] = {NULL};
+ UINT sample;
+ AUDIO_CHANNEL_TYPE inChTypes[(8)];
+ UCHAR inChIndices[(8)];
+ UCHAR numChPerGrp[2][(4)];
+ int nContentCh = 0; /* Number of channels with content */
+ int nEmptyCh = 0; /* Number of channels with content */
+ int ch, chGrp, isCompatible = 1;
+
+ /* Do not change the signalling which is the channel types and indices.
+ Just reorder and add channels. So first save the input signalling. */
+ FDKmemcpy(inChTypes, channelType,
+ numInChannels * sizeof(AUDIO_CHANNEL_TYPE));
+ FDKmemclear(inChTypes + numInChannels,
+ ((8) - numInChannels) * sizeof(AUDIO_CHANNEL_TYPE));
+ FDKmemcpy(inChIndices, channelIndices, numInChannels * sizeof(UCHAR));
+ FDKmemclear(inChIndices + numInChannels,
+ ((8) - numInChannels) * sizeof(UCHAR));
+
+ /* Set this stages output stride and channel mode: */
+ outStride = (fInterleaved) ? numOutChannels : 1;
+ outChMode = outChModeTable[numOutChannels];
+ FDK_ASSERT(outChMode != CH_MODE_UNDEFINED);
+
+ /* Check if input channel config can be easily mapped to the desired
+ * output config. */
+ for (chGrp = 0; chGrp < (4); chGrp += 1) {
+ numChPerGrp[IN][chGrp] = (inChMode >> (chGrp * 4)) & 0xF;
+ numChPerGrp[OUT][chGrp] = (outChMode >> (chGrp * 4)) & 0xF;
+
+ if (numChPerGrp[IN][chGrp] > numChPerGrp[OUT][chGrp]) {
+ isCompatible = 0;
+ break;
+ }
+ }
+
+ if (isCompatible) {
+ /* Get new channel description and channel
+ * mapping for the desired output channel mode. */
+ getChannelDescription(outChMode, mapDescr, channelType, channelIndices,
+ outOffsetTable);
+ /* If the input config has a back center channel but the output
+ config has not, copy it to left and right (if available). */
+ if ((numChPerGrp[IN][CH_GROUP_REAR] % 2) &&
+ !(numChPerGrp[OUT][CH_GROUP_REAR] % 2)) {
+ if (numChPerGrp[IN][CH_GROUP_REAR] == 1) {
+ inOffsetTable[RIGHT_REAR_CHANNEL] =
+ inOffsetTable[LEFT_REAR_CHANNEL];
+ } else if (numChPerGrp[IN][CH_GROUP_REAR] == 3) {
+ inOffsetTable[RIGHT_MULTIPRPS_CHANNEL] =
+ inOffsetTable[LEFT_MULTIPRPS_CHANNEL];
+ }
+ }
+ } else {
+ /* Just copy and extend the original config */
+ FDKmemcpy(outOffsetTable, inOffsetTable, (8) * sizeof(UCHAR));
+ }
+
+ /* Set I/O channel pointer.
+ Note: The following assignment algorithm clears the channel offset
+ tables. Thus they can not be used afterwards. */
+ for (ch = 0; ch < (8); ch += 1) {
+ if ((outOffsetTable[ch] < 255) &&
+ (inOffsetTable[ch] < 255)) { /* Set I/O pointer: */
+ pIn[nContentCh] =
+ &pPcmBuf[inOffsetTable[ch] * offset + (frameSize - 1) * inStride];
+ pOut[nContentCh] = &pPcmBuf[outOffsetTable[ch] * offset +
+ (frameSize - 1) * outStride];
+ /* Update signalling */
+ channelType[outOffsetTable[ch]] = inChTypes[inOffsetTable[ch]];
+ channelIndices[outOffsetTable[ch]] = inChIndices[inOffsetTable[ch]];
+ inOffsetTable[ch] = 255;
+ outOffsetTable[ch] = 255;
+ nContentCh += 1;
+ }
+ }
+ if (isCompatible) {
+ /* Assign the remaining input channels.
+ This is just a safety appliance. We should never need it. */
+ for (ch = 0; ch < (8); ch += 1) {
+ if (inOffsetTable[ch] < 255) {
+ int outCh;
+ for (outCh = 0; outCh < (8); outCh += 1) {
+ if (outOffsetTable[outCh] < 255) {
+ break;
+ }
+ }
+ if (outCh >= (8)) {
+ FDK_ASSERT(0);
+ break;
+ }
+ /* Set I/O pointer: */
+ pIn[nContentCh] = &pPcmBuf[inOffsetTable[ch] * offset +
+ (frameSize - 1) * inStride];
+ pOut[nContentCh] = &pPcmBuf[outOffsetTable[outCh] * offset +
+ (frameSize - 1) * outStride];
+ /* Update signalling */
+ FDK_ASSERT(inOffsetTable[outCh] < numInChannels);
+ FDK_ASSERT(outOffsetTable[outCh] < numOutChannels);
+ channelType[outOffsetTable[outCh]] = inChTypes[inOffsetTable[ch]];
+ channelIndices[outOffsetTable[outCh]] =
+ inChIndices[inOffsetTable[ch]];
+ inOffsetTable[ch] = 255;
+ outOffsetTable[outCh] = 255;
+ nContentCh += 1;
+ }
+ }
+ /* Set the remaining output channel pointer */
+ for (ch = 0; ch < (8); ch += 1) {
+ if (outOffsetTable[ch] < 255) {
+ pOut[nContentCh + nEmptyCh] = &pPcmBuf[outOffsetTable[ch] * offset +
+ (frameSize - 1) * outStride];
+ /* Expand output signalling */
+ channelType[outOffsetTable[ch]] = ACT_NONE;
+ channelIndices[outOffsetTable[ch]] = (UCHAR)nEmptyCh;
+ outOffsetTable[ch] = 255;
+ nEmptyCh += 1;
+ }
+ }
+ } else {
+ /* Set the remaining output channel pointer */
+ for (ch = nContentCh; ch < numOutChannels; ch += 1) {
+ pOut[ch] = &pPcmBuf[ch * offset + (frameSize - 1) * outStride];
+ /* Expand output signalling */
+ channelType[ch] = ACT_NONE;
+ channelIndices[ch] = (UCHAR)nEmptyCh;
+ nEmptyCh += 1;
+ }
+ }
+
+ /* First copy the channels that have signal */
+ for (sample = 0; sample < frameSize; sample += 1) {
+ DMX_PCM tIn[(8)];
+ /* Read all channel samples */
+ for (ch = 0; ch < nContentCh; ch += 1) {
+ tIn[ch] = *pIn[ch];
+ pIn[ch] -= inStride;
+ }
+ /* Write all channel samples */
+ for (ch = 0; ch < nContentCh; ch += 1) {
+ *pOut[ch] = tIn[ch];
+ pOut[ch] -= outStride;
+ }
+ }
+
+ /* Clear all the other channels */
+ for (sample = 0; sample < frameSize; sample++) {
+ for (ch = nContentCh; ch < numOutChannels; ch += 1) {
+ *pOut[ch] = (DMX_PCM)0;
+ pOut[ch] -= outStride;
+ }
+ }
+ }
+
+ /* update the number of output channels */
+ *nChannels = numOutChannels;
+ } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ - - - - - - - - - - - - - - - - - - */
+ else if (numInChannels == numOutChannels) {
+ /* Don't need to change the channel description here */
+
+ switch (numInChannels) {
+ case 2: { /* Set up channel pointer */
+ DMX_PCM *pInPcm[(8)];
+ DMX_PCM *pOutL, *pOutR;
+ FIXP_DMX flev;
+
+ UINT sample;
+
+ if (fInterleaved) {
+ inStride = numInChannels;
+ outStride =
+ 2; /* fixed !!! (below stereo is donwmixed to mono if required */
+ offset = 1; /* Channel specific offset factor */
+ } else {
+ inStride = 1;
+ outStride = 1;
+ offset = frameSize; /* Channel specific offset factor */
+ }
+
+ /* Set input channel pointer */
+ pInPcm[LEFT_FRONT_CHANNEL] =
+ &pPcmBuf[inOffsetTable[LEFT_FRONT_CHANNEL] * offset];
+ pInPcm[RIGHT_FRONT_CHANNEL] =
+ &pPcmBuf[inOffsetTable[RIGHT_FRONT_CHANNEL] * offset];
+
+ /* Set output channel pointer (same as input) */
+ pOutL = pInPcm[LEFT_FRONT_CHANNEL];
+ pOutR = pInPcm[RIGHT_FRONT_CHANNEL];
+
+ /* Set downmix levels: */
+ flev = FL2FXCONST_DMX(0.70710678f);
+ /* 2/0 input: */
+ switch (dualChannelMode) {
+ case CH1_MODE: /* L' = 0.707 * Ch1; R' = 0.707 * Ch1 */
+ for (sample = 0; sample < frameSize; sample++) {
+ *pOutL = *pOutR = (DMX_PCM)SATURATE_RIGHT_SHIFT(
+ fMult((DMX_PCMF)*pInPcm[LEFT_FRONT_CHANNEL], flev),
+ DFRACT_BITS - DMX_PCM_BITS, DMX_PCM_BITS);
+
+ pInPcm[LEFT_FRONT_CHANNEL] += inStride;
+ pOutL += outStride;
+ pOutR += outStride;
+ }
+ break;
+ case CH2_MODE: /* L' = 0.707 * Ch2; R' = 0.707 * Ch2 */
+ for (sample = 0; sample < frameSize; sample++) {
+ *pOutL = *pOutR = (DMX_PCM)SATURATE_RIGHT_SHIFT(
+ fMult((DMX_PCMF)*pInPcm[RIGHT_FRONT_CHANNEL], flev),
+ DFRACT_BITS - DMX_PCM_BITS, DMX_PCM_BITS);
+
+ pInPcm[RIGHT_FRONT_CHANNEL] += inStride;
+ pOutL += outStride;
+ pOutR += outStride;
+ }
+ break;
+ case MIXED_MODE: /* L' = 0.5*Ch1 + 0.5*Ch2; R' = 0.5*Ch1 + 0.5*Ch2 */
+ for (sample = 0; sample < frameSize; sample++) {
+ *pOutL = *pOutR = (*pInPcm[LEFT_FRONT_CHANNEL] >> 1) +
+ (*pInPcm[RIGHT_FRONT_CHANNEL] >> 1);
+
+ pInPcm[LEFT_FRONT_CHANNEL] += inStride;
+ pInPcm[RIGHT_FRONT_CHANNEL] += inStride;
+ pOutL += outStride;
+ pOutR += outStride;
+ }
+ break;
+ default:
+ case STEREO_MODE:
+ /* nothing to do */
+ break;
+ }
+ } break;
+
+ default:
+ /* nothing to do */
+ break;
+ }
+ }
+
+ return (errorStatus);
+}
+
+/** Close an instance of the PCM downmix module.
+ * @param [inout] Pointer to a buffer containing the handle of the instance.
+ * @returns Returns an error code.
+ **/
+PCMDMX_ERROR pcmDmx_Close(HANDLE_PCM_DOWNMIX *pSelf) {
+ if (pSelf == NULL) {
+ return (PCMDMX_INVALID_HANDLE);
+ }
+
+ FreePcmDmxInstance(pSelf);
+ *pSelf = NULL;
+
+ return (PCMDMX_OK);
+}
+
+/** Get library info for this module.
+ * @param [out] Pointer to an allocated LIB_INFO structure.
+ * @returns Returns an error code.
+ */
+PCMDMX_ERROR pcmDmx_GetLibInfo(LIB_INFO *info) {
+ int i;
+
+ if (info == NULL) {
+ return PCMDMX_INVALID_ARGUMENT;
+ }
+
+ /* Search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) {
+ return PCMDMX_INVALID_ARGUMENT;
+ }
+
+ /* Add the library info */
+ info[i].module_id = FDK_PCMDMX;
+ info[i].version =
+ LIB_VERSION(PCMUTIL_LIB_VL0, PCMUTIL_LIB_VL1, PCMUTIL_LIB_VL2);
+ LIB_VERSION_STRING(info + i);
+ info[i].build_date = PCMUTIL_LIB_BUILD_DATE;
+ info[i].build_time = PCMUTIL_LIB_BUILD_TIME;
+ info[i].title = PCMDMX_LIB_TITLE;
+
+ /* Set flags */
+ info[i].flags = 0 | CAPF_DMX_BLIND /* At least blind downmixing is possible */
+ | CAPF_DMX_PCE /* Guided downmix with data from MPEG-2/4
+ Program Config Elements (PCE). */
+ | CAPF_DMX_ARIB /* PCE guided downmix with slightly different
+ equations and levels. */
+ | CAPF_DMX_DVB /* Guided downmix with data from DVB ancillary
+ data fields. */
+ | CAPF_DMX_CH_EXP /* Simple upmixing by dublicating channels
+ or adding zero channels. */
+ | CAPF_DMX_6_CH | CAPF_DMX_8_CH;
+
+ /* Add lib info for FDK tools (if not yet done). */
+ FDK_toolsGetLibInfo(info);
+
+ return PCMDMX_OK;
+}
diff --git a/fdk-aac/libPCMutils/src/version.h b/fdk-aac/libPCMutils/src/version.h
new file mode 100644
index 0000000..fa31af1
--- /dev/null
+++ b/fdk-aac/libPCMutils/src/version.h
@@ -0,0 +1,119 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** PCM utility library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#if !defined(VERSION_H)
+#define VERSION_H
+
+/* library info */
+#define PCMUTIL_LIB_VL0 3
+#define PCMUTIL_LIB_VL1 0
+#define PCMUTIL_LIB_VL2 0
+#define PCMUTIL_LIB_TITLE "PCM Utility Lib"
+#ifdef __ANDROID__
+#define PCMUTIL_LIB_BUILD_DATE ""
+#define PCMUTIL_LIB_BUILD_TIME ""
+#else
+#define PCMUTIL_LIB_BUILD_DATE __DATE__
+#define PCMUTIL_LIB_BUILD_TIME __TIME__
+#endif
+
+#endif /* !defined(VERSION_H) */
diff --git a/fdk-aac/libSACdec/include/sac_dec_errorcodes.h b/fdk-aac/libSACdec/include/sac_dec_errorcodes.h
new file mode 100644
index 0000000..ee8b9f8
--- /dev/null
+++ b/fdk-aac/libSACdec/include/sac_dec_errorcodes.h
@@ -0,0 +1,157 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: error codes for mpeg surround decoder
+
+*******************************************************************************/
+
+#ifndef SAC_DEC_ERRORCODES_H
+#define SAC_DEC_ERRORCODES_H
+
+typedef enum {
+
+ __mps_error_start = -1000,
+
+ MPS_OK = 0,
+
+ /* generic/init errors */
+ MPS_NOTOK = __mps_error_start,
+
+ MPS_OUTOFMEMORY,
+ MPS_INVALID_HANDLE,
+ MPS_INVALID_PARAMETER, /* SetParam not successfull */
+ MPS_UNSUPPORTED_HRTFMODEL, /* SetHRTFModel() not successfull */
+ MPS_UNSUPPORTED_HRTFFREQ, /* SetHRTFModel() not successfull */
+
+ MPS_UNSUPPORTED_UPMIX_TYPE, /* CheckLevelTreeUpmixType() */
+ MPS_UNSUPPORTED_FORMAT, /* various functions; unknown aot or no_channels in
+ filterbank */
+ MPS_OUTPUT_BUFFER_TOO_SMALL, /* Size of provided output time buffer is too
+ small */
+
+ /* ssc errors */
+ MPS_INVALID_PARAMETERBANDS, /* unsupported numParameterBands in
+ SpatialDecDecodeHeader() */
+ MPS_INVALID_TREECONFIG,
+ MPS_INVALID_HRTFSET, /* SpatialDecDecodeHeader() */
+ MPS_INVALID_TTT, /* SpatialDecDecodeHeader() */
+ MPS_INVALID_BOXIDX, /* ecDataDec() */
+ MPS_INVALID_SETIDX, /* ecDataDec() */
+ MPS_INVALID_QUANTMODE, /* SpatialDecParseSpecificConfig() */
+ MPS_UNEQUAL_SSC, /* FDK_SpatialDecCompareSpatialSpecificConfigHeader() */
+ MPS_UNSUPPORTED_CONFIG, /* number of core channels; 3DStereoInversion; */
+
+ /* parse errors */
+ MPS_PARSE_ERROR,
+ MPS_INVALID_TEMPSHAPE, /* SpatialDecParseFrameData() */
+
+ /* render errors */
+ MPS_WRONG_PARAMETERSETS,
+ MPS_WRONG_PARAMETERBANDS, /* decodeAndMapFrameSmg() */
+ MPS_WRONG_TREECONFIG,
+ MPS_WRONG_BLINDCONFIG,
+ MPS_WRONG_OTT,
+ MPS_WRONG_QUANTMODE,
+ MPS_RESDEC_ERROR,
+ MPS_APPLY_M2_ERROR, /* error in applyM2x()selection */
+
+ __mps_error_end
+
+} SACDEC_ERROR;
+
+#endif
diff --git a/fdk-aac/libSACdec/include/sac_dec_lib.h b/fdk-aac/libSACdec/include/sac_dec_lib.h
new file mode 100644
index 0000000..9913279
--- /dev/null
+++ b/fdk-aac/libSACdec/include/sac_dec_lib.h
@@ -0,0 +1,477 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: Space Decoder
+
+*******************************************************************************/
+
+#ifndef SAC_DEC_LIB_H
+#define SAC_DEC_LIB_H
+
+#include "common_fix.h"
+#include "FDK_audio.h"
+#include "sac_dec_errorcodes.h"
+#include "FDK_bitstream.h"
+#include "FDK_qmf_domain.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * \brief MPEG Surround input data interface mode.
+ **/
+typedef enum {
+ SAC_INTERFACE_QMF =
+ 0, /*!< Use QMF domain interface for the input downmix audio. */
+ SAC_INTERFACE_TIME, /*!< Use time domain interface for the input downmix
+ audio. */
+ SAC_INTERFACE_AUTO /*!< */
+} SAC_INPUT_CONFIG;
+
+/**
+ * \brief MPEG Surround output mode.
+ **/
+typedef enum {
+ SACDEC_OUT_MODE_NORMAL =
+ 0, /*!< Normal multi channel processing without output restrictions. */
+ SACDEC_OUT_MODE_BINAURAL, /*!< Two channel output with binaural processsing.
+ */
+ SACDEC_OUT_MODE_STEREO, /*!< Always two channel output mode. */
+ SACDEC_OUT_MODE_6CHANNEL /*!< Always process with 5.1 channel output. */
+} SAC_DEC_OUTPUT_MODE;
+
+/**
+ * \brief MPEG Surround binaural HRTF model.
+ * HRTF will be applied only in combination with upmixtype
+ *SAC_UPMIX_TYPE_BINAURAL.
+ **/
+typedef enum {
+ SAC_BINAURAL_HRTF_KEMAR = 0,
+ SAC_BINAURAL_HRTF_VAST,
+ SAC_BINAURAL_HRTF_MPSVT,
+ SAC_BINAURAL_SINGLE_HRTFS
+} SAC_BINAURAL_HRTF_MODEL;
+
+/**
+ * \brief MPEG Surround decoder instance available.
+ **/
+typedef enum {
+ SAC_INSTANCE_NOT_FULL_AVAILABLE =
+ 0, /*!< MPEG Surround decoder instance not full available. */
+ SAC_INSTANCE_FULL_AVAILABLE /*!< MPEG Surround decoder instance full
+ available. */
+} SAC_INSTANCE_AVAIL;
+
+/**
+ * \brief MPEG Surround decoder dynamic parameters.
+ *
+ * Use mpegSurroundDecoder_SetParam() function to configure internal status of
+ * following parameters.
+ */
+typedef enum {
+ SACDEC_OUTPUT_MODE = 0x0001, /*!< Set MPEG Surround decoder output mode. See
+ SAC_DEC_OUTPUT_MODE. */
+ SACDEC_BLIND_ENABLE =
+ 0x0002, /*!< Multi channel output without MPEG Surround side info. */
+ SACDEC_PARTIALLY_COMPLEX =
+ 0x0003, /*!< Set partially complex flag for MPEG Surround.
+ 0: Use complex valued QMF data.
+ 1: Use real valued QMF data (low power mode) */
+ SACDEC_INTERFACE =
+ 0x0004, /*!< Select signal input interface for MPEG Surround.
+ Switch time interface off: 0
+ Switch time interface on: 1 */
+ SACDEC_BS_DELAY = 0x0005, /*!< Select bit stream delay for MPEG Surround.
+ Switch bit stream delay off: 0
+ Switch bit stream delay on: 1 */
+ SACDEC_BINAURAL_QUALITY =
+ 0x0102, /*!< Set binaural quality for MPEG Surround binaural mode.
+ 0: Low Complexity,
+ 1: High Quality */
+ SACDEC_BINAURAL_DISTANCE = 0x0103, /*!< Set perceived distance for binaural
+ playback (binaural mode only). The valid
+ values range from 0 to 100. Where 100
+ corresponds to the farthest perceived
+ distance. */
+ SACDEC_BINAURAL_DIALOG_CLARITY =
+ 0x0104, /*!< Set dialog clarity (for binaural playback).
+ The valid values range from 0 to 100. */
+ SACDEC_BINAURAL_FRONT_ANGLE = 0x0105, /*!< Set angle between the virtual front
+ speaker pair (binaural mode only).
+ The valid range is from 0 to 180
+ angular degrees. */
+ SACDEC_BINAURAL_BACK_ANGLE = 0x0106, /*!< Set angle between the virtual back
+ speaker pair (binaural mode only). The
+ valid range is from 0 to 180 angular
+ degrees. */
+ SACDEC_BINAURAL_PRESET = 0x0107, /*!< Set a virtual speaker setup preset for
+ binaural playback (binaural mode only).
+ This meta-parameter implicitly modifies
+ the following parameters:
+ SACDEC_BINAURAL_DISTANCE,
+ SACDEC_BINAURAL_DIALOG_CLARITY,
+ SACDEC_BINAURAL_FRONT_ANGLE and
+ SACDEC_BINAURAL_BACK_ANGLE.
+ The following presets are available:
+ 1: Dry room
+ 2: Living room (default)
+ 3: Cinema */
+
+ SACDEC_BS_INTERRUPTION =
+ 0x0200, /*!< If the given value is unequal to 0 hint the MPEG Surround
+ decoder that the next input data is discontinuous, because of
+ frame loss, seeking, etc. Announce the decoder that the
+ bitstream data was interrupted (fSync = 0). This will cause the
+ surround decoder not to parse any new bitstream data until a
+ new header with a valid Spatial Specific Config and a
+ independently decodable frame is found. Specially important
+ when the MPEG Surround data is split accross several frames
+ (for example in the case of AAC-LC downmix with 1024
+ framelength and 2048 surround frame length) and a discontinuity
+ in the bitstream data occurs. If fSync is 1, assume that MPEG
+ Surround data is in sync (out of band config for example). */
+ SACDEC_CLEAR_HISTORY = 0x0201, /*!< If the given value is unequal to 0 clear
+ all internal states (delay lines, QMF
+ states, ...) of the MPEG Surround decoder.
+ This will cause a discontinuity in the audio
+ output signal. */
+
+ SACDEC_CONCEAL_NUM_KEEP_FRAMES =
+ 0x0301, /*!< Error concealment: The Number of frames the module keeps the
+ last spatial image before fading to the particular spatial
+ scenario starts. The default is 10 frames. */
+ SACDEC_CONCEAL_FADE_OUT_SLOPE_LENGTH =
+ 0x0302, /*!< Error concealment: Length of the slope (in frames) the module
+ creates to fade from the last spatial scenario to the
+ particular default scenario (downmix) in case of consecutive
+ errors. Default is 5. */
+ SACDEC_CONCEAL_FADE_IN_SLOPE_LENGTH =
+ 0x0303, /*!< Error concealment: Length of the slope (in frames) the module
+ creates to fade from the default spatial scenario (downmix) to
+ the current scenario after fade-out. Default parameter value
+ is 5. */
+ SACDEC_CONCEAL_NUM_RELEASE_FRAMES =
+ 0x0304 /*!< Error concealment: The number of error free frames before the
+ module starts fading from default to the current spatial
+ scenario. Default parameter value is 3 frames. */
+} SACDEC_PARAM;
+
+#define PCM_MPS INT_PCM
+
+/**
+ * \brief MPEG Surround decoder handle.
+ */
+typedef struct MpegSurroundDecoder CMpegSurroundDecoder;
+
+/**
+ * \brief Check if the full MPEG Surround decoder instance is allocated.
+ *
+ * Check if the full MPEG Surround decoder instance is allocated.
+ *
+ * \param pMpegSurroundDecoder A pointer to a decoder stucture.
+ *
+ * \return SACDEC_ERROR error code
+ */
+SAC_INSTANCE_AVAIL
+mpegSurroundDecoder_IsFullMpegSurroundDecoderInstanceAvailable(
+ CMpegSurroundDecoder *pMpegSurroundDecoder);
+
+/**
+ * \brief Open one instance of the MPEG Surround decoder.
+ *
+ * Allocate one instance of decoder and input buffers.
+ * - Allocate decoder structure
+ * - Allocate input buffers (QMF/time/MPS data)
+ *
+ * \param pMpegSurroundDecoder A pointer to a decoder handle; filled on
+ * return.
+ * \param splitMemoryAllocation Allocate only outer layer of MPS decoder. Core
+ * part is reallocated later if needed.
+ * \param stereoConfigIndex USAC: Save memory by opening the MPS decoder
+ * for a specific stereoConfigIndex. (Needs optimization macros enabled.)
+ * \param pQmfDomain Pointer to QMF domain data structure.
+ *
+ * \return SACDEC_ERROR error code
+ */
+SACDEC_ERROR mpegSurroundDecoder_Open(
+ CMpegSurroundDecoder **pMpegSurroundDecoder, int stereoConfigIndex,
+ HANDLE_FDK_QMF_DOMAIN pQmfDomain);
+
+/**
+ * \brief Init one instance of the MPEG Surround decoder.
+ *
+ * Init one instance of the MPEG Surround decoder
+ *
+ * \param pMpegSurroundDecoder A pointer to a decoder handle;
+ *
+ * \return SACDEC_ERROR error code
+ */
+SACDEC_ERROR mpegSurroundDecoder_Init(
+ CMpegSurroundDecoder *pMpegSurroundDecoder);
+
+/**
+ * \brief Read and parse SpatialSpecificConfig.
+ *
+ * \param pMpegSurroundDecoder A pointer to a decoder handle.
+ * \param hBs bitstream handle config parsing data source.
+ *
+ * \return SACDEC_ERROR error code
+ */
+SACDEC_ERROR mpegSurroundDecoder_Config(
+ CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
+ AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize,
+ INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes,
+ const UCHAR configMode, UCHAR *configChanged);
+
+SACDEC_ERROR
+mpegSurroundDecoder_ConfigureQmfDomain(
+ CMpegSurroundDecoder *pMpegSurroundDecoder,
+ SAC_INPUT_CONFIG sac_dec_interface, UINT coreSamplingRate,
+ AUDIO_OBJECT_TYPE coreCodec);
+
+/**
+ * \brief Parse MPEG Surround data without header
+ *
+ * \param pMpegSurroundDecoder A MPEG Surrround decoder handle.
+ * \param hBs Bit stream handle data input source
+ * \param pMpsDataBits Pointer to number of valid bits in extension
+ * payload. Function updates mpsDataBits while parsing bitstream.
+ * \param fGlobalIndependencyFlag Global independency flag of current frame.
+ *
+ * \return Error code.
+ */
+int mpegSurroundDecoder_ParseNoHeader(
+ CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
+ int *pMpsDataBits, int fGlobalIndependencyFlag);
+
+/* #ifdef SACDEC_MPS_ENABLE */
+/**
+ * \brief Parse MPEG Surround data with header. Header is ancType, ancStart,
+ ancStop (4 bits total). Body is ancDataSegmentByte[i].
+ *
+ * \param pMpegSurroundDecoder A MPEG Surrround decoder handle.
+ * \param hBs Bit stream handle data input source
+ * \param pMpsDataBits Pointer to number of valid bits in extension
+ payload. Function updates mpsDataBits while parsing bitstream. Needs to be a
+ multiple of 8 + 4 (4 bits header).
+ * \param coreCodec The audio object type of the core codec handling
+ the downmix input signal.
+ * \param sampleRate Samplerate of input downmix data.
+ * \param nChannels Amount of input channels.
+ * \param frameSize Amount of input samples.
+ * \param fGlobalIndependencyFlag Global independency flag of current frame.
+ *
+ * \return Error code.
+ */
+int mpegSurroundDecoder_Parse(CMpegSurroundDecoder *pMpegSurroundDecoder,
+ HANDLE_FDK_BITSTREAM hBs, int *pMpsDataBits,
+ AUDIO_OBJECT_TYPE coreCodec, int sampleRate,
+ int frameSize, int fGlobalIndependencyFlag);
+/* #endif */
+
+/**
+ * \brief Apply MPEG Surround upmix.
+ *
+ * Process one downmix audio frame and decode one surround frame if it applies.
+ * Downmix framing can be different from surround framing, so depending on the
+ * frame size of the downmix audio data and the framing being used by the MPEG
+ * Surround decoder, it could be that only every second call, for example, of
+ * this function actually surround data was decoded. The returned value of
+ * frameSize will be zero, if no surround data was decoded.
+ *
+ * Decoding one MPEG Surround frame. Depending on interface configuration
+ * mpegSurroundDecoder_SetParam(self, SACDEC_INTERFACE, value), the QMF or time
+ * interface will be applied. External access to QMF buffer interface can be
+ * achieved by mpegSurroundDecoder_GetQmfBuffer() call before decode frame.
+ * While using time interface, pTimeData buffer will be shared as input and
+ * output buffer.
+ *
+ * \param pMpegSurroundDecoder A MPEG Surrround decoder handle.
+ * \param pTimeData Pointer to time buffer. Depending on interface
+ * configuration, the content of pTimeData is ignored, and the internal QMF
+ * buffer will be used as input data source.
+ * Otherwise, the MPEG Surround processing is applied to the timesignal
+ * pTimeData. For both variants, the resulting MPEG
+ * Surround signal is written into pTimeData.
+ * \param timeDataSize Size of pTimeData (available buffer size).
+ * \param timeDataFrameSize Frame size of input timedata
+ * \param nChannels Pointer where the amount of input channels is
+ * given and amount of output channels is returned.
+ * \param frameSize Pointer where the amount of output samples is
+ * returned into.
+ * \param channelType Array were the corresponding channel type for
+ * each output audio channel is stored into.
+ * \param channelIndices Array were the corresponding channel type index
+ * for each output audio channel is stored into.
+ * \param mapDescr Channep map descriptor for output channel mapping
+ * to be used (From MPEG PCE ordering to whatever is required).
+ *
+ * \return Error code.
+ */
+int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
+ INT_PCM *input, PCM_MPS *pTimeData,
+ const int timeDataSize, int timeDataFrameSize,
+ int *nChannels, int *frameSize, int sampleRate,
+ AUDIO_OBJECT_TYPE coreCodec,
+ AUDIO_CHANNEL_TYPE channelType[],
+ UCHAR channelIndices[],
+ const FDK_channelMapDescr *const mapDescr);
+
+/**
+ * \brief Deallocate a MPEG Surround decoder instance.
+ * \param pMpegSurroundDecoder A decoder handle.
+ * \return No return value.
+ */
+void mpegSurroundDecoder_Close(CMpegSurroundDecoder *pMpegSurroundDecoder);
+
+/**
+ * \brief Free config dependent MPEG Surround memory.
+ * \param pMpegSurroundDecoder A decoder handle.
+ * \return error.
+ */
+SACDEC_ERROR mpegSurroundDecoder_FreeMem(
+ CMpegSurroundDecoder *pMpegSurroundDecoder);
+
+/**
+ * \brief Set one single MPEG Surround decoder parameter.
+ *
+ * \param pMpegSurroundDecoder A MPEG Surrround decoder handle. Must not be
+ * NULL pointer.
+ * \param param Parameter to be set. See SACDEC_PARAM.
+ * \param value Parameter value. See SACDEC_PARAM.
+ *
+ * \return 0 on sucess, and non-zero on failure.
+ */
+SACDEC_ERROR mpegSurroundDecoder_SetParam(
+ CMpegSurroundDecoder *pMpegSurroundDecoder, const SACDEC_PARAM param,
+ const INT value);
+
+/**
+ * \brief Retrieve MPEG Surround decoder library info and fill info list with all depending library infos.
+ * \param libInfo Pointer to library info list to be filled.
+ * \return 0 on sucess, and non-zero on failure.
+ **/
+int mpegSurroundDecoder_GetLibInfo(LIB_INFO *libInfo);
+
+/**
+ * \brief Set one single MPEG Surround decoder parameter.
+ *
+ * \param pMpegSurroundDecoder A valid MPEG Surrround decoder handle.
+ *
+ * \return The additional signal delay caused by the module.
+ */
+UINT mpegSurroundDecoder_GetDelay(const CMpegSurroundDecoder *self);
+
+/**
+ * \brief Get info on whether the USAC pseudo LR feature is active.
+ *
+ * \param pMpegSurroundDecoder A valid MPEG Surrround decoder handle.
+ * \param bsPseudoLr Pointer to return wether pseudo LR USAC feature
+ * is used.
+ *
+ * \return 0 on sucess, and non-zero on failure.
+ */
+SACDEC_ERROR mpegSurroundDecoder_IsPseudoLR(
+ CMpegSurroundDecoder *pMpegSurroundDecoder, int *bsPseudoLr);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* #ifndef SAC_DEC_LIB_H */
diff --git a/fdk-aac/libSACdec/src/sac_bitdec.cpp b/fdk-aac/libSACdec/src/sac_bitdec.cpp
new file mode 100644
index 0000000..883e1e8
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_bitdec.cpp
@@ -0,0 +1,2167 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec bitstream decoder
+
+*******************************************************************************/
+
+#include "sac_bitdec.h"
+
+#include "sac_dec_errorcodes.h"
+#include "nlc_dec.h"
+#include "sac_rom.h"
+#include "FDK_matrixCalloc.h"
+#include "sac_tsd.h"
+
+enum {
+ ottVsTotInactiv = 0,
+ ottVsTotDb1Activ = 1,
+ ottVsTotDb2Activ = 2,
+ ottVsTotDb1Db2Activ = 3
+};
+
+static SACDEC_ERROR SpatialDecDecodeHelperInfo(
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig, UPMIXTYPE upmixType) {
+ int i;
+ UINT syntaxFlags;
+
+ /* Determine bit stream syntax */
+ syntaxFlags = 0;
+ switch (pSpatialSpecificConfig->coreCodec) {
+ case AOT_ER_AAC_ELD:
+ case AOT_ER_AAC_LD:
+ syntaxFlags |= SACDEC_SYNTAX_LD;
+ break;
+ case AOT_USAC:
+ syntaxFlags |= SACDEC_SYNTAX_USAC;
+ break;
+ case AOT_NONE:
+ default:
+ return MPS_UNSUPPORTED_FORMAT;
+ }
+
+ pSpatialSpecificConfig->syntaxFlags = syntaxFlags;
+
+ switch (pSpatialSpecificConfig->treeConfig) {
+ case TREE_212: {
+ pSpatialSpecificConfig->ottCLDdefault[0] = 0;
+ } break;
+ default:
+ return MPS_INVALID_TREECONFIG;
+ }
+
+ if (syntaxFlags & SACDEC_SYNTAX_USAC) {
+ if (pSpatialSpecificConfig->bsOttBandsPhasePresent) {
+ pSpatialSpecificConfig->numOttBandsIPD =
+ pSpatialSpecificConfig->bsOttBandsPhase;
+ } else {
+ int numParameterBands;
+
+ numParameterBands = pSpatialSpecificConfig->freqRes;
+ switch (numParameterBands) {
+ case 4:
+ case 5:
+ pSpatialSpecificConfig->numOttBandsIPD = 2;
+ break;
+ case 7:
+ pSpatialSpecificConfig->numOttBandsIPD = 3;
+ break;
+ case 10:
+ pSpatialSpecificConfig->numOttBandsIPD = 5;
+ break;
+ case 14:
+ pSpatialSpecificConfig->numOttBandsIPD = 7;
+ break;
+ case 20:
+ case 28:
+ pSpatialSpecificConfig->numOttBandsIPD = 10;
+ break;
+ default:
+ return MPS_INVALID_PARAMETERBANDS;
+ }
+ }
+ } else {
+ pSpatialSpecificConfig->numOttBandsIPD = 0;
+ }
+ for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
+ {
+ pSpatialSpecificConfig->bitstreamOttBands[i] =
+ pSpatialSpecificConfig->freqRes;
+ }
+ {
+ pSpatialSpecificConfig->numOttBands[i] =
+ pSpatialSpecificConfig->bitstreamOttBands[i];
+ if (syntaxFlags & SACDEC_SYNTAX_USAC &&
+ !pSpatialSpecificConfig->bsOttBandsPhasePresent) {
+ if (pSpatialSpecificConfig->bResidualCoding &&
+ pSpatialSpecificConfig->ResidualConfig[i].bResidualPresent &&
+ (pSpatialSpecificConfig->numOttBandsIPD <
+ pSpatialSpecificConfig->ResidualConfig[i].nResidualBands)) {
+ pSpatialSpecificConfig->numOttBandsIPD =
+ pSpatialSpecificConfig->ResidualConfig[i].nResidualBands;
+ }
+ }
+ }
+ } /* i */
+
+ return MPS_OK;
+}
+
+/*******************************************************************************
+ Functionname: SpatialDecParseExtensionConfig
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+
+static SACDEC_ERROR SpatialDecParseExtensionConfig(
+ HANDLE_FDK_BITSTREAM bitstream, SPATIAL_SPECIFIC_CONFIG *config,
+ int numOttBoxes, int numTttBoxes, int numOutChan, int bitsAvailable) {
+ SACDEC_ERROR err = MPS_OK;
+ INT ba = bitsAvailable;
+
+ config->sacExtCnt = 0;
+ config->bResidualCoding = 0;
+
+ ba = fMin((int)FDKgetValidBits(bitstream), ba);
+
+ while ((ba >= 8) && (config->sacExtCnt < MAX_NUM_EXT_TYPES)) {
+ int bitsRead, nFillBits;
+ INT tmp;
+ UINT sacExtLen;
+
+ config->sacExtType[config->sacExtCnt] = FDKreadBits(bitstream, 4);
+ ba -= 4;
+
+ sacExtLen = FDKreadBits(bitstream, 4);
+ ba -= 4;
+
+ if (sacExtLen == 15) {
+ sacExtLen += FDKreadBits(bitstream, 8);
+ ba -= 8;
+ if (sacExtLen == 15 + 255) {
+ sacExtLen += FDKreadBits(bitstream, 16);
+ ba -= 16;
+ }
+ }
+
+ tmp = (INT)FDKgetValidBits(
+ bitstream); /* Extension config payload start anchor. */
+ if ((tmp <= 0) || (tmp < (INT)sacExtLen * 8) || (ba < (INT)sacExtLen * 8)) {
+ err = MPS_PARSE_ERROR;
+ goto bail;
+ }
+
+ switch (config->sacExtType[config->sacExtCnt]) {
+ default:; /* unknown extension data => do nothing */
+ }
+
+ /* skip remaining extension data */
+ bitsRead = tmp - FDKgetValidBits(bitstream);
+ nFillBits = 8 * sacExtLen - bitsRead;
+
+ if (nFillBits < 0) {
+ err = MPS_PARSE_ERROR;
+ goto bail;
+ } else {
+ /* Skip fill bits or an unkown extension. */
+ FDKpushFor(bitstream, nFillBits);
+ }
+
+ ba -= 8 * sacExtLen;
+ config->sacExtCnt++;
+ }
+
+bail:
+ return err;
+}
+
+SACDEC_ERROR SpatialDecParseSpecificConfigHeader(
+ HANDLE_FDK_BITSTREAM bitstream,
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
+ AUDIO_OBJECT_TYPE coreCodec, SPATIAL_DEC_UPMIX_TYPE upmixType) {
+ SACDEC_ERROR err = MPS_OK;
+ INT numFillBits;
+ int sacHeaderLen = 0;
+ int sacTimeAlignFlag = 0;
+
+ sacTimeAlignFlag = FDKreadBits(bitstream, 1);
+ sacHeaderLen = FDKreadBits(bitstream, 7);
+
+ if (sacHeaderLen == 127) {
+ sacHeaderLen += FDKreadBits(bitstream, 16);
+ }
+ numFillBits = (INT)FDKgetValidBits(bitstream);
+
+ err = SpatialDecParseSpecificConfig(bitstream, pSpatialSpecificConfig,
+ sacHeaderLen, coreCodec);
+
+ numFillBits -=
+ (INT)FDKgetValidBits(bitstream); /* the number of read bits (tmpBits) */
+ numFillBits = (8 * sacHeaderLen) - numFillBits;
+ if (numFillBits < 0) {
+ /* Parsing went wrong */
+ err = MPS_PARSE_ERROR;
+ }
+ /* Move to the very end of the SSC */
+ FDKpushBiDirectional(bitstream, numFillBits);
+
+ if ((err == MPS_OK) && sacTimeAlignFlag) {
+ /* not supported */
+ FDKreadBits(bitstream, 16);
+ err = MPS_UNSUPPORTED_CONFIG;
+ }
+
+ /* Derive additional helper variables */
+ SpatialDecDecodeHelperInfo(pSpatialSpecificConfig, (UPMIXTYPE)upmixType);
+
+ return err;
+}
+
+SACDEC_ERROR SpatialDecParseMps212Config(
+ HANDLE_FDK_BITSTREAM bitstream,
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig, int samplingRate,
+ AUDIO_OBJECT_TYPE coreCodec, INT stereoConfigIndex,
+ INT coreSbrFrameLengthIndex) {
+ int i;
+
+ FDKmemclear(pSpatialSpecificConfig, sizeof(SPATIAL_SPECIFIC_CONFIG));
+
+ pSpatialSpecificConfig->stereoConfigIndex = stereoConfigIndex;
+ pSpatialSpecificConfig->coreSbrFrameLengthIndex = coreSbrFrameLengthIndex;
+ pSpatialSpecificConfig->freqRes =
+ (SPATIALDEC_FREQ_RES)freqResTable[FDKreadBits(bitstream, 3)];
+ if (pSpatialSpecificConfig->freqRes == 0) {
+ return MPS_PARSE_ERROR; /* reserved value */
+ }
+
+ switch (coreCodec) {
+ case AOT_DRM_USAC:
+ pSpatialSpecificConfig->bsFixedGainDMX =
+ (SPATIALDEC_FIXED_GAINS)FDKreadBits(bitstream, 3);
+ /* tempShapeConfig = (bsTempShapeConfigDrm == 1) ? 3 : 0 */
+ pSpatialSpecificConfig->tempShapeConfig =
+ (SPATIALDEC_TS_CONF)(FDKreadBits(bitstream, 1) * 3);
+ pSpatialSpecificConfig->decorrConfig = (SPATIALDEC_DECORR_CONF)0;
+ pSpatialSpecificConfig->bsDecorrType = 0;
+ break;
+ case AOT_USAC:
+ pSpatialSpecificConfig->bsFixedGainDMX =
+ (SPATIALDEC_FIXED_GAINS)FDKreadBits(bitstream, 3);
+ pSpatialSpecificConfig->tempShapeConfig =
+ (SPATIALDEC_TS_CONF)FDKreadBits(bitstream, 2);
+ pSpatialSpecificConfig->decorrConfig =
+ (SPATIALDEC_DECORR_CONF)FDKreadBits(bitstream, 2);
+ if (pSpatialSpecificConfig->decorrConfig > 2) {
+ return MPS_PARSE_ERROR; /* reserved value */
+ }
+ pSpatialSpecificConfig->bsDecorrType = 0;
+ break;
+ default:
+ return MPS_UNSUPPORTED_FORMAT;
+ }
+ pSpatialSpecificConfig->nTimeSlots = (coreSbrFrameLengthIndex == 4) ? 64 : 32;
+ pSpatialSpecificConfig->bsHighRateMode = (UCHAR)FDKreadBits(bitstream, 1);
+
+ {
+ pSpatialSpecificConfig->bsPhaseCoding = (UCHAR)FDKreadBits(bitstream, 1);
+ pSpatialSpecificConfig->bsOttBandsPhasePresent =
+ (UCHAR)FDKreadBits(bitstream, 1);
+ if (pSpatialSpecificConfig->bsOttBandsPhasePresent) {
+ if (MAX_PARAMETER_BANDS < (pSpatialSpecificConfig->bsOttBandsPhase =
+ FDKreadBits(bitstream, 5))) {
+ return MPS_PARSE_ERROR;
+ }
+ } else {
+ pSpatialSpecificConfig->bsOttBandsPhase = 0;
+ }
+ }
+
+ if (stereoConfigIndex > 1) { /* do residual coding */
+ pSpatialSpecificConfig->bResidualCoding = 1;
+ pSpatialSpecificConfig->ResidualConfig->bResidualPresent = 1;
+ if (pSpatialSpecificConfig->freqRes <
+ (pSpatialSpecificConfig->ResidualConfig->nResidualBands =
+ FDKreadBits(bitstream, 5))) {
+ return MPS_PARSE_ERROR;
+ }
+ pSpatialSpecificConfig->bsOttBandsPhase =
+ fMax(pSpatialSpecificConfig->bsOttBandsPhase,
+ pSpatialSpecificConfig->ResidualConfig->nResidualBands);
+ pSpatialSpecificConfig->bsPseudoLr = (UCHAR)FDKreadBits(bitstream, 1);
+
+ if (pSpatialSpecificConfig->bsPhaseCoding) {
+ pSpatialSpecificConfig->bsPhaseCoding = 3;
+ }
+ } else {
+ pSpatialSpecificConfig->bResidualCoding = 0;
+ pSpatialSpecificConfig->ResidualConfig->bResidualPresent = 0;
+ }
+
+ if (pSpatialSpecificConfig->tempShapeConfig == 2) {
+ switch (coreCodec) {
+ case AOT_USAC:
+ pSpatialSpecificConfig->envQuantMode = FDKreadBits(bitstream, 1);
+ break;
+ default: /* added to avoid compiler warning */
+ break; /* added to avoid compiler warning */
+ }
+ }
+
+ /* Static parameters */
+
+ pSpatialSpecificConfig->samplingFreq =
+ samplingRate; /* wrong for stereoConfigIndex == 3 but value is unused */
+ pSpatialSpecificConfig->treeConfig = SPATIALDEC_MODE_RSVD7;
+ pSpatialSpecificConfig->nOttBoxes =
+ treePropertyTable[pSpatialSpecificConfig->treeConfig].numOttBoxes;
+ pSpatialSpecificConfig->nInputChannels =
+ treePropertyTable[pSpatialSpecificConfig->treeConfig].numInputChannels;
+ pSpatialSpecificConfig->nOutputChannels =
+ treePropertyTable[pSpatialSpecificConfig->treeConfig].numOutputChannels;
+
+ pSpatialSpecificConfig->bArbitraryDownmix = 0;
+
+ for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
+ pSpatialSpecificConfig->OttConfig[i].nOttBands = 0;
+ }
+
+ if (coreCodec == AOT_DRM_USAC) {
+ /* MPS payload is MPEG conform -> no need for pseudo DRM AOT */
+ coreCodec = AOT_USAC;
+ }
+ pSpatialSpecificConfig->coreCodec = coreCodec;
+
+ /* Derive additional helper variables */
+ SpatialDecDecodeHelperInfo(pSpatialSpecificConfig, UPMIXTYPE_NORMAL);
+
+ return MPS_OK;
+}
+
+SACDEC_ERROR SpatialDecParseSpecificConfig(
+ HANDLE_FDK_BITSTREAM bitstream,
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig, int sacHeaderLen,
+ AUDIO_OBJECT_TYPE coreCodec) {
+ SACDEC_ERROR err = MPS_OK;
+ int i;
+ int bsSamplingFreqIndex;
+ int bsFreqRes, b3DaudioMode = 0;
+ int numHeaderBits;
+ int cfgStartPos, bitsAvailable;
+
+ FDKmemclear(pSpatialSpecificConfig, sizeof(SPATIAL_SPECIFIC_CONFIG));
+
+ cfgStartPos = FDKgetValidBits(bitstream);
+ /* It might be that we do not know the SSC length beforehand. */
+ if (sacHeaderLen == 0) {
+ bitsAvailable = cfgStartPos;
+ } else {
+ bitsAvailable = 8 * sacHeaderLen;
+ if (bitsAvailable > cfgStartPos) {
+ err = MPS_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ bsSamplingFreqIndex = FDKreadBits(bitstream, 4);
+
+ if (bsSamplingFreqIndex == 15) {
+ pSpatialSpecificConfig->samplingFreq = FDKreadBits(bitstream, 24);
+ } else {
+ pSpatialSpecificConfig->samplingFreq =
+ samplingFreqTable[bsSamplingFreqIndex];
+ if (pSpatialSpecificConfig->samplingFreq == 0) {
+ err = MPS_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ pSpatialSpecificConfig->nTimeSlots = FDKreadBits(bitstream, 5) + 1;
+ if ((pSpatialSpecificConfig->nTimeSlots < 1) ||
+ (pSpatialSpecificConfig->nTimeSlots > MAX_TIME_SLOTS)) {
+ err = MPS_PARSE_ERROR;
+ goto bail;
+ }
+
+ bsFreqRes = FDKreadBits(bitstream, 3);
+
+ pSpatialSpecificConfig->freqRes =
+ (SPATIALDEC_FREQ_RES)freqResTable_LD[bsFreqRes];
+
+ pSpatialSpecificConfig->treeConfig =
+ (SPATIALDEC_TREE_CONFIG)FDKreadBits(bitstream, 4);
+
+ if (pSpatialSpecificConfig->treeConfig != SPATIALDEC_MODE_RSVD7) {
+ err = MPS_UNSUPPORTED_CONFIG;
+ goto bail;
+ }
+
+ {
+ pSpatialSpecificConfig->nOttBoxes =
+ treePropertyTable[pSpatialSpecificConfig->treeConfig].numOttBoxes;
+ pSpatialSpecificConfig->nTttBoxes =
+ treePropertyTable[pSpatialSpecificConfig->treeConfig].numTttBoxes;
+ pSpatialSpecificConfig->nInputChannels =
+ treePropertyTable[pSpatialSpecificConfig->treeConfig].numInputChannels;
+ pSpatialSpecificConfig->nOutputChannels =
+ treePropertyTable[pSpatialSpecificConfig->treeConfig].numOutputChannels;
+ }
+
+ pSpatialSpecificConfig->quantMode =
+ (SPATIALDEC_QUANT_MODE)FDKreadBits(bitstream, 2);
+
+ pSpatialSpecificConfig->bArbitraryDownmix = FDKreadBits(bitstream, 1);
+
+ pSpatialSpecificConfig->bsFixedGainDMX =
+ (SPATIALDEC_FIXED_GAINS)FDKreadBits(bitstream, 3);
+
+ pSpatialSpecificConfig->tempShapeConfig =
+ (SPATIALDEC_TS_CONF)FDKreadBits(bitstream, 2);
+ if (pSpatialSpecificConfig->tempShapeConfig > 2) {
+ return MPS_PARSE_ERROR; /* reserved value */
+ }
+
+ pSpatialSpecificConfig->decorrConfig =
+ (SPATIALDEC_DECORR_CONF)FDKreadBits(bitstream, 2);
+ if (pSpatialSpecificConfig->decorrConfig > 2) {
+ return MPS_PARSE_ERROR; /* reserved value */
+ }
+
+ for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
+ pSpatialSpecificConfig->OttConfig[i].nOttBands = 0;
+ }
+
+ for (i = 0; i < pSpatialSpecificConfig->nTttBoxes; i++) {
+ int bTttDualMode = FDKreadBits(bitstream, 1);
+ FDKreadBits(bitstream, 3); /* not supported */
+
+ if (bTttDualMode) {
+ FDKreadBits(bitstream, 8); /* not supported */
+ }
+ }
+
+ if (pSpatialSpecificConfig->tempShapeConfig == 2) {
+ pSpatialSpecificConfig->envQuantMode = FDKreadBits(bitstream, 1);
+ }
+
+ if (b3DaudioMode) {
+ if (FDKreadBits(bitstream, 2) == 0) { /* b3DaudioHRTFset ? */
+ int hc;
+ int HRTFnumBand;
+ int HRTFfreqRes = FDKreadBits(bitstream, 3);
+ int HRTFnumChan = FDKreadBits(bitstream, 4);
+ int HRTFasymmetric = FDKreadBits(bitstream, 1);
+
+ HRTFnumBand = freqResTable_LD[HRTFfreqRes];
+
+ for (hc = 0; hc < HRTFnumChan; hc++) {
+ FDKpushFor(bitstream, HRTFnumBand * 6); /* HRTFlevelLeft[hc][hb] */
+ if (HRTFasymmetric) {
+ FDKpushFor(bitstream, HRTFnumBand * 6); /* HRTFlevelRight[hc][hb] */
+ }
+ if (FDKreadBits(bitstream, 1)) { /* HRTFphase[hc] ? */
+ FDKpushFor(bitstream, HRTFnumBand * 6); /* HRTFphaseLR[hc][hb] */
+ }
+ if (FDKreadBits(bitstream, 1)) { /* HRTFicc[hc] ? */
+ FDKpushFor(bitstream, HRTFnumBand * 6); /* HRTFiccLR[hc][hb] */
+ }
+ }
+ }
+ }
+
+ FDKbyteAlign(bitstream,
+ cfgStartPos); /* ISO/IEC FDIS 23003-1: 5.2. ... byte alignment
+ with respect to the beginning of the syntactic
+ element in which ByteAlign() occurs. */
+
+ numHeaderBits = cfgStartPos - (INT)FDKgetValidBits(bitstream);
+ bitsAvailable -= numHeaderBits;
+ if (bitsAvailable < 0) {
+ err = MPS_PARSE_ERROR;
+ goto bail;
+ }
+
+ pSpatialSpecificConfig->sacExtCnt = 0;
+ pSpatialSpecificConfig->bResidualCoding = 0;
+
+ err = SpatialDecParseExtensionConfig(
+ bitstream, pSpatialSpecificConfig, pSpatialSpecificConfig->nOttBoxes,
+ pSpatialSpecificConfig->nTttBoxes,
+ pSpatialSpecificConfig->nOutputChannels, bitsAvailable);
+
+ FDKbyteAlign(
+ bitstream,
+ cfgStartPos); /* Same alignment anchor as above because
+ SpatialExtensionConfig() always reads full bytes */
+
+ pSpatialSpecificConfig->coreCodec = coreCodec;
+
+ SpatialDecDecodeHelperInfo(pSpatialSpecificConfig, UPMIXTYPE_NORMAL);
+
+bail:
+ if (sacHeaderLen > 0) {
+ /* If the config is of known length then assure that the
+ bitbuffer is exactly at its end when leaving the function. */
+ FDKpushBiDirectional(
+ bitstream,
+ (sacHeaderLen * 8) - (cfgStartPos - (INT)FDKgetValidBits(bitstream)));
+ }
+
+ return err;
+}
+
+int SpatialDecDefaultSpecificConfig(
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
+ AUDIO_OBJECT_TYPE coreCodec, int samplingFreq, int nTimeSlots,
+ int sacDecoderLevel, int isBlind, int numCoreChannels)
+
+{
+ int err = MPS_OK;
+ int i;
+
+ FDK_ASSERT(coreCodec != AOT_NONE);
+ FDK_ASSERT(nTimeSlots > 0);
+ FDK_ASSERT(samplingFreq > 0);
+
+ pSpatialSpecificConfig->coreCodec = coreCodec;
+ pSpatialSpecificConfig->samplingFreq = samplingFreq;
+ pSpatialSpecificConfig->nTimeSlots = nTimeSlots;
+ if ((pSpatialSpecificConfig->coreCodec == AOT_ER_AAC_ELD) ||
+ (pSpatialSpecificConfig->coreCodec == AOT_ER_AAC_LD))
+ pSpatialSpecificConfig->freqRes = SPATIALDEC_FREQ_RES_23;
+ else
+ pSpatialSpecificConfig->freqRes = SPATIALDEC_FREQ_RES_28;
+
+ {
+ pSpatialSpecificConfig->treeConfig =
+ SPATIALDEC_MODE_RSVD7; /* 212 configuration */
+ }
+
+ {
+ pSpatialSpecificConfig->nOttBoxes =
+ treePropertyTable[pSpatialSpecificConfig->treeConfig].numOttBoxes;
+ pSpatialSpecificConfig->nInputChannels =
+ treePropertyTable[pSpatialSpecificConfig->treeConfig].numInputChannels;
+ pSpatialSpecificConfig->nOutputChannels =
+ treePropertyTable[pSpatialSpecificConfig->treeConfig].numOutputChannels;
+ }
+
+ pSpatialSpecificConfig->quantMode = SPATIALDEC_QUANT_FINE_DEF;
+ pSpatialSpecificConfig->bArbitraryDownmix = 0;
+ pSpatialSpecificConfig->bResidualCoding = 0;
+ if ((pSpatialSpecificConfig->coreCodec == AOT_ER_AAC_ELD) ||
+ (pSpatialSpecificConfig->coreCodec == AOT_ER_AAC_LD))
+ pSpatialSpecificConfig->bsFixedGainDMX = SPATIALDEC_GAIN_RSVD2;
+ else
+ pSpatialSpecificConfig->bsFixedGainDMX = SPATIALDEC_GAIN_MODE0;
+
+ pSpatialSpecificConfig->tempShapeConfig = SPATIALDEC_TS_TPNOWHITE;
+ pSpatialSpecificConfig->decorrConfig = SPATIALDEC_DECORR_MODE0;
+
+ for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
+ pSpatialSpecificConfig->OttConfig[i].nOttBands = 0;
+ }
+
+ return err;
+}
+
+/*******************************************************************************
+ Functionname: coarse2fine
+ *******************************************************************************
+
+ Description:
+ Parameter index mapping from coarse to fine quantization
+
+ Arguments:
+
+Input:
+
+Output:
+
+*******************************************************************************/
+static void coarse2fine(SCHAR *data, DATA_TYPE dataType, int startBand,
+ int numBands) {
+ int i;
+
+ for (i = startBand; i < startBand + numBands; i++) {
+ data[i] <<= 1;
+ }
+
+ if (dataType == t_CLD) {
+ for (i = startBand; i < startBand + numBands; i++) {
+ if (data[i] == -14)
+ data[i] = -15;
+ else if (data[i] == 14)
+ data[i] = 15;
+ }
+ }
+}
+
+/*******************************************************************************
+ Functionname: fine2coarse
+ *******************************************************************************
+
+ Description:
+ Parameter index mapping from fine to coarse quantization
+
+ Arguments:
+
+Input:
+
+Output:
+
+*******************************************************************************/
+static void fine2coarse(SCHAR *data, DATA_TYPE dataType, int startBand,
+ int numBands) {
+ int i;
+
+ for (i = startBand; i < startBand + numBands; i++) {
+ /* Note: the if cases below actually make a difference (negative values) */
+ if (dataType == t_CLD)
+ data[i] /= 2;
+ else
+ data[i] >>= 1;
+ }
+}
+
+/*******************************************************************************
+ Functionname: getStrideMap
+ *******************************************************************************
+
+ Description:
+ Index Mapping accroding to pbStrides
+
+ Arguments:
+
+Input:
+
+Output:
+
+*******************************************************************************/
+static int getStrideMap(int freqResStride, int startBand, int stopBand,
+ int *aStrides) {
+ int i, pb, pbStride, dataBands, strOffset;
+
+ pbStride = pbStrideTable[freqResStride];
+ dataBands = (stopBand - startBand - 1) / pbStride + 1;
+
+ aStrides[0] = startBand;
+ for (pb = 1; pb <= dataBands; pb++) {
+ aStrides[pb] = aStrides[pb - 1] + pbStride;
+ }
+ strOffset = 0;
+ while (aStrides[dataBands] > stopBand) {
+ if (strOffset < dataBands) strOffset++;
+ for (i = strOffset; i <= dataBands; i++) {
+ aStrides[i]--;
+ }
+ }
+
+ return dataBands;
+}
+
+/*******************************************************************************
+ Functionname: ecDataDec
+ *******************************************************************************
+
+ Description:
+ Do delta decoding and dequantization
+
+ Arguments:
+
+Input:
+
+Output:
+
+
+*******************************************************************************/
+
+static SACDEC_ERROR ecDataDec(
+ const SPATIAL_BS_FRAME *frame, UINT syntaxFlags,
+ HANDLE_FDK_BITSTREAM bitstream, LOSSLESSDATA *const llData,
+ SCHAR (*data)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS], SCHAR **lastdata,
+ int datatype, int boxIdx, int startBand, int stopBand, SCHAR defaultValue) {
+ SACDEC_ERROR err = MPS_OK;
+ int i, j, pb, dataSets, setIdx, bsDataPair, dataBands, oldQuantCoarseXXX;
+ INT aStrides[MAX_PARAMETER_BANDS + 1] = {0};
+
+ dataSets = 0;
+ for (i = 0; i < frame->numParameterSets; i++) {
+ llData->bsXXXDataMode[i] = (SCHAR)FDKreadBits(bitstream, 2);
+
+ if ((frame->bsIndependencyFlag == 1) && (i == 0) &&
+ (llData->bsXXXDataMode[i] == 1 ||
+ llData->bsXXXDataMode[i] == 2)) { /* This check catches bitstreams
+ generated by older encoder that
+ cause trouble */
+ return MPS_PARSE_ERROR;
+ }
+ if ((i >= frame->numParameterSets - 1) &&
+ (llData->bsXXXDataMode[i] ==
+ 2)) { /* The interpolation mode must not be active for the last
+ parameter set */
+ return MPS_PARSE_ERROR;
+ }
+
+ if (llData->bsXXXDataMode[i] == 3) {
+ dataSets++;
+ }
+ }
+
+ setIdx = 0;
+ bsDataPair = 0;
+ oldQuantCoarseXXX = llData->state->bsQuantCoarseXXXprevParse;
+
+ for (i = 0; i < frame->numParameterSets; i++) {
+ if (llData->bsXXXDataMode[i] == 0) {
+ for (pb = startBand; pb < stopBand; pb++) {
+ lastdata[boxIdx][pb] = defaultValue;
+ }
+
+ oldQuantCoarseXXX = 0;
+ }
+
+ if (llData->bsXXXDataMode[i] == 3) {
+ if (bsDataPair) {
+ bsDataPair = 0;
+ } else {
+ bsDataPair = FDKreadBits(bitstream, 1);
+ llData->bsQuantCoarseXXX[setIdx] = (UCHAR)FDKreadBits(bitstream, 1);
+ llData->bsFreqResStrideXXX[setIdx] = (UCHAR)FDKreadBits(bitstream, 2);
+
+ if (llData->bsQuantCoarseXXX[setIdx] != oldQuantCoarseXXX) {
+ if (oldQuantCoarseXXX) {
+ coarse2fine(lastdata[boxIdx], (DATA_TYPE)datatype, startBand,
+ stopBand - startBand);
+ } else {
+ fine2coarse(lastdata[boxIdx], (DATA_TYPE)datatype, startBand,
+ stopBand - startBand);
+ }
+ }
+
+ dataBands = getStrideMap(llData->bsFreqResStrideXXX[setIdx], startBand,
+ stopBand, aStrides);
+
+ for (pb = 0; pb < dataBands; pb++) {
+ lastdata[boxIdx][startBand + pb] = lastdata[boxIdx][aStrides[pb]];
+ }
+
+ if (boxIdx > MAX_NUM_OTT) return MPS_INVALID_BOXIDX;
+ if ((setIdx + bsDataPair) > MAX_PARAMETER_SETS)
+ return MPS_INVALID_SETIDX;
+
+ /* DECODER_TYPE defined in FDK_tools */
+ DECODER_TYPE this_decoder_type = SAC_DECODER;
+ if (syntaxFlags & (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) {
+ this_decoder_type = USAC_DECODER;
+ } else if (syntaxFlags & SACDEC_SYNTAX_LD) {
+ this_decoder_type = SAOC_DECODER;
+ }
+
+ err = (SACDEC_ERROR)EcDataPairDec(
+ this_decoder_type, bitstream, data[boxIdx][setIdx + 0],
+ data[boxIdx][setIdx + 1], lastdata[boxIdx], (DATA_TYPE)datatype,
+ startBand, dataBands, bsDataPair, llData->bsQuantCoarseXXX[setIdx],
+ !(frame->bsIndependencyFlag && (i == 0)) || (setIdx > 0));
+ if (err != MPS_OK) goto bail;
+
+ if (datatype == t_IPD) {
+ const SCHAR mask = (llData->bsQuantCoarseXXX[setIdx]) ? 7 : 15;
+ for (pb = 0; pb < dataBands; pb++) {
+ for (j = aStrides[pb]; j < aStrides[pb + 1]; j++) {
+ lastdata[boxIdx][j] =
+ data[boxIdx][setIdx + bsDataPair][startBand + pb] & mask;
+ }
+ }
+ } else {
+ for (pb = 0; pb < dataBands; pb++) {
+ for (j = aStrides[pb]; j < aStrides[pb + 1]; j++) {
+ lastdata[boxIdx][j] =
+ data[boxIdx][setIdx + bsDataPair][startBand + pb];
+ }
+ }
+ }
+
+ oldQuantCoarseXXX = llData->bsQuantCoarseXXX[setIdx];
+
+ if (bsDataPair) {
+ llData->bsQuantCoarseXXX[setIdx + 1] =
+ llData->bsQuantCoarseXXX[setIdx];
+ llData->bsFreqResStrideXXX[setIdx + 1] =
+ llData->bsFreqResStrideXXX[setIdx];
+ }
+ setIdx += bsDataPair + 1;
+ } /* !bsDataPair */
+ } /* llData->bsXXXDataMode[i] == 3 */
+ }
+
+ llData->state->bsQuantCoarseXXXprevParse = oldQuantCoarseXXX;
+
+bail:
+ return err;
+}
+
+/*******************************************************************************
+ Functionname: parseArbitraryDownmixData
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+static SACDEC_ERROR parseArbitraryDownmixData(
+ spatialDec *self, const SPATIAL_SPECIFIC_CONFIG *pSSC,
+ const UINT syntaxFlags, const SPATIAL_BS_FRAME *frame,
+ HANDLE_FDK_BITSTREAM bitstream) {
+ SACDEC_ERROR err = MPS_OK;
+ int ch;
+ int offset = pSSC->nOttBoxes;
+
+ /* CLD (arbitrary down-mix gains) */
+ for (ch = 0; ch < pSSC->nInputChannels; ch++) {
+ err = ecDataDec(frame, syntaxFlags, bitstream,
+ &frame->CLDLosslessData[offset + ch],
+ frame->cmpArbdmxGainIdx, self->cmpArbdmxGainIdxPrev, t_CLD,
+ ch, 0, pSSC->freqRes, arbdmxGainDefault);
+ if (err != MPS_OK) return err;
+ }
+
+ return err;
+
+} /* parseArbitraryDownmixData */
+
+/*******************************************************************************
+ Functionname: SpatialDecParseFrame
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Input:
+
+ Output:
+
+*******************************************************************************/
+
+static int nBitsParamSlot(int i) {
+ int bitsParamSlot;
+
+ bitsParamSlot = fMax(0, DFRACT_BITS - 1 - fNormz((FIXP_DBL)i));
+ if ((1 << bitsParamSlot) < i) {
+ bitsParamSlot++;
+ }
+ FDK_ASSERT((bitsParamSlot >= 0) && (bitsParamSlot <= 32));
+
+ return bitsParamSlot;
+}
+
+SACDEC_ERROR SpatialDecParseFrameData(
+ spatialDec_struct *self, SPATIAL_BS_FRAME *frame,
+ HANDLE_FDK_BITSTREAM bitstream,
+ const SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig, UPMIXTYPE upmixType,
+ int fGlobalIndependencyFlag) {
+ SACDEC_ERROR err = MPS_OK;
+ int bsFramingType, dataBands, ps, pg, i;
+ int pb;
+ int numTempShapeChan = 0;
+ int bsNumOutputChannels =
+ treePropertyTable[pSpatialSpecificConfig->treeConfig]
+ .numOutputChannels; /* CAUTION: Maybe different to
+ pSpatialSpecificConfig->treeConfig in some
+ modes! */
+ int paramSetErr = 0;
+ UINT alignAnchor = FDKgetValidBits(
+ bitstream); /* Anchor for ByteAlign() function. See comment below. */
+ UINT syntaxFlags;
+
+ syntaxFlags = pSpatialSpecificConfig->syntaxFlags;
+
+ if ((syntaxFlags & (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) &&
+ pSpatialSpecificConfig->bsHighRateMode == 0) {
+ bsFramingType = 0; /* fixed framing */
+ frame->numParameterSets = 1;
+ } else {
+ bsFramingType = FDKreadBits(bitstream, 1);
+ if (syntaxFlags & SACDEC_SYNTAX_LD)
+ frame->numParameterSets = FDKreadBits(bitstream, 1) + 1;
+ else
+ frame->numParameterSets = FDKreadBits(bitstream, 3) + 1;
+ }
+
+ /* Any error after this line shall trigger parameter invalidation at bail
+ * label. */
+ paramSetErr = 1;
+
+ if (frame->numParameterSets >= MAX_PARAMETER_SETS) {
+ goto bail;
+ }
+
+ /* Basic config check. */
+ if (pSpatialSpecificConfig->nInputChannels <= 0 ||
+ pSpatialSpecificConfig->nOutputChannels <= 0) {
+ err = MPS_UNSUPPORTED_CONFIG;
+ goto bail;
+ }
+
+ if (bsFramingType) {
+ int prevParamSlot = -1;
+ int bitsParamSlot;
+
+ {
+ bitsParamSlot = nBitsParamSlot(pSpatialSpecificConfig->nTimeSlots);
+
+ for (i = 0; i < frame->numParameterSets; i++) {
+ frame->paramSlot[i] = FDKreadBits(bitstream, bitsParamSlot);
+ /* Sanity check */
+ if ((frame->paramSlot[i] <= prevParamSlot) ||
+ (frame->paramSlot[i] >= pSpatialSpecificConfig->nTimeSlots)) {
+ err = MPS_PARSE_ERROR;
+ goto bail;
+ }
+ prevParamSlot = frame->paramSlot[i];
+ }
+ }
+ } else {
+ for (i = 0; i < frame->numParameterSets; i++) {
+ frame->paramSlot[i] = ((pSpatialSpecificConfig->nTimeSlots * (i + 1)) /
+ frame->numParameterSets) -
+ 1;
+ }
+ }
+
+ if ((syntaxFlags & (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) &&
+ fGlobalIndependencyFlag) {
+ frame->bsIndependencyFlag = 1;
+ } else {
+ frame->bsIndependencyFlag = (UCHAR)FDKreadBits(bitstream, 1);
+ }
+
+ /*
+ * OttData()
+ */
+ for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
+ err = ecDataDec(frame, syntaxFlags, bitstream, &frame->CLDLosslessData[i],
+ frame->cmpOttCLDidx, self->cmpOttCLDidxPrev, t_CLD, i, 0,
+ pSpatialSpecificConfig->bitstreamOttBands[i],
+ pSpatialSpecificConfig->ottCLDdefault[i]);
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ } /* i < numOttBoxes */
+
+ {
+ for (i = 0; i < pSpatialSpecificConfig->nOttBoxes; i++) {
+ err = ecDataDec(frame, syntaxFlags, bitstream, &frame->ICCLosslessData[i],
+ frame->cmpOttICCidx, self->cmpOttICCidxPrev, t_ICC, i, 0,
+ pSpatialSpecificConfig->bitstreamOttBands[i], ICCdefault);
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ } /* i < numOttBoxes */
+ } /* !oneICC */
+
+ if ((pSpatialSpecificConfig->treeConfig == SPATIALDEC_MODE_RSVD7) &&
+ (pSpatialSpecificConfig->bsPhaseCoding)) {
+ frame->phaseMode = FDKreadBits(bitstream, 1);
+
+ if (frame->phaseMode == 0) {
+ for (pb = 0; pb < pSpatialSpecificConfig->numOttBandsIPD; pb++) {
+ self->cmpOttIPDidxPrev[0][pb] = 0;
+ for (i = 0; i < frame->numParameterSets; i++) {
+ frame->cmpOttIPDidx[0][i][pb] = 0;
+ // frame->ottIPDidx[0][i][pb] = 0;
+ }
+ /* self->ottIPDidxPrev[0][pb] = 0; */
+ }
+ frame->OpdSmoothingMode = 0;
+ } else {
+ frame->OpdSmoothingMode = FDKreadBits(bitstream, 1);
+ err = ecDataDec(frame, syntaxFlags, bitstream, &frame->IPDLosslessData[0],
+ frame->cmpOttIPDidx, self->cmpOttIPDidxPrev, t_IPD, 0, 0,
+ pSpatialSpecificConfig->numOttBandsIPD, IPDdefault);
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ }
+ }
+
+ /*
+ * SmgData()
+ */
+
+ {
+ if (!pSpatialSpecificConfig->bsHighRateMode &&
+ (syntaxFlags & SACDEC_SYNTAX_USAC)) {
+ for (ps = 0; ps < frame->numParameterSets; ps++) {
+ frame->bsSmoothMode[ps] = 0;
+ }
+ } else {
+ for (ps = 0; ps < frame->numParameterSets; ps++) {
+ frame->bsSmoothMode[ps] = (UCHAR)FDKreadBits(bitstream, 2);
+ if (frame->bsSmoothMode[ps] >= 2) {
+ frame->bsSmoothTime[ps] = (UCHAR)FDKreadBits(bitstream, 2);
+ }
+ if (frame->bsSmoothMode[ps] == 3) {
+ frame->bsFreqResStrideSmg[ps] = (UCHAR)FDKreadBits(bitstream, 2);
+ dataBands = (pSpatialSpecificConfig->freqRes - 1) /
+ pbStrideTable[frame->bsFreqResStrideSmg[ps]] +
+ 1;
+ for (pg = 0; pg < dataBands; pg++) {
+ frame->bsSmgData[ps][pg] = (UCHAR)FDKreadBits(bitstream, 1);
+ }
+ }
+ } /* ps < numParameterSets */
+ }
+ }
+
+ /*
+ * TempShapeData()
+ */
+ if ((pSpatialSpecificConfig->tempShapeConfig == 3) &&
+ (syntaxFlags & SACDEC_SYNTAX_USAC)) {
+ int TsdErr;
+ TsdErr = TsdRead(bitstream, pSpatialSpecificConfig->nTimeSlots,
+ &frame->TsdData[0]);
+ if (TsdErr) {
+ err = MPS_PARSE_ERROR;
+ goto bail;
+ }
+ } else {
+ frame->TsdData[0].bsTsdEnable = 0;
+ }
+
+ for (i = 0; i < bsNumOutputChannels; i++) {
+ frame->tempShapeEnableChannelSTP[i] = 0;
+ frame->tempShapeEnableChannelGES[i] = 0;
+ }
+
+ if ((pSpatialSpecificConfig->tempShapeConfig == 1) ||
+ (pSpatialSpecificConfig->tempShapeConfig == 2)) {
+ int bsTempShapeEnable = FDKreadBits(bitstream, 1);
+ if (bsTempShapeEnable) {
+ numTempShapeChan =
+ tempShapeChanTable[pSpatialSpecificConfig->tempShapeConfig - 1]
+ [pSpatialSpecificConfig->treeConfig];
+ switch (pSpatialSpecificConfig->tempShapeConfig) {
+ case 1: /* STP */
+ for (i = 0; i < numTempShapeChan; i++) {
+ int stpEnable = FDKreadBits(bitstream, 1);
+ frame->tempShapeEnableChannelSTP[i] = stpEnable;
+ }
+ break;
+ case 2: /* GES */
+ {
+ UCHAR gesChannelEnable[MAX_OUTPUT_CHANNELS];
+
+ for (i = 0; i < numTempShapeChan; i++) {
+ gesChannelEnable[i] = (UCHAR)FDKreadBits(bitstream, 1);
+ frame->tempShapeEnableChannelGES[i] = gesChannelEnable[i];
+ }
+ for (i = 0; i < numTempShapeChan; i++) {
+ if (gesChannelEnable[i]) {
+ int envShapeData_tmp[MAX_TIME_SLOTS];
+ if (huff_dec_reshape(bitstream, envShapeData_tmp,
+ pSpatialSpecificConfig->nTimeSlots) != 0) {
+ err = MPS_PARSE_ERROR;
+ goto bail;
+ }
+ for (int ts = 0; ts < pSpatialSpecificConfig->nTimeSlots; ts++) {
+ if (!(envShapeData_tmp[ts] >= 0) &&
+ (envShapeData_tmp[ts] <= 4)) {
+ err = MPS_PARSE_ERROR;
+ goto bail;
+ }
+ frame->bsEnvShapeData[i][ts] = (UCHAR)envShapeData_tmp[ts];
+ }
+ }
+ }
+ } break;
+ default:
+ err = MPS_INVALID_TEMPSHAPE;
+ goto bail;
+ }
+ } /* bsTempShapeEnable */
+ } /* pSpatialSpecificConfig->tempShapeConfig != 0 */
+
+ if (pSpatialSpecificConfig->bArbitraryDownmix != 0) {
+ err = parseArbitraryDownmixData(self, pSpatialSpecificConfig, syntaxFlags,
+ frame, bitstream);
+ if (err != MPS_OK) goto bail;
+ }
+
+ if (1 && (!(syntaxFlags & (SACDEC_SYNTAX_USAC)))) {
+ FDKbyteAlign(bitstream,
+ alignAnchor); /* ISO/IEC FDIS 23003-1: 5.2. ... byte alignment
+ with respect to the beginning of the syntactic
+ element in which ByteAlign() occurs. */
+ }
+
+bail:
+ if (err != MPS_OK && paramSetErr != 0) {
+ /* Since the parameter set data has already been written to the instance we
+ * need to ... */
+ frame->numParameterSets = 0; /* ... signal that it is corrupt ... */
+ }
+
+ return err;
+
+} /* SpatialDecParseFrame */
+
+/*******************************************************************************
+ Functionname: createMapping
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+static void createMapping(int aMap[MAX_PARAMETER_BANDS + 1], int startBand,
+ int stopBand, int stride) {
+ int inBands, outBands, bandsAchived, bandsDiff, incr, k, i;
+ int vDk[MAX_PARAMETER_BANDS + 1];
+ inBands = stopBand - startBand;
+ outBands = (inBands - 1) / stride + 1;
+
+ if (outBands < 1) {
+ outBands = 1;
+ }
+
+ bandsAchived = outBands * stride;
+ bandsDiff = inBands - bandsAchived;
+ for (i = 0; i < outBands; i++) {
+ vDk[i] = stride;
+ }
+
+ if (bandsDiff > 0) {
+ incr = -1;
+ k = outBands - 1;
+ } else {
+ incr = 1;
+ k = 0;
+ }
+
+ while (bandsDiff != 0) {
+ vDk[k] = vDk[k] - incr;
+ k = k + incr;
+ bandsDiff = bandsDiff + incr;
+ if (k >= outBands) {
+ if (bandsDiff > 0) {
+ k = outBands - 1;
+ } else if (bandsDiff < 0) {
+ k = 0;
+ }
+ }
+ }
+ aMap[0] = startBand;
+ for (i = 0; i < outBands; i++) {
+ aMap[i + 1] = aMap[i] + vDk[i];
+ }
+} /* createMapping */
+
+/*******************************************************************************
+ Functionname: mapFrequency
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+static void mapFrequency(const SCHAR *pInput, /* Input */
+ SCHAR *pOutput, /* Output */
+ int *pMap, /* Mapping function */
+ int dataBands) /* Number of data Bands */
+{
+ int i, j;
+ int startBand0 = pMap[0];
+
+ for (i = 0; i < dataBands; i++) {
+ int startBand, stopBand, value;
+
+ value = pInput[i + startBand0];
+
+ startBand = pMap[i];
+ stopBand = pMap[i + 1];
+ for (j = startBand; j < stopBand; j++) {
+ pOutput[j] = value;
+ }
+ }
+}
+
+/*******************************************************************************
+ Functionname: deq
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+static int deqIdx(int value, int paramType) {
+ int idx = -1;
+
+ switch (paramType) {
+ case t_CLD:
+ if (((value + 15) >= 0) && ((value + 15) < 31)) {
+ idx = (value + 15);
+ }
+ break;
+
+ case t_ICC:
+ if ((value >= 0) && (value < 8)) {
+ idx = value;
+ }
+ break;
+
+ case t_IPD:
+ /* (+/-)15 * MAX_PARAMETER_BANDS for differential coding in frequency
+ * domain (according to rbl) */
+ if ((value >= -420) && (value <= 420)) {
+ idx = (value & 0xf);
+ }
+ break;
+
+ default:
+ FDK_ASSERT(0);
+ }
+
+ return idx;
+}
+
+ /*******************************************************************************
+ Functionname: factorFunct
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+ *******************************************************************************/
+
+#define SF_IDX (7)
+#define SF_FACTOR (3)
+#define SCALE_FACTOR (1 << SF_FACTOR)
+#define SCALE_CLD_C1C2 (1 << SF_CLD_C1C2)
+
+static FIXP_DBL factorFunct(FIXP_DBL ottVsTotDb, INT quantMode) {
+ FIXP_DBL factor;
+
+ if (ottVsTotDb > FL2FXCONST_DBL(0.0)) {
+ ottVsTotDb = FL2FXCONST_DBL(0.0);
+ }
+
+ ottVsTotDb = -ottVsTotDb;
+
+ switch (quantMode) {
+ case 0:
+ factor = FL2FXCONST_DBL(1.0f / SCALE_FACTOR);
+ break;
+ case 1:
+ if (ottVsTotDb >= FL2FXCONST_DBL(21.0f / SCALE_CLD_C1C2))
+ factor = FL2FXCONST_DBL(5.0f / SCALE_FACTOR);
+ else if (ottVsTotDb <= FL2FXCONST_DBL(1.0f / SCALE_CLD_C1C2))
+ factor = FL2FXCONST_DBL(1.0f / SCALE_FACTOR);
+ else
+ factor = (fMult(FL2FXCONST_DBL(0.2f), ottVsTotDb) +
+ FL2FXCONST_DBL(0.8f / SCALE_CLD_C1C2))
+ << (SF_CLD_C1C2 - SF_FACTOR);
+ break;
+ case 2:
+ if (ottVsTotDb >= FL2FXCONST_DBL(25.0f / SCALE_CLD_C1C2)) {
+ FDK_ASSERT(SF_FACTOR == 3);
+ factor = (FIXP_DBL)
+ MAXVAL_DBL; /* avoid warning: FL2FXCONST_DBL(8.0f/SCALE_FACTOR) */
+ } else if (ottVsTotDb <= FL2FXCONST_DBL(1.0f / SCALE_CLD_C1C2))
+ factor = FL2FXCONST_DBL(1.0f / SCALE_FACTOR);
+ else
+ factor = (fMult(FL2FXCONST_DBL(7.0f / 24.0f), ottVsTotDb) +
+ FL2FXCONST_DBL((17.0f / 24.0f) / SCALE_CLD_C1C2))
+ << (SF_CLD_C1C2 - SF_FACTOR);
+ break;
+ default:
+ factor = FL2FXCONST_DBL(0.0f);
+ }
+
+ return (factor);
+}
+
+/*******************************************************************************
+ Functionname: factorCLD
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+static void factorCLD(SCHAR *idx, FIXP_DBL ottVsTotDb, FIXP_DBL *ottVsTotDb1,
+ FIXP_DBL *ottVsTotDb2, SCHAR ottVsTotDbMode,
+ INT quantMode) {
+ FIXP_DBL factor;
+ FIXP_DBL cldIdxFract;
+ INT cldIdx;
+
+ factor = factorFunct(ottVsTotDb, quantMode);
+
+ cldIdxFract =
+ fMult((FIXP_DBL)((*idx) << ((DFRACT_BITS - 1) - SF_IDX)), factor);
+ cldIdxFract += FL2FXCONST_DBL(15.5f / (1 << (SF_FACTOR + SF_IDX)));
+ cldIdx = fixp_truncateToInt(cldIdxFract, SF_FACTOR + SF_IDX);
+
+ cldIdx = fMin(cldIdx, 30);
+ cldIdx = fMax(cldIdx, 0);
+
+ *idx = cldIdx - 15;
+
+ if (ottVsTotDbMode & ottVsTotDb1Activ)
+ (*ottVsTotDb1) = ottVsTotDb + dequantCLD_c1[cldIdx];
+
+ if (ottVsTotDbMode & ottVsTotDb2Activ)
+ (*ottVsTotDb2) = ottVsTotDb + dequantCLD_c1[30 - cldIdx];
+}
+
+/*******************************************************************************
+ Functionname: mapIndexData
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+static SACDEC_ERROR mapIndexData(
+ LOSSLESSDATA *llData, SCHAR ***outputDataIdx, SCHAR ***outputIdxData,
+ const SCHAR (*cmpIdxData)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],
+ SCHAR ***diffIdxData, SCHAR xttIdx, SCHAR **idxPrev, int paramIdx,
+ int paramType, int startBand, int stopBand, SCHAR defaultValue,
+ int numParameterSets, const int *paramSlot, int extendFrame, int quantMode,
+ SpatialDecConcealmentInfo *concealmentInfo, SCHAR ottVsTotDbMode,
+ FIXP_DBL (*pOttVsTotDbIn)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],
+ FIXP_DBL (*pOttVsTotDb1)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],
+ FIXP_DBL (*pOttVsTotDb2)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS]) {
+ int aParamSlots[MAX_PARAMETER_SETS];
+ int aInterpolate[MAX_PARAMETER_SETS];
+
+ int dataSets;
+ int aMap[MAX_PARAMETER_BANDS + 1];
+
+ int setIdx, i, band, parmSlot;
+ int dataBands;
+ int ps, pb;
+ int i1;
+
+ if (numParameterSets > MAX_PARAMETER_SETS) return MPS_WRONG_PARAMETERSETS;
+
+ dataSets = 0;
+ for (i = 0; i < numParameterSets; i++) {
+ if (llData->bsXXXDataMode[i] == 3) {
+ aParamSlots[dataSets] = i;
+ dataSets++;
+ }
+ }
+
+ setIdx = 0;
+
+ /* Main concealment stage is here: */
+ SpatialDecConcealment_Apply(
+ concealmentInfo, cmpIdxData[xttIdx],
+ (diffIdxData != NULL) ? diffIdxData[xttIdx] : NULL, idxPrev[xttIdx],
+ llData->bsXXXDataMode, startBand, stopBand, defaultValue, paramType,
+ numParameterSets);
+
+ /* Prepare data */
+ for (i = 0; i < numParameterSets; i++) {
+ if (llData->bsXXXDataMode[i] == 0) {
+ llData->nocmpQuantCoarseXXX[i] = 0;
+ for (band = startBand; band < stopBand; band++) {
+ outputIdxData[xttIdx][i][band] = defaultValue;
+ }
+ for (band = startBand; band < stopBand; band++) {
+ idxPrev[xttIdx][band] = outputIdxData[xttIdx][i][band];
+ }
+ /* Because the idxPrev are also set to the defaultValue -> signalize fine
+ */
+ llData->state->bsQuantCoarseXXXprev = 0;
+ }
+
+ if (llData->bsXXXDataMode[i] == 1) {
+ for (band = startBand; band < stopBand; band++) {
+ outputIdxData[xttIdx][i][band] = idxPrev[xttIdx][band];
+ }
+ llData->nocmpQuantCoarseXXX[i] = llData->state->bsQuantCoarseXXXprev;
+ }
+
+ if (llData->bsXXXDataMode[i] == 2) {
+ for (band = startBand; band < stopBand; band++) {
+ outputIdxData[xttIdx][i][band] = idxPrev[xttIdx][band];
+ }
+ llData->nocmpQuantCoarseXXX[i] = llData->state->bsQuantCoarseXXXprev;
+ aInterpolate[i] = 1;
+ } else {
+ aInterpolate[i] = 0;
+ }
+
+ if (llData->bsXXXDataMode[i] == 3) {
+ int stride;
+
+ parmSlot = aParamSlots[setIdx];
+ stride = pbStrideTable[llData->bsFreqResStrideXXX[setIdx]];
+ dataBands = (stopBand - startBand - 1) / stride + 1;
+ createMapping(aMap, startBand, stopBand, stride);
+ mapFrequency(&cmpIdxData[xttIdx][setIdx][0],
+ &outputIdxData[xttIdx][parmSlot][0], aMap, dataBands);
+ for (band = startBand; band < stopBand; band++) {
+ idxPrev[xttIdx][band] = outputIdxData[xttIdx][parmSlot][band];
+ }
+ llData->state->bsQuantCoarseXXXprev = llData->bsQuantCoarseXXX[setIdx];
+ llData->nocmpQuantCoarseXXX[i] = llData->bsQuantCoarseXXX[setIdx];
+
+ setIdx++;
+ }
+ if (diffIdxData != NULL) {
+ for (band = startBand; band < stopBand; band++) {
+ outputIdxData[xttIdx][i][band] += diffIdxData[xttIdx][i][band];
+ }
+ }
+ } /* for( i = 0 ; i < numParameterSets; i++ ) */
+
+ /* Map all coarse data to fine */
+ for (i = 0; i < numParameterSets; i++) {
+ if (llData->nocmpQuantCoarseXXX[i] == 1) {
+ coarse2fine(outputIdxData[xttIdx][i], (DATA_TYPE)paramType, startBand,
+ stopBand - startBand);
+ llData->nocmpQuantCoarseXXX[i] = 0;
+ }
+ }
+
+ /* Interpolate */
+ i1 = 0;
+ for (i = 0; i < numParameterSets; i++) {
+ int xi, i2, x1, x2;
+
+ if (aInterpolate[i] != 1) {
+ i1 = i;
+ }
+ i2 = i;
+ while (aInterpolate[i2] == 1) {
+ i2++;
+ }
+ x1 = paramSlot[i1];
+ xi = paramSlot[i];
+ x2 = paramSlot[i2];
+
+ if (aInterpolate[i] == 1) {
+ if (i2 >= numParameterSets) return MPS_WRONG_PARAMETERSETS;
+ for (band = startBand; band < stopBand; band++) {
+ int yi, y1, y2;
+ y1 = outputIdxData[xttIdx][i1][band];
+ y2 = outputIdxData[xttIdx][i2][band];
+ if (x1 != x2) {
+ yi = y1 + (xi - x1) * (y2 - y1) / (x2 - x1);
+ } else {
+ yi = y1 /*+ (xi-x1)*(y2-y1)/1e-12*/;
+ }
+ outputIdxData[xttIdx][i][band] = yi;
+ }
+ }
+ } /* for( i = 0 ; i < numParameterSets; i++ ) */
+
+ /* Dequantize data and apply factorCLD if necessary */
+ for (ps = 0; ps < numParameterSets; ps++) {
+ if (quantMode && (paramType == t_CLD)) {
+ if (pOttVsTotDbIn == 0) return MPS_WRONG_OTT;
+ if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode == ottVsTotDb1Activ))
+ return MPS_WRONG_OTT;
+ if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode == ottVsTotDb2Activ))
+ return MPS_WRONG_OTT;
+
+ for (pb = startBand; pb < stopBand; pb++) {
+ factorCLD(&(outputIdxData[xttIdx][ps][pb]), (*pOttVsTotDbIn)[ps][pb],
+ (pOttVsTotDb1 != NULL) ? &((*pOttVsTotDb1)[ps][pb]) : NULL,
+ (pOttVsTotDb2 != NULL) ? &((*pOttVsTotDb2)[ps][pb]) : NULL,
+ ottVsTotDbMode, quantMode);
+ }
+ }
+
+ /* Dequantize data */
+ for (band = startBand; band < stopBand; band++) {
+ outputDataIdx[xttIdx][ps][band] =
+ deqIdx(outputIdxData[xttIdx][ps][band], paramType);
+ if (outputDataIdx[xttIdx][ps][band] == -1) {
+ outputDataIdx[xttIdx][ps][band] = defaultValue;
+ }
+ }
+ } /* for( i = 0 ; i < numParameterSets; i++ ) */
+
+ if (extendFrame) {
+ for (band = startBand; band < stopBand; band++) {
+ outputDataIdx[xttIdx][numParameterSets][band] =
+ outputDataIdx[xttIdx][numParameterSets - 1][band];
+ }
+ }
+
+ return MPS_OK;
+}
+
+/*******************************************************************************
+ Functionname: decodeAndMapFrameOtt
+ *******************************************************************************
+
+ Description:
+ Do delta decoding and dequantization
+
+ Arguments:
+
+Input:
+
+Output:
+
+*******************************************************************************/
+static SACDEC_ERROR decodeAndMapFrameOtt(HANDLE_SPATIAL_DEC self,
+ SPATIAL_BS_FRAME *pCurBs) {
+ int i, ottIdx;
+ int numOttBoxes;
+
+ SACDEC_ERROR err = MPS_OK;
+
+ numOttBoxes = self->numOttBoxes;
+
+ switch (self->treeConfig) {
+ default: {
+ if (self->quantMode != 0) {
+ goto bail;
+ }
+ }
+ for (i = 0; i < numOttBoxes; i++) {
+ err = mapIndexData(
+ &pCurBs->CLDLosslessData[i], /* LOSSLESSDATA *llData,*/
+ self->ottCLD__FDK, self->outIdxData,
+ pCurBs
+ ->cmpOttCLDidx, /* int
+ cmpIdxData[MAX_NUM_OTT][MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],
+ */
+ NULL, /* no differential data */
+ i, /* int xttIdx, Which ott/ttt index to use for input and
+ output buffers */
+ self->ottCLDidxPrev, /* int
+ idxPrev[MAX_NUM_OTT][MAX_PARAMETER_BANDS],
+ */
+ i, t_CLD, 0, /* int startBand, */
+ self->pConfigCurrent->bitstreamOttBands[i], /* int stopBand, */
+ self->pConfigCurrent->ottCLDdefault[i], /* int defaultValue, */
+ pCurBs->numParameterSets, /* int numParameterSets) */
+ pCurBs->paramSlot, self->extendFrame, self->quantMode,
+ &(self->concealInfo), ottVsTotInactiv, NULL, NULL, NULL);
+ if (err != MPS_OK) goto bail;
+
+ } /* for(i = 0; i < numOttBoxes ; i++ ) */
+ break;
+ } /* case */
+
+ for (ottIdx = 0; ottIdx < numOttBoxes; ottIdx++) {
+ /* Read ICC */
+ err = mapIndexData(
+ &pCurBs->ICCLosslessData[ottIdx], /* LOSSLESSDATA *llData,*/
+ self->ottICC__FDK, self->outIdxData,
+ pCurBs
+ ->cmpOttICCidx, /* int
+ cmpIdxData[MAX_NUM_OTT][MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS],
+ */
+ self->ottICCdiffidx, /* differential data */
+ ottIdx, /* int xttIdx, Which ott/ttt index to use for input and
+ output buffers */
+ self->ottICCidxPrev, /* int idxPrev[MAX_NUM_OTT][MAX_PARAMETER_BANDS],
+ */
+ ottIdx, t_ICC, 0, /* int startBand, */
+ self->pConfigCurrent->bitstreamOttBands[ottIdx], /* int stopBand, */
+ ICCdefault, /* int defaultValue, */
+ pCurBs->numParameterSets, /* int numParameterSets) */
+ pCurBs->paramSlot, self->extendFrame, self->quantMode,
+ &(self->concealInfo), ottVsTotInactiv, NULL, NULL, NULL);
+ if (err != MPS_OK) goto bail;
+ } /* ottIdx */
+
+ if ((self->treeConfig == TREE_212) && (self->phaseCoding)) {
+ if (pCurBs->phaseMode == 0) {
+ for (int pb = 0; pb < self->pConfigCurrent->numOttBandsIPD; pb++) {
+ self->ottIPDidxPrev[0][pb] = 0;
+ }
+ }
+ for (ottIdx = 0; ottIdx < numOttBoxes; ottIdx++) {
+ err = mapIndexData(
+ &pCurBs->IPDLosslessData[ottIdx], self->ottIPD__FDK, self->outIdxData,
+ pCurBs->cmpOttIPDidx, NULL, ottIdx, self->ottIPDidxPrev, ottIdx,
+ t_IPD, 0, self->numOttBandsIPD, IPDdefault, pCurBs->numParameterSets,
+ pCurBs->paramSlot, self->extendFrame, self->quantMode,
+ &(self->concealInfo), ottVsTotInactiv, NULL, NULL, NULL);
+ }
+ }
+
+bail:
+
+ return MPS_OK;
+
+} /* decodeAndMapFrameOtt */
+
+/*******************************************************************************
+ Functionname: decodeAndMapFrameSmg
+ *******************************************************************************
+
+ Description:
+ Decode smoothing flags
+
+ Arguments:
+
+Input:
+
+Output:
+
+
+*******************************************************************************/
+static SACDEC_ERROR decodeAndMapFrameSmg(HANDLE_SPATIAL_DEC self,
+ const SPATIAL_BS_FRAME *frame) {
+ int ps, pb, pg, pbStride, dataBands, pbStart, pbStop,
+ aGroupToBand[MAX_PARAMETER_BANDS + 1];
+
+ if (frame->numParameterSets > MAX_PARAMETER_SETS)
+ return MPS_WRONG_PARAMETERSETS;
+ if (self->bitstreamParameterBands > MAX_PARAMETER_BANDS)
+ return MPS_WRONG_PARAMETERBANDS;
+
+ for (ps = 0; ps < frame->numParameterSets; ps++) {
+ switch (frame->bsSmoothMode[ps]) {
+ case 0:
+ self->smgTime[ps] = 256;
+ FDKmemclear(self->smgData[ps],
+ self->bitstreamParameterBands * sizeof(UCHAR));
+ break;
+
+ case 1:
+ if (ps > 0) {
+ self->smgTime[ps] = self->smgTime[ps - 1];
+ FDKmemcpy(self->smgData[ps], self->smgData[ps - 1],
+ self->bitstreamParameterBands * sizeof(UCHAR));
+ } else {
+ self->smgTime[ps] = self->smoothState->prevSmgTime;
+ FDKmemcpy(self->smgData[ps], self->smoothState->prevSmgData,
+ self->bitstreamParameterBands * sizeof(UCHAR));
+ }
+ break;
+
+ case 2:
+ self->smgTime[ps] = smgTimeTable[frame->bsSmoothTime[ps]];
+ for (pb = 0; pb < self->bitstreamParameterBands; pb++) {
+ self->smgData[ps][pb] = 1;
+ }
+ break;
+
+ case 3:
+ self->smgTime[ps] = smgTimeTable[frame->bsSmoothTime[ps]];
+ pbStride = pbStrideTable[frame->bsFreqResStrideSmg[ps]];
+ dataBands = (self->bitstreamParameterBands - 1) / pbStride + 1;
+ createMapping(aGroupToBand, 0, self->bitstreamParameterBands, pbStride);
+ for (pg = 0; pg < dataBands; pg++) {
+ pbStart = aGroupToBand[pg];
+ pbStop = aGroupToBand[pg + 1];
+ for (pb = pbStart; pb < pbStop; pb++) {
+ self->smgData[ps][pb] = frame->bsSmgData[ps][pg];
+ }
+ }
+ break;
+ }
+ }
+
+ self->smoothState->prevSmgTime = self->smgTime[frame->numParameterSets - 1];
+ FDKmemcpy(self->smoothState->prevSmgData,
+ self->smgData[frame->numParameterSets - 1],
+ self->bitstreamParameterBands * sizeof(UCHAR));
+
+ if (self->extendFrame) {
+ self->smgTime[frame->numParameterSets] =
+ self->smgTime[frame->numParameterSets - 1];
+ FDKmemcpy(self->smgData[frame->numParameterSets],
+ self->smgData[frame->numParameterSets - 1],
+ self->bitstreamParameterBands * sizeof(UCHAR));
+ }
+
+ return MPS_OK;
+}
+
+/*******************************************************************************
+ Functionname: decodeAndMapFrameArbdmx
+ *******************************************************************************
+
+ Description:
+ Do delta decoding and dequantization
+
+ Arguments:
+
+Input:
+
+Output:
+
+*******************************************************************************/
+static SACDEC_ERROR decodeAndMapFrameArbdmx(HANDLE_SPATIAL_DEC self,
+ const SPATIAL_BS_FRAME *frame) {
+ SACDEC_ERROR err = MPS_OK;
+ int ch;
+ int offset = self->numOttBoxes;
+
+ for (ch = 0; ch < self->numInputChannels; ch++) {
+ err = mapIndexData(&frame->CLDLosslessData[offset + ch],
+ self->arbdmxGain__FDK, self->outIdxData,
+ frame->cmpArbdmxGainIdx, NULL, /* no differential data */
+ ch, self->arbdmxGainIdxPrev, offset + ch, t_CLD, 0,
+ self->bitstreamParameterBands,
+ 0 /*self->arbdmxGainDefault*/, frame->numParameterSets,
+ frame->paramSlot, self->extendFrame, 0,
+ &(self->concealInfo), ottVsTotInactiv, NULL, NULL, NULL);
+ if (err != MPS_OK) goto bail;
+ }
+
+bail:
+ return err;
+} /* decodeAndMapFrameArbdmx */
+
+/*******************************************************************************
+ Functionname: SpatialDecDecodeFrame
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+SACDEC_ERROR SpatialDecDecodeFrame(spatialDec *self, SPATIAL_BS_FRAME *frame) {
+ SACDEC_ERROR err = MPS_OK;
+
+ self->extendFrame = 0;
+ if (frame->paramSlot[frame->numParameterSets - 1] != self->timeSlots - 1) {
+ self->extendFrame = 1;
+ }
+
+ self->TsdTs = 0;
+
+ /****** DTDF and MAP DATA ********/
+ if ((err = decodeAndMapFrameOtt(self, frame)) != MPS_OK) goto bail;
+
+ if ((err = decodeAndMapFrameSmg(self, frame)) != MPS_OK) goto bail;
+
+ if (self->arbitraryDownmix != 0) {
+ if ((err = decodeAndMapFrameArbdmx(self, frame)) != MPS_OK) goto bail;
+ }
+
+ if (self->extendFrame) {
+ frame->numParameterSets =
+ fixMin(MAX_PARAMETER_SETS, frame->numParameterSets + 1);
+ frame->paramSlot[frame->numParameterSets - 1] = self->timeSlots - 1;
+
+ for (int p = 0; p < frame->numParameterSets; p++) {
+ if (frame->paramSlot[p] > self->timeSlots - 1) {
+ frame->paramSlot[p] = self->timeSlots - 1;
+ err = MPS_PARSE_ERROR;
+ }
+ }
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ }
+
+bail:
+ return err;
+} /* SpatialDecDecodeFrame() */
+
+/*******************************************************************************
+ Functionname: SpatialDecodeHeader
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+
+SACDEC_ERROR SpatialDecDecodeHeader(
+ spatialDec *self, SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig) {
+ SACDEC_ERROR err = MPS_OK;
+ int i;
+
+ self->samplingFreq = pSpatialSpecificConfig->samplingFreq;
+ self->timeSlots = pSpatialSpecificConfig->nTimeSlots;
+ self->frameLength = self->timeSlots * self->qmfBands;
+ self->bitstreamParameterBands = pSpatialSpecificConfig->freqRes;
+
+ if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD)
+ self->hybridBands = self->qmfBands;
+ else
+ self->hybridBands = SacGetHybridSubbands(self->qmfBands);
+ self->tp_hybBandBorder = 12;
+
+ self->numParameterBands = self->bitstreamParameterBands;
+
+ if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) {
+ switch (self->numParameterBands) {
+ case 4:
+ self->kernels = kernels_4_to_64;
+ break;
+ case 5:
+ self->kernels = kernels_5_to_64;
+ break;
+ case 7:
+ self->kernels = kernels_7_to_64;
+ break;
+ case 9:
+ self->kernels = kernels_9_to_64;
+ break;
+ case 12:
+ self->kernels = kernels_12_to_64;
+ break;
+ case 15:
+ self->kernels = kernels_15_to_64;
+ break;
+ case 23:
+ self->kernels = kernels_23_to_64;
+ break;
+ default:
+ return MPS_INVALID_PARAMETERBANDS; /* unsupported numParameterBands */
+ }
+ } else {
+ switch (self->numParameterBands) {
+ case 4:
+ self->kernels = kernels_4_to_71;
+ break;
+ case 5:
+ self->kernels = kernels_5_to_71;
+ break;
+ case 7:
+ self->kernels = kernels_7_to_71;
+ break;
+ case 10:
+ self->kernels = kernels_10_to_71;
+ break;
+ case 14:
+ self->kernels = kernels_14_to_71;
+ break;
+ case 20:
+ self->kernels = kernels_20_to_71;
+ break;
+ case 28:
+ self->kernels = kernels_28_to_71;
+ break;
+ default:
+ return MPS_INVALID_PARAMETERBANDS; /* unsupported numParameterBands */
+ }
+ }
+
+ /* create param to hyb band table */
+ FDKmemclear(self->param2hyb, (MAX_PARAMETER_BANDS + 1) * sizeof(int));
+ for (i = 0; i < self->hybridBands; i++) {
+ self->param2hyb[self->kernels[i] + 1] = i + 1;
+ }
+ {
+ int pb = self->kernels[i - 1] + 2;
+ for (; pb < (MAX_PARAMETER_BANDS + 1); pb++) {
+ self->param2hyb[pb] = i;
+ }
+ for (pb = 0; pb < MAX_PARAMETER_BANDS; pb += 1) {
+ self->kernels_width[pb] = self->param2hyb[pb + 1] - self->param2hyb[pb];
+ }
+ }
+
+ self->treeConfig = pSpatialSpecificConfig->treeConfig;
+
+ self->numOttBoxes = pSpatialSpecificConfig->nOttBoxes;
+
+ self->numInputChannels = pSpatialSpecificConfig->nInputChannels;
+
+ self->numOutputChannels = pSpatialSpecificConfig->nOutputChannels;
+
+ self->quantMode = pSpatialSpecificConfig->quantMode;
+
+ self->arbitraryDownmix = pSpatialSpecificConfig->bArbitraryDownmix;
+
+ self->numM2rows = self->numOutputChannels;
+
+ {
+ self->residualCoding = 0;
+ if (self->arbitraryDownmix == 2)
+ self->arbitraryDownmix = 1; /* no arbitrary downmix residuals */
+ }
+ if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC)) {
+ self->residualCoding = pSpatialSpecificConfig->bResidualCoding;
+ }
+
+ self->clipProtectGain__FDK =
+ FX_CFG2FX_DBL(clipGainTable__FDK[pSpatialSpecificConfig->bsFixedGainDMX]);
+ self->clipProtectGainSF__FDK =
+ clipGainSFTable__FDK[pSpatialSpecificConfig->bsFixedGainDMX];
+
+ self->tempShapeConfig = pSpatialSpecificConfig->tempShapeConfig;
+
+ self->decorrConfig = pSpatialSpecificConfig->decorrConfig;
+
+ if (self->upmixType == UPMIXTYPE_BYPASS) {
+ self->numOutputChannels = self->numInputChannels;
+ }
+
+ self->numOutputChannelsAT = self->numOutputChannels;
+
+ self->numOttBandsIPD = pSpatialSpecificConfig->numOttBandsIPD;
+ self->phaseCoding = pSpatialSpecificConfig->bsPhaseCoding;
+ for (i = 0; i < self->numOttBoxes; i++) {
+ {
+ self->pConfigCurrent->bitstreamOttBands[i] =
+ self->bitstreamParameterBands;
+ }
+ self->numOttBands[i] = self->pConfigCurrent->bitstreamOttBands[i];
+ } /* i */
+
+ if (self->residualCoding) {
+ int numBoxes = self->numOttBoxes;
+ for (i = 0; i < numBoxes; i++) {
+ self->residualPresent[i] =
+ pSpatialSpecificConfig->ResidualConfig[i].bResidualPresent;
+
+ if (self->residualPresent[i]) {
+ self->residualBands[i] =
+ pSpatialSpecificConfig->ResidualConfig[i].nResidualBands;
+ /* conversion from hybrid bands to qmf bands */
+ self->residualQMFBands[i] =
+ fMax(self->param2hyb[self->residualBands[i]] + 3 - 10,
+ 3); /* simplification for the lowest 10 hybrid bands */
+ } else {
+ self->residualBands[i] = 0;
+ self->residualQMFBands[i] = 0;
+ }
+ }
+ } /* self->residualCoding */
+ else {
+ int boxes = self->numOttBoxes;
+ for (i = 0; i < boxes; i += 1) {
+ self->residualPresent[i] = 0;
+ self->residualBands[i] = 0;
+ }
+ }
+
+ switch (self->treeConfig) {
+ case TREE_212:
+ self->numDirektSignals = 1;
+ self->numDecorSignals = 1;
+ self->numXChannels = 1;
+ if (self->arbitraryDownmix == 2) {
+ self->numXChannels += 1;
+ }
+ self->numVChannels = self->numDirektSignals + self->numDecorSignals;
+ break;
+ default:
+ return MPS_INVALID_TREECONFIG;
+ }
+
+ self->highRateMode = pSpatialSpecificConfig->bsHighRateMode;
+ self->decorrType = pSpatialSpecificConfig->bsDecorrType;
+
+ SpatialDecDecodeHelperInfo(pSpatialSpecificConfig, UPMIXTYPE_NORMAL);
+
+ return err;
+}
+
+/*******************************************************************************
+ Functionname: SpatialDecCreateBsFrame
+ *******************************************************************************
+
+ Description: Create spatial bitstream structure
+
+ Arguments: spatialDec* self
+ const SPATIAL_BS_FRAME **bsFrame
+
+ Return: -
+
+*******************************************************************************/
+SACDEC_ERROR SpatialDecCreateBsFrame(SPATIAL_BS_FRAME *bsFrame,
+ BS_LL_STATE *llState) {
+ SPATIAL_BS_FRAME *pBs = bsFrame;
+
+ const int maxNumOtt = MAX_NUM_OTT;
+ const int maxNumInputChannels = MAX_INPUT_CHANNELS;
+
+ FDK_ALLOCATE_MEMORY_1D_P(
+ pBs->cmpOttIPDidx, maxNumOtt * MAX_PARAMETER_SETS * MAX_PARAMETER_BANDS,
+ SCHAR, SCHAR(*)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS])
+
+ /* Arbitrary Downmix */
+ FDK_ALLOCATE_MEMORY_1D_P(
+ pBs->cmpArbdmxGainIdx,
+ maxNumInputChannels * MAX_PARAMETER_SETS * MAX_PARAMETER_BANDS, SCHAR,
+ SCHAR(*)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS])
+
+ /* Lossless control */
+ FDK_ALLOCATE_MEMORY_1D(pBs->CLDLosslessData, MAX_NUM_PARAMETERS, LOSSLESSDATA)
+ FDK_ALLOCATE_MEMORY_1D(pBs->ICCLosslessData, MAX_NUM_PARAMETERS, LOSSLESSDATA)
+
+ FDK_ALLOCATE_MEMORY_1D(pBs->IPDLosslessData, MAX_NUM_PARAMETERS, LOSSLESSDATA)
+
+ pBs->newBsData = 0;
+ pBs->numParameterSets = 1;
+
+ /* Link lossless states */
+ for (int x = 0; x < MAX_NUM_PARAMETERS; x++) {
+ pBs->CLDLosslessData[x].state = &llState->CLDLosslessState[x];
+ pBs->ICCLosslessData[x].state = &llState->ICCLosslessState[x];
+
+ pBs->IPDLosslessData[x].state = &llState->IPDLosslessState[x];
+ }
+
+ return MPS_OK;
+
+bail:
+ return MPS_OUTOFMEMORY;
+}
+
+/*******************************************************************************
+ Functionname: SpatialDecCloseBsFrame
+ *******************************************************************************
+
+ Description: Close spatial bitstream structure
+
+ Arguments: spatialDec* self
+
+ Return: -
+
+*******************************************************************************/
+void SpatialDecCloseBsFrame(SPATIAL_BS_FRAME *pBs) {
+ if (pBs != NULL) {
+ /* These arrays contain the compact indices, only one value per pbstride,
+ * only paramsets actually containing data. */
+
+ FDK_FREE_MEMORY_1D(pBs->cmpOttIPDidx);
+
+ /* Arbitrary Downmix */
+ FDK_FREE_MEMORY_1D(pBs->cmpArbdmxGainIdx);
+
+ /* Lossless control */
+ FDK_FREE_MEMORY_1D(pBs->IPDLosslessData);
+ FDK_FREE_MEMORY_1D(pBs->CLDLosslessData);
+ FDK_FREE_MEMORY_1D(pBs->ICCLosslessData);
+ }
+}
diff --git a/fdk-aac/libSACdec/src/sac_bitdec.h b/fdk-aac/libSACdec/src/sac_bitdec.h
new file mode 100644
index 0000000..cb0c7d2
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_bitdec.h
@@ -0,0 +1,161 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec bitstream decoder
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Spatial Audio bitstream decoder
+*/
+
+#ifndef SAC_BITDEC_H
+#define SAC_BITDEC_H
+
+#include "sac_dec.h"
+
+typedef struct {
+ SCHAR numInputChannels;
+ SCHAR numOutputChannels;
+ SCHAR numOttBoxes;
+ SCHAR numTttBoxes;
+ SCHAR ottModeLfe[MAX_NUM_OTT];
+} TREEPROPERTIES;
+
+enum { TREE_212 = 7, TREE_DUMMY = 255 };
+
+enum { QUANT_FINE = 0, QUANT_EBQ1 = 1, QUANT_EBQ2 = 2 };
+
+SACDEC_ERROR SpatialDecParseSpecificConfigHeader(
+ HANDLE_FDK_BITSTREAM bitstream,
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
+ AUDIO_OBJECT_TYPE coreCodec, SPATIAL_DEC_UPMIX_TYPE upmixType);
+
+SACDEC_ERROR SpatialDecParseMps212Config(
+ HANDLE_FDK_BITSTREAM bitstream,
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig, int samplingRate,
+ AUDIO_OBJECT_TYPE coreCodec, INT stereoConfigIndex,
+ INT coreSbrFrameLengthIndex);
+
+SACDEC_ERROR SpatialDecParseSpecificConfig(
+ HANDLE_FDK_BITSTREAM bitstream,
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig, int sacHeaderLen,
+ AUDIO_OBJECT_TYPE coreCodec);
+
+int SpatialDecDefaultSpecificConfig(
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
+ AUDIO_OBJECT_TYPE coreCodec, int samplingFreq, int nTimeSlots,
+ int sacDecoderLevel, int isBlind, int coreChannels);
+
+SACDEC_ERROR SpatialDecCreateBsFrame(SPATIAL_BS_FRAME *bsFrame,
+ BS_LL_STATE *llState);
+
+void SpatialDecCloseBsFrame(SPATIAL_BS_FRAME *bsFrame);
+
+SACDEC_ERROR SpatialDecParseFrameData(
+ spatialDec *self, SPATIAL_BS_FRAME *frame, HANDLE_FDK_BITSTREAM bitstream,
+ const SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig, UPMIXTYPE upmixType,
+ int fGlobalIndependencyFlag);
+
+SACDEC_ERROR SpatialDecDecodeFrame(spatialDec *self, SPATIAL_BS_FRAME *frame);
+
+SACDEC_ERROR SpatialDecDecodeHeader(
+ spatialDec *self, SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig);
+
+#endif
diff --git a/fdk-aac/libSACdec/src/sac_calcM1andM2.cpp b/fdk-aac/libSACdec/src/sac_calcM1andM2.cpp
new file mode 100644
index 0000000..6e5a145
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_calcM1andM2.cpp
@@ -0,0 +1,848 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec M1 and M2 calculation
+
+*******************************************************************************/
+
+#include "sac_calcM1andM2.h"
+#include "sac_bitdec.h"
+#include "sac_process.h"
+#include "sac_rom.h"
+#include "sac_smoothing.h"
+#include "FDK_trigFcts.h"
+
+/* assorted definitions and constants */
+
+#define ABS_THR2 1.0e-9
+#define SQRT2_FDK \
+ ((FIXP_DBL)FL2FXCONST_DBL(0.70710678118f)) /* FDKsqrt(2.0) scaled by 0.5 */
+
+static void param2UMX_PS__FDK(spatialDec* self,
+ FIXP_DBL H11[MAX_PARAMETER_BANDS],
+ FIXP_DBL H12[MAX_PARAMETER_BANDS],
+ FIXP_DBL H21[MAX_PARAMETER_BANDS],
+ FIXP_DBL H22[MAX_PARAMETER_BANDS],
+ FIXP_DBL c_l[MAX_PARAMETER_BANDS],
+ FIXP_DBL c_r[MAX_PARAMETER_BANDS], int ottBoxIndx,
+ int parameterSetIndx, int resBands);
+
+static void param2UMX_PS_Core__FDK(
+ const SCHAR cld[MAX_PARAMETER_BANDS], const SCHAR icc[MAX_PARAMETER_BANDS],
+ const int numOttBands, const int resBands,
+ FIXP_DBL H11[MAX_PARAMETER_BANDS], FIXP_DBL H12[MAX_PARAMETER_BANDS],
+ FIXP_DBL H21[MAX_PARAMETER_BANDS], FIXP_DBL H22[MAX_PARAMETER_BANDS],
+ FIXP_DBL c_l[MAX_PARAMETER_BANDS], FIXP_DBL c_r[MAX_PARAMETER_BANDS]);
+
+static void param2UMX_PS_IPD_OPD__FDK(
+ spatialDec* self, const SPATIAL_BS_FRAME* frame,
+ FIXP_DBL H11re[MAX_PARAMETER_BANDS], FIXP_DBL H12re[MAX_PARAMETER_BANDS],
+ FIXP_DBL H21re[MAX_PARAMETER_BANDS], FIXP_DBL H22re[MAX_PARAMETER_BANDS],
+ FIXP_DBL c_l[MAX_PARAMETER_BANDS], FIXP_DBL c_r[MAX_PARAMETER_BANDS],
+ int ottBoxIndx, int parameterSetIndx, int residualBands);
+
+static void param2UMX_Prediction__FDK(
+ spatialDec* self, FIXP_DBL H11re[MAX_PARAMETER_BANDS],
+ FIXP_DBL H11im[MAX_PARAMETER_BANDS], FIXP_DBL H12re[MAX_PARAMETER_BANDS],
+ FIXP_DBL H12im[MAX_PARAMETER_BANDS], FIXP_DBL H21re[MAX_PARAMETER_BANDS],
+ FIXP_DBL H21im[MAX_PARAMETER_BANDS], FIXP_DBL H22re[MAX_PARAMETER_BANDS],
+ FIXP_DBL H22im[MAX_PARAMETER_BANDS], int ottBoxIndx, int parameterSetIndx,
+ int resBands);
+
+/* static void SpatialDecCalculateM0(spatialDec* self,int ps); */
+static SACDEC_ERROR SpatialDecCalculateM1andM2_212(
+ spatialDec* self, int ps, const SPATIAL_BS_FRAME* frame);
+
+/*******************************************************************************
+ Functionname: SpatialDecGetResidualIndex
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Input:
+
+ Output:
+
+*******************************************************************************/
+int SpatialDecGetResidualIndex(spatialDec* self, int row) {
+ return row2residual[self->treeConfig][row];
+}
+
+/*******************************************************************************
+ Functionname: UpdateAlpha
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Input:
+
+ Output:
+
+*******************************************************************************/
+static void updateAlpha(spatialDec* self) {
+ int nChIn = self->numInputChannels;
+ int ch;
+
+ for (ch = 0; ch < nChIn; ch++) {
+ FIXP_DBL alpha = /* FL2FXCONST_DBL(1.0f) */ (FIXP_DBL)MAXVAL_DBL;
+
+ self->arbdmxAlphaPrev__FDK[ch] = self->arbdmxAlpha__FDK[ch];
+
+ self->arbdmxAlpha__FDK[ch] = alpha;
+ }
+}
+
+/*******************************************************************************
+ Functionname: SpatialDecCalculateM1andM2
+ *******************************************************************************
+ Description:
+ Arguments:
+*******************************************************************************/
+SACDEC_ERROR SpatialDecCalculateM1andM2(spatialDec* self, int ps,
+ const SPATIAL_BS_FRAME* frame) {
+ SACDEC_ERROR err = MPS_OK;
+
+ if ((self->arbitraryDownmix != 0) && (ps == 0)) {
+ updateAlpha(self);
+ }
+
+ self->pActivM2ParamBands = NULL;
+
+ switch (self->upmixType) {
+ case UPMIXTYPE_BYPASS:
+ case UPMIXTYPE_NORMAL:
+ switch (self->treeConfig) {
+ case TREE_212:
+ err = SpatialDecCalculateM1andM2_212(self, ps, frame);
+ break;
+ default:
+ err = MPS_WRONG_TREECONFIG;
+ };
+ break;
+
+ default:
+ err = MPS_WRONG_TREECONFIG;
+ }
+
+ if (err != MPS_OK) {
+ goto bail;
+ }
+
+bail:
+ return err;
+}
+
+/*******************************************************************************
+ Functionname: SpatialDecCalculateM1andM2_212
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+static SACDEC_ERROR SpatialDecCalculateM1andM2_212(
+ spatialDec* self, int ps, const SPATIAL_BS_FRAME* frame) {
+ SACDEC_ERROR err = MPS_OK;
+ int pb;
+
+ FIXP_DBL H11re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)};
+ FIXP_DBL H12re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)};
+ FIXP_DBL H21re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)};
+ FIXP_DBL H22re[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)};
+ FIXP_DBL H11im[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)};
+ FIXP_DBL H21im[MAX_PARAMETER_BANDS] = {FL2FXCONST_DBL(0.0f)};
+
+ INT phaseCoding = self->phaseCoding;
+
+ switch (phaseCoding) {
+ case 1:
+ /* phase coding: yes; residuals: no */
+ param2UMX_PS_IPD_OPD__FDK(self, frame, H11re, H12re, H21re, H22re, NULL,
+ NULL, 0, ps, self->residualBands[0]);
+ break;
+ case 3:
+ /* phase coding: yes; residuals: yes */
+ param2UMX_Prediction__FDK(self, H11re, H11im, H12re, NULL, H21re, H21im,
+ H22re, NULL, 0, ps, self->residualBands[0]);
+ break;
+ default:
+ if (self->residualCoding) {
+ /* phase coding: no; residuals: yes */
+ param2UMX_Prediction__FDK(self, H11re, NULL, H12re, NULL, H21re, NULL,
+ H22re, NULL, 0, ps, self->residualBands[0]);
+ } else {
+ /* phase coding: no; residuals: no */
+ param2UMX_PS__FDK(self, H11re, H12re, H21re, H22re, NULL, NULL, 0, ps,
+ 0);
+ }
+ break;
+ }
+
+ for (pb = 0; pb < self->numParameterBands; pb++) {
+ self->M2Real__FDK[0][0][pb] = (H11re[pb]);
+ self->M2Real__FDK[0][1][pb] = (H12re[pb]);
+
+ self->M2Real__FDK[1][0][pb] = (H21re[pb]);
+ self->M2Real__FDK[1][1][pb] = (H22re[pb]);
+ }
+ if (phaseCoding == 3) {
+ for (pb = 0; pb < self->numParameterBands; pb++) {
+ self->M2Imag__FDK[0][0][pb] = (H11im[pb]);
+ self->M2Imag__FDK[1][0][pb] = (H21im[pb]);
+ self->M2Imag__FDK[0][1][pb] = (FIXP_DBL)0; // H12im[pb];
+ self->M2Imag__FDK[1][1][pb] = (FIXP_DBL)0; // H22im[pb];
+ }
+ }
+
+ if (self->phaseCoding == 1) {
+ SpatialDecSmoothOPD(
+ self, frame,
+ ps); /* INPUT: PhaseLeft, PhaseRight, (opdLeftState, opdRightState) */
+ }
+
+ return err;
+}
+
+/*******************************************************************************
+ Functionname: param2UMX_PS_Core
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+static void param2UMX_PS_Core__FDK(
+ const SCHAR cld[MAX_PARAMETER_BANDS], const SCHAR icc[MAX_PARAMETER_BANDS],
+ const int numOttBands, const int resBands,
+ FIXP_DBL H11[MAX_PARAMETER_BANDS], FIXP_DBL H12[MAX_PARAMETER_BANDS],
+ FIXP_DBL H21[MAX_PARAMETER_BANDS], FIXP_DBL H22[MAX_PARAMETER_BANDS],
+ FIXP_DBL c_l[MAX_PARAMETER_BANDS], FIXP_DBL c_r[MAX_PARAMETER_BANDS]) {
+ int band;
+
+ if ((c_l != NULL) && (c_r != NULL)) {
+ for (band = 0; band < numOttBands; band++) {
+ SpatialDequantGetCLDValues(cld[band], &c_l[band], &c_r[band]);
+ }
+ }
+
+ band = 0;
+ FDK_ASSERT(resBands == 0);
+ for (; band < numOttBands; band++) {
+ /* compute mixing variables: */
+ const int idx1 = cld[band];
+ const int idx2 = icc[band];
+ H11[band] = FX_CFG2FX_DBL(H11_nc[idx1][idx2]);
+ H21[band] = FX_CFG2FX_DBL(H11_nc[30 - idx1][idx2]);
+ H12[band] = FX_CFG2FX_DBL(H12_nc[idx1][idx2]);
+ H22[band] = FX_CFG2FX_DBL(-H12_nc[30 - idx1][idx2]);
+ }
+}
+
+/*******************************************************************************
+ Functionname: param2UMX_PS
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+static void param2UMX_PS__FDK(spatialDec* self,
+ FIXP_DBL H11[MAX_PARAMETER_BANDS],
+ FIXP_DBL H12[MAX_PARAMETER_BANDS],
+ FIXP_DBL H21[MAX_PARAMETER_BANDS],
+ FIXP_DBL H22[MAX_PARAMETER_BANDS],
+ FIXP_DBL c_l[MAX_PARAMETER_BANDS],
+ FIXP_DBL c_r[MAX_PARAMETER_BANDS], int ottBoxIndx,
+ int parameterSetIndx, int residualBands) {
+ int band;
+ param2UMX_PS_Core__FDK(self->ottCLD__FDK[ottBoxIndx][parameterSetIndx],
+ self->ottICC__FDK[ottBoxIndx][parameterSetIndx],
+ self->numOttBands[ottBoxIndx], residualBands, H11, H12,
+ H21, H22, c_l, c_r);
+
+ for (band = self->numOttBands[ottBoxIndx]; band < self->numParameterBands;
+ band++) {
+ H11[band] = H21[band] = H12[band] = H22[band] = FL2FXCONST_DBL(0.f);
+ }
+}
+
+#define N_CLD (31)
+#define N_IPD (16)
+
+static const FIXP_DBL sinIpd_tab[N_IPD] = {
+ FIXP_DBL(0x00000000), FIXP_DBL(0x30fbc54e), FIXP_DBL(0x5a827999),
+ FIXP_DBL(0x7641af3d), FIXP_DBL(0x7fffffff), FIXP_DBL(0x7641af3d),
+ FIXP_DBL(0x5a82799a), FIXP_DBL(0x30fbc54d), FIXP_DBL(0xffffffff),
+ FIXP_DBL(0xcf043ab3), FIXP_DBL(0xa57d8666), FIXP_DBL(0x89be50c3),
+ FIXP_DBL(0x80000000), FIXP_DBL(0x89be50c3), FIXP_DBL(0xa57d8666),
+ FIXP_DBL(0xcf043ab2),
+};
+
+/* cosIpd[i] = sinIpd[(i+4)&15] */
+#define SIN_IPD(a) (sinIpd_tab[(a)])
+#define COS_IPD(a) (sinIpd_tab[((a) + 4) & 15]) //(cosIpd_tab[(a)])
+
+static const FIXP_SGL sqrt_one_minus_ICC2[8] = {
+ FL2FXCONST_SGL(0.0f),
+ FL2FXCONST_SGL(0.349329357483736f),
+ FL2FXCONST_SGL(0.540755219669676f),
+ FL2FXCONST_SGL(0.799309172723546f),
+ FL2FXCONST_SGL(0.929968187843004f),
+ FX_DBL2FXCONST_SGL(MAXVAL_DBL),
+ FL2FXCONST_SGL(0.80813303360276f),
+ FL2FXCONST_SGL(0.141067359796659f),
+};
+
+/* exponent of sqrt(CLD) */
+static const SCHAR sqrt_CLD_e[N_CLD] = {
+ -24, -7, -6, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0, 0, 0, 1,
+ 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 25};
+
+static const FIXP_DBL sqrt_CLD_m[N_CLD] = {
+ FL2FXCONST_DBL(0.530542153566195f),
+ FL2FXCONST_DBL(0.719796896243647f),
+ FL2FXCONST_DBL(0.64f),
+ FL2FXCONST_DBL(0.569049411212455f),
+ FL2FXCONST_DBL(0.505964425626941f),
+ FL2FXCONST_DBL(0.899746120304559f),
+ FL2FXCONST_DBL(0.635462587779425f),
+ FL2FXCONST_DBL(0.897614763441571f),
+ FL2FXCONST_DBL(0.633957276984445f),
+ FL2FXCONST_DBL(0.895488455427336f),
+ FL2FXCONST_DBL(0.632455532033676f),
+ FL2FXCONST_DBL(0.796214341106995f),
+ FL2FXCONST_DBL(0.501187233627272f),
+ FL2FXCONST_DBL(0.630957344480193f),
+ FL2FXCONST_DBL(0.794328234724281f),
+ FL2FXCONST_DBL(0.5f),
+ FL2FXCONST_DBL(0.629462705897084f),
+ FL2FXCONST_DBL(0.792446596230557f),
+ FL2FXCONST_DBL(0.99763115748444f),
+ FL2FXCONST_DBL(0.627971607877395f),
+ FL2FXCONST_DBL(0.790569415042095f),
+ FL2FXCONST_DBL(0.558354490188704f),
+ FL2FXCONST_DBL(0.788696680600242f),
+ FL2FXCONST_DBL(0.557031836333591f),
+ FL2FXCONST_DBL(0.786828382371355f),
+ FL2FXCONST_DBL(0.555712315637163f),
+ FL2FXCONST_DBL(0.988211768802619f),
+ FL2FXCONST_DBL(0.87865832060992f),
+ FL2FXCONST_DBL(0.78125f),
+ FL2FXCONST_DBL(0.694640394546454f),
+ FL2FXCONST_DBL(0.942432183077448f),
+};
+
+static const FIXP_DBL CLD_m[N_CLD] = {
+ FL2FXCONST_DBL(0.281474976710656f),
+ FL2FXCONST_DBL(0.518107571841987f),
+ FL2FXCONST_DBL(0.4096f),
+ FL2FXCONST_DBL(0.323817232401242f),
+ FL2FXCONST_DBL(0.256f),
+ FL2FXCONST_DBL(0.809543081003105f),
+ FL2FXCONST_DBL(0.403812700467324f),
+ FL2FXCONST_DBL(0.805712263548267f),
+ FL2FXCONST_DBL(0.401901829041533f),
+ FL2FXCONST_DBL(0.801899573803636f),
+ FL2FXCONST_DBL(0.4f),
+ FL2FXCONST_DBL(0.633957276984445f),
+ FL2FXCONST_DBL(0.251188643150958f),
+ FL2FXCONST_DBL(0.398107170553497f),
+ FL2FXCONST_DBL(0.630957344480193f),
+ FL2FXCONST_DBL(0.25f),
+ FL2FXCONST_DBL(0.396223298115278f),
+ FL2FXCONST_DBL(0.627971607877395f),
+ FL2FXCONST_DBL(0.995267926383743f),
+ FL2FXCONST_DBL(0.394348340300121f),
+ FL2FXCONST_DBL(0.625f),
+ FL2FXCONST_DBL(0.311759736713887f),
+ FL2FXCONST_DBL(0.62204245398984f),
+ FL2FXCONST_DBL(0.310284466689172f),
+ FL2FXCONST_DBL(0.619098903305123f),
+ FL2FXCONST_DBL(0.308816177750818f),
+ FL2FXCONST_DBL(0.9765625f),
+ FL2FXCONST_DBL(0.772040444377046f),
+ FL2FXCONST_DBL(0.6103515625f),
+ FL2FXCONST_DBL(0.482525277735654f),
+ FL2FXCONST_DBL(0.888178419700125),
+};
+
+static FIXP_DBL dequantIPD_CLD_ICC_splitAngle__FDK_Function(INT ipdIdx,
+ INT cldIdx,
+ INT iccIdx) {
+ FIXP_DBL cld;
+ SpatialDequantGetCLD2Values(cldIdx, &cld);
+
+ /*const FIXP_DBL one_m = (FIXP_DBL)MAXVAL_DBL;
+ const int one_e = 0;*/
+ const FIXP_DBL one_m = FL2FXCONST_DBL(0.5f);
+ const int one_e = 1;
+ /* iidLin = sqrt(cld); */
+ FIXP_DBL iidLin_m = sqrt_CLD_m[cldIdx];
+ int iidLin_e = sqrt_CLD_e[cldIdx];
+ /* iidLin2 = cld; */
+ FIXP_DBL iidLin2_m = CLD_m[cldIdx];
+ int iidLin2_e = sqrt_CLD_e[cldIdx] << 1;
+ /* iidLin21 = iidLin2 + 1.0f; */
+ int iidLin21_e;
+ FIXP_DBL iidLin21_m =
+ fAddNorm(iidLin2_m, iidLin2_e, one_m, one_e, &iidLin21_e);
+ /* iidIcc2 = iidLin * icc * 2.0f; */
+ FIXP_CFG icc = dequantICC__FDK[iccIdx];
+ FIXP_DBL temp1_m, temp1c_m;
+ int temp1_e, temp1c_e;
+ temp1_m = fMult(iidLin_m, icc);
+ temp1_e = iidLin_e + 1;
+
+ FIXP_DBL cosIpd, sinIpd;
+ cosIpd = COS_IPD(ipdIdx);
+ sinIpd = SIN_IPD(ipdIdx);
+
+ temp1c_m = fMult(temp1_m, cosIpd);
+ temp1c_e = temp1_e; //+cosIpd_e;
+
+ int temp2_e, temp3_e, inv_temp3_e, ratio_e;
+ FIXP_DBL temp2_m =
+ fAddNorm(iidLin21_m, iidLin21_e, temp1c_m, temp1c_e, &temp2_e);
+ FIXP_DBL temp3_m =
+ fAddNorm(iidLin21_m, iidLin21_e, temp1_m, temp1_e, &temp3_e);
+ /* calculate 1/temp3 needed later */
+ inv_temp3_e = temp3_e;
+ FIXP_DBL inv_temp3_m = invFixp(temp3_m, &inv_temp3_e);
+ FIXP_DBL ratio_m =
+ fAddNorm(fMult(inv_temp3_m, temp2_m), (inv_temp3_e + temp2_e),
+ FL2FXCONST_DBL(1e-9f), 0, &ratio_e);
+
+ int weight2_e, tempb_atan2_e;
+ FIXP_DBL weight2_m =
+ fPow(ratio_m, ratio_e, FL2FXCONST_DBL(0.5f), -1, &weight2_e);
+ /* atan2(w2*sinIpd, w1*iidLin + w2*cosIpd) = atan2(w2*sinIpd, (2 - w2)*iidLin
+ * + w2*cosIpd) = atan2(w2*sinIpd, 2*iidLin + w2*(cosIpd - iidLin)); */
+ /* tmpa_atan2 = w2*sinIpd; tmpb_atan2 = 2*iidLin + w2*(cosIpd - iidLin); */
+ FIXP_DBL tempb_atan2_m = iidLin_m;
+ tempb_atan2_e = iidLin_e + 1;
+ int add_tmp1_e = 0;
+ FIXP_DBL add_tmp1_m = fAddNorm(cosIpd, 0, -iidLin_m, iidLin_e, &add_tmp1_e);
+ FIXP_DBL add_tmp2_m = fMult(add_tmp1_m, weight2_m);
+ int add_tmp2_e = add_tmp1_e + weight2_e;
+ tempb_atan2_m = fAddNorm(tempb_atan2_m, tempb_atan2_e, add_tmp2_m, add_tmp2_e,
+ &tempb_atan2_e);
+
+ FIXP_DBL tempa_atan2_m = fMult(weight2_m, sinIpd);
+ int tempa_atan2_e = weight2_e; // + sinIpd_e;
+
+ if (tempa_atan2_e > tempb_atan2_e) {
+ tempb_atan2_m = (tempb_atan2_m >> (tempa_atan2_e - tempb_atan2_e));
+ tempb_atan2_e = tempa_atan2_e;
+ } else if (tempb_atan2_e > tempa_atan2_e) {
+ tempa_atan2_m = (tempa_atan2_m >> (tempb_atan2_e - tempa_atan2_e));
+ }
+
+ return fixp_atan2(tempa_atan2_m, tempb_atan2_m);
+}
+
+static void calculateOpd(spatialDec* self, INT ottBoxIndx, INT parameterSetIndx,
+ FIXP_DBL opd[MAX_PARAMETER_BANDS]) {
+ INT band;
+
+ for (band = 0; band < self->numOttBandsIPD; band++) {
+ INT idxCld = self->ottCLD__FDK[ottBoxIndx][parameterSetIndx][band];
+ INT idxIpd = self->ottIPD__FDK[ottBoxIndx][parameterSetIndx][band];
+ INT idxIcc = self->ottICC__FDK[ottBoxIndx][parameterSetIndx][band];
+ FIXP_DBL cld, ipd;
+
+ ipd = FX_CFG2FX_DBL(dequantIPD__FDK[idxIpd]);
+
+ SpatialDequantGetCLD2Values(idxCld, &cld);
+
+ /* ipd(idxIpd==8) == PI */
+ if ((cld == FL2FXCONST_DBL(0.0f)) && (idxIpd == 8)) {
+ opd[2 * band] = FL2FXCONST_DBL(0.0f);
+ } else {
+ opd[2 * band] = (dequantIPD_CLD_ICC_splitAngle__FDK_Function(
+ idxIpd, idxCld, idxIcc) >>
+ (IPD_SCALE - AT2O_SF));
+ }
+ opd[2 * band + 1] = opd[2 * band] - ipd;
+ }
+}
+
+/* wrap phase in rad to the range of 0 <= x < 2*pi */
+static FIXP_DBL wrapPhase(FIXP_DBL phase) {
+ while (phase < (FIXP_DBL)0) phase += PIx2__IPD;
+ while (phase >= PIx2__IPD) phase -= PIx2__IPD;
+ FDK_ASSERT((phase >= (FIXP_DBL)0) && (phase < PIx2__IPD));
+
+ return phase;
+}
+
+/*******************************************************************************
+ Functionname: param2UMX_PS_IPD
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+static void param2UMX_PS_IPD_OPD__FDK(
+ spatialDec* self, const SPATIAL_BS_FRAME* frame,
+ FIXP_DBL H11[MAX_PARAMETER_BANDS], FIXP_DBL H12[MAX_PARAMETER_BANDS],
+ FIXP_DBL H21[MAX_PARAMETER_BANDS], FIXP_DBL H22[MAX_PARAMETER_BANDS],
+ FIXP_DBL c_l[MAX_PARAMETER_BANDS], FIXP_DBL c_r[MAX_PARAMETER_BANDS],
+ int ottBoxIndx, int parameterSetIndx, int residualBands) {
+ INT band;
+ FIXP_DBL opd[2 * MAX_PARAMETER_BANDS];
+ INT numOttBands = self->numOttBands[ottBoxIndx];
+ INT numIpdBands;
+
+ numIpdBands = frame->phaseMode ? self->numOttBandsIPD : 0;
+
+ FDK_ASSERT(self->residualCoding == 0);
+
+ param2UMX_PS_Core__FDK(self->ottCLD__FDK[ottBoxIndx][parameterSetIndx],
+ self->ottICC__FDK[ottBoxIndx][parameterSetIndx],
+ self->numOttBands[ottBoxIndx], residualBands, H11, H12,
+ H21, H22, c_l, c_r);
+
+ for (band = self->numOttBands[ottBoxIndx]; band < self->numParameterBands;
+ band++) {
+ H11[band] = H21[band] = H12[band] = H22[band] = FL2FXCONST_DBL(0.f);
+ }
+
+ if (frame->phaseMode) {
+ calculateOpd(self, ottBoxIndx, parameterSetIndx, opd);
+
+ for (band = 0; band < numIpdBands; band++) {
+ self->PhaseLeft__FDK[band] = wrapPhase(opd[2 * band]);
+ self->PhaseRight__FDK[band] = wrapPhase(opd[2 * band + 1]);
+ }
+ }
+
+ for (band = numIpdBands; band < numOttBands; band++) {
+ self->PhaseLeft__FDK[band] = FL2FXCONST_DBL(0.0f);
+ self->PhaseRight__FDK[band] = FL2FXCONST_DBL(0.0f);
+ }
+}
+
+FDK_INLINE void param2UMX_Prediction_Core__FDK(
+ FIXP_DBL* H11re, FIXP_DBL* H11im, FIXP_DBL* H12re, FIXP_DBL* H12im,
+ FIXP_DBL* H21re, FIXP_DBL* H21im, FIXP_DBL* H22re, FIXP_DBL* H22im,
+ int cldIdx, int iccIdx, int ipdIdx, int band, int numOttBandsIPD,
+ int resBands) {
+#define MAX_WEIGHT (1.2f)
+ FDK_ASSERT((H12im == NULL) && (H22im == NULL)); /* always == 0 */
+
+ if ((band < numOttBandsIPD) && (cldIdx == 15) && (iccIdx == 0) &&
+ (ipdIdx == 8)) {
+ const FIXP_DBL gain =
+ FL2FXCONST_DBL(0.5f / MAX_WEIGHT) >> SCALE_PARAM_M2_212_PRED;
+
+ *H11re = gain;
+ if (band < resBands) {
+ *H21re = gain;
+ *H12re = gain;
+ *H22re = -gain;
+ } else {
+ *H21re = -gain;
+ *H12re = (FIXP_DBL)0;
+ *H22re = (FIXP_DBL)0;
+ }
+ if ((H11im != NULL) &&
+ (H21im != NULL) /*&& (H12im!=NULL) && (H22im!=NULL)*/) {
+ *H11im = (FIXP_DBL)0;
+ *H21im = (FIXP_DBL)0;
+ /* *H12im = (FIXP_DBL)0; */
+ /* *H22im = (FIXP_DBL)0; */
+ }
+ } else {
+ const FIXP_DBL one_m = (FIXP_DBL)MAXVAL_DBL;
+ const int one_e = 0;
+ /* iidLin = sqrt(cld); */
+ FIXP_DBL iidLin_m = sqrt_CLD_m[cldIdx];
+ int iidLin_e = sqrt_CLD_e[cldIdx];
+ /* iidLin2 = cld; */
+ FIXP_DBL iidLin2_m = CLD_m[cldIdx];
+ int iidLin2_e = sqrt_CLD_e[cldIdx] << 1;
+ /* iidLin21 = iidLin2 + 1.0f; */
+ int iidLin21_e;
+ FIXP_DBL iidLin21_m =
+ fAddNorm(iidLin2_m, iidLin2_e, one_m, one_e, &iidLin21_e);
+ /* iidIcc2 = iidLin * icc * 2.0f; */
+ FIXP_CFG icc = dequantICC__FDK[iccIdx];
+ int iidIcc2_e = iidLin_e + 1;
+ FIXP_DBL iidIcc2_m = fMult(iidLin_m, icc);
+ FIXP_DBL temp_m, sqrt_temp_m, inv_temp_m, weight_m;
+ int temp_e, sqrt_temp_e, inv_temp_e, weight_e, scale;
+ FIXP_DBL cosIpd, sinIpd;
+
+ cosIpd = COS_IPD((band < numOttBandsIPD) ? ipdIdx : 0);
+ sinIpd = SIN_IPD((band < numOttBandsIPD) ? ipdIdx : 0);
+
+ /* temp = iidLin21 + iidIcc2 * cosIpd; */
+ temp_m = fAddNorm(iidLin21_m, iidLin21_e, fMult(iidIcc2_m, cosIpd),
+ iidIcc2_e, &temp_e);
+
+ /* calculate 1/temp needed later */
+ inv_temp_e = temp_e;
+ inv_temp_m = invFixp(temp_m, &inv_temp_e);
+
+ /* 1/weight = sqrt(temp) * 1/sqrt(iidLin21) */
+ if (temp_e & 1) {
+ sqrt_temp_m = temp_m >> 1;
+ sqrt_temp_e = (temp_e + 1) >> 1;
+ } else {
+ sqrt_temp_m = temp_m;
+ sqrt_temp_e = temp_e >> 1;
+ }
+ sqrt_temp_m = sqrtFixp(sqrt_temp_m);
+ if (iidLin21_e & 1) {
+ iidLin21_e += 1;
+ iidLin21_m >>= 1;
+ }
+ /* weight_[m,e] is actually 1/weight in the next few lines */
+ weight_m = invSqrtNorm2(iidLin21_m, &weight_e);
+ weight_e -= iidLin21_e >> 1;
+ weight_m = fMult(sqrt_temp_m, weight_m);
+ weight_e += sqrt_temp_e;
+ scale = fNorm(weight_m);
+ weight_m = scaleValue(weight_m, scale);
+ weight_e -= scale;
+ /* weight = 0.5 * max(1/weight, 1/maxWeight) */
+ if ((weight_e < 0) ||
+ ((weight_e == 0) && (weight_m < FL2FXCONST_DBL(1.f / MAX_WEIGHT)))) {
+ weight_m = FL2FXCONST_DBL(1.f / MAX_WEIGHT);
+ weight_e = 0;
+ }
+ weight_e -= 1;
+
+ {
+ FIXP_DBL alphaRe_m, alphaIm_m, accu_m;
+ int alphaRe_e, alphaIm_e, accu_e;
+ /* alphaRe = (1.0f - iidLin2) / temp; */
+ alphaRe_m = fAddNorm(one_m, one_e, -iidLin2_m, iidLin2_e, &alphaRe_e);
+ alphaRe_m = fMult(alphaRe_m, inv_temp_m);
+ alphaRe_e += inv_temp_e;
+
+ /* H11re = weight - alphaRe * weight; */
+ /* H21re = weight + alphaRe * weight; */
+ accu_m = fMult(alphaRe_m, weight_m);
+ accu_e = alphaRe_e + weight_e;
+ {
+ int accu2_e;
+ FIXP_DBL accu2_m;
+ accu2_m = fAddNorm(weight_m, weight_e, -accu_m, accu_e, &accu2_e);
+ *H11re = scaleValue(accu2_m, accu2_e - SCALE_PARAM_M2_212_PRED);
+ accu2_m = fAddNorm(weight_m, weight_e, accu_m, accu_e, &accu2_e);
+ *H21re = scaleValue(accu2_m, accu2_e - SCALE_PARAM_M2_212_PRED);
+ }
+
+ if ((H11im != NULL) &&
+ (H21im != NULL) /*&& (H12im != NULL) && (H22im != NULL)*/) {
+ /* alphaIm = -iidIcc2 * sinIpd / temp; */
+ alphaIm_m = fMult(-iidIcc2_m, sinIpd);
+ alphaIm_m = fMult(alphaIm_m, inv_temp_m);
+ alphaIm_e = iidIcc2_e + inv_temp_e;
+ /* H11im = -alphaIm * weight; */
+ /* H21im = alphaIm * weight; */
+ accu_m = fMult(alphaIm_m, weight_m);
+ accu_e = alphaIm_e + weight_e;
+ accu_m = scaleValue(accu_m, accu_e - SCALE_PARAM_M2_212_PRED);
+ *H11im = -accu_m;
+ *H21im = accu_m;
+
+ /* *H12im = (FIXP_DBL)0; */
+ /* *H22im = (FIXP_DBL)0; */
+ }
+ }
+ if (band < resBands) {
+ FIXP_DBL weight =
+ scaleValue(weight_m, weight_e - SCALE_PARAM_M2_212_PRED);
+ *H12re = weight;
+ *H22re = -weight;
+ } else {
+ /* beta = 2.0f * iidLin * (float) sqrt(1.0f - icc * icc) * weight / temp;
+ */
+ FIXP_DBL beta_m;
+ int beta_e;
+ beta_m = FX_SGL2FX_DBL(sqrt_one_minus_ICC2[iccIdx]);
+ beta_e = 1; /* multipication with 2.0f */
+ beta_m = fMult(beta_m, weight_m);
+ beta_e += weight_e;
+ beta_m = fMult(beta_m, iidLin_m);
+ beta_e += iidLin_e;
+ beta_m = fMult(beta_m, inv_temp_m);
+ beta_e += inv_temp_e;
+
+ beta_m = scaleValue(beta_m, beta_e - SCALE_PARAM_M2_212_PRED);
+ *H12re = beta_m;
+ *H22re = -beta_m;
+ }
+ }
+}
+
+static void param2UMX_Prediction__FDK(spatialDec* self, FIXP_DBL* H11re,
+ FIXP_DBL* H11im, FIXP_DBL* H12re,
+ FIXP_DBL* H12im, FIXP_DBL* H21re,
+ FIXP_DBL* H21im, FIXP_DBL* H22re,
+ FIXP_DBL* H22im, int ottBoxIndx,
+ int parameterSetIndx, int resBands) {
+ int band;
+ FDK_ASSERT((H12im == NULL) && (H22im == NULL)); /* always == 0 */
+
+ for (band = 0; band < self->numParameterBands; band++) {
+ int cldIdx = self->ottCLD__FDK[ottBoxIndx][parameterSetIndx][band];
+ int iccIdx = self->ottICC__FDK[ottBoxIndx][parameterSetIndx][band];
+ int ipdIdx = self->ottIPD__FDK[ottBoxIndx][parameterSetIndx][band];
+
+ param2UMX_Prediction_Core__FDK(
+ &H11re[band], (H11im ? &H11im[band] : NULL), &H12re[band], NULL,
+ &H21re[band], (H21im ? &H21im[band] : NULL), &H22re[band], NULL, cldIdx,
+ iccIdx, ipdIdx, band, self->numOttBandsIPD, resBands);
+ }
+}
+
+/*******************************************************************************
+ Functionname: initM1andM2
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+
+SACDEC_ERROR initM1andM2(spatialDec* self, int initStatesFlag,
+ int configChanged) {
+ SACDEC_ERROR err = MPS_OK;
+
+ self->bOverwriteM1M2prev = (configChanged && !initStatesFlag) ? 1 : 0;
+
+ { self->numM2rows = self->numOutputChannels; }
+
+ if (initStatesFlag) {
+ int i, j, k;
+
+ for (i = 0; i < self->numM2rows; i++) {
+ for (j = 0; j < self->numVChannels; j++) {
+ for (k = 0; k < MAX_PARAMETER_BANDS; k++) {
+ self->M2Real__FDK[i][j][k] = FL2FXCONST_DBL(0);
+ self->M2RealPrev__FDK[i][j][k] = FL2FXCONST_DBL(0);
+ }
+ }
+ }
+ }
+
+ return err;
+}
diff --git a/fdk-aac/libSACdec/src/sac_calcM1andM2.h b/fdk-aac/libSACdec/src/sac_calcM1andM2.h
new file mode 100644
index 0000000..996238d
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_calcM1andM2.h
@@ -0,0 +1,129 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec M1 and M2 calculation
+
+*******************************************************************************/
+
+/* sa_calcM1andM2.h */
+
+#ifndef SAC_CALCM1ANDM2_H
+#define SAC_CALCM1ANDM2_H
+
+#include "sac_dec.h"
+
+#define SCALE_PARAM_M1 3
+
+/* Scaling of M2 matrix, but only for binaural upmix type. */
+#define SCALE_PARAM_CALC_M2 (3)
+#define SCALE_PARAM_M2_515X (3)
+#define SCALE_PARAM_M2_525 (SCALE_PARAM_M1 + HRG_SF + 1 - SCALE_PARAM_CALC_M2)
+#define SCALE_PARAM_M2_212_PRED (3)
+/* Scaling of spectral data after applying M2 matrix, but only for binaural
+ upmix type Scaling is compensated later in synthesis qmf filterbank */
+#define SCALE_DATA_APPLY_M2 (1)
+
+SACDEC_ERROR initM1andM2(spatialDec* self, int initStatesFlag,
+ int configChanged);
+
+int SpatialDecGetResidualIndex(spatialDec* self, int row);
+
+SACDEC_ERROR SpatialDecCalculateM1andM2(spatialDec* self, int ps,
+ const SPATIAL_BS_FRAME* frame);
+
+#endif /* SAC_CALCM1ANDM2_H */
diff --git a/fdk-aac/libSACdec/src/sac_dec.cpp b/fdk-aac/libSACdec/src/sac_dec.cpp
new file mode 100644
index 0000000..4537d6e
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_dec.cpp
@@ -0,0 +1,1509 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Decoder Library
+
+*******************************************************************************/
+
+#include "sac_dec_errorcodes.h"
+#include "sac_dec.h"
+
+#include "sac_process.h"
+#include "sac_bitdec.h"
+#include "sac_smoothing.h"
+#include "sac_calcM1andM2.h"
+#include "sac_reshapeBBEnv.h"
+#include "sac_stp.h"
+#include "sac_rom.h"
+
+#include "FDK_decorrelate.h"
+
+#include "FDK_trigFcts.h"
+#include "FDK_matrixCalloc.h"
+
+/* static int pbStrideTable[] = {1, 2, 5, 28}; see sac_rom.cpp */
+
+enum {
+ APPLY_M2_NONE = 0, /* init value */
+ APPLY_M2 = 1, /* apply m2 fallback implementation */
+ APPLY_M2_MODE212 = 2, /* apply m2 for 212 mode */
+ APPLY_M2_MODE212_Res_PhaseCoding =
+ 3 /* apply m2 for 212 mode with residuals and phase coding */
+};
+
+/******************************************************************************************/
+/* function: FDK_SpatialDecInitDefaultSpatialSpecificConfig */
+/* output: struct of type SPATIAL_SPECIFIC_CONFIG */
+/* input: core coder audio object type */
+/* input: nr of core channels */
+/* input: sampling rate */
+/* input: nr of time slots */
+/* input: decoder level */
+/* input: flag indicating upmix type blind */
+/* */
+/* returns: error code */
+/******************************************************************************************/
+int FDK_SpatialDecInitDefaultSpatialSpecificConfig(
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
+ AUDIO_OBJECT_TYPE coreCodec, int coreChannels, int samplingFreq,
+ int nTimeSlots, int decoderLevel, int isBlind) {
+ return SpatialDecDefaultSpecificConfig(pSpatialSpecificConfig, coreCodec,
+ samplingFreq, nTimeSlots, decoderLevel,
+ isBlind, coreChannels);
+}
+
+/******************************************************************************************/
+/* function: FDK_SpatialDecCompareSpatialSpecificConfigHeader */
+/* input: 2 pointers to a ssc */
+/* */
+/* output: - */
+/* returns: error code (0 = equal, <>0 unequal) */
+/******************************************************************************************/
+int FDK_SpatialDecCompareSpatialSpecificConfigHeader(
+ SPATIAL_SPECIFIC_CONFIG *pSsc1, SPATIAL_SPECIFIC_CONFIG *pSsc2) {
+ int result = MPS_OK;
+
+ /* we assume: every bit must be equal */
+ if (FDKmemcmp(pSsc1, pSsc2, sizeof(SPATIAL_SPECIFIC_CONFIG)) != 0) {
+ result = MPS_UNEQUAL_SSC;
+ }
+ return result;
+}
+
+/*******************************************************************************
+ Functionname: SpatialDecClearFrameData
+ *******************************************************************************
+
+ Description: Clear/Fake frame data to avoid misconfiguration and allow proper
+ error concealment.
+ Arguments:
+ Input: self (frame data)
+ Output: No return value.
+
+*******************************************************************************/
+static void SpatialDecClearFrameData(
+ spatialDec *self, /* Shall be removed */
+ SPATIAL_BS_FRAME *bsFrame, const SACDEC_CREATION_PARAMS *const setup) {
+ int i;
+
+ FDK_ASSERT(self != NULL);
+ FDK_ASSERT(bsFrame != NULL);
+ FDK_ASSERT(setup != NULL);
+
+ /* do not apply shaping tools (GES or STP) */
+ for (i = 0; i < setup->maxNumOutputChannels;
+ i += 1) { /* MAX_OUTPUT_CHANNELS */
+ bsFrame->tempShapeEnableChannelSTP[i] = 0;
+ bsFrame->tempShapeEnableChannelGES[i] = 0;
+ }
+
+ bsFrame->TsdData->bsTsdEnable = 0;
+
+ /* use only 1 parameter set at the end of the frame */
+ bsFrame->numParameterSets = 1;
+ bsFrame->paramSlot[0] = self->timeSlots - 1;
+
+ /* parameter smoothing tool set to off */
+ bsFrame->bsSmoothMode[0] = 0;
+
+ /* reset residual data */
+ {
+ int resQmfBands, resTimeSlots = (1);
+
+ resQmfBands = setup->maxNumQmfBands;
+
+ for (i = 0; i < setup->bProcResidual
+ ? fMin(setup->maxNumResChannels,
+ setup->maxNumOttBoxes + setup->maxNumInputChannels)
+ : 0;
+ i += 1) {
+ for (int j = 0; j < resTimeSlots; j += 1) {
+ for (int k = 0; k < resQmfBands; k += 1) {
+ self->qmfResidualReal__FDK[i][j][k] = FL2FXCONST_DBL(0.0f);
+ self->qmfResidualImag__FDK[i][j][k] = FL2FXCONST_DBL(0.0f);
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+/*******************************************************************************
+ Functionname: FDK_SpatialDecOpen
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+spatialDec *FDK_SpatialDecOpen(const SPATIAL_DEC_CONFIG *config,
+ int stereoConfigIndex) {
+ int i;
+ int lfSize, hfSize;
+ spatialDec *self = NULL;
+ SACDEC_CREATION_PARAMS setup;
+
+ switch (config->decoderLevel) {
+ case DECODER_LEVEL_0: /* 212 maxNumOutputChannels== 2 */
+ setup.maxNumInputChannels = 1;
+ setup.maxNumOutputChannels = 2;
+ setup.maxNumQmfBands = 64;
+ setup.maxNumXChannels = 2;
+ setup.maxNumVChannels = 2;
+ setup.maxNumDecorChannels = 1;
+ setup.bProcResidual = 1;
+ setup.maxNumResidualChannels = 0;
+ setup.maxNumOttBoxes = 1;
+ setup.maxNumParams = setup.maxNumInputChannels + setup.maxNumOttBoxes;
+ break;
+ default:
+ return NULL;
+ }
+
+ setup.maxNumResChannels = 1;
+
+ {
+ switch (config->maxNumOutputChannels) {
+ case OUTPUT_CHANNELS_2_0:
+ setup.maxNumOutputChannels = fMin(setup.maxNumOutputChannels, 2);
+ break;
+ case OUTPUT_CHANNELS_DEFAULT:
+ default:
+ break;
+ }
+ }
+
+ setup.maxNumHybridBands = SacGetHybridSubbands(setup.maxNumQmfBands);
+
+ switch (config->decoderMode) {
+ case EXT_HQ_ONLY:
+ setup.maxNumCmplxQmfBands = setup.maxNumQmfBands;
+ setup.maxNumCmplxHybBands = setup.maxNumHybridBands;
+ break;
+ default:
+ setup.maxNumCmplxQmfBands = fixMax(PC_NUM_BANDS, setup.maxNumQmfBands);
+ setup.maxNumCmplxHybBands =
+ fixMax(PC_NUM_HYB_BANDS, setup.maxNumHybridBands);
+ break;
+ } /* switch config->decoderMode */
+
+ FDK_ALLOCATE_MEMORY_1D_INT(self, 1, spatialDec, SECT_DATA_L2)
+
+ self->createParams = setup;
+
+ FDK_ALLOCATE_MEMORY_1D(self->param2hyb, MAX_PARAMETER_BANDS + 1, int)
+
+ FDK_ALLOCATE_MEMORY_1D(self->numOttBands, setup.maxNumOttBoxes, int)
+
+ /* allocate arrays */
+
+ FDK_ALLOCATE_MEMORY_1D(self->smgTime, MAX_PARAMETER_SETS, int)
+ FDK_ALLOCATE_MEMORY_2D(self->smgData, MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS,
+ UCHAR)
+
+ FDK_ALLOCATE_MEMORY_3D(self->ottCLD__FDK, setup.maxNumOttBoxes,
+ MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
+ FDK_ALLOCATE_MEMORY_3D(self->ottICC__FDK, setup.maxNumOttBoxes,
+ MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
+ FDK_ALLOCATE_MEMORY_3D(self->ottIPD__FDK, setup.maxNumOttBoxes,
+ MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
+
+ /* Last parameters from prev frame */
+ FDK_ALLOCATE_MEMORY_2D(self->ottCLDidxPrev, setup.maxNumOttBoxes,
+ MAX_PARAMETER_BANDS, SCHAR)
+ FDK_ALLOCATE_MEMORY_2D(self->ottICCidxPrev, setup.maxNumOttBoxes,
+ MAX_PARAMETER_BANDS, SCHAR)
+ FDK_ALLOCATE_MEMORY_3D(self->ottICCdiffidx, setup.maxNumOttBoxes,
+ MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
+ FDK_ALLOCATE_MEMORY_2D(self->ottIPDidxPrev, setup.maxNumOttBoxes,
+ MAX_PARAMETER_BANDS, SCHAR)
+ FDK_ALLOCATE_MEMORY_2D(self->arbdmxGainIdxPrev, setup.maxNumInputChannels,
+ MAX_PARAMETER_BANDS, SCHAR)
+ FDK_ALLOCATE_MEMORY_2D(self->cmpOttCLDidxPrev, setup.maxNumOttBoxes,
+ MAX_PARAMETER_BANDS, SCHAR)
+ FDK_ALLOCATE_MEMORY_2D(self->cmpOttICCidxPrev, setup.maxNumOttBoxes,
+ MAX_PARAMETER_BANDS, SCHAR)
+ FDK_ALLOCATE_MEMORY_3D(self->outIdxData, setup.maxNumOttBoxes,
+ MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
+
+ FDK_ALLOCATE_MEMORY_3D(self->arbdmxGain__FDK, setup.maxNumInputChannels,
+ MAX_PARAMETER_SETS, MAX_PARAMETER_BANDS, SCHAR)
+ FDK_ALLOCATE_MEMORY_1D(self->arbdmxAlpha__FDK, setup.maxNumInputChannels,
+ FIXP_DBL)
+ FDK_ALLOCATE_MEMORY_1D(self->arbdmxAlphaPrev__FDK, setup.maxNumInputChannels,
+ FIXP_DBL)
+ FDK_ALLOCATE_MEMORY_2D(self->cmpArbdmxGainIdxPrev, setup.maxNumInputChannels,
+ MAX_PARAMETER_BANDS, SCHAR)
+
+ FDK_ALLOCATE_MEMORY_2D(self->cmpOttIPDidxPrev, setup.maxNumOttBoxes,
+ MAX_PARAMETER_BANDS, SCHAR)
+
+ FDK_ALLOCATE_MEMORY_3D_INT(self->M2Real__FDK, setup.maxNumOutputChannels,
+ setup.maxNumVChannels, MAX_PARAMETER_BANDS,
+ FIXP_DBL, SECT_DATA_L2)
+ FDK_ALLOCATE_MEMORY_3D(self->M2Imag__FDK, setup.maxNumOutputChannels,
+ setup.maxNumVChannels, MAX_PARAMETER_BANDS, FIXP_DBL)
+
+ FDK_ALLOCATE_MEMORY_3D_INT(self->M2RealPrev__FDK, setup.maxNumOutputChannels,
+ setup.maxNumVChannels, MAX_PARAMETER_BANDS,
+ FIXP_DBL, SECT_DATA_L2)
+ FDK_ALLOCATE_MEMORY_3D(self->M2ImagPrev__FDK, setup.maxNumOutputChannels,
+ setup.maxNumVChannels, MAX_PARAMETER_BANDS, FIXP_DBL)
+
+ FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(
+ self->qmfInputReal__FDK, setup.maxNumInputChannels, setup.maxNumQmfBands,
+ FIXP_DBL, SECT_DATA_L2)
+ FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(
+ self->qmfInputImag__FDK, setup.maxNumInputChannels,
+ setup.maxNumCmplxQmfBands, FIXP_DBL, SECT_DATA_L2)
+
+ FDK_ALLOCATE_MEMORY_2D_INT(self->hybInputReal__FDK, setup.maxNumInputChannels,
+ setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
+ FDK_ALLOCATE_MEMORY_2D_INT(self->hybInputImag__FDK, setup.maxNumInputChannels,
+ setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
+
+ if (setup.bProcResidual) {
+ FDK_ALLOCATE_MEMORY_1D(self->qmfResidualReal__FDK, setup.maxNumResChannels,
+ FIXP_DBL **)
+ FDK_ALLOCATE_MEMORY_1D(self->qmfResidualImag__FDK, setup.maxNumResChannels,
+ FIXP_DBL **)
+
+ FDK_ALLOCATE_MEMORY_1D(self->hybResidualReal__FDK, setup.maxNumResChannels,
+ FIXP_DBL *)
+ FDK_ALLOCATE_MEMORY_1D(self->hybResidualImag__FDK, setup.maxNumResChannels,
+ FIXP_DBL *)
+
+ for (i = 0; i < setup.maxNumResChannels; i++) {
+ int resQmfBands = (config->decoderMode == EXT_LP_ONLY)
+ ? PC_NUM_BANDS
+ : setup.maxNumQmfBands;
+ int resHybBands = (config->decoderMode == EXT_LP_ONLY)
+ ? PC_NUM_HYB_BANDS
+ : setup.maxNumHybridBands;
+ /* Alignment is needed for USAC residuals because QMF analysis directly
+ * writes to this buffer. */
+ FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(self->qmfResidualReal__FDK[i], (1),
+ resQmfBands, FIXP_DBL, SECT_DATA_L1)
+ FDK_ALLOCATE_MEMORY_2D_INT_ALIGNED(self->qmfResidualImag__FDK[i], (1),
+ resQmfBands, FIXP_DBL, SECT_DATA_L1)
+
+ FDK_ALLOCATE_MEMORY_1D(self->hybResidualReal__FDK[i],
+ setup.maxNumHybridBands, FIXP_DBL)
+ FDK_ALLOCATE_MEMORY_1D(self->hybResidualImag__FDK[i], resHybBands,
+ FIXP_DBL)
+ }
+ } /* if (setup.bProcResidual) */
+
+ FDK_ALLOCATE_MEMORY_2D_INT(self->wReal__FDK, setup.maxNumVChannels,
+ setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
+ FDK_ALLOCATE_MEMORY_2D_INT(self->wImag__FDK, setup.maxNumVChannels,
+ setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
+
+ FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputRealDry__FDK,
+ setup.maxNumOutputChannels,
+ setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
+ FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputImagDry__FDK,
+ setup.maxNumOutputChannels,
+ setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
+
+ FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputRealWet__FDK,
+ setup.maxNumOutputChannels,
+ setup.maxNumHybridBands, FIXP_DBL, SECT_DATA_L2)
+ FDK_ALLOCATE_MEMORY_2D_INT(self->hybOutputImagWet__FDK,
+ setup.maxNumOutputChannels,
+ setup.maxNumCmplxHybBands, FIXP_DBL, SECT_DATA_L2)
+
+ FDK_ALLOCATE_MEMORY_1D(self->hybridSynthesis, setup.maxNumOutputChannels,
+ FDK_SYN_HYB_FILTER)
+
+ FDK_ALLOCATE_MEMORY_1D(
+ self->hybridAnalysis,
+ setup.bProcResidual ? setup.maxNumInputChannels + setup.maxNumResChannels
+ : setup.maxNumInputChannels,
+ FDK_ANA_HYB_FILTER)
+
+ lfSize = 2 * BUFFER_LEN_LF * MAX_QMF_BANDS_TO_HYBRID;
+ {
+ hfSize =
+ BUFFER_LEN_HF * ((setup.maxNumQmfBands - MAX_QMF_BANDS_TO_HYBRID) +
+ (setup.maxNumCmplxQmfBands - MAX_QMF_BANDS_TO_HYBRID));
+ }
+
+ FDK_ALLOCATE_MEMORY_2D_INT(self->pHybridAnaStatesLFdmx,
+ setup.maxNumInputChannels, lfSize, FIXP_DBL,
+ SECT_DATA_L2) {
+ FDK_ALLOCATE_MEMORY_2D(self->pHybridAnaStatesHFdmx,
+ setup.maxNumInputChannels, hfSize, FIXP_DBL)
+ }
+
+ for (i = 0; i < setup.maxNumInputChannels; i++) {
+ FIXP_DBL *pHybridAnaStatesHFdmx;
+
+ pHybridAnaStatesHFdmx = self->pHybridAnaStatesHFdmx[i];
+
+ FDKhybridAnalysisOpen(&self->hybridAnalysis[i],
+ self->pHybridAnaStatesLFdmx[i],
+ lfSize * sizeof(FIXP_DBL), pHybridAnaStatesHFdmx,
+ hfSize * sizeof(FIXP_DBL));
+ }
+ if (setup.bProcResidual) {
+ lfSize = 2 * BUFFER_LEN_LF * MAX_QMF_BANDS_TO_HYBRID;
+ hfSize = BUFFER_LEN_HF *
+ ((((config->decoderMode == EXT_LP_ONLY) ? PC_NUM_BANDS
+ : setup.maxNumQmfBands) -
+ MAX_QMF_BANDS_TO_HYBRID) +
+ (setup.maxNumCmplxQmfBands - MAX_QMF_BANDS_TO_HYBRID));
+
+ FDK_ALLOCATE_MEMORY_2D_INT(self->pHybridAnaStatesLFres,
+ setup.maxNumResChannels, lfSize, FIXP_DBL,
+ SECT_DATA_L2)
+ FDK_ALLOCATE_MEMORY_2D(self->pHybridAnaStatesHFres, setup.maxNumResChannels,
+ hfSize, FIXP_DBL)
+
+ for (i = setup.maxNumInputChannels;
+ i < (setup.maxNumInputChannels + setup.maxNumResChannels); i++) {
+ FDKhybridAnalysisOpen(
+ &self->hybridAnalysis[i],
+ self->pHybridAnaStatesLFres[i - setup.maxNumInputChannels],
+ lfSize * sizeof(FIXP_DBL),
+ self->pHybridAnaStatesHFres[i - setup.maxNumInputChannels],
+ hfSize * sizeof(FIXP_DBL));
+ }
+ }
+
+ FDK_ALLOCATE_MEMORY_1D(self->smoothState, 1, SMOOTHING_STATE)
+ FDK_ALLOCATE_MEMORY_1D(self->reshapeBBEnvState, 1, RESHAPE_BBENV_STATE)
+
+ FDK_ALLOCATE_MEMORY_1D(self->apDecor, setup.maxNumDecorChannels, DECORR_DEC)
+ FDK_ALLOCATE_MEMORY_2D_INT(self->pDecorBufferCplx, setup.maxNumDecorChannels,
+ (2 * ((825) + (373))), FIXP_DBL, SECT_DATA_L2)
+
+ for (i = 0; i < setup.maxNumDecorChannels; i++) {
+ if (FDKdecorrelateOpen(&self->apDecor[i], self->pDecorBufferCplx[i],
+ (2 * ((825) + (373))))) {
+ goto bail;
+ }
+ }
+
+ if (subbandTPCreate(&self->hStpDec) != MPS_OK) {
+ goto bail;
+ }
+
+ /* save general decoder configuration */
+ self->decoderLevel = config->decoderLevel;
+ self->decoderMode = config->decoderMode;
+ self->binauralMode = config->binauralMode;
+
+ /* preinitialize configuration */
+ self->partiallyComplex = (config->decoderMode != EXT_HQ_ONLY) ? 1 : 0;
+
+ /* Set to default state */
+ SpatialDecConcealment_Init(&self->concealInfo, MPEGS_CONCEAL_RESET_ALL);
+
+ /* Everything is fine so return the handle */
+ return self;
+
+bail:
+ /* Collector for all errors.
+ Deallocate all memory and return a invalid handle. */
+ FDK_SpatialDecClose(self);
+
+ return NULL;
+}
+
+/*******************************************************************************
+ Functionname: isValidConfig
+ *******************************************************************************
+
+ Description: Validate if configuration is supported in present instance
+
+ Arguments:
+
+ Return: 1: all okay
+ 0: configuration not supported
+*******************************************************************************/
+static int isValidConfig(spatialDec const *const self,
+ const SPATIAL_DEC_UPMIX_TYPE upmixType,
+ SPATIALDEC_PARAM const *const pUserParams,
+ const AUDIO_OBJECT_TYPE coreAot) {
+ UPMIXTYPE nUpmixType;
+
+ FDK_ASSERT(self != NULL);
+ FDK_ASSERT(pUserParams != NULL);
+
+ nUpmixType = (UPMIXTYPE)upmixType;
+
+ switch (nUpmixType) {
+ case UPMIXTYPE_BYPASS: /* UPMIX_TYPE_BYPASS */
+ break;
+ case UPMIXTYPE_NORMAL: /* UPMIX_TYPE_NORMAL */
+ break;
+ default:
+ return 0; /* unsupported upmixType */
+ }
+
+ return 1; /* upmixType supported */
+}
+
+static SACDEC_ERROR CheckLevelTreeUpmixType(
+ const SACDEC_CREATION_PARAMS *const pCreateParams,
+ const SPATIAL_SPECIFIC_CONFIG *const pSsc, const int decoderLevel,
+ const UPMIXTYPE upmixType) {
+ SACDEC_ERROR err = MPS_OK;
+ int nOutputChannels, treeConfig;
+
+ FDK_ASSERT(pCreateParams != NULL);
+ FDK_ASSERT(pSsc != NULL);
+
+ treeConfig = pSsc->treeConfig;
+
+ switch (decoderLevel) {
+ case 0: {
+ if (treeConfig != SPATIALDEC_MODE_RSVD7) {
+ err = MPS_INVALID_TREECONFIG;
+ goto bail;
+ }
+ break;
+ }
+ default:
+ err = MPS_INVALID_PARAMETER /* MPS_UNIMPLEMENTED */;
+ goto bail;
+ }
+
+ switch (upmixType) {
+ case UPMIXTYPE_BYPASS:
+ nOutputChannels = pSsc->nInputChannels;
+ break;
+ default:
+ nOutputChannels = pSsc->nOutputChannels;
+ break;
+ }
+
+ /* Is sufficient memory allocated. */
+ if ((pSsc->nInputChannels > pCreateParams->maxNumInputChannels) ||
+ (nOutputChannels > pCreateParams->maxNumOutputChannels) ||
+ (pSsc->nOttBoxes > pCreateParams->maxNumOttBoxes)) {
+ err = MPS_INVALID_PARAMETER;
+ }
+
+bail:
+ return err;
+}
+
+void SpatialDecInitParserContext(spatialDec *self) {
+ int i, j;
+
+ for (i = 0; i < self->createParams.maxNumOttBoxes; i += 1) {
+ for (j = 0; j < MAX_PARAMETER_BANDS; j++) {
+ self->ottCLDidxPrev[i][j] = 0;
+ self->ottICCidxPrev[i][j] = 0;
+ self->cmpOttCLDidxPrev[i][j] = 0;
+ self->cmpOttICCidxPrev[i][j] = 0;
+ }
+ }
+ for (i = 0; i < self->createParams.maxNumInputChannels; i++) {
+ for (j = 0; j < MAX_PARAMETER_BANDS; j++) {
+ self->arbdmxGainIdxPrev[i][j] = 0;
+ self->cmpArbdmxGainIdxPrev[i][j] = 0;
+ }
+ }
+}
+
+/*******************************************************************************
+ Functionname: FDK_SpatialDecInit
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+
+SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
+ int nQmfBands,
+ SPATIAL_DEC_UPMIX_TYPE const upmixType,
+ SPATIALDEC_PARAM *pUserParams, UINT initFlags) {
+ SACDEC_ERROR err = MPS_OK;
+ int nCh, i, j, k;
+ int maxQmfBands;
+ int bypassMode = 0;
+
+ self->useFDreverb = 0;
+
+ /* check configuration parameter */
+ if (!isValidConfig(self, upmixType, pUserParams,
+ pSpatialSpecificConfig->coreCodec)) {
+ return MPS_INVALID_PARAMETER;
+ }
+
+ /* check tree configuration */
+ err = CheckLevelTreeUpmixType(&self->createParams, pSpatialSpecificConfig,
+ self->decoderLevel, (UPMIXTYPE)upmixType);
+ if (err != MPS_OK) {
+ goto bail;
+ }
+
+ /* Store and update instance after all checks passed successfully: */
+ self->upmixType = (UPMIXTYPE)upmixType;
+
+ if (initFlags & MPEGS_INIT_PARAMS_ERROR_CONCEALMENT) { /* At least one error
+ concealment
+ parameter changed */
+ err = SpatialDecConcealment_SetParam(
+ &self->concealInfo, SAC_DEC_CONCEAL_METHOD, pUserParams->concealMethod);
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ err = SpatialDecConcealment_SetParam(&self->concealInfo,
+ SAC_DEC_CONCEAL_NUM_KEEP_FRAMES,
+ pUserParams->concealNumKeepFrames);
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ err = SpatialDecConcealment_SetParam(
+ &self->concealInfo, SAC_DEC_CONCEAL_FADE_OUT_SLOPE_LENGTH,
+ pUserParams->concealFadeOutSlopeLength);
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ err = SpatialDecConcealment_SetParam(&self->concealInfo,
+ SAC_DEC_CONCEAL_FADE_IN_SLOPE_LENGTH,
+ pUserParams->concealFadeInSlopeLength);
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ err = SpatialDecConcealment_SetParam(&self->concealInfo,
+ SAC_DEC_CONCEAL_NUM_RELEASE_FRAMES,
+ pUserParams->concealNumReleaseFrames);
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ }
+
+ if (initFlags &
+ MPEGS_INIT_STATES_ERROR_CONCEALMENT) { /* Set to default state */
+ SpatialDecConcealment_Init(&self->concealInfo, MPEGS_CONCEAL_RESET_STATE);
+ }
+
+ /* determine bypass mode */
+ bypassMode |= pUserParams->bypassMode;
+ bypassMode |= ((self->upmixType == UPMIXTYPE_BYPASS) ? 1 : 0);
+
+ /* static decoder scale depends on number of qmf bands */
+ switch (nQmfBands) {
+ case 16:
+ case 24:
+ case 32:
+ self->staticDecScale = 21;
+ break;
+ case 64:
+ self->staticDecScale = 22;
+ break;
+ default:
+ return MPS_INVALID_PARAMETER;
+ }
+
+ self->numParameterSetsPrev = 1;
+
+ self->qmfBands = nQmfBands;
+ /* self->hybridBands will be updated in SpatialDecDecodeHeader() below. */
+
+ self->bShareDelayWithSBR = 0;
+
+ err = SpatialDecDecodeHeader(self, pSpatialSpecificConfig);
+ if (err != MPS_OK) {
+ goto bail;
+ }
+
+ self->stereoConfigIndex = pSpatialSpecificConfig->stereoConfigIndex;
+
+ if (initFlags & MPEGS_INIT_STATES_ANA_QMF_FILTER) {
+ self->qmfInputDelayBufPos = 0;
+ self->pc_filterdelay = 1; /* Division by 0 not possible */
+ }
+
+ maxQmfBands = self->qmfBands;
+
+ /* init residual decoder */
+
+ /* init tonality smoothing */
+ if (initFlags & MPEGS_INIT_STATES_PARAM) {
+ initParameterSmoothing(self);
+ }
+
+ /* init GES */
+ initBBEnv(self, (initFlags & MPEGS_INIT_STATES_GES) ? 1 : 0);
+
+ /* Clip protection is applied only for normal processing. */
+ if (!isTwoChMode(self->upmixType) && !bypassMode) {
+ self->staticDecScale += self->clipProtectGainSF__FDK;
+ }
+
+ {
+ UINT flags = 0;
+ INT initStatesFlag = (initFlags & MPEGS_INIT_STATES_ANA_QMF_FILTER) ? 1 : 0;
+ INT useLdFilter =
+ (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) ? 1 : 0;
+
+ flags = self->pQmfDomain->globalConf.flags_requested;
+ flags &= (~(UINT)QMF_FLAG_LP);
+
+ if (initStatesFlag)
+ flags &= ~QMF_FLAG_KEEP_STATES;
+ else
+ flags |= QMF_FLAG_KEEP_STATES;
+
+ if (useLdFilter)
+ flags |= QMF_FLAG_MPSLDFB;
+ else
+ flags &= ~QMF_FLAG_MPSLDFB;
+
+ self->pQmfDomain->globalConf.flags_requested = flags;
+ FDK_QmfDomain_Configure(self->pQmfDomain);
+
+ /* output scaling */
+ for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
+ int outputScale = 0, outputGain_e = 0, scale = 0;
+ FIXP_DBL outputGain_m = getChGain(self, nCh, &outputGain_e);
+
+ if (!isTwoChMode(self->upmixType) && !bypassMode) {
+ outputScale +=
+ self->clipProtectGainSF__FDK; /* consider clip protection scaling at
+ synthesis qmf */
+ }
+
+ scale = outputScale;
+
+ qmfChangeOutScalefactor(&self->pQmfDomain->QmfDomainOut[nCh].fb, scale);
+ qmfChangeOutGain(&self->pQmfDomain->QmfDomainOut[nCh].fb, outputGain_m,
+ outputGain_e);
+ }
+ }
+
+ for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
+ FDKhybridSynthesisInit(&self->hybridSynthesis[nCh], THREE_TO_TEN,
+ self->qmfBands, maxQmfBands);
+ }
+
+ /* for input, residual channels and arbitrary down-mix residual channels */
+ for (nCh = 0; nCh < self->createParams.maxNumInputChannels; nCh++) {
+ FDKhybridAnalysisInit(
+ &self->hybridAnalysis[nCh], THREE_TO_TEN, self->qmfBands, maxQmfBands,
+ (initFlags & MPEGS_INIT_STATES_ANA_HYB_FILTER) ? 1 : 0);
+ }
+ for (; nCh < (self->createParams.bProcResidual
+ ? (self->createParams.maxNumInputChannels +
+ self->createParams.maxNumResChannels)
+ : self->createParams.maxNumInputChannels);
+ nCh++) {
+ FDKhybridAnalysisInit(&self->hybridAnalysis[nCh], THREE_TO_TEN, maxQmfBands,
+ maxQmfBands, 0);
+ }
+
+ {
+ for (k = 0; k < self->numDecorSignals; k++) {
+ int errCode, idec;
+ FDK_DECORR_TYPE decorrType = DECORR_PS;
+ decorrType = DECORR_LD;
+ if (self->pConfigCurrent->syntaxFlags &
+ (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) {
+ decorrType =
+ ((self->treeConfig == TREE_212) && (self->decorrType == DECORR_PS))
+ ? DECORR_PS
+ : DECORR_USAC;
+ }
+ {
+ idec = k;
+ if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) {
+ if (self->treeConfig == TREE_212 && k == 0) {
+ idec = 2;
+ }
+ }
+ }
+ errCode = FDKdecorrelateInit(
+ &self->apDecor[k], self->hybridBands, decorrType, DUCKER_AUTOMATIC,
+ self->decorrConfig, idec, 0, /* self->partiallyComplex */
+ 0, 0, /* isLegacyPS */
+ (initFlags & MPEGS_INIT_STATES_DECORRELATOR) ? 1 : 0);
+ if (errCode) return MPS_NOTOK;
+ }
+ } /* !self->partiallyComplex */
+
+ err = initM1andM2(self, (initFlags & MPEGS_INIT_STATES_M1M2) ? 1 : 0,
+ (initFlags & MPEGS_INIT_CONFIG) ? 1 : 0);
+ if (err != MPS_OK) return err;
+
+ /* Initialization of previous frame data */
+ if (initFlags & MPEGS_INIT_STATES_PARAM) {
+ for (i = 0; i < self->createParams.maxNumOttBoxes; i += 1) {
+ /* reset icc diff data */
+ for (k = 0; k < MAX_PARAMETER_SETS; k += 1) {
+ for (j = 0; j < MAX_PARAMETER_BANDS; j += 1) {
+ self->ottICCdiffidx[i][k][j] = 0;
+ }
+ }
+ }
+ /* Parameter Smoothing */
+ /* robustness: init with one of the values of smgTimeTable[] = {64, 128,
+ 256, 512} to avoid division by zero in calcFilterCoeff__FDK() */
+ self->smoothState->prevSmgTime = smgTimeTable[2]; /* == 256 */
+ FDKmemclear(self->smoothState->prevSmgData,
+ MAX_PARAMETER_BANDS * sizeof(UCHAR));
+ FDKmemclear(self->smoothState->opdLeftState__FDK,
+ MAX_PARAMETER_BANDS * sizeof(FIXP_DBL));
+ FDKmemclear(self->smoothState->opdRightState__FDK,
+ MAX_PARAMETER_BANDS * sizeof(FIXP_DBL));
+ }
+
+ self->prevTimeSlot = -1;
+ self->curTimeSlot =
+ MAX_TIME_SLOTS + 1; /* Initialize with a invalid value to trigger
+ concealment if first frame has no valid data. */
+ self->curPs = 0;
+
+ subbandTPInit(self->hStpDec);
+
+bail:
+ return err;
+}
+
+void SpatialDecChannelProperties(spatialDec *self,
+ AUDIO_CHANNEL_TYPE channelType[],
+ UCHAR channelIndices[],
+ const FDK_channelMapDescr *const mapDescr) {
+ if ((self == NULL) || (channelType == NULL) || (channelIndices == NULL) ||
+ (mapDescr == NULL)) {
+ return; /* no extern buffer to be filled */
+ }
+
+ if (self->numOutputChannelsAT !=
+ treePropertyTable[self->treeConfig].numOutputChannels) {
+ int ch;
+ /* Declare all channels to be front channels: */
+ for (ch = 0; ch < self->numOutputChannelsAT; ch += 1) {
+ channelType[ch] = ACT_FRONT;
+ channelIndices[ch] = ch;
+ }
+ } else {
+ /* ISO/IEC FDIS 23003-1:2006(E), page 46, Table 40 bsTreeConfig */
+ switch (self->treeConfig) {
+ case TREE_212:
+ channelType[0] = ACT_FRONT;
+ channelIndices[0] = 0;
+ channelType[1] = ACT_FRONT;
+ channelIndices[1] = 1;
+ break;
+ default:;
+ }
+ }
+}
+
+/*******************************************************************************
+ Functionname: FDK_SpatialDecClose
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+
+void FDK_SpatialDecClose(spatialDec *self) {
+ if (self) {
+ int k;
+
+ if (self->apDecor != NULL) {
+ for (k = 0; k < self->createParams.maxNumDecorChannels; k++) {
+ FDKdecorrelateClose(&(self->apDecor[k]));
+ }
+ FDK_FREE_MEMORY_1D(self->apDecor);
+ }
+ if (self->pDecorBufferCplx != NULL) {
+ FDK_FREE_MEMORY_2D(self->pDecorBufferCplx);
+ }
+
+ subbandTPDestroy(&self->hStpDec);
+
+ FDK_FREE_MEMORY_1D(self->reshapeBBEnvState);
+ FDK_FREE_MEMORY_1D(self->smoothState);
+
+ FDK_FREE_MEMORY_2D(self->pHybridAnaStatesLFdmx);
+ FDK_FREE_MEMORY_2D(self->pHybridAnaStatesHFdmx);
+ FDK_FREE_MEMORY_2D(self->pHybridAnaStatesLFres);
+ FDK_FREE_MEMORY_2D(self->pHybridAnaStatesHFres);
+ FDK_FREE_MEMORY_1D(self->hybridAnalysis);
+
+ FDK_FREE_MEMORY_1D(self->hybridSynthesis);
+
+ /* The time buffer is passed to the decoder from outside to avoid copying
+ * (zero copy). */
+ /* FDK_FREE_MEMORY_2D(self->timeOut__FDK); */
+
+ FDK_FREE_MEMORY_2D(self->hybOutputImagWet__FDK);
+ FDK_FREE_MEMORY_2D(self->hybOutputRealWet__FDK);
+
+ FDK_FREE_MEMORY_2D(self->hybOutputImagDry__FDK);
+ FDK_FREE_MEMORY_2D(self->hybOutputRealDry__FDK);
+
+ FDK_FREE_MEMORY_2D(self->wImag__FDK);
+ FDK_FREE_MEMORY_2D(self->wReal__FDK);
+
+ if (self->createParams.bProcResidual) {
+ int i;
+
+ for (i = 0; i < self->createParams.maxNumResChannels; i++) {
+ if (self->hybResidualImag__FDK != NULL)
+ FDK_FREE_MEMORY_1D(self->hybResidualImag__FDK[i]);
+ if (self->hybResidualReal__FDK != NULL)
+ FDK_FREE_MEMORY_1D(self->hybResidualReal__FDK[i]);
+ if (self->qmfResidualImag__FDK != NULL)
+ FDK_FREE_MEMORY_2D_ALIGNED(self->qmfResidualImag__FDK[i]);
+ if (self->qmfResidualReal__FDK != NULL)
+ FDK_FREE_MEMORY_2D_ALIGNED(self->qmfResidualReal__FDK[i]);
+ }
+
+ FDK_FREE_MEMORY_1D(self->hybResidualImag__FDK);
+ FDK_FREE_MEMORY_1D(self->hybResidualReal__FDK);
+
+ FDK_FREE_MEMORY_1D(self->qmfResidualImag__FDK);
+ FDK_FREE_MEMORY_1D(self->qmfResidualReal__FDK);
+
+ } /* self->createParams.bProcResidual */
+
+ FDK_FREE_MEMORY_2D(self->hybInputImag__FDK);
+ FDK_FREE_MEMORY_2D(self->hybInputReal__FDK);
+
+ FDK_FREE_MEMORY_2D_ALIGNED(self->qmfInputImag__FDK);
+ FDK_FREE_MEMORY_2D_ALIGNED(self->qmfInputReal__FDK);
+
+ FDK_FREE_MEMORY_3D(self->M2ImagPrev__FDK);
+
+ FDK_FREE_MEMORY_3D(self->M2RealPrev__FDK);
+
+ FDK_FREE_MEMORY_3D(self->M2Imag__FDK);
+
+ FDK_FREE_MEMORY_3D(self->M2Real__FDK);
+
+ FDK_FREE_MEMORY_1D(self->arbdmxAlphaPrev__FDK);
+ FDK_FREE_MEMORY_1D(self->arbdmxAlpha__FDK);
+
+ FDK_FREE_MEMORY_3D(self->arbdmxGain__FDK);
+
+ FDK_FREE_MEMORY_3D(self->ottIPD__FDK);
+ FDK_FREE_MEMORY_3D(self->ottICC__FDK);
+ FDK_FREE_MEMORY_3D(self->ottCLD__FDK);
+
+ /* Last parameters from prev frame */
+ FDK_FREE_MEMORY_2D(self->ottCLDidxPrev);
+ FDK_FREE_MEMORY_2D(self->ottICCidxPrev);
+ FDK_FREE_MEMORY_3D(self->ottICCdiffidx);
+ FDK_FREE_MEMORY_2D(self->ottIPDidxPrev);
+ FDK_FREE_MEMORY_2D(self->arbdmxGainIdxPrev);
+
+ FDK_FREE_MEMORY_2D(self->cmpOttCLDidxPrev);
+ FDK_FREE_MEMORY_2D(self->cmpOttICCidxPrev);
+ FDK_FREE_MEMORY_3D(self->outIdxData);
+ FDK_FREE_MEMORY_2D(self->cmpOttIPDidxPrev);
+ FDK_FREE_MEMORY_2D(self->cmpArbdmxGainIdxPrev);
+
+ FDK_FREE_MEMORY_2D(self->smgData);
+ FDK_FREE_MEMORY_1D(self->smgTime);
+
+ FDK_FREE_MEMORY_1D(self->numOttBands);
+
+ FDK_FREE_MEMORY_1D(self->param2hyb);
+
+ FDK_FREE_MEMORY_1D(self);
+ }
+
+ return;
+}
+
+/**
+ * \brief Apply Surround bypass buffer copies
+ * \param self spatialDec handle
+ * \param hybInputReal
+ * \param hybInputImag
+ * \param hybOutputReal
+ * \param hybOutputImag
+ * \param numInputChannels amount if input channels available in hybInputReal
+ * and hybInputImag, which may differ from self->numInputChannels.
+ */
+static void SpatialDecApplyBypass(spatialDec *self, FIXP_DBL **hybInputReal,
+ FIXP_DBL **hybInputImag,
+ FIXP_DBL **hybOutputReal,
+ FIXP_DBL **hybOutputImag,
+ const int numInputChannels) {
+ int complexHybBands;
+
+ complexHybBands = self->hybridBands;
+
+ {
+ int ch;
+ int rf = -1, lf = -1, cf = -1; /* Right Front, Left Front, Center Front */
+
+ /* Determine output channel indices according to tree config */
+ switch (self->treeConfig) {
+ case TREE_212: /* 212 */
+ lf = 0;
+ rf = 1;
+ break;
+ default:;
+ }
+
+ /* Note: numInputChannels might not match the tree config ! */
+ switch (numInputChannels) {
+ case 1:
+ if (cf > 0) {
+ FDKmemcpy(hybOutputReal[cf], hybInputReal[0],
+ self->hybridBands * sizeof(FIXP_DBL));
+ FDKmemcpy(hybOutputImag[cf], hybInputImag[0],
+ complexHybBands * sizeof(FIXP_DBL));
+ } else {
+ FDKmemcpy(hybOutputReal[lf], hybInputReal[0],
+ self->hybridBands * sizeof(FIXP_DBL));
+ FDKmemcpy(hybOutputReal[rf], hybInputReal[0],
+ self->hybridBands * sizeof(FIXP_DBL));
+ FDKmemcpy(hybOutputImag[lf], hybInputImag[0],
+ complexHybBands * sizeof(FIXP_DBL));
+ FDKmemcpy(hybOutputImag[rf], hybInputImag[0],
+ complexHybBands * sizeof(FIXP_DBL));
+ }
+ break;
+ case 2:
+ FDK_ASSERT(lf != -1);
+ FDK_ASSERT(rf != -1);
+ FDKmemcpy(hybOutputReal[lf], hybInputReal[0],
+ self->hybridBands * sizeof(FIXP_DBL));
+ FDKmemcpy(hybOutputReal[rf], hybInputReal[1],
+ self->hybridBands * sizeof(FIXP_DBL));
+ FDKmemcpy(hybOutputImag[lf], hybInputImag[0],
+ complexHybBands * sizeof(FIXP_DBL));
+ FDKmemcpy(hybOutputImag[rf], hybInputImag[1],
+ complexHybBands * sizeof(FIXP_DBL));
+ break;
+ }
+ for (ch = 0; ch < self->numOutputChannelsAT; ch++) {
+ if (ch == lf || ch == rf || ch == cf) {
+ continue; /* Skip bypassed channels */
+ }
+ FDKmemclear(hybOutputReal[ch], self->hybridBands * sizeof(FIXP_DBL));
+ FDKmemclear(hybOutputImag[ch], complexHybBands * sizeof(FIXP_DBL));
+ }
+ }
+}
+
+/*******************************************************************************
+ Functionname: SpatialDecApplyParameterSets
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+static SACDEC_ERROR SpatialDecApplyParameterSets(
+ spatialDec *self, const SPATIAL_BS_FRAME *frame, SPATIALDEC_INPUT_MODE mode,
+ PCM_MPS *inData, /* Time domain input */
+ FIXP_DBL **qmfInDataReal, /* QMF domain data l/r */
+ FIXP_DBL **qmfInDataImag, /* QMF domain data l/r */
+ UINT nSamples, UINT controlFlags, int numInputChannels,
+ const FDK_channelMapDescr *const mapDescr) {
+ SACDEC_ERROR err = MPS_OK;
+
+ FIXP_SGL alpha;
+
+ int ts;
+ int ch;
+ int hyb;
+
+ int prevSlot = self->prevTimeSlot;
+ int ps = self->curPs;
+ int ts_io = 0; /* i/o dependent slot */
+ int bypassMode = (controlFlags & MPEGS_BYPASSMODE) ? 1 : 0;
+
+ /* Bypass can be triggered by the upmixType, too. */
+ bypassMode |= ((self->upmixType == UPMIXTYPE_BYPASS) ? 1 : 0);
+
+ /*
+ * Decode available slots
+ */
+ for (ts = self->curTimeSlot;
+ ts <= fixMin(self->curTimeSlot + (int)nSamples / self->qmfBands - 1,
+ self->timeSlots - 1);
+ ts++, ts_io++) {
+ int currSlot = frame->paramSlot[ps];
+
+ /*
+ * Get new parameter set
+ */
+ if (ts == prevSlot + 1) {
+ err = SpatialDecCalculateM1andM2(self, ps,
+ frame); /* input: ottCLD, ottICC, ... */
+ /* output: M1param(Real/Imag), M2(Real/Imag) */
+ if (err != MPS_OK) {
+ bypassMode = 1;
+ if (self->errInt == MPS_OK) {
+ /* store internal error befor it gets overwritten */
+ self->errInt = err;
+ }
+ err = MPS_OK;
+ }
+
+ if ((ps == 0) && (self->bOverwriteM1M2prev != 0)) {
+ /* copy matrix entries of M1/M2 of the first parameter set to the
+ previous matrices (of the last frame). This avoids the interpolation
+ of incompatible values. E.g. for residual bands the coefficients are
+ calculated differently compared to non-residual bands.
+ */
+ SpatialDecBufferMatrices(self); /* input: M(1/2)param(Real/Imag) */
+ /* output: M(1/2)param(Real/Imag)Prev */
+ self->bOverwriteM1M2prev = 0;
+ }
+
+ SpatialDecSmoothM1andM2(
+ self, frame,
+ ps); /* input: M1param(Real/Imag)(Prev), M2(Real/Imag)(Prev) */
+ /* output: M1param(Real/Imag), M2(Real/Imag) */
+ }
+
+ alpha = FX_DBL2FX_SGL(fDivNorm(ts - prevSlot, currSlot - prevSlot));
+
+ switch (mode) {
+ case INPUTMODE_QMF_SBR:
+ if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD)
+ self->bShareDelayWithSBR = 0; /* We got no hybrid delay */
+ else
+ self->bShareDelayWithSBR = 1;
+ SpatialDecFeedQMF(self, qmfInDataReal, qmfInDataImag, ts_io, bypassMode,
+ self->qmfInputReal__FDK, self->qmfInputImag__FDK,
+ self->numInputChannels);
+ break;
+ case INPUTMODE_TIME:
+ self->bShareDelayWithSBR = 0;
+ SpatialDecQMFAnalysis(self, inData, ts_io, bypassMode,
+ self->qmfInputReal__FDK, self->qmfInputImag__FDK,
+ self->numInputChannels);
+ break;
+ default:
+ break;
+ }
+
+ if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC) &&
+ self->residualCoding) {
+ int offset;
+ ch = 1;
+
+ offset = self->pQmfDomain->globalConf.nBandsSynthesis *
+ self->pQmfDomain->globalConf.nQmfTimeSlots;
+
+ {
+ const PCM_MPS *inSamples =
+ &inData[ts * self->pQmfDomain->globalConf.nBandsAnalysis];
+
+ CalculateSpaceAnalysisQmf(
+ &self->pQmfDomain->QmfDomainIn[ch].fb, inSamples + (ch * offset),
+ self->qmfResidualReal__FDK[0][0], self->qmfResidualImag__FDK[0][0]);
+
+ if (!isTwoChMode(self->upmixType) && !bypassMode) {
+ int i;
+ FIXP_DBL *RESTRICT self_qmfResidualReal__FDK_0_0 =
+ &self->qmfResidualReal__FDK[0][0][0];
+ FIXP_DBL *RESTRICT self_qmfResidualImag__FDK_0_0 =
+ &self->qmfResidualImag__FDK[0][0][0];
+
+ if ((self->pQmfDomain->globalConf.nBandsAnalysis == 24) &&
+ !(self->stereoConfigIndex == 3)) {
+ for (i = 0; i < self->qmfBands; i++) {
+ self_qmfResidualReal__FDK_0_0[i] =
+ fMult(self_qmfResidualReal__FDK_0_0[i] << 1,
+ self->clipProtectGain__FDK);
+ self_qmfResidualImag__FDK_0_0[i] =
+ fMult(self_qmfResidualImag__FDK_0_0[i] << 1,
+ self->clipProtectGain__FDK);
+ }
+ } else {
+ for (i = 0; i < self->qmfBands; i++) {
+ self_qmfResidualReal__FDK_0_0[i] = fMult(
+ self_qmfResidualReal__FDK_0_0[i], self->clipProtectGain__FDK);
+ self_qmfResidualImag__FDK_0_0[i] = fMult(
+ self_qmfResidualImag__FDK_0_0[i], self->clipProtectGain__FDK);
+ }
+ }
+ }
+ }
+ }
+
+ SpatialDecHybridAnalysis(
+ self, /* input: qmfInput(Real/Imag), qmfResidual(Real/Imag) */
+ self->qmfInputReal__FDK, self->qmfInputImag__FDK,
+ self->hybInputReal__FDK, self->hybInputImag__FDK, ts, numInputChannels);
+
+ if (bypassMode) {
+ SpatialDecApplyBypass(
+ self, self->hybInputReal__FDK, /* input: hybInput(Real/Imag) */
+ self->hybInputImag__FDK,
+ self->hybOutputRealDry__FDK, /* output: hybOutput(Real/Imag)Dry */
+ self->hybOutputImagDry__FDK, numInputChannels);
+ } else /* !bypassMode */
+ {
+ FIXP_DBL *pxReal[MAX_NUM_XCHANNELS] = {NULL};
+ FIXP_DBL *pxImag[MAX_NUM_XCHANNELS] = {NULL};
+
+ SpatialDecCreateX(self,
+ self->hybInputReal__FDK, /* input: hybInput(Real/Imag),
+ hybResidual(Real/Imag) */
+ self->hybInputImag__FDK, pxReal, pxImag);
+
+ {
+ SpatialDecApplyM1_CreateW_Mode212(
+ self, frame, pxReal, pxImag,
+ self->wReal__FDK, /* output: w(Real/Imag) */
+ self->wImag__FDK);
+ }
+ if (err != MPS_OK) goto bail;
+
+ int applyM2Config = APPLY_M2_NONE;
+
+ applyM2Config = APPLY_M2;
+ if ((self->pConfigCurrent->syntaxFlags &
+ (SACDEC_SYNTAX_USAC | SACDEC_SYNTAX_RSVD50)) &&
+ (self->tempShapeConfig != 1) && (self->tempShapeConfig != 2)) {
+ if (self->phaseCoding == 3)
+ applyM2Config = APPLY_M2_MODE212_Res_PhaseCoding;
+ else
+ applyM2Config = APPLY_M2_MODE212;
+ }
+
+ switch (applyM2Config) {
+ case APPLY_M2_MODE212: {
+ err = SpatialDecApplyM2_Mode212(
+ self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
+ self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK);
+ } break;
+ case APPLY_M2_MODE212_Res_PhaseCoding:
+ err = SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
+ self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
+ self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK);
+ break;
+ case APPLY_M2:
+ err = SpatialDecApplyM2(
+ self, ps, alpha, self->wReal__FDK, self->wImag__FDK,
+ self->hybOutputRealDry__FDK, self->hybOutputImagDry__FDK,
+ self->hybOutputRealWet__FDK, self->hybOutputImagWet__FDK);
+ break;
+ default:
+ err = MPS_APPLY_M2_ERROR;
+ goto bail;
+ }
+
+ if (err != MPS_OK) goto bail;
+
+ if ((self->tempShapeConfig == 2) && (!isTwoChMode(self->upmixType))) {
+ SpatialDecReshapeBBEnv(self, frame,
+ ts); /* input: reshapeBBEnvState,
+ hybOutput(Real/Imag)(Dry/Wet),
+ hybInput(Real/Imag) */
+ } /* output: hybOutput(Real/Imag)Dry */
+
+ /* Merge parts of the dry and wet QMF buffers. */
+ if ((self->tempShapeConfig == 1) && (!isTwoChMode(self->upmixType))) {
+ for (ch = 0; ch < self->numOutputChannels; ch++) {
+ for (hyb = 0; hyb < self->tp_hybBandBorder; hyb++) {
+ self->hybOutputRealDry__FDK[ch][hyb] +=
+ self->hybOutputRealWet__FDK[ch][hyb];
+ self->hybOutputImagDry__FDK[ch][hyb] +=
+ self->hybOutputImagWet__FDK[ch][hyb];
+ } /* loop hyb */
+ } /* loop ch */
+ err = subbandTPApply(
+ self, frame); /* input: hStpDec, hybOutput(Real/Imag)Dry/Wet */
+ /* output: hStpDec, hybOutput(Real/Imag)Dry */
+ if (err != MPS_OK) goto bail;
+ } /* (self->tempShapeConfig == 1) */
+ else {
+ /* The wet signal is added to the dry signal in applyM2 if GES and STP
+ * are disabled */
+ if ((self->tempShapeConfig == 1) || (self->tempShapeConfig == 2)) {
+ int nHybBands;
+ nHybBands = self->hybridBands;
+
+ for (ch = 0; ch < self->numOutputChannels; ch++) {
+ FIXP_DBL *RESTRICT pRealDry = self->hybOutputRealDry__FDK[ch];
+ FIXP_DBL *RESTRICT pImagDry = self->hybOutputImagDry__FDK[ch];
+ FIXP_DBL *RESTRICT pRealWet = self->hybOutputRealWet__FDK[ch];
+ FIXP_DBL *RESTRICT pImagWet = self->hybOutputImagWet__FDK[ch];
+ for (hyb = 0; hyb < nHybBands; hyb++) {
+ pRealDry[hyb] += pRealWet[hyb];
+ pImagDry[hyb] += pImagWet[hyb];
+ } /* loop hyb */
+ for (; hyb < self->hybridBands; hyb++) {
+ pRealDry[hyb] += pRealWet[hyb];
+ } /* loop hyb */
+ } /* loop ch */
+ } /* ( self->tempShapeConfig == 1 ) || ( self->tempShapeConfig == 2 ) */
+ } /* !self->tempShapeConfig == 1 */
+ } /* !bypassMode */
+
+ if (self->phaseCoding == 1) {
+ /* only if bsPhaseCoding == 1 and bsResidualCoding == 0 */
+
+ SpatialDecApplyPhase(
+ self, alpha, (ts == currSlot) /* signal the last slot of the set */
+ );
+ }
+
+ /*
+ * Synthesis Filtering
+ */
+
+ err = SpatialDecSynthesis(
+ self, ts_io,
+ self->hybOutputRealDry__FDK, /* input: hybOutput(Real/Imag)Dry */
+ self->hybOutputImagDry__FDK, self->timeOut__FDK, /* output: timeOut */
+ numInputChannels, mapDescr);
+
+ if (err != MPS_OK) goto bail;
+
+ /*
+ * Update parameter buffer
+ */
+ if (ts == currSlot) {
+ SpatialDecBufferMatrices(self); /* input: M(1/2)param(Real/Imag) */
+ /* output: M(1/2)param(Real/Imag)Prev */
+
+ prevSlot = currSlot;
+ ps++;
+ } /* if (ts==currSlot) */
+
+ } /* ts loop */
+
+ /*
+ * Save parameter states
+ */
+ self->prevTimeSlot = prevSlot;
+ self->curTimeSlot = ts;
+ self->curPs = ps;
+
+bail:
+
+ return err;
+}
+
+SACDEC_ERROR SpatialDecApplyFrame(
+ spatialDec *self,
+ SPATIAL_BS_FRAME *frame, /* parsed frame data to be applied */
+ SPATIALDEC_INPUT_MODE inputMode, PCM_MPS *inData, /* Time domain input */
+ FIXP_DBL **qmfInDataReal, /* QMF domain data l/r */
+ FIXP_DBL **qmfInDataImag, /* QMF domain data l/r */
+ PCM_MPS *pcmOutBuf, /* MAX_OUTPUT_CHANNELS*MAX_TIME_SLOTS*NUM_QMF_BANDS] */
+ UINT nSamples, UINT *pControlFlags, int numInputChannels,
+ const FDK_channelMapDescr *const mapDescr) {
+ SACDEC_ERROR err = MPS_OK;
+
+ int fDecAndMapFrameData;
+ int controlFlags;
+
+ FDK_ASSERT(self != NULL);
+ FDK_ASSERT(pControlFlags != NULL);
+ FDK_ASSERT(pcmOutBuf != NULL);
+
+ self->errInt = err; /* Init internal error */
+
+ controlFlags = *pControlFlags;
+
+ if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC) &&
+ (self->stereoConfigIndex > 1)) {
+ numInputChannels =
+ 1; /* Do not count residual channel as input channel. It is handled
+ seperately. */
+ }
+
+ /* Check if input amount of channels is consistent */
+ if (numInputChannels != self->numInputChannels) {
+ controlFlags |= MPEGS_CONCEAL;
+ if (numInputChannels > self->createParams.maxNumInputChannels) {
+ return MPS_INVALID_PARAMETER;
+ }
+ }
+
+ self->timeOut__FDK = pcmOutBuf;
+
+ /* Determine local function control flags */
+ fDecAndMapFrameData = frame->newBsData;
+
+ if (((fDecAndMapFrameData ==
+ 0) /* assures that conceal flag will not be set for blind mode */
+ && (self->curTimeSlot + (int)nSamples / self->qmfBands >
+ self->timeSlots)) ||
+ (frame->numParameterSets ==
+ 0)) { /* New input samples but missing side info */
+ fDecAndMapFrameData = 1;
+ controlFlags |= MPEGS_CONCEAL;
+ }
+
+ if ((fDecAndMapFrameData == 0) &&
+ (frame->paramSlot[fMax(0, frame->numParameterSets - 1)] !=
+ (self->timeSlots - 1) ||
+ self->curTimeSlot >
+ frame->paramSlot[self->curPs])) { /* Detected faulty parameter slot
+ data. */
+ fDecAndMapFrameData = 1;
+ controlFlags |= MPEGS_CONCEAL;
+ }
+
+ /* Update concealment state machine */
+ SpatialDecConcealment_UpdateState(
+ &self->concealInfo,
+ (controlFlags & MPEGS_CONCEAL)
+ ? 0
+ : 1); /* convert from conceal flag to frame ok flag */
+
+ if (fDecAndMapFrameData) {
+ /* Reset spatial framing control vars */
+ frame->newBsData = 0;
+ self->prevTimeSlot = -1;
+ self->curTimeSlot = 0;
+ self->curPs = 0;
+
+ if (controlFlags & MPEGS_CONCEAL) {
+ /* Reset frame data to avoid misconfiguration. */
+ SpatialDecClearFrameData(self, frame, &self->createParams);
+ }
+
+ {
+ err = SpatialDecDecodeFrame(self, frame); /* input: ... */
+ /* output: decodeAndMapFrameDATA */
+ }
+
+ if (err != MPS_OK) {
+ /* Rescue strategy is to apply bypass mode in order
+ to keep at least the downmix channels continuous. */
+ controlFlags |= MPEGS_CONCEAL;
+ if (self->errInt == MPS_OK) {
+ /* store internal error befor it gets overwritten */
+ self->errInt = err;
+ }
+ }
+ }
+
+ err = SpatialDecApplyParameterSets(
+ self, frame, inputMode, inData, qmfInDataReal, qmfInDataImag, nSamples,
+ controlFlags | ((err == MPS_OK) ? 0 : MPEGS_BYPASSMODE), numInputChannels,
+ mapDescr);
+ if (err != MPS_OK) {
+ goto bail;
+ }
+
+bail:
+
+ *pControlFlags = controlFlags;
+
+ return err;
+}
diff --git a/fdk-aac/libSACdec/src/sac_dec.h b/fdk-aac/libSACdec/src/sac_dec.h
new file mode 100644
index 0000000..992acad
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_dec.h
@@ -0,0 +1,539 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Decoder Library structures
+
+*******************************************************************************/
+
+#ifndef SAC_DEC_H
+#define SAC_DEC_H
+
+#include "common_fix.h"
+
+#include "sac_dec_interface.h" /* library interface in ../include */
+
+#include "FDK_qmf_domain.h"
+#include "sac_qmf.h"
+#include "FDK_bitstream.h" /* mp4 bitbuffer */
+#include "sac_calcM1andM2.h"
+#include "FDK_hybrid.h"
+#include "FDK_decorrelate.h"
+#include "sac_reshapeBBEnv.h"
+
+#include "sac_dec_conceal.h"
+
+#include "sac_tsd.h"
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define ICCdefault 0
+#define IPDdefault 0
+#define arbdmxGainDefault 0
+#define CPCdefault 10
+#define tttCLD1default 15
+#define tttCLD2default 0
+
+#define IS_HQ_ONLY(aot) \
+ ((aot) == AOT_ER_AAC_LD || (aot) == AOT_ER_AAC_ELD || (aot) == AOT_USAC || \
+ (aot) == AOT_RSVD50)
+
+#define SCONST(x) FL2FXCONST_DBL(x)
+
+#define PC_NUM_BANDS (8)
+#define PC_NUM_HYB_BANDS (PC_NUM_BANDS - 3 + 10)
+#define ABS_THR (1e-9f * 32768 * 32768)
+
+#define MAX_HYBRID_BANDS (MAX_NUM_QMF_BANDS - 3 + 10)
+#define HYBRID_FILTER_DELAY (6)
+
+#define MAX_RESIDUAL_FRAMES (4)
+#define MAX_RESIDUAL_BISTREAM \
+ (836) /* 48000 bps * 3 res / (8 * 44100 / 2048 ) */
+#define MAX_MDCT_COEFFS (1024)
+#define SACDEC_RESIDUAL_BS_BUF_SIZE \
+ (1024) /* used to setup and check residual bitstream buffer */
+
+#define MAX_NUM_PARAMS (MAX_NUM_OTT + 4 * MAX_NUM_TTT + MAX_INPUT_CHANNELS)
+#define MAX_NUM_PARAMETERS (MAX(MAX_NUM_PARAMS, MAX_NUM_OTT))
+
+#define MAX_PARAMETER_SETS (9)
+
+#define MAX_M2_INPUT (MAX_OUTPUT_CHANNELS) /* 3 direct + 5 diffuse */
+
+#define MAX_QMF_BANDS_TO_HYBRID \
+ (3) /* 3 bands are filtered again in "40 bands" case */
+#define PROTO_LEN (13)
+#define BUFFER_LEN_LF (PROTO_LEN)
+#define BUFFER_LEN_HF ((PROTO_LEN - 1) / 2)
+
+#define MAX_NO_DECORR_CHANNELS (MAX_OUTPUT_CHANNELS)
+#define HRTF_AZIMUTHS (5)
+
+#define MAX_NUM_OTT_AT 0
+
+/* left out */
+
+typedef enum {
+ UPMIXTYPE_BYPASS = -1, /*just bypass the input channels without processing*/
+ UPMIXTYPE_NORMAL = 0 /*multichannel loudspeaker upmix with spatial data*/
+} UPMIXTYPE;
+
+static inline int isTwoChMode(UPMIXTYPE upmixType) {
+ int retval = 0;
+ return retval;
+}
+
+ /* left out end */
+
+#define MPEGS_BYPASSMODE (0x00000001)
+#define MPEGS_CONCEAL (0x00000002)
+
+typedef struct STP_DEC *HANDLE_STP_DEC;
+
+typedef struct {
+ SCHAR bsQuantCoarseXXXprev;
+ SCHAR bsQuantCoarseXXXprevParse;
+} LOSSLESSSTATE;
+
+typedef struct {
+ SCHAR bsXXXDataMode[MAX_PARAMETER_SETS];
+ SCHAR bsQuantCoarseXXX[MAX_PARAMETER_SETS];
+ SCHAR bsFreqResStrideXXX[MAX_PARAMETER_SETS];
+ SCHAR nocmpQuantCoarseXXX[MAX_PARAMETER_SETS];
+ LOSSLESSSTATE *state; /* Link to persistent state information */
+} LOSSLESSDATA;
+
+struct SPATIAL_BS_FRAME_struct {
+ UCHAR bsIndependencyFlag;
+ UCHAR newBsData;
+ UCHAR numParameterSets;
+
+ /*
+ If bsFramingType == 0, then the paramSlot[ps] for 0 <= ps < numParamSets is
+ calculated as follows: paramSlot[ps] = ceil(numSlots*(ps+1)/numParamSets) - 1
+ Otherwise, it is
+ paramSlot[ps] = bsParamSlot[ps]
+ */
+ INT paramSlot[MAX_PARAMETER_SETS];
+
+ /* These arrays contain the compact indices, only one value per pbstride, only
+ * paramsets actually containing data. */
+ /* These values are written from the parser in ecDataDec() and read during
+ * decode in mapIndexData() */
+ SCHAR cmpOttCLDidx[MAX_NUM_OTT + MAX_NUM_OTT_AT][MAX_PARAMETER_SETS]
+ [MAX_PARAMETER_BANDS];
+ SCHAR cmpOttICCidx[MAX_NUM_OTT][MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS];
+
+ /* Smoothing */
+ UCHAR bsSmoothMode[MAX_PARAMETER_SETS];
+ UCHAR bsSmoothTime[MAX_PARAMETER_SETS];
+ UCHAR bsFreqResStrideSmg[MAX_PARAMETER_SETS];
+ UCHAR bsSmgData[MAX_PARAMETER_SETS]
+ [MAX_PARAMETER_BANDS]; /* smoothing flags, one if band is
+ smoothed, otherwise zero */
+
+ /* Arbitrary Downmix */
+ SCHAR (*cmpArbdmxGainIdx)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS];
+
+ /* Lossless control */
+ LOSSLESSDATA *CLDLosslessData;
+ LOSSLESSDATA *ICCLosslessData;
+ /* LOSSLESSDATA *ADGLosslessData; -> is stored in CLDLosslessData[offset] */
+
+ LOSSLESSDATA *IPDLosslessData;
+ SCHAR (*cmpOttIPDidx)[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS];
+ int phaseMode;
+ int OpdSmoothingMode;
+
+ UCHAR tempShapeEnableChannelGES[MAX_OUTPUT_CHANNELS]; /*!< GES side info. */
+ UCHAR bsEnvShapeData[MAX_OUTPUT_CHANNELS]
+ [MAX_TIME_SLOTS]; /*!< GES side info (quantized). */
+
+ UCHAR tempShapeEnableChannelSTP[MAX_OUTPUT_CHANNELS]; /*!< STP side info. */
+
+ TSD_DATA TsdData[1]; /*!< TSD data structure. */
+};
+
+typedef struct {
+ /* Lossless state */
+ LOSSLESSSTATE CLDLosslessState[MAX_NUM_PARAMETERS];
+ LOSSLESSSTATE ICCLosslessState[MAX_NUM_PARAMETERS];
+ LOSSLESSSTATE IPDLosslessState[MAX_NUM_PARAMETERS];
+} BS_LL_STATE;
+
+typedef struct {
+ int prevParamSlot;
+ int prevSmgTime;
+ UCHAR prevSmgData[MAX_PARAMETER_BANDS];
+
+ FIXP_DBL opdLeftState__FDK[MAX_PARAMETER_BANDS];
+ FIXP_DBL opdRightState__FDK[MAX_PARAMETER_BANDS];
+
+} SMOOTHING_STATE;
+
+typedef struct {
+ FIXP_DBL alpha__FDK;
+ FIXP_DBL beta__FDK;
+ FIXP_DBL partNrgPrev__FDK[2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS]
+ [BB_ENV_SIZE];
+ FIXP_DBL normNrgPrev__FDK[2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS];
+ FIXP_DBL frameNrgPrev__FDK[2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS];
+ INT partNrgPrevSF[2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS];
+ INT partNrgPrev2SF[2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS];
+ INT normNrgPrevSF[2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS];
+ INT frameNrgPrevSF[2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS];
+} RESHAPE_BBENV_STATE;
+
+typedef struct {
+ int maxNumInputChannels;
+ int maxNumOutputChannels;
+ int maxNumQmfBands;
+ int maxNumHybridBands;
+ int maxNumXChannels;
+ int maxNumVChannels;
+ int maxNumDecorChannels;
+ int maxNumCmplxQmfBands;
+ int maxNumCmplxHybBands;
+ int maxNumResChannels;
+ int bProcResidual; /* process residual */
+ int maxNumResidualChannels;
+ int maxNumOttBoxes;
+ int maxNumParams;
+
+} SACDEC_CREATION_PARAMS;
+
+struct spatialDec_struct {
+ SACDEC_ERROR
+ errInt; /* Field to store internal errors.
+ Will be clear at the very beginning of each process call. */
+ int staticDecScale; /* static scale of decoder */
+
+ /* GENERAL */
+ int samplingFreq; /* [Hz] */
+ CFG_LEVEL decoderLevel; /* 0..5 */
+ CFG_EXTENT decoderMode;
+ CFG_BINAURAL binauralMode;
+
+ SACDEC_CREATION_PARAMS createParams;
+
+ int numComplexProcessingBands;
+
+ int treeConfig; /* TREE_5151 = 5151, TREE_5152 = 5152, TREE_525 = 525, defined
+ in sac_bitdec.h */
+
+ int numInputChannels; /* 1 (M) or 2 (L,R) */
+ int numOutputChannels; /* 6 for 3/2.1 (FL,FR,FC,LF,BL,BR) */
+ int numOttBoxes; /* number of ott boxes */
+ int numM2rows;
+
+ int numOutputChannelsAT; /* Number of output channels after arbitrary tree
+ processing */
+
+ int quantMode; /* QUANT_FINE, QUANT_EBQ1, QUANT_EBQ2, defined in sac_bitdec.h
+ */
+ int arbitraryDownmix; /* (arbitraryDownmix != 0) 1 arbitrary downmix data
+ present, 2 arbitrary downmix residual data present*/
+ int residualCoding; /* (residualCoding != 0) => residual coding data present
+ */
+ UCHAR nrResidualFrame;
+ UCHAR nrArbDownmixResidualFrame;
+ FDK_BITSTREAM **hResidualBitstreams;
+ int tempShapeConfig; /* */
+ int decorrType; /* Indicates to use PS or none PS decorrelator. */
+ int decorrConfig; /* chosen decorrelator */
+ int envQuantMode; /* quantization mode of envelope reshaping data */
+
+ FIXP_DBL clipProtectGain__FDK; /* global gain for upmix */
+ char clipProtectGainSF__FDK; /* global gain for upmix */
+
+ /* Currently ignoring center decorr
+ numVChannels = numDirektSignals + numDecorSignals */
+ int numDirektSignals; /* needed for W, Number of direkt signals 515 -> 1 525
+ -> 3 */
+ int wStartResidualIdx; /* Where to start read residuals for W, = 0 for 515, =
+ 1 for 525 since one residual is used in V */
+ int numDecorSignals; /* needed for W, Number of residual and decorrelated
+ signals, = 2, 3 for center deccorelation*/
+ int numVChannels; /* direct signals + decorelator signals */
+ int numXChannels; /* direct input signals + TTT-residuals */
+
+ int timeSlots; /* length of spatial frame in QMF samples */
+ int curTimeSlot; /* pointer to the current time slot used for hyperframing */
+ int prevTimeSlot; /* */
+ int curPs;
+ int frameLength; /* number of output waveform samples/channel/frame */
+ UPMIXTYPE upmixType;
+ int partiallyComplex;
+ int useFDreverb;
+
+ int bShareDelayWithSBR;
+
+ int tp_hybBandBorder; /* Hybrid band indicating the HP filter cut-off. */
+
+ /* FREQUENCY MAPPING */
+ int qmfBands;
+ int hybridBands;
+ const SCHAR *kernels; /* Mapping hybrid band to parameter band. */
+
+ int TsdTs; /**< TSD QMF slot counter 0<= ts < numSlots */
+
+ int *param2hyb; /* Mapping parameter bands to hybrid bands */
+ int kernels_width[MAX_PARAMETER_BANDS]; /* Mapping parmeter band to hybrid
+ band offsets. */
+
+ /* Residual coding */
+ int residualSamplingFreq;
+ UCHAR residualPresent[MAX_NUM_OTT + MAX_NUM_TTT];
+ UCHAR residualBands[MAX_NUM_OTT + MAX_NUM_TTT]; /* 0, if no residual data
+ present for this box */
+ UCHAR residualQMFBands[MAX_NUM_OTT + MAX_NUM_TTT]; /* needed for optimized
+ mdct2qmf calculation */
+ SPATIAL_SPECIFIC_CONFIG *pConfigCurrent;
+
+ int arbdmxFramesPerSpatialFrame;
+ int arbdmxUpdQMF;
+
+ int numParameterBands; /* Number of parameter bands 40, 28, 20, 14, 10, ...
+ .*/
+ int bitstreamParameterBands;
+ int *numOttBands; /* number of bands for each ott, is != numParameterBands for
+ LFEs */
+
+ /* 1 MAPPING */
+ UCHAR extendFrame;
+ UCHAR numParameterSetsPrev;
+
+ int *smgTime;
+ UCHAR **smgData;
+
+ /* PARAMETER DATA decoded and dequantized */
+
+ /* Last parameters from prev frame required during decode in mapIndexData()
+ * and not touched during parse */
+ SCHAR **ottCLDidxPrev;
+ SCHAR **ottICCidxPrev;
+ SCHAR **arbdmxGainIdxPrev;
+ SCHAR **ottIPDidxPrev;
+ SCHAR ***outIdxData; /* is this really persistent memory ? */
+
+ /* State mem required during parse in SpatialDecParseFrameData() */
+ SCHAR **cmpOttCLDidxPrev;
+ SCHAR **cmpOttICCidxPrev;
+ SCHAR ***ottICCdiffidx;
+ SCHAR **cmpOttIPDidxPrev;
+
+ /* State mem required in parseArbitraryDownmixData */
+ SCHAR **cmpArbdmxGainIdxPrev;
+
+ SCHAR ***ottCLD__FDK;
+ SCHAR ***ottICC__FDK;
+
+ SCHAR ***arbdmxGain__FDK; /* Holds the artistic downmix correction index.*/
+
+ FIXP_DBL *arbdmxAlpha__FDK;
+ FIXP_DBL *arbdmxAlphaPrev__FDK;
+
+ UCHAR stereoConfigIndex;
+ int highRateMode;
+
+ int phaseCoding;
+
+ SCHAR ***ottIPD__FDK;
+
+ FIXP_DBL PhaseLeft__FDK[MAX_PARAMETER_BANDS];
+ FIXP_DBL PhaseRight__FDK[MAX_PARAMETER_BANDS];
+ FIXP_DBL PhasePrevLeft__FDK[MAX_PARAMETER_BANDS];
+ FIXP_DBL PhasePrevRight__FDK[MAX_PARAMETER_BANDS];
+ int numOttBandsIPD;
+
+ /* GAIN MATRICIES FOR CURRENT and PREVIOUS PARMATER SET(s)*/
+ FIXP_DBL ***M2Real__FDK;
+ FIXP_DBL ***M2Imag__FDK;
+ FIXP_DBL ***M2RealPrev__FDK;
+ FIXP_DBL ***M2ImagPrev__FDK;
+
+ /* INPUT SIGNALS */
+ FIXP_DBL ***qmfInputRealDelayBuffer__FDK;
+ FIXP_DBL ***qmfInputImagDelayBuffer__FDK;
+
+ int pc_filterdelay; /* additional delay to align HQ with LP before hybird
+ analysis */
+ int qmfInputDelayBufPos;
+ FIXP_DBL **qmfInputReal__FDK;
+ FIXP_DBL **qmfInputImag__FDK;
+
+ FIXP_DBL **hybInputReal__FDK;
+ FIXP_DBL **hybInputImag__FDK;
+
+ FIXP_DBL **binInputReverb;
+
+ FIXP_DBL binGain, reverbGain;
+ FIXP_DBL binCenterGain, reverbCenterGain;
+
+ /* RESIDUAL SIGNALS */
+
+ FIXP_DBL ***qmfResidualReal__FDK;
+ FIXP_DBL ***qmfResidualImag__FDK;
+
+ FIXP_DBL **hybResidualReal__FDK;
+ FIXP_DBL **hybResidualImag__FDK;
+
+ int qmfOutputRealDryDelayBufPos;
+ FIXP_DBL ***qmfOutputRealDryDelayBuffer__FDK;
+ FIXP_DBL ***qmfOutputImagDryFilterBuffer__FDK;
+ FIXP_DBL *qmfOutputImagDryFilterBufferBase__FDK;
+
+ /* TEMPORARY SIGNALS */
+
+ FIXP_DBL **wReal__FDK;
+ FIXP_DBL **wImag__FDK;
+
+ /* OUTPUT SIGNALS */
+ FIXP_DBL **hybOutputRealDry__FDK;
+ FIXP_DBL **hybOutputImagDry__FDK;
+ FIXP_DBL **hybOutputRealWet__FDK;
+ FIXP_DBL **hybOutputImagWet__FDK;
+ PCM_MPS *timeOut__FDK;
+
+ HANDLE_FDK_QMF_DOMAIN pQmfDomain;
+
+ FDK_ANA_HYB_FILTER
+ *hybridAnalysis; /*!< pointer Analysis hybrid filterbank array. */
+ FDK_SYN_HYB_FILTER
+ *hybridSynthesis; /*!< pointer Synthesis hybrid filterbank array. */
+ FIXP_DBL **
+ pHybridAnaStatesLFdmx; /*!< pointer to analysis hybrid filter states LF */
+ FIXP_DBL **
+ pHybridAnaStatesHFdmx; /*!< pointer to analysis hybrid filter states HF */
+ FIXP_DBL **
+ pHybridAnaStatesLFres; /*!< pointer to analysis hybrid filter states LF */
+ FIXP_DBL **
+ pHybridAnaStatesHFres; /*!< pointer to analysis hybrid filter states HF */
+
+ DECORR_DEC *apDecor; /*!< pointer decorrelator array. */
+ FIXP_DBL **pDecorBufferCplx;
+
+ SMOOTHING_STATE *smoothState; /*!< Pointer to smoothing states. */
+
+ RESHAPE_BBENV_STATE *reshapeBBEnvState; /*!< GES handle. */
+ SCHAR row2channelDmxGES[MAX_OUTPUT_CHANNELS];
+
+ HANDLE_STP_DEC hStpDec; /*!< STP handle. */
+
+ const UCHAR *pActivM2ParamBands;
+
+ int bOverwriteM1M2prev; /* Overwrite previous M2/M2 params with first set of
+ new frame after SSC change (aka
+ decodeAfterConfigHasChangedFlag). */
+ SpatialDecConcealmentInfo concealInfo;
+};
+
+#define SACDEC_SYNTAX_MPS 1
+#define SACDEC_SYNTAX_USAC 2
+#define SACDEC_SYNTAX_RSVD50 4
+#define SACDEC_SYNTAX_L2 8
+#define SACDEC_SYNTAX_L3 16
+#define SACDEC_SYNTAX_LD 32
+
+static inline int GetProcBand(spatialDec_struct *self, int qs) {
+ return self->kernels[qs];
+}
+
+#endif /* SAC_DEC_H */
diff --git a/fdk-aac/libSACdec/src/sac_dec_conceal.cpp b/fdk-aac/libSACdec/src/sac_dec_conceal.cpp
new file mode 100644
index 0000000..dfeef7b
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_dec_conceal.cpp
@@ -0,0 +1,392 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s): Christian Ertel, Christian Griebel
+
+ Description: SAC Dec error concealment
+
+*******************************************************************************/
+
+#include "sac_dec_conceal.h"
+
+void SpatialDecConcealment_Init(SpatialDecConcealmentInfo *info,
+ const UINT resetFlags) {
+ FDK_ASSERT(info != NULL);
+
+ if (resetFlags & MPEGS_CONCEAL_RESET_STATE) {
+ info->concealState = SpatialDecConcealState_Init;
+ /* Frame counters will be initialized implicitely in function
+ * SpatialDecConcealment_UpdateState(). */
+ }
+
+ if (resetFlags & MPEGS_CONCEAL_RESET_PARAMETER) {
+ /* Set default params */
+ info->concealParams.method = MPEGS_CONCEAL_DEFAULT_METHOD;
+ info->concealParams.numKeepFrames = MPEGS_CONCEAL_DEFAULT_NUM_KEEP_FRAMES;
+ info->concealParams.numFadeOutFrames =
+ MPEGS_CONCEAL_DEFAULT_FADE_OUT_SLOPE_LENGTH;
+ info->concealParams.numFadeInFrames =
+ MPEGS_CONCEAL_DEFAULT_FADE_IN_SLOPE_LENGTH;
+ info->concealParams.numReleaseFrames =
+ MPEGS_CONCEAL_DEFAULT_NUM_RELEASE_FRAMES;
+ }
+
+ return;
+}
+
+int SpatialDecConcealment_Apply(
+ SpatialDecConcealmentInfo *info,
+ const SCHAR (*cmpIdxData)[MAX_PARAMETER_BANDS], SCHAR **diffIdxData,
+ SCHAR *
+ idxPrev, /* char
+ idxPrev[SPATIALDEC_MAX_NUM_OTT][SPATIALDEC_MAX_PARAMETER_BANDS],
+ */
+ SCHAR *bsXXXDataMode, const int startBand, const int stopBand,
+ const SCHAR defaultValue, const int paramType, const int numParamSets) {
+ int appliedProcessing = 0;
+ int band, dataMode = -1;
+
+ FDK_ASSERT(info != NULL);
+ FDK_ASSERT(cmpIdxData != NULL);
+ FDK_ASSERT(idxPrev != NULL);
+ FDK_ASSERT(bsXXXDataMode != NULL);
+
+ /* Processing depends only on the internal state */
+ switch (info->concealState) {
+ case SpatialDecConcealState_Init:
+ dataMode = 0; /* default */
+ break;
+
+ case SpatialDecConcealState_Ok:
+ /* Nothing to do */
+ break;
+
+ case SpatialDecConcealState_Keep:
+ dataMode = 1; /* keep */
+ break;
+
+ case SpatialDecConcealState_FadeToDefault: {
+ /* Start simple fade out */
+ FIXP_DBL fac = fDivNorm(info->cntStateFrames + 1,
+ info->concealParams.numFadeOutFrames + 1);
+
+ for (band = startBand; band < stopBand; band += 1) {
+ /* idxPrev = fac * defaultValue + (1-fac) * idxPrev; */
+ idxPrev[band] =
+ fMultI(fac, defaultValue - idxPrev[band]) + idxPrev[band];
+ }
+ dataMode = 1; /* keep */
+ appliedProcessing = 1;
+ } break;
+
+ case SpatialDecConcealState_Default:
+ for (band = startBand; band < stopBand; band += 1) {
+ idxPrev[band] = defaultValue;
+ }
+ dataMode = 1; /* keep */
+ appliedProcessing = 1;
+ break;
+
+ case SpatialDecConcealState_FadeFromDefault: {
+ FIXP_DBL fac = fDivNorm(info->cntValidFrames + 1,
+ info->concealParams.numFadeInFrames + 1);
+
+ for (band = startBand; band < stopBand; band += 1) {
+ /* idxPrev = fac * cmpIdxData + (1-fac) * defaultValue; */
+ idxPrev[band] =
+ fMultI(fac, cmpIdxData[numParamSets - 1][band] - defaultValue) +
+ defaultValue;
+ }
+ dataMode = 1; /* keep */
+ appliedProcessing = 1;
+ } break;
+
+ default:
+ FDK_ASSERT(0); /* All valid states shall be handled above. */
+ break;
+ }
+
+ if (dataMode >= 0) {
+ int i;
+ for (i = 0; i < numParamSets; i += 1) {
+ bsXXXDataMode[i] = dataMode;
+ if (diffIdxData != NULL) {
+ for (band = startBand; band < stopBand; band += 1) {
+ diffIdxData[i][band] = 0;
+ }
+ }
+ }
+ }
+
+ return appliedProcessing;
+}
+
+void SpatialDecConcealment_UpdateState(SpatialDecConcealmentInfo *info,
+ const int frameOk) {
+ FDK_ASSERT(info != NULL);
+
+ if (frameOk) {
+ info->cntValidFrames += 1;
+ } else {
+ info->cntValidFrames = 0;
+ }
+
+ switch (info->concealState) {
+ case SpatialDecConcealState_Init:
+ if (frameOk) {
+ /* NEXT STATE: Ok */
+ info->concealState = SpatialDecConcealState_Ok;
+ info->cntStateFrames = 0;
+ }
+ break;
+
+ case SpatialDecConcealState_Ok:
+ if (!frameOk) {
+ /* NEXT STATE: Keep */
+ info->concealState = SpatialDecConcealState_Keep;
+ info->cntStateFrames = 0;
+ }
+ break;
+
+ case SpatialDecConcealState_Keep:
+ info->cntStateFrames += 1;
+ if (frameOk) {
+ /* NEXT STATE: Ok */
+ info->concealState = SpatialDecConcealState_Ok;
+ } else {
+ if (info->cntStateFrames >= info->concealParams.numKeepFrames) {
+ if (info->concealParams.numFadeOutFrames == 0) {
+ /* NEXT STATE: Default */
+ info->concealState = SpatialDecConcealState_Default;
+ } else {
+ /* NEXT STATE: Fade to default */
+ info->concealState = SpatialDecConcealState_FadeToDefault;
+ info->cntStateFrames = 0;
+ }
+ }
+ }
+ break;
+
+ case SpatialDecConcealState_FadeToDefault:
+ info->cntStateFrames += 1;
+ if (info->cntValidFrames > 0) {
+ /* NEXT STATE: Fade in from default */
+ info->concealState = SpatialDecConcealState_FadeFromDefault;
+ info->cntStateFrames = 0;
+ } else {
+ if (info->cntStateFrames >= info->concealParams.numFadeOutFrames) {
+ /* NEXT STATE: Default */
+ info->concealState = SpatialDecConcealState_Default;
+ }
+ }
+ break;
+
+ case SpatialDecConcealState_Default:
+ if (info->cntValidFrames > 0) {
+ if (info->concealParams.numFadeInFrames == 0) {
+ /* NEXT STATE: Ok */
+ info->concealState = SpatialDecConcealState_Ok;
+ } else {
+ /* NEXT STATE: Fade in from default */
+ info->concealState = SpatialDecConcealState_FadeFromDefault;
+ info->cntValidFrames = 0;
+ }
+ }
+ break;
+
+ case SpatialDecConcealState_FadeFromDefault:
+ info->cntValidFrames += 1;
+ if (frameOk) {
+ if (info->cntValidFrames >= info->concealParams.numFadeInFrames) {
+ /* NEXT STATE: Ok */
+ info->concealState = SpatialDecConcealState_Ok;
+ }
+ } else {
+ /* NEXT STATE: Fade to default */
+ info->concealState = SpatialDecConcealState_FadeToDefault;
+ info->cntStateFrames = 0;
+ }
+ break;
+
+ default:
+ FDK_ASSERT(0); /* All valid states should be handled above! */
+ break;
+ }
+}
+
+SACDEC_ERROR SpatialDecConcealment_SetParam(SpatialDecConcealmentInfo *self,
+ const SAC_DEC_CONCEAL_PARAM param,
+ const INT value) {
+ SACDEC_ERROR err = MPS_OK;
+
+ switch (param) {
+ case SAC_DEC_CONCEAL_METHOD:
+ switch ((SpatialDecConcealmentMethod)value) {
+ case SAC_DEC_CONCEAL_WITH_ZERO_VALUED_OUTPUT:
+ case SAC_DEC_CONCEAL_BY_FADING_PARAMETERS:
+ break;
+ default:
+ err = MPS_INVALID_PARAMETER;
+ goto bail;
+ }
+ if (self != NULL) {
+ /* store parameter value */
+ self->concealParams.method = (SpatialDecConcealmentMethod)value;
+ } else {
+ err = MPS_INVALID_HANDLE;
+ goto bail;
+ }
+ break;
+ case SAC_DEC_CONCEAL_NUM_KEEP_FRAMES:
+ if (value < 0) {
+ err = MPS_INVALID_PARAMETER;
+ goto bail;
+ }
+ if (self != NULL) {
+ /* store parameter value */
+ self->concealParams.numKeepFrames = (UINT)value;
+ } else {
+ err = MPS_INVALID_HANDLE;
+ goto bail;
+ }
+ break;
+ case SAC_DEC_CONCEAL_FADE_OUT_SLOPE_LENGTH:
+ if (value < 0) {
+ err = MPS_INVALID_PARAMETER;
+ goto bail;
+ }
+ if (self != NULL) {
+ /* store parameter value */
+ self->concealParams.numFadeOutFrames = (UINT)value;
+ } else {
+ err = MPS_INVALID_HANDLE;
+ goto bail;
+ }
+ break;
+ case SAC_DEC_CONCEAL_FADE_IN_SLOPE_LENGTH:
+ if (value < 0) {
+ err = MPS_INVALID_PARAMETER;
+ goto bail;
+ }
+ if (self != NULL) {
+ /* store parameter value */
+ self->concealParams.numFadeInFrames = (UINT)value;
+ } else {
+ err = MPS_INVALID_HANDLE;
+ goto bail;
+ }
+ break;
+ case SAC_DEC_CONCEAL_NUM_RELEASE_FRAMES:
+ if (value < 0) {
+ err = MPS_INVALID_PARAMETER;
+ goto bail;
+ }
+ if (self != NULL) {
+ /* store parameter value */
+ self->concealParams.numReleaseFrames = (UINT)value;
+ } else {
+ err = MPS_INVALID_HANDLE;
+ goto bail;
+ }
+ break;
+ default:
+ err = MPS_INVALID_PARAMETER;
+ goto bail;
+ }
+
+bail:
+ return err;
+}
diff --git a/fdk-aac/libSACdec/src/sac_dec_conceal.h b/fdk-aac/libSACdec/src/sac_dec_conceal.h
new file mode 100644
index 0000000..27f5249
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_dec_conceal.h
@@ -0,0 +1,187 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s): Christian Ertel, Christian Griebel
+
+ Description: SAC Dec error concealment
+
+*******************************************************************************/
+
+#ifndef SAC_DEC_CONCEAL_H
+#define SAC_DEC_CONCEAL_H
+
+#include "sac_dec_interface.h"
+
+/* Modules dynamic parameters: */
+typedef enum {
+ SAC_DEC_CONCEAL_METHOD = 0,
+ SAC_DEC_CONCEAL_NUM_KEEP_FRAMES,
+ SAC_DEC_CONCEAL_FADE_OUT_SLOPE_LENGTH,
+ SAC_DEC_CONCEAL_FADE_IN_SLOPE_LENGTH,
+ SAC_DEC_CONCEAL_NUM_RELEASE_FRAMES
+
+} SAC_DEC_CONCEAL_PARAM;
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* sac_dec_interface.h */
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - */
+typedef enum {
+ SAC_DEC_CONCEAL_WITH_ZERO_VALUED_OUTPUT = 0,
+ SAC_DEC_CONCEAL_BY_FADING_PARAMETERS = 1
+
+} SpatialDecConcealmentMethod;
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/* Default dynamic parameter values: */
+#define MPEGS_CONCEAL_DEFAULT_METHOD SAC_DEC_CONCEAL_BY_FADING_PARAMETERS
+#define MPEGS_CONCEAL_DEFAULT_NUM_KEEP_FRAMES (10)
+#define MPEGS_CONCEAL_DEFAULT_FADE_OUT_SLOPE_LENGTH (5)
+#define MPEGS_CONCEAL_DEFAULT_FADE_IN_SLOPE_LENGTH (5)
+#define MPEGS_CONCEAL_DEFAULT_NUM_RELEASE_FRAMES (3)
+
+typedef enum {
+ SpatialDecConcealState_Init = 0,
+ SpatialDecConcealState_Ok,
+ SpatialDecConcealState_Keep,
+ SpatialDecConcealState_FadeToDefault,
+ SpatialDecConcealState_Default,
+ SpatialDecConcealState_FadeFromDefault
+
+} SpatialDecConcealmentState;
+
+typedef struct {
+ SpatialDecConcealmentMethod method;
+
+ UINT numKeepFrames;
+ UINT numFadeOutFrames;
+ UINT numFadeInFrames;
+ UINT numReleaseFrames;
+
+} SpatialDecConcealmentParams;
+
+typedef struct {
+ SpatialDecConcealmentParams concealParams; /* User set params */
+ SpatialDecConcealmentState
+ concealState; /* State of internal state machine (fade-in/out etc) */
+
+ UINT cntStateFrames; /* Counter for fade-in/out handling */
+ UINT cntValidFrames; /* Counter for the number of consecutive good frames*/
+
+} SpatialDecConcealmentInfo;
+
+/* Module reset flags */
+#define MPEGS_CONCEAL_RESET_STATE (0x01)
+#define MPEGS_CONCEAL_RESET_PARAMETER (0x02)
+#define MPEGS_CONCEAL_RESET_ALL (0xFF)
+
+void SpatialDecConcealment_Init(SpatialDecConcealmentInfo *info,
+ const UINT resetFlags);
+
+int SpatialDecConcealment_Apply(SpatialDecConcealmentInfo *info,
+ const SCHAR (*cmpIdxData)[MAX_PARAMETER_BANDS],
+ SCHAR **diffIdxData, SCHAR *idxPrev,
+ SCHAR *bsXXXDataMode, const int startBand,
+ const int stopBand, const SCHAR defaultValue,
+ const int paramType, const int numParamSets);
+
+void SpatialDecConcealment_UpdateState(SpatialDecConcealmentInfo *info,
+ const int frameOk);
+
+SACDEC_ERROR SpatialDecConcealment_SetParam(SpatialDecConcealmentInfo *info,
+ const SAC_DEC_CONCEAL_PARAM param,
+ const INT value);
+
+#endif /* SAC_DEC_CONCEAL_H */
diff --git a/fdk-aac/libSACdec/src/sac_dec_interface.h b/fdk-aac/libSACdec/src/sac_dec_interface.h
new file mode 100644
index 0000000..a2eea92
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_dec_interface.h
@@ -0,0 +1,335 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Decoder Library Interface
+
+*******************************************************************************/
+
+#ifndef SAC_DEC_INTERFACE_H
+#define SAC_DEC_INTERFACE_H
+
+#include "common_fix.h"
+#include "FDK_audio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sac_dec_errorcodes.h"
+#include "sac_dec_ssc_struct.h"
+
+/**
+ * \brief Baseline MPEG-Surround profile Level 1-5.
+ */
+typedef enum {
+ DECODER_LEVEL_0 = 0, /*!< Level 0: dummy level; 212 only */
+ DECODER_LEVEL_6 = 6 /*!< Level 6: no support */
+} CFG_LEVEL;
+
+/*
+ * \brief Number of output channels restriction.
+ */
+typedef enum {
+ OUTPUT_CHANNELS_DEFAULT, /*!< Default configuration depending on Decoder Level
+ */
+ OUTPUT_CHANNELS_2_0, /*!< Limitation to stereo output */
+ OUTPUT_CHANNELS_5_1 /*!< Limitation to 5.1 output */
+} CFG_RESTRICTION;
+
+/*
+ * \brief Supported decoder mode.
+ */
+typedef enum {
+ EXT_HQ_ONLY = 0, /*!< High Quality processing only */
+ EXT_LP_ONLY = 1, /*!< Low Power procesing only */
+ EXT_HQ_AND_LP = 2 /*!< Support both HQ and LP processing */
+} CFG_EXTENT;
+
+/*
+ * \brief Supported binaural mode.
+ */
+typedef enum {
+ BINAURAL_NONE = -1 /*!< No binaural procesing supported */
+} CFG_BINAURAL;
+
+/**
+ * \brief Decoder configuration structure.
+ *
+ * These structure contains all parameters necessary for decoder open function.
+ * The configuration specifies the functional range of the decoder instance.
+ */
+typedef struct {
+ CFG_LEVEL decoderLevel;
+ CFG_EXTENT decoderMode;
+ CFG_RESTRICTION maxNumOutputChannels;
+ CFG_BINAURAL binauralMode;
+
+} SPATIAL_DEC_CONFIG;
+
+typedef enum {
+ INPUTMODE_QMF = 1000,
+ INPUTMODE_QMF_SBR = 1001,
+ INPUTMODE_TIME = 1002
+} SPATIALDEC_INPUT_MODE;
+
+/**
+ * \brief MPEG Surround upmix type mode.
+ **/
+typedef enum {
+ UPMIX_TYPE_BYPASS =
+ -1, /*!< Bypass the downmix channels from the core decoder. */
+ UPMIX_TYPE_NORMAL = 0 /*!< Multi channel output. */
+
+} SPATIAL_DEC_UPMIX_TYPE;
+
+/**
+ * \brief Dynamic decoder parameters.
+ */
+typedef struct {
+ /* Basics */
+ UCHAR outputMode;
+ UCHAR blindEnable;
+ UCHAR bypassMode;
+
+ /* Error concealment */
+ UCHAR concealMethod;
+ UINT concealNumKeepFrames;
+ UINT concealFadeOutSlopeLength;
+ UINT concealFadeInSlopeLength;
+ UINT concealNumReleaseFrames;
+
+} SPATIALDEC_PARAM;
+
+/**
+ * \brief Flags which control the initialization
+ **/
+typedef enum {
+ MPEGS_INIT_NONE = 0x00000000, /*!< Indicates no initialization */
+
+ MPEGS_INIT_CONFIG = 0x00000010, /*!< Indicates a configuration change due to
+ SSC value changes */
+
+ MPEGS_INIT_STATES_ANA_QMF_FILTER =
+ 0x00000100, /*!< Controls the initialization of the analysis qmf filter
+ states */
+ MPEGS_INIT_STATES_SYN_QMF_FILTER =
+ 0x00000200, /*!< Controls the initialization of the synthesis qmf filter
+ states */
+ MPEGS_INIT_STATES_ANA_HYB_FILTER = 0x00000400, /*!< Controls the
+ initialization of the
+ analysis hybrid filter
+ states */
+ MPEGS_INIT_STATES_DECORRELATOR =
+ 0x00000800, /*!< Controls the initialization of the decorrelator states */
+ MPEGS_INIT_STATES_M1M2 = 0x00002000, /*!< Controls the initialization of the
+ history in m1 and m2 parameter
+ calculation */
+ MPEGS_INIT_STATES_GES = 0x00004000, /*!< Controls the initialization of the
+ history in the ges calculation */
+ MPEGS_INIT_STATES_REVERB =
+ 0x00008000, /*!< Controls the initialization of the reverb states */
+ MPEGS_INIT_STATES_PARAM =
+ 0x00020000, /*!< Controls the initialization of the history of all other
+ parameter */
+ MPEGS_INIT_STATES_ERROR_CONCEALMENT =
+ 0x00080000, /*!< Controls the initialization of the error concealment
+ module state */
+ MPEGS_INIT_PARAMS_ERROR_CONCEALMENT = 0x00200000 /*!< Controls the
+ initialization of the
+ whole error concealment
+ parameter set */
+
+} MPEGS_INIT_CTRL_FLAGS;
+
+#define MASK_MPEGS_INIT_ALL_STATES (0x000FFF00)
+#define MASK_MPEGS_INIT_ALL_PARAMS (0x00F00000)
+
+typedef struct spatialDec_struct spatialDec, *HANDLE_SPATIAL_DEC;
+
+typedef struct SPATIAL_BS_FRAME_struct SPATIAL_BS_FRAME;
+
+typedef struct {
+ UINT sizePersistent; /* persistent memory */
+ UINT sizeFastPersistent; /* fast persistent memory */
+
+} MEM_REQUIREMENTS;
+
+#define PCM_MPS INT_PCM
+#define PCM_MPSF FIXP_PCM
+
+#define FIXP_DBL2PCM_MPS(x) ((INT_PCM)FX_DBL2FX_PCM(x))
+
+/* exposed functions (library interface) */
+
+int FDK_SpatialDecCompareSpatialSpecificConfigHeader(
+ SPATIAL_SPECIFIC_CONFIG *pSsc1, SPATIAL_SPECIFIC_CONFIG *pSsc2);
+
+int FDK_SpatialDecInitDefaultSpatialSpecificConfig(
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
+ AUDIO_OBJECT_TYPE coreCodec, int coreChannels, int samplingFreq,
+ int nTimeSlots, int decoderLevel, int isBlind);
+
+spatialDec *FDK_SpatialDecOpen(const SPATIAL_DEC_CONFIG *config,
+ int stereoConfigIndex);
+
+/**
+ * \brief Initialize state variables of the MPS parser
+ */
+void SpatialDecInitParserContext(spatialDec *self);
+
+/**
+ * \brief Initialize state of MPS decoder. This may happen after the first parse
+ * operation.
+ */
+SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
+ SPATIAL_SPECIFIC_CONFIG *pSpatialSpecificConfig,
+ int nQmfBands,
+ SPATIAL_DEC_UPMIX_TYPE const upmixType,
+ SPATIALDEC_PARAM *pUserParams,
+ UINT initFlags /* MPEGS_INIT_CTRL_FLAGS */
+);
+
+/**
+ * \brief Apply decoded MPEG Surround parameters to time domain or QMF down mix
+ * data.
+ * \param self spatial decoder handle.
+ * \param inData Pointer to time domain input down mix data if any.
+ * \param qmfInDataReal Pointer array of QMF domain down mix input data (real
+ * part).
+ * \param qmfInDataImag Pointer array of QMF domain down mix input data
+ * (imaginary part).
+ * \param pcmOutBuf Pointer to a time domain buffer were the upmixed output data
+ * will be stored into.
+ * \param nSamples Amount of audio samples per channel of down mix input data
+ * (frame length).
+ * \param pControlFlags pointer to control flags field; input/output.
+ * \param numInputChannels amount of down mix input channels. Might not match
+ * the current tree config, useful for internal sanity checks and bypass mode.
+ * \param channelMapping array containing the desired output channel ordering to
+ * transform MPEG PCE style ordering to any other channel ordering. First
+ * dimension is the total channel count.
+ */
+SACDEC_ERROR SpatialDecApplyFrame(
+ spatialDec *self, SPATIAL_BS_FRAME *frame, SPATIALDEC_INPUT_MODE inputMode,
+ PCM_MPS *inData, /* Time domain input */
+ FIXP_DBL **qmfInDataReal, /* interleaved l/r */
+ FIXP_DBL **qmfInDataImag, /* interleaved l/r */
+ PCM_MPS *pcmOutBuf, /* MAX_OUTPUT_CHANNELS*MAX_TIME_SLOTS*NUM_QMF_BANDS] */
+ UINT nSamples, UINT *pControlFlags, int numInputChannels,
+ const FDK_channelMapDescr *const mapDescr);
+
+/**
+ * \brief Fill given arrays with audio channel types and indices.
+ * \param self spatial decoder handle.
+ * \param channelType array where corresponding channel types fr each output
+ * channels are stored into.
+ * \param channelIndices array where corresponding channel type indices fr each
+ * output channels are stored into.
+ */
+void SpatialDecChannelProperties(spatialDec *self,
+ AUDIO_CHANNEL_TYPE channelType[],
+ UCHAR channelIndices[],
+ const FDK_channelMapDescr *const mapDescr);
+
+void FDK_SpatialDecClose(spatialDec *self);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SAC_DEC_INTERFACE_H */
diff --git a/fdk-aac/libSACdec/src/sac_dec_lib.cpp b/fdk-aac/libSACdec/src/sac_dec_lib.cpp
new file mode 100644
index 0000000..bf6dedf
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_dec_lib.cpp
@@ -0,0 +1,1995 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Decoder Library Interface
+
+*******************************************************************************/
+
+#include "sac_dec_lib.h"
+#include "sac_dec_interface.h"
+#include "sac_dec.h"
+#include "sac_bitdec.h"
+#include "FDK_matrixCalloc.h"
+
+#define MPS_DATA_BUFFER_SIZE (2048)
+
+/**
+ * \brief MPEG Surround data indication.
+ **/
+typedef enum {
+ MPEGS_ANCTYPE_FRAME = 0, /*!< MPEG Surround frame, see ISO/IEC 23003-1 */
+ MPEGS_ANCTYPE_HEADER_AND_FRAME = 1, /*!< MPEG Surround header and MPEG
+ Surround frame, see ISO/IEC 23003-1 */
+ MPEGS_ANCTYPE_RESERVED_1 = 2, /*!< reserved, see ISO/IEC 23003-1 */
+ MPEGS_ANCTYPE_RESERVED_2 = 3 /*!< reserved, see ISO/IEC 23003-1*/
+} MPEGS_ANCTYPE;
+
+/**
+ * \brief MPEG Surround data segment indication.
+ **/
+typedef enum {
+ MPEGS_CONTINUE = 0, /*!< Indicates if data segment continues a data block. */
+ MPEGS_STOP = 1, /*!< Indicates if data segment ends a data block. */
+ MPEGS_START = 2, /*!< Indicates if data segment begins a data block. */
+ MPEGS_START_STOP =
+ 3 /*!< Indicates if data segment begins and ends a data block. */
+} MPEGS_ANCSTARTSTOP;
+
+/**
+ * \brief MPEG Surround synchronizaiton state.
+ *
+ * CAUTION: Changing the enumeration values can break the sync mechanism
+ *because it is based on comparing the state values.
+ **/
+typedef enum {
+ MPEGS_SYNC_LOST =
+ 0, /*!< Indicates lost sync because of current discontinuity. */
+ MPEGS_SYNC_FOUND = 1, /*!< Parsed a valid header and (re)intialization was
+ successfully completed. */
+ MPEGS_SYNC_COMPLETE = 2 /*!< In sync and continuous. Found an independent
+ frame in addition to MPEGS_SYNC_FOUND.
+ Precondition: MPEGS_SYNC_FOUND. */
+} MPEGS_SYNCSTATE;
+
+/**
+ * \brief MPEG Surround operation mode.
+ **/
+typedef enum {
+ MPEGS_OPMODE_EMM = 0, /*!< Mode: Enhanced Matrix Mode (Blind) */
+ MPEGS_OPMODE_MPS_PAYLOAD = 1, /*!< Mode: Normal, Stereo or Binaural */
+ MPEGS_OPMODE_NO_MPS_PAYLOAD = 2 /*!< Mode: no MPEG Surround payload */
+} MPEGS_OPMODE;
+
+/**
+ * \brief MPEG Surround init flags.
+ **/
+typedef enum {
+ MPEGS_INIT_OK = 0x00000000, /*!< indicate correct initialization */
+ MPEGS_INIT_ENFORCE_REINIT =
+ 0x00000001, /*!< indicate complete initialization */
+
+ MPEGS_INIT_CHANGE_OUTPUT_MODE =
+ 0x00000010, /*!< indicate change of the output mode */
+ MPEGS_INIT_CHANGE_PARTIALLY_COMPLEX =
+ 0x00000020, /*!< indicate change of low power/high quality */
+ MPEGS_INIT_CHANGE_TIME_FREQ_INTERFACE =
+ 0x00000040, /*!< indicate change of qmf/time interface */
+ MPEGS_INIT_CHANGE_HEADER = 0x00000080, /*!< indicate change of header */
+
+ MPEGS_INIT_ERROR_PAYLOAD =
+ 0x00000100, /*!< indicate payload/ancType/ancStartStop error */
+
+ MPEGS_INIT_BS_INTERRUPTION =
+ 0x00001000, /*!< indicate bitstream interruption */
+ MPEGS_INIT_CLEAR_HISTORY =
+ 0x00002000, /*!< indicate that all states shall be cleared */
+
+ /* Re-initialization of submodules */
+
+ MPEGS_INIT_CHANGE_CONCEAL_PARAMS = 0x00100000, /*!< indicate a change of at
+ least one error concealment
+ param */
+
+ /* No re-initialization needed, currently not used */
+ MPEGS_INIT_CHANGE_BYPASS_MODE =
+ 0x01000000, /*!< indicate change of bypass mode */
+
+ /* Re-initialization needed, currently not used */
+ MPEGS_INIT_ERROR_ANC_TYPE = 0x10000000, /*!< indicate ancType error*/
+ MPEGS_INIT_ERROR_ANC_STARTSTOP =
+ 0x20000000 /*!< indicate ancStartStop error */
+} MPEGS_INIT_FLAGS;
+
+struct MpegSurroundDecoder {
+ HANDLE_FDK_QMF_DOMAIN pQmfDomain;
+ UCHAR mpsData[MPS_DATA_BUFFER_SIZE]; /* Buffer for MPS payload accross more
+ than one segment */
+ INT mpsDataBits; /* Amount of bits in mpsData */
+ /* MPEG Surround decoder */
+ SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig[1]; /* SSC delay line which is
+ used during decoding */
+ spatialDec *pSpatialDec;
+ SPATIAL_SPECIFIC_CONFIG
+ spatialSpecificConfigBackup; /* SSC used while parsing */
+
+ /* Creation parameter */
+ UCHAR mpegSurroundDecoderLevel;
+ /* Run-time parameter */
+ UCHAR mpegSurroundSscIsGlobalCfg; /* Flag telling that the SSC
+ (::spatialSpecificConfig) is a
+ out-of-band configuration. */
+ UCHAR mpegSurroundUseTimeInterface;
+
+ SPATIAL_BS_FRAME
+ bsFrames[1]; /* Bitstream Structs that contain data read from the
+ SpatialFrame() bitstream element */
+ BS_LL_STATE llState; /* Bit stream parser state memory */
+ UCHAR bsFrameParse; /* Current parse frame context index */
+ UCHAR bsFrameDecode; /* Current decode/apply frame context index */
+ UCHAR bsFrameDelay; /* Amount of frames delay between parsing and processing.
+ Required i.e. for interpolation error concealment. */
+
+ /* User prameters */
+ SPATIALDEC_PARAM mpegSurroundUserParams;
+
+ /* Internal flags */
+ SPATIAL_DEC_UPMIX_TYPE upmixType;
+ int initFlags[1];
+ MPEGS_ANCSTARTSTOP ancStartStopPrev;
+ MPEGS_SYNCSTATE fOnSync[1];
+
+ /* Inital decoder configuration */
+ SPATIAL_DEC_CONFIG decConfig;
+};
+
+SACDEC_ERROR
+static sscCheckOutOfBand(const SPATIAL_SPECIFIC_CONFIG *pSsc,
+ const INT coreCodec, const INT sampleRate,
+ const INT frameSize);
+
+static SACDEC_ERROR sscParseCheck(const SPATIAL_SPECIFIC_CONFIG *pSsc);
+
+/**
+ * \brief Get the number of QMF bands from the sampling frequency (in Hz)
+ **/
+static int mpegSurroundDecoder_GetNrOfQmfBands(
+ const SPATIAL_SPECIFIC_CONFIG *pSsc, UINT sampleRate) {
+ UINT samplingFrequency = sampleRate;
+ int qmfBands = 64;
+
+ if (pSsc != NULL) {
+ switch (pSsc->coreCodec) {
+ case AOT_USAC:
+ if ((pSsc->stereoConfigIndex == 3)) {
+ static const UCHAR mapIdx2QmfBands[3] = {24, 32, 16};
+ FDK_ASSERT((pSsc->coreSbrFrameLengthIndex >= 2) &&
+ (pSsc->coreSbrFrameLengthIndex <= 4));
+ qmfBands = mapIdx2QmfBands[pSsc->coreSbrFrameLengthIndex - 2];
+ }
+ return qmfBands;
+ default:
+ samplingFrequency = pSsc->samplingFreq;
+ break;
+ }
+ }
+
+ /* number of QMF bands depend on sampling frequency, see FDIS 23003-1:2006
+ * Chapter 6.3.3 */
+ if (samplingFrequency < 27713) {
+ qmfBands = 32;
+ }
+ if (samplingFrequency > 55426) {
+ qmfBands = 128;
+ }
+
+ return qmfBands;
+}
+
+/**
+ * \brief Analyse init flags
+ **/
+static int mpegSurroundDecoder_CalcInitFlags(SPATIAL_SPECIFIC_CONFIG *pSsc1,
+ SPATIAL_SPECIFIC_CONFIG *pSsc2,
+ int upmixTypeFlag,
+ int binauralQualityFlag,
+ int partiallyComplexFlag,
+ int *ctrlFlags) {
+ /* Analyse core coder */
+ if (pSsc1->coreCodec != pSsc2->coreCodec) {
+ *ctrlFlags |= MASK_MPEGS_INIT_ALL_STATES;
+ *ctrlFlags |= MASK_MPEGS_INIT_ALL_PARAMS;
+ } else {
+ /* Analyse elements for initialization of space analysis qmf filterbank */
+ if ((partiallyComplexFlag) || (pSsc1->treeConfig != pSsc2->treeConfig) ||
+ (pSsc1->samplingFreq != pSsc2->samplingFreq)) {
+ *ctrlFlags |= MPEGS_INIT_STATES_ANA_QMF_FILTER;
+ *ctrlFlags |= MPEGS_INIT_STATES_ANA_HYB_FILTER;
+ }
+
+ /* Analyse elements for initialization of space synthesis qmf filterbank */
+ if ((upmixTypeFlag) || (partiallyComplexFlag) ||
+ (pSsc1->treeConfig != pSsc2->treeConfig) ||
+ (pSsc1->samplingFreq != pSsc2->samplingFreq) ||
+ (pSsc1->bsFixedGainDMX != pSsc2->bsFixedGainDMX)) {
+ *ctrlFlags |= MPEGS_INIT_STATES_SYN_QMF_FILTER;
+ }
+
+ /* Analyse elements for initialization of decorrelator */
+ if ((upmixTypeFlag) || (partiallyComplexFlag) ||
+ (pSsc1->treeConfig != pSsc2->treeConfig) ||
+ (pSsc1->samplingFreq != pSsc2->samplingFreq) ||
+ (pSsc1->decorrConfig != pSsc2->decorrConfig)) {
+ *ctrlFlags |= MPEGS_INIT_STATES_DECORRELATOR;
+ }
+
+ /* Analyse elements for initialization of m1 and m2 calculation */
+ if ((upmixTypeFlag) || (binauralQualityFlag) ||
+ (pSsc1->treeConfig != pSsc2->treeConfig) ||
+ (pSsc1->samplingFreq != pSsc2->samplingFreq))
+
+ {
+ *ctrlFlags |= MPEGS_INIT_STATES_M1M2;
+ }
+
+ /* Analyse elements for initialization of GES */
+ if ((upmixTypeFlag) || (pSsc1->treeConfig != pSsc2->treeConfig) ||
+ (pSsc1->tempShapeConfig != pSsc2->tempShapeConfig)) {
+ *ctrlFlags |= MPEGS_INIT_STATES_GES;
+ }
+
+ /* Analyse elements for initialization of FDreverb */
+ if ((upmixTypeFlag) || (binauralQualityFlag) || (partiallyComplexFlag) ||
+ (pSsc1->samplingFreq != pSsc2->samplingFreq) ||
+ (pSsc1->nTimeSlots != pSsc2->nTimeSlots)) {
+ *ctrlFlags |= MPEGS_INIT_STATES_REVERB;
+ }
+
+ /* Reset previous frame data whenever the config changes */
+ if (*ctrlFlags & MPEGS_INIT_CONFIG) {
+ *ctrlFlags |= MPEGS_INIT_STATES_PARAM;
+ }
+ }
+
+ return MPS_OK;
+}
+
+/**
+ * \brief Reset MPEG Surround status info
+ **/
+static void updateMpegSurroundDecoderStatus(
+ CMpegSurroundDecoder *pMpegSurroundDecoder, int initFlags,
+ MPEGS_SYNCSTATE fOnSync, MPEGS_ANCSTARTSTOP ancStartStopPrev) {
+ pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
+ initFlags;
+ if ((pMpegSurroundDecoder->mpegSurroundSscIsGlobalCfg != 0) &&
+ (pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] >=
+ MPEGS_SYNC_FOUND) &&
+ (fOnSync < MPEGS_SYNC_FOUND)) {
+ pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
+ MPEGS_SYNC_FOUND;
+ } else {
+ pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
+ fOnSync;
+ }
+ pMpegSurroundDecoder->ancStartStopPrev = ancStartStopPrev;
+}
+
+static SACDEC_ERROR mpegSurroundDecoder_Create(
+ CMpegSurroundDecoder **pMpegSurroundDecoder, int stereoConfigIndex,
+ HANDLE_FDK_QMF_DOMAIN pQmfDomain);
+
+SAC_INSTANCE_AVAIL
+mpegSurroundDecoder_IsFullMpegSurroundDecoderInstanceAvailable(
+ CMpegSurroundDecoder *pMpegSurroundDecoder) {
+ SAC_INSTANCE_AVAIL instanceAvailable = SAC_INSTANCE_NOT_FULL_AVAILABLE;
+
+ if (pMpegSurroundDecoder->pSpatialDec != NULL) {
+ instanceAvailable = SAC_INSTANCE_FULL_AVAILABLE;
+ }
+
+ return instanceAvailable;
+}
+
+SACDEC_ERROR mpegSurroundDecoder_Open(
+ CMpegSurroundDecoder **pMpegSurroundDecoder, int stereoConfigIndex,
+ HANDLE_FDK_QMF_DOMAIN pQmfDomain) {
+ SACDEC_ERROR error;
+
+ error = mpegSurroundDecoder_Create(pMpegSurroundDecoder, stereoConfigIndex,
+ pQmfDomain);
+
+ return error;
+}
+
+/**
+ * \brief Renamed function from getUpmixType to check_UParam_Build_DecConfig.
+ * This function checks if user params, decoder config and SSC are valid
+ * and if the decoder build can handle all this settings.
+ * The upmix type may be modified by this function.
+ * It is called in initMpegSurroundDecoder() after the ssc parse check,
+ * to have all checks in one place and to ensure these checks are always
+ * performed if config changes (inband and out-of-band).
+ *
+ * \param pUserParams User data handle.
+ * \param pDecConfig decoder config handle.
+ * \param pSsc spatial specific config handle.
+ * \param pUpmixType upmix type which is set by this function
+ *
+ * \return MPS_OK on sucess, and else on failure.
+ */
+static SACDEC_ERROR check_UParam_Build_DecConfig(
+ SPATIALDEC_PARAM const *pUserParams, SPATIAL_DEC_CONFIG const *pDecConfig,
+ const SPATIAL_SPECIFIC_CONFIG *pSsc, SPATIAL_DEC_UPMIX_TYPE *pUpmixType) {
+ int dmxChannels, outChannels, maxNumOutChannels;
+
+ FDK_ASSERT(pUserParams != NULL);
+ FDK_ASSERT(pUpmixType != NULL);
+
+ /* checks if implementation can handle the Ssc */
+
+ switch (pSsc->treeConfig) {
+ case SPATIALDEC_MODE_RSVD7: /* 212 */
+ dmxChannels = 1;
+ outChannels = 2;
+ break;
+ default:
+ return MPS_UNSUPPORTED_CONFIG;
+ }
+
+ /* ------------------------------------------- */
+
+ /* Analyse pDecConfig params */
+ switch (pDecConfig->binauralMode) {
+ case BINAURAL_NONE:
+ break;
+ default:
+ return MPS_UNSUPPORTED_CONFIG;
+ }
+
+ switch (pDecConfig->decoderMode) {
+ case EXT_HQ_ONLY:
+ break;
+ default:
+ return MPS_UNSUPPORTED_CONFIG;
+ }
+
+ switch (pDecConfig->maxNumOutputChannels) {
+ case OUTPUT_CHANNELS_DEFAULT:
+ /* No special restrictions -> Get the level restriction: */
+ switch (pDecConfig->decoderLevel) {
+ case DECODER_LEVEL_0:
+ maxNumOutChannels = 2;
+ break;
+ default:
+ return MPS_UNSUPPORTED_CONFIG;
+ }
+ break;
+ case OUTPUT_CHANNELS_2_0:
+ maxNumOutChannels = 2;
+ break;
+ default:
+ return MPS_UNSUPPORTED_CONFIG;
+ }
+ /* ------------------------- */
+
+ /* check if we can handle user params */
+ if (pUserParams->blindEnable == 1) {
+ return MPS_UNSUPPORTED_CONFIG;
+ }
+ {
+ switch ((SAC_DEC_OUTPUT_MODE)pUserParams->outputMode) {
+ case SACDEC_OUT_MODE_NORMAL:
+ if (maxNumOutChannels >= outChannels) {
+ *pUpmixType = UPMIX_TYPE_NORMAL;
+ } else {
+ { *pUpmixType = UPMIX_TYPE_BYPASS; }
+ }
+ break;
+ case SACDEC_OUT_MODE_STEREO:
+ if (dmxChannels == 1) {
+ if (outChannels == 2) {
+ *pUpmixType = UPMIX_TYPE_NORMAL;
+ }
+ } else {
+ *pUpmixType = UPMIX_TYPE_BYPASS;
+ }
+ break;
+ case SACDEC_OUT_MODE_6CHANNEL:
+ if (outChannels > 6) {
+ { *pUpmixType = UPMIX_TYPE_BYPASS; }
+ } else {
+ *pUpmixType = UPMIX_TYPE_NORMAL;
+ }
+ break;
+ default:
+ return MPS_UNSUPPORTED_CONFIG;
+ }
+ }
+
+ return MPS_OK;
+}
+
+/**
+ * \brief Init MPEG Surround decoder.
+ **/
+static SACDEC_ERROR initMpegSurroundDecoder(
+ CMpegSurroundDecoder *pMpegSurroundDecoder) {
+ SACDEC_ERROR err;
+ int initFlags = MPEGS_INIT_NONE, initFlagsDec;
+ int upmixTypeCurr = pMpegSurroundDecoder->upmixType;
+
+ FDK_ASSERT(pMpegSurroundDecoder != NULL);
+
+ SPATIAL_SPECIFIC_CONFIG *const pSSCinput =
+ &pMpegSurroundDecoder->spatialSpecificConfigBackup;
+ SPATIAL_SPECIFIC_CONFIG *const pSSCtarget =
+ &pMpegSurroundDecoder
+ ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
+ initFlagsDec =
+ pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode];
+
+ if (pSSCinput->coreCodec != AOT_USAC) {
+ /* here we check if we have a valid Ssc */
+ err = sscParseCheck(pSSCinput);
+ if (err != MPS_OK) goto bail;
+ }
+
+ /* here we check if Ssc matches build; also check UParams and DecConfig */
+ /* if desired upmixType is changes */
+ err = check_UParam_Build_DecConfig(
+ &pMpegSurroundDecoder->mpegSurroundUserParams,
+ &pMpegSurroundDecoder->decConfig, pSSCinput,
+ &pMpegSurroundDecoder->upmixType);
+ if (err != MPS_OK) goto bail;
+
+ /* init config */
+ if (initFlagsDec & MPEGS_INIT_CHANGE_HEADER) {
+ initFlags |= MPEGS_INIT_CONFIG;
+ }
+ /* init all states */
+ if (initFlagsDec & MPEGS_INIT_CLEAR_HISTORY) {
+ initFlags |= MASK_MPEGS_INIT_ALL_STATES;
+ }
+ if (initFlagsDec & MPEGS_INIT_CHANGE_CONCEAL_PARAMS) {
+ initFlags |= MPEGS_INIT_PARAMS_ERROR_CONCEALMENT;
+ }
+
+ if (initFlagsDec & MPEGS_INIT_ENFORCE_REINIT) {
+ /* init all states */
+ initFlags |= MASK_MPEGS_INIT_ALL_STATES;
+ initFlags |= MASK_MPEGS_INIT_ALL_PARAMS;
+ } else {
+ /* analyse states which have to be initialized */
+ mpegSurroundDecoder_CalcInitFlags(
+ pSSCtarget, pSSCinput,
+ (upmixTypeCurr !=
+ pMpegSurroundDecoder->upmixType), /* upmixType changed */
+ 0, (initFlagsDec & MPEGS_INIT_CHANGE_PARTIALLY_COMPLEX) ? 1 : 0,
+ &initFlags);
+ }
+
+ {
+ int nrOfQmfBands;
+ FDKmemcpy(pSSCtarget, pSSCinput, sizeof(SPATIAL_SPECIFIC_CONFIG));
+
+ nrOfQmfBands = mpegSurroundDecoder_GetNrOfQmfBands(
+ pSSCtarget, pSSCtarget->samplingFreq);
+ err = FDK_SpatialDecInit(
+ pMpegSurroundDecoder->pSpatialDec,
+ &pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode],
+ pSSCtarget, nrOfQmfBands, pMpegSurroundDecoder->upmixType,
+ &pMpegSurroundDecoder->mpegSurroundUserParams, initFlags);
+
+ if (err != MPS_OK) goto bail;
+
+ /* Signal that we got a header and can go on decoding */
+ if (err == MPS_OK) {
+ initFlagsDec = MPEGS_INIT_OK;
+ {
+ pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
+ MPEGS_SYNC_FOUND;
+ }
+ }
+ }
+
+bail:
+ pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] =
+ initFlagsDec;
+ return err;
+}
+
+/**
+ * \brief Init MPEG Surround decoder.
+ **/
+SACDEC_ERROR mpegSurroundDecoder_Init(
+ CMpegSurroundDecoder *pMpegSurroundDecoder) {
+ SACDEC_ERROR err = MPS_OK;
+
+ if (pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode]) {
+ err = initMpegSurroundDecoder(pMpegSurroundDecoder);
+ }
+ return err;
+}
+
+/**
+ * \brief Open MPEG Surround decoder.
+ **/
+static SACDEC_ERROR mpegSurroundDecoder_Create(
+ CMpegSurroundDecoder **pMpegSurroundDecoder, int stereoConfigIndex,
+ HANDLE_FDK_QMF_DOMAIN pQmfDomain) {
+ SACDEC_ERROR err = MPS_OK;
+ CMpegSurroundDecoder *sacDec = NULL;
+ spatialDec *self = NULL;
+
+ /* decoderLevel decoderMode maxNumOutputChannels binauralMode */
+ static const SPATIAL_DEC_CONFIG decConfig = {
+ (CFG_LEVEL)(0), EXT_HQ_ONLY, OUTPUT_CHANNELS_DEFAULT, BINAURAL_NONE};
+
+ if (*pMpegSurroundDecoder == NULL) {
+ FDK_ALLOCATE_MEMORY_1D(*pMpegSurroundDecoder, 1, CMpegSurroundDecoder)
+
+ for (int i = 0; i < 1; i++) {
+ err = SpatialDecCreateBsFrame(&(*pMpegSurroundDecoder)->bsFrames[i],
+ &(*pMpegSurroundDecoder)->llState);
+ if (err != MPS_OK) {
+ sacDec = *pMpegSurroundDecoder;
+ goto bail;
+ }
+ }
+ (*pMpegSurroundDecoder)->pQmfDomain = pQmfDomain;
+
+ (*pMpegSurroundDecoder)->bsFrameDelay = 1;
+ (*pMpegSurroundDecoder)->bsFrameParse = 0;
+ (*pMpegSurroundDecoder)->bsFrameDecode = 0;
+
+ return err;
+ } else {
+ sacDec = *pMpegSurroundDecoder;
+ }
+
+ if (sacDec->pSpatialDec == NULL) {
+ if ((self = FDK_SpatialDecOpen(&decConfig, stereoConfigIndex)) == NULL) {
+ err = MPS_OUTOFMEMORY;
+ goto bail;
+ }
+ } else {
+ self = sacDec->pSpatialDec;
+ }
+
+ self->pQmfDomain = sacDec->pQmfDomain;
+
+ sacDec->pSpatialDec = self;
+
+ /* default parameter set */
+ sacDec->mpegSurroundUserParams.outputMode = SACDEC_OUT_MODE_NORMAL;
+ sacDec->mpegSurroundUserParams.blindEnable = 0;
+ sacDec->mpegSurroundUserParams.bypassMode = 0;
+ sacDec->mpegSurroundUserParams.concealMethod = 1;
+ sacDec->mpegSurroundUserParams.concealNumKeepFrames = 10;
+ sacDec->mpegSurroundUserParams.concealFadeOutSlopeLength = 5;
+ sacDec->mpegSurroundUserParams.concealFadeInSlopeLength = 5;
+ sacDec->mpegSurroundUserParams.concealNumReleaseFrames = 3;
+ sacDec->mpegSurroundSscIsGlobalCfg = 0;
+ sacDec->mpegSurroundUseTimeInterface = 1;
+ sacDec->mpegSurroundDecoderLevel = decConfig.decoderLevel;
+
+ sacDec->upmixType = UPMIX_TYPE_NORMAL;
+
+ /* signalize spatial decoder re-initalization */
+ updateMpegSurroundDecoderStatus(sacDec, MPEGS_INIT_ENFORCE_REINIT,
+ MPEGS_SYNC_LOST, MPEGS_STOP);
+
+ /* return decoder instance */
+ *pMpegSurroundDecoder = sacDec;
+ sacDec->decConfig = decConfig;
+
+ SpatialDecInitParserContext(sacDec->pSpatialDec);
+
+ return err;
+
+bail:
+ if (sacDec != NULL) {
+ mpegSurroundDecoder_Close(sacDec);
+ }
+ *pMpegSurroundDecoder = NULL;
+ if (err == MPS_OK) {
+ return MPS_OUTOFMEMORY;
+ } else {
+ return err;
+ }
+}
+
+/**
+ * \brief Config MPEG Surround decoder.
+ **/
+SACDEC_ERROR mpegSurroundDecoder_Config(
+ CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
+ AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize,
+ INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes,
+ const UCHAR configMode, UCHAR *configChanged) {
+ SACDEC_ERROR err = MPS_OK;
+ SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig;
+ SPATIAL_SPECIFIC_CONFIG *pSsc =
+ &pMpegSurroundDecoder->spatialSpecificConfigBackup;
+
+ switch (coreCodec) {
+ case AOT_DRM_USAC:
+ case AOT_USAC:
+ if (configMode == AC_CM_DET_CFG_CHANGE) {
+ /* In config detection mode write spatial specific config parameters
+ * into temporarily allocated structure */
+ err = SpatialDecParseMps212Config(
+ hBs, &spatialSpecificConfig, samplingRate, coreCodec,
+ stereoConfigIndex, coreSbrFrameLengthIndex);
+ pSsc = &spatialSpecificConfig;
+ } else {
+ err = SpatialDecParseMps212Config(
+ hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
+ samplingRate, coreCodec, stereoConfigIndex,
+ coreSbrFrameLengthIndex);
+ }
+ break;
+ case AOT_ER_AAC_ELD:
+ case AOT_ER_AAC_LD:
+ if (configMode == AC_CM_DET_CFG_CHANGE) {
+ /* In config detection mode write spatial specific config parameters
+ * into temporarily allocated structure */
+ err = SpatialDecParseSpecificConfig(hBs, &spatialSpecificConfig,
+ configBytes, coreCodec);
+ pSsc = &spatialSpecificConfig;
+ } else {
+ err = SpatialDecParseSpecificConfig(
+ hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
+ configBytes, coreCodec);
+ }
+ break;
+ default:
+ err = MPS_UNSUPPORTED_FORMAT;
+ break;
+ }
+
+ if (err != MPS_OK) {
+ goto bail;
+ }
+
+ err = sscCheckOutOfBand(pSsc, coreCodec, samplingRate, frameSize);
+
+ if (err != MPS_OK) {
+ goto bail;
+ }
+
+ if (configMode & AC_CM_DET_CFG_CHANGE) {
+ return err;
+ }
+
+ if (configMode & AC_CM_ALLOC_MEM) {
+ if (*configChanged) {
+ err = mpegSurroundDecoder_Open(&pMpegSurroundDecoder, stereoConfigIndex,
+ NULL);
+ if (err) {
+ return err;
+ }
+ }
+ }
+
+ {
+ SPATIAL_SPECIFIC_CONFIG *sscParse =
+ &pMpegSurroundDecoder
+ ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameParse];
+
+ if (FDK_SpatialDecCompareSpatialSpecificConfigHeader(
+ &pMpegSurroundDecoder->spatialSpecificConfigBackup, sscParse)) {
+ pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameParse] |=
+ MPEGS_INIT_CHANGE_HEADER;
+ /* Error resilience code */
+ if (pMpegSurroundDecoder->pSpatialDec == NULL) {
+ err = MPS_NOTOK;
+ goto bail;
+ }
+ SpatialDecInitParserContext(pMpegSurroundDecoder->pSpatialDec);
+ pMpegSurroundDecoder->pSpatialDec->pConfigCurrent =
+ &pMpegSurroundDecoder
+ ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
+ }
+ }
+
+ if (err == MPS_OK) {
+ /* We got a valid out-of-band configuration so label it accordingly. */
+ pMpegSurroundDecoder->mpegSurroundSscIsGlobalCfg = 1;
+ }
+
+bail:
+ return err;
+}
+
+/**
+ * \brief Determine MPEG Surround operation mode.
+ **/
+static MPEGS_OPMODE mpegSurroundOperationMode(
+ CMpegSurroundDecoder *pMpegSurroundDecoder, int mpsDataBits) {
+ MPEGS_OPMODE mode;
+
+ {
+ if ((mpsDataBits > 0) &&
+ (pMpegSurroundDecoder->mpegSurroundUserParams.blindEnable == 0)) {
+ mode = MPEGS_OPMODE_MPS_PAYLOAD; /* Mode: Normal, Stereo or Binaural */
+ } else {
+ mode = MPEGS_OPMODE_NO_MPS_PAYLOAD; /* Mode: No MPEG Surround Payload */
+ updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
+ MPEGS_INIT_ERROR_PAYLOAD, MPEGS_SYNC_LOST,
+ MPEGS_STOP);
+ }
+ }
+
+ return (mode);
+}
+
+/**
+ * \brief Check ssc for parse errors.
+ * This one is called in initMpegSurroundDecoder()
+ * to ensure checking of inband and out-of-band mps configs.
+ * Only parse errors checked here! Check for valid config is done
+ * in check_UParam_Build_DecConfig()!
+ *
+ * \param pSsc spatial specific config handle.
+ *
+ * \return MPS_OK on sucess, and else on parse error.
+ */
+static SACDEC_ERROR sscParseCheck(const SPATIAL_SPECIFIC_CONFIG *pSsc) {
+ if (pSsc->samplingFreq > 96000) return MPS_PARSE_ERROR;
+ if (pSsc->samplingFreq < 8000) return MPS_PARSE_ERROR;
+
+ if ((pSsc->treeConfig < 0) || (pSsc->treeConfig > 7)) {
+ return MPS_PARSE_ERROR;
+ }
+
+ if ((pSsc->quantMode < 0) || (pSsc->quantMode > 2)) {
+ return MPS_PARSE_ERROR;
+ }
+
+ /* now we are sure there were no parsing errors */
+
+ return MPS_OK;
+}
+
+/**
+ * \brief Check number of time slots
+ *
+ * Basically the mps frame length must be a multiple of the core coder frame
+ * length. The below table shows all valid configurations in detail. See ISO/IEC
+ * 23003-1: "Table 4A - Allowed values for bsFrameLength in the Baseline MPEG
+ * Surround Profile"
+ *
+ * Downmix Coder Downmix Code Allowed values for bsFrameLength
+ * Allowed frame sizes for normal, downsampled and upsampled MPS Framelength
+ * (QMF Samples)
+ *
+ * AAC 1024 16 15, 31, 47, 63 1024 2048 3072 4096
+ * downsampled MPS 32 31, 63 1024 2048 upsampled MPS
+ * 8 7, 15, 23, 31, 39, 47, 55, 63, 71 1024 2048 3072 4096
+ * 5120 6144 7168 8192 9216
+ *
+ * AAC 960 15 14, 29, 44, 59 960 1920 2880 3840
+ * downsampled MPS 30 29, 59 960 1920 upsampled MPS
+ * 7,5 14, 29, 44, 59 1920 3840 5760 7680
+ *
+ * HE-AAC 1024/2048 32 31, 63 2048 4096 downsampled MPS
+ * 64 63 2048 upsampled MPS
+ * 16 15, 31, 47, 63 2048 4096 6144 8192
+ *
+ * HE-AAC 960/1920 30 29, 59 1920 3840 downsampled MPS
+ * 60 59 1920 upsampled MPS
+ * 15 14, 29, 44, 59 1920 3840 5760 7680
+ *
+ * BSAC 16 15, 31, 47, 63 1024 2048 3072 4096
+ * downsampled MPS 32 31, 63 1024 2048 upsampled MPS
+ * 8 7, 15, 23, 31, 39, 47, 55, 63, 71 1024 2048 3072 4096
+ * 5120 6144 7168 8192 9216
+ *
+ * BSAC with SBR 32 31, 63 2048 4096 downsampled MPS
+ * 64 63 2048 upsampled MPS
+ * 16 15, 31, 47, 63 2048 4096 6144 8192
+ *
+ * AAC LD 512 8 7, 15, 23, 31, 39, 47, 55, 63, 71
+ * 512 1024 1536 2048 2560 3072 3584 4096 4608 downsampled MPS
+ * 16 15, 31, 47, 63 512 1024 1536 2048
+ *
+ * AAC ELD 512 8 7, 15, 23, 31, 39, 47, 55, 63, 71
+ * 512 1024 1536 2048 2560 3072 3584 4096 4608 downsampled MPS
+ * 16 15, 31, 47, 63 512 1024 1536 2048
+ *
+ * AAC ELD with SBR 512/1024 16 15, 31, 47, 63 1024 2048 3072 4096
+ * downsampled MPS 32 31, 63 1024 2048 upsampled MPS
+ * 8 7, 15, 23, 31, 39, 47, 55, 63, 71 1024 2048 3072 4096
+ * 5120 6144 7168 8192 9216
+ *
+ * MPEG1/2 Layer II 18 17, 35, 53, 71 1152 2304 3456 4608
+ * downsampled MPS 36 35, 71 1152 2304
+ *
+ * MPEG1/2 Layer III 18 17, 35, 53, 71 1152 2304 3456 4608
+ * downsampled MPS 36 35, 71 1152 2304
+ *
+ * \param frameLength
+ * \param qmfBands
+ * \param timeSlots
+ *
+ * \return error code
+ */
+SACDEC_ERROR checkTimeSlots(int frameLength, int qmfBands, int timeSlots) {
+ int len;
+ int maxFrameLength;
+
+ if (qmfBands == 64) {
+ /* normal MPEG Surround */
+ switch (frameLength) {
+ case 960:
+ case 1920:
+ maxFrameLength = 3840;
+ break;
+ case 1024:
+ case 2048:
+ maxFrameLength = 4096;
+ break;
+ case 512:
+ case 1152:
+ maxFrameLength = 4608;
+ break;
+ default:
+ return MPS_PARSE_ERROR;
+ }
+ } else if (qmfBands == 32) {
+ /* downsampled MPEG Surround */
+ switch (frameLength) {
+ case 960:
+ case 1920:
+ maxFrameLength = 1920;
+ break;
+ case 512:
+ case 1024:
+ case 2048:
+ maxFrameLength = 2048;
+ break;
+ case 1152:
+ maxFrameLength = 2304;
+ break;
+ default:
+ return MPS_PARSE_ERROR;
+ }
+ } else if (qmfBands == 128) {
+ /* upsampled MPEG Surround */
+ switch (frameLength) {
+ case 1920:
+ maxFrameLength = 7680;
+ break;
+ case 1024:
+ maxFrameLength = 9216;
+ break;
+ case 2048:
+ maxFrameLength = 8192;
+ break;
+ case 512:
+ case 960:
+ case 1152:
+ /* no break, no support for upsampled MPEG Surround */
+ default:
+ return MPS_PARSE_ERROR;
+ }
+ } else {
+ return MPS_PARSE_ERROR;
+ }
+
+ len = frameLength;
+
+ while (len <= maxFrameLength) {
+ if (len == timeSlots * qmfBands) {
+ return MPS_OK;
+ }
+ len += frameLength;
+ }
+ return MPS_PARSE_ERROR;
+}
+
+/**
+ * \brief Check ssc for consistency (e.g. bit errors could cause trouble)
+ * First of currently two ssc-checks.
+ * This (old) one is called in mpegSurroundDecoder_Apply()
+ * only if inband mps config is contained in stream.
+ *
+ * New ssc check is split in two functions sscParseCheck() and
+ * check_UParam_Build_DecConfig(). sscParseCheck() checks only for correct
+ * parsing. check_UParam_Build_DecConfig() is used to check if we have a
+ * valid config. Both are called in initMpegSurroundDecoder() to ensure
+ * checking of inband and out-of-band mps configs.
+ *
+ * If this function can be integrated into the new functions.
+ * We can remove this one.
+ *
+ * \param pSsc spatial specific config handle.
+ * \param frameLength
+ * \param sampleRate
+ *
+ * \return MPS_OK on sucess, and else on failure.
+ */
+static SACDEC_ERROR sscCheckInBand(SPATIAL_SPECIFIC_CONFIG *pSsc,
+ int frameLength, int sampleRate) {
+ SACDEC_ERROR err = MPS_OK;
+ int qmfBands;
+
+ FDK_ASSERT(pSsc != NULL);
+
+ /* check ssc for parse errors */
+ if (sscParseCheck(pSsc) != MPS_OK) {
+ err = MPS_PARSE_ERROR;
+ }
+
+ /* core fs and mps fs must match */
+ if (pSsc->samplingFreq != sampleRate) {
+ err = MPS_PARSE_ERROR /* MPEGSDEC_SSC_PARSE_ERROR */;
+ }
+
+ qmfBands = mpegSurroundDecoder_GetNrOfQmfBands(pSsc, pSsc->samplingFreq);
+
+ if (checkTimeSlots(frameLength, qmfBands, pSsc->nTimeSlots) != MPS_OK) {
+ err = MPS_PARSE_ERROR;
+ }
+
+ return err;
+}
+
+SACDEC_ERROR
+mpegSurroundDecoder_ConfigureQmfDomain(
+ CMpegSurroundDecoder *pMpegSurroundDecoder,
+ SAC_INPUT_CONFIG sac_dec_interface, UINT coreSamplingRate,
+ AUDIO_OBJECT_TYPE coreCodec) {
+ SACDEC_ERROR err = MPS_OK;
+ FDK_QMF_DOMAIN_GC *pGC = NULL;
+
+ if (pMpegSurroundDecoder == NULL) {
+ return MPS_INVALID_HANDLE;
+ }
+
+ FDK_ASSERT(pMpegSurroundDecoder->pSpatialDec);
+
+ pGC = &pMpegSurroundDecoder->pQmfDomain->globalConf;
+ if (pMpegSurroundDecoder->mpegSurroundSscIsGlobalCfg) {
+ SPATIAL_SPECIFIC_CONFIG *pSSC =
+ &pMpegSurroundDecoder->spatialSpecificConfigBackup;
+ if (sac_dec_interface == SAC_INTERFACE_TIME) {
+ /* For SAC_INTERFACE_QMF these parameters are set by SBR. */
+ pGC->nBandsAnalysis_requested = mpegSurroundDecoder_GetNrOfQmfBands(
+ pSSC, coreSamplingRate); /* coreSamplingRate == outputSamplingRate for
+ SAC_INTERFACE_TIME */
+ pGC->nBandsSynthesis_requested = pGC->nBandsAnalysis_requested;
+ pGC->nInputChannels_requested =
+ fMax((UINT)pSSC->nInputChannels, (UINT)pGC->nInputChannels_requested);
+ }
+ pGC->nOutputChannels_requested =
+ fMax((UINT)pSSC->nOutputChannels, (UINT)pGC->nOutputChannels_requested);
+ } else {
+ if (sac_dec_interface == SAC_INTERFACE_TIME) {
+ /* For SAC_INTERFACE_QMF these parameters are set by SBR. */
+ pGC->nBandsAnalysis_requested = mpegSurroundDecoder_GetNrOfQmfBands(
+ NULL, coreSamplingRate); /* coreSamplingRate == outputSamplingRate for
+ SAC_INTERFACE_TIME */
+ pGC->nBandsSynthesis_requested = pGC->nBandsAnalysis_requested;
+ pGC->nInputChannels_requested =
+ pMpegSurroundDecoder->pSpatialDec->createParams.maxNumInputChannels;
+ }
+ pGC->nOutputChannels_requested =
+ pMpegSurroundDecoder->pSpatialDec->createParams.maxNumOutputChannels;
+ }
+ pGC->nQmfProcBands_requested = 64;
+ pGC->nQmfProcChannels_requested =
+ fMin((INT)pGC->nInputChannels_requested,
+ pMpegSurroundDecoder->pSpatialDec->createParams.maxNumInputChannels);
+
+ if (coreCodec == AOT_ER_AAC_ELD) {
+ pGC->flags_requested |= QMF_FLAG_MPSLDFB;
+ pGC->flags_requested &= ~QMF_FLAG_CLDFB;
+ }
+
+ return err;
+}
+
+/**
+ * \brief Check out-of-band config
+ *
+ * \param pSsc spatial specific config handle.
+ * \param coreCodec core codec.
+ * \param sampleRate sampling frequency.
+ *
+ * \return errorStatus
+ */
+SACDEC_ERROR
+sscCheckOutOfBand(const SPATIAL_SPECIFIC_CONFIG *pSsc, const INT coreCodec,
+ const INT sampleRate, const INT frameSize) {
+ FDK_ASSERT(pSsc != NULL);
+ int qmfBands = 0;
+
+ /* check ssc for parse errors */
+ if (sscParseCheck(pSsc) != MPS_OK) {
+ return MPS_PARSE_ERROR;
+ }
+
+ switch (coreCodec) {
+ case AOT_USAC:
+ case AOT_DRM_USAC:
+ /* ISO/IEC 23003-1:2007(E), Chapter 6.3.3, Support for lower and higher
+ * sampling frequencies */
+ if (pSsc->samplingFreq >= 55426) {
+ return MPS_PARSE_ERROR;
+ }
+ break;
+ case AOT_ER_AAC_LD:
+ case AOT_ER_AAC_ELD:
+ /* core fs and mps fs must match */
+ if (pSsc->samplingFreq != sampleRate) {
+ return MPS_PARSE_ERROR;
+ }
+
+ /* ISO/IEC 14496-3:2009 FDAM 3: Chapter 1.5.2.3, Levels for the Low Delay
+ * AAC v2 profile */
+ if (pSsc->samplingFreq > 48000) {
+ return MPS_PARSE_ERROR;
+ }
+
+ qmfBands = mpegSurroundDecoder_GetNrOfQmfBands(pSsc, pSsc->samplingFreq);
+ switch (frameSize) {
+ case 480:
+ if (!((qmfBands == 32) && (pSsc->nTimeSlots == 15))) {
+ return MPS_PARSE_ERROR;
+ }
+ break;
+ case 960:
+ if (!((qmfBands == 64) && (pSsc->nTimeSlots == 15))) {
+ return MPS_PARSE_ERROR;
+ }
+ break;
+ case 512:
+ if (!(((qmfBands == 32) && (pSsc->nTimeSlots == 16)) ||
+ ((qmfBands == 64) && (pSsc->nTimeSlots == 8)))) {
+ return MPS_PARSE_ERROR;
+ }
+ break;
+ case 1024:
+ if (!((qmfBands == 64) && (pSsc->nTimeSlots == 16))) {
+ return MPS_PARSE_ERROR;
+ }
+ break;
+ default:
+ return MPS_PARSE_ERROR;
+ }
+ break;
+ default:
+ return MPS_PARSE_ERROR;
+ break;
+ }
+
+ return MPS_OK;
+}
+
+/**
+ * \brief Decode MPEG Surround frame.
+ **/
+int mpegSurroundDecoder_ParseNoHeader(
+ CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
+ int *pMpsDataBits, int fGlobalIndependencyFlag) {
+ SACDEC_ERROR err = MPS_OK;
+ SPATIAL_SPECIFIC_CONFIG *sscParse;
+ int bitsAvail, numSacBits;
+
+ if (pMpegSurroundDecoder == NULL || hBs == NULL) {
+ return MPS_INVALID_HANDLE;
+ }
+
+ sscParse = &pMpegSurroundDecoder
+ ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameParse];
+
+ bitsAvail = FDKgetValidBits(hBs);
+
+ /* First spatial specific config is parsed into spatialSpecificConfigBackup,
+ * second spatialSpecificConfigBackup is copied into
+ * spatialSpecificConfig[bsFrameDecode] */
+ if (pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameParse]) {
+ FDKmemcpy(sscParse, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
+ sizeof(SPATIAL_SPECIFIC_CONFIG));
+ pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameParse] =
+ MPEGS_SYNC_FOUND;
+ }
+
+ if (bitsAvail <= 0) {
+ err = MPS_PARSE_ERROR;
+ } else {
+ err = SpatialDecParseFrameData(
+ pMpegSurroundDecoder->pSpatialDec,
+ &pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameParse],
+ hBs, sscParse, (UPMIXTYPE)pMpegSurroundDecoder->upmixType,
+ fGlobalIndependencyFlag);
+ if (err == MPS_OK) {
+ pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameParse]
+ .newBsData = 1;
+ }
+ }
+
+ numSacBits = bitsAvail - (INT)FDKgetValidBits(hBs);
+
+ if (numSacBits > bitsAvail) {
+ pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameParse]
+ .newBsData = 0;
+ err = MPS_PARSE_ERROR;
+ }
+
+ *pMpsDataBits -= numSacBits;
+
+ return err;
+}
+
+/**
+ * \brief Check, if ancType is valid.
+ **/
+static int isValidAncType(CMpegSurroundDecoder *pMpegSurroundDecoder,
+ int ancType) {
+ int ret = 1;
+
+ if ((ancType != MPEGS_ANCTYPE_HEADER_AND_FRAME) &&
+ (ancType != MPEGS_ANCTYPE_FRAME)) {
+ ret = 0;
+ }
+
+ if (ret == 0) {
+ updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
+ MPEGS_INIT_ERROR_PAYLOAD, MPEGS_SYNC_LOST,
+ MPEGS_STOP);
+ }
+
+ return (ret);
+}
+
+/**
+ * \brief Check, if ancStartStop is valid.
+ **/
+static int isValidAncStartStop(CMpegSurroundDecoder *pMpegSurroundDecoder,
+ int ancStartStop) {
+ int ret = 1;
+
+ switch (ancStartStop) {
+ case MPEGS_START:
+ /* Sequence start - start and continue - start not allowed */
+ if ((pMpegSurroundDecoder->ancStartStopPrev == MPEGS_START) ||
+ (pMpegSurroundDecoder->ancStartStopPrev == MPEGS_CONTINUE)) {
+ ret = 0;
+ }
+ break;
+
+ case MPEGS_STOP:
+ /* MPS payload of the previous frame must be valid if current type is stop
+ Sequence startstop - stop and stop - stop not allowed
+ Sequence startstop - continue and stop - continue are allowed */
+ if ((pMpegSurroundDecoder->ancStartStopPrev == MPEGS_STOP) ||
+ (pMpegSurroundDecoder->ancStartStopPrev == MPEGS_START_STOP)) {
+ ret = 0;
+ }
+ break;
+
+ case MPEGS_CONTINUE:
+ case MPEGS_START_STOP:
+ /* No error detection possible for this states */
+ break;
+ }
+
+ if (ret == 0) {
+ updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
+ MPEGS_INIT_ERROR_PAYLOAD, MPEGS_SYNC_LOST,
+ MPEGS_STOP);
+ } else {
+ pMpegSurroundDecoder->ancStartStopPrev = (MPEGS_ANCSTARTSTOP)ancStartStop;
+ }
+
+ return (ret);
+}
+
+int mpegSurroundDecoder_Parse(CMpegSurroundDecoder *pMpegSurroundDecoder,
+ HANDLE_FDK_BITSTREAM hBs, int *pMpsDataBits,
+ AUDIO_OBJECT_TYPE coreCodec, int sampleRate,
+ int frameSize, int fGlobalIndependencyFlag) {
+ SACDEC_ERROR err = MPS_OK;
+ SPATIAL_SPECIFIC_CONFIG *sscParse;
+ SPATIAL_BS_FRAME *bsFrame;
+ HANDLE_FDK_BITSTREAM hMpsBsData = NULL;
+ FDK_BITSTREAM mpsBsData;
+ int mpsDataBits = *pMpsDataBits;
+ int mpsBsBits;
+ MPEGS_ANCTYPE ancType;
+ MPEGS_ANCSTARTSTOP ancStartStop;
+
+ if (pMpegSurroundDecoder == NULL) {
+ return MPS_INVALID_HANDLE;
+ }
+
+ FDK_ASSERT(pMpegSurroundDecoder->pSpatialDec);
+
+ mpsBsBits = (INT)FDKgetValidBits(hBs);
+
+ sscParse = &pMpegSurroundDecoder
+ ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameParse];
+ bsFrame = &pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameParse];
+
+ /*
+ Find operation mode of mpeg surround decoder:
+ - MPEGS_OPMODE_EMM: Mode: Enhanced Matrix Mode (Blind)
+ - MPEGS_OPMODE_MPS_PAYLOAD: Mode: Normal, Stereo or Binaural
+ - MPEGS_OPMODE_NO_MPS_PAYLOAD: Mode: No MpegSurround Payload
+ */
+ {
+ /* Parse ancType and ancStartStop */
+ ancType = (MPEGS_ANCTYPE)FDKreadBits(hBs, 2);
+ ancStartStop = (MPEGS_ANCSTARTSTOP)FDKreadBits(hBs, 2);
+ mpsDataBits -= 4;
+
+ /* Set valid anc type flag, if ancType signals a payload with either header
+ * and frame or frame */
+ if (isValidAncType(pMpegSurroundDecoder, ancType)) {
+ /* Set valid anc startstop flag, if transmitted sequence is not illegal */
+ if (isValidAncStartStop(pMpegSurroundDecoder, ancStartStop)) {
+ switch (ancStartStop) {
+ case MPEGS_START:
+ /* Assuming that core coder frame size (AAC) is smaller than MPS
+ coder frame size. Save audio data for next frame. */
+ if (mpsDataBits > MPS_DATA_BUFFER_SIZE * 8) {
+ err = MPS_NOTOK;
+ goto bail;
+ }
+ for (int i = 0; i < mpsDataBits / 8; i++) {
+ pMpegSurroundDecoder->mpsData[i] = FDKreadBits(hBs, 8);
+ }
+ pMpegSurroundDecoder->mpsDataBits = mpsDataBits;
+ break;
+
+ case MPEGS_CONTINUE:
+ case MPEGS_STOP:
+ /* Assuming that core coder frame size (AAC) is smaller than MPS
+ coder frame size. Save audio data for next frame. */
+ if ((pMpegSurroundDecoder->mpsDataBits + mpsDataBits) >
+ MPS_DATA_BUFFER_SIZE * 8) {
+ err = MPS_NOTOK;
+ goto bail;
+ }
+ for (int i = 0; i < mpsDataBits / 8; i++) {
+ pMpegSurroundDecoder
+ ->mpsData[(pMpegSurroundDecoder->mpsDataBits / 8) + i] =
+ FDKreadBits(hBs, 8);
+ }
+ pMpegSurroundDecoder->mpsDataBits += mpsDataBits;
+ FDKinitBitStream(&mpsBsData, pMpegSurroundDecoder->mpsData,
+ MAX_BUFSIZE_BYTES,
+ pMpegSurroundDecoder->mpsDataBits, BS_READER);
+ hMpsBsData = &mpsBsData;
+ break;
+
+ case MPEGS_START_STOP:
+ pMpegSurroundDecoder->mpsDataBits = mpsDataBits;
+ hMpsBsData = hBs;
+ break;
+
+ default:
+ FDK_ASSERT(0);
+ }
+
+ if ((ancStartStop == MPEGS_STOP) ||
+ (ancStartStop == MPEGS_START_STOP)) {
+ switch (ancType) {
+ case MPEGS_ANCTYPE_HEADER_AND_FRAME: {
+ int parseResult, bitsRead;
+ SPATIAL_SPECIFIC_CONFIG spatialSpecificConfigTmp =
+ pMpegSurroundDecoder->spatialSpecificConfigBackup;
+
+ /* Parse spatial specific config */
+ bitsRead = (INT)FDKgetValidBits(hMpsBsData);
+
+ err = SpatialDecParseSpecificConfigHeader(
+ hMpsBsData,
+ &pMpegSurroundDecoder->spatialSpecificConfigBackup, coreCodec,
+ pMpegSurroundDecoder->upmixType);
+
+ bitsRead = (bitsRead - (INT)FDKgetValidBits(hMpsBsData));
+ parseResult = ((err == MPS_OK) ? bitsRead : -bitsRead);
+
+ if (parseResult < 0) {
+ parseResult = -parseResult;
+ err = MPS_PARSE_ERROR;
+ } else if (err == MPS_OK) {
+ /* Check SSC for consistency (e.g. bit errors could cause
+ * trouble) */
+ err = sscCheckInBand(
+ &pMpegSurroundDecoder->spatialSpecificConfigBackup,
+ frameSize, sampleRate);
+ }
+ if (err != MPS_OK) {
+ pMpegSurroundDecoder->spatialSpecificConfigBackup =
+ spatialSpecificConfigTmp;
+ break;
+ }
+
+ pMpegSurroundDecoder->mpsDataBits -= parseResult;
+
+ /* Initiate re-initialization, if header has changed */
+ if (FDK_SpatialDecCompareSpatialSpecificConfigHeader(
+ &pMpegSurroundDecoder->spatialSpecificConfigBackup,
+ sscParse) == MPS_UNEQUAL_SSC) {
+ pMpegSurroundDecoder
+ ->initFlags[pMpegSurroundDecoder->bsFrameParse] |=
+ MPEGS_INIT_CHANGE_HEADER;
+ SpatialDecInitParserContext(pMpegSurroundDecoder->pSpatialDec);
+ /* We found a valid in-band configuration. Therefore any
+ * previous config is invalid now. */
+ pMpegSurroundDecoder->mpegSurroundSscIsGlobalCfg = 0;
+ }
+ }
+ FDK_FALLTHROUGH;
+ case MPEGS_ANCTYPE_FRAME:
+
+ if (pMpegSurroundDecoder
+ ->initFlags[pMpegSurroundDecoder->bsFrameParse] &
+ MPEGS_INIT_ERROR_PAYLOAD) {
+ err = MPS_PARSE_ERROR;
+ break;
+ }
+
+ /* First spatial specific config is parsed into
+ * spatialSpecificConfigBackup, second spatialSpecificConfigBackup
+ * is copied into spatialSpecificConfig[bsFrameDecode] */
+ if (pMpegSurroundDecoder
+ ->initFlags[pMpegSurroundDecoder->bsFrameParse]) {
+ FDKmemcpy(sscParse,
+ &pMpegSurroundDecoder->spatialSpecificConfigBackup,
+ sizeof(SPATIAL_SPECIFIC_CONFIG));
+ pMpegSurroundDecoder
+ ->fOnSync[pMpegSurroundDecoder->bsFrameParse] =
+ MPEGS_SYNC_FOUND;
+ }
+
+ if (pMpegSurroundDecoder
+ ->fOnSync[pMpegSurroundDecoder->bsFrameParse] >=
+ MPEGS_SYNC_FOUND) {
+ int nbits = 0, bitsAvail;
+
+ if (err != MPS_OK) {
+ break;
+ }
+
+ bitsAvail = FDKgetValidBits(hMpsBsData);
+
+ if (bitsAvail <= 0) {
+ err = MPS_PARSE_ERROR;
+ } else {
+ err = SpatialDecParseFrameData(
+ pMpegSurroundDecoder->pSpatialDec, bsFrame, hMpsBsData,
+ sscParse, (UPMIXTYPE)pMpegSurroundDecoder->upmixType,
+ fGlobalIndependencyFlag);
+ if (err == MPS_OK) {
+ bsFrame->newBsData = 1;
+ }
+ }
+
+ nbits = bitsAvail - (INT)FDKgetValidBits(hMpsBsData);
+
+ if ((nbits > bitsAvail) ||
+ (nbits > pMpegSurroundDecoder->mpsDataBits) ||
+ (pMpegSurroundDecoder->mpsDataBits > nbits + 7 &&
+ !IS_LOWDELAY(coreCodec))) {
+ bsFrame->newBsData = 0;
+ err = MPS_PARSE_ERROR;
+ break;
+ }
+ pMpegSurroundDecoder->mpsDataBits -= nbits;
+ }
+ break;
+
+ default: /* added to avoid compiler warning */
+ err = MPS_NOTOK;
+ break; /* added to avoid compiler warning */
+ } /* switch (ancType) */
+
+ if (err == MPS_OK) {
+ pMpegSurroundDecoder->ancStartStopPrev = ancStartStop;
+ } else {
+ updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
+ MPEGS_INIT_ERROR_PAYLOAD,
+ MPEGS_SYNC_LOST, MPEGS_STOP);
+ pMpegSurroundDecoder->mpsDataBits = 0;
+ }
+ } /* (ancStartStop == MPEGS_STOP) || (ancStartStop == MPEGS_START_STOP)
+ */
+ } /* validAncStartStop */
+ } /* validAncType */
+ }
+
+bail:
+
+ *pMpsDataBits -= (mpsBsBits - (INT)FDKgetValidBits(hBs));
+
+ return err;
+}
+
+int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
+ INT_PCM *input, PCM_MPS *pTimeData,
+ const int timeDataSize, int timeDataFrameSize,
+ int *nChannels, int *frameSize, int sampleRate,
+ AUDIO_OBJECT_TYPE coreCodec,
+ AUDIO_CHANNEL_TYPE channelType[],
+ UCHAR channelIndices[],
+ const FDK_channelMapDescr *const mapDescr) {
+ SACDEC_ERROR err = MPS_OK;
+ PCM_MPS *pTimeOut = pTimeData;
+ UINT initControlFlags = 0, controlFlags = 0;
+ int timeDataRequiredSize = 0;
+ int newData;
+
+ if (pMpegSurroundDecoder == NULL) {
+ return MPS_INVALID_HANDLE;
+ }
+
+ FDK_ASSERT(pMpegSurroundDecoder->pSpatialDec);
+
+ if (!FDK_chMapDescr_isValid(mapDescr)) {
+ return MPS_INVALID_HANDLE;
+ }
+
+ if ((*nChannels <= 0) || (*nChannels > 2)) {
+ return MPS_NOTOK;
+ }
+
+ pMpegSurroundDecoder->pSpatialDec->pConfigCurrent =
+ &pMpegSurroundDecoder
+ ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
+ newData = pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameParse]
+ .newBsData;
+
+ switch (mpegSurroundOperationMode(pMpegSurroundDecoder, 1000)) {
+ case MPEGS_OPMODE_MPS_PAYLOAD:
+ if (pMpegSurroundDecoder
+ ->initFlags[pMpegSurroundDecoder->bsFrameDecode]) {
+ err = initMpegSurroundDecoder(pMpegSurroundDecoder);
+ }
+
+ if (err == MPS_OK) {
+ if ((pMpegSurroundDecoder
+ ->fOnSync[pMpegSurroundDecoder->bsFrameDecode] !=
+ MPEGS_SYNC_COMPLETE) &&
+ (pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode]
+ .bsIndependencyFlag == 1)) {
+ /* We got a valid header and independently decodeable frame data.
+ -> Go to the next sync level and start processing. */
+ pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
+ MPEGS_SYNC_COMPLETE;
+ }
+ } else {
+ /* We got a valid config header but found an error while parsing the
+ bitstream. Wait for the next independent frame and apply error
+ conealment in the meantime. */
+ pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
+ MPEGS_SYNC_FOUND;
+ controlFlags |= MPEGS_CONCEAL;
+ err = MPS_OK;
+ }
+ /*
+ Concealment:
+ - Bitstream is available, no sync found during bitstream processing
+ - Bitstream is available, sync lost due to corrupted bitstream
+ - Bitstream is available, sync found but no independent frame
+ */
+ if (pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] !=
+ MPEGS_SYNC_COMPLETE) {
+ controlFlags |= MPEGS_CONCEAL;
+ }
+ break;
+
+ case MPEGS_OPMODE_NO_MPS_PAYLOAD:
+ /* Concealment: No bitstream is available */
+ controlFlags |= MPEGS_CONCEAL;
+ break;
+
+ default:
+ err = MPS_NOTOK;
+ }
+
+ if (err != MPS_OK) {
+ goto bail;
+ }
+
+ /*
+ * Force BypassMode if choosen by user
+ */
+ if (pMpegSurroundDecoder->mpegSurroundUserParams.bypassMode) {
+ controlFlags |= MPEGS_BYPASSMODE;
+ }
+
+ if (pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode]) {
+ int startWithDfltCfg = 0;
+ /*
+ * Init with a default configuration if we came here and are still not
+ * initialized.
+ */
+ if (pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] &
+ MPEGS_INIT_ENFORCE_REINIT) {
+ /* Get default spatial specific config */
+ if (FDK_SpatialDecInitDefaultSpatialSpecificConfig(
+ &pMpegSurroundDecoder->spatialSpecificConfigBackup, coreCodec,
+ *nChannels, sampleRate,
+ *frameSize /
+ mpegSurroundDecoder_GetNrOfQmfBands(NULL, sampleRate),
+ pMpegSurroundDecoder->mpegSurroundDecoderLevel,
+ pMpegSurroundDecoder->mpegSurroundUserParams.blindEnable)) {
+ err = MPS_NOTOK;
+ goto bail;
+ }
+
+ /* Initiate re-initialization, if header has changed */
+ if (FDK_SpatialDecCompareSpatialSpecificConfigHeader(
+ &pMpegSurroundDecoder->spatialSpecificConfigBackup,
+ &pMpegSurroundDecoder->spatialSpecificConfig
+ [pMpegSurroundDecoder->bsFrameDecode]) == MPS_UNEQUAL_SSC) {
+ pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
+ MPEGS_INIT_CHANGE_HEADER;
+ SpatialDecInitParserContext(pMpegSurroundDecoder->pSpatialDec);
+ }
+
+ startWithDfltCfg = 1;
+ }
+
+ /* First spatial specific config is parsed into spatialSpecificConfigBackup,
+ * second spatialSpecificConfigBackup is copied into spatialSpecificConfig
+ */
+ err = initMpegSurroundDecoder(pMpegSurroundDecoder);
+
+ if (startWithDfltCfg) {
+ /* initialized with default config, but no sync found */
+ /* maybe use updateMpegSurroundDecoderStatus later on */
+ pMpegSurroundDecoder->fOnSync[pMpegSurroundDecoder->bsFrameDecode] =
+ MPEGS_SYNC_LOST;
+ }
+
+ /* Since we do not have state MPEGS_SYNC_COMPLETE apply concealment */
+ controlFlags |= MPEGS_CONCEAL;
+
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ }
+
+ /*
+ * Process MPEG Surround Audio
+ */
+ initControlFlags = controlFlags;
+
+ /* Check that provided output buffer is large enough. */
+ if (pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis == 0) {
+ err = MPS_UNSUPPORTED_FORMAT;
+ goto bail;
+ }
+ timeDataRequiredSize =
+ (timeDataFrameSize *
+ pMpegSurroundDecoder->pSpatialDec->numOutputChannelsAT *
+ pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsSynthesis) /
+ pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis;
+ if (timeDataSize < timeDataRequiredSize) {
+ err = MPS_OUTPUT_BUFFER_TOO_SMALL;
+ goto bail;
+ }
+
+ if ((pMpegSurroundDecoder->pSpatialDec->pConfigCurrent->syntaxFlags &
+ SACDEC_SYNTAX_USAC) &&
+ (pMpegSurroundDecoder->pSpatialDec->stereoConfigIndex > 1)) {
+ FDK_ASSERT(timeDataRequiredSize >= timeDataFrameSize * *nChannels);
+ /* Place samples comprising QMF time slots spaced at QMF output Band raster
+ * to allow slot wise processing */
+ int timeDataFrameSizeOut =
+ (timeDataFrameSize *
+ pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsSynthesis) /
+ pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis;
+ pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput =
+ pTimeData + timeDataFrameSizeOut - timeDataFrameSize;
+ for (int i = *nChannels - 1; i >= 0; i--) {
+ FDKmemmove(pTimeData + (i + 1) * timeDataFrameSizeOut - timeDataFrameSize,
+ pTimeData + timeDataFrameSize * i,
+ sizeof(PCM_MPS) * timeDataFrameSize);
+ FDKmemclear(pTimeData + i * timeDataFrameSizeOut,
+ sizeof(PCM_MPS) * (timeDataFrameSizeOut - timeDataFrameSize));
+ }
+ } else {
+ if (pMpegSurroundDecoder->mpegSurroundUseTimeInterface) {
+ FDKmemcpy(input, pTimeData,
+ sizeof(INT_PCM) * (*nChannels) * (*frameSize));
+ pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput = input;
+ }
+ }
+
+ /*
+ * Process MPEG Surround Audio
+ */
+ err = SpatialDecApplyFrame(
+ pMpegSurroundDecoder->pSpatialDec,
+ &pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode],
+ pMpegSurroundDecoder->mpegSurroundUseTimeInterface ? INPUTMODE_TIME
+ : INPUTMODE_QMF_SBR,
+ pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput, NULL, NULL,
+ pTimeOut, *frameSize, &controlFlags, *nChannels, mapDescr);
+ *nChannels = pMpegSurroundDecoder->pSpatialDec->numOutputChannelsAT;
+
+ if (err !=
+ MPS_OK) { /* A fatal error occured. Go back to start and try again: */
+ updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
+ MPEGS_INIT_ENFORCE_REINIT, MPEGS_SYNC_LOST,
+ MPEGS_STOP);
+ *frameSize =
+ 0; /* Declare that framework can not use the data in pTimeOut. */
+ } else {
+ if (((controlFlags & MPEGS_CONCEAL) &&
+ !(initControlFlags & MPEGS_CONCEAL)) ||
+ (pMpegSurroundDecoder->pSpatialDec->errInt !=
+ MPS_OK)) { /* Account for errors that occured in
+ SpatialDecApplyFrame(): */
+ updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
+ MPEGS_INIT_ERROR_PAYLOAD, MPEGS_SYNC_LOST,
+ MPEGS_STOP);
+ }
+ }
+
+ if ((err == MPS_OK) && !(controlFlags & MPEGS_BYPASSMODE) &&
+ !(pMpegSurroundDecoder->upmixType == UPMIX_TYPE_BYPASS)) {
+ SpatialDecChannelProperties(pMpegSurroundDecoder->pSpatialDec, channelType,
+ channelIndices, mapDescr);
+ }
+
+bail:
+
+ if (newData) {
+ /* numParameterSetsPrev shall only be read in the decode process, because of
+ that we can update this state variable here */
+ pMpegSurroundDecoder->pSpatialDec->numParameterSetsPrev =
+ pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode]
+ .numParameterSets;
+ }
+
+ return (err);
+}
+
+/**
+ * \brief Free config dependent MPEG Surround memory.
+ **/
+SACDEC_ERROR mpegSurroundDecoder_FreeMem(
+ CMpegSurroundDecoder *pMpegSurroundDecoder) {
+ SACDEC_ERROR err = MPS_OK;
+
+ if (pMpegSurroundDecoder != NULL) {
+ FDK_SpatialDecClose(pMpegSurroundDecoder->pSpatialDec);
+ pMpegSurroundDecoder->pSpatialDec = NULL;
+ }
+
+ return err;
+}
+
+/**
+ * \brief Close MPEG Surround decoder.
+ **/
+void mpegSurroundDecoder_Close(CMpegSurroundDecoder *pMpegSurroundDecoder) {
+ if (pMpegSurroundDecoder != NULL) {
+ FDK_SpatialDecClose(pMpegSurroundDecoder->pSpatialDec);
+ pMpegSurroundDecoder->pSpatialDec = NULL;
+
+ for (int i = 0; i < 1; i++) {
+ SpatialDecCloseBsFrame(&pMpegSurroundDecoder->bsFrames[i]);
+ }
+
+ FDK_FREE_MEMORY_1D(pMpegSurroundDecoder);
+ }
+}
+
+#define SACDEC_VL0 2
+#define SACDEC_VL1 0
+#define SACDEC_VL2 0
+
+int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) {
+ int i;
+
+ if (info == NULL) {
+ return -1;
+ }
+
+ /* search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) return -1;
+
+ info += i;
+
+ info->module_id = FDK_MPSDEC;
+#ifdef __ANDROID__
+ info->build_date = "";
+ info->build_time = "";
+#else
+ info->build_date = __DATE__;
+ info->build_time = __TIME__;
+#endif
+ info->title = "MPEG Surround Decoder";
+ info->version = LIB_VERSION(SACDEC_VL0, SACDEC_VL1, SACDEC_VL2);
+ LIB_VERSION_STRING(info);
+ info->flags = 0 | CAPF_MPS_LD | CAPF_MPS_USAC | CAPF_MPS_HQ |
+ CAPF_MPS_1CH_IN | CAPF_MPS_2CH_OUT; /* end flags */
+
+ return 0;
+}
+
+SACDEC_ERROR mpegSurroundDecoder_SetParam(
+ CMpegSurroundDecoder *pMpegSurroundDecoder, const SACDEC_PARAM param,
+ const INT value) {
+ SACDEC_ERROR err = MPS_OK;
+ SPATIALDEC_PARAM *pUserParams = NULL;
+
+ /* check decoder handle */
+ if (pMpegSurroundDecoder != NULL) {
+ /* init local shortcuts */
+ pUserParams = &pMpegSurroundDecoder->mpegSurroundUserParams;
+ } else {
+ err = MPS_INVALID_HANDLE;
+ /* check the parameter values before exiting. */
+ }
+
+ /* apply param value */
+ switch (param) {
+ case SACDEC_OUTPUT_MODE:
+ switch ((SAC_DEC_OUTPUT_MODE)value) {
+ case SACDEC_OUT_MODE_NORMAL:
+ case SACDEC_OUT_MODE_STEREO:
+ break;
+ default:
+ err = MPS_INVALID_PARAMETER;
+ }
+ if (err == MPS_OK) {
+ if (0) {
+ err = MPS_INVALID_PARAMETER;
+ } else if (pUserParams->outputMode != (UCHAR)value) {
+ pUserParams->outputMode = (UCHAR)value;
+ pMpegSurroundDecoder
+ ->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
+ MPEGS_INIT_CHANGE_OUTPUT_MODE;
+ }
+ }
+ break;
+
+ case SACDEC_INTERFACE:
+ if (value < 0 || value > 1) {
+ err = MPS_INVALID_PARAMETER;
+ }
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ if (pMpegSurroundDecoder->mpegSurroundUseTimeInterface != (UCHAR)value) {
+ pMpegSurroundDecoder->mpegSurroundUseTimeInterface = (UCHAR)value;
+ pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
+ MPEGS_INIT_CHANGE_TIME_FREQ_INTERFACE;
+ }
+ break;
+
+ case SACDEC_BS_INTERRUPTION:
+ if ((err == MPS_OK) && (value != 0)) {
+ updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
+ MPEGS_INIT_BS_INTERRUPTION,
+ MPEGS_SYNC_LOST, MPEGS_STOP);
+ }
+ break;
+
+ case SACDEC_CLEAR_HISTORY:
+ if ((err == MPS_OK) && (value != 0)) {
+ /* Just reset the states and go on. */
+ updateMpegSurroundDecoderStatus(pMpegSurroundDecoder,
+ MPEGS_INIT_CLEAR_HISTORY,
+ MPEGS_SYNC_LOST, MPEGS_STOP);
+ }
+ break;
+
+ case SACDEC_CONCEAL_NUM_KEEP_FRAMES:
+ if (value < 0) { /* Check valid value range */
+ err = MPS_INVALID_PARAMETER;
+ }
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ if (pUserParams->concealNumKeepFrames != (UINT)value) {
+ pUserParams->concealNumKeepFrames = (UINT)value;
+ pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
+ MPEGS_INIT_CHANGE_CONCEAL_PARAMS;
+ }
+ break;
+
+ case SACDEC_CONCEAL_FADE_OUT_SLOPE_LENGTH:
+ if (value < 0) { /* Check valid value range */
+ err = MPS_INVALID_PARAMETER;
+ }
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ if (pUserParams->concealFadeOutSlopeLength != (UINT)value) {
+ pUserParams->concealFadeOutSlopeLength = (UINT)value;
+ pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
+ MPEGS_INIT_CHANGE_CONCEAL_PARAMS;
+ }
+ break;
+
+ case SACDEC_CONCEAL_FADE_IN_SLOPE_LENGTH:
+ if (value < 0) { /* Check valid value range */
+ err = MPS_INVALID_PARAMETER;
+ }
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ if (pUserParams->concealFadeInSlopeLength != (UINT)value) {
+ pUserParams->concealFadeInSlopeLength = (UINT)value;
+ pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
+ MPEGS_INIT_CHANGE_CONCEAL_PARAMS;
+ }
+ break;
+
+ case SACDEC_CONCEAL_NUM_RELEASE_FRAMES:
+ if (value < 0) { /* Check valid value range */
+ err = MPS_INVALID_PARAMETER;
+ }
+ if (err != MPS_OK) {
+ goto bail;
+ }
+ if (pUserParams->concealNumReleaseFrames != (UINT)value) {
+ pUserParams->concealNumReleaseFrames = (UINT)value;
+ pMpegSurroundDecoder->initFlags[pMpegSurroundDecoder->bsFrameDecode] |=
+ MPEGS_INIT_CHANGE_CONCEAL_PARAMS;
+ }
+ break;
+
+ default:
+ err = MPS_INVALID_PARAMETER;
+ break;
+ } /* switch(param) */
+
+bail:
+ return err;
+}
+
+SACDEC_ERROR mpegSurroundDecoder_IsPseudoLR(
+ CMpegSurroundDecoder *pMpegSurroundDecoder, int *bsPseudoLr) {
+ if (pMpegSurroundDecoder != NULL) {
+ const SPATIAL_SPECIFIC_CONFIG *sscDecode =
+ &pMpegSurroundDecoder
+ ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
+ *bsPseudoLr = (int)sscDecode->bsPseudoLr;
+ return MPS_OK;
+ } else
+ return MPS_INVALID_HANDLE;
+}
+
+/**
+ * \brief Get the signal delay caused by the MPEG Surround decoder module.
+ **/
+UINT mpegSurroundDecoder_GetDelay(const CMpegSurroundDecoder *self) {
+ INT outputDelay = 0;
+
+ if (self != NULL) {
+ const SPATIAL_SPECIFIC_CONFIG *sscDecode =
+ &self->spatialSpecificConfig[self->bsFrameDecode];
+ AUDIO_OBJECT_TYPE coreCodec = sscDecode->coreCodec;
+
+ /* See chapter 4.5 (delay and synchronization) of ISO/IEC FDIS 23003-1 and
+ chapter 5.4.3 of ISO/IEC FDIS 23003-2 for details on the following
+ figures. */
+
+ if (coreCodec > AOT_NULL_OBJECT) {
+ if (IS_LOWDELAY(coreCodec)) {
+ /* All low delay variants (ER-AAC-(E)LD): */
+ outputDelay += 256;
+ } else if (!IS_USAC(coreCodec)) {
+ /* By the method of elimination this is the GA (AAC-LC, HE-AAC, ...)
+ * branch: */
+ outputDelay += 320 + 257; /* cos to exp delay + QMF synthesis */
+ if (self->mpegSurroundUseTimeInterface) {
+ outputDelay += 320 + 384; /* QMF and hybrid analysis */
+ }
+ }
+ }
+ }
+
+ return (outputDelay);
+}
diff --git a/fdk-aac/libSACdec/src/sac_dec_ssc_struct.h b/fdk-aac/libSACdec/src/sac_dec_ssc_struct.h
new file mode 100644
index 0000000..b67b465
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_dec_ssc_struct.h
@@ -0,0 +1,283 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: interface - spatial specific config struct
+
+*******************************************************************************/
+
+#ifndef SAC_DEC_SSC_STRUCT_H
+#define SAC_DEC_SSC_STRUCT_H
+
+#include "FDK_audio.h"
+
+#define MAX_NUM_QMF_BANDS (128)
+#define MAX_TIME_SLOTS 64
+#define MAX_INPUT_CHANNELS 1
+#define MAX_OUTPUT_CHANNELS \
+ 2 /* CAUTION: This does NOT restrict the number of \
+ output channels exclusively! In addition it \
+ affects the max number of bitstream and residual channels! */
+#define MAX_NUM_OTT (5)
+#define MAX_NUM_TTT (0)
+#define MAX_NUM_EXT_TYPES (8)
+#define MAX_PARAMETER_BANDS (28)
+#define MAX_PARAMETER_BANDS_LD (23)
+
+#define MAX_NUM_XCHANNELS (6)
+
+#define MAX_ARBITRARY_TREE_LEVELS (0)
+
+typedef enum {
+ /* CAUTION: Do not change enum values! */
+ SPATIALDEC_FREQ_RES_40 = 40,
+ SPATIALDEC_FREQ_RES_28 = 28,
+ SPATIALDEC_FREQ_RES_23 = 23,
+ SPATIALDEC_FREQ_RES_20 = 20,
+ SPATIALDEC_FREQ_RES_15 = 15,
+ SPATIALDEC_FREQ_RES_14 = 14,
+ SPATIALDEC_FREQ_RES_12 = 12,
+ SPATIALDEC_FREQ_RES_10 = 10,
+ SPATIALDEC_FREQ_RES_9 = 9,
+ SPATIALDEC_FREQ_RES_7 = 7,
+ SPATIALDEC_FREQ_RES_5 = 5,
+ SPATIALDEC_FREQ_RES_4 = 4
+
+} SPATIALDEC_FREQ_RES;
+
+typedef enum {
+
+ SPATIALDEC_QUANT_FINE_DEF = 0,
+ SPATIALDEC_QUANT_EDQ1 = 1,
+ SPATIALDEC_QUANT_EDQ2 = 2,
+ SPATIALDEC_QUANT_RSVD3 = 3,
+ SPATIALDEC_QUANT_RSVD4 = 4,
+ SPATIALDEC_QUANT_RSVD5 = 5,
+ SPATIALDEC_QUANT_RSVD6 = 6,
+ SPATIALDEC_QUANT_RSVD7 = 7
+
+} SPATIALDEC_QUANT_MODE;
+
+typedef enum { SPATIALDEC_MODE_RSVD7 = 7 } SPATIALDEC_TREE_CONFIG;
+
+typedef enum {
+
+ SPATIALDEC_GAIN_MODE0 = 0,
+ SPATIALDEC_GAIN_RSVD1 = 1,
+ SPATIALDEC_GAIN_RSVD2 = 2,
+ SPATIALDEC_GAIN_RSVD3 = 3,
+ SPATIALDEC_GAIN_RSVD4 = 4,
+ SPATIALDEC_GAIN_RSVD5 = 5,
+ SPATIALDEC_GAIN_RSVD6 = 6,
+ SPATIALDEC_GAIN_RSVD7 = 7,
+ SPATIALDEC_GAIN_RSVD8 = 8,
+ SPATIALDEC_GAIN_RSVD9 = 9,
+ SPATIALDEC_GAIN_RSVD10 = 10,
+ SPATIALDEC_GAIN_RSVD11 = 11,
+ SPATIALDEC_GAIN_RSVD12 = 12,
+ SPATIALDEC_GAIN_RSVD13 = 13,
+ SPATIALDEC_GAIN_RSVD14 = 14,
+ SPATIALDEC_GAIN_RSVD15 = 15
+
+} SPATIALDEC_FIXED_GAINS;
+
+typedef enum {
+
+ SPATIALDEC_TS_TPNOWHITE = 0,
+ SPATIALDEC_TS_TPWHITE = 1,
+ SPATIALDEC_TS_TES = 2,
+ SPATIALDEC_TS_NOTS = 3,
+ SPATIALDEC_TS_RSVD4 = 4,
+ SPATIALDEC_TS_RSVD5 = 5,
+ SPATIALDEC_TS_RSVD6 = 6,
+ SPATIALDEC_TS_RSVD7 = 7,
+ SPATIALDEC_TS_RSVD8 = 8,
+ SPATIALDEC_TS_RSVD9 = 9,
+ SPATIALDEC_TS_RSVD10 = 10,
+ SPATIALDEC_TS_RSVD11 = 11,
+ SPATIALDEC_TS_RSVD12 = 12,
+ SPATIALDEC_TS_RSVD13 = 13,
+ SPATIALDEC_TS_RSVD14 = 14,
+ SPATIALDEC_TS_RSVD15 = 15
+
+} SPATIALDEC_TS_CONF;
+
+typedef enum {
+
+ SPATIALDEC_DECORR_MODE0 = 0,
+ SPATIALDEC_DECORR_MODE1 = 1,
+ SPATIALDEC_DECORR_MODE2 = 2,
+ SPATIALDEC_DECORR_RSVD3 = 3,
+ SPATIALDEC_DECORR_RSVD4 = 4,
+ SPATIALDEC_DECORR_RSVD5 = 5,
+ SPATIALDEC_DECORR_RSVD6 = 6,
+ SPATIALDEC_DECORR_RSVD7 = 7,
+ SPATIALDEC_DECORR_RSVD8 = 8,
+ SPATIALDEC_DECORR_RSVD9 = 9,
+ SPATIALDEC_DECORR_RSVD10 = 10,
+ SPATIALDEC_DECORR_RSVD11 = 11,
+ SPATIALDEC_DECORR_RSVD12 = 12,
+ SPATIALDEC_DECORR_RSVD13 = 13,
+ SPATIALDEC_DECORR_RSVD14 = 14,
+ SPATIALDEC_DECORR_RSVD15 = 15
+
+} SPATIALDEC_DECORR_CONF;
+
+typedef struct T_SPATIALDEC_OTT_CONF {
+ int nOttBands;
+
+} SPATIALDEC_OTT_CONF;
+
+typedef struct T_SPATIALDEC_RESIDUAL_CONF {
+ int bResidualPresent;
+ int nResidualBands;
+
+} SPATIALDEC_RESIDUAL_CONF;
+
+typedef struct T_SPATIAL_SPECIFIC_CONFIG {
+ UINT syntaxFlags;
+ int samplingFreq;
+ int nTimeSlots;
+ SPATIALDEC_FREQ_RES freqRes;
+ SPATIALDEC_TREE_CONFIG treeConfig;
+ SPATIALDEC_QUANT_MODE quantMode;
+ int bArbitraryDownmix;
+
+ int bResidualCoding;
+ SPATIALDEC_FIXED_GAINS bsFixedGainDMX;
+
+ SPATIALDEC_TS_CONF tempShapeConfig;
+ SPATIALDEC_DECORR_CONF decorrConfig;
+
+ int nInputChannels; /* derived from treeConfig */
+ int nOutputChannels; /* derived from treeConfig */
+
+ /* ott config */
+ int nOttBoxes; /* derived from treeConfig */
+ SPATIALDEC_OTT_CONF OttConfig[MAX_NUM_OTT]; /* dimension nOttBoxes */
+
+ /* ttt config */
+ int nTttBoxes; /* derived from treeConfig */
+
+ /* residual config */
+ SPATIALDEC_RESIDUAL_CONF
+ ResidualConfig[MAX_NUM_OTT +
+ MAX_NUM_TTT]; /* dimension (nOttBoxes + nTttBoxes) */
+
+ int sacExtCnt;
+ int sacExtType[MAX_NUM_EXT_TYPES];
+ int envQuantMode;
+
+ AUDIO_OBJECT_TYPE coreCodec;
+
+ UCHAR stereoConfigIndex;
+ UCHAR coreSbrFrameLengthIndex; /* Table 70 in ISO/IEC FDIS 23003-3:2011 */
+ UCHAR bsHighRateMode;
+ UCHAR bsDecorrType;
+ UCHAR bsPseudoLr;
+ UCHAR bsPhaseCoding;
+ UCHAR bsOttBandsPhasePresent;
+ int bsOttBandsPhase;
+
+ SCHAR ottCLDdefault[MAX_NUM_OTT];
+ UCHAR numOttBandsIPD;
+ UCHAR bitstreamOttBands[MAX_NUM_OTT];
+ UCHAR numOttBands[MAX_NUM_OTT];
+
+} SPATIAL_SPECIFIC_CONFIG;
+
+#endif
diff --git a/fdk-aac/libSACdec/src/sac_process.cpp b/fdk-aac/libSACdec/src/sac_process.cpp
new file mode 100644
index 0000000..56c72ad
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_process.cpp
@@ -0,0 +1,1066 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Processing
+
+*******************************************************************************/
+
+/* data structures and interfaces for spatial audio reference software */
+#include "sac_process.h"
+
+#include "sac_bitdec.h"
+#include "sac_calcM1andM2.h"
+#include "sac_smoothing.h"
+#include "sac_rom.h"
+
+#include "sac_dec_errorcodes.h"
+
+#include "FDK_trigFcts.h"
+#include "FDK_decorrelate.h"
+
+/**
+ * \brief Linear interpolation between two parameter values.
+ * a*alpha + b*(1-alpha)
+ * = a*alpha + b - b*alpha
+ *
+ * \param alpha Weighting factor.
+ * \param a Parameter a.
+ * \param b Parameter b.
+ *
+ * \return Interpolated parameter value.
+ */
+FDK_INLINE FIXP_DBL interpolateParameter(const FIXP_SGL alpha, const FIXP_DBL a,
+ const FIXP_DBL b) {
+ return (b - fMult(alpha, b) + fMult(alpha, a));
+}
+
+/**
+ * \brief Map MPEG Surround channel indices to MPEG 4 PCE like channel indices.
+ * \param self Spatial decoder handle.
+ * \param ch MPEG Surround channel index.
+ * \return MPEG 4 PCE style channel index, corresponding to the given MPEG
+ * Surround channel index.
+ */
+static UINT mapChannel(spatialDec *self, UINT ch) {
+ static const UCHAR chanelIdx[][8] = {
+ {0, 1, 2, 3, 4, 5, 6, 7}, /* binaural, TREE_212, arbitrary tree */
+ };
+
+ int idx = 0;
+
+ return (chanelIdx[idx][ch]);
+}
+
+FIXP_DBL getChGain(spatialDec *self, UINT ch, INT *scale) {
+ /* init no gain modifier */
+ FIXP_DBL gain = 0x80000000;
+ *scale = 0;
+
+ if ((!isTwoChMode(self->upmixType)) &&
+ (self->upmixType != UPMIXTYPE_BYPASS)) {
+ if ((ch == 0) || (ch == 1) || (ch == 2)) {
+ /* no modifier */
+ }
+ }
+
+ return gain;
+}
+
+SACDEC_ERROR SpatialDecQMFAnalysis(spatialDec *self, const PCM_MPS *inData,
+ const INT ts, const INT bypassMode,
+ FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
+ const int numInputChannels) {
+ SACDEC_ERROR err = MPS_OK;
+ int ch, offset;
+
+ offset = self->pQmfDomain->globalConf.nBandsSynthesis *
+ self->pQmfDomain->globalConf.nQmfTimeSlots;
+
+ {
+ for (ch = 0; ch < numInputChannels; ch++) {
+ const PCM_MPS *inSamples =
+ &inData[ts * self->pQmfDomain->globalConf.nBandsAnalysis];
+ FIXP_DBL *pQmfRealAnalysis = qmfReal[ch]; /* no delay in blind mode */
+ FIXP_DBL *pQmfImagAnalysis = qmfImag[ch];
+
+ CalculateSpaceAnalysisQmf(&self->pQmfDomain->QmfDomainIn[ch].fb,
+ inSamples + (ch * offset), pQmfRealAnalysis,
+ pQmfImagAnalysis);
+
+ if (!isTwoChMode(self->upmixType) && !bypassMode) {
+ int i;
+ for (i = 0; i < self->qmfBands; i++) {
+ qmfReal[ch][i] = fMult(qmfReal[ch][i], self->clipProtectGain__FDK);
+ qmfImag[ch][i] = fMult(qmfImag[ch][i], self->clipProtectGain__FDK);
+ }
+ }
+ }
+ }
+
+ self->qmfInputDelayBufPos =
+ (self->qmfInputDelayBufPos + 1) % self->pc_filterdelay;
+
+ return err;
+}
+
+SACDEC_ERROR SpatialDecFeedQMF(spatialDec *self, FIXP_DBL **qmfInDataReal,
+ FIXP_DBL **qmfInDataImag, const INT ts,
+ const INT bypassMode, FIXP_DBL **qmfReal__FDK,
+ FIXP_DBL **qmfImag__FDK,
+ const INT numInputChannels) {
+ SACDEC_ERROR err = MPS_OK;
+ int ch;
+
+ {
+ for (ch = 0; ch < numInputChannels; ch++) {
+ FIXP_DBL *pQmfRealAnalysis =
+ qmfReal__FDK[ch]; /* no delay in blind mode */
+ FIXP_DBL *pQmfImagAnalysis = qmfImag__FDK[ch];
+
+ /* Write Input data to pQmfRealAnalysis. */
+ if (self->bShareDelayWithSBR) {
+ FDK_QmfDomain_GetSlot(
+ &self->pQmfDomain->QmfDomainIn[ch], ts + HYBRID_FILTER_DELAY, 0,
+ MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis, pQmfImagAnalysis, 15);
+ FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts,
+ MAX_QMF_BANDS_TO_HYBRID, self->qmfBands,
+ pQmfRealAnalysis, pQmfImagAnalysis, 15);
+ } else {
+ FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts, 0,
+ self->qmfBands, pQmfRealAnalysis,
+ pQmfImagAnalysis, 15);
+ }
+ if (ts == self->pQmfDomain->globalConf.nQmfTimeSlots - 1) {
+ /* Is currently also needed in case we dont have any overlap. We need to
+ * save lb_scale to ov_lb_scale */
+ FDK_QmfDomain_SaveOverlap(&self->pQmfDomain->QmfDomainIn[ch], 0);
+ }
+
+ /* Apply clip protection to output. */
+ if (!isTwoChMode(self->upmixType) && !bypassMode) {
+ int i;
+ for (i = 0; i < self->qmfBands; i++) {
+ qmfReal__FDK[ch][i] =
+ fMult(qmfReal__FDK[ch][i], self->clipProtectGain__FDK);
+ qmfImag__FDK[ch][i] =
+ fMult(qmfImag__FDK[ch][i], self->clipProtectGain__FDK);
+ }
+ }
+
+ } /* End of loop over numInputChannels */
+ }
+
+ self->qmfInputDelayBufPos =
+ (self->qmfInputDelayBufPos + 1) % self->pc_filterdelay;
+
+ return err;
+}
+
+/*******************************************************************************
+ Functionname: SpatialDecHybridAnalysis
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Input:
+ float** pointers[4] leftReal, leftIm, rightReal, rightIm
+
+ Output:
+ float self->qmfInputReal[MAX_INPUT_CHANNELS][MAX_TIME_SLOTS][MAX_QMF_BANDS];
+ float self->qmfInputImag[MAX_INPUT_CHANNELS][MAX_TIME_SLOTS][MAX_QMF_BANDS];
+
+ float
+self->hybInputReal[MAX_INPUT_CHANNELS][MAX_TIME_SLOTS][MAX_HYBRID_BANDS]; float
+self->hybInputImag[MAX_INPUT_CHANNELS][MAX_TIME_SLOTS][MAX_HYBRID_BANDS];
+
+
+*******************************************************************************/
+SACDEC_ERROR SpatialDecHybridAnalysis(spatialDec *self, FIXP_DBL **qmfInputReal,
+ FIXP_DBL **qmfInputImag,
+ FIXP_DBL **hybOutputReal,
+ FIXP_DBL **hybOutputImag, const INT ts,
+ const INT numInputChannels) {
+ SACDEC_ERROR err = MPS_OK;
+ int ch;
+
+ for (ch = 0; ch < numInputChannels;
+ ch++) /* hybrid filtering for down-mix signals */
+ {
+ if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) {
+ int k;
+ /* No hybrid filtering. Just copy the QMF data. */
+ for (k = 0; k < self->hybridBands; k += 1) {
+ hybOutputReal[ch][k] = qmfInputReal[ch][k];
+ hybOutputImag[ch][k] = qmfInputImag[ch][k];
+ }
+ } else {
+ self->hybridAnalysis[ch].hfMode = self->bShareDelayWithSBR;
+
+ if (self->stereoConfigIndex == 3)
+ FDK_ASSERT(self->hybridAnalysis[ch].hfMode == 0);
+ FDKhybridAnalysisApply(&self->hybridAnalysis[ch], qmfInputReal[ch],
+ qmfInputImag[ch], hybOutputReal[ch],
+ hybOutputImag[ch]);
+ }
+ }
+
+ if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC) &&
+ self->residualCoding) {
+ self->hybridAnalysis[numInputChannels].hfMode = 0;
+ FDKhybridAnalysisApply(
+ &self->hybridAnalysis[numInputChannels],
+ self->qmfResidualReal__FDK[0][0], self->qmfResidualImag__FDK[0][0],
+ self->hybResidualReal__FDK[0], self->hybResidualImag__FDK[0]);
+ }
+
+ return err;
+}
+
+SACDEC_ERROR SpatialDecCreateX(spatialDec *self, FIXP_DBL **hybInputReal,
+ FIXP_DBL **hybInputImag, FIXP_DBL **pxReal,
+ FIXP_DBL **pxImag) {
+ SACDEC_ERROR err = MPS_OK;
+ int row;
+
+ /* Creating wDry */
+ for (row = 0; row < self->numInputChannels; row++) {
+ /* pointer to direct signals */
+ pxReal[row] = hybInputReal[row];
+ pxImag[row] = hybInputImag[row];
+ }
+
+ return err;
+}
+
+static void M2ParamToKernelMult(FIXP_SGL *RESTRICT pKernel,
+ FIXP_DBL *RESTRICT Mparam,
+ FIXP_DBL *RESTRICT MparamPrev,
+ int *RESTRICT pWidth, FIXP_SGL alpha__FDK,
+ int nBands) {
+ int pb;
+
+ for (pb = 0; pb < nBands; pb++) {
+ FIXP_SGL tmp = FX_DBL2FX_SGL(
+ interpolateParameter(alpha__FDK, Mparam[pb], MparamPrev[pb]));
+
+ int i = pWidth[pb];
+ if (i & 1) *pKernel++ = tmp;
+ if (i & 2) {
+ *pKernel++ = tmp;
+ *pKernel++ = tmp;
+ }
+ for (i >>= 2; i--;) {
+ *pKernel++ = tmp;
+ *pKernel++ = tmp;
+ *pKernel++ = tmp;
+ *pKernel++ = tmp;
+ }
+ }
+}
+
+SACDEC_ERROR SpatialDecApplyM1_CreateW_Mode212(
+ spatialDec *self, const SPATIAL_BS_FRAME *frame, FIXP_DBL **xReal,
+ FIXP_DBL **xImag, FIXP_DBL **vReal, FIXP_DBL **vImag) {
+ SACDEC_ERROR err = MPS_OK;
+ int res;
+ FIXP_DBL *decorrInReal = vReal[0];
+ FIXP_DBL *decorrInImag = vImag[0];
+
+ /* M1 does not do anything in 212 mode, so use simplified processing */
+ FDK_ASSERT(self->numVChannels == 2);
+ FDK_ASSERT(self->numDirektSignals == 1);
+ FDK_ASSERT(self->numDecorSignals == 1);
+ FDKmemcpy(vReal[0], xReal[0], self->hybridBands * sizeof(FIXP_DBL));
+ FDKmemcpy(vImag[0], xImag[0], self->hybridBands * sizeof(FIXP_DBL));
+
+ if (isTsdActive(frame->TsdData)) {
+ /* Generate v_{x,nonTr} as input for allpass based decorrelator */
+ TsdGenerateNonTr(self->hybridBands, frame->TsdData, self->TsdTs, vReal[0],
+ vImag[0], vReal[1], vImag[1], &decorrInReal,
+ &decorrInImag);
+ }
+ /* - Decorrelate */
+ res = SpatialDecGetResidualIndex(self, 1);
+ if (FDKdecorrelateApply(&self->apDecor[0], decorrInReal, decorrInImag,
+ vReal[1], vImag[1],
+ self->param2hyb[self->residualBands[res]])) {
+ return MPS_NOTOK;
+ }
+ if (isTsdActive(frame->TsdData)) {
+ /* Generate v_{x,Tr}, apply transient decorrelator and add to allpass based
+ * decorrelator output */
+ TsdApply(self->hybridBands, frame->TsdData, &self->TsdTs,
+ vReal[0], /* input: v_x */
+ vImag[0],
+ vReal[1], /* input: d_{x,nonTr}; output: d_{x,nonTr} + d_{x,Tr} */
+ vImag[1]);
+ }
+
+ /* Write residual signal in approriate parameter bands */
+ if (self->residualBands[res] > 0) {
+ int stopBand = self->param2hyb[self->residualBands[res]];
+ FDKmemcpy(vReal[1], self->hybResidualReal__FDK[res],
+ fixMin(stopBand, self->hybridBands) * sizeof(FIXP_DBL));
+ FDKmemcpy(vImag[1], self->hybResidualImag__FDK[res],
+ fixMin(stopBand, self->hybridBands) * sizeof(FIXP_DBL));
+ } /* (self->residualBands[res]>0) */
+
+ return err;
+}
+
+SACDEC_ERROR SpatialDecApplyM2_Mode212(spatialDec *self, INT ps,
+ const FIXP_SGL alpha, FIXP_DBL **wReal,
+ FIXP_DBL **wImag,
+ FIXP_DBL **hybOutputRealDry,
+ FIXP_DBL **hybOutputImagDry) {
+ SACDEC_ERROR err = MPS_OK;
+ INT row;
+
+ INT *pWidth = self->kernels_width;
+ /* for stereoConfigIndex == 3 case hybridBands is < 71 */
+ INT pb_max = self->kernels[self->hybridBands - 1] + 1;
+ INT max_row = self->numOutputChannels;
+
+ INT M2_exp = 0;
+ if (self->residualCoding) M2_exp = 3;
+
+ for (row = 0; row < max_row; row++) // 2 times
+ {
+ FIXP_DBL *Mparam0 = self->M2Real__FDK[row][0];
+ FIXP_DBL *Mparam1 = self->M2Real__FDK[row][1];
+ FIXP_DBL *MparamPrev0 = self->M2RealPrev__FDK[row][0];
+ FIXP_DBL *MparamPrev1 = self->M2RealPrev__FDK[row][1];
+
+ FIXP_DBL *RESTRICT pHybOutRealDry = hybOutputRealDry[row];
+ FIXP_DBL *RESTRICT pHybOutImagDry = hybOutputImagDry[row];
+
+ FIXP_DBL *RESTRICT pWReal0 = wReal[0];
+ FIXP_DBL *RESTRICT pWReal1 = wReal[1];
+ FIXP_DBL *RESTRICT pWImag0 = wImag[0];
+ FIXP_DBL *RESTRICT pWImag1 = wImag[1];
+ for (INT pb = 0; pb < pb_max; pb++) {
+ FIXP_DBL tmp0, tmp1;
+
+ tmp0 = interpolateParameter(alpha, Mparam0[pb], MparamPrev0[pb]);
+ tmp1 = interpolateParameter(alpha, Mparam1[pb], MparamPrev1[pb]);
+
+ INT i = pWidth[pb];
+
+ do // about 3-4 times
+ {
+ FIXP_DBL var0, var1, real, imag;
+
+ var0 = *pWReal0++;
+ var1 = *pWReal1++;
+ real = fMultDiv2(var0, tmp0);
+ var0 = *pWImag0++;
+ real = fMultAddDiv2(real, var1, tmp1);
+ var1 = *pWImag1++;
+ imag = fMultDiv2(var0, tmp0);
+ *pHybOutRealDry++ = real << (1 + M2_exp);
+ imag = fMultAddDiv2(imag, var1, tmp1);
+ *pHybOutImagDry++ = imag << (1 + M2_exp);
+ } while (--i != 0);
+ }
+ }
+ return err;
+}
+
+SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
+ spatialDec *self, INT ps, const FIXP_SGL alpha, FIXP_DBL **wReal,
+ FIXP_DBL **wImag, FIXP_DBL **hybOutputRealDry,
+ FIXP_DBL **hybOutputImagDry) {
+ SACDEC_ERROR err = MPS_OK;
+ INT row;
+ INT scale_param_m2;
+ INT *pWidth = self->kernels_width;
+ INT pb_max = self->kernels[self->hybridBands - 1] + 1;
+
+ scale_param_m2 = SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2;
+
+ for (row = 0; row < self->numM2rows; row++) {
+ INT qs, pb;
+
+ FIXP_DBL *RESTRICT pWReal0 = wReal[0];
+ FIXP_DBL *RESTRICT pWImag0 = wImag[0];
+ FIXP_DBL *RESTRICT pWReal1 = wReal[1];
+ FIXP_DBL *RESTRICT pWImag1 = wImag[1];
+
+ FIXP_DBL *MReal0 = self->M2Real__FDK[row][0];
+ FIXP_DBL *MImag0 = self->M2Imag__FDK[row][0];
+ FIXP_DBL *MReal1 = self->M2Real__FDK[row][1];
+ FIXP_DBL *MRealPrev0 = self->M2RealPrev__FDK[row][0];
+ FIXP_DBL *MImagPrev0 = self->M2ImagPrev__FDK[row][0];
+ FIXP_DBL *MRealPrev1 = self->M2RealPrev__FDK[row][1];
+
+ FIXP_DBL *RESTRICT pHybOutRealDry = hybOutputRealDry[row];
+ FIXP_DBL *RESTRICT pHybOutImagDry = hybOutputImagDry[row];
+
+ FDK_ASSERT(!(self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD));
+ FDK_ASSERT((pWidth[0] + pWidth[1]) >= 3);
+
+ for (pb = 0, qs = 3; pb < 2; pb++) {
+ INT s;
+ FIXP_DBL maxVal;
+ FIXP_SGL mReal1;
+ FIXP_SGL mReal0, mImag0;
+ FIXP_DBL iReal0, iImag0, iReal1;
+
+ iReal0 = interpolateParameter(alpha, MReal0[pb], MRealPrev0[pb]);
+ iImag0 = -interpolateParameter(alpha, MImag0[pb], MImagPrev0[pb]);
+ iReal1 = interpolateParameter(alpha, MReal1[pb], MRealPrev1[pb]);
+
+ maxVal = fAbs(iReal0) | fAbs(iImag0);
+ maxVal |= fAbs(iReal1);
+
+ s = fMax(CntLeadingZeros(maxVal) - 1, 0);
+ s = fMin(s, scale_param_m2);
+
+ mReal0 = FX_DBL2FX_SGL(iReal0 << s);
+ mImag0 = FX_DBL2FX_SGL(iImag0 << s);
+ mReal1 = FX_DBL2FX_SGL(iReal1 << s);
+
+ s = scale_param_m2 - s;
+
+ INT i = pWidth[pb];
+
+ do {
+ FIXP_DBL real, imag, wReal0, wImag0, wReal1, wImag1;
+
+ wReal0 = *pWReal0++;
+ wImag0 = *pWImag0++;
+ wReal1 = *pWReal1++;
+ wImag1 = *pWImag1++;
+
+ cplxMultDiv2(&real, &imag, wReal0, wImag0, mReal0, mImag0);
+
+ *pHybOutRealDry++ = fMultAddDiv2(real, wReal1, mReal1) << s;
+ *pHybOutImagDry++ = fMultAddDiv2(imag, wImag1, mReal1) << s;
+
+ if (qs > 0) {
+ mImag0 = -mImag0;
+ qs--;
+ }
+ } while (--i != 0);
+ }
+
+ for (; pb < pb_max; pb++) {
+ INT s;
+ FIXP_DBL maxVal;
+ FIXP_SGL mReal1;
+ FIXP_SGL mReal0, mImag0;
+ FIXP_DBL iReal0, iImag0, iReal1;
+
+ iReal0 = interpolateParameter(alpha, MReal0[pb], MRealPrev0[pb]);
+ iImag0 = interpolateParameter(alpha, MImag0[pb], MImagPrev0[pb]);
+ iReal1 = interpolateParameter(alpha, MReal1[pb], MRealPrev1[pb]);
+
+ maxVal = fAbs(iReal0) | fAbs(iImag0);
+ maxVal |= fAbs(iReal1);
+
+ s = fMax(CntLeadingZeros(maxVal) - 1, 0);
+ s = fMin(s, scale_param_m2);
+
+ mReal0 = FX_DBL2FX_SGL(iReal0 << s);
+ mImag0 = FX_DBL2FX_SGL(iImag0 << s);
+ mReal1 = FX_DBL2FX_SGL(iReal1 << s);
+
+ s = scale_param_m2 - s;
+
+ INT i = pWidth[pb];
+
+ do {
+ FIXP_DBL real, imag, wReal0, wImag0, wReal1, wImag1;
+
+ wReal0 = *pWReal0++;
+ wImag0 = *pWImag0++;
+ wReal1 = *pWReal1++;
+ wImag1 = *pWImag1++;
+
+ cplxMultDiv2(&real, &imag, wReal0, wImag0, mReal0, mImag0);
+
+ *pHybOutRealDry++ = fMultAddDiv2(real, wReal1, mReal1) << s;
+ *pHybOutImagDry++ = fMultAddDiv2(imag, wImag1, mReal1) << s;
+ } while (--i != 0);
+ }
+ }
+
+ return err;
+}
+
+SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
+ FIXP_DBL **wReal, FIXP_DBL **wImag,
+ FIXP_DBL **hybOutputRealDry,
+ FIXP_DBL **hybOutputImagDry,
+ FIXP_DBL **hybOutputRealWet,
+ FIXP_DBL **hybOutputImagWet) {
+ SACDEC_ERROR err = MPS_OK;
+
+ {
+ int qs, row, col;
+ int complexHybBands;
+ int complexParBands;
+ int scale_param_m2 = 0;
+ int toolsDisabled;
+
+ UCHAR activParamBands;
+ FIXP_DBL *RESTRICT pWReal, *RESTRICT pWImag, *RESTRICT pHybOutRealDry,
+ *RESTRICT pHybOutImagDry, *RESTRICT pHybOutRealWet,
+ *RESTRICT pHybOutImagWet;
+ C_ALLOC_SCRATCH_START(pKernel, FIXP_SGL, MAX_HYBRID_BANDS);
+
+ /* The wet signal is added to the dry signal directly in applyM2 if GES and
+ * STP are disabled */
+ toolsDisabled =
+ ((self->tempShapeConfig == 1) || (self->tempShapeConfig == 2)) ? 0 : 1;
+
+ {
+ complexHybBands = self->hybridBands;
+ complexParBands = self->numParameterBands;
+ }
+
+ FDKmemclear(hybOutputImagDry[0],
+ self->createParams.maxNumOutputChannels *
+ self->createParams.maxNumCmplxHybBands * sizeof(FIXP_DBL));
+ FDKmemclear(hybOutputRealDry[0], self->createParams.maxNumOutputChannels *
+ self->createParams.maxNumHybridBands *
+ sizeof(FIXP_DBL));
+
+ if (!toolsDisabled) {
+ FDKmemclear(hybOutputRealWet[0],
+ self->createParams.maxNumOutputChannels *
+ self->createParams.maxNumHybridBands * sizeof(FIXP_DBL));
+ FDKmemclear(hybOutputImagWet[0],
+ self->createParams.maxNumOutputChannels *
+ self->createParams.maxNumCmplxHybBands *
+ sizeof(FIXP_DBL));
+ }
+
+ if (self->phaseCoding == 3) {
+ /* + SCALE_DATA_APPLY_M2 to compensate for Div2 below ?! */
+ scale_param_m2 = SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2;
+ }
+
+ for (row = 0; row < self->numM2rows; row++) {
+ pHybOutRealDry = hybOutputRealDry[row];
+ pHybOutImagDry = hybOutputImagDry[row];
+
+ if (toolsDisabled) {
+ pHybOutRealWet = hybOutputRealDry[row];
+ pHybOutImagWet = hybOutputImagDry[row];
+ } else {
+ pHybOutRealWet = hybOutputRealWet[row];
+ pHybOutImagWet = hybOutputImagWet[row];
+ }
+
+ for (col = 0; col < self->numDirektSignals; col++) {
+ if (self->pActivM2ParamBands ==
+ 0) { /* default setting, calculate all rows and columns */
+ activParamBands = 1;
+ } else {
+ if (self->pActivM2ParamBands[MAX_M2_INPUT * row +
+ col]) /* table with activ and inactiv
+ bands exists for current
+ configuration */
+ activParamBands = 1;
+ else
+ activParamBands = 0;
+ }
+ if (activParamBands) {
+ pWReal = wReal[col];
+ pWImag = wImag[col];
+
+ M2ParamToKernelMult(pKernel, self->M2Real__FDK[row][col],
+ self->M2RealPrev__FDK[row][col],
+ self->kernels_width, alpha,
+ self->numParameterBands);
+
+ if (1 && (self->phaseCoding != 3)) {
+ /* direct signals */
+ {
+ /* only one sample will be assigned to each row, hence
+ * accumulation is not neccessary; that is valid for all
+ * configurations */
+ for (qs = 0; qs < complexHybBands; qs++) {
+ pHybOutRealDry[qs] = fMult(pWReal[qs], pKernel[qs]);
+ pHybOutImagDry[qs] = fMult(pWImag[qs], pKernel[qs]);
+ }
+ }
+ } else { /* isBinauralMode(self->upmixType) */
+
+ for (qs = 0; qs < complexHybBands; qs++) {
+ pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
+ << (scale_param_m2);
+ pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
+ << (scale_param_m2);
+ }
+
+ M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
+ self->M2ImagPrev__FDK[row][col],
+ self->kernels_width, alpha, complexParBands);
+
+ /* direct signals sign is -1 for qs = 0,2 */
+ pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0])
+ << (scale_param_m2);
+ pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0])
+ << (scale_param_m2);
+
+ pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2])
+ << (scale_param_m2);
+ pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2])
+ << (scale_param_m2);
+
+ /* direct signals sign is +1 for qs = 1,3,4,5,...,complexHybBands */
+ pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1])
+ << (scale_param_m2);
+ pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1])
+ << (scale_param_m2);
+
+ for (qs = 3; qs < complexHybBands; qs++) {
+ pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
+ << (scale_param_m2);
+ pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
+ << (scale_param_m2);
+ }
+ } /* self->upmixType */
+ } /* if (activParamBands) */
+ } /* self->numDirektSignals */
+
+ for (; col < self->numVChannels; col++) {
+ if (self->pActivM2ParamBands ==
+ 0) { /* default setting, calculate all rows and columns */
+ activParamBands = 1;
+ } else {
+ if (self->pActivM2ParamBands[MAX_M2_INPUT * row +
+ col]) /* table with activ and inactiv
+ bands exists for current
+ configuration */
+ activParamBands = 1;
+ else
+ activParamBands = 0;
+ }
+
+ if (activParamBands) {
+ int resBandIndex;
+ int resHybIndex;
+
+ resBandIndex =
+ self->residualBands[SpatialDecGetResidualIndex(self, col)];
+ resHybIndex = self->param2hyb[resBandIndex];
+
+ pWReal = wReal[col];
+ pWImag = wImag[col];
+
+ M2ParamToKernelMult(pKernel, self->M2Real__FDK[row][col],
+ self->M2RealPrev__FDK[row][col],
+ self->kernels_width, alpha,
+ self->numParameterBands);
+
+ if (1 && (self->phaseCoding != 3)) {
+ /* residual signals */
+ for (qs = 0; qs < resHybIndex; qs++) {
+ pHybOutRealDry[qs] += fMult(pWReal[qs], pKernel[qs]);
+ pHybOutImagDry[qs] += fMult(pWImag[qs], pKernel[qs]);
+ }
+ /* decor signals */
+ for (; qs < complexHybBands; qs++) {
+ pHybOutRealWet[qs] += fMult(pWReal[qs], pKernel[qs]);
+ pHybOutImagWet[qs] += fMult(pWImag[qs], pKernel[qs]);
+ }
+ } else { /* self->upmixType */
+ /* residual signals */
+ FIXP_DBL *RESTRICT pHybOutReal;
+ FIXP_DBL *RESTRICT pHybOutImag;
+
+ for (qs = 0; qs < resHybIndex; qs++) {
+ pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
+ << (scale_param_m2);
+ pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
+ << (scale_param_m2);
+ }
+ /* decor signals */
+ for (; qs < complexHybBands; qs++) {
+ pHybOutRealWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
+ << (scale_param_m2);
+ pHybOutImagWet[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
+ << (scale_param_m2);
+ }
+
+ M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
+ self->M2ImagPrev__FDK[row][col],
+ self->kernels_width, alpha, complexParBands);
+
+ /* direct signals sign is -1 for qs = 0,2 */
+ /* direct signals sign is +1 for qs = 1,3.. */
+ if (toolsDisabled) {
+ pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0])
+ << (scale_param_m2);
+ pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0])
+ << (scale_param_m2);
+
+ pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1])
+ << (scale_param_m2);
+ pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1])
+ << (scale_param_m2);
+
+ pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2])
+ << (scale_param_m2);
+ pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2])
+ << (scale_param_m2);
+ } else {
+ pHybOutReal = &pHybOutRealDry[0];
+ pHybOutImag = &pHybOutImagDry[0];
+ if (0 == resHybIndex) {
+ pHybOutReal = &pHybOutRealWet[0];
+ pHybOutImag = &pHybOutImagWet[0];
+ }
+ pHybOutReal[0] += fMultDiv2(pWImag[0], pKernel[0])
+ << (scale_param_m2);
+ pHybOutImag[0] -= fMultDiv2(pWReal[0], pKernel[0])
+ << (scale_param_m2);
+
+ if (1 == resHybIndex) {
+ pHybOutReal = &pHybOutRealWet[0];
+ pHybOutImag = &pHybOutImagWet[0];
+ }
+ pHybOutReal[1] -= fMultDiv2(pWImag[1], pKernel[1])
+ << (scale_param_m2);
+ pHybOutImag[1] += fMultDiv2(pWReal[1], pKernel[1])
+ << (scale_param_m2);
+
+ if (2 == resHybIndex) {
+ pHybOutReal = &pHybOutRealWet[0];
+ pHybOutImag = &pHybOutImagWet[0];
+ }
+ pHybOutReal[2] += fMultDiv2(pWImag[2], pKernel[2])
+ << (scale_param_m2);
+ pHybOutImag[2] -= fMultDiv2(pWReal[2], pKernel[2])
+ << (scale_param_m2);
+ }
+
+ for (qs = 3; qs < resHybIndex; qs++) {
+ pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
+ << (scale_param_m2);
+ pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
+ << (scale_param_m2);
+ }
+ /* decor signals */
+ for (; qs < complexHybBands; qs++) {
+ pHybOutRealWet[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
+ << (scale_param_m2);
+ pHybOutImagWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
+ << (scale_param_m2);
+ }
+ } /* self->upmixType */
+ } /* if (activParamBands) { */
+ } /* self->numVChannels */
+ }
+
+ C_ALLOC_SCRATCH_END(pKernel, FIXP_SGL, MAX_HYBRID_BANDS);
+ }
+
+ return err;
+}
+
+SACDEC_ERROR SpatialDecSynthesis(spatialDec *self, const INT ts,
+ FIXP_DBL **hybOutputReal,
+ FIXP_DBL **hybOutputImag, PCM_MPS *timeOut,
+ const INT numInputChannels,
+ const FDK_channelMapDescr *const mapDescr) {
+ SACDEC_ERROR err = MPS_OK;
+
+ int ch;
+ int stride, offset;
+
+ stride = self->numOutputChannelsAT;
+ offset = 1;
+
+ PCM_MPS *pTimeOut__FDK =
+ &timeOut[stride * self->pQmfDomain->globalConf.nBandsSynthesis * ts];
+ C_ALLOC_SCRATCH_START(pQmfReal, FIXP_DBL, QMF_MAX_SYNTHESIS_BANDS);
+ C_ALLOC_SCRATCH_START(pQmfImag, FIXP_DBL, QMF_MAX_SYNTHESIS_BANDS);
+
+ for (ch = 0; ch < self->numOutputChannelsAT; ch++) {
+ if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) {
+ int k;
+ /* No hybrid filtering. Just copy the QMF data. */
+ for (k = 0; k < self->hybridBands; k += 1) {
+ pQmfReal[k] = hybOutputReal[ch][k];
+ pQmfImag[k] = hybOutputImag[ch][k];
+ }
+ } else {
+ FDKhybridSynthesisApply(&self->hybridSynthesis[ch], hybOutputReal[ch],
+ hybOutputImag[ch], pQmfReal, pQmfImag);
+ }
+
+ /* Map channel indices from MPEG Surround -> PCE style -> channelMapping[]
+ */
+ FDK_ASSERT(self->numOutputChannelsAT <= 6);
+ int outCh = FDK_chMapDescr_getMapValue(mapDescr, mapChannel(self, ch),
+ self->numOutputChannelsAT);
+
+ {
+ if (self->stereoConfigIndex == 3) {
+ /* MPS -> SBR */
+ int i;
+ FIXP_DBL *pWorkBufReal, *pWorkBufImag;
+ FDK_ASSERT((self->pQmfDomain->QmfDomainOut[outCh].fb.outGain_m ==
+ (FIXP_DBL)0x80000000) &&
+ (self->pQmfDomain->QmfDomainOut[outCh].fb.outGain_e == 0));
+ FDK_QmfDomain_GetWorkBuffer(&self->pQmfDomain->QmfDomainIn[outCh], ts,
+ &pWorkBufReal, &pWorkBufImag);
+ FDK_ASSERT(self->qmfBands <=
+ self->pQmfDomain->QmfDomainIn[outCh].workBuf_nBands);
+ for (i = 0; i < self->qmfBands; i++) {
+ pWorkBufReal[i] = pQmfReal[i];
+ pWorkBufImag[i] = pQmfImag[i];
+ }
+ self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale =
+ -7; /*-ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK;*/
+ self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -=
+ self->pQmfDomain->QmfDomainIn[outCh].fb.filterScale;
+ self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -=
+ self->clipProtectGainSF__FDK;
+
+ } else {
+ /* Call the QMF synthesis for dry. */
+ err = CalculateSpaceSynthesisQmf(&self->pQmfDomain->QmfDomainOut[outCh],
+ pQmfReal, pQmfImag, stride,
+ pTimeOut__FDK + (offset * outCh));
+ }
+ if (err != MPS_OK) goto bail;
+ }
+ } /* ch loop */
+
+bail:
+ C_ALLOC_SCRATCH_END(pQmfImag, FIXP_DBL, QMF_MAX_SYNTHESIS_BANDS);
+ C_ALLOC_SCRATCH_END(pQmfReal, FIXP_DBL, QMF_MAX_SYNTHESIS_BANDS);
+
+ return err;
+}
+
+void SpatialDecBufferMatrices(spatialDec *self) {
+ int row, col;
+ int complexParBands;
+ complexParBands = self->numParameterBands;
+
+ /*
+ buffer matrices M2
+ */
+ for (row = 0; row < self->numM2rows; row++) {
+ for (col = 0; col < self->numVChannels; col++) {
+ FDKmemcpy(self->M2RealPrev__FDK[row][col], self->M2Real__FDK[row][col],
+ self->numParameterBands * sizeof(FIXP_DBL));
+ if (0 || (self->phaseCoding == 3)) {
+ FDKmemcpy(self->M2ImagPrev__FDK[row][col], self->M2Imag__FDK[row][col],
+ complexParBands * sizeof(FIXP_DBL));
+ }
+ }
+ }
+
+ /* buffer phase */
+ FDKmemcpy(self->PhasePrevLeft__FDK, self->PhaseLeft__FDK,
+ self->numParameterBands * sizeof(FIXP_DBL));
+ FDKmemcpy(self->PhasePrevRight__FDK, self->PhaseRight__FDK,
+ self->numParameterBands * sizeof(FIXP_DBL));
+}
+
+#define PHASE_SCALE 2
+
+#ifndef P_PI
+#define P_PI 3.1415926535897932
+#endif
+
+/* For better precision, PI (pi_x2) is already doubled */
+static FIXP_DBL interp_angle__FDK(FIXP_DBL angle1, FIXP_DBL angle2,
+ FIXP_SGL alpha, FIXP_DBL pi_x2) {
+ if (angle2 - angle1 > (pi_x2 >> 1)) angle2 -= pi_x2;
+
+ if (angle1 - angle2 > (pi_x2 >> 1)) angle1 -= pi_x2;
+
+ return interpolateParameter(alpha, angle2, angle1);
+}
+
+/*
+ *
+ */
+void SpatialDecApplyPhase(spatialDec *self, FIXP_SGL alpha__FDK,
+ int lastSlotOfParamSet) {
+ int pb, qs;
+ FIXP_DBL ppb[MAX_PARAMETER_BANDS *
+ 4]; /* left real, imag - right real, imag interleaved */
+
+ const FIXP_DBL pi_x2 = PIx2__IPD;
+ for (pb = 0; pb < self->numParameterBands; pb++) {
+ FIXP_DBL pl, pr;
+
+ pl = interp_angle__FDK(self->PhasePrevLeft__FDK[pb],
+ self->PhaseLeft__FDK[pb], alpha__FDK, pi_x2);
+ pr = interp_angle__FDK(self->PhasePrevRight__FDK[pb],
+ self->PhaseRight__FDK[pb], alpha__FDK, pi_x2);
+
+ inline_fixp_cos_sin(pl, pr, IPD_SCALE, &ppb[4 * pb]);
+ }
+
+ /* sign is -1 for qs = 0,2 and +1 for qs = 1 */
+
+ const SCHAR *kernels = &self->kernels[0];
+
+ FIXP_DBL *Dry_real0 = &self->hybOutputRealDry__FDK[0][0];
+ FIXP_DBL *Dry_imag0 = &self->hybOutputImagDry__FDK[0][0];
+ FIXP_DBL *Dry_real1 = &self->hybOutputRealDry__FDK[1][0];
+ FIXP_DBL *Dry_imag1 = &self->hybOutputImagDry__FDK[1][0];
+
+ for (qs = 2; qs >= 0; qs--) {
+ FIXP_DBL out_re, out_im;
+
+ pb = *kernels++;
+ if (qs == 1) /* sign[qs] >= 0 */
+ {
+ cplxMultDiv2(&out_re, &out_im, *Dry_real0, *Dry_imag0, ppb[4 * pb + 0],
+ ppb[4 * pb + 1]);
+ out_re <<= PHASE_SCALE - 1;
+ out_im <<= PHASE_SCALE - 1;
+ *Dry_real0++ = out_re;
+ *Dry_imag0++ = out_im;
+
+ cplxMultDiv2(&out_re, &out_im, *Dry_real1, *Dry_imag1, ppb[4 * pb + 2],
+ ppb[4 * pb + 3]);
+ out_re <<= PHASE_SCALE - 1;
+ out_im <<= PHASE_SCALE - 1;
+ *Dry_real1++ = out_re;
+ *Dry_imag1++ = out_im;
+ } else {
+ cplxMultDiv2(&out_re, &out_im, *Dry_real0, *Dry_imag0, ppb[4 * pb + 0],
+ -ppb[4 * pb + 1]);
+ out_re <<= PHASE_SCALE - 1;
+ out_im <<= PHASE_SCALE - 1;
+ *Dry_real0++ = out_re;
+ *Dry_imag0++ = out_im;
+
+ cplxMultDiv2(&out_re, &out_im, *Dry_real1, *Dry_imag1, ppb[4 * pb + 2],
+ -ppb[4 * pb + 3]);
+ out_re <<= PHASE_SCALE - 1;
+ out_im <<= PHASE_SCALE - 1;
+ *Dry_real1++ = out_re;
+ *Dry_imag1++ = out_im;
+ }
+ }
+
+ /* sign is +1 for qs >=3 */
+ for (qs = self->hybridBands - 3; qs--;) {
+ FIXP_DBL out_re, out_im;
+
+ pb = *kernels++;
+ cplxMultDiv2(&out_re, &out_im, *Dry_real0, *Dry_imag0, ppb[4 * pb + 0],
+ ppb[4 * pb + 1]);
+ out_re <<= PHASE_SCALE - 1;
+ out_im <<= PHASE_SCALE - 1;
+ *Dry_real0++ = out_re;
+ *Dry_imag0++ = out_im;
+
+ cplxMultDiv2(&out_re, &out_im, *Dry_real1, *Dry_imag1, ppb[4 * pb + 2],
+ ppb[4 * pb + 3]);
+ out_re <<= PHASE_SCALE - 1;
+ out_im <<= PHASE_SCALE - 1;
+ *Dry_real1++ = out_re;
+ *Dry_imag1++ = out_im;
+ }
+}
diff --git a/fdk-aac/libSACdec/src/sac_process.h b/fdk-aac/libSACdec/src/sac_process.h
new file mode 100644
index 0000000..ee2f2fe
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_process.h
@@ -0,0 +1,297 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Processing
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Polyphase Filterbank
+*/
+
+#ifndef SAC_PROCESS_H
+#define SAC_PROCESS_H
+
+#include "sac_dec.h"
+
+void SpatialDecApplyPhase(spatialDec *self, FIXP_SGL alpha,
+ int lastSlotOfParamSet);
+
+/**
+ * \brief Apply QMF Analysis Filterbank.
+ *
+ * Calculates qmf data on downmix input time data.
+ * Delaylines will be applied if necessaray.
+ *
+ * \param self A spatial decoder handle.
+ * \param inData Downmix channel time data as input.
+ * \param ts Signals time slot offset for input buffer.
+ * \param qmfReal Downmix channel qmf output data.
+ * \param qmfImag Downmix channel qmf output data.
+ *
+ * \return Error status.
+ */
+SACDEC_ERROR SpatialDecQMFAnalysis(spatialDec *self, const PCM_MPS *inData,
+ const INT ts, const INT bypassMode,
+ FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
+ const int numInputChannels);
+
+/**
+ * \brief Feed spatial decoder with external qmf data.
+ *
+ * \param self A spatial decoder handle.
+ * \param qmfInDataReal External qmf downmix data as input.
+ * \param qmfInDataImag External qmf downmix data as input.
+ * \param ts Signals time slot in input buffer to process.
+ * \param qmfReal Downmix channel qmf output data.
+ * \param qmfImag Downmix channel qmf output data.
+ * \param numInputChannels Number of input channels. Might differ from
+ * self->numInputChannels.
+ *
+ * \return Error status.
+ */
+SACDEC_ERROR SpatialDecFeedQMF(spatialDec *self, FIXP_DBL **qmfInDataReal,
+ FIXP_DBL **qmfInDataImag, const INT ts,
+ const INT bypassMode, FIXP_DBL **qmfReal,
+ FIXP_DBL **qmfImag, const INT numInputChannels);
+
+/**
+ * \brief Apply Hybrdid Analysis Filterbank.
+ *
+ * Calculates hybrid data on downmix input data.
+ * Residual hybrid signals will also be calculated on current slot if available.
+ *
+ * \param self A spatial decoder handle.
+ * \param qmfInputReal Downmix channel qmf data as input.
+ * \param qmfInputImag Downmix channel qmf data as input.
+ * \param hybOutputReal Downmix channel hybrid output data.
+ * \param hybOutputImag Downmix channel hybrid output data.
+ * \param ts Signals time slot in spatial frame to process.
+ * \param numInputChannels Number of input channels. Might differ from
+ * self->numInputChannels.
+ *
+ * \return Error status.
+ */
+SACDEC_ERROR SpatialDecHybridAnalysis(spatialDec *self, FIXP_DBL **qmfInputReal,
+ FIXP_DBL **qmfInputImag,
+ FIXP_DBL **hybOutputReal,
+ FIXP_DBL **hybOutputImag, const INT ts,
+ const INT numInputChannels);
+
+/**
+ * \brief Create X data.
+ *
+ * Returns a pointer list over Xchannels pointing to downmix input channels
+ * and to residual channels when provided.
+ *
+ * \param self A spatial decoder handle.
+ * \param hybInputReal Downmix channel hybrid data as input.
+ * \param hybInputImag Downmix channel hybrid data as input.
+ * \param pxReal Pointer to hybrid and residual data as output.
+ * \param pxImag Pointer to hybrid and residual data as output.
+ *
+ * \return Error status.
+ */
+SACDEC_ERROR SpatialDecCreateX(spatialDec *self, FIXP_DBL **hybInputReal,
+ FIXP_DBL **hybInputImag, FIXP_DBL **pxReal,
+ FIXP_DBL **pxImag);
+
+/**
+ * \brief MPS212 combined version of apply M1 parameters and create wet signal
+ *
+ * \param self A spatial decoder handle.
+ * \param xReal Downmix and residual X data as input.
+ * \param xImag Downmix and residual X data as input.
+ * \param vReal output data: [0] direct signal (V); [1] wet signal
+ * (W).
+ * \param vImag output data: [0] direct signal (V); [1] wet signal
+ * (W).
+ *
+ * \return Error status.
+ */
+SACDEC_ERROR SpatialDecApplyM1_CreateW_Mode212(
+ spatialDec *self, const SPATIAL_BS_FRAME *frame, FIXP_DBL **xReal,
+ FIXP_DBL **xImag, FIXP_DBL **vReal, FIXP_DBL **vImag);
+
+/**
+ * \brief Apply M2 parameters.
+ *
+ * \param self A spatial decoder handle.
+ * \param ps Signals parameter band from where M2 parameter to
+ * use.
+ * \param alpha Smoothing factor between current and previous
+ * parameter band. Rangeability between 0.f and 1.f.
+ * \param wReal Wet input data.
+ * \param wImag Wet input data.
+ * \param hybOutputRealDry Dry output data.
+ * \param hybOutputImagDry Dry output data.
+ * \param hybOutputRealWet Wet output data.
+ * \param hybOutputImagWet Wet output data.
+ *
+ * \return Error status.
+ */
+SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
+ FIXP_DBL **wReal, FIXP_DBL **wImag,
+ FIXP_DBL **hybOutputRealDry,
+ FIXP_DBL **hybOutputImagDry,
+ FIXP_DBL **hybOutputRealWet,
+ FIXP_DBL **hybOutputImagWet);
+
+/**
+ * \brief Apply M2 parameter for 212 mode with residualCoding and phaseCoding.
+ *
+ * \param self [i] A spatial decoder handle.
+ * \param ps [i] Signals parameter band from where M2 parameter
+ * to use.
+ * \param alpha [i] Smoothing factor between current and previous
+ * parameter band. Rangeability between 0.f and 1.f.
+ * \param wReal [i] Wet input data.
+ * \param wImag [i] Wet input data.
+ * \param hybOutputRealDry [o] Dry output data.
+ * \param hybOutputImagDry [o] Dry output data.
+ *
+ * \return error
+ */
+SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
+ spatialDec *self, INT ps, const FIXP_SGL alpha, FIXP_DBL **wReal,
+ FIXP_DBL **wImag, FIXP_DBL **hybOutputRealDry, FIXP_DBL **hybOutputImagDry);
+
+/**
+ * \brief Apply M2 parameter for 212 mode, upmix from mono to stereo.
+ *
+ * \param self [i] A spatial decoder handle.
+ * \param ps [i] Signals parameter band from where M2 parameter
+ * to use.
+ * \param alpha [i] Smoothing factor between current and previous
+ * parameter band. Rangeability between 0.f and 1.f.
+ * \param wReal [i] Wet input data.
+ * \param wImag [i] Wet input data.
+ * \param hybOutputRealDry [o] Dry output data.
+ * \param hybOutputImagDry [o] Dry output data.
+ *
+ * \return error
+ */
+SACDEC_ERROR SpatialDecApplyM2_Mode212(spatialDec *self, INT ps,
+ const FIXP_SGL alpha, FIXP_DBL **wReal,
+ FIXP_DBL **wImag,
+ FIXP_DBL **hybOutputRealDry,
+ FIXP_DBL **hybOutputImagDry);
+
+/**
+ * \brief Convert Hybrid input to output audio data.
+ *
+ * \param hSpaceSynthesisQmf A spatial decoder handle.
+ * \param ts Signals time slot in spatial frame to process.
+ * \param hybOutputReal Hybrid data as input.
+ * \param hybOutputImag Hybrid data as input.
+ * \param timeOut audio output data.
+ *
+ * \return Error status.
+ */
+SACDEC_ERROR SpatialDecSynthesis(spatialDec *self, const INT ts,
+ FIXP_DBL **hybOutputReal,
+ FIXP_DBL **hybOutputImag, PCM_MPS *timeOut,
+ const INT numInputChannels,
+ const FDK_channelMapDescr *const mapDescr);
+
+void SpatialDecBufferMatrices(spatialDec *self);
+
+FIXP_DBL getChGain(spatialDec *self, UINT ch, INT *scale);
+
+#endif
diff --git a/fdk-aac/libSACdec/src/sac_qmf.cpp b/fdk-aac/libSACdec/src/sac_qmf.cpp
new file mode 100644
index 0000000..a075490
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_qmf.cpp
@@ -0,0 +1,156 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec QMF processing
+
+*******************************************************************************/
+
+#include "sac_qmf.h"
+
+#include "FDK_matrixCalloc.h"
+#include "sac_dec_interface.h"
+#include "sac_rom.h"
+
+#include "qmf.h"
+
+SACDEC_ERROR CalculateSpaceSynthesisQmf(
+ const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr,
+ const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig) {
+ SACDEC_ERROR err = MPS_OK;
+
+ if (hQmfDomainOutCh == NULL) {
+ err = MPS_INVALID_HANDLE;
+ } else {
+ HANDLE_SPACE_SYNTHESIS_QMF hSpaceSynthesisQmf = &hQmfDomainOutCh->fb;
+#if (QMF_MAX_SYNTHESIS_BANDS <= 64)
+ C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL,
+ (QMF_MAX_SYNTHESIS_BANDS << 1));
+#else
+ C_AALLOC_STACK_START(pWorkBuffer, FIXP_DBL, (QMF_MAX_SYNTHESIS_BANDS << 1));
+#endif
+
+ qmfSynthesisFilteringSlot(hSpaceSynthesisQmf, Sr, Si, 0, 0, timeSig, stride,
+ pWorkBuffer);
+
+#if (QMF_MAX_SYNTHESIS_BANDS <= 64)
+ C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, (QMF_MAX_SYNTHESIS_BANDS << 1));
+#else
+ C_AALLOC_STACK_END(pWorkBuffer, FIXP_DBL, (QMF_MAX_SYNTHESIS_BANDS << 1));
+#endif
+ }
+
+ return err;
+}
+
+SACDEC_ERROR CalculateSpaceAnalysisQmf(
+ HANDLE_SPACE_ANALYSIS_QMF hSpaceAnalysisQmf, const PCM_MPS *timeSig,
+ FIXP_DBL *Sr, FIXP_DBL *Si) {
+ SACDEC_ERROR err = MPS_OK;
+
+ if (hSpaceAnalysisQmf == NULL) {
+ err = MPS_INVALID_HANDLE;
+ } else {
+ C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, (64 << 1));
+
+ qmfAnalysisFilteringSlot(hSpaceAnalysisQmf, Sr, Si, timeSig, 1,
+ pWorkBuffer);
+ C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, (64 << 1));
+ }
+
+ return err;
+}
diff --git a/fdk-aac/libSACdec/src/sac_qmf.h b/fdk-aac/libSACdec/src/sac_qmf.h
new file mode 100644
index 0000000..d1dc837
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_qmf.h
@@ -0,0 +1,143 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec QMF processing
+
+*******************************************************************************/
+
+#ifndef SAC_QMF_H
+#define SAC_QMF_H
+
+#include "common_fix.h"
+
+#include "sac_dec_interface.h"
+
+#include "FDK_qmf_domain.h"
+#define HANDLE_SPACE_ANALYSIS_QMF HANDLE_QMF_FILTER_BANK
+#define HANDLE_SPACE_SYNTHESIS_QMF HANDLE_QMF_FILTER_BANK
+
+/**
+ * \brief Convert Qmf input to output audio data.
+ *
+ * \param hSpaceSynthesisQmf A Qmf Synthesis Filterbank handle.
+ * \param Sr Pointer to Qmf input buffer.
+ * \param Si Pointer to Qmf input buffer.
+ * \param stride Stride factor for output data, 1 if none.
+ * \param timeSig (None-)Interleaved audio output data.
+ *
+ * \return Error status.
+ */
+SACDEC_ERROR CalculateSpaceSynthesisQmf(
+ const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr,
+ const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig);
+
+/**
+ * \brief Convert audio input data to qmf representation.
+ *
+ * \param hSpaceAnalysisQmf A Qmf Analysis Filterbank handle.
+ * \param timeSig (None-)Interleavd audio input data.
+ * \param Sr Pointer to Qmf output buffer.
+ * \param Si Pointer to Qmf output buffer.
+ *
+ * \return Error status.
+ */
+SACDEC_ERROR CalculateSpaceAnalysisQmf(
+ HANDLE_SPACE_ANALYSIS_QMF hSpaceAnalysisQmf, const PCM_MPS *timeSig,
+ FIXP_DBL *Sr, FIXP_DBL *Si);
+
+#endif /* SAC_QMF_H */
diff --git a/fdk-aac/libSACdec/src/sac_reshapeBBEnv.cpp b/fdk-aac/libSACdec/src/sac_reshapeBBEnv.cpp
new file mode 100644
index 0000000..87c0ac6
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_reshapeBBEnv.cpp
@@ -0,0 +1,680 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec guided envelope shaping
+
+*******************************************************************************/
+
+#include "sac_reshapeBBEnv.h"
+
+#include "sac_dec.h"
+#include "sac_bitdec.h"
+#include "sac_calcM1andM2.h"
+#include "sac_reshapeBBEnv.h"
+#include "sac_rom.h"
+
+#define INP_DRY_WET 0
+#define INP_DMX 1
+
+#define SF_SHAPE 1
+#define SF_DIV32 6
+#define SF_FACTOR_SLOT 5
+
+#define START_BB_ENV 0 /* 10 */
+#define END_BB_ENV 9 /* 18 */
+
+#define SF_ALPHA1 8
+#define SF_BETA1 4
+
+void initBBEnv(spatialDec *self, int initStatesFlag) {
+ INT ch, k;
+
+ for (ch = 0; ch < self->numOutputChannels; ch++) {
+ k = row2channelGES[self->treeConfig][ch];
+ self->row2channelDmxGES[ch] = k;
+ if (k == -1) continue;
+
+ switch (self->treeConfig) {
+ case TREE_212:
+ self->row2channelDmxGES[ch] = 0;
+ break;
+ default:;
+ }
+ }
+
+ if (initStatesFlag) {
+ for (k = 0; k < 2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS; k++) {
+ self->reshapeBBEnvState->normNrgPrev__FDK[k] =
+ FL2FXCONST_DBL(0.5f); /* 32768.f*32768.f */
+ self->reshapeBBEnvState->normNrgPrevSF[k] = DFRACT_BITS - 1;
+ self->reshapeBBEnvState->partNrgPrevSF[k] = 0;
+ self->reshapeBBEnvState->partNrgPrev2SF[k] = 0;
+ self->reshapeBBEnvState->frameNrgPrevSF[k] = 0;
+ }
+ }
+
+ self->reshapeBBEnvState->alpha__FDK =
+ FL2FXCONST_DBL(0.99637845575f); /* FDKexp(-64 / (0.4f * 44100)) */
+ self->reshapeBBEnvState->beta__FDK =
+ FL2FXCONST_DBL(0.96436909488f); /* FDKexp(-64 / (0.04f * 44100)) */
+}
+
+static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
+ FIXP_DBL *RESTRICT pImag,
+ FIXP_DBL *RESTRICT slotNrg, INT maxValSF,
+ INT hybBands) {
+ INT qs;
+ FIXP_DBL nrg;
+
+ /* qs = 12, 13, 14 */
+ slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ /* qs = 15 */
+ slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ /* qs = 16, 17 */
+ nrg = ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ slotNrg[4] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ /* qs = 18, 19, 20 */
+ nrg = ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ nrg += ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ slotNrg[5] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ /* qs = 21, 22 */
+ nrg = ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ slotNrg[6] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ /* qs = 23, 24 */
+ if (hybBands > 23) {
+ slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ /* qs = 25, 26, 29, 28, 29 */
+ nrg = ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ nrg += ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ nrg += ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ nrg += ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ slotNrg[7] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ /* qs = 30 ... min(41,hybBands-1) */
+ nrg = ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ for (qs = 31; qs < hybBands; qs++) {
+ nrg += ((fPow2Div2((*pReal++) << maxValSF) +
+ fPow2Div2((*pImag++) << maxValSF)) >>
+ (SF_FACTOR_SLOT - 1));
+ }
+ slotNrg[8] = nrg;
+ } else {
+ slotNrg[7] = (FIXP_DBL)0;
+ slotNrg[8] = (FIXP_DBL)0;
+ }
+}
+
+static inline INT getMaxValDmx(FIXP_DBL *RESTRICT pReal,
+ FIXP_DBL *RESTRICT pImag, INT cplxBands,
+ INT hybBands) {
+ INT qs, clz;
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+
+ for (qs = 12; qs < cplxBands; qs++) {
+ maxVal |= fAbs(pReal[qs]);
+ maxVal |= fAbs(pImag[qs]);
+ }
+ for (; qs < hybBands; qs++) {
+ maxVal |= fAbs(pReal[qs]);
+ }
+
+ clz = fixMax(0, CntLeadingZeros(maxVal) - 1);
+
+ return (clz);
+}
+
+static inline INT getMaxValDryWet(FIXP_DBL *RESTRICT pReal,
+ FIXP_DBL *RESTRICT pImag,
+ FIXP_DBL *RESTRICT pHybOutputRealDry,
+ FIXP_DBL *RESTRICT pHybOutputImagDry,
+ FIXP_DBL *RESTRICT pHybOutputRealWet,
+ FIXP_DBL *RESTRICT pHybOutputImagWet,
+ INT cplxBands, INT hybBands) {
+ INT qs, clz;
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+
+ for (qs = 12; qs < cplxBands; qs++) {
+ pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs];
+ maxVal |= fAbs(pReal[qs]);
+ pImag[qs] = pHybOutputImagDry[qs] + pHybOutputImagWet[qs];
+ maxVal |= fAbs(pImag[qs]);
+ }
+ for (; qs < hybBands; qs++) {
+ pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs];
+ maxVal |= fAbs(pReal[qs]);
+ }
+
+ clz = fixMax(0, CntLeadingZeros(maxVal) - 1);
+
+ return (clz);
+}
+
+static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry,
+ FIXP_DBL *RESTRICT slotAmp_wet,
+ FIXP_DBL *RESTRICT pHybOutputRealDry,
+ FIXP_DBL *RESTRICT pHybOutputImagDry,
+ FIXP_DBL *RESTRICT pHybOutputRealWet,
+ FIXP_DBL *RESTRICT pHybOutputImagWet, INT cplxBands,
+ INT hybBands) {
+ INT qs;
+ FIXP_DBL dry, wet;
+
+ dry = wet = FL2FXCONST_DBL(0.0f);
+ for (qs = 0; qs < cplxBands; qs++) {
+ dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]) +
+ fPow2Div2(pHybOutputImagDry[qs]));
+ wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]) +
+ fPow2Div2(pHybOutputImagWet[qs]));
+ }
+ for (; qs < hybBands; qs++) {
+ dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]));
+ wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]));
+ }
+ *slotAmp_dry = dry;
+ *slotAmp_wet = wet;
+}
+
+#if defined(__aarch64__)
+__attribute__((noinline))
+#endif
+static void
+shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry,
+ FIXP_DBL dryFac, INT scale, INT cplxBands, INT hybBands) {
+ INT qs;
+
+ if (scale == 0) {
+ for (qs = 0; qs < cplxBands; qs++) {
+ pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
+ pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac);
+ }
+ for (; qs < hybBands; qs++) {
+ pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
+ }
+ } else {
+ for (qs = 0; qs < cplxBands; qs++) {
+ pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale;
+ pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac) << scale;
+ }
+ for (; qs < hybBands; qs++) {
+ pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale;
+ }
+ }
+}
+
+static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
+ FIXP_DBL *pEnv, const SPATIAL_BS_FRAME *frame) {
+ INT ch, pb, prevChOffs;
+ INT clz, scale, scale_min, envSF;
+ INT scaleCur, scalePrev, commonScale;
+ INT slotNrgSF, partNrgSF, frameNrgSF;
+ INT *pPartNrgPrevSF, *pFrameNrgPrevSF;
+ INT *pNormNrgPrevSF, *pPartNrgPrev2SF;
+
+ FIXP_DBL maxVal, env, frameNrg, normNrg;
+ FIXP_DBL *pReal, *pImag;
+ FIXP_DBL *partNrg, *partNrgPrev;
+
+ C_ALLOC_SCRATCH_START(pScratchBuffer, FIXP_DBL,
+ (2 * 42 + MAX_PARAMETER_BANDS));
+ C_ALLOC_SCRATCH_START(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
+ C_ALLOC_SCRATCH_START(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
+
+ FIXP_DBL *slotNrg = pScratchBuffer + (2 * 42);
+
+ RESHAPE_BBENV_STATE *pBBEnvState = self->reshapeBBEnvState;
+
+ FIXP_DBL alpha = pBBEnvState->alpha__FDK;
+ /*FIXP_DBL alpha1 = (FL2FXCONST_DBL(1.0f) - alpha) << SF_ALPHA1;*/
+ FIXP_DBL alpha1 = ((FIXP_DBL)MAXVAL_DBL - alpha) << SF_ALPHA1;
+ FIXP_DBL beta = pBBEnvState->beta__FDK;
+ /*FIXP_DBL beta1 = (FL2FXCONST_DBL(1.0f) - beta) << SF_BETA1;*/
+ FIXP_DBL beta1 = ((FIXP_DBL)MAXVAL_DBL - beta) << SF_BETA1;
+
+ INT shapeActiv = 1;
+ INT hybBands = fixMin(42, self->hybridBands);
+ INT staticScale = self->staticDecScale;
+ INT cplxBands;
+ cplxBands = fixMin(42, self->hybridBands);
+
+ for (ch = start; ch < channels; ch++) {
+ if (inp == INP_DRY_WET) {
+ INT ch2 = row2channelGES[self->treeConfig][ch];
+ if (ch2 == -1) {
+ continue;
+ } else {
+ if (frame->tempShapeEnableChannelGES[ch2]) {
+ shapeActiv = 1;
+ } else {
+ shapeActiv = 0;
+ }
+ }
+ prevChOffs = ch;
+ pReal = pScratchBuffer;
+ pImag = pScratchBuffer + 42;
+ clz = getMaxValDryWet(
+ pReal, pImag, self->hybOutputRealDry__FDK[ch],
+ self->hybOutputImagDry__FDK[ch], self->hybOutputRealWet__FDK[ch],
+ self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
+ } else {
+ prevChOffs = ch + self->numOutputChannels;
+ pReal = self->hybInputReal__FDK[ch];
+ pImag = self->hybInputImag__FDK[ch];
+ clz = getMaxValDmx(pReal, pImag, cplxBands, hybBands);
+ }
+
+ partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
+ pPartNrgPrevSF = &pBBEnvState->partNrgPrevSF[prevChOffs];
+ pFrameNrgPrevSF = &pBBEnvState->frameNrgPrevSF[prevChOffs];
+ pNormNrgPrevSF = &pBBEnvState->normNrgPrevSF[prevChOffs];
+ pPartNrgPrev2SF = &pBBEnvState->partNrgPrev2SF[prevChOffs];
+
+ /* calculate slot energy */
+ {
+ getSlotNrgHQ(&pReal[12], &pImag[12], slotNrg, clz,
+ fixMin(42, self->hybridBands)); /* scale slotNrg:
+ 2*(staticScale-clz) +
+ SF_FACTOR_SLOT */
+ }
+
+ slotNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
+ frameNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
+
+ partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
+ pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1);
+ scalePrev = fixMax(fixMin(partNrgSF - pPartNrgPrevSF[0], DFRACT_BITS - 1),
+ -(DFRACT_BITS - 1));
+ scaleCur =
+ fixMax(fixMin(partNrgSF - slotNrgSF + SF_ALPHA1, DFRACT_BITS - 1),
+ -(DFRACT_BITS - 1));
+
+ maxVal = FL2FXCONST_DBL(0.0f);
+ frameNrg = FL2FXCONST_DBL(0.0f);
+ if ((scaleCur < 0) && (scalePrev < 0)) {
+ scaleCur = -scaleCur;
+ scalePrev = -scalePrev;
+ for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
+ partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
+ (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
+ << 1;
+ maxVal |= partNrg[pb];
+ frameNrg += slotNrg[pb] >> 3;
+ }
+ } else if ((scaleCur >= 0) && (scalePrev >= 0)) {
+ for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
+ partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
+ (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
+ << 1;
+ maxVal |= partNrg[pb];
+ frameNrg += slotNrg[pb] >> 3;
+ }
+ } else if ((scaleCur < 0) && (scalePrev >= 0)) {
+ scaleCur = -scaleCur;
+ for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
+ partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
+ (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
+ << 1;
+ maxVal |= partNrg[pb];
+ frameNrg += slotNrg[pb] >> 3;
+ }
+ } else { /* if ( (scaleCur >= 0) && (scalePrev < 0) ) */
+ scalePrev = -scalePrev;
+ for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
+ partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
+ (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
+ << 1;
+ maxVal |= partNrg[pb];
+ frameNrg += slotNrg[pb] >> 3;
+ }
+ }
+
+ /* frameNrg /= (END_BB_ENV - START_BB_ENV); 0.88888888888f =
+ * (1/(END_BB_ENV-START_BB_ENV)<<3; shift with 3 is compensated in loop
+ * above */
+ frameNrg = fMult(frameNrg, FL2FXCONST_DBL(0.88888888888f));
+
+ /* store scalefactor and headroom for part nrg prev */
+ pPartNrgPrevSF[0] = partNrgSF;
+ pPartNrgPrev2SF[0] = fixMax(0, CntLeadingZeros(maxVal) - 1);
+
+ commonScale = fixMax(frameNrgSF - SF_ALPHA1 + 1, pFrameNrgPrevSF[0] + 1);
+ scalePrev = fixMin(commonScale - pFrameNrgPrevSF[0], DFRACT_BITS - 1);
+ scaleCur = fixMin(commonScale - frameNrgSF + SF_ALPHA1, DFRACT_BITS - 1);
+ frameNrgSF = commonScale;
+
+ frameNrg = ((fMultDiv2(alpha1, frameNrg) >> scaleCur) +
+ (fMultDiv2(alpha, pBBEnvState->frameNrgPrev__FDK[prevChOffs]) >>
+ scalePrev))
+ << 1;
+
+ clz = fixMax(0, CntLeadingZeros(frameNrg) - 1);
+ pBBEnvState->frameNrgPrev__FDK[prevChOffs] = frameNrg << clz;
+ pFrameNrgPrevSF[0] = frameNrgSF - clz;
+
+ env = FL2FXCONST_DBL(0.0f);
+ scale = clz + partNrgSF - frameNrgSF;
+ scale_min = DFRACT_BITS - 1;
+ for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
+ if ((partNrg[pb] | slotNrg[pb]) != FL2FXCONST_DBL(0.0f)) {
+ INT s;
+ INT sc = 0;
+ INT sn = fixMax(0, CntLeadingZeros(slotNrg[pb]) - 1);
+ FIXP_DBL inv_sqrt = invSqrtNorm2(partNrg[pb], &sc);
+ FIXP_DBL res = fMult(slotNrg[pb] << sn, fPow2(inv_sqrt));
+
+ s = fixMax(0, CntLeadingZeros(res) - 1);
+ res = res << s;
+
+ sc = scale - (2 * sc - sn - s);
+ scale_min = fixMin(scale_min, sc);
+
+ resPb[pb] = res;
+ resPbSF[pb] = sc;
+ } else {
+ resPb[pb] = (FIXP_DBL)0;
+ resPbSF[pb] = 0;
+ }
+ }
+
+ scale_min = 4 - scale_min;
+
+ for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
+ INT sc = fixMax(fixMin(resPbSF[pb] + scale_min, DFRACT_BITS - 1),
+ -(DFRACT_BITS - 1));
+
+ if (sc < 0) {
+ env += resPb[pb] << (-sc);
+ } else {
+ env += resPb[pb] >> (sc);
+ }
+ }
+
+ env = fMultDiv2(env, pBBEnvState->frameNrgPrev__FDK[prevChOffs]);
+ envSF = slotNrgSF + scale_min + 1;
+
+ commonScale = fixMax(envSF - SF_BETA1 + 1, pNormNrgPrevSF[0] + 1);
+ scalePrev = fixMin(commonScale - pNormNrgPrevSF[0], DFRACT_BITS - 1);
+ scaleCur = fixMin(commonScale - envSF + SF_BETA1, DFRACT_BITS - 1);
+
+ normNrg = ((fMultDiv2(beta1, env) >> scaleCur) +
+ (fMultDiv2(beta, pBBEnvState->normNrgPrev__FDK[prevChOffs]) >>
+ scalePrev))
+ << 1;
+
+ clz = fixMax(0, CntLeadingZeros(normNrg) - 1);
+ pBBEnvState->normNrgPrev__FDK[prevChOffs] = normNrg << clz;
+ pNormNrgPrevSF[0] = commonScale - clz;
+
+ if (shapeActiv) {
+ if ((env | normNrg) != FL2FXCONST_DBL(0.0f)) {
+ INT sc, se, sn;
+ se = fixMax(0, CntLeadingZeros(env) - 1);
+ sc = commonScale + SF_DIV32 - envSF + se;
+ env = fMult(sqrtFixp((env << se) >> (sc & 0x1)),
+ invSqrtNorm2(normNrg, &sn));
+
+ sc = fixMin((sc >> 1) - sn, DFRACT_BITS - 1);
+ if (sc < 0) {
+ env <<= (-sc);
+ } else {
+ env >>= (sc);
+ }
+ }
+ /* env is scaled by SF_DIV32/2 bits */
+ }
+ pEnv[ch] = env;
+ }
+
+ C_ALLOC_SCRATCH_END(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
+ C_ALLOC_SCRATCH_END(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
+ C_ALLOC_SCRATCH_END(pScratchBuffer, FIXP_DBL, (2 * 42 + MAX_PARAMETER_BANDS));
+}
+
+void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
+ INT ts) {
+ INT ch, scale;
+ INT dryFacSF, slotAmpSF;
+ FIXP_DBL tmp, dryFac, envShape;
+ FIXP_DBL slotAmp_dry, slotAmp_wet, slotAmp_ratio;
+ FIXP_DBL envDry[MAX_OUTPUT_CHANNELS], envDmx[2];
+
+ INT cplxBands;
+ INT hybBands = self->hybridBands - 6;
+
+ cplxBands = self->hybridBands - 6;
+
+ /* extract downmix envelope(s) */
+ switch (self->treeConfig) {
+ default:
+ extractBBEnv(self, INP_DMX, 0, fMin(self->numInputChannels, 2), envDmx,
+ frame);
+ }
+
+ /* extract dry and wet envelopes */
+ extractBBEnv(self, INP_DRY_WET, 0, self->numOutputChannels, envDry, frame);
+
+ for (ch = 0; ch < self->numOutputChannels; ch++) {
+ INT ch2;
+
+ ch2 = row2channelGES[self->treeConfig][ch];
+
+ if (ch2 == -1) continue;
+
+ if (frame->tempShapeEnableChannelGES[ch2]) {
+ INT sc;
+
+ /* reshape dry and wet signals according to transmitted envelope */
+
+ /* De-quantize GES data */
+ FDK_ASSERT((frame->bsEnvShapeData[ch2][ts] >= 0) &&
+ (frame->bsEnvShapeData[ch2][ts] <= 4));
+ FDK_ASSERT((self->envQuantMode == 0) || (self->envQuantMode == 1));
+ envShape =
+ FX_CFG2FX_DBL(envShapeDataTable__FDK[frame->bsEnvShapeData[ch2][ts]]
+ [self->envQuantMode]);
+
+ /* get downmix channel */
+ ch2 = self->row2channelDmxGES[ch];
+
+ /* multiply ratio with dmx envelope; tmp is scaled by SF_DIV32/2+SF_SHAPE
+ * bits */
+ if (ch2 == 2) {
+ tmp = fMultDiv2(envShape, envDmx[0]) + fMultDiv2(envShape, envDmx[1]);
+ } else {
+ tmp = fMult(envShape, envDmx[ch2]);
+ }
+
+ /* weighting factors */
+ dryFacSF = slotAmpSF = 0;
+ dryFac = slotAmp_ratio = FL2FXCONST_DBL(0.0f);
+
+ /* dryFac will be scaled by dryFacSF bits */
+ if (envDry[ch] != FL2FXCONST_DBL(0.0f)) {
+ envDry[ch] = invSqrtNorm2(envDry[ch], &dryFacSF);
+ dryFac = fMultDiv2(tmp, fPow2Div2(envDry[ch])) << 2;
+ dryFacSF = SF_SHAPE + 2 * dryFacSF;
+ }
+
+ /* calculate slotAmp_dry and slotAmp_wet */
+ slotAmp(&slotAmp_dry, &slotAmp_wet, &self->hybOutputRealDry__FDK[ch][6],
+ &self->hybOutputImagDry__FDK[ch][6],
+ &self->hybOutputRealWet__FDK[ch][6],
+ &self->hybOutputImagWet__FDK[ch][6], cplxBands, hybBands);
+
+ /* slotAmp_ratio will be scaled by slotAmpSF bits */
+ if (slotAmp_dry != FL2FXCONST_DBL(0.0f)) {
+ sc = fixMax(0, CntLeadingZeros(slotAmp_wet) - 1);
+ sc = sc - (sc & 1);
+
+ slotAmp_wet = sqrtFixp(slotAmp_wet << sc);
+ slotAmp_dry = invSqrtNorm2(slotAmp_dry, &slotAmpSF);
+
+ slotAmp_ratio = fMult(slotAmp_wet, slotAmp_dry);
+ slotAmpSF = slotAmpSF - (sc >> 1);
+ }
+
+ /* calculate common scale factor */
+ scale =
+ fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3
+ bits to avoid overflows
+ when calculating dryFac */
+ dryFac = dryFac >> (scale - dryFacSF);
+ slotAmp_ratio = slotAmp_ratio >> (scale - slotAmpSF);
+
+ /* limit dryFac */
+ dryFac = fixMax(
+ FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1),
+ fMult(dryFac, slotAmp_ratio) - (slotAmp_ratio >> scale) +
+ (dryFac >> scale));
+ dryFac = fixMin(
+ FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1),
+ dryFac); /* reduce shift bits by 3, because upper
+ limit 4.0 is scaled with 3 bits */
+ scale = 2 * scale + 1;
+
+ /* improve precision for dryFac */
+ sc = fixMax(0, CntLeadingZeros(dryFac) - 1);
+ dryFac = dryFac << (INT)fixMin(scale, sc);
+ scale = scale - fixMin(scale, sc);
+
+ /* shaping */
+ shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6],
+ &self->hybOutputImagDry__FDK[ch][6], dryFac, scale, cplxBands,
+ hybBands);
+ }
+ }
+}
diff --git a/fdk-aac/libSACdec/src/sac_reshapeBBEnv.h b/fdk-aac/libSACdec/src/sac_reshapeBBEnv.h
new file mode 100644
index 0000000..1658530
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_reshapeBBEnv.h
@@ -0,0 +1,114 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec guided envelope shaping
+
+*******************************************************************************/
+
+#ifndef SAC_RESHAPEBBENV_H
+#define SAC_RESHAPEBBENV_H
+
+#include "sac_dec_interface.h"
+
+#define BB_ENV_SIZE 9 /* END_BB_ENV - START_BB_ENV */
+
+void initBBEnv(spatialDec *self, int initStatesFlag);
+void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
+ int ts);
+
+#endif
diff --git a/fdk-aac/libSACdec/src/sac_rom.cpp b/fdk-aac/libSACdec/src/sac_rom.cpp
new file mode 100644
index 0000000..4285b65
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_rom.cpp
@@ -0,0 +1,709 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec tables
+
+*******************************************************************************/
+
+#include "sac_rom.h"
+#include "sac_calcM1andM2.h"
+
+#define SCALE_CPC(a) (FL2FXCONST_CFG(a / (float)(1 << SCALE_PARAM_M1)))
+const FIXP_CFG dequantCPC__FDK[] = {
+ SCALE_CPC(-2.0f), SCALE_CPC(-1.9f), SCALE_CPC(-1.8f), SCALE_CPC(-1.7f),
+ SCALE_CPC(-1.6f), SCALE_CPC(-1.5f), SCALE_CPC(-1.4f), SCALE_CPC(-1.3f),
+ SCALE_CPC(-1.2f), SCALE_CPC(-1.1f), SCALE_CPC(-1.0f), SCALE_CPC(-0.9f),
+ SCALE_CPC(-0.8f), SCALE_CPC(-0.7f), SCALE_CPC(-0.6f), SCALE_CPC(-0.5f),
+ SCALE_CPC(-0.4f), SCALE_CPC(-0.3f), SCALE_CPC(-0.2f), SCALE_CPC(-0.1f),
+ SCALE_CPC(0.0f), SCALE_CPC(0.1f), SCALE_CPC(0.2f), SCALE_CPC(0.3f),
+ SCALE_CPC(0.4f), SCALE_CPC(0.5f), SCALE_CPC(0.6f), SCALE_CPC(0.7f),
+ SCALE_CPC(0.8f), SCALE_CPC(0.9f), SCALE_CPC(1.0f), SCALE_CPC(1.1f),
+ SCALE_CPC(1.2f), SCALE_CPC(1.3f), SCALE_CPC(1.4f), SCALE_CPC(1.5f),
+ SCALE_CPC(1.6f), SCALE_CPC(1.7f), SCALE_CPC(1.8f), SCALE_CPC(1.9f),
+ SCALE_CPC(2.0f), SCALE_CPC(2.1f), SCALE_CPC(2.2f), SCALE_CPC(2.3f),
+ SCALE_CPC(2.4f), SCALE_CPC(2.5f), SCALE_CPC(2.6f), SCALE_CPC(2.7f),
+ SCALE_CPC(2.8f), SCALE_CPC(2.9f), SCALE_CPC(3.0f)};
+
+#define SCALE_ICC(a) (FL2FXCONST_CFG(a))
+const FIXP_CFG dequantICC__FDK[8] = {
+ /*SCALE_ICC(1.00000f)*/ FX_DBL2FX_CFG(MAXVAL_DBL),
+ SCALE_ICC(0.9370f),
+ SCALE_ICC(0.84118f),
+ SCALE_ICC(0.60092f),
+ SCALE_ICC(0.36764f),
+ SCALE_ICC(0.0000f),
+ SCALE_ICC(-0.58900f),
+ SCALE_ICC(-0.9900f)};
+
+#define SCALE_CLD2(a) (FL2FXCONST_CFG(a / (float)(1 << 8)))
+const FIXP_CFG dequantCLD__FDK[31] = {
+ SCALE_CLD2(-150.0f), SCALE_CLD2(-45.0f), SCALE_CLD2(-40.0f),
+ SCALE_CLD2(-35.0f), SCALE_CLD2(-30.0f), SCALE_CLD2(-25.0f),
+ SCALE_CLD2(-22.0f), SCALE_CLD2(-19.0f), SCALE_CLD2(-16.0f),
+ SCALE_CLD2(-13.0f), SCALE_CLD2(-10.0f), SCALE_CLD2(-8.0f),
+ SCALE_CLD2(-6.0f), SCALE_CLD2(-4.0f), SCALE_CLD2(-2.0f),
+ SCALE_CLD2(0.0f), SCALE_CLD2(2.0f), SCALE_CLD2(4.0f),
+ SCALE_CLD2(6.0f), SCALE_CLD2(8.0f), SCALE_CLD2(10.0f),
+ SCALE_CLD2(13.0f), SCALE_CLD2(16.0f), SCALE_CLD2(19.0f),
+ SCALE_CLD2(22.0f), SCALE_CLD2(25.0f), SCALE_CLD2(30.0f),
+ SCALE_CLD2(35.0f), SCALE_CLD2(40.0f), SCALE_CLD2(45.0f),
+ SCALE_CLD2(150.0f)};
+
+#define SCALE_IPD(a) (FL2FXCONST_CFG(a / (float)(1 << IPD_SCALE)))
+const FIXP_CFG dequantIPD__FDK[16] = {
+ /* SCALE_IPD(0.000000000f), SCALE_IPD(0.392699082f),
+ SCALE_IPD(0.785398163f), SCALE_IPD(1.178097245f),
+ SCALE_IPD(1.570796327f), SCALE_IPD(1.963495408f),
+ SCALE_IPD(2.356194490f), SCALE_IPD(2.748893572f),
+ SCALE_IPD(3.141592654f), SCALE_IPD(3.534291735f),
+ SCALE_IPD(3.926990817f), SCALE_IPD(4.319689899f),
+ SCALE_IPD(4.712388980f), SCALE_IPD(5.105088062f),
+ SCALE_IPD(5.497787144f), SCALE_IPD(5.890486225f) */
+ SCALE_IPD(0.00000000000000f), SCALE_IPD(0.392699082f),
+ SCALE_IPD(0.78539816339745f), SCALE_IPD(1.178097245f),
+ SCALE_IPD(1.57079632679490f), SCALE_IPD(1.963495408f),
+ SCALE_IPD(2.35619449019234f), SCALE_IPD(2.748893572f),
+ SCALE_IPD(3.14159265358979f), SCALE_IPD(3.534291735f),
+ SCALE_IPD(3.92699081698724f), SCALE_IPD(4.319689899f),
+ SCALE_IPD(4.71238898038469f), SCALE_IPD(5.105088062f),
+ SCALE_IPD(5.49778714378214f), SCALE_IPD(5.890486225f)};
+
+#define SCALE_SPLIT_ANGLE(a) (FL2FXCONST_CFG(a / (float)(1 << IPD_SCALE)))
+/*
+ Generate table dequantIPD_CLD_ICC_splitAngle__FDK[16][31][8]:
+
+ #define ABS_THR ( 1e-9f * 32768 * 32768 )
+
+ float dequantICC[] =
+ {1.0000f,0.9370f,0.84118f,0.60092f,0.36764f,0.0f,-0.5890f,-0.9900f}; float
+ dequantCLD[] =
+ {-150.0,-45.0,-40.0,-35.0,-30.0,-25.0,-22.0,-19.0,-16.0,-13.0,-10.0, -8.0,
+ -6.0, -4.0, -2.0, 0.0, 2.0, 4.0, 6.0, 8.0,
+ 10.0, 13.0, 16.0, 19.0, 22.0, 25.0, 30.0, 35.0, 40.0, 45.0, 150.0 }; float
+ dequantIPD[] =
+ {0.f,0.392699082f,0.785398163f,1.178097245f,1.570796327f,1.963495408f,
+ 2.35619449f,2.748893572f,3.141592654f,3.534291735f,3.926990817f,
+ 4.319689899f,4.71238898f,5.105088062f,5.497787144f,5.890486225f};
+
+ for (ipdIdx=0; ipdIdx<16; ipdIdx++)
+ for (cldIdx=0; cldIdx<31; cldIdx++)
+ for (iccIdx=0; iccIdx<8; iccIdx++) {
+ ipd = dequantIPD[ipdIdx];
+ cld = dequantCLD[cldIdx];
+ icc = dequantICC[iccIdx];
+ iidLin = (float) pow(10.0f, cld / 20.0f);
+ iidLin2 = iidLin * iidLin;
+ iidLin21 = iidLin2 + 1.0f;
+ sinIpd = (float) sin(ipd);
+ cosIpd = (float) cos(ipd);
+ temp1 = 2.0f * icc * iidLin;
+ temp1c = temp1 * cosIpd;
+ ratio = (iidLin21 + temp1c) / (iidLin21 + temp1) + ABS_THR;
+ w2 = (float) pow(ratio, 0.25f);
+ w1 = 2.0f - w2;
+ dequantIPD_CLD_ICC_splitAngle__FDK[ipdIdx][cldIdx][iccIdx] = (float)
+ atan2(w2 * sinIpd, w1 * iidLin + w2 * cosIpd);
+ }
+*/
+
+#define SCALE_CLD(a) (FL2FXCONST_CFG(a))
+
+const FIXP_CFG dequantCLD_c_l[31] = {
+ SCALE_CLD(0.0000000316f),
+ SCALE_CLD(0.0056233243f),
+ SCALE_CLD(0.0099994997f),
+ SCALE_CLD(0.0177799836f),
+ SCALE_CLD(0.0316069759f),
+ SCALE_CLD(0.0561454296f),
+ SCALE_CLD(0.0791834071f),
+ SCALE_CLD(0.1115021780f),
+ SCALE_CLD(0.1565355062f),
+ SCALE_CLD(0.2184644639f),
+ SCALE_CLD(0.3015113473f),
+ SCALE_CLD(0.3698741496f),
+ SCALE_CLD(0.4480624795f),
+ SCALE_CLD(0.5336171389f),
+ SCALE_CLD(0.6219832301f),
+ SCALE_CLD(0.7071067691f),
+ SCALE_CLD(0.7830305696f),
+ SCALE_CLD(0.8457261920f),
+ SCALE_CLD(0.8940021992f),
+ SCALE_CLD(0.9290818572f),
+ SCALE_CLD(0.9534626007f),
+ SCALE_CLD(0.9758449197f),
+ SCALE_CLD(0.9876723289f),
+ SCALE_CLD(0.9937641621f),
+ SCALE_CLD(0.9968600869f),
+ SCALE_CLD(0.9984226227f),
+ SCALE_CLD(0.9995003939f),
+ SCALE_CLD(0.9998419285f),
+ SCALE_CLD(0.9999499917f),
+ SCALE_CLD(0.9999842048f),
+ /*SCALE_CLD(1.0000000000f)*/ FX_DBL2FX_CFG(MAXVAL_DBL)};
+
+#define SC_H(a) (FL2FXCONST_CFG(a))
+#define DATA_TYPE_H FIXP_CFG
+
+/* not correlated tables */
+const DATA_TYPE_H H11_nc[31][8] = {
+ {SC_H(0.0000000316f), SC_H(0.0000000296f), SC_H(0.0000000266f),
+ SC_H(0.0000000190f), SC_H(0.0000000116f), SC_H(0.0000000000f),
+ SC_H(-0.0000000186f), SC_H(-0.0000000313f)},
+ {SC_H(0.0056233243f), SC_H(0.0052728835f), SC_H(0.0047394098f),
+ SC_H(0.0033992692f), SC_H(0.0020946222f), SC_H(0.0000316215f),
+ SC_H(-0.0032913829f), SC_H(-0.0055664564f)},
+ {SC_H(0.0099994997f), SC_H(0.0093815643f), SC_H(0.0084402543f),
+ SC_H(0.0060722125f), SC_H(0.0037622179f), SC_H(0.0000999898f),
+ SC_H(-0.0058238208f), SC_H(-0.0098974844f)},
+ {SC_H(0.0177799836f), SC_H(0.0166974831f), SC_H(0.0150465844f),
+ SC_H(0.0108831404f), SC_H(0.0068073822f), SC_H(0.0003161267f),
+ SC_H(-0.0102626514f), SC_H(-0.0175957214f)},
+ {SC_H(0.0316069759f), SC_H(0.0297324844f), SC_H(0.0268681273f),
+ SC_H(0.0196138974f), SC_H(0.0124691967f), SC_H(0.0009989988f),
+ SC_H(-0.0179452803f), SC_H(-0.0312700421f)},
+ {SC_H(0.0561454296f), SC_H(0.0529650487f), SC_H(0.0480896905f),
+ SC_H(0.0356564634f), SC_H(0.0232860073f), SC_H(0.0031523081f),
+ SC_H(-0.0309029408f), SC_H(-0.0555154830f)},
+ {SC_H(0.0791834071f), SC_H(0.0748842582f), SC_H(0.0682762116f),
+ SC_H(0.0513241664f), SC_H(0.0343080349f), SC_H(0.0062700072f),
+ SC_H(-0.0422340371f), SC_H(-0.0782499388f)},
+ {SC_H(0.1115021780f), SC_H(0.1057924852f), SC_H(0.0969873071f),
+ SC_H(0.0742305145f), SC_H(0.0511277616f), SC_H(0.0124327289f),
+ SC_H(-0.0566596612f), SC_H(-0.1100896299f)},
+ {SC_H(0.1565355062f), SC_H(0.1491366178f), SC_H(0.1376826316f),
+ SC_H(0.1078186408f), SC_H(0.0770794004f), SC_H(0.0245033558f),
+ SC_H(-0.0735980421f), SC_H(-0.1543303132f)},
+ {SC_H(0.2184644639f), SC_H(0.2091979682f), SC_H(0.1947948188f),
+ SC_H(0.1568822265f), SC_H(0.1172478944f), SC_H(0.0477267131f),
+ SC_H(-0.0899507254f), SC_H(-0.2148526460f)},
+ {SC_H(0.3015113473f), SC_H(0.2904391289f), SC_H(0.2731673419f),
+ SC_H(0.2273024023f), SC_H(0.1786239147f), SC_H(0.0909090787f),
+ SC_H(-0.0964255333f), SC_H(-0.2951124907f)},
+ {SC_H(0.3698741496f), SC_H(0.3578284085f), SC_H(0.3390066922f),
+ SC_H(0.2888108492f), SC_H(0.2351117432f), SC_H(0.1368068755f),
+ SC_H(-0.0850296095f), SC_H(-0.3597966135f)},
+ {SC_H(0.4480624795f), SC_H(0.4354025424f), SC_H(0.4156077504f),
+ SC_H(0.3627120256f), SC_H(0.3058823943f), SC_H(0.2007599771f),
+ SC_H(-0.0484020934f), SC_H(-0.4304940701f)},
+ {SC_H(0.5336171389f), SC_H(0.5208471417f), SC_H(0.5008935928f),
+ SC_H(0.4476420581f), SC_H(0.3905044496f), SC_H(0.2847472429f),
+ SC_H(0.0276676007f), SC_H(-0.4966579080f)},
+ {SC_H(0.6219832301f), SC_H(0.6096963882f), SC_H(0.5905415416f),
+ SC_H(0.5396950245f), SC_H(0.4856070578f), SC_H(0.3868631124f),
+ SC_H(0.1531652957f), SC_H(-0.5045361519f)},
+ {SC_H(0.7071067691f), SC_H(0.6958807111f), SC_H(0.6784504056f),
+ SC_H(0.6326373219f), SC_H(0.5847306848f), SC_H(0.4999999702f),
+ SC_H(0.3205464482f), SC_H(0.0500000045f)},
+ {SC_H(0.7830305696f), SC_H(0.7733067870f), SC_H(0.7582961321f),
+ SC_H(0.7194055915f), SC_H(0.6797705293f), SC_H(0.6131368876f),
+ SC_H(0.4997332692f), SC_H(0.6934193969f)},
+ {SC_H(0.8457261920f), SC_H(0.8377274871f), SC_H(0.8254694939f),
+ SC_H(0.7942851782f), SC_H(0.7635439038f), SC_H(0.7152527571f),
+ SC_H(0.6567122936f), SC_H(0.8229061961f)},
+ {SC_H(0.8940021992f), SC_H(0.8877248168f), SC_H(0.8781855106f),
+ SC_H(0.8544237614f), SC_H(0.8318918347f), SC_H(0.7992399335f),
+ SC_H(0.7751275301f), SC_H(0.8853276968f)},
+ {SC_H(0.9290818572f), SC_H(0.9243524075f), SC_H(0.9172304869f),
+ SC_H(0.8998877406f), SC_H(0.8841174841f), SC_H(0.8631930947f),
+ SC_H(0.8565139771f), SC_H(0.9251161218f)},
+ {SC_H(0.9534626007f), SC_H(0.9500193000f), SC_H(0.9448821545f),
+ SC_H(0.9326565266f), SC_H(0.9220023751f), SC_H(0.9090909362f),
+ SC_H(0.9096591473f), SC_H(0.9514584541f)},
+ {SC_H(0.9758449197f), SC_H(0.9738122821f), SC_H(0.9708200693f),
+ SC_H(0.9639287591f), SC_H(0.9582763910f), SC_H(0.9522733092f),
+ SC_H(0.9553207159f), SC_H(0.9750427008f)},
+ {SC_H(0.9876723289f), SC_H(0.9865267277f), SC_H(0.9848603010f),
+ SC_H(0.9811310172f), SC_H(0.9782302976f), SC_H(0.9754966497f),
+ SC_H(0.9779621363f), SC_H(0.9873252511f)},
+ {SC_H(0.9937641621f), SC_H(0.9931397438f), SC_H(0.9922404289f),
+ SC_H(0.9902750254f), SC_H(0.9888116717f), SC_H(0.9875672460f),
+ SC_H(0.9891131520f), SC_H(0.9936066866f)},
+ {SC_H(0.9968600869f), SC_H(0.9965277910f), SC_H(0.9960530400f),
+ SC_H(0.9950347543f), SC_H(0.9943022728f), SC_H(0.9937300086f),
+ SC_H(0.9946073294f), SC_H(0.9967863560f)},
+ {SC_H(0.9984226227f), SC_H(0.9982488155f), SC_H(0.9980020523f),
+ SC_H(0.9974802136f), SC_H(0.9971146584f), SC_H(0.9968476892f),
+ SC_H(0.9973216057f), SC_H(0.9983873963f)},
+ {SC_H(0.9995003939f), SC_H(0.9994428754f), SC_H(0.9993617535f),
+ SC_H(0.9991930723f), SC_H(0.9990783334f), SC_H(0.9990010262f),
+ SC_H(0.9991616607f), SC_H(0.9994897842f)},
+ {SC_H(0.9998419285f), SC_H(0.9998232722f), SC_H(0.9997970462f),
+ SC_H(0.9997430444f), SC_H(0.9997069836f), SC_H(0.9996838570f),
+ SC_H(0.9997364879f), SC_H(0.9998386502f)},
+ {SC_H(0.9999499917f), SC_H(0.9999440312f), SC_H(0.9999356270f),
+ SC_H(0.9999184012f), SC_H(0.9999070764f), SC_H(0.9998999834f),
+ SC_H(0.9999169707f), SC_H(0.9999489784f)},
+ {SC_H(0.9999842048f), SC_H(0.9999822974f), SC_H(0.9999796152f),
+ SC_H(0.9999741912f), SC_H(0.9999706149f), SC_H(0.9999684095f),
+ SC_H(0.9999738336f), SC_H(0.9999839067f)},
+ /* { SC_H( 1.0000000000f), SC_H( 1.0000000000f), SC_H( 1.0000000000f),
+ SC_H( 1.0000000000f), SC_H( 1.0000000000f), SC_H( 1.0000000000f),
+ SC_H( 1.0000000000f), SC_H( 1.0000000000f)} */
+ {FX_DBL2FX_CFG(MAXVAL_DBL), FX_DBL2FX_CFG(MAXVAL_DBL),
+ FX_DBL2FX_CFG(MAXVAL_DBL), FX_DBL2FX_CFG(MAXVAL_DBL),
+ FX_DBL2FX_CFG(MAXVAL_DBL), FX_DBL2FX_CFG(MAXVAL_DBL),
+ FX_DBL2FX_CFG(MAXVAL_DBL), FX_DBL2FX_CFG(MAXVAL_DBL)}};
+const DATA_TYPE_H H12_nc[31][8] = {
+ {SC_H(0.0000000000f), SC_H(0.0000000110f), SC_H(0.0000000171f),
+ SC_H(0.0000000253f), SC_H(0.0000000294f), SC_H(0.0000000316f),
+ SC_H(0.0000000256f), SC_H(0.0000000045f)},
+ {SC_H(0.0000000000f), SC_H(0.0019540924f), SC_H(0.0030265113f),
+ SC_H(0.0044795922f), SC_H(0.0052186525f), SC_H(0.0056232354f),
+ SC_H(0.0045594489f), SC_H(0.0007977085f)},
+ {SC_H(0.0000000000f), SC_H(0.0034606720f), SC_H(0.0053620986f),
+ SC_H(0.0079446984f), SC_H(0.0092647560f), SC_H(0.0099989995f),
+ SC_H(0.0081285369f), SC_H(0.0014247064f)},
+ {SC_H(0.0000000000f), SC_H(0.0061091618f), SC_H(0.0094724922f),
+ SC_H(0.0140600521f), SC_H(0.0164252054f), SC_H(0.0177771728f),
+ SC_H(0.0145191532f), SC_H(0.0025531140f)},
+ {SC_H(0.0000000000f), SC_H(0.0107228858f), SC_H(0.0166464616f),
+ SC_H(0.0247849934f), SC_H(0.0290434174f), SC_H(0.0315911844f),
+ SC_H(0.0260186065f), SC_H(0.0046027615f)},
+ {SC_H(0.0000000000f), SC_H(0.0186282862f), SC_H(0.0289774220f),
+ SC_H(0.0433696397f), SC_H(0.0510888547f), SC_H(0.0560568646f),
+ SC_H(0.0468755551f), SC_H(0.0083869267f)},
+ {SC_H(0.0000000000f), SC_H(0.0257363543f), SC_H(0.0401044972f),
+ SC_H(0.0602979437f), SC_H(0.0713650510f), SC_H(0.0789347738f),
+ SC_H(0.0669798329f), SC_H(0.0121226767f)},
+ {SC_H(0.0000000000f), SC_H(0.0352233723f), SC_H(0.0550108925f),
+ SC_H(0.0832019597f), SC_H(0.0990892947f), SC_H(0.1108068749f),
+ SC_H(0.0960334241f), SC_H(0.0176920593f)},
+ {SC_H(0.0000000000f), SC_H(0.0475566536f), SC_H(0.0744772255f),
+ SC_H(0.1134835035f), SC_H(0.1362429112f), SC_H(0.1546057910f),
+ SC_H(0.1381545961f), SC_H(0.0261824392f)},
+ {SC_H(0.0000000000f), SC_H(0.0629518181f), SC_H(0.0989024863f),
+ SC_H(0.1520351619f), SC_H(0.1843357086f), SC_H(0.2131874412f),
+ SC_H(0.1990868896f), SC_H(0.0395608991f)},
+ {SC_H(0.0000000000f), SC_H(0.0809580907f), SC_H(0.1276271492f),
+ SC_H(0.1980977356f), SC_H(0.2429044843f), SC_H(0.2874797881f),
+ SC_H(0.2856767476f), SC_H(0.0617875643f)},
+ {SC_H(0.0000000000f), SC_H(0.0936254337f), SC_H(0.1479234397f),
+ SC_H(0.2310739607f), SC_H(0.2855334580f), SC_H(0.3436433673f),
+ SC_H(0.3599678576f), SC_H(0.0857512727f)},
+ {SC_H(0.0000000000f), SC_H(0.1057573780f), SC_H(0.1674221754f),
+ SC_H(0.2630588412f), SC_H(0.3274079263f), SC_H(0.4005688727f),
+ SC_H(0.4454404712f), SC_H(0.1242370531f)},
+ {SC_H(0.0000000000f), SC_H(0.1160409302f), SC_H(0.1839915067f),
+ SC_H(0.2904545665f), SC_H(0.3636667728f), SC_H(0.4512939751f),
+ SC_H(0.5328993797f), SC_H(0.1951362640f)},
+ {SC_H(0.0000000000f), SC_H(0.1230182052f), SC_H(0.1952532977f),
+ SC_H(0.3091802597f), SC_H(0.3886501491f), SC_H(0.4870318770f),
+ SC_H(0.6028295755f), SC_H(0.3637395203f)},
+ {SC_H(0.0000000000f), SC_H(0.1254990250f), SC_H(0.1992611140f),
+ SC_H(0.3158638775f), SC_H(0.3976053298f), SC_H(0.5000000000f),
+ SC_H(0.6302776933f), SC_H(0.7053368092f)},
+ {SC_H(0.0000000000f), SC_H(0.1230182052f), SC_H(0.1952533126f),
+ SC_H(0.3091802597f), SC_H(0.3886501491f), SC_H(0.4870319068f),
+ SC_H(0.6028295755f), SC_H(0.3637394905f)},
+ {SC_H(0.0000000000f), SC_H(0.1160409302f), SC_H(0.1839915216f),
+ SC_H(0.2904545665f), SC_H(0.3636668026f), SC_H(0.4512939751f),
+ SC_H(0.5328993797f), SC_H(0.1951362044f)},
+ {SC_H(0.0000000000f), SC_H(0.1057573855f), SC_H(0.1674221754f),
+ SC_H(0.2630588710f), SC_H(0.3274079263f), SC_H(0.4005688727f),
+ SC_H(0.4454405010f), SC_H(0.1242370382f)},
+ {SC_H(0.0000000000f), SC_H(0.0936254337f), SC_H(0.1479234397f),
+ SC_H(0.2310739607f), SC_H(0.2855334580f), SC_H(0.3436433673f),
+ SC_H(0.3599678576f), SC_H(0.0857512653f)},
+ {SC_H(0.0000000000f), SC_H(0.0809580907f), SC_H(0.1276271492f),
+ SC_H(0.1980977207f), SC_H(0.2429044843f), SC_H(0.2874797881f),
+ SC_H(0.2856767476f), SC_H(0.0617875606f)},
+ {SC_H(0.0000000000f), SC_H(0.0629518107f), SC_H(0.0989024863f),
+ SC_H(0.1520351619f), SC_H(0.1843357235f), SC_H(0.2131874412f),
+ SC_H(0.1990868896f), SC_H(0.0395609401f)},
+ {SC_H(0.0000000000f), SC_H(0.0475566462f), SC_H(0.0744772255f),
+ SC_H(0.1134835184f), SC_H(0.1362429112f), SC_H(0.1546057761f),
+ SC_H(0.1381545961f), SC_H(0.0261824802f)},
+ {SC_H(0.0000000000f), SC_H(0.0352233797f), SC_H(0.0550108962f),
+ SC_H(0.0832019448f), SC_H(0.0990892798f), SC_H(0.1108068526f),
+ SC_H(0.0960334465f), SC_H(0.0176920686f)},
+ {SC_H(0.0000000000f), SC_H(0.0257363524f), SC_H(0.0401044935f),
+ SC_H(0.0602979474f), SC_H(0.0713650808f), SC_H(0.0789347589f),
+ SC_H(0.0669797957f), SC_H(0.0121226516f)},
+ {SC_H(0.0000000000f), SC_H(0.0186282881f), SC_H(0.0289774258f),
+ SC_H(0.0433696248f), SC_H(0.0510888547f), SC_H(0.0560568906f),
+ SC_H(0.0468755886f), SC_H(0.0083869714f)},
+ {SC_H(0.0000000000f), SC_H(0.0107228830f), SC_H(0.0166464727f),
+ SC_H(0.0247849822f), SC_H(0.0290434249f), SC_H(0.0315911621f),
+ SC_H(0.0260186475f), SC_H(0.0046027377f)},
+ {SC_H(0.0000000000f), SC_H(0.0061091576f), SC_H(0.0094724894f),
+ SC_H(0.0140600465f), SC_H(0.0164251942f), SC_H(0.0177771524f),
+ SC_H(0.0145191504f), SC_H(0.0025530567f)},
+ {SC_H(0.0000000000f), SC_H(0.0034606743f), SC_H(0.0053620976f),
+ SC_H(0.0079446994f), SC_H(0.0092647672f), SC_H(0.0099990256f),
+ SC_H(0.0081285043f), SC_H(0.0014247177f)},
+ {SC_H(0.0000000000f), SC_H(0.0019540912f), SC_H(0.0030265225f),
+ SC_H(0.0044795908f), SC_H(0.0052186381f), SC_H(0.0056232223f),
+ SC_H(0.0045594289f), SC_H(0.0007977359f)},
+ {SC_H(0.0000000000f), SC_H(0.0000000149f), SC_H(0.0000000298f),
+ SC_H(0.0000000298f), SC_H(0.0000000000f), SC_H(0.0000000596f),
+ SC_H(0.0000000000f), SC_H(0.0000000000f)}};
+
+/*
+ for (i=0; i<31; i++) {
+ cld = dequantCLD[i];
+ val = (float)(FDKexp(cld/dbe)/(1+FDKexp(cld/dbe)));
+ val = (float)(dbe*FDKlog(val));
+ }
+*/
+#define SCALE_CLD_C1C2(a) (FL2FXCONST_DBL(a / (float)(1 << SF_CLD_C1C2)))
+const FIXP_DBL dequantCLD_c1[31] = {SCALE_CLD_C1C2(-1.5000000000000000e+002f),
+ SCALE_CLD_C1C2(-4.5000137329101563e+001f),
+ SCALE_CLD_C1C2(-4.0000434875488281e+001f),
+ SCALE_CLD_C1C2(-3.5001373291015625e+001f),
+ SCALE_CLD_C1C2(-3.0004341125488281e+001f),
+ SCALE_CLD_C1C2(-2.5013711929321289e+001f),
+ SCALE_CLD_C1C2(-2.2027315139770508e+001f),
+ SCALE_CLD_C1C2(-1.9054332733154297e+001f),
+ SCALE_CLD_C1C2(-1.6107742309570313e+001f),
+ SCALE_CLD_C1C2(-1.3212384223937988e+001f),
+ SCALE_CLD_C1C2(-1.0413927078247070e+001f),
+ SCALE_CLD_C1C2(-8.6389207839965820e+000f),
+ SCALE_CLD_C1C2(-6.9732279777526855e+000f),
+ SCALE_CLD_C1C2(-5.4554042816162109e+000f),
+ SCALE_CLD_C1C2(-4.1244258880615234e+000f),
+ SCALE_CLD_C1C2(-3.0102999210357666e+000f),
+ SCALE_CLD_C1C2(-2.1244258880615234e+000f),
+ SCALE_CLD_C1C2(-1.4554045200347900e+000f),
+ SCALE_CLD_C1C2(-9.7322785854339600e-001f),
+ SCALE_CLD_C1C2(-6.3892036676406860e-001f),
+ SCALE_CLD_C1C2(-4.1392669081687927e-001f),
+ SCALE_CLD_C1C2(-2.1238386631011963e-001f),
+ SCALE_CLD_C1C2(-1.0774217545986176e-001f),
+ SCALE_CLD_C1C2(-5.4333221167325974e-002f),
+ SCALE_CLD_C1C2(-2.7315950021147728e-002f),
+ SCALE_CLD_C1C2(-1.3711934909224510e-002f),
+ SCALE_CLD_C1C2(-4.3406565673649311e-003f),
+ SCALE_CLD_C1C2(-1.3732088264077902e-003f),
+ SCALE_CLD_C1C2(-4.3438826105557382e-004f),
+ SCALE_CLD_C1C2(-1.3745666365139186e-004f),
+ SCALE_CLD_C1C2(0.0000000000000000e+000f)};
+
+/* sac_stp */
+/* none scaled */
+const FIXP_CFG BP__FDK[] = {FL2FXCONST_CFG(0.73919999599457),
+ FL2FXCONST_CFG(0.97909998893738),
+ FL2FXCONST_CFG(0.99930000305176)};
+
+/* scaled with 26 bits */
+const FIXP_CFG BP_GF__FDK[] = {
+ FL2FXCONST_CFG(0.00000000643330), FL2FXCONST_CFG(0.00004396850232),
+ FL2FXCONST_CFG(0.00087456948552), FL2FXCONST_CFG(0.00474648220243),
+ FL2FXCONST_CFG(0.01717987244800), FL2FXCONST_CFG(0.04906742491073),
+ FL2FXCONST_CFG(0.10569518656729), FL2FXCONST_CFG(0.21165767592653),
+ FL2FXCONST_CFG(0.36036762478024), FL2FXCONST_CFG(0.59894182766948),
+ FL2FXCONST_CFG(0.81641678929129), FL2FXCONST_CFG(0.97418481133397),
+ FL2FXCONST_CFG(0.99575411610845), FL2FXCONST_CFG(0.88842666281361),
+ FL2FXCONST_CFG(0.79222317063736), FL2FXCONST_CFG(0.70828604318604),
+ FL2FXCONST_CFG(0.66395054816338), FL2FXCONST_CFG(0.64633739516952),
+ FL2FXCONST_CFG(0.66098278185255)};
+
+/* sac_bitdec */
+const INT samplingFreqTable[16] = {96000, 88200, 64000, 48000, 44100, 32000,
+ 24000, 22050, 16000, 12000, 11025, 8000,
+ 7350, 0, 0, 0};
+
+const UCHAR freqResTable[] = {0, 28, 20, 14, 10, 7, 5, 4};
+
+const UCHAR freqResTable_LD[] = {0, 23, 15, 12, 9, 7, 5, 4};
+
+const UCHAR tempShapeChanTable[][8] = {{5, 5, 4, 6, 6, 4, 4, 2},
+ {5, 5, 5, 7, 7, 4, 4, 2}};
+
+const TREEPROPERTIES treePropertyTable[] = {
+ {1, 6, 5, 0, {0, 0, 0, 0, 1}}, {1, 6, 5, 0, {0, 0, 1, 0, 0}},
+ {2, 6, 3, 1, {1, 0, 0, 0, 0}}, {2, 8, 5, 1, {1, 0, 0, 0, 0}},
+ {2, 8, 5, 1, {1, 0, 0, 0, 0}}, {6, 8, 2, 0, {0, 0, 0, 0, 0}},
+ {6, 8, 2, 0, {0, 0, 0, 0, 0}}, {1, 2, 1, 0, {0, 0, 0, 0, 0}}};
+
+const SCHAR kernels_4_to_71[MAX_HYBRID_BANDS] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
+
+const SCHAR kernels_5_to_71[MAX_HYBRID_BANDS] = {
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
+
+const SCHAR kernels_7_to_71[MAX_HYBRID_BANDS] = {
+ 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
+
+const SCHAR kernels_10_to_71[MAX_HYBRID_BANDS] = {
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 7, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
+
+const SCHAR kernels_14_to_71[MAX_HYBRID_BANDS] = {
+ 0, 0, 0, 0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8,
+ 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
+
+const SCHAR kernels_20_to_71[MAX_HYBRID_BANDS] = {
+ 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19};
+
+const SCHAR kernels_28_to_71[MAX_HYBRID_BANDS] = {
+ 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, 22, 23,
+ 23, 23, 23, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 26, 26, 26,
+ 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27};
+
+const SCHAR kernels_4_to_64[MAX_HYBRID_BANDS] = {
+ 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
+
+const SCHAR kernels_5_to_64[MAX_HYBRID_BANDS] = {
+ 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
+
+const SCHAR kernels_7_to_64[MAX_HYBRID_BANDS] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
+
+const SCHAR kernels_9_to_64[MAX_HYBRID_BANDS] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
+
+const SCHAR kernels_12_to_64[MAX_HYBRID_BANDS] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 9,
+ 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11};
+
+const SCHAR kernels_15_to_64[MAX_HYBRID_BANDS] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12,
+ 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14};
+
+const SCHAR kernels_23_to_64[MAX_HYBRID_BANDS] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13, 14, 14, 15,
+ 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20,
+ 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22};
+
+const UCHAR mapping_15_to_23[MAX_PARAMETER_BANDS_LD] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10,
+ 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14};
+
+const UCHAR mapping_12_to_23[MAX_PARAMETER_BANDS_LD] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11};
+
+const UCHAR mapping_9_to_23[MAX_PARAMETER_BANDS_LD] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8};
+
+const UCHAR mapping_7_to_23[MAX_PARAMETER_BANDS_LD] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6};
+
+const UCHAR mapping_5_to_23[MAX_PARAMETER_BANDS_LD] = {
+ 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4};
+
+const UCHAR mapping_4_to_23[MAX_PARAMETER_BANDS_LD] = {
+ 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3};
+
+const FIXP_CFG clipGainTable__FDK[] = {
+ /*CLIP_PROTECT_GAIN_0(1.000000f)*/ FX_DBL2FX_CFG(MAXVAL_DBL),
+ CLIP_PROTECT_GAIN_1(1.189207f),
+ CLIP_PROTECT_GAIN_1(1.414213f),
+ CLIP_PROTECT_GAIN_1(1.681792f),
+ /*CLIP_PROTECT_GAIN_1(2.000000f)*/ FX_DBL2FX_CFG(MAXVAL_DBL),
+ CLIP_PROTECT_GAIN_2(2.378414f),
+ CLIP_PROTECT_GAIN_2(2.828427f),
+ /*CLIP_PROTECT_GAIN_2(4.000000f)*/ FX_DBL2FX_CFG(MAXVAL_DBL)};
+
+const UCHAR clipGainSFTable__FDK[] = {0, 1, 1, 1, 1, 2, 2, 2};
+
+const UCHAR pbStrideTable[] = {1, 2, 5, 28};
+
+const int smgTimeTable[] = {64, 128, 256, 512};
+
+/* table is scaled by factor 0.5 */
+const FIXP_CFG envShapeDataTable__FDK[5][2] = {
+ {FL2FXCONST_CFG(0.25000000000000f), FL2FXCONST_CFG(0.25000000000000f)},
+ {FL2FXCONST_CFG(0.35355339059327f), FL2FXCONST_CFG(0.31498026247372f)},
+ {FL2FXCONST_CFG(0.50000000000000f), FL2FXCONST_CFG(0.39685026299205f)},
+ {FL2FXCONST_CFG(0.70710678118655f), FL2FXCONST_CFG(0.50000000000000f)},
+ {/*FL2FXCONST_CFG( 1.00000000000000f)*/ FX_DBL2FX_CFG(MAXVAL_DBL),
+ FL2FXCONST_CFG(0.62996052494744f)}};
+
+/* sac_calcM1andM2 */
+const SCHAR row2channelSTP[][MAX_M2_INPUT] = {{0, 1}, {0, 3}, {0, 2}, {0, 4},
+ {0, 4}, {0, 2}, {-1, 2}, {0, 1}};
+
+const SCHAR row2channelGES[][MAX_M2_INPUT] = {{0, 1}, {0, 3}, {0, 3}, {0, 5},
+ {0, 5}, {0, 2}, {-1, 2}, {0, 1}};
+
+const SCHAR row2residual[][MAX_M2_INPUT] = {{-1, 0}, {-1, 0}, {-1, -1},
+ {-1, -1}, {-1, -1}, {-1, -1},
+ {-1, -1}, {-1, 0}};
+
+/*******************************************************************************
+ Functionname: sac_getCLDValues
+ *******************************************************************************
+
+ Description: Get CLD values from table index.
+
+ Arguments:
+ index: Table index
+ *cu, *cl : Pointer to locations where resulting values will be written to.
+
+ Return: nothing
+
+*******************************************************************************/
+void SpatialDequantGetCLDValues(int index, FIXP_DBL* cu, FIXP_DBL* cl) {
+ *cu = FX_CFG2FX_DBL(dequantCLD_c_l[index]);
+ *cl = FX_CFG2FX_DBL(dequantCLD_c_l[31 - 1 - index]);
+}
+
+void SpatialDequantGetCLD2Values(int idx, FIXP_DBL* x) {
+ *x = FX_CFG2FX_DBL(dequantCLD__FDK[idx]);
+}
diff --git a/fdk-aac/libSACdec/src/sac_rom.h b/fdk-aac/libSACdec/src/sac_rom.h
new file mode 100644
index 0000000..d366fb6
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_rom.h
@@ -0,0 +1,230 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec tables
+
+*******************************************************************************/
+
+#ifndef SAC_ROM_H
+#define SAC_ROM_H
+
+#include "FDK_archdef.h"
+#include "sac_dec_interface.h"
+
+#include "huff_nodes.h"
+#include "sac_bitdec.h"
+#include "machine_type.h"
+
+/* Global ROM table data type: */
+#ifndef ARCH_PREFER_MULT_32x32
+#define FIXP_CFG FIXP_SGL
+#define FX_CFG2FX_DBL FX_SGL2FX_DBL
+#define FX_CFG2FX_SGL
+#define CFG(a) (FX_DBL2FXCONST_SGL(a))
+#define FL2FXCONST_CFG FL2FXCONST_SGL
+#define FX_DBL2FX_CFG(x) FX_DBL2FX_SGL((FIXP_DBL)(x))
+#else
+#define FIXP_CFG FIXP_DBL
+#define FX_CFG2FX_DBL
+#define FX_CFG2FX_SGL FX_DBL2FX_SGL
+#define CFG(a) FIXP_DBL(a)
+#define FL2FXCONST_CFG FL2FXCONST_DBL
+#define FX_DBL2FX_CFG(x) ((FIXP_DBL)(x))
+#endif
+
+/* others */
+#define SCALE_INV_ICC (2)
+#define G_dd_SCALE (2)
+
+#define QCC_SCALE 1
+#define M1M2_DATA FIXP_DBL
+#ifndef ARCH_PREFER_MULT_32x32
+#define M1M2_CDATA FIXP_SGL
+#define M1M2_CDATA2FX_DBL(a) FX_SGL2FX_DBL(a)
+#define FX_DBL2M1M2_CDATA(a) FX_DBL2FX_SGL(a)
+#else
+#define M1M2_CDATA FIXP_DBL
+#define M1M2_CDATA2FX_DBL(a) (a)
+#define FX_DBL2M1M2_CDATA(a) (a)
+#endif
+
+#define CLIP_PROTECT_GAIN_0(x) FL2FXCONST_CFG(((x) / (float)(1 << 0)))
+#define CLIP_PROTECT_GAIN_1(x) FL2FXCONST_CFG(((x) / (float)(1 << 1)))
+#define CLIP_PROTECT_GAIN_2(x) FL2FXCONST_CFG(((x) / (float)(1 << 2)))
+
+#define SF_CLD_C1C2 (8)
+
+extern const FIXP_CFG dequantCPC__FDK[];
+extern const FIXP_CFG dequantICC__FDK[8];
+extern const FIXP_CFG dequantCLD__FDK[31];
+
+#define IPD_SCALE (5)
+#define PI__IPD (FL2FXCONST_DBL(3.1415926535897932f / (float)(1 << IPD_SCALE)))
+/* Define for PI*2 for better precision in SpatialDecApplyPhase() */
+#define PIx2__IPD \
+ (FL2FXCONST_DBL(3.1415926535897932f / (float)(1 << (IPD_SCALE - 1))))
+
+extern const FIXP_CFG dequantIPD__FDK[16];
+
+extern const FIXP_CFG H11_nc[31][8];
+extern const FIXP_CFG H12_nc[31][8];
+
+extern const FIXP_DBL dequantCLD_c1[31];
+
+extern const FIXP_CFG BP__FDK[];
+extern const FIXP_CFG BP_GF__FDK[];
+extern const SCHAR row2channelSTP[][MAX_M2_INPUT];
+
+/* sac_bitdec */
+extern const INT samplingFreqTable[16];
+extern const UCHAR freqResTable[];
+extern const UCHAR freqResTable_LD[];
+extern const UCHAR tempShapeChanTable[2][8];
+extern const TREEPROPERTIES treePropertyTable[];
+
+extern const SCHAR kernels_4_to_71[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_5_to_71[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_7_to_71[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_10_to_71[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_14_to_71[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_20_to_71[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_28_to_71[MAX_HYBRID_BANDS];
+
+extern const UCHAR mapping_4_to_28[MAX_PARAMETER_BANDS];
+extern const UCHAR mapping_5_to_28[MAX_PARAMETER_BANDS];
+extern const UCHAR mapping_7_to_28[MAX_PARAMETER_BANDS];
+extern const UCHAR mapping_10_to_28[MAX_PARAMETER_BANDS];
+extern const UCHAR mapping_14_to_28[MAX_PARAMETER_BANDS];
+extern const UCHAR mapping_20_to_28[MAX_PARAMETER_BANDS];
+extern const SCHAR kernels_4_to_64[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_5_to_64[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_7_to_64[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_9_to_64[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_12_to_64[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_15_to_64[MAX_HYBRID_BANDS];
+extern const SCHAR kernels_23_to_64[MAX_HYBRID_BANDS];
+
+extern const UCHAR mapping_15_to_23[MAX_PARAMETER_BANDS_LD];
+extern const UCHAR mapping_12_to_23[MAX_PARAMETER_BANDS_LD];
+extern const UCHAR mapping_9_to_23[MAX_PARAMETER_BANDS_LD];
+extern const UCHAR mapping_7_to_23[MAX_PARAMETER_BANDS_LD];
+extern const UCHAR mapping_5_to_23[MAX_PARAMETER_BANDS_LD];
+extern const UCHAR mapping_4_to_23[MAX_PARAMETER_BANDS_LD];
+
+extern const FIXP_CFG clipGainTable__FDK[];
+extern const UCHAR clipGainSFTable__FDK[];
+
+extern const UCHAR pbStrideTable[];
+extern const int smgTimeTable[];
+
+extern const FIXP_CFG envShapeDataTable__FDK[5][2];
+extern const SCHAR row2channelGES[][MAX_M2_INPUT];
+
+/* sac_calcM1andM2 */
+extern const SCHAR row2residual[][MAX_M2_INPUT];
+
+void SpatialDequantGetCLDValues(int index, FIXP_DBL* cu, FIXP_DBL* cl);
+
+void SpatialDequantGetCLD2Values(int index, FIXP_DBL* x);
+
+/* External helper functions */
+static inline int SacGetHybridSubbands(int qmfSubbands) {
+ return qmfSubbands - MAX_QMF_BANDS_TO_HYBRID + 10;
+}
+
+#endif /* SAC_ROM_H */
diff --git a/fdk-aac/libSACdec/src/sac_smoothing.cpp b/fdk-aac/libSACdec/src/sac_smoothing.cpp
new file mode 100644
index 0000000..bee6551
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_smoothing.cpp
@@ -0,0 +1,295 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec parameter smoothing
+
+*******************************************************************************/
+
+#include "sac_dec.h"
+#include "sac_bitdec.h"
+#include "sac_smoothing.h"
+#include "sac_rom.h"
+
+/*******************************************************************************
+ Functionname: calcFilterCoeff
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Input:
+
+ Output:
+
+
+*******************************************************************************/
+static FIXP_DBL calcFilterCoeff__FDK(spatialDec *self, int ps,
+ const SPATIAL_BS_FRAME *frame) {
+ int dSlots;
+ FIXP_DBL delta;
+
+ dSlots = frame->paramSlot[ps] - self->smoothState->prevParamSlot;
+
+ if (dSlots <= 0) {
+ dSlots += self->timeSlots;
+ }
+
+ delta = fDivNorm(dSlots, self->smgTime[ps]);
+
+ return delta;
+}
+
+/*******************************************************************************
+ Functionname: getSmoothOnOff
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Input:
+
+ Output:
+
+
+*******************************************************************************/
+static int getSmoothOnOff(spatialDec *self, int ps, int pb) {
+ int smoothBand = 0;
+
+ smoothBand = self->smgData[ps][pb];
+
+ return smoothBand;
+}
+
+void SpatialDecSmoothM1andM2(spatialDec *self, const SPATIAL_BS_FRAME *frame,
+ int ps) {
+ FIXP_DBL delta__FDK;
+ FIXP_DBL one_minus_delta__FDK;
+
+ int pb, row, col;
+ int residualBands = 0;
+
+ if (self->residualCoding) {
+ int i;
+ int boxes = self->numOttBoxes;
+ for (i = 0; i < boxes; i++) {
+ if (self->residualBands[i] > residualBands) {
+ residualBands = self->residualBands[i];
+ }
+ }
+ }
+
+ delta__FDK = calcFilterCoeff__FDK(self, ps, frame);
+ if (delta__FDK == /*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL)
+ one_minus_delta__FDK = FL2FXCONST_DBL(0.0f);
+ else if (delta__FDK == FL2FXCONST_DBL(0.0f))
+ one_minus_delta__FDK = /*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL;
+ else
+ one_minus_delta__FDK = (FL2FXCONST_DBL(0.5f) - (delta__FDK >> 1)) << 1;
+
+ for (pb = 0; pb < self->numParameterBands; pb++) {
+ int smoothBand;
+
+ smoothBand = getSmoothOnOff(self, ps, pb);
+
+ if (smoothBand && (pb >= residualBands)) {
+ for (row = 0; row < self->numM2rows; row++) {
+ for (col = 0; col < self->numVChannels; col++) {
+ self->M2Real__FDK[row][col][pb] =
+ ((fMultDiv2(delta__FDK, self->M2Real__FDK[row][col][pb]) +
+ fMultDiv2(one_minus_delta__FDK,
+ self->M2RealPrev__FDK[row][col][pb]))
+ << 1);
+ if (0 || (self->phaseCoding == 3)) {
+ self->M2Imag__FDK[row][col][pb] =
+ ((fMultDiv2(delta__FDK, self->M2Imag__FDK[row][col][pb]) +
+ fMultDiv2(one_minus_delta__FDK,
+ self->M2ImagPrev__FDK[row][col][pb]))
+ << 1);
+ }
+ }
+ }
+ }
+ }
+ self->smoothState->prevParamSlot = frame->paramSlot[ps];
+}
+
+/* init states */
+void initParameterSmoothing(spatialDec *self) {
+ self->smoothState->prevParamSlot = 0;
+}
+
+void SpatialDecSmoothOPD(spatialDec *self, const SPATIAL_BS_FRAME *frame,
+ int ps) {
+ int pb;
+ int dSlots;
+ FIXP_DBL delta__FDK;
+ FIXP_DBL one_minus_delta__FDK;
+ FIXP_DBL *phaseLeftSmooth__FDK = self->smoothState->opdLeftState__FDK;
+ FIXP_DBL *phaseRightSmooth__FDK = self->smoothState->opdRightState__FDK;
+ int quantCoarse;
+
+ quantCoarse = frame->IPDLosslessData[0].bsQuantCoarseXXX[ps];
+
+ if (frame->OpdSmoothingMode == 0) {
+ FDKmemcpy(phaseLeftSmooth__FDK, self->PhaseLeft__FDK,
+ self->numParameterBands * sizeof(FIXP_DBL));
+ FDKmemcpy(phaseRightSmooth__FDK, self->PhaseRight__FDK,
+ self->numParameterBands * sizeof(FIXP_DBL));
+ } else {
+ if (ps == 0) {
+ dSlots = frame->paramSlot[ps] + 1;
+ } else {
+ dSlots = frame->paramSlot[ps] - frame->paramSlot[ps - 1];
+ }
+
+ delta__FDK = (FIXP_DBL)((INT)(FL2FXCONST_DBL(0.0078125f)) * dSlots);
+
+ if (delta__FDK == (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/)
+ one_minus_delta__FDK = FL2FXCONST_DBL(0.0f);
+ else if (delta__FDK == FL2FXCONST_DBL(0.0f))
+ one_minus_delta__FDK = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/;
+ else
+ one_minus_delta__FDK = (FL2FXCONST_DBL(0.5f) - (delta__FDK >> 1)) << 1;
+
+ for (pb = 0; pb < self->numParameterBands; pb++) {
+ FIXP_DBL tmpL, tmpR, tmp;
+
+ tmpL = self->PhaseLeft__FDK[pb];
+ tmpR = self->PhaseRight__FDK[pb];
+
+ while (tmpL > phaseLeftSmooth__FDK[pb] + PI__IPD) tmpL -= PI__IPD << 1;
+ while (tmpL < phaseLeftSmooth__FDK[pb] - PI__IPD) tmpL += PI__IPD << 1;
+ while (tmpR > phaseRightSmooth__FDK[pb] + PI__IPD) tmpR -= PI__IPD << 1;
+ while (tmpR < phaseRightSmooth__FDK[pb] - PI__IPD) tmpR += PI__IPD << 1;
+
+ phaseLeftSmooth__FDK[pb] =
+ fMult(delta__FDK, tmpL) +
+ fMult(one_minus_delta__FDK, phaseLeftSmooth__FDK[pb]);
+ phaseRightSmooth__FDK[pb] =
+ fMult(delta__FDK, tmpR) +
+ fMult(one_minus_delta__FDK, phaseRightSmooth__FDK[pb]);
+
+ tmp = (((tmpL >> 1) - (tmpR >> 1)) - ((phaseLeftSmooth__FDK[pb] >> 1) -
+ (phaseRightSmooth__FDK[pb] >> 1)))
+ << 1;
+ while (tmp > PI__IPD) tmp -= PI__IPD << 1;
+ while (tmp < -PI__IPD) tmp += PI__IPD << 1;
+ if (fixp_abs(tmp) > fMult((quantCoarse ? FL2FXCONST_DBL(50.f / 180.f)
+ : FL2FXCONST_DBL(25.f / 180.f)),
+ PI__IPD)) {
+ phaseLeftSmooth__FDK[pb] = tmpL;
+ phaseRightSmooth__FDK[pb] = tmpR;
+ }
+
+ while (phaseLeftSmooth__FDK[pb] > PI__IPD << 1)
+ phaseLeftSmooth__FDK[pb] -= PI__IPD << 1;
+ while (phaseLeftSmooth__FDK[pb] < (FIXP_DBL)0)
+ phaseLeftSmooth__FDK[pb] += PI__IPD << 1;
+ while (phaseRightSmooth__FDK[pb] > PI__IPD << 1)
+ phaseRightSmooth__FDK[pb] -= PI__IPD << 1;
+ while (phaseRightSmooth__FDK[pb] < (FIXP_DBL)0)
+ phaseRightSmooth__FDK[pb] += PI__IPD << 1;
+
+ self->PhaseLeft__FDK[pb] = phaseLeftSmooth__FDK[pb];
+ self->PhaseRight__FDK[pb] = phaseRightSmooth__FDK[pb];
+ }
+ }
+ return;
+}
diff --git a/fdk-aac/libSACdec/src/sac_smoothing.h b/fdk-aac/libSACdec/src/sac_smoothing.h
new file mode 100644
index 0000000..fdf3f5b
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_smoothing.h
@@ -0,0 +1,114 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec parameter smoothing
+
+*******************************************************************************/
+
+#ifndef SAC_SMOOTHING_H
+#define SAC_SMOOTHING_H
+
+#include "sac_dec.h"
+
+void initParameterSmoothing(spatialDec *self);
+void SpatialDecSmoothM1andM2(spatialDec *self, const SPATIAL_BS_FRAME *frame,
+ int ps);
+void SpatialDecSmoothOPD(spatialDec *self, const SPATIAL_BS_FRAME *frame,
+ int ps);
+
+#endif
diff --git a/fdk-aac/libSACdec/src/sac_stp.cpp b/fdk-aac/libSACdec/src/sac_stp.cpp
new file mode 100644
index 0000000..818e9df
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_stp.cpp
@@ -0,0 +1,548 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec subband processing
+
+*******************************************************************************/
+
+#include "sac_stp.h"
+#include "sac_calcM1andM2.h"
+#include "sac_bitdec.h"
+#include "FDK_matrixCalloc.h"
+#include "sac_rom.h"
+
+#define BP_GF_START 6
+#define BP_GF_SIZE 25
+#define HP_SIZE 9
+#define STP_UPDATE_ENERGY_RATE 32
+
+#define SF_WET 5
+#define SF_DRY \
+ 3 /* SF_DRY == 2 would produce good conformance test results as well */
+#define SF_PRODUCT_BP_GF 13
+#define SF_PRODUCT_BP_GF_GF 26
+#define SF_SCALE 2
+
+#define SF_SCALE_LD64 FL2FXCONST_DBL(0.03125) /* LD64((1<<SF_SCALE))*/
+#define STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.950f) /* 0.95 */
+#define ONE_MINUS_STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.05f) /* 1.0 - 0.95 */
+#define STP_LPF_COEFF2__FDK FL2FXCONST_DBL(0.450f) /* 0.45 */
+#define ONE_MINUS_STP_LPF_COEFF2__FDK \
+ FL2FXCONST_DBL(1.0f - 0.450f) /* 1.0 - 0.45 */
+#define STP_SCALE_LIMIT__FDK \
+ FL2FXCONST_DBL(2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE */
+#define ONE_DIV_STP_SCALE_LIMIT__FDK \
+ FL2FXCONST_DBL(1.0f / 2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE \
+ */
+#define ABS_THR__FDK \
+ FL2FXCONST_DBL(ABS_THR / \
+ ((float)(1 << (22 + 22 - 26)))) /* scaled by 18 bits */
+#define ABS_THR2__FDK \
+ FL2FXCONST_DBL(ABS_THR * 32.0f * 32.0f / \
+ ((float)(1 << (22 + 22 - 26)))) /* scaled by 10 bits */
+#define STP_SCALE_LIMIT_HI \
+ FL2FXCONST_DBL(3.02222222222 / (1 << SF_SCALE)) /* see 4. below */
+#define STP_SCALE_LIMIT_LO \
+ FL2FXCONST_DBL(0.28289992119 / (1 << SF_SCALE)) /* see 4. below */
+#define STP_SCALE_LIMIT_HI_LD64 \
+ FL2FXCONST_DBL(0.04986280452) /* see 4. below \
+ */
+#define STP_SCALE_LIMIT_LO_LD64 \
+ FL2FXCONST_DBL(0.05692613500) /* see 4. below \
+ */
+
+/* Scale factor calculation for the diffuse signal needs adapted thresholds
+ for STP_SCALE_LIMIT and 1/STP_SCALE_LIMIT:
+
+ 1. scale = sqrt(DryNrg/WetNrg)
+
+ 2. Damping of scale factor
+ scale2 = 0.1 + 0.9 * scale
+
+ 3. Limiting of scale factor
+ STP_SCALE_LIMIT >= scale2 >= 1/STP_SCALE_LIMIT
+ => STP_SCALE_LIMIT >= (0.1 + 0.9 * scale) >= 1/STP_SCALE_LIMIT
+ => (STP_SCALE_LIMIT-0.1)/0.9 >= scale >=
+ (1/STP_SCALE_LIMIT-0.1)/0.9
+
+ 3. Limiting of scale factor before sqrt calculation
+ ((STP_SCALE_LIMIT-0.1)/0.9)^2 >= (scale^2) >=
+ ((1/STP_SCALE_LIMIT-0.1)/0.9)^2 (STP_SCALE_LIMIT_HI)^2 >= (scale^2) >=
+ (STP_SCALE_LIMIT_LO)^2
+
+ 4. Thresholds for limiting of scale factor
+ STP_SCALE_LIMIT_HI = ((2.82-0.1)/0.9)
+ STP_SCALE_LIMIT_LO = (((1.0/2.82)-0.1)/0.9)
+ STP_SCALE_LIMIT_HI_LD64 = LD64(STP_SCALE_LIMIT_HI*STP_SCALE_LIMIT_HI)
+ STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO)
+*/
+
+#define DRY_ENER_WEIGHT(DryEner) DryEner = DryEner >> dry_scale_dmx
+
+#define WET_ENER_WEIGHT(WetEner) WetEner = WetEner << wet_scale_dmx
+
+#define DRY_ENER_SUM_REAL(DryEner, dmxReal, n) \
+ DryEner += \
+ fMultDiv2(fPow2Div2(dmxReal << SF_DRY), pBP[n]) >> ((2 * SF_DRY) - 2)
+
+#define DRY_ENER_SUM_CPLX(DryEner, dmxReal, dmxImag, n) \
+ DryEner += fMultDiv2( \
+ fPow2Div2(dmxReal << SF_DRY) + fPow2Div2(dmxImag << SF_DRY), pBP[n])
+
+#define CALC_WET_SCALE(dryIdx, wetIdx) \
+ if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \
+ scale[wetIdx] = STP_SCALE_LIMIT_HI; \
+ } else if (DryEnerLD64[dryIdx] < \
+ (WetEnerLD64[wetIdx] - STP_SCALE_LIMIT_LO_LD64)) { \
+ scale[wetIdx] = STP_SCALE_LIMIT_LO; \
+ } else { \
+ tmp = ((DryEnerLD64[dryIdx] - WetEnerLD64[wetIdx]) >> 1) - SF_SCALE_LD64; \
+ scale[wetIdx] = CalcInvLdData(tmp); \
+ }
+
+struct STP_DEC {
+ FIXP_DBL runDryEner[MAX_INPUT_CHANNELS];
+ FIXP_DBL runWetEner[MAX_OUTPUT_CHANNELS];
+ FIXP_DBL oldDryEnerLD64[MAX_INPUT_CHANNELS];
+ FIXP_DBL oldWetEnerLD64[MAX_OUTPUT_CHANNELS];
+ FIXP_DBL prev_tp_scale[MAX_OUTPUT_CHANNELS];
+ const FIXP_CFG *BP;
+ const FIXP_CFG *BP_GF;
+ int update_old_ener;
+};
+
+inline void combineSignalReal(FIXP_DBL *hybOutputRealDry,
+ FIXP_DBL *hybOutputRealWet, int bands) {
+ int n;
+
+ for (n = bands - 1; n >= 0; n--) {
+ *hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet;
+ hybOutputRealDry++, hybOutputRealWet++;
+ }
+}
+
+inline void combineSignalRealScale1(FIXP_DBL *hybOutputRealDry,
+ FIXP_DBL *hybOutputRealWet, FIXP_DBL scaleX,
+ int bands) {
+ int n;
+
+ for (n = bands - 1; n >= 0; n--) {
+ *hybOutputRealDry =
+ *hybOutputRealDry +
+ (fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1));
+ hybOutputRealDry++, hybOutputRealWet++;
+ }
+}
+
+inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
+ FIXP_DBL *hybOutputImagDry,
+ FIXP_DBL *hybOutputRealWet,
+ FIXP_DBL *hybOutputImagWet, int bands) {
+ int n;
+
+ for (n = bands - 1; n >= 0; n--) {
+ *hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet;
+ *hybOutputImagDry = *hybOutputImagDry + *hybOutputImagWet;
+ hybOutputRealDry++, hybOutputRealWet++;
+ hybOutputImagDry++, hybOutputImagWet++;
+ }
+}
+
+inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry,
+ FIXP_DBL *hybOutputImagDry,
+ FIXP_DBL *hybOutputRealWet,
+ FIXP_DBL *hybOutputImagWet,
+ const FIXP_CFG *pBP, FIXP_DBL scaleX,
+ int bands) {
+ int n;
+ FIXP_DBL scaleY;
+ for (n = bands - 1; n >= 0; n--) {
+ scaleY = fMultDiv2(scaleX, *pBP);
+ *hybOutputRealDry =
+ *hybOutputRealDry +
+ (fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 2));
+ *hybOutputImagDry =
+ *hybOutputImagDry +
+ (fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 2));
+ hybOutputRealDry++, hybOutputRealWet++;
+ hybOutputImagDry++, hybOutputImagWet++;
+ pBP++;
+ }
+}
+
+inline void combineSignalCplxScale2(FIXP_DBL *hybOutputRealDry,
+ FIXP_DBL *hybOutputImagDry,
+ FIXP_DBL *hybOutputRealWet,
+ FIXP_DBL *hybOutputImagWet, FIXP_DBL scaleX,
+ int bands) {
+ int n;
+
+ for (n = bands - 1; n >= 0; n--) {
+ *hybOutputRealDry =
+ *hybOutputRealDry +
+ (fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1));
+ *hybOutputImagDry =
+ *hybOutputImagDry +
+ (fMultDiv2(*hybOutputImagWet, scaleX) << (SF_SCALE + 1));
+ hybOutputRealDry++, hybOutputRealWet++;
+ hybOutputImagDry++, hybOutputImagWet++;
+ }
+}
+
+/*******************************************************************************
+ Functionname: subbandTPCreate
+ ******************************************************************************/
+SACDEC_ERROR subbandTPCreate(HANDLE_STP_DEC *hStpDec) {
+ HANDLE_STP_DEC self = NULL;
+ FDK_ALLOCATE_MEMORY_1D(self, 1, struct STP_DEC)
+ if (hStpDec != NULL) {
+ *hStpDec = self;
+ }
+
+ return MPS_OK;
+bail:
+ return MPS_OUTOFMEMORY;
+}
+
+SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) {
+ SACDEC_ERROR err = MPS_OK;
+ int ch;
+
+ for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
+ self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
+ self->oldWetEnerLD64[ch] =
+ FL2FXCONST_DBL(0.34375f); /* 32768.0*32768.0/2^(44-26-10) */
+ }
+ for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
+ self->oldDryEnerLD64[ch] =
+ FL2FXCONST_DBL(0.1875f); /* 32768.0*32768.0/2^(44-26) */
+ }
+
+ self->BP = BP__FDK;
+ self->BP_GF = BP_GF__FDK;
+
+ self->update_old_ener = 0;
+
+ return err;
+}
+
+/*******************************************************************************
+ Functionname: subbandTPDestroy
+ ******************************************************************************/
+void subbandTPDestroy(HANDLE_STP_DEC *hStpDec) {
+ if (hStpDec != NULL) {
+ FDK_FREE_MEMORY_1D(*hStpDec);
+ }
+}
+
+/*******************************************************************************
+ Functionname: subbandTPApply
+ ******************************************************************************/
+SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
+ FIXP_DBL *qmfOutputRealDry[MAX_OUTPUT_CHANNELS];
+ FIXP_DBL *qmfOutputImagDry[MAX_OUTPUT_CHANNELS];
+ FIXP_DBL *qmfOutputRealWet[MAX_OUTPUT_CHANNELS];
+ FIXP_DBL *qmfOutputImagWet[MAX_OUTPUT_CHANNELS];
+
+ FIXP_DBL DryEner[MAX_INPUT_CHANNELS];
+ FIXP_DBL scale[MAX_OUTPUT_CHANNELS];
+
+ FIXP_DBL DryEnerLD64[MAX_INPUT_CHANNELS];
+ FIXP_DBL WetEnerLD64[MAX_OUTPUT_CHANNELS];
+
+ FIXP_DBL DryEner0 = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL WetEnerX, damp, tmp;
+ FIXP_DBL dmxReal0, dmxImag0;
+ int skipChannels[MAX_OUTPUT_CHANNELS];
+ int n, ch, cplxBands, cplxHybBands;
+ int dry_scale_dmx, wet_scale_dmx;
+ int i_LF, i_RF;
+ HANDLE_STP_DEC hStpDec;
+ const FIXP_CFG *pBP;
+
+ int nrgScale = (2 * self->clipProtectGainSF__FDK);
+
+ hStpDec = self->hStpDec;
+
+ /* set scalefactor and loop counter */
+ FDK_ASSERT(SF_DRY >= 1);
+ {
+ cplxBands = BP_GF_SIZE;
+ cplxHybBands = self->hybridBands;
+ dry_scale_dmx = (2 * SF_DRY) - 2;
+ wet_scale_dmx = 2;
+ }
+
+ /* setup pointer for forming the direct downmix signal */
+ for (ch = 0; ch < self->numOutputChannels; ch++) {
+ qmfOutputRealDry[ch] = &self->hybOutputRealDry__FDK[ch][7];
+ qmfOutputRealWet[ch] = &self->hybOutputRealWet__FDK[ch][7];
+ qmfOutputImagDry[ch] = &self->hybOutputImagDry__FDK[ch][7];
+ qmfOutputImagWet[ch] = &self->hybOutputImagWet__FDK[ch][7];
+ }
+
+ /* clear skipping flag for all output channels */
+ FDKmemset(skipChannels, 0, self->numOutputChannels * sizeof(int));
+
+ /* set scale values to zero */
+ FDKmemset(scale, 0, self->numOutputChannels * sizeof(FIXP_DBL));
+
+ /* update normalisation energy with latest smoothed energy */
+ if (hStpDec->update_old_ener == STP_UPDATE_ENERGY_RATE) {
+ hStpDec->update_old_ener = 1;
+ for (ch = 0; ch < self->numInputChannels; ch++) {
+ hStpDec->oldDryEnerLD64[ch] =
+ CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK);
+ }
+ for (ch = 0; ch < self->numOutputChannels; ch++) {
+ hStpDec->oldWetEnerLD64[ch] =
+ CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
+ }
+ } else {
+ hStpDec->update_old_ener++;
+ }
+
+ /* get channel configuration */
+ switch (self->treeConfig) {
+ case TREE_212:
+ i_LF = 0;
+ i_RF = 1;
+ break;
+ default:
+ return MPS_WRONG_TREECONFIG;
+ }
+
+ /* form the 'direct' downmix signal */
+ pBP = hStpDec->BP_GF - BP_GF_START;
+ switch (self->treeConfig) {
+ case TREE_212:
+ for (n = BP_GF_START; n < cplxBands; n++) {
+ dmxReal0 = qmfOutputRealDry[i_LF][n] + qmfOutputRealDry[i_RF][n];
+ dmxImag0 = qmfOutputImagDry[i_LF][n] + qmfOutputImagDry[i_RF][n];
+ DRY_ENER_SUM_CPLX(DryEner0, dmxReal0, dmxImag0, n);
+ }
+ DRY_ENER_WEIGHT(DryEner0);
+ break;
+ default:;
+ }
+ DryEner[0] = DryEner0;
+
+ /* normalise the 'direct' signals */
+ for (ch = 0; ch < self->numInputChannels; ch++) {
+ DryEner[ch] = DryEner[ch] << (nrgScale);
+ hStpDec->runDryEner[ch] =
+ fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
+ fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
+ if (DryEner[ch] != FL2FXCONST_DBL(0.0f)) {
+ DryEnerLD64[ch] =
+ fixMax((CalcLdData(DryEner[ch]) - hStpDec->oldDryEnerLD64[ch]),
+ FL2FXCONST_DBL(-0.484375f));
+ } else {
+ DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
+ }
+ }
+ if (self->treeConfig == TREE_212) {
+ for (; ch < MAX_INPUT_CHANNELS; ch++) {
+ DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
+ }
+ }
+
+ /* normalise the 'diffuse' signals */
+ pBP = hStpDec->BP_GF - BP_GF_START;
+ for (ch = 0; ch < self->numOutputChannels; ch++) {
+ if (skipChannels[ch]) {
+ continue;
+ }
+
+ WetEnerX = FL2FXCONST_DBL(0.0f);
+ for (n = BP_GF_START; n < cplxBands; n++) {
+ tmp = fPow2Div2(qmfOutputRealWet[ch][n] << SF_WET);
+ tmp += fPow2Div2(qmfOutputImagWet[ch][n] << SF_WET);
+ WetEnerX += fMultDiv2(tmp, pBP[n]);
+ }
+ WET_ENER_WEIGHT(WetEnerX);
+
+ WetEnerX = WetEnerX << (nrgScale);
+ hStpDec->runWetEner[ch] =
+ fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
+ fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);
+
+ if (WetEnerX == FL2FXCONST_DBL(0.0f)) {
+ WetEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
+ } else {
+ WetEnerLD64[ch] =
+ fixMax((CalcLdData(WetEnerX) - hStpDec->oldWetEnerLD64[ch]),
+ FL2FXCONST_DBL(-0.484375f));
+ }
+ }
+
+ /* compute scale factor for the 'diffuse' signals */
+ switch (self->treeConfig) {
+ case TREE_212:
+ if (DryEner[0] != FL2FXCONST_DBL(0.0f)) {
+ CALC_WET_SCALE(0, i_LF);
+ CALC_WET_SCALE(0, i_RF);
+ }
+ break;
+ default:;
+ }
+
+ damp = FL2FXCONST_DBL(0.1f / (1 << SF_SCALE));
+ for (ch = 0; ch < self->numOutputChannels; ch++) {
+ /* damp the scaling factor */
+ scale[ch] = damp + fMult(FL2FXCONST_DBL(0.9f), scale[ch]);
+
+ /* limiting the scale factor */
+ if (scale[ch] > STP_SCALE_LIMIT__FDK) {
+ scale[ch] = STP_SCALE_LIMIT__FDK;
+ }
+ if (scale[ch] < ONE_DIV_STP_SCALE_LIMIT__FDK) {
+ scale[ch] = ONE_DIV_STP_SCALE_LIMIT__FDK;
+ }
+
+ /* low pass filter the scaling factor */
+ scale[ch] =
+ fMult(STP_LPF_COEFF2__FDK, scale[ch]) +
+ fMult(ONE_MINUS_STP_LPF_COEFF2__FDK, hStpDec->prev_tp_scale[ch]);
+ hStpDec->prev_tp_scale[ch] = scale[ch];
+ }
+
+ /* combine 'direct' and scaled 'diffuse' signal */
+ FDK_ASSERT((HP_SIZE - 3 + 10 - 1) == PC_NUM_HYB_BANDS);
+ const SCHAR *channlIndex = row2channelSTP[self->treeConfig];
+
+ for (ch = 0; ch < self->numOutputChannels; ch++) {
+ int no_scaling;
+
+ no_scaling = !frame->tempShapeEnableChannelSTP[channlIndex[ch]];
+ if (no_scaling) {
+ combineSignalCplx(
+ &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
+ &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
+ &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
+ &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
+ cplxHybBands - self->tp_hybBandBorder);
+
+ } else {
+ FIXP_DBL scaleX;
+ scaleX = scale[ch];
+ pBP = hStpDec->BP - self->tp_hybBandBorder;
+ /* Band[HP_SIZE-3+10-1] needs not to be processed in
+ combineSignalCplxScale1(), because pB[HP_SIZE-3+10-1] would be 1.0 */
+ combineSignalCplxScale1(
+ &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
+ &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
+ &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
+ &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
+ &pBP[self->tp_hybBandBorder], scaleX,
+ (HP_SIZE - 3 + 10 - 1) - self->tp_hybBandBorder);
+
+ {
+ combineSignalCplxScale2(
+ &self->hybOutputRealDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
+ &self->hybOutputImagDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
+ &self->hybOutputRealWet__FDK[ch][HP_SIZE - 3 + 10 - 1],
+ &self->hybOutputImagWet__FDK[ch][HP_SIZE - 3 + 10 - 1], scaleX,
+ cplxHybBands - (HP_SIZE - 3 + 10 - 1));
+ }
+ }
+ }
+
+ return (SACDEC_ERROR)MPS_OK;
+ ;
+}
diff --git a/fdk-aac/libSACdec/src/sac_stp.h b/fdk-aac/libSACdec/src/sac_stp.h
new file mode 100644
index 0000000..18471bd
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_stp.h
@@ -0,0 +1,115 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s):
+
+ Description: SAC Dec subband processing
+
+*******************************************************************************/
+
+#ifndef SAC_STP_H
+#define SAC_STP_H
+
+#include "sac_dec.h"
+
+SACDEC_ERROR subbandTPCreate(HANDLE_STP_DEC *hStpDec);
+
+SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self);
+
+SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame);
+void subbandTPDestroy(HANDLE_STP_DEC *hStpDec);
+
+#endif
diff --git a/fdk-aac/libSACdec/src/sac_tsd.cpp b/fdk-aac/libSACdec/src/sac_tsd.cpp
new file mode 100644
index 0000000..30acca8
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_tsd.cpp
@@ -0,0 +1,353 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: USAC MPS212 Transient Steering Decorrelator (TSD)
+
+*******************************************************************************/
+
+#include "sac_tsd.h"
+
+#define TSD_START_BAND (7)
+#define SIZE_S (4)
+#define SIZE_C (5)
+
+/*** Tables ***/
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+static const UCHAR nBitsTsdCW_32slots[32] = {
+ 5, 9, 13, 16, 18, 20, 22, 24, 25, 26, 27, 28, 29, 29, 30, 30,
+ 30, 29, 29, 28, 27, 26, 25, 24, 22, 20, 18, 16, 13, 9, 5, 0};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+static const UCHAR nBitsTsdCW_64slots[64] = {
+ 6, 11, 16, 20, 23, 27, 30, 33, 35, 38, 40, 42, 44, 46, 48, 49,
+ 51, 52, 53, 55, 56, 57, 58, 58, 59, 60, 60, 60, 61, 61, 61, 61,
+ 61, 61, 61, 60, 60, 60, 59, 58, 58, 57, 56, 55, 53, 52, 51, 49,
+ 48, 46, 44, 42, 40, 38, 35, 33, 30, 27, 23, 20, 16, 11, 6, 0};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+static const FIXP_STP phiTsd[8] = {
+ STCP(0x7fffffff, 0x00000000), STCP(0x5a82799a, 0x5a82799a),
+ STCP(0x00000000, 0x7fffffff), STCP(0xa57d8666, 0x5a82799a),
+ STCP(0x80000000, 0x00000000), STCP(0xa57d8666, 0xa57d8666),
+ STCP(0x00000000, 0x80000000), STCP(0x5a82799a, 0xa57d8666),
+};
+
+/*** Static Functions ***/
+static void longmult1(USHORT a[], USHORT b, USHORT d[], int len) {
+ int k;
+ ULONG tmp;
+ ULONG b0 = (ULONG)b;
+
+ tmp = ((ULONG)a[0]) * b0;
+ d[0] = (USHORT)tmp;
+
+ for (k = 1; k < len; k++) {
+ tmp = (tmp >> 16) + ((ULONG)a[k]) * b0;
+ d[k] = (USHORT)tmp;
+ }
+}
+
+static void longdiv(USHORT b[], USHORT a, USHORT d[], USHORT *pr, int len) {
+ ULONG r;
+ ULONG tmp;
+ int k;
+
+ FDK_ASSERT(a != 0);
+
+ r = 0;
+
+ for (k = len - 1; k >= 0; k--) {
+ tmp = ((ULONG)b[k]) + (r << 16);
+
+ if (tmp) {
+ d[k] = (USHORT)(tmp / a);
+ r = tmp - d[k] * a;
+ } else {
+ d[k] = 0;
+ }
+ }
+ *pr = (USHORT)r;
+}
+
+static void longsub(USHORT a[], USHORT b[], int lena, int lenb) {
+ int h;
+ LONG carry = 0;
+
+ FDK_ASSERT(lena >= lenb);
+ for (h = 0; h < lenb; h++) {
+ carry += ((LONG)a[h]) - ((LONG)b[h]);
+ a[h] = (USHORT)carry;
+ carry = carry >> 16;
+ }
+
+ for (; h < lena; h++) {
+ carry = ((LONG)a[h]) + carry;
+ a[h] = (USHORT)carry;
+ carry = carry >> 16;
+ }
+
+ FDK_ASSERT(carry ==
+ 0); /* carry != 0 indicates subtraction underflow, e.g. b > a */
+ return;
+}
+
+static int longcompare(USHORT a[], USHORT b[], int len) {
+ int i;
+
+ for (i = len - 1; i > 0; i--) {
+ if (a[i] != b[i]) break;
+ }
+ return (a[i] >= b[i]) ? 1 : 0;
+}
+
+FDK_INLINE int isTrSlot(const TSD_DATA *pTsdData, const int ts) {
+ return (pTsdData->bsTsdTrPhaseData[ts] >= 0);
+}
+
+/*** Public Functions ***/
+int TsdRead(HANDLE_FDK_BITSTREAM hBs, const int numSlots, TSD_DATA *pTsdData) {
+ int nBitsTrSlots = 0;
+ int bsTsdNumTrSlots;
+ const UCHAR *nBitsTsdCW_tab = NULL;
+
+ switch (numSlots) {
+ case 32:
+ nBitsTrSlots = 4;
+ nBitsTsdCW_tab = nBitsTsdCW_32slots;
+ break;
+ case 64:
+ nBitsTrSlots = 5;
+ nBitsTsdCW_tab = nBitsTsdCW_64slots;
+ break;
+ default:
+ return 1;
+ }
+
+ /*** Read TempShapeData for bsTempShapeConfig == 3 ***/
+ pTsdData->bsTsdEnable = FDKreadBit(hBs);
+ if (!pTsdData->bsTsdEnable) {
+ return 0;
+ }
+
+ /*** Parse/Decode TsdData() ***/
+ pTsdData->numSlots = numSlots;
+
+ bsTsdNumTrSlots = FDKreadBits(hBs, nBitsTrSlots);
+
+ /* Decode transient slot positions */
+ {
+ int nBitsTsdCW = (int)nBitsTsdCW_tab[bsTsdNumTrSlots];
+ SCHAR *phaseData = pTsdData->bsTsdTrPhaseData;
+ int p = bsTsdNumTrSlots + 1;
+ int k, h;
+ USHORT s[SIZE_S] = {0};
+ USHORT c[SIZE_C] = {0};
+ USHORT r[1];
+
+ /* Init with TsdSepData[k] = 0 */
+ for (k = 0; k < numSlots; k++) {
+ phaseData[k] = -1; /* means TsdSepData[] = 0 */
+ }
+
+ for (h = (SIZE_S - 1); h >= 0; h--) {
+ if (nBitsTsdCW > h * 16) {
+ s[h] = (USHORT)FDKreadBits(hBs, nBitsTsdCW - h * 16);
+ nBitsTsdCW = h * 16;
+ }
+ }
+
+ /* c = prod_{h=1}^{p} (k-p+h)/h */
+ k = numSlots - 1;
+ c[0] = k - p + 1;
+ for (h = 2; h <= p; h++) {
+ longmult1(c, (k - p + h), c, 5); /* c *= k - p + h; */
+ longdiv(c, h, c, r, 5); /* c /= h; */
+ FDK_ASSERT(*r == 0);
+ }
+
+ /* go through all slots */
+ for (; k >= 0; k--) {
+ if (p > k) {
+ for (; k >= 0; k--) {
+ phaseData[k] = 1; /* means TsdSepData[] = 1 */
+ }
+ break;
+ }
+ if (longcompare(s, c, 4)) { /* (s >= c) */
+ longsub(s, c, 4, 4); /* s -= c; */
+ phaseData[k] = 1; /* means TsdSepData[] = 1 */
+ if (p == 1) {
+ break;
+ }
+ /* Update c for next iteration: c_new = c_old * p / k */
+ longmult1(c, p, c, 5);
+ p--;
+ } else {
+ /* Update c for next iteration: c_new = c_old * (k-p) / k */
+ longmult1(c, (k - p), c, 5);
+ }
+ longdiv(c, k, c, r, 5);
+ FDK_ASSERT(*r == 0);
+ }
+
+ /* Read phase data */
+ for (k = 0; k < numSlots; k++) {
+ if (phaseData[k] == 1) {
+ phaseData[k] = FDKreadBits(hBs, 3);
+ }
+ }
+ }
+
+ return 0;
+}
+
+void TsdGenerateNonTr(const int numHybridBands, const TSD_DATA *pTsdData,
+ const int ts, FIXP_DBL *pVdirectReal,
+ FIXP_DBL *pVdirectImag, FIXP_DBL *pVnonTrReal,
+ FIXP_DBL *pVnonTrImag, FIXP_DBL **ppDecorrInReal,
+ FIXP_DBL **ppDecorrInImag) {
+ int k = 0;
+
+ if (!isTrSlot(pTsdData, ts)) {
+ /* Let allpass based decorrelator read from direct input. */
+ *ppDecorrInReal = pVdirectReal;
+ *ppDecorrInImag = pVdirectImag;
+ return;
+ }
+
+ /* Generate nonTr input signal for allpass based decorrelator */
+ for (; k < TSD_START_BAND; k++) {
+ pVnonTrReal[k] = pVdirectReal[k];
+ pVnonTrImag[k] = pVdirectImag[k];
+ }
+ for (; k < numHybridBands; k++) {
+ pVnonTrReal[k] = (FIXP_DBL)0;
+ pVnonTrImag[k] = (FIXP_DBL)0;
+ }
+ *ppDecorrInReal = pVnonTrReal;
+ *ppDecorrInImag = pVnonTrImag;
+}
+
+void TsdApply(const int numHybridBands, const TSD_DATA *pTsdData, int *pTsdTs,
+ const FIXP_DBL *pVdirectReal, const FIXP_DBL *pVdirectImag,
+ FIXP_DBL *pDnonTrReal, FIXP_DBL *pDnonTrImag) {
+ const int ts = *pTsdTs;
+
+ if (isTrSlot(pTsdData, ts)) {
+ int k;
+ const FIXP_STP *phi = &phiTsd[pTsdData->bsTsdTrPhaseData[ts]];
+ FDK_ASSERT((pTsdData->bsTsdTrPhaseData[ts] >= 0) &&
+ (pTsdData->bsTsdTrPhaseData[ts] < 8));
+
+ /* d = d_nonTr + v_direct * exp(j * bsTsdTrPhaseData[ts]/4 * pi ) */
+ for (k = TSD_START_BAND; k < numHybridBands; k++) {
+ FIXP_DBL tempReal, tempImag;
+ cplxMult(&tempReal, &tempImag, pVdirectReal[k], pVdirectImag[k], *phi);
+ pDnonTrReal[k] += tempReal;
+ pDnonTrImag[k] += tempImag;
+ }
+ }
+
+ /* The modulo MAX_TSD_TIME_SLOTS operation is to avoid illegal memory accesses
+ * in case of errors. */
+ *pTsdTs = (ts + 1) & (MAX_TSD_TIME_SLOTS - 1);
+ return;
+}
diff --git a/fdk-aac/libSACdec/src/sac_tsd.h b/fdk-aac/libSACdec/src/sac_tsd.h
new file mode 100644
index 0000000..2521e27
--- /dev/null
+++ b/fdk-aac/libSACdec/src/sac_tsd.h
@@ -0,0 +1,167 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround decoder library *************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: USAC MPS212 Transient Steering Decorrelator (TSD)
+
+*******************************************************************************/
+
+#ifndef SAC_TSD_H
+#define SAC_TSD_H
+
+#include "FDK_bitstream.h"
+#include "common_fix.h"
+
+#define MAX_TSD_TIME_SLOTS (64)
+
+/** Structure which holds the data needed to apply TSD to current frame. */
+typedef struct {
+ UCHAR bsTsdEnable; /**< for current frame TSD is (0:disabled, 1:enabled) */
+ UCHAR numSlots; /**< total number of QMF slots per frame */
+ SCHAR
+ bsTsdTrPhaseData[MAX_TSD_TIME_SLOTS]; /**< -1 => TsdSepData[ts]=0; 0-7:
+ values of bsTsdTrPhaseData[ts]
+ and TsdSepData[ts]=1 */
+} TSD_DATA;
+
+FDK_INLINE int isTsdActive(const TSD_DATA *pTsdData) {
+ return (int)pTsdData->bsTsdEnable;
+}
+
+/**
+ * \brief Parse and Decode TSD data.
+ * \param[in] hBs bitstream handle to read data from.
+ * \param[in] numSlots number of QMF slots per frame.
+ * \param[out] pTsdData pointer to TSD data structure.
+ * \return 0 on succes, 1 on error.
+ */
+int TsdRead(HANDLE_FDK_BITSTREAM hBs, const int numSlots, TSD_DATA *pTsdData);
+
+/**
+ * \brief Perform transient seperation (v_{x,nonTr} signal).
+ * \param[in] numHybridBands number of hybrid bands.
+ * \param[in] pTsdData pointer to TSD data structure.
+ * \param[in] pVdirectReal pointer to array with direct signal.
+ * \param[in] pVdirectImag pointer to array with direct signal.
+ * \param[out] pVnonTrReal pointer to array with nonTr signal.
+ * \param[out] pVnonTrImag pointer to array with nonTr signal.
+ * \param[out] ppDecorrInReal handle to array where allpass based decorrelator
+ * should read from (modified by this function).
+ * \param[out] ppDecorrInImag handle to array where allpass based decorrelator
+ * should read from (modified by this function).
+ */
+void TsdGenerateNonTr(const int numHybridBands, const TSD_DATA *pTsdData,
+ const int ts, FIXP_DBL *pVdirectReal,
+ FIXP_DBL *pVdirectImag, FIXP_DBL *pVnonTrReal,
+ FIXP_DBL *pVnonTrImag, FIXP_DBL **ppDecorrInReal,
+ FIXP_DBL **ppDecorrInImag);
+
+/**
+ * \brief Generate d_{x,Tr} signal and add to d_{x,nonTr} signal
+ * \param[in] numHybridBands
+ * \param[in,out] pTsdData
+ * \param pTsdTs pointer to persistent time slot counter
+ * \param[in] pVdirectReal
+ * \param[in] pVdirectImag
+ * \param[out] pDnonTrReal
+ * \param[out] pDnonTrImag
+ */
+void TsdApply(const int numHybridBands, const TSD_DATA *pTsdData, int *pTsdTs,
+ const FIXP_DBL *pVdirectReal, const FIXP_DBL *pVdirectImag,
+ FIXP_DBL *pDnonTrReal, FIXP_DBL *pDnonTrImag);
+
+#endif /* #ifndef SAC_TSD_H */
diff --git a/fdk-aac/libSACenc/include/sacenc_lib.h b/fdk-aac/libSACenc/include/sacenc_lib.h
new file mode 100644
index 0000000..758cc0f
--- /dev/null
+++ b/fdk-aac/libSACenc/include/sacenc_lib.h
@@ -0,0 +1,405 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Encoder API
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ ******************************************************************************/
+
+#ifndef SACENC_LIB_H
+#define SACENC_LIB_H
+
+/* Includes ******************************************************************/
+#include "machine_type.h"
+#include "FDK_audio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+
+/**
+ * Space encoder error codes.
+ */
+typedef enum {
+ SACENC_OK = 0x00000000, /*!< No error happened. All fine. */
+ SACENC_INVALID_HANDLE =
+ 0x00000080, /*!< Handle passed to function call was invalid. */
+ SACENC_MEMORY_ERROR = 0x00000800, /*!< Memory allocation failed. */
+ SACENC_INIT_ERROR = 0x00008000, /*!< General initialization error. */
+ SACENC_ENCODE_ERROR =
+ 0x00080000, /*!< The encoding process was interrupted by an unexpected
+ error. */
+ SACENC_PARAM_ERROR = 0x00800000, /*!< Invalid runtime parameter. */
+ SACENC_UNSUPPORTED_PARAMETER = 0x00800001, /*!< Parameter not available. */
+ SACENC_INVALID_CONFIG = 0x00800002, /*!< Configuration not provided. */
+ SACENC_UNKNOWN_ERROR = 0x08000000 /*!< Unknown error. */
+
+} FDK_SACENC_ERROR;
+
+typedef enum {
+ SACENC_INVALID_MODE = 0,
+ SACENC_212 = 8,
+ SACENC_ESCAPE = 15
+
+} MP4SPACEENC_MODE;
+
+typedef enum {
+ SACENC_BANDS_INVALID = 0,
+ SACENC_BANDS_4 = 4,
+ SACENC_BANDS_5 = 5,
+ SACENC_BANDS_7 = 7,
+ SACENC_BANDS_9 = 9,
+ SACENC_BANDS_12 = 12,
+ SACENC_BANDS_15 = 15,
+ SACENC_BANDS_23 = 23
+
+} MP4SPACEENC_BANDS_CONFIG;
+
+typedef enum {
+ SACENC_QUANTMODE_INVALID = -1,
+ SACENC_QUANTMODE_FINE = 0,
+ SACENC_QUANTMODE_EBQ1 = 1,
+ SACENC_QUANTMODE_EBQ2 = 2,
+ SACENC_QUANTMODE_RSVD3 = 3
+
+} MP4SPACEENC_QUANTMODE;
+
+typedef enum {
+ SACENC_DMXGAIN_INVALID = -1,
+ SACENC_DMXGAIN_0_dB = 0,
+ SACENC_DMXGAIN_1_5_dB = 1,
+ SACENC_DMXGAIN_3_dB = 2,
+ SACENC_DMXGAIN_4_5_dB = 3,
+ SACENC_DMXGAIN_6_dB = 4,
+ SACENC_DMXGAIN_7_5_dB = 5,
+ SACENC_DMXGAIN_9_dB = 6,
+ SACENC_DMXGAIN_12_dB = 7
+
+} MP4SPACEENC_DMX_GAIN;
+
+/**
+ * \brief Space Encoder setting parameters.
+ *
+ * Use FDK_sacenc_setParam() function to configure the internal status of the
+ * following parameters.
+ */
+typedef enum {
+ SACENC_LOWDELAY, /*!< Configure lowdelay MPEG Surround.
+ - 0: Disable Lowdelay. (default)
+ - 1: Enable Lowdelay.
+ - 2: Enable Lowdelay including keep frame. */
+
+ SACENC_ENC_MODE, /*!< Configure encoder tree mode. See ::MP4SPACEENC_MODE for
+ available values. */
+
+ SACENC_SAMPLERATE, /*!< Configure encoder sampling rate. */
+
+ SACENC_FRAME_TIME_SLOTS, /*!< Configure number of slots per spatial frame. */
+
+ SACENC_PARAM_BANDS, /*!< Configure number of parameter bands. See
+ ::MP4SPACEENC_BANDS_CONFIG for available values. */
+
+ SACENC_TIME_DOM_DMX, /*!< Configure time domain downmix.
+ - 0: No time domain downmix. (default)
+ - 1: Static time domain downmix.
+ - 2: Enhanced time domain downmix, stereo to mono
+ only. */
+
+ SACENC_DMX_GAIN, /*!< Configure downmix gain. See ::MP4SPACEENC_DMX_GAIN for
+ available values. */
+
+ SACENC_COARSE_QUANT, /*!< Use coarse parameter quantization.
+ - 0: No (default)
+ - 1: Yes */
+
+ SACENC_QUANT_MODE, /*!< Configure quanitzation mode. See
+ ::MP4SPACEENC_QUANTMODE for available values. */
+
+ SACENC_TIME_ALIGNMENT, /*!< Configure time alignment in samples. */
+
+ SACENC_INDEPENDENCY_COUNT, /*!< Configure the independency count. (count == 0
+ means independencyFlag == 1) */
+
+ SACENC_INDEPENDENCY_FACTOR, /*!< How often should we set the independency flag
+ */
+
+ SACENC_NONE /*!< ------ */
+
+} SPACEENC_PARAM;
+
+/**
+ * Describes Spatial Specific Config.
+ */
+typedef struct {
+ INT nSscSizeBits; /*!< Number of valid bits in pSsc buffer. */
+ UCHAR *pSsc; /*!< SpatialSpecificConfig buffer in binary format. */
+
+} MPEG4SPACEENC_SSCBUF;
+
+/**
+ * Provides some info about the encoder configuration.
+ */
+typedef struct {
+ INT nSampleRate; /*!< Configured sampling rate.*/
+ INT nSamplesFrame; /*!< Frame length in samples. */
+ INT nTotalInputChannels; /*!< Number of expected audio input channels. */
+ INT nDmxDelay; /*!< Delay of the downmixed signal. */
+ INT nCodecDelay; /*!< Delay of the whole en-/decoded signal, including
+ core-coder delay. */
+ INT nDecoderDelay; /*!< Delay added by the MP4SPACE decoder. */
+ INT nPayloadDelay; /*!< Delay of the payload. */
+ INT nDiscardOutFrames; /*!< Number of dmx frames to discard for alignment with
+ bitstream. */
+
+ MPEG4SPACEENC_SSCBUF
+ *pSscBuf; /*!< Pointer to Spatial Specific Config structure. */
+
+} MP4SPACEENC_INFO;
+
+/**
+ * MPEG Surround encoder handle.
+ */
+typedef struct MP4SPACE_ENCODER *HANDLE_MP4SPACE_ENCODER;
+
+/**
+ * Defines the input arguments for a FDK_sacenc_encode() call.
+ */
+typedef struct {
+ INT nInputSamples; /*!< Number of valid input audio samples (multiple of input
+ channels). */
+ UINT inputBufferSizePerChannel; /*!< Size of input buffer (input audio
+ samples) per channel. */
+ UINT isInputInterleaved; /*!< Indicates if input audio samples are represented
+ in blocks or interleaved:
+ - 0 : in blocks.
+ - 1 : interleaved. */
+
+} SACENC_InArgs;
+
+/**
+ * Defines the output arguments for a FDK_sacenc_encode() call.
+ */
+typedef struct {
+ INT nOutputBits; /*!< Number of valid payload bits generated during
+ FDK_sacenc_encode(). */
+ INT nOutputSamples; /*!< Number of valid output audio samples generated during
+ FDK_sacenc_encode(). */
+ UINT nSamplesConsumed; /*!< Number of input audio samples consumed in
+ FDK_sacenc_encode(). */
+
+} SACENC_OutArgs;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/**
+ * \brief Opens a new instace of the MPEG Surround encoder.
+ *
+ * \param phMp4SpaceEnc Pointer to the encoder handle to be deallocated.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, SACENC_MEMORY_ERROR, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_open(HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc);
+
+/**
+ * \brief Finalizes opening process of MPEG Surround encoder.
+ *
+ * Shows, how many samples are needed as input
+ *
+ * \param hMp4SpaceEnc A valid MPEG Surround encoder handle.
+ * \param dmxDelay Downmix delay.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, SACENC_INIT_ERROR, SACENC_INVALID_CONFIG,
+ * on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_init(HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ const INT dmxDelay);
+
+/**
+ * \brief Close the MPEG Surround encoder instance.
+ *
+ * Deallocate encoder instance and free whole memory.
+ *
+ * \param phMp4SpaceEnc Pointer to the encoder handle to be deallocated.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_close(HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc);
+
+/**
+ * \brief MPEG surround parameter extraction, framwise.
+ *
+ * \param hMp4SpaceEnc A valid MPEG Surround encoder handle.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_encode(const HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ const FDK_bufDescr *inBufDesc,
+ const FDK_bufDescr *outBufDesc,
+ const SACENC_InArgs *inargs,
+ SACENC_OutArgs *outargs);
+
+/**
+ * \brief Provides information on produced bitstream.
+ *
+ * \param hMp4SpaceEnc A valid MPEG Surround encoder handle.
+ * \param pInfo Pointer to an encoder info struct, filled on
+ * return.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_getInfo(const HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ MP4SPACEENC_INFO *const pInfo);
+
+/**
+ * \brief Set one single MPEG Surround encoder parameter.
+ *
+ * This function allows configuration of all encoder parameters specified in
+ * ::SPACEENC_PARAM. Each parameter must be set with a separate function call.
+ * An internal validation of the configuration value range will be done.
+ *
+ * \param hMp4SpaceEnc A valid MPEG Surround encoder handle.
+ * \param param Parameter to be set. See ::SPACEENC_PARAM.
+ * \param value Parameter value. See parameter description in
+ * ::SPACEENC_PARAM.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, SACENC_UNSUPPORTED_PARAMETER,
+ * SACENC_INVALID_CONFIG, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_setParam(HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ const SPACEENC_PARAM param,
+ const UINT value);
+
+/**
+ * \brief Get information about MPEG Surround encoder library build.
+ *
+ * Fill a given LIB_INFO structure with library version information.
+ *
+ * \param info Pointer to an allocated LIB_INFO struct.
+ *
+ * \return
+ * - SACENC_OK, on success.
+ * - SACENC_INVALID_HANDLE, SACENC_INIT_ERROR, on failure.
+ */
+FDK_SACENC_ERROR FDK_sacenc_getLibInfo(LIB_INFO *info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SACENC_LIB_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_bitstream.cpp b/fdk-aac/libSACenc/src/sacenc_bitstream.cpp
new file mode 100644
index 0000000..dacfc27
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_bitstream.cpp
@@ -0,0 +1,826 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s):
+
+ Description: Encoder Library Interface
+ Bitstream Writer
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_bitstream.h"
+#include "sacenc_const.h"
+
+#include "genericStds.h"
+#include "common_fix.h"
+
+#include "FDK_matrixCalloc.h"
+#include "sacenc_nlc_enc.h"
+
+/* Defines *******************************************************************/
+#define MAX_FREQ_RES_INDEX 8
+#define MAX_SAMPLING_FREQUENCY_INDEX 13
+#define SAMPLING_FREQUENCY_INDEX_ESCAPE 15
+
+/* Data Types ****************************************************************/
+typedef struct {
+ SCHAR cld_old[SACENC_MAX_NUM_BOXES][MAX_NUM_BINS];
+ SCHAR icc_old[SACENC_MAX_NUM_BOXES][MAX_NUM_BINS];
+ UCHAR quantCoarseCldPrev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+ UCHAR quantCoarseIccPrev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+
+} PREV_OTTDATA;
+
+typedef struct {
+ PREV_OTTDATA prevOttData;
+
+} STATIC_SPATIALFRAME;
+
+typedef struct BSF_INSTANCE {
+ SPATIALSPECIFICCONFIG spatialSpecificConfig;
+ SPATIALFRAME frame;
+ STATIC_SPATIALFRAME prevFrameData;
+
+} BSF_INSTANCE;
+
+/* Constants *****************************************************************/
+static const INT SampleRateTable[MAX_SAMPLING_FREQUENCY_INDEX] = {
+ 96000, 88200, 64000, 48000, 44100, 32000, 24000,
+ 22050, 16000, 12000, 11025, 8000, 7350};
+
+static const UCHAR FreqResBinTable_LD[MAX_FREQ_RES_INDEX] = {0, 23, 15, 12,
+ 9, 7, 5, 4};
+static const UCHAR FreqResStrideTable_LD[] = {1, 2, 5, 23};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static FDK_SACENC_ERROR DuplicateLosslessData(
+ const INT startBox, const INT stopBox,
+ const LOSSLESSDATA *const hLosslessDataFrom, const INT setFrom,
+ LOSSLESSDATA *const hLosslessDataTo, const INT setTo) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hLosslessDataFrom) || (NULL == hLosslessDataTo)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i;
+
+ for (i = startBox; i < stopBox; i++) {
+ hLosslessDataTo->bsXXXDataMode[i][setTo] =
+ hLosslessDataFrom->bsXXXDataMode[i][setFrom];
+ hLosslessDataTo->bsDataPair[i][setTo] =
+ hLosslessDataFrom->bsDataPair[i][setFrom];
+ hLosslessDataTo->bsQuantCoarseXXX[i][setTo] =
+ hLosslessDataFrom->bsQuantCoarseXXX[i][setFrom];
+ hLosslessDataTo->bsFreqResStrideXXX[i][setTo] =
+ hLosslessDataFrom->bsFreqResStrideXXX[i][setFrom];
+ }
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_duplicateParameterSet(
+ const SPATIALFRAME *const hFrom, const INT setFrom, SPATIALFRAME *const hTo,
+ const INT setTo) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hFrom) || (NULL == hTo)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int box;
+ /* Only Copy Parameter Set selective stuff */
+
+ /* OTT-Data */
+ for (box = 0; box < SACENC_MAX_NUM_BOXES; box++) {
+ FDKmemcpy(hTo->ottData.cld[box][setTo], hFrom->ottData.cld[box][setFrom],
+ sizeof(hFrom->ottData.cld[0][0]));
+ FDKmemcpy(hTo->ottData.icc[box][setTo], hFrom->ottData.icc[box][setFrom],
+ sizeof(hFrom->ottData.icc[0][0]));
+ }
+
+ /* LOSSLESSDATA */
+ DuplicateLosslessData(0, SACENC_MAX_NUM_BOXES, &hFrom->CLDLosslessData,
+ setFrom, &hTo->CLDLosslessData, setTo);
+ DuplicateLosslessData(0, SACENC_MAX_NUM_BOXES, &hFrom->ICCLosslessData,
+ setFrom, &hTo->ICCLosslessData, setTo);
+
+ } /* valid handle */
+
+ return error;
+}
+
+/* set frame defaults */
+static void clearFrame(SPATIALFRAME *const pFrame) {
+ FDKmemclear(pFrame, sizeof(SPATIALFRAME));
+
+ pFrame->bsIndependencyFlag = 1;
+ pFrame->framingInfo.numParamSets = 1;
+}
+
+static void fine2coarse(SCHAR *const data, const DATA_TYPE dataType,
+ const INT startBand, const INT numBands) {
+ int i;
+ if (dataType == t_CLD) {
+ for (i = startBand; i < startBand + numBands; i++) {
+ data[i] /= 2;
+ }
+ } else {
+ for (i = startBand; i < startBand + numBands; i++) {
+ data[i] >>= 1;
+ }
+ }
+}
+
+static void coarse2fine(SCHAR *const data, const DATA_TYPE dataType,
+ const INT startBand, const INT numBands) {
+ int i;
+
+ for (i = startBand; i < startBand + numBands; i++) {
+ data[i] <<= 1;
+ }
+
+ if (dataType == t_CLD) {
+ for (i = startBand; i < startBand + numBands; i++) {
+ if (data[i] == -14) {
+ data[i] = -15;
+ } else if (data[i] == 14) {
+ data[i] = 15;
+ }
+ }
+ } /* (dataType == t_CLD) */
+}
+
+static UCHAR getBsFreqResStride(const INT index) {
+ const UCHAR *pFreqResStrideTable = NULL;
+ int freqResStrideTableSize = 0;
+
+ pFreqResStrideTable = FreqResStrideTable_LD;
+ freqResStrideTableSize =
+ sizeof(FreqResStrideTable_LD) / sizeof(*FreqResStrideTable_LD);
+
+ return (((NULL != pFreqResStrideTable) && (index >= 0) &&
+ (index < freqResStrideTableSize))
+ ? pFreqResStrideTable[index]
+ : 1);
+}
+
+/* write data to bitstream */
+static void ecData(HANDLE_FDK_BITSTREAM bitstream,
+ SCHAR data[MAX_NUM_PARAMS][MAX_NUM_BINS],
+ SCHAR oldData[MAX_NUM_BINS],
+ UCHAR quantCoarseXXXprev[MAX_NUM_PARAMS],
+ LOSSLESSDATA *const losslessData, const DATA_TYPE dataType,
+ const INT paramIdx, const INT numParamSets,
+ const INT independencyFlag, const INT startBand,
+ const INT stopBand, const INT defaultValue) {
+ int ps, pb, strOffset, pbStride, dataBands, i;
+ int aStrides[MAX_NUM_BINS + 1] = {0};
+ SHORT cmpIdxData[2][MAX_NUM_BINS] = {{0}};
+ SHORT cmpOldData[MAX_NUM_BINS] = {0};
+
+ /* bsXXXDataMode */
+ if (independencyFlag || (losslessData->bsQuantCoarseXXX[paramIdx][0] !=
+ quantCoarseXXXprev[paramIdx])) {
+ losslessData->bsXXXDataMode[paramIdx][0] = FINECOARSE;
+ } else {
+ losslessData->bsXXXDataMode[paramIdx][0] = KEEP;
+ for (i = startBand; i < stopBand; i++) {
+ if (data[0][i] != oldData[i]) {
+ losslessData->bsXXXDataMode[paramIdx][0] = FINECOARSE;
+ break;
+ }
+ }
+ }
+
+ FDKwriteBits(bitstream, losslessData->bsXXXDataMode[paramIdx][0], 2);
+
+ for (ps = 1; ps < numParamSets; ps++) {
+ if (losslessData->bsQuantCoarseXXX[paramIdx][ps] !=
+ losslessData->bsQuantCoarseXXX[paramIdx][ps - 1]) {
+ losslessData->bsXXXDataMode[paramIdx][ps] = FINECOARSE;
+ } else {
+ losslessData->bsXXXDataMode[paramIdx][ps] = KEEP;
+ for (i = startBand; i < stopBand; i++) {
+ if (data[ps][i] != data[ps - 1][i]) {
+ losslessData->bsXXXDataMode[paramIdx][ps] = FINECOARSE;
+ break;
+ }
+ }
+ }
+
+ FDKwriteBits(bitstream, losslessData->bsXXXDataMode[paramIdx][ps], 2);
+ } /* for ps */
+
+ /* Create data pairs if possible */
+ for (ps = 0; ps < (numParamSets - 1); ps++) {
+ if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE) {
+ /* Check if next parameter set is FINCOARSE */
+ if (losslessData->bsXXXDataMode[paramIdx][ps + 1] == FINECOARSE) {
+ /* We have to check if ps and ps+1 use the same bsXXXQuantMode */
+ /* and also have the same stride */
+ if ((losslessData->bsQuantCoarseXXX[paramIdx][ps + 1] ==
+ losslessData->bsQuantCoarseXXX[paramIdx][ps]) &&
+ (losslessData->bsFreqResStrideXXX[paramIdx][ps + 1] ==
+ losslessData->bsFreqResStrideXXX[paramIdx][ps])) {
+ losslessData->bsDataPair[paramIdx][ps] = 1;
+ losslessData->bsDataPair[paramIdx][ps + 1] = 1;
+
+ /* We have a data pair -> Jump to the ps after next ps*/
+ ps++;
+ continue;
+ }
+ }
+ /* dataMode of next ps is not FINECOARSE or does not use the same
+ * bsXXXQuantMode/stride */
+ /* -> no dataPair possible */
+ losslessData->bsDataPair[paramIdx][ps] = 0;
+
+ /* Initialize ps after next ps to Zero (only important for the last
+ * parameter set) */
+ losslessData->bsDataPair[paramIdx][ps + 1] = 0;
+ } else {
+ /* No FINECOARSE -> no data pair possible */
+ losslessData->bsDataPair[paramIdx][ps] = 0;
+
+ /* Initialize ps after next ps to Zero (only important for the last
+ * parameter set) */
+ losslessData->bsDataPair[paramIdx][ps + 1] = 0;
+ }
+ } /* for ps */
+
+ for (ps = 0; ps < numParamSets; ps++) {
+ if (losslessData->bsXXXDataMode[paramIdx][ps] == DEFAULT) {
+ /* Prepare old data */
+ for (i = startBand; i < stopBand; i++) {
+ oldData[i] = defaultValue;
+ }
+ quantCoarseXXXprev[paramIdx] = 0; /* Default data are always fine */
+ }
+
+ if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE) {
+ FDKwriteBits(bitstream, losslessData->bsDataPair[paramIdx][ps], 1);
+ FDKwriteBits(bitstream, losslessData->bsQuantCoarseXXX[paramIdx][ps], 1);
+ FDKwriteBits(bitstream, losslessData->bsFreqResStrideXXX[paramIdx][ps],
+ 2);
+
+ if (losslessData->bsQuantCoarseXXX[paramIdx][ps] !=
+ quantCoarseXXXprev[paramIdx]) {
+ if (quantCoarseXXXprev[paramIdx]) {
+ coarse2fine(oldData, dataType, startBand, stopBand - startBand);
+ } else {
+ fine2coarse(oldData, dataType, startBand, stopBand - startBand);
+ }
+ }
+
+ /* Handle strides */
+ pbStride =
+ getBsFreqResStride(losslessData->bsFreqResStrideXXX[paramIdx][ps]);
+ dataBands = (stopBand - startBand - 1) / pbStride + 1;
+
+ aStrides[0] = startBand;
+ for (pb = 1; pb <= dataBands; pb++) {
+ aStrides[pb] = aStrides[pb - 1] + pbStride;
+ }
+
+ strOffset = 0;
+ while (aStrides[dataBands] > stopBand) {
+ if (strOffset < dataBands) {
+ strOffset++;
+ }
+ for (i = strOffset; i <= dataBands; i++) {
+ aStrides[i]--;
+ }
+ } /* while */
+
+ for (pb = 0; pb < dataBands; pb++) {
+ cmpOldData[startBand + pb] = oldData[aStrides[pb]];
+ cmpIdxData[0][startBand + pb] = data[ps][aStrides[pb]];
+
+ if (losslessData->bsDataPair[paramIdx][ps]) {
+ cmpIdxData[1][startBand + pb] = data[ps + 1][aStrides[pb]];
+ }
+ } /* for pb*/
+
+ /* Finally encode */
+ if (losslessData->bsDataPair[paramIdx][ps]) {
+ fdk_sacenc_ecDataPairEnc(bitstream, cmpIdxData, cmpOldData, dataType, 0,
+ startBand, dataBands,
+ losslessData->bsQuantCoarseXXX[paramIdx][ps],
+ independencyFlag && (ps == 0));
+ } else {
+ fdk_sacenc_ecDataSingleEnc(bitstream, cmpIdxData, cmpOldData, dataType,
+ 0, startBand, dataBands,
+ losslessData->bsQuantCoarseXXX[paramIdx][ps],
+ independencyFlag && (ps == 0));
+ }
+
+ /* Overwrite old data */
+ for (i = startBand; i < stopBand; i++) {
+ if (losslessData->bsDataPair[paramIdx][ps]) {
+ oldData[i] = data[ps + 1][i];
+ } else {
+ oldData[i] = data[ps][i];
+ }
+ }
+
+ quantCoarseXXXprev[paramIdx] =
+ losslessData->bsQuantCoarseXXX[paramIdx][ps];
+
+ /* Jump forward if we have encoded a data pair */
+ if (losslessData->bsDataPair[paramIdx][ps]) {
+ ps++;
+ }
+
+ } /* if (losslessData->bsXXXDataMode[paramIdx][ps] == FINECOARSE ) */
+ } /* for ps */
+}
+
+/****************************************************************************/
+/* Bitstream formatter interface functions */
+/****************************************************************************/
+static FDK_SACENC_ERROR getBsFreqResIndex(const INT numBands,
+ INT *const pbsFreqResIndex) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pbsFreqResIndex) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ const UCHAR *pFreqResBinTable = FreqResBinTable_LD;
+ int i;
+ *pbsFreqResIndex = -1;
+
+ for (i = 0; i < MAX_FREQ_RES_INDEX; i++) {
+ if (numBands == pFreqResBinTable[i]) {
+ *pbsFreqResIndex = i;
+ break;
+ }
+ }
+ if (*pbsFreqResIndex < 0 || *pbsFreqResIndex >= MAX_FREQ_RES_INDEX) {
+ error = SACENC_INVALID_CONFIG;
+ }
+ }
+ return error;
+}
+
+static FDK_SACENC_ERROR getSamplingFrequencyIndex(
+ const INT bsSamplingFrequency, INT *const pbsSamplingFrequencyIndex) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pbsSamplingFrequencyIndex) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i;
+ *pbsSamplingFrequencyIndex = SAMPLING_FREQUENCY_INDEX_ESCAPE;
+
+ for (i = 0; i < MAX_SAMPLING_FREQUENCY_INDEX; i++) {
+ if (bsSamplingFrequency == SampleRateTable[i]) { /*spatial sampling rate*/
+ *pbsSamplingFrequencyIndex = i;
+ break;
+ }
+ }
+ }
+ return error;
+}
+
+/* destroy encoder instance */
+FDK_SACENC_ERROR fdk_sacenc_destroySpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE *selfPtr) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((selfPtr == NULL) || (*selfPtr == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if (*selfPtr != NULL) {
+ FDK_FREE_MEMORY_1D(*selfPtr);
+ }
+ }
+ return error;
+}
+
+/* create encoder instance */
+FDK_SACENC_ERROR fdk_sacenc_createSpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE *selfPtr) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == selfPtr) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* allocate encoder struct */
+ FDK_ALLOCATE_MEMORY_1D(*selfPtr, 1, BSF_INSTANCE);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_destroySpatialBitstreamEncoder(selfPtr);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+/* init encoder instance */
+FDK_SACENC_ERROR fdk_sacenc_initSpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE selfPtr) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (selfPtr == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* init/clear */
+ clearFrame(&selfPtr->frame);
+
+ } /* valid handle */
+ return error;
+}
+
+/* get SpatialSpecificConfig struct */
+SPATIALSPECIFICCONFIG *fdk_sacenc_getSpatialSpecificConfig(
+ HANDLE_BSF_INSTANCE selfPtr) {
+ return ((selfPtr == NULL) ? NULL : &(selfPtr->spatialSpecificConfig));
+}
+
+/* write SpatialSpecificConfig to stream */
+FDK_SACENC_ERROR fdk_sacenc_writeSpatialSpecificConfig(
+ SPATIALSPECIFICCONFIG *const spatialSpecificConfig,
+ UCHAR *const pOutputBuffer, const INT outputBufferSize,
+ INT *const pnOutputBits) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+ INT bsSamplingFrequencyIndex = 0;
+ INT bsFreqRes = 0;
+
+ if ((spatialSpecificConfig == NULL) || (pOutputBuffer == NULL) ||
+ (pnOutputBits == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDK_BITSTREAM bitstream;
+
+ /* Find FreqRes */
+ if (SACENC_OK != (error = getBsFreqResIndex(spatialSpecificConfig->numBands,
+ &bsFreqRes)))
+ goto bail;
+
+ /* Find SamplingFrequencyIndex */
+ if (SACENC_OK != (error = getSamplingFrequencyIndex(
+ spatialSpecificConfig->bsSamplingFrequency,
+ &bsSamplingFrequencyIndex)))
+ goto bail;
+
+ /* bind extern buffer to bitstream handle */
+ FDKinitBitStream(&bitstream, pOutputBuffer, outputBufferSize, 0, BS_WRITER);
+
+ /****************************************************************************/
+ /* write to bitstream */
+
+ FDKwriteBits(&bitstream, bsSamplingFrequencyIndex, 4);
+
+ if (bsSamplingFrequencyIndex == 15) {
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsSamplingFrequency, 24);
+ }
+
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsFrameLength, 5);
+
+ FDKwriteBits(&bitstream, bsFreqRes, 3);
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsTreeConfig, 4);
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsQuantMode, 2);
+
+ FDKwriteBits(&bitstream, 0, 1); /* bsArbitraryDownmix */
+
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsFixedGainDMX, 3);
+
+ FDKwriteBits(&bitstream, TEMPSHAPE_OFF, 2);
+ FDKwriteBits(&bitstream, spatialSpecificConfig->bsDecorrConfig, 2);
+
+ FDKbyteAlign(&bitstream, 0); /* byte alignment */
+
+ /* return number of valid bits in bitstream */
+ if ((*pnOutputBits = FDKgetValidBits(&bitstream)) >
+ (outputBufferSize * 8)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* terminate buffer with alignment */
+ FDKbyteAlign(&bitstream, 0);
+
+ } /* valid handle */
+
+bail:
+ return error;
+}
+
+/* get SpatialFrame struct */
+SPATIALFRAME *fdk_sacenc_getSpatialFrame(HANDLE_BSF_INSTANCE selfPtr,
+ const SPATIALFRAME_TYPE frameType) {
+ int idx = -1;
+
+ switch (frameType) {
+ case READ_SPATIALFRAME:
+ case WRITE_SPATIALFRAME:
+ idx = 0;
+ break;
+ default:
+ idx = -1; /* invalid configuration */
+ } /* switch frameType */
+
+ return (((selfPtr == NULL) || (idx == -1)) ? NULL : &selfPtr->frame);
+}
+
+static FDK_SACENC_ERROR writeFramingInfo(HANDLE_FDK_BITSTREAM hBitstream,
+ const FRAMINGINFO *const pFramingInfo,
+ const INT frameLength) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hBitstream == NULL) || (pFramingInfo == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDKwriteBits(hBitstream, pFramingInfo->bsFramingType, 1);
+ FDKwriteBits(hBitstream, pFramingInfo->numParamSets - 1, 1);
+
+ if (pFramingInfo->bsFramingType) {
+ int ps = 0;
+ int numParamSets = pFramingInfo->numParamSets;
+
+ {
+ for (ps = 0; ps < numParamSets; ps++) {
+ int bitsParamSlot = 0;
+ while ((1 << bitsParamSlot) < (frameLength + 1)) bitsParamSlot++;
+ if (bitsParamSlot > 0)
+ FDKwriteBits(hBitstream, pFramingInfo->bsParamSlots[ps],
+ bitsParamSlot);
+ }
+ }
+ } /* pFramingInfo->bsFramingType */
+ } /* valid handle */
+
+ return error;
+}
+
+static FDK_SACENC_ERROR writeSmgData(HANDLE_FDK_BITSTREAM hBitstream,
+ const SMGDATA *const pSmgData,
+ const INT numParamSets,
+ const INT dataBands) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hBitstream == NULL) || (pSmgData == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i, j;
+
+ for (i = 0; i < numParamSets; i++) {
+ FDKwriteBits(hBitstream, pSmgData->bsSmoothMode[i], 2);
+
+ if (pSmgData->bsSmoothMode[i] >= 2) {
+ FDKwriteBits(hBitstream, pSmgData->bsSmoothTime[i], 2);
+ }
+ if (pSmgData->bsSmoothMode[i] == 3) {
+ const int stride = getBsFreqResStride(pSmgData->bsFreqResStride[i]);
+ FDKwriteBits(hBitstream, pSmgData->bsFreqResStride[i], 2);
+ for (j = 0; j < dataBands; j += stride) {
+ FDKwriteBits(hBitstream, pSmgData->bsSmgData[i][j], 1);
+ }
+ }
+ } /* for i */
+ } /* valid handle */
+
+ return error;
+}
+
+static FDK_SACENC_ERROR writeOttData(
+ HANDLE_FDK_BITSTREAM hBitstream, PREV_OTTDATA *const pPrevOttData,
+ OTTDATA *const pOttData, const OTTCONFIG ottConfig[SACENC_MAX_NUM_BOXES],
+ LOSSLESSDATA *const pCLDLosslessData, LOSSLESSDATA *const pICCLosslessData,
+ const INT numOttBoxes, const INT numBands, const INT numParamSets,
+ const INT bsIndependencyFlag) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hBitstream == NULL) || (pPrevOttData == NULL) || (pOttData == NULL) ||
+ (ottConfig == NULL) || (pCLDLosslessData == NULL) ||
+ (pICCLosslessData == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i;
+ for (i = 0; i < numOttBoxes; i++) {
+ ecData(hBitstream, pOttData->cld[i], pPrevOttData->cld_old[i],
+ pPrevOttData->quantCoarseCldPrev[i], pCLDLosslessData, t_CLD, i,
+ numParamSets, bsIndependencyFlag, 0, ottConfig[i].bsOttBands, 15);
+ }
+ {
+ for (i = 0; i < numOttBoxes; i++) {
+ {
+ ecData(hBitstream, pOttData->icc[i], pPrevOttData->icc_old[i],
+ pPrevOttData->quantCoarseIccPrev[i], pICCLosslessData, t_ICC,
+ i, numParamSets, bsIndependencyFlag, 0, numBands, 0);
+ }
+ } /* for i */
+ }
+ } /* valid handle */
+
+ return error;
+}
+
+/* write extension frame data to stream */
+static FDK_SACENC_ERROR WriteSpatialExtensionFrame(
+ HANDLE_FDK_BITSTREAM bitstream, HANDLE_BSF_INSTANCE self) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((bitstream == NULL) || (self == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDKbyteAlign(bitstream, 0);
+ } /* valid handle */
+
+ return error;
+}
+
+/* write frame data to stream */
+FDK_SACENC_ERROR fdk_sacenc_writeSpatialFrame(UCHAR *const pOutputBuffer,
+ const INT outputBufferSize,
+ INT *const pnOutputBits,
+ HANDLE_BSF_INSTANCE selfPtr) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((pOutputBuffer == NULL) || (pnOutputBits == NULL) || (selfPtr == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ SPATIALFRAME *frame = NULL;
+ SPATIALSPECIFICCONFIG *config = NULL;
+ FDK_BITSTREAM bitstream;
+
+ int i, j, numParamSets, numOttBoxes;
+
+ if ((NULL ==
+ (frame = fdk_sacenc_getSpatialFrame(selfPtr, READ_SPATIALFRAME))) ||
+ (NULL == (config = &(selfPtr->spatialSpecificConfig)))) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ numOttBoxes = selfPtr->spatialSpecificConfig.treeDescription.numOttBoxes;
+
+ numParamSets = frame->framingInfo.numParamSets;
+
+ if (frame->bUseBBCues) {
+ for (i = 0; i < SACENC_MAX_NUM_BOXES; i++) {
+ /* If a transient was detected, force only the second ps broad band */
+ if (numParamSets == 1) {
+ frame->CLDLosslessData.bsFreqResStrideXXX[i][0] = 3;
+ frame->ICCLosslessData.bsFreqResStrideXXX[i][0] = 3;
+ } else {
+ for (j = 1; j < MAX_NUM_PARAMS; j++) {
+ frame->CLDLosslessData.bsFreqResStrideXXX[i][j] = 3;
+ frame->ICCLosslessData.bsFreqResStrideXXX[i][j] = 3;
+ }
+ }
+ }
+ } /* frame->bUseBBCues */
+
+ /* bind extern buffer to bitstream handle */
+ FDKinitBitStream(&bitstream, pOutputBuffer, outputBufferSize, 0, BS_WRITER);
+
+ if (SACENC_OK != (error = writeFramingInfo(
+ &bitstream, &(frame->framingInfo),
+ selfPtr->spatialSpecificConfig.bsFrameLength))) {
+ goto bail;
+ }
+
+ /* write bsIndependencyFlag */
+ FDKwriteBits(&bitstream, frame->bsIndependencyFlag, 1);
+
+ /* write spatial data to bitstream */
+ if (SACENC_OK !=
+ (error = writeOttData(&bitstream, &selfPtr->prevFrameData.prevOttData,
+ &frame->ottData, config->ottConfig,
+ &frame->CLDLosslessData, &frame->ICCLosslessData,
+ numOttBoxes, config->numBands, numParamSets,
+ frame->bsIndependencyFlag))) {
+ goto bail;
+ }
+ if (SACENC_OK != (error = writeSmgData(&bitstream, &frame->smgData,
+ numParamSets, config->numBands))) {
+ goto bail;
+ }
+
+ /* byte alignment */
+ FDKbyteAlign(&bitstream, 0);
+
+ /* Write SpatialExtensionFrame */
+ if (SACENC_OK !=
+ (error = WriteSpatialExtensionFrame(&bitstream, selfPtr))) {
+ goto bail;
+ }
+
+ if (NULL ==
+ (frame = fdk_sacenc_getSpatialFrame(selfPtr, WRITE_SPATIALFRAME))) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ clearFrame(frame);
+
+ /* return number of valid bits in bitstream */
+ if ((*pnOutputBits = FDKgetValidBits(&bitstream)) >
+ (outputBufferSize * 8)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* terminate buffer with alignment */
+ FDKbyteAlign(&bitstream, 0);
+
+ } /* valid handle */
+
+bail:
+ return error;
+}
diff --git a/fdk-aac/libSACenc/src/sacenc_bitstream.h b/fdk-aac/libSACenc/src/sacenc_bitstream.h
new file mode 100644
index 0000000..67b7b5a
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_bitstream.h
@@ -0,0 +1,296 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s):
+
+ Description: Encoder Library Interface
+ Bitstream Writer
+
+*******************************************************************************/
+
+#ifndef SACENC_BITSTREAM_H
+#define SACENC_BITSTREAM_H
+
+/* Includes ******************************************************************/
+#include "FDK_bitstream.h"
+#include "FDK_matrixCalloc.h"
+#include "sacenc_lib.h"
+#include "sacenc_const.h"
+
+/* Defines *******************************************************************/
+#define MAX_NUM_BINS 23
+#define MAX_NUM_PARAMS 2
+#define MAX_NUM_OUTPUTCHANNELS SACENC_MAX_OUTPUT_CHANNELS
+#define MAX_TIME_SLOTS 32
+
+typedef enum {
+ TREE_212 = 7,
+ TREE_ESCAPE = 15
+
+} TREECONFIG;
+
+typedef enum {
+ FREQ_RES_40 = 0,
+ FREQ_RES_20 = 1,
+ FREQ_RES_10 = 2,
+ FREQ_RES_5 = 3
+
+} FREQ;
+
+typedef enum {
+ QUANTMODE_INVALID = -1,
+ QUANTMODE_FINE = 0,
+ QUANTMODE_EBQ1 = 1,
+ QUANTMODE_EBQ2 = 2
+
+} QUANTMODE;
+
+typedef enum {
+ TEMPSHAPE_OFF = 0
+
+} TEMPSHAPECONFIG;
+
+typedef enum {
+ FIXEDGAINDMX_INVALID = -1,
+ FIXEDGAINDMX_0 = 0,
+ FIXEDGAINDMX_1 = 1,
+ FIXEDGAINDMX_2 = 2,
+ FIXEDGAINDMX_3 = 3,
+ FIXEDGAINDMX_4 = 4,
+ FIXEDGAINDMX_5 = 5,
+ FIXEDGAINDMX_6 = 6,
+ FIXEDGAINDMX_7 = 7
+
+} FIXEDGAINDMXCONFIG;
+
+typedef enum {
+ DECORR_INVALID = -1,
+ DECORR_QMFSPLIT0 = 0, /* QMF splitfreq: 3, 15, 24, 65 */
+ DECORR_QMFSPLIT1 = 1, /* QMF splitfreq: 3, 50, 65, 65 */
+ DECORR_QMFSPLIT2 = 2 /* QMF splitfreq: 0, 15, 65, 65 */
+
+} DECORRCONFIG;
+
+typedef enum {
+ DEFAULT = 0,
+ KEEP = 1,
+ INTERPOLATE = 2,
+ FINECOARSE = 3
+
+} DATA_MODE;
+
+typedef enum {
+ READ_SPATIALFRAME = 0,
+ WRITE_SPATIALFRAME = 1
+
+} SPATIALFRAME_TYPE;
+
+/* Data Types ****************************************************************/
+typedef struct {
+ INT numOttBoxes;
+ INT numInChan;
+ INT numOutChan;
+
+} TREEDESCRIPTION;
+
+typedef struct {
+ INT bsOttBands;
+
+} OTTCONFIG;
+
+typedef struct {
+ INT bsSamplingFrequency; /* for bsSamplingFrequencyIndex */
+ INT bsFrameLength;
+ INT numBands; /* for bsFreqRes */
+ TREECONFIG bsTreeConfig;
+ QUANTMODE bsQuantMode;
+ FIXEDGAINDMXCONFIG bsFixedGainDMX;
+ int bsEnvQuantMode;
+ DECORRCONFIG bsDecorrConfig;
+ TREEDESCRIPTION treeDescription;
+ OTTCONFIG ottConfig[SACENC_MAX_NUM_BOXES];
+
+} SPATIALSPECIFICCONFIG;
+
+typedef struct {
+ UCHAR bsFramingType;
+ UCHAR numParamSets;
+ UCHAR bsParamSlots[MAX_NUM_PARAMS];
+
+} FRAMINGINFO;
+
+typedef struct {
+ SCHAR cld[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS][MAX_NUM_BINS];
+ SCHAR icc[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS][MAX_NUM_BINS];
+
+} OTTDATA;
+
+typedef struct {
+ UCHAR bsSmoothMode[MAX_NUM_PARAMS];
+ UCHAR bsSmoothTime[MAX_NUM_PARAMS];
+ UCHAR bsFreqResStride[MAX_NUM_PARAMS];
+ UCHAR bsSmgData[MAX_NUM_PARAMS][MAX_NUM_BINS];
+
+} SMGDATA;
+
+typedef struct {
+ UCHAR bsEnvShapeChannel[MAX_NUM_OUTPUTCHANNELS];
+ UCHAR bsEnvShapeData[MAX_NUM_OUTPUTCHANNELS][MAX_TIME_SLOTS];
+
+} TEMPSHAPEDATA;
+
+typedef struct {
+ UCHAR bsXXXDataMode[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+ UCHAR bsDataPair[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+ UCHAR bsQuantCoarseXXX[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+ UCHAR bsFreqResStrideXXX[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAMS];
+
+} LOSSLESSDATA;
+
+typedef struct {
+ FRAMINGINFO framingInfo;
+ UCHAR bsIndependencyFlag;
+ OTTDATA ottData;
+ SMGDATA smgData;
+ TEMPSHAPEDATA tempShapeData;
+ LOSSLESSDATA CLDLosslessData;
+ LOSSLESSDATA ICCLosslessData;
+ UCHAR bUseBBCues;
+
+} SPATIALFRAME;
+
+typedef struct BSF_INSTANCE *HANDLE_BSF_INSTANCE;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+/* destroy encoder instance */
+FDK_SACENC_ERROR fdk_sacenc_destroySpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE *selfPtr);
+
+/* create encoder instance */
+FDK_SACENC_ERROR fdk_sacenc_createSpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE *selfPtr);
+
+FDK_SACENC_ERROR fdk_sacenc_initSpatialBitstreamEncoder(
+ HANDLE_BSF_INSTANCE selfPtr);
+
+/* get SpatialSpecificConfig struct */
+SPATIALSPECIFICCONFIG *fdk_sacenc_getSpatialSpecificConfig(
+ HANDLE_BSF_INSTANCE selfPtr);
+
+/* write SpatialSpecificConfig to stream */
+FDK_SACENC_ERROR fdk_sacenc_writeSpatialSpecificConfig(
+ SPATIALSPECIFICCONFIG *const spatialSpecificConfig,
+ UCHAR *const pOutputBuffer, const INT outputBufferSize,
+ INT *const pnOutputBits);
+
+/* get SpatialFrame struct */
+SPATIALFRAME *fdk_sacenc_getSpatialFrame(HANDLE_BSF_INSTANCE selfPtr,
+ const SPATIALFRAME_TYPE frameType);
+
+/* write frame data to stream */
+FDK_SACENC_ERROR fdk_sacenc_writeSpatialFrame(UCHAR *const pOutputBuffer,
+ const INT outputBufferSize,
+ INT *const pnOutputBits,
+ HANDLE_BSF_INSTANCE selfPtr);
+
+/* Copy/Save spatial frame data for one parameter set */
+FDK_SACENC_ERROR fdk_sacenc_duplicateParameterSet(
+ const SPATIALFRAME *const hFrom, const INT setFrom, SPATIALFRAME *const hTo,
+ const INT setTo);
+
+#endif /* SACENC_BITSTREAM_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_const.h b/fdk-aac/libSACenc/src/sacenc_const.h
new file mode 100644
index 0000000..c86e765
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_const.h
@@ -0,0 +1,126 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Markus Multrus
+
+ Description: Encoder Library Interface
+ constants to MPEG-4 spatial encoder lib
+
+*******************************************************************************/
+
+#ifndef SACENC_CONST_H
+#define SACENC_CONST_H
+
+/* Includes ******************************************************************/
+#include "machine_type.h"
+
+/* Defines *******************************************************************/
+#define NUM_QMF_BANDS 64
+#define MAX_QMF_BANDS 128
+
+#define SACENC_MAX_NUM_BOXES 1
+#define SACENC_MAX_INPUT_CHANNELS 2
+#define SACENC_MAX_OUTPUT_CHANNELS 1
+
+#define SACENC_FLOAT_EPSILON (1e-9f)
+
+/* Data Types ****************************************************************/
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+#endif /* SACENC_CONST_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_delay.cpp b/fdk-aac/libSACenc/src/sacenc_delay.cpp
new file mode 100644
index 0000000..f2ed6b0
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_delay.cpp
@@ -0,0 +1,472 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Christian Goettlinger
+
+ Description: Encoder Library Interface
+ delay management of the encoder
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ This file contains all delay infrastructure
+ ******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_delay.h"
+#include "sacenc_const.h"
+#include "FDK_matrixCalloc.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+struct DELAY {
+ struct DELAY_CONFIG {
+ /* Routing Config Switches*/
+ INT bDmxAlign;
+ INT bTimeDomDmx;
+ INT bMinimizeDelay;
+ INT bSacTimeAlignmentDynamicOut;
+
+ /* Needed Input Variables*/
+ INT nQmfLen;
+ INT nFrameLen;
+ INT nSurroundDelay;
+ INT nArbDmxDelay;
+ INT nLimiterDelay;
+ INT nCoreCoderDelay;
+ INT nSacStreamMuxDelay;
+ INT nSacTimeAlignment; /* Overwritten, if bSacTimeAlignmentDynamicOut */
+ } config;
+
+ /* Variable Delaybuffers -> Delays */
+ INT nDmxAlignBuffer;
+ INT nSurroundAnalysisBuffer;
+ INT nArbDmxAnalysisBuffer;
+ INT nOutputAudioBuffer;
+ INT nBitstreamFrameBuffer;
+ INT nOutputAudioQmfFrameBuffer;
+ INT nDiscardOutFrames;
+
+ /* Variable Delaybuffers Computation Variables */
+ INT nBitstreamFrameBufferSize;
+
+ /* Output: Infos */
+ INT nInfoDmxDelay; /* Delay of the downmixed signal after the space encoder */
+ INT nInfoCodecDelay; /* Delay of the whole en-/decoder including CoreCoder */
+ INT nInfoDecoderDelay; /* Delay of the Mpeg Surround decoder */
+};
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_delay_Open()
+description: initializes Delays
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_delay_Open(HANDLE_DELAY *phDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == phDelay) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDK_ALLOCATE_MEMORY_1D(*phDelay, 1, struct DELAY);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_delay_Close(phDelay);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_delay_Close()
+description: destructs Delay
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_delay_Close(HANDLE_DELAY *phDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == phDelay) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if (NULL != *phDelay) {
+ FDK_FREE_MEMORY_1D(*phDelay);
+ }
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_Init(HANDLE_DELAY hDelay, const INT nQmfLen,
+ const INT nFrameLen,
+ const INT nCoreCoderDelay,
+ const INT nSacStreamMuxDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hDelay) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Fill structure before calculation */
+ FDKmemclear(&hDelay->config, sizeof(hDelay->config));
+
+ hDelay->config.nQmfLen = nQmfLen;
+ hDelay->config.nFrameLen = nFrameLen;
+ hDelay->config.nCoreCoderDelay = nCoreCoderDelay;
+ hDelay->config.nSacStreamMuxDelay = nSacStreamMuxDelay;
+ }
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_delay_SubCalulateBufferDelays()
+description: Calculates the Delays of the buffers
+returns: Error Code
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_delay_SubCalulateBufferDelays(HANDLE_DELAY hDel) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hDel) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int nEncoderAnDelay, nEncoderSynDelay, nEncoderWinDelay, nDecoderAnDelay,
+ nDecoderSynDelay, nResidualCoderFrameDelay,
+ nArbDmxResidualCoderFrameDelay;
+
+ if (hDel->config.bSacTimeAlignmentDynamicOut > 0) {
+ hDel->config.nSacTimeAlignment = 0;
+ }
+
+ {
+ nEncoderAnDelay =
+ 2 * hDel->config.nQmfLen +
+ hDel->config.nQmfLen / 2; /* Only Ld-QMF Delay, no hybrid */
+ nEncoderSynDelay = 1 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
+ nDecoderAnDelay = 2 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
+ nDecoderSynDelay = 1 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
+ nEncoderWinDelay =
+ hDel->config.nFrameLen / 2; /* WindowLookahead is just half a frame */
+ }
+
+ { nResidualCoderFrameDelay = 0; }
+
+ { nArbDmxResidualCoderFrameDelay = 0; }
+
+ /* Calculate variable Buffer-Delays */
+ if (hDel->config.bTimeDomDmx == 0) {
+ /* ArbitraryDmx and TdDmx off */
+ int tempDelay;
+
+ hDel->nSurroundAnalysisBuffer = 0;
+ hDel->nArbDmxAnalysisBuffer = 0;
+ tempDelay = nEncoderSynDelay + hDel->config.nLimiterDelay +
+ hDel->config.nCoreCoderDelay +
+ hDel->config.nSacTimeAlignment + nDecoderAnDelay;
+ tempDelay = (nResidualCoderFrameDelay * hDel->config.nFrameLen) +
+ hDel->config.nSacStreamMuxDelay - tempDelay;
+
+ if (tempDelay > 0) {
+ hDel->nBitstreamFrameBuffer = 0;
+ hDel->nOutputAudioBuffer = tempDelay;
+ } else {
+ tempDelay = -tempDelay;
+ hDel->nBitstreamFrameBuffer =
+ (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
+ hDel->nOutputAudioBuffer =
+ (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen) - tempDelay;
+ }
+
+ hDel->nOutputAudioQmfFrameBuffer =
+ (hDel->nOutputAudioBuffer + (hDel->config.nQmfLen / 2) - 1) /
+ hDel->config.nQmfLen;
+
+ if (hDel->config.bDmxAlign > 0) {
+ tempDelay = nEncoderWinDelay + nEncoderAnDelay + nEncoderSynDelay +
+ hDel->nOutputAudioBuffer + hDel->config.nLimiterDelay +
+ hDel->config.nCoreCoderDelay;
+ hDel->nDiscardOutFrames =
+ (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
+ hDel->nDmxAlignBuffer =
+ hDel->nDiscardOutFrames * hDel->config.nFrameLen - tempDelay;
+ } else {
+ hDel->nDiscardOutFrames = 0;
+ hDel->nDmxAlignBuffer = 0;
+ }
+
+ /* Output: Info-Variables */
+ hDel->nInfoDmxDelay = hDel->nSurroundAnalysisBuffer + nEncoderAnDelay +
+ nEncoderWinDelay + nEncoderSynDelay +
+ hDel->nOutputAudioBuffer +
+ hDel->config.nLimiterDelay;
+ hDel->nInfoCodecDelay =
+ hDel->nInfoDmxDelay + hDel->config.nCoreCoderDelay +
+ hDel->config.nSacTimeAlignment + nDecoderAnDelay + nDecoderSynDelay;
+
+ } else {
+ /* ArbitraryDmx or TdDmx on */
+ int tempDelay1, tempDelay2, tempDelay12, tempDelay3;
+
+ tempDelay1 = hDel->config.nArbDmxDelay - hDel->config.nSurroundDelay;
+
+ if (tempDelay1 >= 0) {
+ hDel->nSurroundAnalysisBuffer = tempDelay1;
+ hDel->nArbDmxAnalysisBuffer = 0;
+ } else {
+ hDel->nSurroundAnalysisBuffer = 0;
+ hDel->nArbDmxAnalysisBuffer = -tempDelay1;
+ }
+
+ tempDelay1 = nEncoderWinDelay + hDel->config.nSurroundDelay +
+ hDel->nSurroundAnalysisBuffer +
+ nEncoderAnDelay; /*Surround Path*/
+ tempDelay2 = nEncoderWinDelay + hDel->config.nArbDmxDelay +
+ hDel->nArbDmxAnalysisBuffer +
+ nEncoderAnDelay; /* ArbDmx Compare Path */
+ tempDelay3 = hDel->config.nArbDmxDelay + hDel->config.nLimiterDelay +
+ hDel->config.nCoreCoderDelay +
+ hDel->config.nSacTimeAlignment +
+ nDecoderAnDelay; /* ArbDmx Passthrough*/
+
+ tempDelay12 =
+ FDKmax(nResidualCoderFrameDelay, nArbDmxResidualCoderFrameDelay) *
+ hDel->config.nFrameLen;
+ tempDelay12 += hDel->config.nSacStreamMuxDelay;
+
+ if (tempDelay1 > tempDelay2) {
+ tempDelay12 += tempDelay1;
+ } else {
+ tempDelay12 += tempDelay2;
+ }
+
+ if (tempDelay3 > tempDelay12) {
+ if (hDel->config.bMinimizeDelay > 0) {
+ hDel->nBitstreamFrameBuffer =
+ (tempDelay3 - tempDelay12) / hDel->config.nFrameLen; /*floor*/
+ hDel->nOutputAudioBuffer = 0;
+ hDel->nSurroundAnalysisBuffer +=
+ (tempDelay3 - tempDelay12 -
+ (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen));
+ hDel->nArbDmxAnalysisBuffer +=
+ (tempDelay3 - tempDelay12 -
+ (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen));
+ } else {
+ hDel->nBitstreamFrameBuffer =
+ ((tempDelay3 - tempDelay12) + hDel->config.nFrameLen - 1) /
+ hDel->config.nFrameLen;
+ hDel->nOutputAudioBuffer =
+ hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen +
+ tempDelay12 - tempDelay3;
+ }
+ } else {
+ hDel->nBitstreamFrameBuffer = 0;
+ hDel->nOutputAudioBuffer = tempDelay12 - tempDelay3;
+ }
+
+ if (hDel->config.bDmxAlign > 0) {
+ int tempDelay = hDel->config.nArbDmxDelay + hDel->nOutputAudioBuffer +
+ hDel->config.nLimiterDelay +
+ hDel->config.nCoreCoderDelay;
+ hDel->nDiscardOutFrames =
+ (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
+ hDel->nDmxAlignBuffer =
+ hDel->nDiscardOutFrames * hDel->config.nFrameLen - tempDelay;
+ } else {
+ hDel->nDiscardOutFrames = 0;
+ hDel->nDmxAlignBuffer = 0;
+ }
+
+ /* Output: Info-Variables */
+ hDel->nInfoDmxDelay = hDel->config.nArbDmxDelay +
+ hDel->nOutputAudioBuffer +
+ hDel->config.nLimiterDelay;
+ hDel->nInfoCodecDelay =
+ hDel->nInfoDmxDelay + hDel->config.nCoreCoderDelay +
+ hDel->config.nSacTimeAlignment + nDecoderAnDelay + nDecoderSynDelay;
+ hDel->nInfoDecoderDelay = nDecoderAnDelay + nDecoderSynDelay;
+
+ } /* ArbitraryDmx or TdDmx on */
+
+ /* Additonal Variables needed for Computation Issues */
+ hDel->nBitstreamFrameBufferSize = hDel->nBitstreamFrameBuffer + 1;
+ }
+
+ return error;
+}
+
+static FDK_SACENC_ERROR assignParameterInRange(
+ const INT startRange, /* including startRange */
+ const INT stopRange, /* including stopRange */
+ const INT value, /* value to write*/
+ INT *const ptr /* destination pointer*/
+) {
+ FDK_SACENC_ERROR error = SACENC_INVALID_CONFIG;
+
+ if ((startRange <= value) && (value <= stopRange)) {
+ *ptr = value;
+ error = SACENC_OK;
+ }
+
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetDmxAlign(HANDLE_DELAY hDelay,
+ const INT bDmxAlignIn) {
+ return (assignParameterInRange(0, 1, bDmxAlignIn, &hDelay->config.bDmxAlign));
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetTimeDomDmx(HANDLE_DELAY hDelay,
+ const INT bTimeDomDmxIn) {
+ return (
+ assignParameterInRange(0, 1, bTimeDomDmxIn, &hDelay->config.bTimeDomDmx));
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetSacTimeAlignmentDynamicOut(
+ HANDLE_DELAY hDelay, const INT bSacTimeAlignmentDynamicOutIn) {
+ return (assignParameterInRange(0, 1, bSacTimeAlignmentDynamicOutIn,
+ &hDelay->config.bSacTimeAlignmentDynamicOut));
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetNSacTimeAlignment(
+ HANDLE_DELAY hDelay, const INT nSacTimeAlignmentIn) {
+ return (assignParameterInRange(-32768, 32767, nSacTimeAlignmentIn,
+ &hDelay->config.nSacTimeAlignment));
+}
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetMinimizeDelay(HANDLE_DELAY hDelay,
+ const INT bMinimizeDelay) {
+ return (assignParameterInRange(0, 1, bMinimizeDelay,
+ &hDelay->config.bMinimizeDelay));
+}
+
+INT fdk_sacenc_delay_GetOutputAudioBufferDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nOutputAudioBuffer);
+}
+
+INT fdk_sacenc_delay_GetSurroundAnalysisBufferDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nSurroundAnalysisBuffer);
+}
+
+INT fdk_sacenc_delay_GetArbDmxAnalysisBufferDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nArbDmxAnalysisBuffer);
+}
+
+INT fdk_sacenc_delay_GetBitstreamFrameBufferSize(HANDLE_DELAY hDelay) {
+ return (hDelay->nBitstreamFrameBufferSize);
+}
+
+INT fdk_sacenc_delay_GetDmxAlignBufferDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nDmxAlignBuffer);
+}
+
+INT fdk_sacenc_delay_GetDiscardOutFrames(HANDLE_DELAY hDelay) {
+ return (hDelay->nDiscardOutFrames);
+}
+
+INT fdk_sacenc_delay_GetInfoDmxDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nInfoDmxDelay);
+}
+
+INT fdk_sacenc_delay_GetInfoCodecDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nInfoCodecDelay);
+}
+
+INT fdk_sacenc_delay_GetInfoDecoderDelay(HANDLE_DELAY hDelay) {
+ return (hDelay->nInfoDecoderDelay);
+}
diff --git a/fdk-aac/libSACenc/src/sacenc_delay.h b/fdk-aac/libSACenc/src/sacenc_delay.h
new file mode 100644
index 0000000..38bfbc5
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_delay.h
@@ -0,0 +1,175 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Christian Goettlinger
+
+ Description: Encoder Library Interface
+ delay management of the encoder
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ ******************************************************************************/
+#ifndef SACENC_DELAY_H
+#define SACENC_DELAY_H
+
+/* Includes ******************************************************************/
+#include "sacenc_lib.h"
+#include "machine_type.h"
+#include "FDK_matrixCalloc.h"
+
+/* Defines *******************************************************************/
+#define MAX_DELAY_INPUT 1024
+#define MAX_DELAY_OUTPUT 4096
+/* bumped from 0 to 5. this should be equal or larger to the dualrate sbr
+ * resampler filter length */
+#define MAX_DELAY_SURROUND_ANALYSIS 5
+#define MAX_BITSTREAM_DELAY 1
+
+/* Data Types ****************************************************************/
+typedef struct DELAY *HANDLE_DELAY;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_delay_Open(HANDLE_DELAY *phDelay);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_Close(HANDLE_DELAY *phDelay);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_Init(HANDLE_DELAY hDelay, const INT nQmfLen,
+ const INT nFrameLen,
+ const INT nCoreCoderDelay,
+ const INT nSacStreamMuxDelay);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SubCalulateBufferDelays(HANDLE_DELAY hDel);
+
+/* Set Expert Config Parameters */
+FDK_SACENC_ERROR fdk_sacenc_delay_SetDmxAlign(HANDLE_DELAY hDelay,
+ const INT bDmxAlignIn);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetTimeDomDmx(HANDLE_DELAY hDelay,
+ const INT bTimeDomDmxIn);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetSacTimeAlignmentDynamicOut(
+ HANDLE_DELAY hDelay, const INT bSacTimeAlignmentDynamicOutIn);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetNSacTimeAlignment(
+ HANDLE_DELAY hDelay, const INT nSacTimeAlignmentIn);
+
+FDK_SACENC_ERROR fdk_sacenc_delay_SetMinimizeDelay(HANDLE_DELAY hDelay,
+ const INT bMinimizeDelay);
+
+/* Get Internal Variables */
+INT fdk_sacenc_delay_GetOutputAudioBufferDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetSurroundAnalysisBufferDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetArbDmxAnalysisBufferDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetBitstreamFrameBufferSize(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetDmxAlignBufferDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetDiscardOutFrames(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetInfoDmxDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetInfoCodecDelay(HANDLE_DELAY hDelay);
+
+INT fdk_sacenc_delay_GetInfoDecoderDelay(HANDLE_DELAY hDelay);
+
+#endif /* SACENC_DELAY_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_dmx_tdom_enh.cpp b/fdk-aac/libSACenc/src/sacenc_dmx_tdom_enh.cpp
new file mode 100644
index 0000000..be66c83
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_dmx_tdom_enh.cpp
@@ -0,0 +1,639 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): M. Luis Valero
+
+ Description: Enhanced Time Domain Downmix
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_dmx_tdom_enh.h"
+
+#include "FDK_matrixCalloc.h"
+#include "FDK_trigFcts.h"
+#include "fixpoint_math.h"
+
+/* Defines *******************************************************************/
+#define PI_FLT 3.1415926535897931f
+#define ALPHA_FLT 0.0001f
+
+#define PI_E (2)
+#define PI_M (FL2FXCONST_DBL(PI_FLT / (1 << PI_E)))
+
+#define ALPHA_E (13)
+#define ALPHA_M (FL2FXCONST_DBL(ALPHA_FLT * (1 << ALPHA_E)))
+
+enum { L = 0, R = 1 };
+
+/* Data Types ****************************************************************/
+typedef struct T_ENHANCED_TIME_DOMAIN_DMX {
+ int maxFramelength;
+
+ int framelength;
+
+ FIXP_DBL prev_gain_m[2];
+ INT prev_gain_e;
+ FIXP_DBL prev_H1_m[2];
+ INT prev_H1_e;
+
+ FIXP_DBL *sinusWindow_m;
+ SCHAR sinusWindow_e;
+
+ FIXP_DBL prev_Left_m;
+ INT prev_Left_e;
+ FIXP_DBL prev_Right_m;
+ INT prev_Right_e;
+ FIXP_DBL prev_XNrg_m;
+ INT prev_XNrg_e;
+
+ FIXP_DBL lin_bbCld_weight_m;
+ INT lin_bbCld_weight_e;
+ FIXP_DBL gain_weight_m[2];
+ INT gain_weight_e;
+
+} ENHANCED_TIME_DOMAIN_DMX;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+static void calculateRatio(const FIXP_DBL sqrt_linCld_m,
+ const INT sqrt_linCld_e, const FIXP_DBL lin_Cld_m,
+ const INT lin_Cld_e, const FIXP_DBL Icc_m,
+ const INT Icc_e, FIXP_DBL G_m[2], INT *G_e);
+
+static void calculateDmxGains(const FIXP_DBL lin_Cld_m, const INT lin_Cld_e,
+ const FIXP_DBL lin_Cld2_m, const INT lin_Cld2_e,
+ const FIXP_DBL Icc_m, const INT Icc_e,
+ const FIXP_DBL G_m[2], const INT G_e,
+ FIXP_DBL H1_m[2], INT *pH1_e);
+
+/* Function / Class Definition ***********************************************/
+static FIXP_DBL invSqrtNorm2(const FIXP_DBL op_m, const INT op_e,
+ INT *const result_e) {
+ FIXP_DBL src_m = op_m;
+ int src_e = op_e;
+
+ if (src_e & 1) {
+ src_m >>= 1;
+ src_e += 1;
+ }
+
+ src_m = invSqrtNorm2(src_m, result_e);
+ *result_e = (*result_e) - (src_e >> 1);
+
+ return src_m;
+}
+
+static FIXP_DBL sqrtFixp(const FIXP_DBL op_m, const INT op_e,
+ INT *const result_e) {
+ FIXP_DBL src_m = op_m;
+ int src_e = op_e;
+
+ if (src_e & 1) {
+ src_m >>= 1;
+ src_e += 1;
+ }
+
+ *result_e = (src_e >> 1);
+ return sqrtFixp(src_m);
+}
+
+static FIXP_DBL fixpAdd(const FIXP_DBL src1_m, const INT src1_e,
+ const FIXP_DBL src2_m, const INT src2_e,
+ INT *const dst_e) {
+ FIXP_DBL dst_m;
+
+ if (src1_m == FL2FXCONST_DBL(0.f)) {
+ *dst_e = src2_e;
+ dst_m = src2_m;
+ } else if (src2_m == FL2FXCONST_DBL(0.f)) {
+ *dst_e = src1_e;
+ dst_m = src1_m;
+ } else {
+ *dst_e = fixMax(src1_e, src2_e) + 1;
+ dst_m =
+ scaleValue(src1_m, fixMax((src1_e - (*dst_e)), -(DFRACT_BITS - 1))) +
+ scaleValue(src2_m, fixMax((src2_e - (*dst_e)), -(DFRACT_BITS - 1)));
+ }
+ return dst_m;
+}
+
+/**
+ * \brief Sum up fixpoint values with best possible accuracy.
+ *
+ * \param value1 First input value.
+ * \param q1 Scaling factor of first input value.
+ * \param pValue2 Pointer to second input value, will be modified on
+ * return.
+ * \param pQ2 Pointer to second scaling factor, will be modified on
+ * return.
+ *
+ * \return void
+ */
+static void fixpAddNorm(const FIXP_DBL value1, const INT q1,
+ FIXP_DBL *const pValue2, INT *const pQ2) {
+ const int headroom1 = fNormz(fixp_abs(value1)) - 1;
+ const int headroom2 = fNormz(fixp_abs(*pValue2)) - 1;
+ int resultScale = fixMax(q1 - headroom1, (*pQ2) - headroom2);
+
+ if ((value1 != FL2FXCONST_DBL(0.f)) && (*pValue2 != FL2FXCONST_DBL(0.f))) {
+ resultScale++;
+ }
+
+ *pValue2 =
+ scaleValue(value1, q1 - resultScale) +
+ scaleValue(*pValue2, fixMax(-(DFRACT_BITS - 1), ((*pQ2) - resultScale)));
+ *pQ2 = (*pValue2 != (FIXP_DBL)0) ? resultScale : DFRACT_BITS - 1;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_open_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX *phEnhancedTimeDmx, const INT framelength) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx = NULL;
+
+ if (NULL == phEnhancedTimeDmx) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDK_ALLOCATE_MEMORY_1D(hEnhancedTimeDmx, 1, ENHANCED_TIME_DOMAIN_DMX);
+ FDK_ALLOCATE_MEMORY_1D(hEnhancedTimeDmx->sinusWindow_m, 1 + framelength,
+ FIXP_DBL);
+ hEnhancedTimeDmx->maxFramelength = framelength;
+ *phEnhancedTimeDmx = hEnhancedTimeDmx;
+ }
+ return error;
+
+bail:
+ fdk_sacenc_close_enhancedTimeDomainDmx(&hEnhancedTimeDmx);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_init_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx,
+ const FIXP_DBL *const pInputGain_m, const INT inputGain_e,
+ const FIXP_DBL outputGain_m, const INT outputGain_e,
+ const INT framelength) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (hEnhancedTimeDmx == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int smp;
+ if (framelength > hEnhancedTimeDmx->maxFramelength) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+
+ hEnhancedTimeDmx->framelength = framelength;
+
+ INT deltax_e;
+ FIXP_DBL deltax_m;
+
+ deltax_m = fDivNormHighPrec(
+ PI_M, (FIXP_DBL)(2 * hEnhancedTimeDmx->framelength), &deltax_e);
+ deltax_m = scaleValue(deltax_m, PI_E + deltax_e - (DFRACT_BITS - 1) - 1);
+ deltax_e = 1;
+
+ for (smp = 0; smp < hEnhancedTimeDmx->framelength + 1; smp++) {
+ hEnhancedTimeDmx->sinusWindow_m[smp] =
+ fMult(ALPHA_M, fPow2(fixp_sin(smp * deltax_m, deltax_e)));
+ }
+ hEnhancedTimeDmx->sinusWindow_e = -ALPHA_E;
+
+ hEnhancedTimeDmx->prev_Left_m = hEnhancedTimeDmx->prev_Right_m =
+ hEnhancedTimeDmx->prev_XNrg_m = FL2FXCONST_DBL(0.f);
+ hEnhancedTimeDmx->prev_Left_e = hEnhancedTimeDmx->prev_Right_e =
+ hEnhancedTimeDmx->prev_XNrg_e = DFRACT_BITS - 1;
+
+ hEnhancedTimeDmx->lin_bbCld_weight_m =
+ fDivNormHighPrec(fPow2(pInputGain_m[L]), fPow2(pInputGain_m[R]),
+ &hEnhancedTimeDmx->lin_bbCld_weight_e);
+
+ hEnhancedTimeDmx->gain_weight_m[L] = fMult(pInputGain_m[L], outputGain_m);
+ hEnhancedTimeDmx->gain_weight_m[R] = fMult(pInputGain_m[R], outputGain_m);
+ hEnhancedTimeDmx->gain_weight_e =
+ -fNorm(fixMax(hEnhancedTimeDmx->gain_weight_m[L],
+ hEnhancedTimeDmx->gain_weight_m[R]));
+
+ hEnhancedTimeDmx->gain_weight_m[L] = scaleValue(
+ hEnhancedTimeDmx->gain_weight_m[L], -hEnhancedTimeDmx->gain_weight_e);
+ hEnhancedTimeDmx->gain_weight_m[R] = scaleValue(
+ hEnhancedTimeDmx->gain_weight_m[R], -hEnhancedTimeDmx->gain_weight_e);
+ hEnhancedTimeDmx->gain_weight_e += inputGain_e + outputGain_e;
+
+ hEnhancedTimeDmx->prev_gain_m[L] = hEnhancedTimeDmx->gain_weight_m[L] >> 1;
+ hEnhancedTimeDmx->prev_gain_m[R] = hEnhancedTimeDmx->gain_weight_m[R] >> 1;
+ hEnhancedTimeDmx->prev_gain_e = hEnhancedTimeDmx->gain_weight_e + 1;
+
+ hEnhancedTimeDmx->prev_H1_m[L] =
+ scaleValue(hEnhancedTimeDmx->gain_weight_m[L], -4);
+ hEnhancedTimeDmx->prev_H1_m[R] =
+ scaleValue(hEnhancedTimeDmx->gain_weight_m[R], -4);
+ hEnhancedTimeDmx->prev_H1_e = 2 + 2 + hEnhancedTimeDmx->gain_weight_e;
+ }
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_apply_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx,
+ const INT_PCM *const *const inputTime, INT_PCM *const outputTimeDmx,
+ const INT InputDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hEnhancedTimeDmx) || (NULL == inputTime) ||
+ (NULL == inputTime[L]) || (NULL == inputTime[R]) ||
+ (NULL == outputTimeDmx)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int smp;
+ FIXP_DBL lin_bbCld_m, lin_Cld_m, bbCorr_m, sqrt_linCld_m, G_m[2], H1_m[2],
+ gainLeft_m, gainRight_m;
+ FIXP_DBL bbNrgLeft_m, bbNrgRight_m, bbXNrg_m, nrgLeft_m, nrgRight_m, nrgX_m;
+ INT lin_bbCld_e, lin_Cld_e, bbCorr_e, sqrt_linCld_e, G_e, H1_e;
+ INT bbNrgLeft_e, bbNrgRight_e, bbXNrg_e, nrgLeft_e, nrgRight_e, nrgX_e;
+
+ /* Increase energy time resolution with shorter processing blocks. 128 is an
+ * empiric value. */
+ const int granuleLength = fixMin(128, hEnhancedTimeDmx->framelength);
+ int granuleShift =
+ (granuleLength > 1)
+ ? ((DFRACT_BITS - 1) - fNorm((FIXP_DBL)(granuleLength - 1)))
+ : 0;
+ granuleShift = fixMax(
+ 3, granuleShift +
+ 1); /* one bit more headroom for worst case accumulation */
+
+ smp = 0;
+
+ /* Prevent division by zero. */
+ bbNrgLeft_m = bbNrgRight_m = bbXNrg_m = (FIXP_DBL)(1);
+ bbNrgLeft_e = bbNrgRight_e = bbXNrg_e = 0;
+
+ do {
+ const int offset = smp;
+ FIXP_DBL partialL, partialR, partialX;
+ partialL = partialR = partialX = FL2FXCONST_DBL(0.f);
+
+ int in_margin = FDKmin(
+ getScalefactorPCM(
+ &inputTime[L][offset],
+ fixMin(offset + granuleLength, hEnhancedTimeDmx->framelength) -
+ offset,
+ 1),
+ getScalefactorPCM(
+ &inputTime[R][offset],
+ fixMin(offset + granuleLength, hEnhancedTimeDmx->framelength) -
+ offset,
+ 1));
+
+ /* partial energy */
+ for (smp = offset;
+ smp < fixMin(offset + granuleLength, hEnhancedTimeDmx->framelength);
+ smp++) {
+ FIXP_PCM inputL =
+ scaleValue((FIXP_PCM)inputTime[L][smp], in_margin - 1);
+ FIXP_PCM inputR =
+ scaleValue((FIXP_PCM)inputTime[R][smp], in_margin - 1);
+
+ partialL += fPow2Div2(inputL) >> (granuleShift - 3);
+ partialR += fPow2Div2(inputR) >> (granuleShift - 3);
+ partialX += fMultDiv2(inputL, inputR) >> (granuleShift - 3);
+ }
+
+ fixpAddNorm(partialL, granuleShift - 2 * in_margin, &bbNrgLeft_m,
+ &bbNrgLeft_e);
+ fixpAddNorm(partialR, granuleShift - 2 * in_margin, &bbNrgRight_m,
+ &bbNrgRight_e);
+ fixpAddNorm(partialX, granuleShift - 2 * in_margin, &bbXNrg_m, &bbXNrg_e);
+ } while (smp < hEnhancedTimeDmx->framelength);
+
+ nrgLeft_m =
+ fixpAdd(hEnhancedTimeDmx->prev_Left_m, hEnhancedTimeDmx->prev_Left_e,
+ bbNrgLeft_m, bbNrgLeft_e, &nrgLeft_e);
+ nrgRight_m =
+ fixpAdd(hEnhancedTimeDmx->prev_Right_m, hEnhancedTimeDmx->prev_Right_e,
+ bbNrgRight_m, bbNrgRight_e, &nrgRight_e);
+ nrgX_m =
+ fixpAdd(hEnhancedTimeDmx->prev_XNrg_m, hEnhancedTimeDmx->prev_XNrg_e,
+ bbXNrg_m, bbXNrg_e, &nrgX_e);
+
+ lin_bbCld_m = fMult(hEnhancedTimeDmx->lin_bbCld_weight_m,
+ fDivNorm(nrgLeft_m, nrgRight_m, &lin_bbCld_e));
+ lin_bbCld_e +=
+ hEnhancedTimeDmx->lin_bbCld_weight_e + nrgLeft_e - nrgRight_e;
+
+ bbCorr_m = fMult(nrgX_m, invSqrtNorm2(fMult(nrgLeft_m, nrgRight_m),
+ nrgLeft_e + nrgRight_e, &bbCorr_e));
+ bbCorr_e += nrgX_e;
+
+ hEnhancedTimeDmx->prev_Left_m = bbNrgLeft_m;
+ hEnhancedTimeDmx->prev_Left_e = bbNrgLeft_e;
+ hEnhancedTimeDmx->prev_Right_m = bbNrgRight_m;
+ hEnhancedTimeDmx->prev_Right_e = bbNrgRight_e;
+ hEnhancedTimeDmx->prev_XNrg_m = bbXNrg_m;
+ hEnhancedTimeDmx->prev_XNrg_e = bbXNrg_e;
+
+ /*
+ bbCld = 10.f*log10(lin_bbCld)
+
+ lin_Cld = pow(10,bbCld/20)
+ = pow(10,10.f*log10(lin_bbCld)/20.f)
+ = sqrt(lin_bbCld)
+
+ lin_Cld2 = lin_Cld*lin_Cld
+ = sqrt(lin_bbCld)*sqrt(lin_bbCld)
+ = lin_bbCld
+ */
+ lin_Cld_m = sqrtFixp(lin_bbCld_m, lin_bbCld_e, &lin_Cld_e);
+ sqrt_linCld_m = sqrtFixp(lin_Cld_m, lin_Cld_e, &sqrt_linCld_e);
+
+ /*calculate how much right and how much left signal, to avoid signal
+ * cancellations*/
+ calculateRatio(sqrt_linCld_m, sqrt_linCld_e, lin_Cld_m, lin_Cld_e, bbCorr_m,
+ bbCorr_e, G_m, &G_e);
+
+ /*calculate downmix gains*/
+ calculateDmxGains(lin_Cld_m, lin_Cld_e, lin_bbCld_m, lin_bbCld_e, bbCorr_m,
+ bbCorr_e, G_m, G_e, H1_m, &H1_e);
+
+ /*adapt output gains*/
+ H1_m[L] = fMult(H1_m[L], hEnhancedTimeDmx->gain_weight_m[L]);
+ H1_m[R] = fMult(H1_m[R], hEnhancedTimeDmx->gain_weight_m[R]);
+ H1_e += hEnhancedTimeDmx->gain_weight_e;
+
+ gainLeft_m = hEnhancedTimeDmx->prev_gain_m[L];
+ gainRight_m = hEnhancedTimeDmx->prev_gain_m[R];
+
+ INT intermediate_gain_e =
+ +hEnhancedTimeDmx->sinusWindow_e + H1_e - hEnhancedTimeDmx->prev_gain_e;
+
+ for (smp = 0; smp < hEnhancedTimeDmx->framelength; smp++) {
+ const INT N = hEnhancedTimeDmx->framelength;
+ FIXP_DBL intermediate_gainLeft_m, intermediate_gainRight_m, tmp;
+
+ intermediate_gainLeft_m =
+ scaleValue((fMult(hEnhancedTimeDmx->sinusWindow_m[smp], H1_m[L]) +
+ fMult(hEnhancedTimeDmx->sinusWindow_m[N - smp],
+ hEnhancedTimeDmx->prev_H1_m[L])),
+ intermediate_gain_e);
+ intermediate_gainRight_m =
+ scaleValue((fMult(hEnhancedTimeDmx->sinusWindow_m[smp], H1_m[R]) +
+ fMult(hEnhancedTimeDmx->sinusWindow_m[N - smp],
+ hEnhancedTimeDmx->prev_H1_m[R])),
+ intermediate_gain_e);
+
+ gainLeft_m = intermediate_gainLeft_m +
+ fMult(FL2FXCONST_DBL(1.f - ALPHA_FLT), gainLeft_m);
+ gainRight_m = intermediate_gainRight_m +
+ fMult(FL2FXCONST_DBL(1.f - ALPHA_FLT), gainRight_m);
+
+ tmp = fMultDiv2(gainLeft_m, (FIXP_PCM)inputTime[L][smp + InputDelay]) +
+ fMultDiv2(gainRight_m, (FIXP_PCM)inputTime[R][smp + InputDelay]);
+ outputTimeDmx[smp] = (INT_PCM)SATURATE_SHIFT(
+ tmp,
+ -(hEnhancedTimeDmx->prev_gain_e + 1 - (DFRACT_BITS - SAMPLE_BITS)),
+ SAMPLE_BITS);
+ }
+
+ hEnhancedTimeDmx->prev_gain_m[L] = gainLeft_m;
+ hEnhancedTimeDmx->prev_gain_m[R] = gainRight_m;
+
+ hEnhancedTimeDmx->prev_H1_m[L] = H1_m[L];
+ hEnhancedTimeDmx->prev_H1_m[R] = H1_m[R];
+ hEnhancedTimeDmx->prev_H1_e = H1_e;
+ }
+
+ return error;
+}
+
+static void calculateRatio(const FIXP_DBL sqrt_linCld_m,
+ const INT sqrt_linCld_e, const FIXP_DBL lin_Cld_m,
+ const INT lin_Cld_e, const FIXP_DBL Icc_m,
+ const INT Icc_e, FIXP_DBL G_m[2], INT *G_e) {
+#define G_SCALE_FACTOR (2)
+
+ if (Icc_m >= FL2FXCONST_DBL(0.f)) {
+ G_m[0] = G_m[1] = FL2FXCONST_DBL(1.f / (float)(1 << G_SCALE_FACTOR));
+ G_e[0] = G_SCALE_FACTOR;
+ } else {
+ const FIXP_DBL max_gain_factor =
+ FL2FXCONST_DBL(2.f / (float)(1 << G_SCALE_FACTOR));
+ FIXP_DBL tmp1_m, tmp2_m, numerator_m, denominator_m, r_m, r4_m, q;
+ INT tmp1_e, tmp2_e, numerator_e, denominator_e, r_e, r4_e;
+
+ /* r = (lin_Cld + 1 + 2*Icc*sqrt_linCld) / (lin_Cld + 1 -
+ * 2*Icc*sqrt_linCld) = (tmp1 + tmp2) / (tmp1 - tmp2)
+ */
+ tmp1_m =
+ fixpAdd(lin_Cld_m, lin_Cld_e, FL2FXCONST_DBL(1.f / 2.f), 1, &tmp1_e);
+
+ tmp2_m = fMult(Icc_m, sqrt_linCld_m);
+ tmp2_e = 1 + Icc_e + sqrt_linCld_e;
+ numerator_m = fixpAdd(tmp1_m, tmp1_e, tmp2_m, tmp2_e, &numerator_e);
+ denominator_m = fixpAdd(tmp1_m, tmp1_e, -tmp2_m, tmp2_e, &denominator_e);
+
+ if ((numerator_m > FL2FXCONST_DBL(0.f)) &&
+ (denominator_m > FL2FXCONST_DBL(0.f))) {
+ r_m = fDivNorm(numerator_m, denominator_m, &r_e);
+ r_e += numerator_e - denominator_e;
+
+ /* r_4 = sqrt( sqrt( r ) ) */
+ r4_m = sqrtFixp(r_m, r_e, &r4_e);
+ r4_m = sqrtFixp(r4_m, r4_e, &r4_e);
+
+ r4_e -= G_SCALE_FACTOR;
+
+ /* q = min(r4_m, max_gain_factor) */
+ q = ((r4_e >= 0) && (r4_m >= (max_gain_factor >> r4_e)))
+ ? max_gain_factor
+ : scaleValue(r4_m, r4_e);
+ } else {
+ q = FL2FXCONST_DBL(0.f);
+ }
+
+ G_m[0] = max_gain_factor - q;
+ G_m[1] = q;
+
+ *G_e = G_SCALE_FACTOR;
+ }
+}
+
+static void calculateDmxGains(const FIXP_DBL lin_Cld_m, const INT lin_Cld_e,
+ const FIXP_DBL lin_Cld2_m, const INT lin_Cld2_e,
+ const FIXP_DBL Icc_m, const INT Icc_e,
+ const FIXP_DBL G_m[2], const INT G_e,
+ FIXP_DBL H1_m[2], INT *pH1_e) {
+#define H1_SCALE_FACTOR (2)
+ const FIXP_DBL max_gain_factor =
+ FL2FXCONST_DBL(2.f / (float)(1 << H1_SCALE_FACTOR));
+
+ FIXP_DBL nrgRight_m, nrgLeft_m, crossNrg_m, inv_weight_num_m,
+ inv_weight_denom_m, inverse_weight_m, inverse_weight_limited;
+ INT nrgRight_e, nrgLeft_e, crossNrg_e, inv_weight_num_e, inv_weight_denom_e,
+ inverse_weight_e;
+
+ /* nrgRight = sqrt(1/(lin_Cld2 + 1) */
+ nrgRight_m = fixpAdd(lin_Cld2_m, lin_Cld2_e, FL2FXCONST_DBL(1.f / 2.f), 1,
+ &nrgRight_e);
+ nrgRight_m = invSqrtNorm2(nrgRight_m, nrgRight_e, &nrgRight_e);
+
+ /* nrgLeft = lin_Cld * nrgRight */
+ nrgLeft_m = fMult(lin_Cld_m, nrgRight_m);
+ nrgLeft_e = lin_Cld_e + nrgRight_e;
+
+ /* crossNrg = sqrt(nrgLeft*nrgRight) */
+ crossNrg_m = sqrtFixp(fMult(nrgLeft_m, nrgRight_m), nrgLeft_e + nrgRight_e,
+ &crossNrg_e);
+
+ /* inverse_weight = sqrt((nrgLeft + nrgRight) / ( (G[0]*G[0]*nrgLeft) +
+ * (G[1]*G[1]*nrgRight) + 2*G[0]*G[1]*Icc*crossNrg)) = sqrt(inv_weight_num /
+ * inv_weight_denom)
+ */
+ inv_weight_num_m =
+ fixpAdd(nrgRight_m, nrgRight_e, nrgLeft_m, nrgLeft_e, &inv_weight_num_e);
+
+ inv_weight_denom_m =
+ fixpAdd(fMult(fPow2(G_m[0]), nrgLeft_m), 2 * G_e + nrgLeft_e,
+ fMult(fPow2(G_m[1]), nrgRight_m), 2 * G_e + nrgRight_e,
+ &inv_weight_denom_e);
+
+ inv_weight_denom_m =
+ fixpAdd(fMult(fMult(fMult(G_m[0], G_m[1]), crossNrg_m), Icc_m),
+ 1 + 2 * G_e + crossNrg_e + Icc_e, inv_weight_denom_m,
+ inv_weight_denom_e, &inv_weight_denom_e);
+
+ if (inv_weight_denom_m > FL2FXCONST_DBL(0.f)) {
+ inverse_weight_m =
+ fDivNorm(inv_weight_num_m, inv_weight_denom_m, &inverse_weight_e);
+ inverse_weight_m =
+ sqrtFixp(inverse_weight_m,
+ inverse_weight_e + inv_weight_num_e - inv_weight_denom_e,
+ &inverse_weight_e);
+ inverse_weight_e -= H1_SCALE_FACTOR;
+
+ /* inverse_weight_limited = min(max_gain_factor, inverse_weight) */
+ inverse_weight_limited =
+ ((inverse_weight_e >= 0) &&
+ (inverse_weight_m >= (max_gain_factor >> inverse_weight_e)))
+ ? max_gain_factor
+ : scaleValue(inverse_weight_m, inverse_weight_e);
+ } else {
+ inverse_weight_limited = max_gain_factor;
+ }
+
+ H1_m[0] = fMult(G_m[0], inverse_weight_limited);
+ H1_m[1] = fMult(G_m[1], inverse_weight_limited);
+
+ *pH1_e = G_e + H1_SCALE_FACTOR;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_close_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX *phEnhancedTimeDmx) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (phEnhancedTimeDmx == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if (*phEnhancedTimeDmx != NULL) {
+ if ((*phEnhancedTimeDmx)->sinusWindow_m != NULL) {
+ FDK_FREE_MEMORY_1D((*phEnhancedTimeDmx)->sinusWindow_m);
+ }
+ FDK_FREE_MEMORY_1D(*phEnhancedTimeDmx);
+ }
+ }
+ return error;
+}
diff --git a/fdk-aac/libSACenc/src/sacenc_dmx_tdom_enh.h b/fdk-aac/libSACenc/src/sacenc_dmx_tdom_enh.h
new file mode 100644
index 0000000..0b39911
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_dmx_tdom_enh.h
@@ -0,0 +1,134 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): M. Luis Valero
+
+ Description: Enhanced Time Domain Downmix
+
+*******************************************************************************/
+
+#ifndef SACENC_DMX_TDOM_ENH_H
+#define SACENC_DMX_TDOM_ENH_H
+
+/* Includes ******************************************************************/
+#include "sacenc_lib.h"
+#include "common_fix.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+typedef struct T_ENHANCED_TIME_DOMAIN_DMX *HANDLE_ENHANCED_TIME_DOMAIN_DMX;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_open_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX *hEnhancedTimeDmx, const INT framelength);
+
+FDK_SACENC_ERROR fdk_sacenc_init_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx,
+ const FIXP_DBL *const pInputGain_m, const INT inputGain_e,
+ const FIXP_DBL outputGain_m, const INT outputGain_e, const INT framelength);
+
+FDK_SACENC_ERROR fdk_sacenc_apply_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx,
+ const INT_PCM *const *const inputTime, INT_PCM *const outputTimeDmx,
+ const INT InputDelay);
+
+FDK_SACENC_ERROR fdk_sacenc_close_enhancedTimeDomainDmx(
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX *hEnhancedTimeDmx);
+
+#endif /* SACENC_DMX_TDOM_ENH_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_filter.cpp b/fdk-aac/libSACenc/src/sacenc_filter.cpp
new file mode 100644
index 0000000..79f0797
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_filter.cpp
@@ -0,0 +1,207 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): M. Multrus
+
+ Description: Encoder Library
+ Filter functions
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_filter.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+typedef struct T_DC_FILTER {
+ FIXP_DBL c__FDK;
+ FIXP_DBL state__FDK;
+
+} DC_FILTER;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+FDK_SACENC_ERROR fdk_sacenc_createDCFilter(HANDLE_DC_FILTER *hDCFilter) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hDCFilter) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDK_ALLOCATE_MEMORY_1D(*hDCFilter, 1, DC_FILTER);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_destroyDCFilter(hDCFilter);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_initDCFilter(HANDLE_DC_FILTER hDCFilter,
+ const UINT sampleRate) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ FIXP_DBL expC;
+ int s;
+
+ /* Conversion for use of CalcInvLdData: e^x = 2^(x*log10(e)/log10(2) =
+ CalcInvLdData(x*log10(e)/log10(2)/64.0) 1.44269504089 = log10(e)/log10(2)
+ 0.5 = scale constant value with 1 Bits
+ */
+ expC = fDivNormHighPrec((FIXP_DBL)20, (FIXP_DBL)sampleRate, &s);
+ expC = fMultDiv2(FL2FXCONST_DBL(-1.44269504089 * 0.5), expC) >>
+ (LD_DATA_SHIFT - 1 - 1);
+
+ if (s < 0)
+ expC = expC >> (-s);
+ else
+ expC = expC << (s);
+
+ expC = CalcInvLdData(expC);
+
+ hDCFilter->c__FDK = expC;
+ hDCFilter->state__FDK = FL2FXCONST_DBL(0.0f);
+
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_destroyDCFilter(HANDLE_DC_FILTER *hDCFilter) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hDCFilter != NULL) && (*hDCFilter != NULL)) {
+ FDKfree(*hDCFilter);
+
+ *hDCFilter = NULL;
+ }
+
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_applyDCFilter(HANDLE_DC_FILTER hDCFilter,
+ const INT_PCM *const signalIn,
+ INT_PCM *const signalOut,
+ const INT signalLength) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hDCFilter == NULL) || (signalIn == NULL) || (signalOut == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ const INT_PCM *const x = signalIn;
+ INT_PCM *const y = signalOut;
+ const FIXP_DBL c = hDCFilter->c__FDK;
+ FIXP_DBL *const state = &hDCFilter->state__FDK;
+ int i;
+ FIXP_DBL x0, x1, y1;
+
+ x1 = x0 = FX_PCM2FX_DBL(x[0]) >> DC_FILTER_SF;
+ y1 = x0 + (*state);
+
+ for (i = 1; i < signalLength; i++) {
+ x0 = FX_PCM2FX_DBL(x[i]) >> DC_FILTER_SF;
+ y[i - 1] = FX_DBL2FX_PCM(y1);
+ y1 = x0 - x1 + fMult(c, y1);
+ x1 = x0;
+ }
+
+ *state = fMult(c, y1) - x1;
+ y[i - 1] = FX_DBL2FX_PCM(y1);
+ }
+
+ return error;
+}
diff --git a/fdk-aac/libSACenc/src/sacenc_filter.h b/fdk-aac/libSACenc/src/sacenc_filter.h
new file mode 100644
index 0000000..10e3abd
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_filter.h
@@ -0,0 +1,133 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): M. Multrus
+
+ Description: Encoder Library Interface
+ Filter functions
+
+*******************************************************************************/
+
+#ifndef SACENC_FILTER_H
+#define SACENC_FILTER_H
+
+/* Includes ******************************************************************/
+#include "common_fix.h"
+#include "sacenc_lib.h"
+#include "FDK_matrixCalloc.h"
+
+/* Defines *******************************************************************/
+#define DC_FILTER_SF 1
+
+/* Data Types ****************************************************************/
+typedef struct T_DC_FILTER *HANDLE_DC_FILTER;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_createDCFilter(HANDLE_DC_FILTER *hDCFilter);
+
+FDK_SACENC_ERROR fdk_sacenc_initDCFilter(HANDLE_DC_FILTER hDCFilter,
+ const UINT sampleRate);
+
+FDK_SACENC_ERROR fdk_sacenc_destroyDCFilter(HANDLE_DC_FILTER *hDCFilter);
+
+FDK_SACENC_ERROR fdk_sacenc_applyDCFilter(HANDLE_DC_FILTER hDCFilter,
+ const INT_PCM *const signalIn,
+ INT_PCM *const signalOut,
+ const INT signalLength);
+
+#endif /* SACENC_FILTER_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_framewindowing.cpp b/fdk-aac/libSACenc/src/sacenc_framewindowing.cpp
new file mode 100644
index 0000000..15f0f0a
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_framewindowing.cpp
@@ -0,0 +1,568 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Get windows for framing
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ Description of file contents
+ ******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_framewindowing.h"
+#include "sacenc_vectorfunctions.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+typedef struct T_FRAMEWINDOW {
+ INT nTimeSlotsMax;
+ INT bFrameKeep;
+ INT startSlope;
+ INT stopSlope;
+ INT startRect;
+ INT stopRect;
+
+ INT taperAnaLen;
+ INT taperSynLen;
+ FIXP_WIN pTaperAna__FDK[MAX_TIME_SLOTS];
+ FIXP_WIN pTaperSyn__FDK[MAX_TIME_SLOTS];
+
+} FRAMEWINDOW;
+
+typedef enum {
+ FIX_INVALID = -1,
+ FIX_RECT_SMOOTH = 0,
+ FIX_SMOOTH_RECT = 1,
+ FIX_LARGE_SMOOTH = 2,
+ FIX_RECT_TRIANG = 3
+
+} FIX_TYPE;
+
+typedef enum {
+ VAR_INVALID = -1,
+ VAR_HOLD = 0,
+ VAR_ISOLATE = 1
+
+} VAR_TYPE;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static void calcTaperWin(FIXP_WIN *pTaperWin, INT timeSlots) {
+ FIXP_DBL x;
+ int i, scale;
+
+ for (i = 0; i < timeSlots; i++) {
+ x = fDivNormHighPrec((FIXP_DBL)i, (FIXP_DBL)timeSlots, &scale);
+
+ if (scale < 0) {
+ pTaperWin[i] = FX_DBL2FX_WIN(x >> (-scale));
+ } else {
+ pTaperWin[i] = FX_DBL2FX_WIN(x << (scale));
+ }
+ }
+ pTaperWin[timeSlots] = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Create(
+ HANDLE_FRAMEWINDOW *phFrameWindow) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == phFrameWindow) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Memory Allocation */
+ FDK_ALLOCATE_MEMORY_1D(*phFrameWindow, 1, FRAMEWINDOW);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_frameWindow_Destroy(phFrameWindow);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Init(
+ HANDLE_FRAMEWINDOW hFrameWindow,
+ const FRAMEWINDOW_CONFIG *const pFrameWindowConfig) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hFrameWindow == NULL) || (pFrameWindowConfig == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else if (pFrameWindowConfig->nTimeSlotsMax < 0) {
+ error = SACENC_INIT_ERROR;
+ } else {
+ int ts;
+ hFrameWindow->bFrameKeep = pFrameWindowConfig->bFrameKeep;
+ hFrameWindow->nTimeSlotsMax = pFrameWindowConfig->nTimeSlotsMax;
+
+ FIXP_WIN winMaxVal = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
+ int timeSlots = pFrameWindowConfig->nTimeSlotsMax;
+ {
+ hFrameWindow->startSlope = 0;
+ hFrameWindow->stopSlope = ((3 * timeSlots) >> 1) - 1;
+ hFrameWindow->startRect = timeSlots >> 1;
+ hFrameWindow->stopRect = timeSlots;
+ calcTaperWin(hFrameWindow->pTaperSyn__FDK, timeSlots >> 1);
+ hFrameWindow->taperSynLen = timeSlots >> 1;
+ }
+
+ /* Calculate Taper for non-rect. ana. windows */
+ hFrameWindow->taperAnaLen =
+ hFrameWindow->startRect - hFrameWindow->startSlope;
+ for (ts = 0; ts < hFrameWindow->taperAnaLen; ts++) {
+ { hFrameWindow->pTaperAna__FDK[ts] = winMaxVal; }
+ }
+ }
+
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Destroy(
+ HANDLE_FRAMEWINDOW *phFrameWindow) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL != phFrameWindow) && (NULL != *phFrameWindow)) {
+ FDKfree(*phFrameWindow);
+ *phFrameWindow = NULL;
+ }
+ return error;
+}
+
+static FDK_SACENC_ERROR FrameWinList_Reset(FRAMEWIN_LIST *const pFrameWinList) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pFrameWinList) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int k = 0;
+ for (k = 0; k < MAX_NUM_PARAMS; k++) {
+ pFrameWinList->dat[k].slot = -1;
+ pFrameWinList->dat[k].hold = FW_INTP;
+ }
+ pFrameWinList->n = 0;
+ }
+ return error;
+}
+
+static FDK_SACENC_ERROR FrameWindowList_Add(FRAMEWIN_LIST *const pFrameWinList,
+ const INT slot,
+ const FW_SLOTTYPE hold) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pFrameWinList) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if (pFrameWinList->n >= MAX_NUM_PARAMS) { /* Place left in List ?*/
+ error = SACENC_PARAM_ERROR;
+ } else if (pFrameWinList->n > 0 &&
+ pFrameWinList->dat[pFrameWinList->n - 1].slot - slot > 0) {
+ error = SACENC_PARAM_ERROR;
+ } else {
+ pFrameWinList->dat[pFrameWinList->n].slot = slot;
+ pFrameWinList->dat[pFrameWinList->n].hold = hold;
+ pFrameWinList->n++;
+ }
+ }
+ return error;
+}
+
+static FDK_SACENC_ERROR FrameWindowList_Remove(
+ FRAMEWIN_LIST *const pFrameWinList, const INT idx) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pFrameWinList) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int k = 0;
+ if (idx < 0 || idx >= MAX_NUM_PARAMS) {
+ error = SACENC_PARAM_ERROR;
+ } else if (pFrameWinList->n > 0) {
+ if (idx == MAX_NUM_PARAMS - 1) {
+ pFrameWinList->dat[idx].slot = -1;
+ pFrameWinList->dat[idx].hold = FW_INTP;
+ } else {
+ for (k = idx; k < MAX_NUM_PARAMS - 1; k++) {
+ pFrameWinList->dat[k] = pFrameWinList->dat[k + 1];
+ }
+ }
+ pFrameWinList->n--;
+ }
+ }
+ return error;
+}
+
+static FDK_SACENC_ERROR FrameWindowList_Limit(
+ FRAMEWIN_LIST *const pFrameWinList, const INT ll /*lower limit*/,
+ const INT ul /*upper limit*/
+) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == pFrameWinList) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int k = 0;
+ for (k = 0; k < pFrameWinList->n; k++) {
+ if (pFrameWinList->dat[k].slot < ll || pFrameWinList->dat[k].slot > ul) {
+ FrameWindowList_Remove(pFrameWinList, k);
+ --k;
+ }
+ }
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_GetWindow(
+ HANDLE_FRAMEWINDOW hFrameWindow, INT tr_pos[MAX_NUM_PARAMS],
+ const INT timeSlots, FRAMINGINFO *const pFramingInfo,
+ FIXP_WIN *pWindowAna__FDK[MAX_NUM_PARAMS],
+ FRAMEWIN_LIST *const pFrameWinList, const INT avoid_keep) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hFrameWindow == NULL) || (tr_pos == NULL) || (pFramingInfo == NULL) ||
+ (pFrameWinList == NULL) || (pWindowAna__FDK == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ const VAR_TYPE varType = VAR_HOLD;
+ const int tranL = 4;
+ int winCnt = 0;
+ int w, ps;
+
+ int startSlope = hFrameWindow->startSlope;
+ int stopSlope = hFrameWindow->stopSlope;
+ int startRect = hFrameWindow->startRect;
+ int stopRect = hFrameWindow->stopRect;
+ int taperAnaLen = hFrameWindow->taperAnaLen;
+
+ FIXP_WIN winMaxVal = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
+ FIXP_WIN applyRightWindowGain__FDK[MAX_NUM_PARAMS];
+ FIXP_WIN *pTaperAna__FDK = hFrameWindow->pTaperAna__FDK;
+
+ /* sanity check */
+ for (ps = 0; ps < MAX_NUM_PARAMS; ps++) {
+ if (pWindowAna__FDK[ps] == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+ }
+
+ if ((timeSlots > hFrameWindow->nTimeSlotsMax) || (timeSlots < 0)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* Reset */
+ if (SACENC_OK != (error = FrameWinList_Reset(pFrameWinList))) goto bail;
+
+ FDKmemclear(applyRightWindowGain__FDK, sizeof(applyRightWindowGain__FDK));
+
+ if (tr_pos[0] > -1) { /* Transients in first (left) half? */
+ int p_l = tr_pos[0];
+ winCnt = 0;
+
+ /* Create Parameter Positions */
+ switch (varType) {
+ case VAR_HOLD:
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, p_l - 1, FW_HOLD)))
+ goto bail;
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, p_l, FW_INTP)))
+ goto bail;
+ break;
+ case VAR_ISOLATE:
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, p_l - 1, FW_HOLD)))
+ goto bail;
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, p_l, FW_INTP)))
+ goto bail;
+ if (SACENC_OK != (error = FrameWindowList_Add(pFrameWinList,
+ p_l + tranL, FW_HOLD)))
+ goto bail;
+ if (SACENC_OK != (error = FrameWindowList_Add(
+ pFrameWinList, p_l + tranL + 1, FW_INTP)))
+ goto bail;
+ break;
+ default:
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+
+ /* Outside of frame? => Kick Out */
+ if (SACENC_OK !=
+ (error = FrameWindowList_Limit(pFrameWinList, 0, timeSlots - 1)))
+ goto bail;
+
+ /* Add timeSlots as temporary border for window creation */
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, timeSlots - 1, FW_HOLD)))
+ goto bail;
+
+ /* Create Windows */
+ for (ps = 0; ps < pFrameWinList->n - 1; ps++) {
+ if (FW_HOLD != pFrameWinList->dat[ps].hold) {
+ int const start = pFrameWinList->dat[ps].slot;
+ int const stop = pFrameWinList->dat[ps + 1].slot;
+
+ /* Analysis Window */
+ FDKmemset_flex(pWindowAna__FDK[winCnt], FX_DBL2FX_WIN((FIXP_DBL)0),
+ start);
+ FDKmemset_flex(&pWindowAna__FDK[winCnt][start], winMaxVal,
+ stop - start + 1);
+ FDKmemset_flex(&pWindowAna__FDK[winCnt][stop + 1],
+ FX_DBL2FX_WIN((FIXP_DBL)0), timeSlots - stop - 1);
+
+ applyRightWindowGain__FDK[winCnt] =
+ pWindowAna__FDK[winCnt][timeSlots - 1];
+ winCnt++;
+ }
+ } /* ps */
+
+ /* Pop temporary frame border */
+ if (SACENC_OK !=
+ (error = FrameWindowList_Remove(pFrameWinList, pFrameWinList->n - 1)))
+ goto bail;
+ } else { /* No transient in left half of ana. window */
+ winCnt = 0;
+
+ /* Add paramter set at end of frame */
+ if (SACENC_OK !=
+ (error = FrameWindowList_Add(pFrameWinList, timeSlots - 1, FW_INTP)))
+ goto bail;
+ /* Analysis Window */
+ FDKmemset_flex(pWindowAna__FDK[winCnt], FX_DBL2FX_WIN((FIXP_DBL)0),
+ startSlope);
+ FDKmemcpy_flex(&pWindowAna__FDK[winCnt][startSlope], 1, pTaperAna__FDK, 1,
+ taperAnaLen);
+ FDKmemset_flex(&pWindowAna__FDK[winCnt][startRect], winMaxVal,
+ timeSlots - startRect);
+
+ applyRightWindowGain__FDK[winCnt] = winMaxVal;
+ winCnt++;
+ } /* if (tr_pos[0] > -1) */
+
+ for (w = 0; w < winCnt; w++) {
+ if (applyRightWindowGain__FDK[w] > (FIXP_WIN)0) {
+ if (tr_pos[1] > -1) { /* Transients in second (right) half? */
+ int p_r = tr_pos[1];
+
+ /* Analysis Window */
+ FDKmemset_flex(&pWindowAna__FDK[w][timeSlots], winMaxVal,
+ p_r - timeSlots);
+ FDKmemset_flex(&pWindowAna__FDK[w][p_r], FX_DBL2FX_WIN((FIXP_DBL)0),
+ 2 * timeSlots - p_r);
+
+ } else { /* No transient in right half of ana. window */
+ /* Analysis Window */
+ FDKmemset_flex(&pWindowAna__FDK[w][timeSlots], winMaxVal,
+ stopRect - timeSlots + 1);
+ FDKmemcpy_flex(&pWindowAna__FDK[w][stopRect], 1,
+ &pTaperAna__FDK[taperAnaLen - 1], -1, taperAnaLen);
+ FDKmemset_flex(&pWindowAna__FDK[w][stopSlope + 1],
+ FX_DBL2FX_WIN((FIXP_DBL)0),
+ 2 * timeSlots - stopSlope - 1);
+
+ } /* if (tr_pos[1] > -1) */
+
+ /* Weight */
+ if (applyRightWindowGain__FDK[w] < winMaxVal) {
+ int ts;
+ for (ts = 0; ts < timeSlots; ts++) {
+ pWindowAna__FDK[w][timeSlots + ts] =
+ FX_DBL2FX_WIN(fMult(pWindowAna__FDK[w][timeSlots + ts],
+ applyRightWindowGain__FDK[w]));
+ }
+ }
+ } /* if (applyRightWindowGain[w] > 0.0f) */
+ else {
+ /* All Zero */
+ FDKmemset_flex(&pWindowAna__FDK[w][timeSlots],
+ FX_DBL2FX_WIN((FIXP_DBL)0), timeSlots);
+ }
+ } /* loop over windows */
+
+ if (hFrameWindow->bFrameKeep == 1) {
+ FDKmemcpy_flex(&pWindowAna__FDK[0][2 * timeSlots], 1,
+ &pWindowAna__FDK[0][timeSlots], 1, timeSlots);
+ FDKmemcpy_flex(&pWindowAna__FDK[0][timeSlots], 1, pWindowAna__FDK[0], 1,
+ timeSlots);
+
+ if (avoid_keep != 0) {
+ FDKmemset_flex(pWindowAna__FDK[0], FX_DBL2FX_WIN((FIXP_DBL)0),
+ timeSlots);
+ } else {
+ FDKmemset_flex(pWindowAna__FDK[0], winMaxVal, timeSlots);
+ }
+ } /* if (hFrameWindow->bFrameKeep==1) */
+
+ /* Feed Info to Bitstream Formatter */
+ pFramingInfo->numParamSets = pFrameWinList->n;
+ pFramingInfo->bsFramingType = 1; /* variable framing */
+ for (ps = 0; ps < pFramingInfo->numParamSets; ps++) {
+ pFramingInfo->bsParamSlots[ps] = pFrameWinList->dat[ps].slot;
+ }
+
+ /* if there is just one param set at last slot,
+ use fixed framing to save some bits */
+ if ((pFramingInfo->numParamSets == 1) &&
+ (pFramingInfo->bsParamSlots[0] == timeSlots - 1)) {
+ pFramingInfo->bsFramingType = 0;
+ }
+
+ } /* valid handle */
+
+bail:
+
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_analysisWindowing(
+ const INT nTimeSlots, const INT startTimeSlot,
+ FIXP_WIN *pFrameWindowAna__FDK, const FIXP_DPK *const *const ppDataIn__FDK,
+ FIXP_DPK *const *const ppDataOut__FDK, const INT nHybridBands,
+ const INT dim) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((pFrameWindowAna__FDK == NULL) || (ppDataIn__FDK == NULL) ||
+ (ppDataOut__FDK == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i, ts;
+ FIXP_WIN maxVal = FX_DBL2FX_WIN((FIXP_DBL)MAXVAL_DBL);
+
+ if (dim == FW_CHANGE_DIM) {
+ for (ts = startTimeSlot; ts < nTimeSlots; ts++) {
+ FIXP_WIN win = pFrameWindowAna__FDK[ts];
+ if (win == maxVal) {
+ for (i = 0; i < nHybridBands; i++) {
+ ppDataOut__FDK[i][ts].v.re = ppDataIn__FDK[ts][i].v.re;
+ ppDataOut__FDK[i][ts].v.im = ppDataIn__FDK[ts][i].v.im;
+ }
+ } else {
+ for (i = 0; i < nHybridBands; i++) {
+ ppDataOut__FDK[i][ts].v.re = fMult(win, ppDataIn__FDK[ts][i].v.re);
+ ppDataOut__FDK[i][ts].v.im = fMult(win, ppDataIn__FDK[ts][i].v.im);
+ }
+ }
+ } /* ts */
+ } else {
+ for (ts = startTimeSlot; ts < nTimeSlots; ts++) {
+ FIXP_WIN win = pFrameWindowAna__FDK[ts];
+ if (win == maxVal) {
+ for (i = 0; i < nHybridBands; i++) {
+ ppDataOut__FDK[ts][i].v.re = ppDataIn__FDK[ts][i].v.re;
+ ppDataOut__FDK[ts][i].v.im = ppDataIn__FDK[ts][i].v.im;
+ }
+ } else {
+ for (i = 0; i < nHybridBands; i++) {
+ ppDataOut__FDK[ts][i].v.re = fMult(win, ppDataIn__FDK[ts][i].v.re);
+ ppDataOut__FDK[ts][i].v.im = fMult(win, ppDataIn__FDK[ts][i].v.im);
+ }
+ }
+ } /* ts */
+ }
+ }
+
+ return error;
+}
diff --git a/fdk-aac/libSACenc/src/sacenc_framewindowing.h b/fdk-aac/libSACenc/src/sacenc_framewindowing.h
new file mode 100644
index 0000000..6b22dc9
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_framewindowing.h
@@ -0,0 +1,181 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Get windows for framing
+
+*******************************************************************************/
+
+#ifndef SACENC_FRAMEWINDOWING_H
+#define SACENC_FRAMEWINDOWING_H
+
+/**************************************************************************/ /**
+ \file
+ Description of file contents
+ ******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "genericStds.h"
+#include "common_fix.h"
+#include "sacenc_lib.h"
+#include "sacenc_bitstream.h"
+
+/* Defines *******************************************************************/
+#define FIXP_WIN FIXP_DBL
+#define FX_DBL2FX_WIN(x) (x)
+#define DALDATATYPE_WIN DALDATATYPE_DFRACT
+
+typedef enum {
+ FW_INTP = 0,
+ FW_HOLD = 1
+
+} FW_SLOTTYPE;
+
+typedef enum {
+ FW_LEAVE_DIM = 0,
+ FW_CHANGE_DIM = 1
+
+} FW_DIMENSION;
+
+/* Data Types ****************************************************************/
+typedef struct T_FRAMEWINDOW *HANDLE_FRAMEWINDOW;
+
+typedef struct T_FRAMEWINDOW_CONFIG {
+ INT nTimeSlotsMax;
+ INT bFrameKeep;
+
+} FRAMEWINDOW_CONFIG;
+
+typedef struct {
+ INT slot;
+ FW_SLOTTYPE hold;
+
+} FRAMEWIN_DATA;
+
+typedef struct {
+ FRAMEWIN_DATA dat[MAX_NUM_PARAMS];
+ INT n;
+
+} FRAMEWIN_LIST;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Create(
+ HANDLE_FRAMEWINDOW *phFrameWindow);
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Init(
+ HANDLE_FRAMEWINDOW hFrameWindow,
+ const FRAMEWINDOW_CONFIG *const pFrameWindowConfig);
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_Destroy(
+ HANDLE_FRAMEWINDOW *phFrameWindow);
+
+FDK_SACENC_ERROR fdk_sacenc_frameWindow_GetWindow(
+ HANDLE_FRAMEWINDOW hFrameWindow, INT tr_pos[MAX_NUM_PARAMS],
+ const INT timeSlots, FRAMINGINFO *const pFramingInfo,
+ FIXP_WIN *pWindowAna__FDK[MAX_NUM_PARAMS],
+ FRAMEWIN_LIST *const pFrameWinList, const INT avoid_keep);
+
+FDK_SACENC_ERROR fdk_sacenc_analysisWindowing(
+ const INT nTimeSlots, const INT startTimeSlot,
+ FIXP_WIN *pFrameWindowAna__FDK, const FIXP_DPK *const *const ppDataIn__FDK,
+ FIXP_DPK *const *const ppDataOut__FDK, const INT nHybridBands,
+ const INT dim);
+
+#endif /* SACENC_FRAMEWINDOWING_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_huff_tab.cpp b/fdk-aac/libSACenc/src/sacenc_huff_tab.cpp
new file mode 100644
index 0000000..7b28ecd
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_huff_tab.cpp
@@ -0,0 +1,997 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Markus Lohwasser
+
+ Description: SAC-Encoder constant huffman tables
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_huff_tab.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+
+/* Constants *****************************************************************/
+const HUFF_CLD_TABLE fdk_sacenc_huffCLDTab = {
+ {/* h1D[2][31] */
+ {HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000002, 2),
+ HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x000000fe, 8),
+ HUFF_PACK(0x000001fe, 9), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x000007fe, 11), HUFF_PACK(0x00000ffe, 12),
+ HUFF_PACK(0x00001ffe, 13), HUFF_PACK(0x00007ffe, 15),
+ HUFF_PACK(0x00007ffc, 15), HUFF_PACK(0x0000fffe, 16),
+ HUFF_PACK(0x0000fffa, 16), HUFF_PACK(0x0001fffe, 17),
+ HUFF_PACK(0x0001fff6, 17), HUFF_PACK(0x0003fffe, 18),
+ HUFF_PACK(0x0003ffff, 18), HUFF_PACK(0x0007ffde, 19),
+ HUFF_PACK(0x0003ffee, 18), HUFF_PACK(0x000fffbe, 20),
+ HUFF_PACK(0x001fff7e, 21), HUFF_PACK(0x00fffbfc, 24),
+ HUFF_PACK(0x00fffbfd, 24), HUFF_PACK(0x00fffbfe, 24),
+ HUFF_PACK(0x00fffbff, 24), HUFF_PACK(0x007ffdfc, 23),
+ HUFF_PACK(0x007ffdfd, 23)},
+ {HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000002, 2),
+ HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x000001fc, 9), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x000003fa, 10), HUFF_PACK(0x000007fe, 11),
+ HUFF_PACK(0x000007f6, 11), HUFF_PACK(0x00000ffe, 12),
+ HUFF_PACK(0x00000fee, 12), HUFF_PACK(0x00001ffe, 13),
+ HUFF_PACK(0x00001fde, 13), HUFF_PACK(0x00003ffe, 14),
+ HUFF_PACK(0x00003fbe, 14), HUFF_PACK(0x00003fbf, 14),
+ HUFF_PACK(0x00007ffe, 15), HUFF_PACK(0x0000fffe, 16),
+ HUFF_PACK(0x0001fffe, 17), HUFF_PACK(0x0007fffe, 19),
+ HUFF_PACK(0x0007fffc, 19), HUFF_PACK(0x000ffffa, 20),
+ HUFF_PACK(0x001ffffc, 21), HUFF_PACK(0x001ffffd, 21),
+ HUFF_PACK(0x001ffffe, 21), HUFF_PACK(0x001fffff, 21),
+ HUFF_PACK(0x000ffffb, 20)}},
+ { /* HUFF_CLD_TAB_2D */
+ { /* HUFF_CLD_TAB_2D[0][] */
+ {/* HUFF_CLD_TAB_2D[0][0] */
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x00000002, 3),
+ HUFF_PACK(0x00000004, 5), HUFF_PACK(0x0000003e, 8)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000007, 4),
+ HUFF_PACK(0x0000000e, 6), HUFF_PACK(0x000000fe, 10)},
+ {HUFF_PACK(0x0000007e, 9), HUFF_PACK(0x0000001e, 7),
+ HUFF_PACK(0x0000000c, 6), HUFF_PACK(0x00000005, 5)},
+ {HUFF_PACK(0x000000ff, 10), HUFF_PACK(0x0000000d, 6),
+ HUFF_PACK(0x00000000, 3), HUFF_PACK(0x00000003, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000002, 3), HUFF_PACK(0x00000003, 3),
+ HUFF_PACK(0x00000010, 5), HUFF_PACK(0x0000007c, 7),
+ HUFF_PACK(0x000000d6, 8), HUFF_PACK(0x000003ee, 10)},
+ {HUFF_PACK(0x0000000a, 4), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x00000016, 5), HUFF_PACK(0x00000034, 6),
+ HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x00001f7e, 13)},
+ {HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x00000036, 6),
+ HUFF_PACK(0x00000026, 6), HUFF_PACK(0x00000046, 7),
+ HUFF_PACK(0x0000011e, 9), HUFF_PACK(0x000001f6, 9)},
+ {HUFF_PACK(0x0000011f, 9), HUFF_PACK(0x000000d7, 8),
+ HUFF_PACK(0x0000008e, 8), HUFF_PACK(0x000000ff, 8),
+ HUFF_PACK(0x0000006a, 7), HUFF_PACK(0x0000004e, 7)},
+ {HUFF_PACK(0x00000fbe, 12), HUFF_PACK(0x000007de, 11),
+ HUFF_PACK(0x0000004f, 7), HUFF_PACK(0x00000037, 6),
+ HUFF_PACK(0x00000017, 5), HUFF_PACK(0x0000001e, 5)},
+ {HUFF_PACK(0x00001f7f, 13), HUFF_PACK(0x000000fa, 8),
+ HUFF_PACK(0x00000022, 6), HUFF_PACK(0x00000012, 5),
+ HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x0000007c, 7),
+ HUFF_PACK(0x000000be, 8), HUFF_PACK(0x0000017a, 9),
+ HUFF_PACK(0x000000ee, 9), HUFF_PACK(0x000007b6, 11)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x00000016, 5), HUFF_PACK(0x00000026, 6),
+ HUFF_PACK(0x0000003e, 7), HUFF_PACK(0x0000002e, 7),
+ HUFF_PACK(0x000001ec, 9), HUFF_PACK(0x000047ce, 15)},
+ {HUFF_PACK(0x00000016, 6), HUFF_PACK(0x0000003c, 6),
+ HUFF_PACK(0x00000022, 6), HUFF_PACK(0x0000004e, 7),
+ HUFF_PACK(0x0000003f, 7), HUFF_PACK(0x0000005e, 8),
+ HUFF_PACK(0x000008fa, 12), HUFF_PACK(0x000008fb, 12)},
+ {HUFF_PACK(0x0000005f, 8), HUFF_PACK(0x000000fa, 8),
+ HUFF_PACK(0x000000bf, 8), HUFF_PACK(0x0000003a, 7),
+ HUFF_PACK(0x000001f6, 9), HUFF_PACK(0x000001de, 10),
+ HUFF_PACK(0x000003da, 10), HUFF_PACK(0x000007b7, 11)},
+ {HUFF_PACK(0x000001df, 10), HUFF_PACK(0x000003ee, 10),
+ HUFF_PACK(0x0000017b, 9), HUFF_PACK(0x000003ef, 10),
+ HUFF_PACK(0x000001ee, 9), HUFF_PACK(0x0000008e, 8),
+ HUFF_PACK(0x000001ef, 9), HUFF_PACK(0x000001fe, 9)},
+ {HUFF_PACK(0x000008f8, 12), HUFF_PACK(0x0000047e, 11),
+ HUFF_PACK(0x0000047f, 11), HUFF_PACK(0x00000076, 8),
+ HUFF_PACK(0x0000003c, 7), HUFF_PACK(0x00000046, 7),
+ HUFF_PACK(0x0000007a, 7), HUFF_PACK(0x0000007e, 7)},
+ {HUFF_PACK(0x000023e6, 14), HUFF_PACK(0x000011f2, 13),
+ HUFF_PACK(0x000001ff, 9), HUFF_PACK(0x0000003d, 7),
+ HUFF_PACK(0x0000004f, 7), HUFF_PACK(0x0000002e, 6),
+ HUFF_PACK(0x00000012, 5), HUFF_PACK(0x00000004, 4)},
+ {HUFF_PACK(0x000047cf, 15), HUFF_PACK(0x0000011e, 9),
+ HUFF_PACK(0x000000bc, 8), HUFF_PACK(0x000000fe, 8),
+ HUFF_PACK(0x0000001c, 6), HUFF_PACK(0x00000010, 5),
+ HUFF_PACK(0x0000000d, 4), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV9_2D */
+ {{HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000007, 4),
+ HUFF_PACK(0x00000006, 5), HUFF_PACK(0x0000007e, 7),
+ HUFF_PACK(0x0000000a, 7), HUFF_PACK(0x0000001e, 8),
+ HUFF_PACK(0x0000008a, 9), HUFF_PACK(0x0000004e, 10),
+ HUFF_PACK(0x00000276, 10), HUFF_PACK(0x000002e2, 11)},
+ {HUFF_PACK(0x00000000, 4), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x00000016, 5), HUFF_PACK(0x00000026, 6),
+ HUFF_PACK(0x00000076, 7), HUFF_PACK(0x000000f2, 8),
+ HUFF_PACK(0x00000012, 8), HUFF_PACK(0x0000005e, 8),
+ HUFF_PACK(0x0000008b, 9), HUFF_PACK(0x00002e76, 15)},
+ {HUFF_PACK(0x00000012, 6), HUFF_PACK(0x00000007, 5),
+ HUFF_PACK(0x00000038, 6), HUFF_PACK(0x0000007c, 7),
+ HUFF_PACK(0x00000008, 7), HUFF_PACK(0x00000046, 8),
+ HUFF_PACK(0x000000f6, 8), HUFF_PACK(0x000001ca, 9),
+ HUFF_PACK(0x0000173a, 14), HUFF_PACK(0x00001738, 14)},
+ {HUFF_PACK(0x0000009e, 8), HUFF_PACK(0x0000004a, 7),
+ HUFF_PACK(0x00000026, 7), HUFF_PACK(0x0000000c, 7),
+ HUFF_PACK(0x0000004e, 8), HUFF_PACK(0x000000f7, 8),
+ HUFF_PACK(0x0000013a, 9), HUFF_PACK(0x0000009e, 11),
+ HUFF_PACK(0x000009fe, 12), HUFF_PACK(0x0000013e, 12)},
+ {HUFF_PACK(0x00000026, 9), HUFF_PACK(0x0000001a, 8),
+ HUFF_PACK(0x000001e6, 9), HUFF_PACK(0x000001e2, 9),
+ HUFF_PACK(0x000000ee, 8), HUFF_PACK(0x000001ce, 9),
+ HUFF_PACK(0x00000277, 10), HUFF_PACK(0x000003ce, 10),
+ HUFF_PACK(0x000002e6, 11), HUFF_PACK(0x000004fc, 11)},
+ {HUFF_PACK(0x000002e3, 11), HUFF_PACK(0x00000170, 10),
+ HUFF_PACK(0x00000172, 10), HUFF_PACK(0x000000ba, 9),
+ HUFF_PACK(0x0000003e, 9), HUFF_PACK(0x000001e3, 9),
+ HUFF_PACK(0x0000001b, 8), HUFF_PACK(0x0000003f, 9),
+ HUFF_PACK(0x0000009e, 9), HUFF_PACK(0x0000009f, 9)},
+ {HUFF_PACK(0x00000b9e, 13), HUFF_PACK(0x000009ff, 12),
+ HUFF_PACK(0x000004fd, 11), HUFF_PACK(0x000004fe, 11),
+ HUFF_PACK(0x000001cf, 9), HUFF_PACK(0x000000ef, 8),
+ HUFF_PACK(0x00000044, 8), HUFF_PACK(0x0000005f, 8),
+ HUFF_PACK(0x000000e4, 8), HUFF_PACK(0x000000f0, 8)},
+ {HUFF_PACK(0x00002e72, 15), HUFF_PACK(0x0000013f, 12),
+ HUFF_PACK(0x00000b9f, 13), HUFF_PACK(0x0000013e, 9),
+ HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x00000047, 8),
+ HUFF_PACK(0x0000000e, 7), HUFF_PACK(0x0000007d, 7),
+ HUFF_PACK(0x00000010, 6), HUFF_PACK(0x00000024, 6)},
+ {HUFF_PACK(0x00002e77, 15), HUFF_PACK(0x00005ce6, 16),
+ HUFF_PACK(0x000000bb, 9), HUFF_PACK(0x000000e6, 8),
+ HUFF_PACK(0x00000016, 8), HUFF_PACK(0x000000ff, 8),
+ HUFF_PACK(0x0000007a, 7), HUFF_PACK(0x0000003a, 6),
+ HUFF_PACK(0x00000017, 5), HUFF_PACK(0x00000002, 4)},
+ {HUFF_PACK(0x00005ce7, 16), HUFF_PACK(0x000003cf, 10),
+ HUFF_PACK(0x00000017, 8), HUFF_PACK(0x000001cb, 9),
+ HUFF_PACK(0x0000009c, 8), HUFF_PACK(0x0000004b, 7),
+ HUFF_PACK(0x00000016, 6), HUFF_PACK(0x0000000a, 5),
+ HUFF_PACK(0x00000008, 4), HUFF_PACK(0x00000006, 3)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ }},
+ {/* HUFF_CLD_TAB_2D[0][1] */
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000076e, 11), HUFF_PACK(0x00000ede, 12)},
+ {HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000003f, 6),
+ HUFF_PACK(0x000003b6, 10), HUFF_PACK(0x0000003a, 6)},
+ {HUFF_PACK(0x0000001c, 5), HUFF_PACK(0x000000ee, 8),
+ HUFF_PACK(0x000001da, 9), HUFF_PACK(0x0000001e, 5)},
+ {HUFF_PACK(0x000000ef, 8), HUFF_PACK(0x00000edf, 12),
+ HUFF_PACK(0x000000ec, 8), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000001c, 5),
+ HUFF_PACK(0x0000007e, 8), HUFF_PACK(0x00000efc, 12),
+ HUFF_PACK(0x0000effe, 16), HUFF_PACK(0x0001dffe, 17)},
+ {HUFF_PACK(0x00000004, 3), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x0000003e, 7), HUFF_PACK(0x00000efe, 12),
+ HUFF_PACK(0x000077fe, 15), HUFF_PACK(0x00000076, 7)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000016, 5),
+ HUFF_PACK(0x000000be, 8), HUFF_PACK(0x00000efd, 12),
+ HUFF_PACK(0x000000ee, 8), HUFF_PACK(0x0000000e, 5)},
+ {HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x0000002e, 6),
+ HUFF_PACK(0x000001de, 9), HUFF_PACK(0x000003be, 10),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x0000001e, 5)},
+ {HUFF_PACK(0x0000007f, 7), HUFF_PACK(0x0000005e, 7),
+ HUFF_PACK(0x00003bfe, 14), HUFF_PACK(0x000000fe, 9),
+ HUFF_PACK(0x0000001e, 6), HUFF_PACK(0x00000002, 3)},
+ {HUFF_PACK(0x000000bf, 8), HUFF_PACK(0x0001dfff, 17),
+ HUFF_PACK(0x00001dfe, 13), HUFF_PACK(0x000000ff, 9),
+ HUFF_PACK(0x0000003a, 6), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000002, 3), HUFF_PACK(0x0000001c, 5),
+ HUFF_PACK(0x000000bc, 8), HUFF_PACK(0x000005fc, 11),
+ HUFF_PACK(0x00005ffe, 15), HUFF_PACK(0x0002ffde, 18),
+ HUFF_PACK(0x000bff7e, 20), HUFF_PACK(0x0017feff, 21)},
+ {HUFF_PACK(0x00000004, 3), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x0000000e, 7), HUFF_PACK(0x000002fa, 10),
+ HUFF_PACK(0x000001fe, 13), HUFF_PACK(0x0000bff2, 16),
+ HUFF_PACK(0x0005ffbe, 19), HUFF_PACK(0x000000ee, 8)},
+ {HUFF_PACK(0x00000002, 4), HUFF_PACK(0x00000016, 5),
+ HUFF_PACK(0x000000f6, 8), HUFF_PACK(0x000005fe, 11),
+ HUFF_PACK(0x000001ff, 13), HUFF_PACK(0x0000bff6, 16),
+ HUFF_PACK(0x000001de, 9), HUFF_PACK(0x0000007e, 7)},
+ {HUFF_PACK(0x00000000, 5), HUFF_PACK(0x0000003c, 6),
+ HUFF_PACK(0x0000000e, 8), HUFF_PACK(0x0000003e, 10),
+ HUFF_PACK(0x00002ffe, 14), HUFF_PACK(0x000002fb, 10),
+ HUFF_PACK(0x000000f7, 8), HUFF_PACK(0x0000002e, 6)},
+ {HUFF_PACK(0x00000006, 6), HUFF_PACK(0x0000007a, 7),
+ HUFF_PACK(0x0000000a, 8), HUFF_PACK(0x0000007e, 11),
+ HUFF_PACK(0x000000fe, 12), HUFF_PACK(0x00000016, 9),
+ HUFF_PACK(0x00000006, 7), HUFF_PACK(0x00000002, 5)},
+ {HUFF_PACK(0x0000000f, 7), HUFF_PACK(0x00000076, 7),
+ HUFF_PACK(0x00000017, 9), HUFF_PACK(0x00005ff8, 15),
+ HUFF_PACK(0x00000bfe, 12), HUFF_PACK(0x0000001e, 9),
+ HUFF_PACK(0x0000007f, 7), HUFF_PACK(0x00000003, 4)},
+ {HUFF_PACK(0x00000004, 7), HUFF_PACK(0x000000bd, 8),
+ HUFF_PACK(0x0000bff3, 16), HUFF_PACK(0x00005fff, 15),
+ HUFF_PACK(0x00000bfa, 12), HUFF_PACK(0x0000017c, 9),
+ HUFF_PACK(0x0000003a, 6), HUFF_PACK(0x00000003, 3)},
+ {HUFF_PACK(0x0000017e, 9), HUFF_PACK(0x0017fefe, 21),
+ HUFF_PACK(0x00017fee, 17), HUFF_PACK(0x00005ffa, 15),
+ HUFF_PACK(0x00000bfb, 12), HUFF_PACK(0x000001df, 9),
+ HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x00000006, 3)}},
+ HUFF_PACK(0x0017feff, 21) /* escape */
+ },
+ {
+ /* LAV9_2D */
+ {{HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x00000014, 5),
+ HUFF_PACK(0x0000008e, 8), HUFF_PACK(0x000004fe, 11),
+ HUFF_PACK(0x000023fe, 14), HUFF_PACK(0x00008ffe, 16),
+ HUFF_PACK(0x0005ffbc, 19), HUFF_PACK(0x0017fef7, 21),
+ HUFF_PACK(0x0017fef7, 21), HUFF_PACK(0x0017fef7, 21)},
+ {HUFF_PACK(0x00000002, 3), HUFF_PACK(0x00000002, 4),
+ HUFF_PACK(0x00000044, 7), HUFF_PACK(0x0000027e, 10),
+ HUFF_PACK(0x000017fc, 13), HUFF_PACK(0x0000bff6, 16),
+ HUFF_PACK(0x0005ffbe, 19), HUFF_PACK(0x00011ff8, 17),
+ HUFF_PACK(0x000bff7a, 20), HUFF_PACK(0x000000bc, 8)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000016, 5),
+ HUFF_PACK(0x0000001a, 7), HUFF_PACK(0x000000fe, 10),
+ HUFF_PACK(0x000011f6, 13), HUFF_PACK(0x0000bffe, 16),
+ HUFF_PACK(0x00011ff9, 17), HUFF_PACK(0x0017fef6, 21),
+ HUFF_PACK(0x0000011e, 9), HUFF_PACK(0x00000056, 7)},
+ {HUFF_PACK(0x00000010, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000009e, 8), HUFF_PACK(0x000007fe, 11),
+ HUFF_PACK(0x000011f7, 13), HUFF_PACK(0x00005ff8, 15),
+ HUFF_PACK(0x00017fee, 17), HUFF_PACK(0x000007ff, 11),
+ HUFF_PACK(0x000000ae, 8), HUFF_PACK(0x0000001e, 7)},
+ {HUFF_PACK(0x00000026, 6), HUFF_PACK(0x0000000e, 6),
+ HUFF_PACK(0x000001ee, 9), HUFF_PACK(0x0000047e, 11),
+ HUFF_PACK(0x00000bfc, 12), HUFF_PACK(0x0000bfff, 16),
+ HUFF_PACK(0x000008fa, 12), HUFF_PACK(0x0000006e, 9),
+ HUFF_PACK(0x000001ef, 9), HUFF_PACK(0x0000007e, 7)},
+ {HUFF_PACK(0x0000007a, 7), HUFF_PACK(0x0000004e, 7),
+ HUFF_PACK(0x0000007e, 9), HUFF_PACK(0x000000de, 10),
+ HUFF_PACK(0x000011fe, 13), HUFF_PACK(0x00002ffe, 14),
+ HUFF_PACK(0x000004ff, 11), HUFF_PACK(0x000000ff, 10),
+ HUFF_PACK(0x000000bd, 8), HUFF_PACK(0x0000002e, 6)},
+ {HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x000000af, 8),
+ HUFF_PACK(0x000001ec, 9), HUFF_PACK(0x000001be, 11),
+ HUFF_PACK(0x00011ffe, 17), HUFF_PACK(0x00002ffa, 14),
+ HUFF_PACK(0x000008fe, 12), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x00000046, 7), HUFF_PACK(0x00000012, 5)},
+ {HUFF_PACK(0x0000003e, 8), HUFF_PACK(0x00000045, 7),
+ HUFF_PACK(0x000002fe, 10), HUFF_PACK(0x000bff7e, 20),
+ HUFF_PACK(0x00005ff9, 15), HUFF_PACK(0x00005ffa, 15),
+ HUFF_PACK(0x00000bfd, 12), HUFF_PACK(0x0000013e, 9),
+ HUFF_PACK(0x0000000c, 6), HUFF_PACK(0x00000007, 4)},
+ {HUFF_PACK(0x000000be, 8), HUFF_PACK(0x00000036, 8),
+ HUFF_PACK(0x000bff7f, 20), HUFF_PACK(0x00023ffe, 18),
+ HUFF_PACK(0x00011ffa, 17), HUFF_PACK(0x00005ffe, 15),
+ HUFF_PACK(0x000001bf, 11), HUFF_PACK(0x000001ed, 9),
+ HUFF_PACK(0x0000002a, 6), HUFF_PACK(0x00000000, 3)},
+ {HUFF_PACK(0x0000017e, 9), HUFF_PACK(0x0017fef7, 21),
+ HUFF_PACK(0x00047ffe, 19), HUFF_PACK(0x00047fff, 19),
+ HUFF_PACK(0x00011ffb, 17), HUFF_PACK(0x00002ffb, 14),
+ HUFF_PACK(0x0000047c, 11), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x0000003c, 6), HUFF_PACK(0x00000006, 3)}},
+ HUFF_PACK(0x0017fef7, 21) /* escape */
+ }}},
+ { /* HUFF_CLD_TAB_2D[1][] */
+ {/* HUFF_CLD_TAB_2D[1][0] */
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x0000001e, 5),
+ HUFF_PACK(0x000003be, 10), HUFF_PACK(0x00000efe, 12)},
+ {HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000001c, 5),
+ HUFF_PACK(0x000001de, 9), HUFF_PACK(0x000000ea, 8)},
+ {HUFF_PACK(0x00000074, 7), HUFF_PACK(0x000000ee, 8),
+ HUFF_PACK(0x000000eb, 8), HUFF_PACK(0x0000001f, 5)},
+ {HUFF_PACK(0x0000077e, 11), HUFF_PACK(0x00000eff, 12),
+ HUFF_PACK(0x00000076, 7), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x00000006, 4),
+ HUFF_PACK(0x00000024, 7), HUFF_PACK(0x0000025e, 11),
+ HUFF_PACK(0x00003cfe, 14), HUFF_PACK(0x000079fe, 15)},
+ {HUFF_PACK(0x00000006, 3), HUFF_PACK(0x00000007, 4),
+ HUFF_PACK(0x00000078, 7), HUFF_PACK(0x000003ce, 10),
+ HUFF_PACK(0x00001e7e, 13), HUFF_PACK(0x000000be, 9)},
+ {HUFF_PACK(0x00000008, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x00000026, 7), HUFF_PACK(0x0000012e, 10),
+ HUFF_PACK(0x000000bf, 9), HUFF_PACK(0x0000002e, 7)},
+ {HUFF_PACK(0x00000027, 7), HUFF_PACK(0x0000007a, 7),
+ HUFF_PACK(0x000001e4, 9), HUFF_PACK(0x00000096, 9),
+ HUFF_PACK(0x0000007b, 7), HUFF_PACK(0x0000003f, 6)},
+ {HUFF_PACK(0x000001e6, 9), HUFF_PACK(0x000001e5, 9),
+ HUFF_PACK(0x00000f3e, 12), HUFF_PACK(0x0000005e, 8),
+ HUFF_PACK(0x00000016, 6), HUFF_PACK(0x0000000e, 4)},
+ {HUFF_PACK(0x0000079e, 11), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x0000025f, 11), HUFF_PACK(0x0000004a, 8),
+ HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x00000006, 4),
+ HUFF_PACK(0x000000de, 8), HUFF_PACK(0x0000069e, 11),
+ HUFF_PACK(0x000034fe, 14), HUFF_PACK(0x0001a7fe, 17),
+ HUFF_PACK(0x00069ff6, 19), HUFF_PACK(0x00069ff7, 19)},
+ {HUFF_PACK(0x00000002, 3), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x0000006a, 7), HUFF_PACK(0x0000034e, 10),
+ HUFF_PACK(0x00001fde, 13), HUFF_PACK(0x000069fe, 15),
+ HUFF_PACK(0x0001a7fc, 17), HUFF_PACK(0x00000372, 10)},
+ {HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x0000003c, 6),
+ HUFF_PACK(0x000000df, 8), HUFF_PACK(0x000001ee, 10),
+ HUFF_PACK(0x00000dde, 12), HUFF_PACK(0x000069fa, 15),
+ HUFF_PACK(0x00000373, 10), HUFF_PACK(0x0000007a, 8)},
+ {HUFF_PACK(0x0000003e, 7), HUFF_PACK(0x00000068, 7),
+ HUFF_PACK(0x000001ba, 9), HUFF_PACK(0x000003f6, 10),
+ HUFF_PACK(0x00000d3e, 12), HUFF_PACK(0x0000034c, 10),
+ HUFF_PACK(0x000001fa, 9), HUFF_PACK(0x000000d2, 8)},
+ {HUFF_PACK(0x0000007e, 8), HUFF_PACK(0x0000007f, 8),
+ HUFF_PACK(0x000001f8, 9), HUFF_PACK(0x000006ee, 11),
+ HUFF_PACK(0x000003de, 11), HUFF_PACK(0x000001b8, 9),
+ HUFF_PACK(0x000001fc, 9), HUFF_PACK(0x0000006b, 7)},
+ {HUFF_PACK(0x000000f6, 9), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x0000034d, 10), HUFF_PACK(0x00003fbe, 14),
+ HUFF_PACK(0x000007f6, 11), HUFF_PACK(0x000003fa, 10),
+ HUFF_PACK(0x0000003c, 7), HUFF_PACK(0x0000003d, 6)},
+ {HUFF_PACK(0x000003f7, 10), HUFF_PACK(0x00000376, 10),
+ HUFF_PACK(0x0001a7ff, 17), HUFF_PACK(0x00003fbf, 14),
+ HUFF_PACK(0x00000ddf, 12), HUFF_PACK(0x000001f9, 9),
+ HUFF_PACK(0x00000036, 6), HUFF_PACK(0x0000000e, 4)},
+ {HUFF_PACK(0x000003df, 11), HUFF_PACK(0x00034ffa, 18),
+ HUFF_PACK(0x000069fb, 15), HUFF_PACK(0x000034fc, 14),
+ HUFF_PACK(0x00000fee, 12), HUFF_PACK(0x000001ff, 9),
+ HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV9_2D */
+ {{HUFF_PACK(0x00000006, 3), HUFF_PACK(0x00000004, 4),
+ HUFF_PACK(0x00000012, 7), HUFF_PACK(0x000007fe, 11),
+ HUFF_PACK(0x00001f7e, 13), HUFF_PACK(0x0000fbfe, 16),
+ HUFF_PACK(0x0001f7fe, 17), HUFF_PACK(0x000b7dfe, 21),
+ HUFF_PACK(0x000b7dff, 21), HUFF_PACK(0x000b7dff, 21)},
+ {HUFF_PACK(0x00000000, 3), HUFF_PACK(0x00000006, 4),
+ HUFF_PACK(0x0000007c, 7), HUFF_PACK(0x00000046, 9),
+ HUFF_PACK(0x000007d0, 12), HUFF_PACK(0x00001f4e, 14),
+ HUFF_PACK(0x0000b7fe, 17), HUFF_PACK(0x00005bee, 16),
+ HUFF_PACK(0x00016fbe, 18), HUFF_PACK(0x000003ee, 10)},
+ {HUFF_PACK(0x00000006, 5), HUFF_PACK(0x0000000a, 5),
+ HUFF_PACK(0x0000002e, 7), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x000007d2, 12), HUFF_PACK(0x00001f4f, 14),
+ HUFF_PACK(0x00002dfe, 15), HUFF_PACK(0x0000b7de, 17),
+ HUFF_PACK(0x000001fe, 10), HUFF_PACK(0x0000002e, 8)},
+ {HUFF_PACK(0x0000007a, 7), HUFF_PACK(0x0000007e, 7),
+ HUFF_PACK(0x0000007a, 8), HUFF_PACK(0x000001fa, 10),
+ HUFF_PACK(0x000007fe, 12), HUFF_PACK(0x00001f7c, 13),
+ HUFF_PACK(0x000016fa, 14), HUFF_PACK(0x0000009e, 10),
+ HUFF_PACK(0x00000020, 8), HUFF_PACK(0x00000021, 8)},
+ {HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x00000016, 7),
+ HUFF_PACK(0x000000fe, 9), HUFF_PACK(0x0000016e, 10),
+ HUFF_PACK(0x0000009f, 10), HUFF_PACK(0x00000b7c, 13),
+ HUFF_PACK(0x000003de, 11), HUFF_PACK(0x000000b6, 9),
+ HUFF_PACK(0x000000be, 9), HUFF_PACK(0x0000007c, 8)},
+ {HUFF_PACK(0x0000005a, 8), HUFF_PACK(0x00000078, 8),
+ HUFF_PACK(0x00000047, 9), HUFF_PACK(0x00000044, 9),
+ HUFF_PACK(0x000007ff, 12), HUFF_PACK(0x000007d1, 12),
+ HUFF_PACK(0x000001f6, 10), HUFF_PACK(0x000001f7, 10),
+ HUFF_PACK(0x0000002f, 8), HUFF_PACK(0x0000002c, 7)},
+ {HUFF_PACK(0x000000fc, 9), HUFF_PACK(0x000001f6, 9),
+ HUFF_PACK(0x000000f6, 9), HUFF_PACK(0x000007ff, 11),
+ HUFF_PACK(0x000016fe, 14), HUFF_PACK(0x000002de, 11),
+ HUFF_PACK(0x000003ea, 11), HUFF_PACK(0x000000bf, 9),
+ HUFF_PACK(0x000000fa, 8), HUFF_PACK(0x0000000a, 6)},
+ {HUFF_PACK(0x0000004e, 9), HUFF_PACK(0x00000026, 8),
+ HUFF_PACK(0x000001ee, 10), HUFF_PACK(0x00005bfe, 16),
+ HUFF_PACK(0x00003efe, 14), HUFF_PACK(0x00000b7e, 13),
+ HUFF_PACK(0x000003eb, 11), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x0000007b, 7), HUFF_PACK(0x00000007, 5)},
+ {HUFF_PACK(0x000001fb, 10), HUFF_PACK(0x00000045, 9),
+ HUFF_PACK(0x00016ffe, 18), HUFF_PACK(0x0001f7ff, 17),
+ HUFF_PACK(0x00002df6, 15), HUFF_PACK(0x00001f7d, 13),
+ HUFF_PACK(0x000003fe, 11), HUFF_PACK(0x0000005e, 8),
+ HUFF_PACK(0x0000003c, 6), HUFF_PACK(0x0000000e, 4)},
+ {HUFF_PACK(0x000003df, 11), HUFF_PACK(0x0005befe, 20),
+ HUFF_PACK(0x0002df7e, 19), HUFF_PACK(0x00016fff, 18),
+ HUFF_PACK(0x00007dfe, 15), HUFF_PACK(0x00000fa6, 13),
+ HUFF_PACK(0x000007de, 11), HUFF_PACK(0x00000079, 8),
+ HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x000b7dff, 21) /* escape */
+ }},
+ {/* HUFF_CLD_TAB_2D[1][1] */
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x000000fa, 8), HUFF_PACK(0x000007de, 11)},
+ {HUFF_PACK(0x0000000c, 4), HUFF_PACK(0x0000001e, 5),
+ HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x000001f6, 9)},
+ {HUFF_PACK(0x000000ff, 8), HUFF_PACK(0x0000007c, 7),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x0000001a, 5)},
+ {HUFF_PACK(0x000007df, 11), HUFF_PACK(0x000003ee, 10),
+ HUFF_PACK(0x0000001b, 5), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000007c, 7), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x00000fbe, 12), HUFF_PACK(0x00003efe, 14)},
+ {HUFF_PACK(0x00000000, 3), HUFF_PACK(0x00000001, 3),
+ HUFF_PACK(0x0000003c, 6), HUFF_PACK(0x0000005e, 8),
+ HUFF_PACK(0x000007de, 11), HUFF_PACK(0x000007be, 11)},
+ {HUFF_PACK(0x0000001e, 6), HUFF_PACK(0x0000000a, 5),
+ HUFF_PACK(0x0000001f, 6), HUFF_PACK(0x0000005f, 8),
+ HUFF_PACK(0x000001ee, 9), HUFF_PACK(0x000001f6, 9)},
+ {HUFF_PACK(0x000001fe, 9), HUFF_PACK(0x000000fe, 8),
+ HUFF_PACK(0x000000f6, 8), HUFF_PACK(0x000000fa, 8),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x00000016, 6)},
+ {HUFF_PACK(0x000007bf, 11), HUFF_PACK(0x000003de, 10),
+ HUFF_PACK(0x000003ee, 10), HUFF_PACK(0x0000007a, 7),
+ HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x00000006, 4)},
+ {HUFF_PACK(0x00003eff, 14), HUFF_PACK(0x00001f7e, 13),
+ HUFF_PACK(0x000003ff, 10), HUFF_PACK(0x0000002e, 7),
+ HUFF_PACK(0x00000004, 4), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000002, 3), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x0000001a, 6), HUFF_PACK(0x000001be, 9),
+ HUFF_PACK(0x000006e6, 11), HUFF_PACK(0x0000067a, 12),
+ HUFF_PACK(0x00000cf2, 13), HUFF_PACK(0x000033de, 15)},
+ {HUFF_PACK(0x0000000c, 4), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x000000de, 8),
+ HUFF_PACK(0x00000372, 10), HUFF_PACK(0x000003d6, 11),
+ HUFF_PACK(0x00000678, 12), HUFF_PACK(0x00000cf6, 13)},
+ {HUFF_PACK(0x00000036, 6), HUFF_PACK(0x00000012, 5),
+ HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x0000003c, 7),
+ HUFF_PACK(0x000001b8, 9), HUFF_PACK(0x000003d4, 11),
+ HUFF_PACK(0x0000033e, 11), HUFF_PACK(0x0000033f, 11)},
+ {HUFF_PACK(0x0000007e, 8), HUFF_PACK(0x0000006a, 7),
+ HUFF_PACK(0x0000004e, 7), HUFF_PACK(0x0000007e, 7),
+ HUFF_PACK(0x000001ba, 9), HUFF_PACK(0x000000ce, 9),
+ HUFF_PACK(0x000000f6, 9), HUFF_PACK(0x000001ee, 10)},
+ {HUFF_PACK(0x000001ef, 10), HUFF_PACK(0x0000013e, 9),
+ HUFF_PACK(0x0000007f, 8), HUFF_PACK(0x00000066, 8),
+ HUFF_PACK(0x000000d6, 8), HUFF_PACK(0x0000003e, 7),
+ HUFF_PACK(0x000000d7, 8), HUFF_PACK(0x0000009e, 8)},
+ {HUFF_PACK(0x000007ae, 12), HUFF_PACK(0x000001e8, 10),
+ HUFF_PACK(0x000001e9, 10), HUFF_PACK(0x0000027e, 10),
+ HUFF_PACK(0x00000032, 7), HUFF_PACK(0x00000018, 6),
+ HUFF_PACK(0x00000026, 6), HUFF_PACK(0x00000034, 6)},
+ {HUFF_PACK(0x00000cf3, 13), HUFF_PACK(0x000007aa, 12),
+ HUFF_PACK(0x000007ab, 12), HUFF_PACK(0x0000027f, 10),
+ HUFF_PACK(0x000001bf, 9), HUFF_PACK(0x0000001b, 6),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000000b, 4)},
+ {HUFF_PACK(0x000033df, 15), HUFF_PACK(0x000019ee, 14),
+ HUFF_PACK(0x000007af, 12), HUFF_PACK(0x000006e7, 11),
+ HUFF_PACK(0x000001bb, 9), HUFF_PACK(0x0000007f, 7),
+ HUFF_PACK(0x00000008, 4), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV9_2D */
+ {{HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x00000008, 4),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x000001ba, 10), HUFF_PACK(0x00000dbe, 12),
+ HUFF_PACK(0x00000d7e, 13), HUFF_PACK(0x00001af6, 14),
+ HUFF_PACK(0x00007fec, 15), HUFF_PACK(0x0001ffb6, 17)},
+ {HUFF_PACK(0x0000000a, 4), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x0000000c, 5), HUFF_PACK(0x00000036, 7),
+ HUFF_PACK(0x000000de, 9), HUFF_PACK(0x000005fe, 11),
+ HUFF_PACK(0x000006be, 12), HUFF_PACK(0x00001b7e, 13),
+ HUFF_PACK(0x00007fee, 15), HUFF_PACK(0x00006dfe, 15)},
+ {HUFF_PACK(0x0000001e, 6), HUFF_PACK(0x0000000e, 5),
+ HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x0000006a, 7),
+ HUFF_PACK(0x000001ae, 9), HUFF_PACK(0x000006fe, 11),
+ HUFF_PACK(0x00000376, 11), HUFF_PACK(0x00000dfe, 13),
+ HUFF_PACK(0x00000dff, 13), HUFF_PACK(0x00000d7f, 13)},
+ {HUFF_PACK(0x000000b6, 8), HUFF_PACK(0x0000005e, 7),
+ HUFF_PACK(0x0000007c, 7), HUFF_PACK(0x0000006e, 7),
+ HUFF_PACK(0x0000006a, 8), HUFF_PACK(0x0000016a, 9),
+ HUFF_PACK(0x00000ffe, 12), HUFF_PACK(0x00000dfe, 12),
+ HUFF_PACK(0x00000ffc, 12), HUFF_PACK(0x00001bfe, 13)},
+ {HUFF_PACK(0x0000035e, 10), HUFF_PACK(0x000001b6, 9),
+ HUFF_PACK(0x0000005e, 8), HUFF_PACK(0x000000b4, 8),
+ HUFF_PACK(0x0000006c, 7), HUFF_PACK(0x0000017e, 9),
+ HUFF_PACK(0x0000036e, 10), HUFF_PACK(0x000003ee, 10),
+ HUFF_PACK(0x0000037e, 11), HUFF_PACK(0x00000377, 11)},
+ {HUFF_PACK(0x00000fff, 12), HUFF_PACK(0x000001ae, 10),
+ HUFF_PACK(0x000001be, 10), HUFF_PACK(0x000001f6, 9),
+ HUFF_PACK(0x000001be, 9), HUFF_PACK(0x000000da, 8),
+ HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x0000016b, 9),
+ HUFF_PACK(0x000000d6, 9), HUFF_PACK(0x0000037e, 10)},
+ {HUFF_PACK(0x000017fe, 13), HUFF_PACK(0x00000bfe, 12),
+ HUFF_PACK(0x000007de, 11), HUFF_PACK(0x000006de, 11),
+ HUFF_PACK(0x000001b8, 10), HUFF_PACK(0x000000d6, 8),
+ HUFF_PACK(0x0000002e, 7), HUFF_PACK(0x00000034, 7),
+ HUFF_PACK(0x000000de, 8), HUFF_PACK(0x000000be, 8)},
+ {HUFF_PACK(0x00007fef, 15), HUFF_PACK(0x000006bc, 12),
+ HUFF_PACK(0x00001bff, 13), HUFF_PACK(0x00001ffa, 13),
+ HUFF_PACK(0x000001b9, 10), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x000000fa, 8), HUFF_PACK(0x0000002e, 6),
+ HUFF_PACK(0x00000034, 6), HUFF_PACK(0x0000001f, 6)},
+ {HUFF_PACK(0x00006dff, 15), HUFF_PACK(0x00001af7, 14),
+ HUFF_PACK(0x000036fe, 14), HUFF_PACK(0x000006fe, 12),
+ HUFF_PACK(0x00000fbe, 12), HUFF_PACK(0x0000035f, 10),
+ HUFF_PACK(0x000000b7, 8), HUFF_PACK(0x0000002c, 6),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x00000009, 4)},
+ {HUFF_PACK(0x0001ffb7, 17), HUFF_PACK(0x0000ffda, 16),
+ HUFF_PACK(0x00000d7a, 13), HUFF_PACK(0x000017ff, 13),
+ HUFF_PACK(0x00000fbf, 12), HUFF_PACK(0x000002fe, 10),
+ HUFF_PACK(0x0000005f, 8), HUFF_PACK(0x00000016, 6),
+ HUFF_PACK(0x00000004, 4), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ }}}}};
+
+const HUFF_ICC_TABLE fdk_sacenc_huffICCTab = {
+ {/* h1D[2][8] */
+ {HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000002, 2),
+ HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x0000007f, 7)},
+ {HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000002, 2),
+ HUFF_PACK(0x00000006, 3), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x0000007f, 7)}},
+ { /* HUFF_ICC_TAB_2D */
+ { /* HUFF_ICC_TAB_2D[0][] */
+ {/* HUFF_ICC_TAB_2D[0][0] */
+ {
+ /* LAV1_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000006, 3)},
+ {HUFF_PACK(0x00000007, 3), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x00000000, 2),
+ HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x0000007e, 8)},
+ {HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x00000004, 4),
+ HUFF_PACK(0x00000016, 6), HUFF_PACK(0x000003fe, 11)},
+ {HUFF_PACK(0x000001fe, 10), HUFF_PACK(0x000000fe, 9),
+ HUFF_PACK(0x0000003e, 7), HUFF_PACK(0x0000001e, 6)},
+ {HUFF_PACK(0x000003ff, 11), HUFF_PACK(0x00000017, 6),
+ HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000003, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x00000002, 3),
+ HUFF_PACK(0x0000000c, 5), HUFF_PACK(0x0000006a, 7),
+ HUFF_PACK(0x000000dc, 8), HUFF_PACK(0x000006ee, 11)},
+ {HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x0000000d, 5), HUFF_PACK(0x0000001e, 6),
+ HUFF_PACK(0x000001ae, 9), HUFF_PACK(0x0000ddff, 16)},
+ {HUFF_PACK(0x000000de, 8), HUFF_PACK(0x0000007e, 7),
+ HUFF_PACK(0x0000001f, 6), HUFF_PACK(0x000001be, 9),
+ HUFF_PACK(0x00006efe, 15), HUFF_PACK(0x0000ddfe, 16)},
+ {HUFF_PACK(0x0000377e, 14), HUFF_PACK(0x00001bbe, 13),
+ HUFF_PACK(0x00000dde, 12), HUFF_PACK(0x000001bf, 9),
+ HUFF_PACK(0x000000d6, 8), HUFF_PACK(0x00000376, 10)},
+ {HUFF_PACK(0x0000ddff, 16), HUFF_PACK(0x0000ddff, 16),
+ HUFF_PACK(0x000001ba, 9), HUFF_PACK(0x00000034, 6),
+ HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x0000000e, 5)},
+ {HUFF_PACK(0x0000ddff, 16), HUFF_PACK(0x000001af, 9),
+ HUFF_PACK(0x0000007f, 7), HUFF_PACK(0x00000036, 6),
+ HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x0000ddff, 16) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x0000002e, 6), HUFF_PACK(0x00000044, 7),
+ HUFF_PACK(0x00000086, 8), HUFF_PACK(0x0000069e, 11),
+ HUFF_PACK(0x0000043e, 11), HUFF_PACK(0x0000087a, 12)},
+ {HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000002a, 6), HUFF_PACK(0x00000046, 7),
+ HUFF_PACK(0x0000015e, 9), HUFF_PACK(0x00000047, 7),
+ HUFF_PACK(0x0000034a, 10), HUFF_PACK(0x0000087b, 12)},
+ {HUFF_PACK(0x000000d6, 8), HUFF_PACK(0x00000026, 6),
+ HUFF_PACK(0x0000002f, 6), HUFF_PACK(0x000000d7, 8),
+ HUFF_PACK(0x0000006a, 7), HUFF_PACK(0x0000034e, 10),
+ HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12)},
+ {HUFF_PACK(0x000002be, 10), HUFF_PACK(0x000001a6, 9),
+ HUFF_PACK(0x000001be, 9), HUFF_PACK(0x00000012, 5),
+ HUFF_PACK(0x000001bf, 9), HUFF_PACK(0x0000087b, 12),
+ HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12)},
+ {HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12),
+ HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12),
+ HUFF_PACK(0x00000036, 6), HUFF_PACK(0x000000d0, 8),
+ HUFF_PACK(0x0000043c, 11), HUFF_PACK(0x0000043f, 11)},
+ {HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12),
+ HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000034b, 10),
+ HUFF_PACK(0x00000027, 6), HUFF_PACK(0x00000020, 6),
+ HUFF_PACK(0x00000042, 7), HUFF_PACK(0x000000d1, 8)},
+ {HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000087b, 12),
+ HUFF_PACK(0x000002bf, 10), HUFF_PACK(0x000000de, 8),
+ HUFF_PACK(0x000000ae, 8), HUFF_PACK(0x00000056, 7),
+ HUFF_PACK(0x00000016, 5), HUFF_PACK(0x00000014, 5)},
+ {HUFF_PACK(0x0000087b, 12), HUFF_PACK(0x0000069f, 11),
+ HUFF_PACK(0x000001a4, 9), HUFF_PACK(0x0000010e, 9),
+ HUFF_PACK(0x00000045, 7), HUFF_PACK(0x0000006e, 7),
+ HUFF_PACK(0x0000001f, 5), HUFF_PACK(0x00000001, 2)}},
+ HUFF_PACK(0x0000087b, 12) /* escape */
+ }},
+ {/* HUFF_ICC_TAB_2D[0][1] */
+ {
+ /* LAV1_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000006, 3)},
+ {HUFF_PACK(0x00000007, 3), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x00000004, 4),
+ HUFF_PACK(0x0000017e, 10), HUFF_PACK(0x000002fe, 11)},
+ {HUFF_PACK(0x00000000, 2), HUFF_PACK(0x0000000e, 5),
+ HUFF_PACK(0x000000be, 9), HUFF_PACK(0x00000016, 6)},
+ {HUFF_PACK(0x0000000f, 5), HUFF_PACK(0x00000014, 6),
+ HUFF_PACK(0x0000005e, 8), HUFF_PACK(0x00000006, 4)},
+ {HUFF_PACK(0x0000002e, 7), HUFF_PACK(0x000002ff, 11),
+ HUFF_PACK(0x00000015, 6), HUFF_PACK(0x00000003, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x0000001e, 5),
+ HUFF_PACK(0x000003fc, 10), HUFF_PACK(0x0000fffa, 16),
+ HUFF_PACK(0x000fff9e, 20), HUFF_PACK(0x000fff9f, 20)},
+ {HUFF_PACK(0x00000006, 3), HUFF_PACK(0x00000004, 4),
+ HUFF_PACK(0x000000be, 9), HUFF_PACK(0x00007ffe, 15),
+ HUFF_PACK(0x0007ffce, 19), HUFF_PACK(0x000000fe, 8)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x0000001e, 6),
+ HUFF_PACK(0x000003fd, 10), HUFF_PACK(0x0000fffb, 16),
+ HUFF_PACK(0x00000ffe, 12), HUFF_PACK(0x0000003e, 6)},
+ {HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x0000007e, 7),
+ HUFF_PACK(0x00001ffe, 13), HUFF_PACK(0x00007fff, 15),
+ HUFF_PACK(0x0000005e, 8), HUFF_PACK(0x0000000e, 5)},
+ {HUFF_PACK(0x0000001f, 6), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x0001fff2, 17), HUFF_PACK(0x00000ffc, 12),
+ HUFF_PACK(0x0000002e, 7), HUFF_PACK(0x0000000e, 4)},
+ {HUFF_PACK(0x000000bf, 9), HUFF_PACK(0x0003ffe6, 18),
+ HUFF_PACK(0x0000fff8, 16), HUFF_PACK(0x00000ffd, 12),
+ HUFF_PACK(0x00000016, 6), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x0000001e, 6),
+ HUFF_PACK(0x00000ffe, 12), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000fffe, 16), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000ffff, 16)},
+ {HUFF_PACK(0x00000006, 3), HUFF_PACK(0x00000008, 5),
+ HUFF_PACK(0x000007fe, 11), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000005a, 8)},
+ {HUFF_PACK(0x00000006, 4), HUFF_PACK(0x0000007a, 7),
+ HUFF_PACK(0x00000164, 10), HUFF_PACK(0x00007ffa, 15),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x00001fee, 13), HUFF_PACK(0x0000003c, 6)},
+ {HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x000000fe, 8),
+ HUFF_PACK(0x000002ce, 11), HUFF_PACK(0x000002cf, 11),
+ HUFF_PACK(0x00007ffb, 15), HUFF_PACK(0x00001fec, 13),
+ HUFF_PACK(0x000000b0, 9), HUFF_PACK(0x0000002e, 7)},
+ {HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x00000165, 10), HUFF_PACK(0x00007ffc, 15),
+ HUFF_PACK(0x00001fef, 13), HUFF_PACK(0x000007fa, 11),
+ HUFF_PACK(0x000007f8, 11), HUFF_PACK(0x0000001f, 6)},
+ {HUFF_PACK(0x0000002f, 7), HUFF_PACK(0x000000f6, 8),
+ HUFF_PACK(0x00001fed, 13), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x00007ffd, 15), HUFF_PACK(0x00000ff2, 12),
+ HUFF_PACK(0x000000b1, 9), HUFF_PACK(0x0000000a, 5)},
+ {HUFF_PACK(0x00000009, 5), HUFF_PACK(0x00000166, 10),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x00007ffe, 15), HUFF_PACK(0x00003ffc, 14),
+ HUFF_PACK(0x0000005b, 8), HUFF_PACK(0x0000000e, 4)},
+ {HUFF_PACK(0x0000007e, 7), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x0000ffff, 16),
+ HUFF_PACK(0x0000ffff, 16), HUFF_PACK(0x00000ff3, 12),
+ HUFF_PACK(0x000000f7, 8), HUFF_PACK(0x00000000, 2)}},
+ HUFF_PACK(0x0000ffff, 16) /* escape */
+ }}},
+ { /* HUFF_ICC_TAB_2D[1][] */
+ {/* HUFF_ICC_TAB_2D[1][0] */
+ {
+ /* LAV1_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000006, 3)},
+ {HUFF_PACK(0x00000007, 3), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000037e, 10), HUFF_PACK(0x00000dfe, 12)},
+ {HUFF_PACK(0x0000000f, 4), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x000001ba, 9), HUFF_PACK(0x000001bb, 9)},
+ {HUFF_PACK(0x000000de, 8), HUFF_PACK(0x000000dc, 8),
+ HUFF_PACK(0x000001be, 9), HUFF_PACK(0x0000001a, 5)},
+ {HUFF_PACK(0x000006fe, 11), HUFF_PACK(0x00000dff, 12),
+ HUFF_PACK(0x00000036, 6), HUFF_PACK(0x00000000, 1)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x000001b6, 9), HUFF_PACK(0x00001b7c, 13),
+ HUFF_PACK(0x0000dbfe, 16), HUFF_PACK(0x00036fff, 18)},
+ {HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x0000001e, 5),
+ HUFF_PACK(0x000001be, 9), HUFF_PACK(0x00000dfe, 12),
+ HUFF_PACK(0x00036ffe, 18), HUFF_PACK(0x0000036e, 10)},
+ {HUFF_PACK(0x0000006e, 7), HUFF_PACK(0x000000fe, 8),
+ HUFF_PACK(0x000000d8, 8), HUFF_PACK(0x000036fe, 14),
+ HUFF_PACK(0x000006de, 11), HUFF_PACK(0x000000de, 8)},
+ {HUFF_PACK(0x000001fa, 9), HUFF_PACK(0x000000da, 8),
+ HUFF_PACK(0x00000dff, 12), HUFF_PACK(0x00001b7e, 13),
+ HUFF_PACK(0x000000d9, 8), HUFF_PACK(0x000000ff, 8)},
+ {HUFF_PACK(0x000003f6, 10), HUFF_PACK(0x000006fe, 11),
+ HUFF_PACK(0x00006dfe, 15), HUFF_PACK(0x0000037e, 10),
+ HUFF_PACK(0x000000fc, 8), HUFF_PACK(0x0000001a, 5)},
+ {HUFF_PACK(0x000007ee, 11), HUFF_PACK(0x0001b7fe, 17),
+ HUFF_PACK(0x00001b7d, 13), HUFF_PACK(0x000007ef, 11),
+ HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00036fff, 18) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x0000000c, 4),
+ HUFF_PACK(0x000007ee, 11), HUFF_PACK(0x00001e7e, 13),
+ HUFF_PACK(0x00003cfe, 14), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x000079ff, 15)},
+ {HUFF_PACK(0x0000000e, 4), HUFF_PACK(0x0000001a, 5),
+ HUFF_PACK(0x000001e6, 9), HUFF_PACK(0x00001fbe, 13),
+ HUFF_PACK(0x000079fe, 15), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x000006fc, 11)},
+ {HUFF_PACK(0x0000006c, 7), HUFF_PACK(0x000000f6, 8),
+ HUFF_PACK(0x000001ba, 9), HUFF_PACK(0x00000dfc, 12),
+ HUFF_PACK(0x00000dfd, 12), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x00000f3e, 12), HUFF_PACK(0x000001bb, 9)},
+ {HUFF_PACK(0x000000dc, 8), HUFF_PACK(0x000001fe, 9),
+ HUFF_PACK(0x0000036e, 10), HUFF_PACK(0x000003fe, 10),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x00000fde, 12),
+ HUFF_PACK(0x000001ee, 9), HUFF_PACK(0x000000f2, 8)},
+ {HUFF_PACK(0x000001fa, 9), HUFF_PACK(0x000003f6, 10),
+ HUFF_PACK(0x000001be, 9), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x00001fbf, 13), HUFF_PACK(0x000003ce, 10),
+ HUFF_PACK(0x000003ff, 10), HUFF_PACK(0x000000de, 8)},
+ {HUFF_PACK(0x00000078, 7), HUFF_PACK(0x000000da, 8),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000006fd, 11), HUFF_PACK(0x0000036c, 10),
+ HUFF_PACK(0x000001ef, 9), HUFF_PACK(0x000000fe, 8)},
+ {HUFF_PACK(0x0000036f, 10), HUFF_PACK(0x00000dfe, 12),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x0000036d, 10),
+ HUFF_PACK(0x000000fc, 8), HUFF_PACK(0x0000003e, 6)},
+ {HUFF_PACK(0x00000dff, 12), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x000079ff, 15),
+ HUFF_PACK(0x000079ff, 15), HUFF_PACK(0x0000079e, 11),
+ HUFF_PACK(0x0000007a, 7), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x000079ff, 15) /* escape */
+ }},
+ {/* HUFF_ICC_TAB_2D[1][1] */
+ {
+ /* LAV1_2D */
+ {{HUFF_PACK(0x00000000, 1), HUFF_PACK(0x00000006, 3)},
+ {HUFF_PACK(0x00000007, 3), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV3_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x000000fc, 8), HUFF_PACK(0x00000fde, 12)},
+ {HUFF_PACK(0x0000000c, 4), HUFF_PACK(0x0000000d, 4),
+ HUFF_PACK(0x000001fe, 9), HUFF_PACK(0x000007ee, 11)},
+ {HUFF_PACK(0x000001fa, 9), HUFF_PACK(0x000001ff, 9),
+ HUFF_PACK(0x000000fe, 8), HUFF_PACK(0x0000003e, 6)},
+ {HUFF_PACK(0x00000fdf, 12), HUFF_PACK(0x000003f6, 10),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x00000000, 1)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV5_2D */
+ {{HUFF_PACK(0x00000000, 2), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000003a, 7), HUFF_PACK(0x00000676, 11),
+ HUFF_PACK(0x000019fe, 13), HUFF_PACK(0x0000cebe, 16)},
+ {HUFF_PACK(0x0000000f, 4), HUFF_PACK(0x00000002, 3),
+ HUFF_PACK(0x0000001e, 6), HUFF_PACK(0x000000fe, 9),
+ HUFF_PACK(0x000019d6, 13), HUFF_PACK(0x0000675e, 15)},
+ {HUFF_PACK(0x0000003e, 7), HUFF_PACK(0x00000032, 6),
+ HUFF_PACK(0x00000018, 5), HUFF_PACK(0x0000033e, 10),
+ HUFF_PACK(0x00000cfe, 12), HUFF_PACK(0x00000677, 11)},
+ {HUFF_PACK(0x00000674, 11), HUFF_PACK(0x0000019c, 9),
+ HUFF_PACK(0x000000ff, 9), HUFF_PACK(0x0000003b, 7),
+ HUFF_PACK(0x0000001c, 6), HUFF_PACK(0x0000007e, 8)},
+ {HUFF_PACK(0x000033fe, 14), HUFF_PACK(0x000033ff, 14),
+ HUFF_PACK(0x00000cea, 12), HUFF_PACK(0x00000066, 7),
+ HUFF_PACK(0x0000001a, 5), HUFF_PACK(0x00000006, 4)},
+ {HUFF_PACK(0x0000cebf, 16), HUFF_PACK(0x000033ae, 14),
+ HUFF_PACK(0x0000067e, 11), HUFF_PACK(0x0000019e, 9),
+ HUFF_PACK(0x0000001b, 5), HUFF_PACK(0x00000002, 2)}},
+ HUFF_PACK(0x00000000, 0) /* escape */
+ },
+ {
+ /* LAV7_2D */
+ {{HUFF_PACK(0x00000002, 2), HUFF_PACK(0x00000002, 4),
+ HUFF_PACK(0x000000fe, 9), HUFF_PACK(0x000007be, 12),
+ HUFF_PACK(0x00000ffc, 13), HUFF_PACK(0x00000ffd, 13),
+ HUFF_PACK(0x00001efe, 15), HUFF_PACK(0x00003dfe, 16)},
+ {HUFF_PACK(0x00000004, 4), HUFF_PACK(0x00000000, 3),
+ HUFF_PACK(0x0000003c, 7), HUFF_PACK(0x000000f6, 10),
+ HUFF_PACK(0x000001da, 11), HUFF_PACK(0x000003fe, 12),
+ HUFF_PACK(0x00003dfe, 15), HUFF_PACK(0x00003dff, 16)},
+ {HUFF_PACK(0x0000003c, 8), HUFF_PACK(0x0000003e, 7),
+ HUFF_PACK(0x0000000a, 5), HUFF_PACK(0x0000003a, 8),
+ HUFF_PACK(0x000003de, 11), HUFF_PACK(0x000007be, 13),
+ HUFF_PACK(0x00000f7e, 14), HUFF_PACK(0x00001efe, 14)},
+ {HUFF_PACK(0x000001de, 11), HUFF_PACK(0x000000ec, 10),
+ HUFF_PACK(0x0000007e, 9), HUFF_PACK(0x0000000c, 5),
+ HUFF_PACK(0x000001ee, 10), HUFF_PACK(0x00000f7e, 13),
+ HUFF_PACK(0x000007fc, 12), HUFF_PACK(0x00003dff, 15)},
+ {HUFF_PACK(0x00007ffe, 16), HUFF_PACK(0x000003be, 12),
+ HUFF_PACK(0x000000fe, 10), HUFF_PACK(0x000001fe, 10),
+ HUFF_PACK(0x0000001a, 6), HUFF_PACK(0x0000001c, 7),
+ HUFF_PACK(0x000007fd, 12), HUFF_PACK(0x00000ffe, 13)},
+ {HUFF_PACK(0x00003dff, 16), HUFF_PACK(0x000003bf, 12),
+ HUFF_PACK(0x00001ffe, 14), HUFF_PACK(0x000003ff, 12),
+ HUFF_PACK(0x0000003e, 8), HUFF_PACK(0x0000001b, 6),
+ HUFF_PACK(0x0000007e, 8), HUFF_PACK(0x000000f6, 9)},
+ {HUFF_PACK(0x00007fff, 16), HUFF_PACK(0x00003dff, 16),
+ HUFF_PACK(0x00003ffe, 15), HUFF_PACK(0x000001db, 11),
+ HUFF_PACK(0x000000ee, 10), HUFF_PACK(0x0000007a, 8),
+ HUFF_PACK(0x0000000e, 5), HUFF_PACK(0x0000000b, 5)},
+ {HUFF_PACK(0x00003dff, 16), HUFF_PACK(0x00003dff, 16),
+ HUFF_PACK(0x000003de, 12), HUFF_PACK(0x000001fe, 11),
+ HUFF_PACK(0x000001ee, 11), HUFF_PACK(0x0000007a, 9),
+ HUFF_PACK(0x00000006, 5), HUFF_PACK(0x00000003, 2)}},
+ HUFF_PACK(0x00003dff, 16) /* escape */
+ }}}}};
+
+const HUFF_PT0_TABLE fdk_sacenc_huffPart0Tab = {
+ {/* CLD */
+ HUFF_PACK(0x00000052, 8), HUFF_PACK(0x000000ae, 9),
+ HUFF_PACK(0x000000af, 9), HUFF_PACK(0x00000028, 7),
+ HUFF_PACK(0x0000006e, 7), HUFF_PACK(0x00000036, 6),
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x0000000c, 4), HUFF_PACK(0x0000000a, 4),
+ HUFF_PACK(0x00000002, 4), HUFF_PACK(0x00000016, 5),
+ HUFF_PACK(0x00000012, 5), HUFF_PACK(0x00000017, 5),
+ HUFF_PACK(0x00000000, 4), HUFF_PACK(0x00000004, 4),
+ HUFF_PACK(0x00000006, 4), HUFF_PACK(0x00000008, 4),
+ HUFF_PACK(0x00000007, 4), HUFF_PACK(0x00000003, 4),
+ HUFF_PACK(0x00000001, 4), HUFF_PACK(0x0000001a, 5),
+ HUFF_PACK(0x00000013, 5), HUFF_PACK(0x0000003e, 6),
+ HUFF_PACK(0x00000016, 6), HUFF_PACK(0x00000017, 6),
+ HUFF_PACK(0x0000006f, 7), HUFF_PACK(0x0000002a, 7),
+ HUFF_PACK(0x00000056, 8), HUFF_PACK(0x00000053, 8),
+ HUFF_PACK(0x0000003f, 6)},
+ {/* ICC */
+ HUFF_PACK(0x0000001e, 5), HUFF_PACK(0x0000000e, 4),
+ HUFF_PACK(0x00000006, 3), HUFF_PACK(0x00000000, 2),
+ HUFF_PACK(0x00000002, 2), HUFF_PACK(0x00000001, 2),
+ HUFF_PACK(0x0000003e, 6), HUFF_PACK(0x0000003f, 6)}};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
diff --git a/fdk-aac/libSACenc/src/sacenc_huff_tab.h b/fdk-aac/libSACenc/src/sacenc_huff_tab.h
new file mode 100644
index 0000000..7d6c331
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_huff_tab.h
@@ -0,0 +1,222 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Markus Lohwasser
+
+ Description: SAC-Encoder constant huffman tables
+
+*******************************************************************************/
+
+#ifndef SACENC_HUFF_TAB_H
+#define SACENC_HUFF_TAB_H
+
+/* Includes ******************************************************************/
+#include "machine_type.h"
+
+/* Defines *******************************************************************/
+#define HUFF_PACK(a, b) \
+ { \
+ ((((ULONG)a) & 0x00FFFFFF) << 8) | (((ULONG)b) & 0xFF) \
+ } /*!< Pack huffman value and length information. */
+#define HUFF_VALUE(a) \
+ (((a.packed >> 8) & 0x00FFFFFF)) /*!< Return value from packed table entry. \
+ */
+#define HUFF_LENGTH(a) \
+ ((a.packed & 0xFF)) /*!< Return length from packed table entry. */
+
+/* Data Types ****************************************************************/
+/**
+ * \brief This struct contains packed huffman entries.
+ *
+ * The packed entry consist of hffman value and length information.
+ *
+ * |---------------------------------|
+ * | value | length |
+ * |---------------------------------|
+ * |<------- 31...8 ------->|< 7..0 >|
+ */
+typedef struct {
+ ULONG packed; /*! Packed huffman entry:
+ - lower 8 bit are reservoed for length information
+ - upper 24 bit contains huffman value */
+} HUFF_ENTRY;
+
+typedef struct {
+ HUFF_ENTRY entry[2][2];
+ HUFF_ENTRY escape;
+
+} LAV1_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[4][4];
+ HUFF_ENTRY escape;
+
+} LAV3_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[6][6];
+ HUFF_ENTRY escape;
+
+} LAV5_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[7][7];
+ HUFF_ENTRY escape;
+
+} LAV6_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[8][8];
+ HUFF_ENTRY escape;
+
+} LAV7_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[10][10];
+ HUFF_ENTRY escape;
+
+} LAV9_2D;
+
+typedef struct {
+ HUFF_ENTRY entry[13][13];
+ HUFF_ENTRY escape;
+
+} LAV12_2D;
+
+typedef struct {
+ LAV3_2D lav3;
+ LAV5_2D lav5;
+ LAV7_2D lav7;
+ LAV9_2D lav9;
+
+} HUFF_CLD_TAB_2D;
+
+typedef struct {
+ LAV1_2D lav1;
+ LAV3_2D lav3;
+ LAV5_2D lav5;
+ LAV7_2D lav7;
+
+} HUFF_ICC_TAB_2D;
+
+typedef struct {
+ HUFF_ENTRY h1D[2][31];
+ HUFF_CLD_TAB_2D h2D[2][2];
+
+} HUFF_CLD_TABLE;
+
+typedef struct {
+ HUFF_ENTRY h1D[2][8];
+ HUFF_ICC_TAB_2D h2D[2][2];
+
+} HUFF_ICC_TABLE;
+
+typedef struct {
+ HUFF_ENTRY cld[31];
+ HUFF_ENTRY icc[8];
+
+} HUFF_PT0_TABLE;
+
+typedef HUFF_ENTRY HUFF_RES_TABLE[5][8];
+
+/* Constants *****************************************************************/
+extern const HUFF_CLD_TABLE fdk_sacenc_huffCLDTab;
+extern const HUFF_ICC_TABLE fdk_sacenc_huffICCTab;
+extern const HUFF_PT0_TABLE fdk_sacenc_huffPart0Tab;
+
+/* Function / Class Declarations *********************************************/
+
+#endif /* SACENC_HUFF_TAB_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_lib.cpp b/fdk-aac/libSACenc/src/sacenc_lib.cpp
new file mode 100644
index 0000000..d6a1658
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_lib.cpp
@@ -0,0 +1,2042 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Interface to Spacial Audio Coding Encoder lib
+
+*******************************************************************************/
+
+/****************************************************************************
+\file
+Description of file contents
+******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_lib.h"
+#include "sacenc_const.h"
+#include "genericStds.h"
+#include "FDK_core.h"
+#include "sacenc_tree.h"
+#include "sacenc_bitstream.h"
+#include "sacenc_onsetdetect.h"
+#include "sacenc_framewindowing.h"
+#include "sacenc_filter.h"
+#include "sacenc_paramextract.h"
+#include "sacenc_staticgain.h"
+#include "sacenc_delay.h"
+#include "sacenc_dmx_tdom_enh.h"
+#include "sacenc_vectorfunctions.h"
+#include "qmf.h"
+
+/* Defines *******************************************************************/
+
+/* Encoder library info */
+#define SACENC_LIB_VL0 2
+#define SACENC_LIB_VL1 0
+#define SACENC_LIB_VL2 0
+#define SACENC_LIB_TITLE "MPEG Surround Encoder"
+#ifdef __ANDROID__
+#define SACENC_LIB_BUILD_DATE ""
+#define SACENC_LIB_BUILD_TIME ""
+#else
+#define SACENC_LIB_BUILD_DATE __DATE__
+#define SACENC_LIB_BUILD_TIME __TIME__
+#endif
+
+#define MAX_MPEGS_BYTES (1 << 14)
+#define MAX_SSC_BYTES (1 << 6)
+
+#define MAX_SPACE_TREE_CHANNELS 2
+#define NUM_KEEP_WINDOWS 3
+
+/* Data Types ****************************************************************/
+typedef struct {
+ MP4SPACEENC_MODE encMode;
+ MP4SPACEENC_BANDS_CONFIG nParamBands;
+ MP4SPACEENC_QUANTMODE quantMode;
+ UCHAR bUseCoarseQuant;
+ UCHAR bLdMode;
+ UCHAR bTimeDomainDmx;
+ UINT sampleRate;
+ UINT frameTimeSlots; /* e.g. 32 when used with HE-AAC */
+ UINT independencyFactor; /* how often should we set the independency flag */
+ INT timeAlignment; /* additional delay for downmix */
+
+} MP4SPACEENC_SETUP, *HANDLE_MP4SPACEENC_SETUP;
+
+struct ENC_CONFIG_SETUP {
+ UCHAR bEncMode_212;
+ UCHAR maxHybridInStaticSlots;
+ LONG maxSamplingrate;
+ INT maxAnalysisLengthTimeSlots;
+ INT maxHybridBands;
+ INT maxQmfBands;
+ INT maxChIn;
+ INT maxFrameTimeSlots;
+ INT maxFrameLength;
+ INT maxChOut;
+ INT maxChTotOut;
+};
+
+struct MP4SPACE_ENCODER {
+ MP4SPACEENC_SETUP user;
+
+ ENC_CONFIG_SETUP setup; /* describe allocated instance */
+
+ HANDLE_FRAMEWINDOW
+ hFrameWindow; /* Windowing, only created+updated, but not used */
+ INT nSamplesValid; /* Input Buffer Handling */
+
+ /* Routing Sensible Switches/Variables */
+ MP4SPACEENC_BANDS_CONFIG nParamBands;
+ UCHAR useTimeDomDownmix;
+
+ /* not Routing Sensible Switches/Varibles - must be contained in Check */
+ MP4SPACEENC_MODE encMode;
+ UCHAR bEncMode_212_only;
+
+ /* not Routing Sensible Switches/Varibles + lower Classes */
+ UCHAR useFrameKeep;
+ UINT independencyFactor;
+ UINT nSampleRate;
+ UCHAR nInputChannels;
+ UCHAR nOutputChannels;
+ UCHAR nFrameTimeSlots; /* e.g. 32 when used with HE-AAC */
+ UCHAR nQmfBands;
+ UCHAR nHybridBands;
+ UINT nFrameLength; /* number of output waveform samples/channel/frame */
+
+ /* not Routing Sensible Switches/Varibles + lower Classes, secondary computed
+ */
+ INT nSamplesNext;
+ INT nAnalysisLengthTimeSlots;
+ INT nAnalysisLookaheadTimeSlots;
+ INT nUpdateHybridPositionTimeSlots;
+ INT *pnOutputBits;
+ INT nInputDelay;
+ INT nOutputBufferDelay;
+ INT nSurroundAnalysisBufferDelay;
+ INT nBitstreamDelayBuffer;
+ INT nBitstreamBufferRead;
+ INT nBitstreamBufferWrite;
+ INT nDiscardOutFrames;
+ INT avoid_keep;
+
+ /* not Routing Sensible Switches/Varibles -> moved to lower Classes */
+ UCHAR useCoarseQuantCld; /* Only Used in SpaceTreeSetup */
+ UCHAR useCoarseQuantIcc; /* Only Used in SpaceTreeSetup */
+ UCHAR useCoarseQuantCpc; /* Only Used in SpaceTreeSetup */
+ UCHAR useCoarseQuantArbDmx; /* ArbitraryDmx,... not available yet */
+ MP4SPACEENC_QUANTMODE
+ quantMode; /* Used for quanitzation and in bitstream writer */
+ INT coreCoderDelay; /* Used in delay compensation */
+ INT timeAlignment; /* Used in delay compensation */
+
+ /* Local Processing Variables */
+ INT independencyCount;
+ INT independencyFlag;
+ INT **ppTrCurrPos; /* belongs somehow to Onset Detection */
+ INT trPrevPos[2 * MAX_NUM_TRANS]; /* belongs somehow to Onset Detection */
+
+ FRAMEWIN_LIST frameWinList;
+ SPATIALFRAME saveFrame;
+
+ /* Module-Handles */
+ SPACE_TREE_SETUP spaceTreeSetup;
+ MPEG4SPACEENC_SSCBUF sscBuf;
+ FIXP_WIN *pFrameWindowAna__FDK[MAX_NUM_PARAMS];
+ HANDLE_QMF_FILTER_BANK *phQmfFiltIn__FDK;
+ HANDLE_DC_FILTER phDCFilterSigIn[SACENC_MAX_INPUT_CHANNELS];
+ HANDLE_ONSET_DETECT phOnset[SACENC_MAX_INPUT_CHANNELS];
+ HANDLE_SPACE_TREE hSpaceTree;
+ HANDLE_BSF_INSTANCE hBitstreamFormatter;
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainConfig;
+ HANDLE_STATIC_GAIN hStaticGain;
+ HANDLE_DELAY hDelay;
+
+ /* enhanced time domain downmix (for stereo input) */
+ HANDLE_ENHANCED_TIME_DOMAIN_DMX hEnhancedTimeDmx;
+
+ /* Data Buffers */
+ INT_PCM **ppTimeSigIn__FDK;
+ INT_PCM **ppTimeSigDelayIn__FDK;
+ INT_PCM **ppTimeSigOut__FDK;
+ FIXP_DPK ***pppHybridIn__FDK;
+ FIXP_DPK ***pppHybridInStatic__FDK;
+ FIXP_DPK ***pppProcDataIn__FDK;
+ INT_PCM *pOutputDelayBuffer__FDK;
+
+ UCHAR **ppBitstreamDelayBuffer;
+
+ UCHAR *pParameterBand2HybridBandOffset;
+ INT staticGainScale;
+
+ INT *pEncoderInputChScale;
+ INT *staticTimeDomainDmxInScale;
+};
+
+/* Constants *****************************************************************/
+static const UCHAR pValidBands_Ld[8] = {4, 5, 7, 9, 12, 15, 23, 40};
+
+static const UCHAR qmf2qmf[] = /* Bypass the HybridAnylyis/Synthesis*/
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127};
+
+/* Function / Class Declarations *********************************************/
+static FDK_SACENC_ERROR mp4SpaceEnc_create(
+ HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc);
+
+static FDK_SACENC_ERROR FillSpatialSpecificConfig(
+ const HANDLE_MP4SPACE_ENCODER hEnc, SPATIALSPECIFICCONFIG *const hSsc);
+
+static FDK_SACENC_ERROR mp4SpaceEnc_FillSpaceTreeSetup(
+ const HANDLE_MP4SPACE_ENCODER hEnc,
+ SPACE_TREE_SETUP *const hSpaceTreeSetup);
+
+static FDK_SACENC_ERROR mp4SpaceEnc_InitDelayCompensation(
+ HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc, const INT coreCoderDelay);
+
+static FDK_SACENC_ERROR mp4SpaceEnc_InitDefault(
+ HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc);
+
+static DECORRCONFIG mp4SpaceEnc_GetDecorrConfig(const MP4SPACEENC_MODE encMode);
+
+static FDK_SACENC_ERROR mp4SpaceEnc_InitNumParamBands(
+ HANDLE_MP4SPACE_ENCODER hEnc, const MP4SPACEENC_BANDS_CONFIG nParamBands);
+
+/* Function / Class Definition ***********************************************/
+static UINT mp4SpaceEnc_GetNumQmfBands(const UINT nSampleRate) {
+ UINT nQmfBands = 0;
+
+ if (nSampleRate < 27713)
+ nQmfBands = 32;
+ else if (nSampleRate < 55426)
+ nQmfBands = 64;
+
+ return nQmfBands;
+}
+
+static UINT updateQmfFlags(const UINT flags, const INT keepStates) {
+ UINT qmfFlags = flags;
+
+ qmfFlags = (qmfFlags & (~(UINT)QMF_FLAG_LP));
+ qmfFlags = (qmfFlags | QMF_FLAG_MPSLDFB);
+ qmfFlags = (keepStates) ? (qmfFlags | QMF_FLAG_KEEP_STATES)
+ : (qmfFlags & (~(UINT)QMF_FLAG_KEEP_STATES));
+
+ return qmfFlags;
+}
+
+static INT freq2HybridBand(const UINT nFrequency, const UINT nSampleRate,
+ const UINT nQmfBands) {
+ /*
+ nQmfSlotWidth = (nSampleRate/2) / nQmfBands;
+ nQmfBand = nFrequency / nQmfSlotWidth;
+ */
+ int nHybridBand = -1;
+ int scale = 0;
+ const FIXP_DBL temp = fDivNorm((FIXP_DBL)(2 * nFrequency * nQmfBands),
+ (FIXP_DBL)nSampleRate, &scale);
+ const int nQmfBand = scaleValue(temp, scale - (DFRACT_BITS - 1));
+
+ if ((nQmfBand > -1) && (nQmfBand < (int)nQmfBands)) {
+ nHybridBand = qmf2qmf[nQmfBand];
+ }
+
+ return nHybridBand;
+}
+
+/*
+ * Examine buffer descriptor regarding choosen type.
+ *
+ * \param pBufDesc Pointer to buffer descriptor
+ * \param type Buffer type to look for.
+
+ * \return - Buffer descriptor index.
+ * -1, if there is no entry available.
+ */
+static INT getBufDescIdx(const FDK_bufDescr *pBufDesc, const UINT type) {
+ INT i, idx = -1;
+
+ for (i = 0; i < (int)pBufDesc->numBufs; i++) {
+ if (pBufDesc->pBufType[i] == type) {
+ idx = i;
+ break;
+ }
+ }
+ return idx;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_open(HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc) {
+ return mp4SpaceEnc_create(phMp4SpaceEnc);
+}
+
+static FDK_SACENC_ERROR mp4SpaceEnc_create(
+ HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+ HANDLE_MP4SPACE_ENCODER hEnc = NULL;
+ ENC_CONFIG_SETUP setup;
+
+ if (NULL == phMp4SpaceEnc) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i, ch;
+ FDKmemclear(&setup, sizeof(ENC_CONFIG_SETUP));
+
+ /* Allocate Encoder Instance */
+ FDK_ALLOCATE_MEMORY_1D(hEnc, 1, struct MP4SPACE_ENCODER);
+
+ /* Clear everything, also pointers. */
+ if (NULL != hEnc) {
+ FDKmemclear(hEnc, sizeof(struct MP4SPACE_ENCODER));
+ }
+
+ setup.maxSamplingrate = 48000;
+ setup.maxFrameTimeSlots = 16;
+
+ setup.maxAnalysisLengthTimeSlots = 3 * setup.maxFrameTimeSlots;
+ setup.maxQmfBands = mp4SpaceEnc_GetNumQmfBands(setup.maxSamplingrate);
+ ;
+ setup.maxHybridBands = setup.maxQmfBands;
+ setup.maxFrameLength = setup.maxQmfBands * setup.maxFrameTimeSlots;
+
+ setup.maxChIn = 2;
+ setup.maxChOut = 1;
+ setup.maxChTotOut = setup.maxChOut;
+ setup.bEncMode_212 = 1;
+ setup.maxHybridInStaticSlots = 24;
+
+ /* Open Static Gain*/
+ if (SACENC_OK !=
+ (error = fdk_sacenc_staticGain_OpenConfig(&hEnc->hStaticGainConfig))) {
+ goto bail;
+ }
+
+ /* enhanced time domain downmix (for stereo input) */
+ if (SACENC_OK != (error = fdk_sacenc_open_enhancedTimeDomainDmx(
+ &hEnc->hEnhancedTimeDmx, setup.maxFrameLength))) {
+ goto bail;
+ }
+
+ FDK_ALLOCATE_MEMORY_1D(hEnc->pParameterBand2HybridBandOffset,
+ MAX_NUM_PARAM_BANDS, UCHAR);
+
+ /* Create Space Tree first, to get number of in-/output channels */
+ if (SACENC_OK != (error = fdk_sacenc_spaceTree_Open(&hEnc->hSpaceTree))) {
+ goto bail;
+ }
+
+ FDK_ALLOCATE_MEMORY_1D(hEnc->pEncoderInputChScale, setup.maxChIn, INT);
+ FDK_ALLOCATE_MEMORY_1D(hEnc->staticTimeDomainDmxInScale, setup.maxChIn,
+ INT);
+
+ FDK_ALLOCATE_MEMORY_1D(hEnc->phQmfFiltIn__FDK, setup.maxChIn,
+ HANDLE_QMF_FILTER_BANK);
+
+ /* Allocate Analysis Filterbank Structs */
+ for (ch = 0; ch < setup.maxChIn; ch++) {
+ FDK_ALLOCATE_MEMORY_1D_INT(hEnc->phQmfFiltIn__FDK[ch], 1,
+ struct QMF_FILTER_BANK, SECT_DATA_L2)
+ FDK_ALLOCATE_MEMORY_1D_INT(hEnc->phQmfFiltIn__FDK[ch]->FilterStates,
+ 2 * 5 * setup.maxQmfBands, FIXP_QAS,
+ SECT_DATA_L2)
+ }
+
+ /* Allocate Synthesis Filterbank Structs for arbitrary downmix */
+
+ /* Allocate DC Filter Struct for normal signal input */
+ for (ch = 0; ch < setup.maxChIn; ch++) {
+ if (SACENC_OK !=
+ (error = fdk_sacenc_createDCFilter(&hEnc->phDCFilterSigIn[ch]))) {
+ goto bail;
+ }
+ }
+
+ /* Open Onset Detection */
+ for (ch = 0; ch < setup.maxChIn; ch++) {
+ if (SACENC_OK != (error = fdk_sacenc_onsetDetect_Open(
+ &hEnc->phOnset[ch], setup.maxFrameTimeSlots))) {
+ goto bail;
+ }
+ }
+
+ FDK_ALLOCATE_MEMORY_2D(hEnc->ppTrCurrPos, setup.maxChIn, MAX_NUM_TRANS,
+ INT);
+
+ /* Create Windowing */
+ if (SACENC_OK !=
+ (error = fdk_sacenc_frameWindow_Create(&hEnc->hFrameWindow))) {
+ goto bail;
+ }
+
+ /* Open static gain */
+ if (SACENC_OK != (error = fdk_sacenc_staticGain_Open(&hEnc->hStaticGain))) {
+ goto bail;
+ }
+
+ /* create bitstream encoder */
+ if (SACENC_OK != (error = fdk_sacenc_createSpatialBitstreamEncoder(
+ &hEnc->hBitstreamFormatter))) {
+ goto bail;
+ }
+
+ FDK_ALLOCATE_MEMORY_1D(hEnc->sscBuf.pSsc, MAX_SSC_BYTES, UCHAR);
+
+ {
+ FDK_ALLOCATE_MEMORY_2D(hEnc->ppTimeSigIn__FDK, setup.maxChIn,
+ setup.maxFrameLength + MAX_DELAY_SURROUND_ANALYSIS,
+ INT_PCM);
+ }
+ FDK_ALLOCATE_MEMORY_2D(hEnc->ppTimeSigDelayIn__FDK, setup.maxChIn,
+ MAX_DELAY_SURROUND_ANALYSIS, INT_PCM);
+
+ /* Create new buffers for several signals (including arbitrary downmix) */
+ if (setup.bEncMode_212 == 0) {
+ /* pOutputDelayBuffer__FDK buffer is not needed for SACENC_212 mode */
+ FDK_ALLOCATE_MEMORY_1D(
+ hEnc->pOutputDelayBuffer__FDK,
+ (setup.maxFrameLength + MAX_DELAY_OUTPUT) * setup.maxChOut, INT_PCM);
+ }
+
+ /* allocate buffers */
+ if (setup.bEncMode_212 == 0) {
+ /* ppTimeSigOut__FDK buffer is not needed for SACENC_212 mode */
+ FDK_ALLOCATE_MEMORY_2D(hEnc->ppTimeSigOut__FDK, setup.maxChTotOut,
+ setup.maxFrameLength, INT_PCM);
+ }
+
+ if (setup.bEncMode_212 == 1) {
+ /* pppHybridIn__FDK buffer can be reduced by maxFrameTimeSlots/2 slots for
+ * SACENC_212 mode */
+ FDK_ALLOCATE_MEMORY_3D(
+ hEnc->pppHybridIn__FDK, setup.maxChIn,
+ setup.maxAnalysisLengthTimeSlots - (setup.maxFrameTimeSlots >> 1),
+ setup.maxHybridBands, FIXP_DPK);
+ FDK_ALLOCATE_MEMORY_3D(hEnc->pppHybridInStatic__FDK, setup.maxChIn,
+ setup.maxHybridInStaticSlots, setup.maxHybridBands,
+ FIXP_DPK);
+ } else {
+ FDK_ALLOCATE_MEMORY_3D(hEnc->pppHybridIn__FDK, setup.maxChIn,
+ setup.maxAnalysisLengthTimeSlots,
+ setup.maxHybridBands, FIXP_DPK);
+ }
+
+ if (setup.bEncMode_212 == 0) {
+ /* pppProcDataIn__FDK buffer is not needed for SACENC_212 mode */
+ FDK_ALLOCATE_MEMORY_3D(hEnc->pppProcDataIn__FDK, MAX_SPACE_TREE_CHANNELS,
+ setup.maxAnalysisLengthTimeSlots,
+ setup.maxHybridBands, FIXP_DPK);
+ }
+ for (i = 0; i < MAX_NUM_PARAMS; i++) {
+ FDK_ALLOCATE_MEMORY_1D(hEnc->pFrameWindowAna__FDK[i],
+ setup.maxAnalysisLengthTimeSlots, FIXP_WIN);
+ } /* for i */
+
+ if (SACENC_OK != (error = fdk_sacenc_delay_Open(&hEnc->hDelay))) {
+ goto bail;
+ }
+
+ if (setup.bEncMode_212 == 0) {
+ /* ppBitstreamDelayBuffer buffer is not needed for SACENC_212 mode */
+ FDK_ALLOCATE_MEMORY_2D(hEnc->ppBitstreamDelayBuffer, MAX_BITSTREAM_DELAY,
+ MAX_MPEGS_BYTES, UCHAR);
+ }
+ FDK_ALLOCATE_MEMORY_1D(hEnc->pnOutputBits, MAX_BITSTREAM_DELAY, INT);
+
+ hEnc->setup = setup; /* save configuration used while encoder allocation. */
+ mp4SpaceEnc_InitDefault(hEnc);
+
+ if (NULL != phMp4SpaceEnc) {
+ *phMp4SpaceEnc = hEnc; /* return encoder handle */
+ }
+
+ } /* valid handle */
+
+ return error;
+
+bail:
+ if (NULL != hEnc) {
+ hEnc->setup = setup;
+ FDK_sacenc_close(&hEnc);
+ }
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+static FDK_SACENC_ERROR mp4SpaceEnc_InitDefault(HANDLE_MP4SPACE_ENCODER hEnc) {
+ FDK_SACENC_ERROR err = SACENC_OK;
+
+ /* Get default static gain configuration. */
+ if (SACENC_OK != (err = fdk_sacenc_staticGain_InitDefaultConfig(
+ hEnc->hStaticGainConfig))) {
+ goto bail;
+ }
+
+bail:
+ return err;
+}
+
+static FDK_SACENC_ERROR FDK_sacenc_configure(
+ HANDLE_MP4SPACE_ENCODER hEnc, const HANDLE_MP4SPACEENC_SETUP hSetup) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ hEnc->nSampleRate = hSetup->sampleRate;
+ hEnc->encMode = hSetup->encMode;
+ hEnc->nQmfBands = mp4SpaceEnc_GetNumQmfBands(hEnc->nSampleRate);
+
+ /* Make sure that we have set time domain downmix for 212 */
+ if (hSetup->encMode == SACENC_212 && hSetup->bTimeDomainDmx == 0) {
+ error = SACENC_INVALID_CONFIG;
+ } else {
+ hEnc->useTimeDomDownmix = hSetup->bTimeDomainDmx;
+ }
+
+ hEnc->timeAlignment = hSetup->timeAlignment;
+ hEnc->quantMode = hSetup->quantMode;
+
+ hEnc->useCoarseQuantCld = hSetup->bUseCoarseQuant;
+ hEnc->useCoarseQuantCpc = hSetup->bUseCoarseQuant;
+ hEnc->useFrameKeep = (hSetup->bLdMode == 2);
+ hEnc->useCoarseQuantIcc = 0; /* not available */
+ hEnc->useCoarseQuantArbDmx = 0; /* not available for user right now */
+ hEnc->independencyFactor = hSetup->independencyFactor;
+ hEnc->independencyCount = 0;
+ hEnc->independencyFlag = 1;
+
+ /* set number of Hybrid bands */
+ hEnc->nHybridBands = hEnc->nQmfBands;
+ hEnc->nFrameTimeSlots = hSetup->frameTimeSlots;
+ mp4SpaceEnc_InitNumParamBands(hEnc, hSetup->nParamBands);
+
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_init(HANDLE_MP4SPACE_ENCODER hEnc,
+ const INT dmxDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ /* Sanity Checks */
+ if (NULL == hEnc) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ const int initStatesFlag = 1;
+
+ int ch; /* loop counter */
+ int nChInArbDmx;
+
+ if (SACENC_OK != (error = FDK_sacenc_configure(hEnc, &hEnc->user))) {
+ goto bail;
+ }
+
+ hEnc->bEncMode_212_only = hEnc->setup.bEncMode_212;
+
+ /* Slots per Frame and Frame Length */
+ if (hEnc->nFrameTimeSlots < 1) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ hEnc->nFrameLength = hEnc->nQmfBands * hEnc->nFrameTimeSlots;
+
+ if (hEnc->useFrameKeep == 1) {
+ hEnc->nAnalysisLengthTimeSlots = 3 * hEnc->nFrameTimeSlots;
+ hEnc->nUpdateHybridPositionTimeSlots = hEnc->nFrameTimeSlots;
+ } else {
+ hEnc->nAnalysisLengthTimeSlots = 2 * hEnc->nFrameTimeSlots;
+ hEnc->nUpdateHybridPositionTimeSlots = 0;
+ }
+
+ {
+ hEnc->nAnalysisLookaheadTimeSlots =
+ hEnc->nAnalysisLengthTimeSlots - 3 * hEnc->nFrameTimeSlots / 2;
+ }
+
+ /* init parameterBand2hybridBandOffset table */
+ fdk_sacenc_calcParameterBand2HybridBandOffset(
+ (BOX_SUBBAND_CONFIG)hEnc->nParamBands, hEnc->nHybridBands,
+ hEnc->pParameterBand2HybridBandOffset);
+
+ /* Fill Setup structure for Space Tree */
+ if (SACENC_OK !=
+ (error = mp4SpaceEnc_FillSpaceTreeSetup(hEnc, &hEnc->spaceTreeSetup))) {
+ goto bail;
+ }
+
+ /* Init space tree configuration */
+ if (SACENC_OK !=
+ (error = fdk_sacenc_spaceTree_Init(
+ hEnc->hSpaceTree, &hEnc->spaceTreeSetup,
+ hEnc->pParameterBand2HybridBandOffset, hEnc->useFrameKeep))) {
+ goto bail;
+ }
+
+ /* Get space tree description and resulting number of input/output channels
+ */
+ {
+ SPACE_TREE_DESCRIPTION spaceTreeDescription;
+
+ if (SACENC_OK != (error = fdk_sacenc_spaceTree_GetDescription(
+ hEnc->hSpaceTree, &spaceTreeDescription))) {
+ goto bail;
+ }
+
+ hEnc->nInputChannels =
+ spaceTreeDescription.nOutChannels; /* space tree description
+ describes decoder
+ configuration */
+ hEnc->nOutputChannels =
+ spaceTreeDescription.nInChannels; /* space tree description
+ describes decoder
+ configuration */
+ }
+
+ nChInArbDmx = 0;
+
+ /* INITIALIZATION */
+ for (ch = 0; ch < hEnc->nInputChannels; ch++) {
+ /* scaling in analysis qmf filterbank (7) */
+ hEnc->pEncoderInputChScale[ch] = 7;
+
+ {
+ /* additional scaling in qmf prototype filter for low delay */
+ hEnc->pEncoderInputChScale[ch] += 1;
+ }
+
+ { hEnc->pEncoderInputChScale[ch] += DC_FILTER_SF; }
+ } /* nInputChannels */
+
+ /* Init analysis filterbank */
+ for (ch = 0; ch < hEnc->nInputChannels; ch++) {
+ hEnc->phQmfFiltIn__FDK[ch]->flags =
+ updateQmfFlags(hEnc->phQmfFiltIn__FDK[ch]->flags, !initStatesFlag);
+
+ if (0 != qmfInitAnalysisFilterBank(
+ hEnc->phQmfFiltIn__FDK[ch],
+ (FIXP_QAS *)hEnc->phQmfFiltIn__FDK[ch]->FilterStates, 1,
+ hEnc->nQmfBands, hEnc->nQmfBands, hEnc->nQmfBands,
+ hEnc->phQmfFiltIn__FDK[ch]->flags)) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+ }
+
+ /* Initialize DC Filter. */
+ {
+ for (ch = 0; ch < hEnc->nInputChannels; ch++) {
+ if (SACENC_OK != (error = fdk_sacenc_initDCFilter(
+ hEnc->phDCFilterSigIn[ch], hEnc->nSampleRate))) {
+ goto bail;
+ }
+ }
+ }
+
+ /* Init onset detect. */
+ {
+ /* init onset detect configuration struct */
+ ONSET_DETECT_CONFIG onsetDetectConfig;
+ onsetDetectConfig.maxTimeSlots = hEnc->nFrameTimeSlots;
+ onsetDetectConfig.lowerBoundOnsetDetection =
+ freq2HybridBand(1725, hEnc->nSampleRate, hEnc->nQmfBands);
+ onsetDetectConfig.upperBoundOnsetDetection = hEnc->nHybridBands;
+
+ for (ch = 0; ch < hEnc->nInputChannels; ch++) {
+ if (SACENC_OK != (error = fdk_sacenc_onsetDetect_Init(
+ hEnc->phOnset[ch], &onsetDetectConfig, 1))) {
+ goto bail;
+ }
+ }
+ }
+
+ {
+ /* init windowing */
+ FRAMEWINDOW_CONFIG framewindowConfig;
+ framewindowConfig.nTimeSlotsMax = hEnc->nFrameTimeSlots;
+ framewindowConfig.bFrameKeep = hEnc->useFrameKeep;
+
+ if (SACENC_OK != (error = fdk_sacenc_frameWindow_Init(
+ hEnc->hFrameWindow, &framewindowConfig))) {
+ goto bail;
+ }
+ }
+
+ /* Set encoder mode for static gain initialization. */
+ if (SACENC_OK != (error = fdk_sacenc_staticGain_SetEncMode(
+ hEnc->hStaticGainConfig, hEnc->encMode))) {
+ goto bail;
+ }
+
+ /* Init static gain. */
+ if (SACENC_OK != (error = fdk_sacenc_staticGain_Init(
+ hEnc->hStaticGain, hEnc->hStaticGainConfig,
+ &(hEnc->staticGainScale)))) {
+ goto bail;
+ }
+
+ for (ch = 0; ch < hEnc->nInputChannels; ch++) {
+ hEnc->pEncoderInputChScale[ch] += hEnc->staticGainScale;
+ }
+
+ /* enhanced downmix for stereo input*/
+ if (hEnc->useTimeDomDownmix != 0) {
+ if (SACENC_OK != (error = fdk_sacenc_init_enhancedTimeDomainDmx(
+ hEnc->hEnhancedTimeDmx,
+ fdk_sacenc_getPreGainPtrFDK(hEnc->hStaticGain),
+ hEnc->staticGainScale,
+ fdk_sacenc_getPostGainFDK(hEnc->hStaticGain),
+ hEnc->staticGainScale, hEnc->nFrameLength))) {
+ goto bail;
+ }
+ }
+
+ /* Create config structure for bitstream formatter including arbitrary
+ * downmix residual */
+ if (SACENC_OK != (error = fdk_sacenc_initSpatialBitstreamEncoder(
+ hEnc->hBitstreamFormatter))) {
+ goto bail;
+ }
+
+ if (SACENC_OK != (error = FillSpatialSpecificConfig(
+ hEnc, fdk_sacenc_getSpatialSpecificConfig(
+ hEnc->hBitstreamFormatter)))) {
+ goto bail;
+ }
+
+ if (SACENC_OK !=
+ (error = fdk_sacenc_writeSpatialSpecificConfig(
+ fdk_sacenc_getSpatialSpecificConfig(hEnc->hBitstreamFormatter),
+ hEnc->sscBuf.pSsc, MAX_SSC_BYTES, &hEnc->sscBuf.nSscSizeBits))) {
+ goto bail;
+ }
+
+ /* init delay compensation with dmx core coder delay; if no core coder is
+ * used, many other buffers are initialized nevertheless */
+ if (SACENC_OK !=
+ (error = mp4SpaceEnc_InitDelayCompensation(hEnc, dmxDelay))) {
+ goto bail;
+ }
+
+ /* How much input do we need? */
+ hEnc->nSamplesNext =
+ hEnc->nFrameLength * (hEnc->nInputChannels + nChInArbDmx);
+ hEnc->nSamplesValid = 0;
+ } /* valid handle */
+
+bail:
+ return error;
+}
+
+static INT getAnalysisLengthTimeSlots(FIXP_WIN *pFrameWindowAna,
+ INT nTimeSlots) {
+ int i;
+ for (i = nTimeSlots - 1; i >= 0; i--) {
+ if (pFrameWindowAna[i] != (FIXP_WIN)0) {
+ break;
+ }
+ }
+ nTimeSlots = i + 1;
+ return nTimeSlots;
+}
+
+static INT getAnalysisStartTimeSlot(FIXP_WIN *pFrameWindowAna, INT nTimeSlots) {
+ int startTimeSlot = 0;
+ int i;
+ for (i = 0; i < nTimeSlots; i++) {
+ if (pFrameWindowAna[i] != (FIXP_WIN)0) {
+ break;
+ }
+ }
+ startTimeSlot = i;
+ return startTimeSlot;
+}
+
+static FDK_SACENC_ERROR __FeedDeinterPreScale(
+ HANDLE_MP4SPACE_ENCODER hEnc, INT_PCM const *const pSamples,
+ INT_PCM *const pOutputSamples, INT const nSamples,
+ UINT const isInputInterleaved, UINT const inputBufferSizePerChannel,
+ UINT *const pnSamplesFed) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hEnc == NULL) || (pSamples == NULL) || (pnSamplesFed == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else if (nSamples == 0) {
+ error = SACENC_INVALID_CONFIG; /* Flushing not implemented */
+ } else {
+ int ch;
+ const INT nChIn = hEnc->nInputChannels;
+ const INT nChInWithDmx = nChIn;
+ const INT samplesToFeed =
+ FDKmin(nSamples, hEnc->nSamplesNext - hEnc->nSamplesValid);
+ const INT nSamplesPerChannel = samplesToFeed / nChInWithDmx;
+
+ if ((samplesToFeed < 0) || (samplesToFeed % nChInWithDmx != 0) ||
+ (samplesToFeed > nChInWithDmx * (INT)hEnc->nFrameLength)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ int i;
+
+ const INT_PCM *pInput__FDK;
+ const INT_PCM *pInput2__FDK;
+
+ { /* no dmx align = default*/
+ pInput__FDK = pSamples;
+ pInput2__FDK = pSamples + (hEnc->nInputDelay * nChInWithDmx);
+ }
+
+ for (i = 0; i < hEnc->nInputChannels; i++) {
+ hEnc->staticTimeDomainDmxInScale[i] = hEnc->staticGainScale;
+ }
+
+ /***** N-channel-input *****/
+ for (ch = 0; ch < nChIn; ch++) {
+ /* Write delayed time signal into time signal buffer */
+ FDKmemcpy(&(hEnc->ppTimeSigIn__FDK[ch][0]),
+ &(hEnc->ppTimeSigDelayIn__FDK[ch][0]),
+ hEnc->nSurroundAnalysisBufferDelay * sizeof(INT_PCM));
+
+ if (isInputInterleaved) {
+ /* Add the new frame de-interleaved. Apply nSurroundAnalysisBufferDelay.
+ */
+ FDKmemcpy_flex(
+ &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay]),
+ 1, pInput__FDK + ch, nChInWithDmx, hEnc->nInputDelay);
+ FDKmemcpy_flex(
+ &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay +
+ hEnc->nInputDelay]),
+ 1, pInput2__FDK + ch, nChInWithDmx,
+ nSamplesPerChannel - hEnc->nInputDelay);
+ } else {
+ /* Input is already deinterleaved, just copy */
+ FDKmemcpy(
+ &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay]),
+ pInput__FDK + ch * inputBufferSizePerChannel,
+ hEnc->nInputDelay * sizeof(INT_PCM));
+ FDKmemcpy(
+ &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nSurroundAnalysisBufferDelay +
+ hEnc->nInputDelay]),
+ pInput2__FDK + ch * inputBufferSizePerChannel,
+ (nSamplesPerChannel - hEnc->nInputDelay) * sizeof(INT_PCM));
+ }
+
+ /* Update time signal delay buffer */
+ FDKmemcpy(&(hEnc->ppTimeSigDelayIn__FDK[ch][0]),
+ &(hEnc->ppTimeSigIn__FDK[ch][hEnc->nFrameLength]),
+ hEnc->nSurroundAnalysisBufferDelay * sizeof(INT_PCM));
+ } /* for ch */
+
+ /***** No Arbitrary Downmix *****/
+ /* "Crude TD Dmx": Time DomainDownmix + NO Arbitrary Downmix, Delay Added at
+ * pOutputBuffer */
+ if ((hEnc->useTimeDomDownmix > 0)) {
+ if ((hEnc->useTimeDomDownmix == 1) || (hEnc->nInputChannels != 2)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ } else {
+ /* enhanced time domain downmix (for stereo input) */
+ if (hEnc->encMode == SACENC_212) {
+ if (pOutputSamples == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ fdk_sacenc_apply_enhancedTimeDomainDmx(
+ hEnc->hEnhancedTimeDmx, hEnc->ppTimeSigIn__FDK, pOutputSamples,
+ hEnc->nSurroundAnalysisBufferDelay);
+ } else {
+ if (&hEnc->ppTimeSigOut__FDK[0][0] == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ fdk_sacenc_apply_enhancedTimeDomainDmx(
+ hEnc->hEnhancedTimeDmx, hEnc->ppTimeSigIn__FDK,
+ &hEnc->ppTimeSigOut__FDK[0][0],
+ hEnc->nSurroundAnalysisBufferDelay);
+ }
+ }
+ }
+
+ /* update number of samples still to process */
+ hEnc->nSamplesValid += samplesToFeed;
+
+ /*return number of fed samples */
+ *pnSamplesFed = samplesToFeed;
+ }
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_encode(const HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ const FDK_bufDescr *inBufDesc,
+ const FDK_bufDescr *outBufDesc,
+ const SACENC_InArgs *inargs,
+ SACENC_OutArgs *outargs) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ const INT_PCM *pInputSamples =
+ (const INT_PCM *)inBufDesc->ppBase[getBufDescIdx(
+ inBufDesc, (FDK_BUF_TYPE_INPUT | FDK_BUF_TYPE_PCM_DATA))];
+
+ INT_PCM *const pOutputSamples = (INT_PCM *)outBufDesc->ppBase[getBufDescIdx(
+ outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA))];
+
+ const int nOutputSamplesBufferSize =
+ outBufDesc->pBufSize[getBufDescIdx(
+ outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA))] /
+ outBufDesc->pEleSize[getBufDescIdx(
+ outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA))];
+
+ if ((hMp4SpaceEnc == NULL) || (pInputSamples == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int nOutputSamples;
+ int i, ch, ps, winCnt, ts, slot;
+ INT currTransPos = -1;
+ SPATIALFRAME *pFrameData = NULL;
+
+ /* Improve Code Readability */
+ const int nChIn = hMp4SpaceEnc->nInputChannels;
+ const int nChInWithDmx = nChIn;
+ const int nChOut = hMp4SpaceEnc->nOutputChannels;
+ const int nSamplesPerChannel = inargs->nInputSamples / nChInWithDmx;
+ const int nOutputSamplesMax = nSamplesPerChannel * nChOut;
+ const int nFrameTimeSlots = hMp4SpaceEnc->nFrameTimeSlots;
+
+ INT encoderInputChScale[SACENC_MAX_INPUT_CHANNELS];
+ INT nFrameTimeSlotsReduction = 0;
+
+ if (hMp4SpaceEnc->encMode == SACENC_212) {
+ nFrameTimeSlotsReduction = hMp4SpaceEnc->nFrameTimeSlots >> 1;
+ }
+
+ for (i = 0; i < nChIn; i++)
+ encoderInputChScale[i] = hMp4SpaceEnc->pEncoderInputChScale[i];
+
+ /* Sanity Check */
+ if ((0 != inargs->nInputSamples % nChInWithDmx)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /*
+ * Get Frame Data Handle.
+ */
+
+ /* get bitstream handle (for storage of cld's, icc's and so on)
+ * get spatialframe 2 frames in the future; NOTE: this is necessary to
+ * synchronise spatial data and audio data */
+ if (NULL == (pFrameData = fdk_sacenc_getSpatialFrame(
+ hMp4SpaceEnc->hBitstreamFormatter, WRITE_SPATIALFRAME))) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* Independent Frames Counters*/
+ if (hMp4SpaceEnc->nDiscardOutFrames >
+ 0) { /* Independent Frames if they should be discarded, Reset Counter*/
+ hMp4SpaceEnc->independencyCount =
+ 0; /* Reset the counter, first valid frame is an independent one*/
+ hMp4SpaceEnc->independencyFlag = 1;
+ } else { /*hMp4SpaceEnc->nDiscardOutFrames == 0*/
+ hMp4SpaceEnc->independencyFlag =
+ (hMp4SpaceEnc->independencyCount == 0) ? 1 : 0;
+ if (hMp4SpaceEnc->independencyFactor > 0) {
+ hMp4SpaceEnc->independencyCount++;
+ hMp4SpaceEnc->independencyCount =
+ hMp4SpaceEnc->independencyCount %
+ ((int)hMp4SpaceEnc->independencyFactor);
+ } else { /* independencyFactor == 0 */
+ hMp4SpaceEnc->independencyCount = -1;
+ }
+ }
+
+ /*
+ * Time signal preprocessing:
+ * - Feed input buffer
+ * - Prescale time signal
+ * - Apply DC filter on input signal
+ */
+
+ /* Feed, Deinterleave, Pre-Scale the input time signals */
+ if (SACENC_OK !=
+ (error = __FeedDeinterPreScale(
+ hMp4SpaceEnc, pInputSamples, pOutputSamples, inargs->nInputSamples,
+ inargs->isInputInterleaved, inargs->inputBufferSizePerChannel,
+ &outargs->nSamplesConsumed))) {
+ goto bail;
+ }
+
+ if (hMp4SpaceEnc->nSamplesNext != hMp4SpaceEnc->nSamplesValid) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ if (hMp4SpaceEnc->encMode == SACENC_212 &&
+ hMp4SpaceEnc->bEncMode_212_only) {
+ for (ch = 0; ch < nChIn; ch++) {
+ for (slot = 0; slot < nFrameTimeSlots; slot++) {
+ setCplxVec(
+ hMp4SpaceEnc->pppHybridIn__FDK
+ [ch][hMp4SpaceEnc->nUpdateHybridPositionTimeSlots +
+ nFrameTimeSlots - nFrameTimeSlotsReduction + slot],
+ (FIXP_DBL)0, hMp4SpaceEnc->nHybridBands);
+ }
+ }
+ }
+
+ /*
+ * Time / Frequency:
+ * - T/F audio input channels
+ * - T/F arbitrary downmix input channels
+ */
+ for (ch = 0; ch < nChIn; ch++) {
+ C_AALLOC_SCRATCH_START(pQmfInReal, FIXP_DBL, MAX_QMF_BANDS)
+ C_AALLOC_SCRATCH_START(pQmfInImag, FIXP_DBL, MAX_QMF_BANDS)
+ FIXP_GAIN *pPreGain =
+ fdk_sacenc_getPreGainPtrFDK(hMp4SpaceEnc->hStaticGain);
+
+ for (ts = 0; ts < nFrameTimeSlots; ts++) {
+ FIXP_DBL *pSpecReal;
+ FIXP_DBL *pSpecImag;
+
+ INT_PCM *pTimeIn =
+ &hMp4SpaceEnc->ppTimeSigIn__FDK[ch][(ts * hMp4SpaceEnc->nQmfBands)];
+
+ {
+ /* Apply DC filter on input channels */
+ if (SACENC_OK != (error = fdk_sacenc_applyDCFilter(
+ hMp4SpaceEnc->phDCFilterSigIn[ch], pTimeIn,
+ pTimeIn, hMp4SpaceEnc->nQmfBands))) {
+ goto bail;
+ }
+ }
+
+ /* QMF filterbank */
+ C_ALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, (MAX_QMF_BANDS << 1));
+
+ qmfAnalysisFilteringSlot(hMp4SpaceEnc->phQmfFiltIn__FDK[ch], pQmfInReal,
+ pQmfInImag, pTimeIn, 1, pWorkBuffer);
+
+ C_ALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, (MAX_QMF_BANDS << 1));
+
+ pSpecReal = pQmfInReal;
+ pSpecImag = pQmfInImag;
+
+ /* Apply pre-scale after filterbank */
+ if (MAXVAL_GAIN != pPreGain[ch]) {
+ for (i = 0; i < hMp4SpaceEnc->nHybridBands; i++) {
+ hMp4SpaceEnc
+ ->pppHybridIn__FDK[ch]
+ [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots +
+ ts][i]
+ .v.re = fMult(pSpecReal[i], pPreGain[ch]);
+ hMp4SpaceEnc
+ ->pppHybridIn__FDK[ch]
+ [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots +
+ ts][i]
+ .v.im = fMult(pSpecImag[i], pPreGain[ch]);
+ }
+ } else {
+ for (i = 0; i < hMp4SpaceEnc->nHybridBands; i++) {
+ hMp4SpaceEnc
+ ->pppHybridIn__FDK[ch]
+ [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots +
+ ts][i]
+ .v.re = pSpecReal[i];
+ hMp4SpaceEnc
+ ->pppHybridIn__FDK[ch]
+ [hMp4SpaceEnc->nAnalysisLookaheadTimeSlots +
+ ts][i]
+ .v.im = pSpecImag[i];
+ }
+ }
+ } /* ts */
+ C_AALLOC_SCRATCH_END(pQmfInImag, FIXP_DBL, MAX_QMF_BANDS)
+ C_AALLOC_SCRATCH_END(pQmfInReal, FIXP_DBL, MAX_QMF_BANDS)
+
+ if (SACENC_OK != error) {
+ goto bail;
+ }
+ } /* ch */
+
+ if (hMp4SpaceEnc->encMode == SACENC_212 &&
+ hMp4SpaceEnc->bEncMode_212_only) {
+ for (ch = 0; ch < nChIn; ch++) {
+ for (slot = 0;
+ slot < (int)(hMp4SpaceEnc->nUpdateHybridPositionTimeSlots +
+ nFrameTimeSlots - nFrameTimeSlotsReduction);
+ slot++) {
+ copyCplxVec(hMp4SpaceEnc->pppHybridIn__FDK[ch][slot],
+ hMp4SpaceEnc->pppHybridInStatic__FDK[ch][slot],
+ hMp4SpaceEnc->nHybridBands);
+ }
+ }
+ for (ch = 0; ch < nChIn; ch++) {
+ for (slot = 0;
+ slot < (int)(hMp4SpaceEnc->nUpdateHybridPositionTimeSlots +
+ nFrameTimeSlots - nFrameTimeSlotsReduction);
+ slot++) {
+ copyCplxVec(
+ hMp4SpaceEnc->pppHybridInStatic__FDK[ch][slot],
+ hMp4SpaceEnc->pppHybridIn__FDK[ch][nFrameTimeSlots + slot],
+ hMp4SpaceEnc->nHybridBands);
+ }
+ }
+ }
+
+ /*
+ * Onset Detection:
+ * - detection of transients
+ * - build framing
+ */
+ for (ch = 0; ch < nChIn; ch++) {
+ if (ch != 3) { /* !LFE */
+ if (SACENC_OK !=
+ (error = fdk_sacenc_onsetDetect_Apply(
+ hMp4SpaceEnc->phOnset[ch], nFrameTimeSlots,
+ hMp4SpaceEnc->nHybridBands,
+ &hMp4SpaceEnc->pppHybridIn__FDK
+ [ch][hMp4SpaceEnc->nAnalysisLookaheadTimeSlots],
+ encoderInputChScale[ch],
+ hMp4SpaceEnc->trPrevPos[1], /* contains previous Transient */
+ hMp4SpaceEnc->ppTrCurrPos[ch]))) {
+ goto bail;
+ }
+
+ if ((1) && (hMp4SpaceEnc->useFrameKeep == 0)) {
+ hMp4SpaceEnc->ppTrCurrPos[ch][0] = -1;
+ }
+
+ /* Find first Transient Position */
+ if ((hMp4SpaceEnc->ppTrCurrPos[ch][0] >= 0) &&
+ ((currTransPos < 0) ||
+ (hMp4SpaceEnc->ppTrCurrPos[ch][0] < currTransPos))) {
+ currTransPos = hMp4SpaceEnc->ppTrCurrPos[ch][0];
+ }
+ } /* !LFE */
+ } /* ch */
+
+ if (hMp4SpaceEnc->useFrameKeep == 1) {
+ if ((currTransPos != -1) || (hMp4SpaceEnc->independencyFlag == 1)) {
+ hMp4SpaceEnc->avoid_keep = NUM_KEEP_WINDOWS;
+ currTransPos = -1;
+ }
+ }
+
+ /* Save previous Transient Position */
+ hMp4SpaceEnc->trPrevPos[0] =
+ FDKmax(-1, hMp4SpaceEnc->trPrevPos[1] - (INT)nFrameTimeSlots);
+ hMp4SpaceEnc->trPrevPos[1] = currTransPos;
+
+ /* Update Onset Detection Energy Buffer */
+ for (ch = 0; ch < nChIn; ch++) {
+ if (SACENC_OK != (error = fdk_sacenc_onsetDetect_Update(
+ hMp4SpaceEnc->phOnset[ch], nFrameTimeSlots))) {
+ goto bail;
+ }
+ }
+
+ /* Framing */
+ if (SACENC_OK !=
+ (error = fdk_sacenc_frameWindow_GetWindow(
+ hMp4SpaceEnc->hFrameWindow, hMp4SpaceEnc->trPrevPos,
+ nFrameTimeSlots, &pFrameData->framingInfo,
+ hMp4SpaceEnc->pFrameWindowAna__FDK, &hMp4SpaceEnc->frameWinList,
+ hMp4SpaceEnc->avoid_keep))) {
+ goto bail;
+ }
+
+ /*
+ * MPS Processing:
+ */
+ for (ps = 0, winCnt = 0; ps < hMp4SpaceEnc->frameWinList.n; ++ps) {
+ /* Analysis Windowing */
+ if (hMp4SpaceEnc->frameWinList.dat[ps].hold == FW_HOLD) {
+ /* ************************************** */
+ /* ONLY COPY AND HOLD PREVIOUS PARAMETERS */
+ if (SACENC_OK != (error = fdk_sacenc_duplicateParameterSet(
+ &hMp4SpaceEnc->saveFrame, 0, pFrameData, ps))) {
+ goto bail;
+ }
+
+ } else { /* !FW_HOLD */
+ /* ************************************** */
+ /* NEW WINDOW */
+
+ INT nAnalysisLengthTimeSlots, analysisStartTimeSlot;
+
+ nAnalysisLengthTimeSlots = getAnalysisLengthTimeSlots(
+ hMp4SpaceEnc->pFrameWindowAna__FDK[winCnt],
+ hMp4SpaceEnc->nAnalysisLengthTimeSlots);
+
+ analysisStartTimeSlot =
+ getAnalysisStartTimeSlot(hMp4SpaceEnc->pFrameWindowAna__FDK[winCnt],
+ hMp4SpaceEnc->nAnalysisLengthTimeSlots);
+
+ /* perform main signal analysis windowing in
+ * fdk_sacenc_spaceTree_Apply() */
+ FIXP_WIN *pFrameWindowAna__FDK =
+ hMp4SpaceEnc->pFrameWindowAna__FDK[winCnt];
+ FIXP_DPK ***pppHybridIn__FDK = hMp4SpaceEnc->pppHybridIn__FDK;
+ FIXP_DPK ***pppProcDataIn__FDK = hMp4SpaceEnc->pppProcDataIn__FDK;
+
+ if (hMp4SpaceEnc->encMode == SACENC_212 &&
+ hMp4SpaceEnc->bEncMode_212_only) {
+ pppProcDataIn__FDK = pppHybridIn__FDK;
+ }
+
+ if (SACENC_OK !=
+ (error = fdk_sacenc_spaceTree_Apply(
+ hMp4SpaceEnc->hSpaceTree, ps, nChIn, nAnalysisLengthTimeSlots,
+ analysisStartTimeSlot, hMp4SpaceEnc->nHybridBands,
+ pFrameWindowAna__FDK, pppHybridIn__FDK,
+ pppProcDataIn__FDK, /* multi-channel input */
+ pFrameData, hMp4SpaceEnc->avoid_keep, encoderInputChScale))) {
+ goto bail;
+ }
+
+ /* Save spatial frame for potential hold parameter set */
+ if (SACENC_OK != (error = fdk_sacenc_duplicateParameterSet(
+ pFrameData, ps, &hMp4SpaceEnc->saveFrame, 0))) {
+ goto bail;
+ }
+
+ ++winCnt;
+ }
+ if (hMp4SpaceEnc->avoid_keep > 0) {
+ hMp4SpaceEnc->avoid_keep--;
+ }
+ } /* Loop over Parameter Sets */
+ /* ---- End of Processing Loop ---- */
+
+ /*
+ * Update hybridInReal/Imag buffer and do the same for arbDmx
+ * this means to move the hybrid data of the current frame to the beginning
+ * of the 2*nFrameLength-long buffer
+ */
+ if (!(hMp4SpaceEnc->encMode == SACENC_212 &&
+ hMp4SpaceEnc->bEncMode_212_only)) {
+ for (ch = 0; ch < nChIn; ch++) { /* for automatic downmix */
+ for (slot = 0;
+ slot < (int)(hMp4SpaceEnc->nUpdateHybridPositionTimeSlots +
+ nFrameTimeSlots - nFrameTimeSlotsReduction);
+ slot++) {
+ copyCplxVec(
+ hMp4SpaceEnc->pppHybridIn__FDK[ch][slot],
+ hMp4SpaceEnc->pppHybridIn__FDK[ch][nFrameTimeSlots + slot],
+ hMp4SpaceEnc->nHybridBands);
+ }
+ for (slot = 0; slot < nFrameTimeSlots; slot++) {
+ setCplxVec(
+ hMp4SpaceEnc->pppHybridIn__FDK
+ [ch][hMp4SpaceEnc->nUpdateHybridPositionTimeSlots +
+ nFrameTimeSlots - nFrameTimeSlotsReduction + slot],
+ (FIXP_DBL)0, hMp4SpaceEnc->nHybridBands);
+ }
+ }
+ }
+ /*
+ * Spatial Tonality:
+ */
+ {
+ /* Smooth config off. */
+ FDKmemclear(&pFrameData->smgData, sizeof(pFrameData->smgData));
+ }
+
+ /*
+ * Create bitstream
+ * - control independecy flag
+ * - write spatial frame
+ * - return bitstream
+ */
+ UCHAR *pBitstreamDelayBuffer;
+
+ if (hMp4SpaceEnc->encMode == SACENC_212) {
+ /* no bitstream delay buffer for SACENC_212 mode, write bitstream directly
+ * into the sacOutBuffer buffer which is provided by the core routine */
+ pBitstreamDelayBuffer = (UCHAR *)outBufDesc->ppBase[1];
+ } else {
+ /* bitstream delay is handled in ppBitstreamDelayBuffer buffer */
+ pBitstreamDelayBuffer =
+ hMp4SpaceEnc
+ ->ppBitstreamDelayBuffer[hMp4SpaceEnc->nBitstreamBufferWrite];
+ }
+ if (pBitstreamDelayBuffer == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ pFrameData->bsIndependencyFlag = hMp4SpaceEnc->independencyFlag;
+
+ if (SACENC_OK !=
+ (error = fdk_sacenc_writeSpatialFrame(
+ pBitstreamDelayBuffer, MAX_MPEGS_BYTES,
+ &hMp4SpaceEnc->pnOutputBits[hMp4SpaceEnc->nBitstreamBufferWrite],
+ hMp4SpaceEnc->hBitstreamFormatter))) {
+ goto bail;
+ }
+
+ /* return bitstream info */
+ if ((hMp4SpaceEnc->nDiscardOutFrames == 0) &&
+ (getBufDescIdx(outBufDesc,
+ (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_BS_DATA)) != -1)) {
+ const INT idx = getBufDescIdx(
+ outBufDesc, (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_BS_DATA));
+ const INT outBits =
+ hMp4SpaceEnc->pnOutputBits[hMp4SpaceEnc->nBitstreamBufferRead];
+
+ if (((outBits + 7) / 8) >
+ (INT)(outBufDesc->pBufSize[idx] / outBufDesc->pEleSize[idx])) {
+ outargs->nOutputBits = 0;
+ error = SACENC_ENCODE_ERROR;
+ goto bail;
+ }
+
+ /* return bitstream buffer, copy delayed bitstream for all configurations
+ * except for the SACENC_212 mode */
+ if (hMp4SpaceEnc->encMode != SACENC_212) {
+ FDKmemcpy(
+ outBufDesc->ppBase[idx],
+ hMp4SpaceEnc
+ ->ppBitstreamDelayBuffer[hMp4SpaceEnc->nBitstreamBufferRead],
+ (outBits + 7) / 8);
+ }
+
+ /* return number of valid bits */
+ outargs->nOutputBits = outBits;
+ } else { /* No spatial data should be returned if the current frame is to be
+ discarded. */
+ outargs->nOutputBits = 0;
+ }
+
+ /* update pointers */
+ hMp4SpaceEnc->nBitstreamBufferRead =
+ (hMp4SpaceEnc->nBitstreamBufferRead + 1) %
+ hMp4SpaceEnc->nBitstreamDelayBuffer;
+ hMp4SpaceEnc->nBitstreamBufferWrite =
+ (hMp4SpaceEnc->nBitstreamBufferWrite + 1) %
+ hMp4SpaceEnc->nBitstreamDelayBuffer;
+
+ /* Set Output Parameters */
+ nOutputSamples =
+ (hMp4SpaceEnc->nDiscardOutFrames == 0)
+ ? (nOutputSamplesMax)
+ : 0; /* don't output samples in case frames to be discarded */
+ if (nOutputSamples > nOutputSamplesBufferSize) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+ outargs->nOutputSamples = nOutputSamples;
+
+ { /* !bQmfOutput */
+
+ if (hMp4SpaceEnc->encMode != SACENC_212) {
+ /* delay output samples and interleave them */
+ /* note: in case of arbitrary downmix this will always be processed,
+ * because nOutputSamples != 0, even if bDMXAlign is switched on */
+ /* always run copy-func, so nOutputSamplesMax instead of nOutputSamples
+ */
+ for (ch = 0; ch < nChOut; ch++) {
+ FDKmemcpy_flex(
+ &hMp4SpaceEnc->pOutputDelayBuffer__FDK
+ [ch + (hMp4SpaceEnc->nOutputBufferDelay) * nChOut],
+ nChOut, hMp4SpaceEnc->ppTimeSigOut__FDK[ch], 1,
+ nOutputSamplesMax / nChOut);
+ }
+
+ /* write delayed data in output pcm stream */
+ /* always calculate, limiter must have a lookahead!!! */
+ FDKmemcpy(pOutputSamples, hMp4SpaceEnc->pOutputDelayBuffer__FDK,
+ nOutputSamplesMax * sizeof(INT_PCM));
+
+ /* update delay buffer (move back end to the beginning of the buffer) */
+ FDKmemmove(
+ hMp4SpaceEnc->pOutputDelayBuffer__FDK,
+ &hMp4SpaceEnc->pOutputDelayBuffer__FDK[nOutputSamplesMax],
+ nChOut * (hMp4SpaceEnc->nOutputBufferDelay) * sizeof(INT_PCM));
+ }
+
+ if (hMp4SpaceEnc->useTimeDomDownmix <= 0) {
+ if (SACENC_OK != (error = fdk_sacenc_staticPostGain_ApplyFDK(
+ hMp4SpaceEnc->hStaticGain, pOutputSamples,
+ nOutputSamplesMax, 0))) {
+ goto bail;
+ }
+ }
+
+ } /* !bQmfOutput */
+
+ if (hMp4SpaceEnc->nDiscardOutFrames > 0) {
+ hMp4SpaceEnc->nDiscardOutFrames--;
+ }
+
+ /* Invalidate Input Buffer */
+ hMp4SpaceEnc->nSamplesValid = 0;
+
+ } /* valid handle */
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_close(HANDLE_MP4SPACE_ENCODER *phMp4SpaceEnc) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL != phMp4SpaceEnc) {
+ if (NULL != *phMp4SpaceEnc) {
+ int ch, i;
+ HANDLE_MP4SPACE_ENCODER const hEnc = *phMp4SpaceEnc;
+
+ if (hEnc->pParameterBand2HybridBandOffset != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->pParameterBand2HybridBandOffset);
+ }
+ /* Free Analysis Filterbank Structs */
+ if (hEnc->pEncoderInputChScale != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->pEncoderInputChScale);
+ }
+ if (hEnc->staticTimeDomainDmxInScale != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->staticTimeDomainDmxInScale);
+ }
+ if (hEnc->phQmfFiltIn__FDK != NULL) {
+ for (ch = 0; ch < hEnc->setup.maxChIn; ch++) {
+ if (hEnc->phQmfFiltIn__FDK[ch] != NULL) {
+ if (hEnc->phQmfFiltIn__FDK[ch]->FilterStates != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->phQmfFiltIn__FDK[ch]->FilterStates);
+ }
+ FDK_FREE_MEMORY_1D(hEnc->phQmfFiltIn__FDK[ch]);
+ }
+ }
+ FDK_FREE_MEMORY_1D(hEnc->phQmfFiltIn__FDK);
+ }
+ for (ch = 0; ch < hEnc->setup.maxChIn; ch++) {
+ if (NULL != hEnc->phDCFilterSigIn[ch]) {
+ fdk_sacenc_destroyDCFilter(&hEnc->phDCFilterSigIn[ch]);
+ }
+ }
+ /* Close Onset Detection */
+ for (ch = 0; ch < hEnc->setup.maxChIn; ch++) {
+ if (NULL != hEnc->phOnset[ch]) {
+ fdk_sacenc_onsetDetect_Close(&hEnc->phOnset[ch]);
+ }
+ }
+ if (hEnc->ppTrCurrPos) {
+ FDK_FREE_MEMORY_2D(hEnc->ppTrCurrPos);
+ }
+ if (hEnc->hFrameWindow) {
+ fdk_sacenc_frameWindow_Destroy(&hEnc->hFrameWindow);
+ }
+ /* Close Space Tree */
+ if (NULL != hEnc->hSpaceTree) {
+ fdk_sacenc_spaceTree_Close(&hEnc->hSpaceTree);
+ }
+ if (NULL != hEnc->hEnhancedTimeDmx) {
+ fdk_sacenc_close_enhancedTimeDomainDmx(&hEnc->hEnhancedTimeDmx);
+ }
+ /* Close Static Gain */
+ if (NULL != hEnc->hStaticGain) {
+ fdk_sacenc_staticGain_Close(&hEnc->hStaticGain);
+ }
+ if (NULL != hEnc->hStaticGainConfig) {
+ fdk_sacenc_staticGain_CloseConfig(&hEnc->hStaticGainConfig);
+ }
+ /* Close Delay*/
+ if (NULL != hEnc->hDelay) {
+ fdk_sacenc_delay_Close(&hEnc->hDelay);
+ }
+ /* Delete Bitstream Stuff */
+ if (NULL != hEnc->hBitstreamFormatter) {
+ fdk_sacenc_destroySpatialBitstreamEncoder(&(hEnc->hBitstreamFormatter));
+ }
+ if (hEnc->pppHybridIn__FDK != NULL) {
+ if (hEnc->setup.bEncMode_212 == 1) {
+ FDK_FREE_MEMORY_3D(hEnc->pppHybridIn__FDK);
+ FDK_FREE_MEMORY_3D(hEnc->pppHybridInStatic__FDK);
+ } else {
+ FDK_FREE_MEMORY_3D(hEnc->pppHybridIn__FDK);
+ }
+ }
+ if (hEnc->pppProcDataIn__FDK != NULL) {
+ FDK_FREE_MEMORY_3D(hEnc->pppProcDataIn__FDK);
+ }
+ if (hEnc->pOutputDelayBuffer__FDK != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->pOutputDelayBuffer__FDK);
+ }
+ if (hEnc->ppTimeSigIn__FDK != NULL) {
+ { FDK_FREE_MEMORY_2D(hEnc->ppTimeSigIn__FDK); }
+ }
+ if (hEnc->ppTimeSigDelayIn__FDK != NULL) {
+ FDK_FREE_MEMORY_2D(hEnc->ppTimeSigDelayIn__FDK);
+ }
+ if (hEnc->ppTimeSigOut__FDK != NULL) {
+ FDK_FREE_MEMORY_2D(hEnc->ppTimeSigOut__FDK);
+ }
+ for (i = 0; i < MAX_NUM_PARAMS; i++) {
+ if (hEnc->pFrameWindowAna__FDK[i] != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->pFrameWindowAna__FDK[i]);
+ }
+ }
+ if (hEnc->pnOutputBits != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->pnOutputBits);
+ }
+ if (hEnc->ppBitstreamDelayBuffer != NULL) {
+ FDK_FREE_MEMORY_2D(hEnc->ppBitstreamDelayBuffer);
+ }
+ if (hEnc->sscBuf.pSsc != NULL) {
+ FDK_FREE_MEMORY_1D(hEnc->sscBuf.pSsc);
+ }
+ FDK_FREE_MEMORY_1D(*phMp4SpaceEnc);
+ }
+ }
+
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+ functionname: mp4SpaceEnc_InitDelayCompensation()
+ description: initialzes delay compensation
+ returns: noError on success, an apropriate error code else
+ -----------------------------------------------------------------------------*/
+static FDK_SACENC_ERROR mp4SpaceEnc_InitDelayCompensation(
+ HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc, const INT coreCoderDelay) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ /* Sanity Check */
+ if (hMp4SpaceEnc == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ hMp4SpaceEnc->coreCoderDelay = coreCoderDelay;
+
+ if (SACENC_OK != (error = fdk_sacenc_delay_Init(
+ hMp4SpaceEnc->hDelay, hMp4SpaceEnc->nQmfBands,
+ hMp4SpaceEnc->nFrameLength, coreCoderDelay,
+ hMp4SpaceEnc->timeAlignment))) {
+ goto bail;
+ }
+
+ fdk_sacenc_delay_SetDmxAlign(hMp4SpaceEnc->hDelay, 0);
+ fdk_sacenc_delay_SetTimeDomDmx(
+ hMp4SpaceEnc->hDelay, (hMp4SpaceEnc->useTimeDomDownmix >= 1) ? 1 : 0);
+ fdk_sacenc_delay_SetMinimizeDelay(hMp4SpaceEnc->hDelay, 1);
+
+ if (SACENC_OK != (error = fdk_sacenc_delay_SubCalulateBufferDelays(
+ hMp4SpaceEnc->hDelay))) {
+ goto bail;
+ }
+
+ /* init output delay compensation */
+ hMp4SpaceEnc->nBitstreamDelayBuffer =
+ fdk_sacenc_delay_GetBitstreamFrameBufferSize(hMp4SpaceEnc->hDelay);
+ hMp4SpaceEnc->nOutputBufferDelay =
+ fdk_sacenc_delay_GetOutputAudioBufferDelay(hMp4SpaceEnc->hDelay);
+ hMp4SpaceEnc->nSurroundAnalysisBufferDelay =
+ fdk_sacenc_delay_GetSurroundAnalysisBufferDelay(hMp4SpaceEnc->hDelay);
+ hMp4SpaceEnc->nBitstreamBufferRead = 0;
+ hMp4SpaceEnc->nBitstreamBufferWrite =
+ hMp4SpaceEnc->nBitstreamDelayBuffer - 1;
+
+ if (hMp4SpaceEnc->encMode == SACENC_212) {
+ /* mode 212 expects no bitstream delay */
+ if (hMp4SpaceEnc->nBitstreamBufferWrite !=
+ hMp4SpaceEnc->nBitstreamBufferRead) {
+ error = SACENC_PARAM_ERROR;
+ goto bail;
+ }
+
+ /* mode 212 expects no output buffer delay */
+ if (hMp4SpaceEnc->nOutputBufferDelay != 0) {
+ error = SACENC_PARAM_ERROR;
+ goto bail;
+ }
+ }
+
+ /*** Input delay to obtain a net encoder delay that is a multiple
+ of the used framelength to ensure synchronization of framing
+ in artistic down-mix with the corresponding spatial data. ***/
+ hMp4SpaceEnc->nDiscardOutFrames =
+ fdk_sacenc_delay_GetDiscardOutFrames(hMp4SpaceEnc->hDelay);
+ hMp4SpaceEnc->nInputDelay =
+ fdk_sacenc_delay_GetDmxAlignBufferDelay(hMp4SpaceEnc->hDelay);
+
+ /* reset independency Flag counter */
+ hMp4SpaceEnc->independencyCount = 0;
+ hMp4SpaceEnc->independencyFlag = 1;
+
+ int i;
+
+ /* write some parameters to bitstream */
+ for (i = 0; i < hMp4SpaceEnc->nBitstreamDelayBuffer - 1; i++) {
+ SPATIALFRAME *pFrameData = NULL;
+
+ if (NULL == (pFrameData = fdk_sacenc_getSpatialFrame(
+ hMp4SpaceEnc->hBitstreamFormatter, READ_SPATIALFRAME))) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ pFrameData->bsIndependencyFlag = 1;
+ pFrameData->framingInfo.numParamSets = 1;
+ pFrameData->framingInfo.bsFramingType = 0;
+
+ fdk_sacenc_writeSpatialFrame(
+ hMp4SpaceEnc->ppBitstreamDelayBuffer[i], MAX_MPEGS_BYTES,
+ &hMp4SpaceEnc->pnOutputBits[i], hMp4SpaceEnc->hBitstreamFormatter);
+ }
+
+ if ((hMp4SpaceEnc->nInputDelay > MAX_DELAY_INPUT) ||
+ (hMp4SpaceEnc->nOutputBufferDelay > MAX_DELAY_OUTPUT) ||
+ (hMp4SpaceEnc->nSurroundAnalysisBufferDelay >
+ MAX_DELAY_SURROUND_ANALYSIS) ||
+ (hMp4SpaceEnc->nBitstreamDelayBuffer > MAX_BITSTREAM_DELAY)) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+ }
+
+bail:
+
+ return error;
+}
+
+static QUANTMODE __mapQuantMode(const MP4SPACEENC_QUANTMODE quantMode) {
+ QUANTMODE bsQuantMode = QUANTMODE_INVALID;
+
+ switch (quantMode) {
+ case SACENC_QUANTMODE_FINE:
+ bsQuantMode = QUANTMODE_FINE;
+ break;
+ case SACENC_QUANTMODE_EBQ1:
+ bsQuantMode = QUANTMODE_EBQ1;
+ break;
+ case SACENC_QUANTMODE_EBQ2:
+ bsQuantMode = QUANTMODE_EBQ2;
+ break;
+ case SACENC_QUANTMODE_RSVD3:
+ case SACENC_QUANTMODE_INVALID:
+ default:
+ bsQuantMode = QUANTMODE_INVALID;
+ } /* switch hEnc->quantMode */
+
+ return bsQuantMode;
+}
+
+static FDK_SACENC_ERROR FillSpatialSpecificConfig(
+ const HANDLE_MP4SPACE_ENCODER hEnc, SPATIALSPECIFICCONFIG *const hSsc) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hEnc) || (NULL == hSsc)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ SPACE_TREE_DESCRIPTION spaceTreeDescription;
+ int i;
+
+ /* Get tree description */
+ if (SACENC_OK != (error = fdk_sacenc_spaceTree_GetDescription(
+ hEnc->hSpaceTree, &spaceTreeDescription))) {
+ goto bail;
+ }
+
+ /* Fill SSC */
+ FDKmemclear(hSsc, sizeof(SPATIALSPECIFICCONFIG)); /* reset */
+
+ hSsc->numBands = hEnc->spaceTreeSetup.nParamBands; /* for bsFreqRes */
+
+ /* Fill tree configuration */
+ hSsc->treeDescription.numOttBoxes = spaceTreeDescription.nOttBoxes;
+ hSsc->treeDescription.numInChan = spaceTreeDescription.nInChannels;
+ hSsc->treeDescription.numOutChan = spaceTreeDescription.nOutChannels;
+
+ for (i = 0; i < SACENC_MAX_NUM_BOXES; i++) {
+ hSsc->ottConfig[i].bsOttBands = hSsc->numBands;
+ }
+
+ switch (hEnc->encMode) {
+ case SACENC_212:
+ hSsc->bsTreeConfig = TREE_212;
+ break;
+ case SACENC_INVALID_MODE:
+ default:
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ hSsc->bsSamplingFrequency =
+ hEnc->nSampleRate; /* for bsSamplingFrequencyIndex */
+ hSsc->bsFrameLength = hEnc->nFrameTimeSlots - 1;
+
+ /* map decorr type */
+ if (DECORR_INVALID ==
+ (hSsc->bsDecorrConfig = mp4SpaceEnc_GetDecorrConfig(hEnc->encMode))) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* map quantMode */
+ if (QUANTMODE_INVALID ==
+ (hSsc->bsQuantMode = __mapQuantMode(hEnc->quantMode))) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* Configure Gains*/
+ hSsc->bsFixedGainDMX = fdk_sacenc_staticGain_GetDmxGain(hEnc->hStaticGain);
+ hSsc->bsEnvQuantMode = 0;
+
+ } /* valid handle */
+
+bail:
+ return error;
+}
+
+static FDK_SACENC_ERROR mp4SpaceEnc_FillSpaceTreeSetup(
+ const HANDLE_MP4SPACE_ENCODER hEnc,
+ SPACE_TREE_SETUP *const hSpaceTreeSetup) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ /* Sanity Check */
+ if (NULL == hEnc || NULL == hSpaceTreeSetup) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ QUANTMODE tmpQuantmode = QUANTMODE_INVALID;
+
+ /* map quantMode */
+ if (QUANTMODE_INVALID == (tmpQuantmode = __mapQuantMode(hEnc->quantMode))) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ hSpaceTreeSetup->nParamBands = hEnc->nParamBands;
+ hSpaceTreeSetup->bUseCoarseQuantTtoCld = hEnc->useCoarseQuantCld;
+ hSpaceTreeSetup->bUseCoarseQuantTtoIcc = hEnc->useCoarseQuantIcc;
+ hSpaceTreeSetup->quantMode = tmpQuantmode;
+ hSpaceTreeSetup->nHybridBandsMax = hEnc->nHybridBands;
+
+ switch (hEnc->encMode) {
+ case SACENC_212:
+ hSpaceTreeSetup->mode = SPACETREE_212;
+ hSpaceTreeSetup->nChannelsInMax = 2;
+ break;
+ case SACENC_INVALID_MODE:
+ default:
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ } /* switch hEnc->encMode */
+
+ } /* valid handle */
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_getInfo(const HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ MP4SPACEENC_INFO *const pInfo) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hMp4SpaceEnc) || (NULL == pInfo)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ pInfo->nSampleRate = hMp4SpaceEnc->nSampleRate;
+ pInfo->nSamplesFrame = hMp4SpaceEnc->nFrameLength;
+ pInfo->nTotalInputChannels = hMp4SpaceEnc->nInputChannels;
+ pInfo->nDmxDelay = fdk_sacenc_delay_GetInfoDmxDelay(hMp4SpaceEnc->hDelay);
+ pInfo->nCodecDelay =
+ fdk_sacenc_delay_GetInfoCodecDelay(hMp4SpaceEnc->hDelay);
+ pInfo->nDecoderDelay =
+ fdk_sacenc_delay_GetInfoDecoderDelay(hMp4SpaceEnc->hDelay);
+ pInfo->nPayloadDelay =
+ fdk_sacenc_delay_GetBitstreamFrameBufferSize(hMp4SpaceEnc->hDelay) - 1;
+ pInfo->nDiscardOutFrames = hMp4SpaceEnc->nDiscardOutFrames;
+
+ pInfo->pSscBuf = &hMp4SpaceEnc->sscBuf;
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_setParam(HANDLE_MP4SPACE_ENCODER hMp4SpaceEnc,
+ const SPACEENC_PARAM param,
+ const UINT value) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ /* check encoder handle */
+ if (hMp4SpaceEnc == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* apply param value */
+ switch (param) {
+ case SACENC_LOWDELAY:
+ if (!((value == 0) || (value == 1) || (value == 2))) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.bLdMode = value;
+ break;
+
+ case SACENC_ENC_MODE:
+ switch ((MP4SPACEENC_MODE)value) {
+ case SACENC_212:
+ hMp4SpaceEnc->user.encMode = (MP4SPACEENC_MODE)value;
+ break;
+ default:
+ error = SACENC_INVALID_CONFIG;
+ }
+ break;
+
+ case SACENC_SAMPLERATE:
+ if (((int)value < 0) ||
+ ((int)value > hMp4SpaceEnc->setup.maxSamplingrate)) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.sampleRate = value;
+ break;
+
+ case SACENC_FRAME_TIME_SLOTS:
+ if (((int)value < 0) ||
+ ((int)value > hMp4SpaceEnc->setup.maxFrameTimeSlots)) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.frameTimeSlots = value;
+ break;
+
+ case SACENC_PARAM_BANDS:
+ switch ((MP4SPACEENC_BANDS_CONFIG)value) {
+ case SACENC_BANDS_4:
+ case SACENC_BANDS_5:
+ case SACENC_BANDS_7:
+ case SACENC_BANDS_9:
+ case SACENC_BANDS_12:
+ case SACENC_BANDS_15:
+ case SACENC_BANDS_23:
+ hMp4SpaceEnc->user.nParamBands = (MP4SPACEENC_BANDS_CONFIG)value;
+ break;
+ default:
+ error = SACENC_INVALID_CONFIG;
+ }
+ break;
+
+ case SACENC_TIME_DOM_DMX:
+ if (!((value == 0) || (value == 2))) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.bTimeDomainDmx = value;
+ break;
+
+ case SACENC_DMX_GAIN:
+ if (!((value == 0) || (value == 1) || (value == 2) || (value == 3) ||
+ (value == 4) || (value == 5) || (value == 6) || (value == 7))) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ error = fdk_sacenc_staticGain_SetDmxGain(hMp4SpaceEnc->hStaticGainConfig,
+ (MP4SPACEENC_DMX_GAIN)value);
+ break;
+
+ case SACENC_COARSE_QUANT:
+ if (!((value == 0) || (value == 1))) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.bUseCoarseQuant = value;
+ break;
+
+ case SACENC_QUANT_MODE:
+ switch ((MP4SPACEENC_QUANTMODE)value) {
+ case SACENC_QUANTMODE_FINE:
+ case SACENC_QUANTMODE_EBQ1:
+ case SACENC_QUANTMODE_EBQ2:
+ hMp4SpaceEnc->user.quantMode = (MP4SPACEENC_QUANTMODE)value;
+ break;
+ default:
+ error = SACENC_INVALID_CONFIG;
+ }
+ break;
+
+ case SACENC_TIME_ALIGNMENT:
+ if ((INT)value < -32768 || (INT)value > 32767) {
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ hMp4SpaceEnc->user.timeAlignment = value;
+ break;
+
+ case SACENC_INDEPENDENCY_COUNT:
+ hMp4SpaceEnc->independencyCount = value;
+ break;
+
+ case SACENC_INDEPENDENCY_FACTOR:
+ hMp4SpaceEnc->user.independencyFactor = value;
+ break;
+
+ default:
+ error = SACENC_UNSUPPORTED_PARAMETER;
+ break;
+ } /* switch(param) */
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR FDK_sacenc_getLibInfo(LIB_INFO *info) {
+ int i = 0;
+
+ if (info == NULL) {
+ return SACENC_INVALID_HANDLE;
+ }
+
+ FDK_toolsGetLibInfo(info);
+
+ /* search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) {
+ return SACENC_INIT_ERROR;
+ }
+
+ info[i].module_id = FDK_MPSENC;
+ info[i].build_date = SACENC_LIB_BUILD_DATE;
+ info[i].build_time = SACENC_LIB_BUILD_TIME;
+ info[i].title = SACENC_LIB_TITLE;
+ info[i].version = LIB_VERSION(SACENC_LIB_VL0, SACENC_LIB_VL1, SACENC_LIB_VL2);
+ LIB_VERSION_STRING(&info[i]);
+
+ /* Capability flags */
+ info[i].flags = 0;
+ /* End of flags */
+
+ return SACENC_OK;
+}
+
+static DECORRCONFIG mp4SpaceEnc_GetDecorrConfig(
+ const MP4SPACEENC_MODE encMode) {
+ DECORRCONFIG decorrConfig = DECORR_INVALID;
+
+ /* set decorrConfig dependent on tree mode */
+ switch (encMode) {
+ case SACENC_212:
+ decorrConfig = DECORR_QMFSPLIT0;
+ break;
+ case SACENC_INVALID_MODE:
+ default:
+ decorrConfig = DECORR_INVALID;
+ }
+ return decorrConfig;
+}
+
+static FDK_SACENC_ERROR mp4SpaceEnc_InitNumParamBands(
+ HANDLE_MP4SPACE_ENCODER hEnc, const MP4SPACEENC_BANDS_CONFIG nParamBands) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ /* Set/Check nParamBands */
+ int k = 0;
+ const int n = sizeof(pValidBands_Ld) / sizeof(UCHAR);
+ const UCHAR *pBands = pValidBands_Ld;
+
+ while (k < n && pBands[k] != (UCHAR)nParamBands) ++k;
+ if (k == n) {
+ hEnc->nParamBands = SACENC_BANDS_INVALID;
+ } else {
+ hEnc->nParamBands = nParamBands;
+ }
+ return error;
+}
diff --git a/fdk-aac/libSACenc/src/sacenc_nlc_enc.cpp b/fdk-aac/libSACenc/src/sacenc_nlc_enc.cpp
new file mode 100644
index 0000000..0ba6cc9
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_nlc_enc.cpp
@@ -0,0 +1,1442 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Karsten Linzmeier
+
+ Description: Noiseless Coding
+ Huffman encoder
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_nlc_enc.h"
+
+#include "genericStds.h"
+#include "fixpoint_math.h"
+
+#include "sacenc_const.h"
+#include "sacenc_huff_tab.h"
+#include "sacenc_paramextract.h"
+
+/* Defines *******************************************************************/
+#define PAIR_SHIFT 4
+#define PAIR_MASK 0xf
+
+#define PBC_MIN_BANDS 5
+
+typedef enum {
+ BACKWARDS = 0x0,
+ FORWARDS = 0x1
+
+} DIRECTION;
+
+typedef enum {
+ DIFF_FREQ = 0x0,
+ DIFF_TIME = 0x1
+
+} DIFF_TYPE;
+
+typedef enum {
+ HUFF_1D = 0x0,
+ HUFF_2D = 0x1
+
+} CODING_SCHEME;
+
+typedef enum {
+ FREQ_PAIR = 0x0,
+ TIME_PAIR = 0x1
+
+} PAIRING;
+
+/* Data Types ****************************************************************/
+
+/* Constants *****************************************************************/
+static const UCHAR lavHuffVal[4] = {0, 2, 6, 7};
+static const UCHAR lavHuffLen[4] = {1, 2, 3, 3};
+
+static const UCHAR lav_step_CLD[] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3};
+static const UCHAR lav_step_ICC[] = {0, 0, 1, 1, 2, 2, 3, 3};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static void split_lsb(const SHORT *const in_data, SHORT offset,
+ const INT num_val, SHORT *const out_data_lsb,
+ SHORT *const out_data_msb) {
+ int i;
+
+ for (i = 0; i < num_val; i++) {
+ SHORT val = in_data[i] + offset;
+ if (out_data_lsb != NULL) out_data_lsb[i] = val & 0x0001;
+ if (out_data_msb != NULL) out_data_msb[i] = val >> 1;
+ }
+}
+
+static void apply_lsb_coding(HANDLE_FDK_BITSTREAM strm,
+ const SHORT *const in_data_lsb, const UINT num_lsb,
+ const INT num_val) {
+ int i;
+
+ for (i = 0; i < num_val; i++) {
+ FDKwriteBits(strm, in_data_lsb[i], num_lsb);
+ }
+}
+
+static void calc_diff_freq(const SHORT *const in_data, SHORT *const out_data,
+ const INT num_val) {
+ int i;
+ out_data[0] = in_data[0];
+
+ for (i = 1; i < num_val; i++) {
+ out_data[i] = in_data[i] - in_data[i - 1];
+ }
+}
+
+static void calc_diff_time(const SHORT *const in_data,
+ const SHORT *const prev_data, SHORT *const out_data,
+ const INT num_val) {
+ int i;
+ out_data[0] = in_data[0];
+ out_data[1] = prev_data[0];
+
+ for (i = 0; i < num_val; i++) {
+ out_data[i + 2] = in_data[i] - prev_data[i];
+ }
+}
+
+static INT sym_check(SHORT data[2], const INT lav, SHORT *const pSym_bits) {
+ UCHAR symBits = 0;
+ int sum_val = data[0] + data[1];
+ int diff_val = data[0] - data[1];
+ int num_sbits = 0;
+
+ if (sum_val != 0) {
+ int sum_neg = (sum_val < 0) ? 1 : 0;
+ if (sum_neg) {
+ sum_val = -sum_val;
+ diff_val = -diff_val;
+ }
+ symBits = (symBits << 1) | sum_neg;
+ num_sbits++;
+ }
+
+ if (diff_val != 0) {
+ int diff_neg = (diff_val < 0) ? 1 : 0;
+ if (diff_neg) {
+ diff_val = -diff_val;
+ }
+ symBits = (symBits << 1) | diff_neg;
+ num_sbits++;
+ }
+
+ if (pSym_bits != NULL) {
+ *pSym_bits = symBits;
+ }
+
+ if (sum_val % 2) {
+ data[0] = lav - sum_val / 2;
+ data[1] = lav - diff_val / 2;
+ } else {
+ data[0] = sum_val / 2;
+ data[1] = diff_val / 2;
+ }
+
+ return num_sbits;
+}
+
+static INT ilog2(UINT i) {
+ int l = 0;
+
+ if (i) i--;
+ while (i > 0) {
+ i >>= 1;
+ l++;
+ }
+
+ return l;
+}
+
+static SHORT calc_pcm_bits(const SHORT num_val, const SHORT num_levels) {
+ SHORT num_complete_chunks = 0, rest_chunk_size = 0;
+ SHORT max_grp_len = 0, bits_pcm = 0;
+ int chunk_levels, i;
+
+ switch (num_levels) {
+ case 3:
+ max_grp_len = 5;
+ break;
+ case 6:
+ max_grp_len = 5;
+ break;
+ case 7:
+ max_grp_len = 6;
+ break;
+ case 11:
+ max_grp_len = 2;
+ break;
+ case 13:
+ max_grp_len = 4;
+ break;
+ case 19:
+ max_grp_len = 4;
+ break;
+ case 25:
+ max_grp_len = 3;
+ break;
+ case 51:
+ max_grp_len = 4;
+ break;
+ default:
+ max_grp_len = 1;
+ }
+
+ num_complete_chunks = num_val / max_grp_len;
+ rest_chunk_size = num_val % max_grp_len;
+
+ chunk_levels = 1;
+ for (i = 1; i <= max_grp_len; i++) {
+ chunk_levels *= num_levels;
+ }
+
+ bits_pcm = (SHORT)(ilog2(chunk_levels) * num_complete_chunks);
+ bits_pcm += (SHORT)(ilog2(num_levels) * rest_chunk_size);
+
+ return bits_pcm;
+}
+
+static void apply_pcm_coding(HANDLE_FDK_BITSTREAM strm,
+ const SHORT *const in_data_1,
+ const SHORT *const in_data_2, const SHORT offset,
+ const SHORT num_val, const SHORT num_levels) {
+ SHORT i = 0, j = 0, idx = 0;
+ SHORT max_grp_len = 0, grp_len = 0, next_val = 0;
+ int grp_val = 0, chunk_levels = 0;
+
+ SHORT pcm_chunk_size[7] = {0};
+
+ switch (num_levels) {
+ case 3:
+ max_grp_len = 5;
+ break;
+ case 5:
+ max_grp_len = 3;
+ break;
+ case 6:
+ max_grp_len = 5;
+ break;
+ case 7:
+ max_grp_len = 6;
+ break;
+ case 9:
+ max_grp_len = 5;
+ break;
+ case 11:
+ max_grp_len = 2;
+ break;
+ case 13:
+ max_grp_len = 4;
+ break;
+ case 19:
+ max_grp_len = 4;
+ break;
+ case 25:
+ max_grp_len = 3;
+ break;
+ case 51:
+ max_grp_len = 4;
+ break;
+ default:
+ max_grp_len = 1;
+ }
+
+ chunk_levels = 1;
+ for (i = 1; i <= max_grp_len; i++) {
+ chunk_levels *= num_levels;
+ pcm_chunk_size[i] = ilog2(chunk_levels);
+ }
+
+ for (i = 0; i < num_val; i += max_grp_len) {
+ grp_len = FDKmin(max_grp_len, num_val - i);
+ grp_val = 0;
+ for (j = 0; j < grp_len; j++) {
+ idx = i + j;
+ if (in_data_2 == NULL) {
+ next_val = in_data_1[idx];
+ } else if (in_data_1 == NULL) {
+ next_val = in_data_2[idx];
+ } else {
+ next_val = ((idx % 2) ? in_data_2[idx / 2] : in_data_1[idx / 2]);
+ }
+ next_val += offset;
+ grp_val = grp_val * num_levels + next_val;
+ }
+
+ FDKwriteBits(strm, grp_val, pcm_chunk_size[grp_len]);
+ }
+}
+
+static UINT huff_enc_1D(HANDLE_FDK_BITSTREAM strm, const DATA_TYPE data_type,
+ const INT dim1, SHORT *const in_data,
+ const SHORT num_val, const SHORT p0_flag) {
+ int i, offset = 0;
+ UINT huffBits = 0;
+
+ HUFF_ENTRY part0 = {0};
+ const HUFF_ENTRY *pHuffTab = NULL;
+
+ switch (data_type) {
+ case t_CLD:
+ pHuffTab = fdk_sacenc_huffCLDTab.h1D[dim1];
+ break;
+ case t_ICC:
+ pHuffTab = fdk_sacenc_huffICCTab.h1D[dim1];
+ break;
+ }
+
+ if (p0_flag) {
+ switch (data_type) {
+ case t_CLD:
+ part0 = fdk_sacenc_huffPart0Tab.cld[in_data[0]];
+ break;
+ case t_ICC:
+ part0 = fdk_sacenc_huffPart0Tab.icc[in_data[0]];
+ break;
+ }
+ huffBits += FDKwriteBits(strm, HUFF_VALUE(part0), HUFF_LENGTH(part0));
+ offset = 1;
+ }
+
+ for (i = offset; i < num_val; i++) {
+ int id_sign = 0;
+ int id = in_data[i];
+
+ if (id != 0) {
+ id_sign = 0;
+ if (id < 0) {
+ id = -id;
+ id_sign = 1;
+ }
+ }
+
+ huffBits +=
+ FDKwriteBits(strm, HUFF_VALUE(pHuffTab[id]), HUFF_LENGTH(pHuffTab[id]));
+
+ if (id != 0) {
+ huffBits += FDKwriteBits(strm, id_sign, 1);
+ }
+ } /* for i */
+
+ return huffBits;
+}
+
+static void getHuffEntry(const INT lav, const DATA_TYPE data_type, const INT i,
+ const SHORT tab_idx_2D[2], const SHORT in_data[][2],
+ HUFF_ENTRY *const pEntry, HUFF_ENTRY *const pEscape) {
+ const HUFF_CLD_TAB_2D *pCLD2dTab =
+ &fdk_sacenc_huffCLDTab.h2D[tab_idx_2D[0]][tab_idx_2D[1]];
+ const HUFF_ICC_TAB_2D *pICC2dTab =
+ &fdk_sacenc_huffICCTab.h2D[tab_idx_2D[0]][tab_idx_2D[1]];
+
+ switch (lav) {
+ case 1: {
+ const LAV1_2D *pLav1 = NULL;
+ switch (data_type) {
+ case t_CLD:
+ pLav1 = NULL;
+ break;
+ case t_ICC:
+ pLav1 = &pICC2dTab->lav1;
+ break;
+ }
+ if (pLav1 != NULL) {
+ *pEntry = pLav1->entry[in_data[i][0]][in_data[i][1]];
+ *pEscape = pLav1->escape;
+ }
+ } break;
+ case 3: {
+ const LAV3_2D *pLav3 = NULL;
+ switch (data_type) {
+ case t_CLD:
+ pLav3 = &pCLD2dTab->lav3;
+ break;
+ case t_ICC:
+ pLav3 = &pICC2dTab->lav3;
+ break;
+ }
+ if (pLav3 != NULL) {
+ *pEntry = pLav3->entry[in_data[i][0]][in_data[i][1]];
+ *pEscape = pLav3->escape;
+ }
+ } break;
+ case 5: {
+ const LAV5_2D *pLav5 = NULL;
+ switch (data_type) {
+ case t_CLD:
+ pLav5 = &pCLD2dTab->lav5;
+ break;
+ case t_ICC:
+ pLav5 = &pICC2dTab->lav5;
+ break;
+ }
+ if (pLav5 != NULL) {
+ *pEntry = pLav5->entry[in_data[i][0]][in_data[i][1]];
+ *pEscape = pLav5->escape;
+ }
+ } break;
+ case 7: {
+ const LAV7_2D *pLav7 = NULL;
+ switch (data_type) {
+ case t_CLD:
+ pLav7 = &pCLD2dTab->lav7;
+ break;
+ case t_ICC:
+ pLav7 = &pICC2dTab->lav7;
+ break;
+ }
+ if (pLav7 != NULL) {
+ *pEntry = pLav7->entry[in_data[i][0]][in_data[i][1]];
+ *pEscape = pLav7->escape;
+ }
+ } break;
+ case 9: {
+ const LAV9_2D *pLav9 = NULL;
+ switch (data_type) {
+ case t_CLD:
+ pLav9 = &pCLD2dTab->lav9;
+ break;
+ case t_ICC:
+ pLav9 = NULL;
+ break;
+ }
+ if (pLav9 != NULL) {
+ *pEntry = pLav9->entry[in_data[i][0]][in_data[i][1]];
+ *pEscape = pLav9->escape;
+ }
+ } break;
+ }
+}
+
+static UINT huff_enc_2D(HANDLE_FDK_BITSTREAM strm, const DATA_TYPE data_type,
+ SHORT tab_idx_2D[2], SHORT lav_idx, SHORT in_data[][2],
+ SHORT num_val, SHORT stride, SHORT *p0_data[2]) {
+ SHORT i = 0, lav = 0, num_sbits = 0, sym_bits = 0, escIdx = 0;
+ SHORT esc_data[2][MAXBANDS] = {{0}};
+
+ UINT huffBits = 0;
+
+ const HUFF_ENTRY *pHuffEntry = NULL;
+
+ switch (data_type) {
+ case t_CLD:
+ lav = 2 * lav_idx + 3; /* LAV */
+ pHuffEntry = fdk_sacenc_huffPart0Tab.cld;
+ break;
+ case t_ICC:
+ lav = 2 * lav_idx + 1; /* LAV */
+ pHuffEntry = fdk_sacenc_huffPart0Tab.icc;
+ break;
+ }
+
+ /* Partition 0 */
+ if (p0_data[0] != NULL) {
+ HUFF_ENTRY entry = pHuffEntry[*p0_data[0]];
+ huffBits += FDKwriteBits(strm, HUFF_VALUE(entry), HUFF_LENGTH(entry));
+ }
+ if (p0_data[1] != NULL) {
+ HUFF_ENTRY entry = pHuffEntry[*p0_data[1]];
+ huffBits += FDKwriteBits(strm, HUFF_VALUE(entry), HUFF_LENGTH(entry));
+ }
+
+ for (i = 0; i < num_val; i += stride) {
+ HUFF_ENTRY entry = {0};
+ HUFF_ENTRY escape = {0};
+
+ esc_data[0][escIdx] = in_data[i][0] + lav;
+ esc_data[1][escIdx] = in_data[i][1] + lav;
+
+ num_sbits = sym_check(in_data[i], lav, &sym_bits);
+
+ getHuffEntry(lav, data_type, i, tab_idx_2D, in_data, &entry, &escape);
+
+ huffBits += FDKwriteBits(strm, HUFF_VALUE(entry), HUFF_LENGTH(entry));
+
+ if ((HUFF_VALUE(entry) == HUFF_VALUE(escape)) &&
+ (HUFF_LENGTH(entry) == HUFF_LENGTH(escape))) {
+ escIdx++;
+ } else {
+ huffBits += FDKwriteBits(strm, sym_bits, num_sbits);
+ }
+ } /* for i */
+
+ if (escIdx > 0) {
+ huffBits += calc_pcm_bits(2 * escIdx, (2 * lav + 1));
+ if (strm != NULL) {
+ apply_pcm_coding(strm, esc_data[0], esc_data[1], 0 /*offset*/, 2 * escIdx,
+ (2 * lav + 1));
+ }
+ }
+
+ return huffBits;
+}
+
+static SCHAR get_next_lav_step(const INT lav, const DATA_TYPE data_type) {
+ SCHAR lav_step = 0;
+
+ switch (data_type) {
+ case t_CLD:
+ lav_step = (lav > 9) ? -1 : lav_step_CLD[lav];
+ break;
+ case t_ICC:
+ lav_step = (lav > 7) ? -1 : lav_step_ICC[lav];
+ break;
+ }
+
+ return lav_step;
+}
+
+static INT diff_type_offset(const DIFF_TYPE diff_type) {
+ int offset = 0;
+ switch (diff_type) {
+ case DIFF_FREQ:
+ offset = 0;
+ break;
+ case DIFF_TIME:
+ offset = 2;
+ break;
+ }
+ return offset;
+}
+
+static SHORT calc_huff_bits(SHORT *in_data_1, SHORT *in_data_2,
+ const DATA_TYPE data_type,
+ const DIFF_TYPE diff_type_1,
+ const DIFF_TYPE diff_type_2, const SHORT num_val,
+ SHORT *const lav_idx, SHORT *const cdg_scheme) {
+ SHORT tab_idx_2D[2][2] = {{0}};
+ SHORT tab_idx_1D[2] = {0};
+ SHORT df_rest_flag[2] = {0};
+ SHORT p0_flag[2] = {0};
+
+ SHORT pair_vec[MAXBANDS][2] = {{0}};
+
+ SHORT *p0_data_1[2] = {NULL};
+ SHORT *p0_data_2[2] = {NULL};
+
+ SHORT i = 0;
+ SHORT lav_fp[2] = {0};
+
+ SHORT bit_count_1D = 0;
+ SHORT bit_count_2D_freq = 0;
+ SHORT bit_count_min = 0;
+
+ SHORT num_val_1_short = 0;
+ SHORT num_val_2_short = 0;
+
+ SHORT *in_data_1_short = NULL;
+ SHORT *in_data_2_short = NULL;
+
+ /* 1D Huffman coding */
+ bit_count_1D = 1; /* HUFF_1D */
+
+ num_val_1_short = num_val;
+ num_val_2_short = num_val;
+
+ if (in_data_1 != NULL) {
+ in_data_1_short = in_data_1 + diff_type_offset(diff_type_1);
+ }
+ if (in_data_2 != NULL) {
+ in_data_2_short = in_data_2 + diff_type_offset(diff_type_2);
+ }
+
+ p0_flag[0] = (diff_type_1 == DIFF_FREQ);
+ p0_flag[1] = (diff_type_2 == DIFF_FREQ);
+
+ tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
+ tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
+
+ if (in_data_1 != NULL) {
+ bit_count_1D += huff_enc_1D(NULL, data_type, tab_idx_1D[0], in_data_1_short,
+ num_val_1_short, p0_flag[0]);
+ }
+ if (in_data_2 != NULL) {
+ bit_count_1D += huff_enc_1D(NULL, data_type, tab_idx_1D[1], in_data_2_short,
+ num_val_2_short, p0_flag[1]);
+ }
+
+ bit_count_min = bit_count_1D;
+ *cdg_scheme = HUFF_1D << PAIR_SHIFT;
+ lav_idx[0] = lav_idx[1] = -1;
+
+ /* Huffman 2D frequency pairs */
+ bit_count_2D_freq = 1; /* HUFF_2D */
+
+ num_val_1_short = num_val;
+ num_val_2_short = num_val;
+
+ if (in_data_1 != NULL) {
+ in_data_1_short = in_data_1 + diff_type_offset(diff_type_1);
+ }
+ if (in_data_2 != NULL) {
+ in_data_2_short = in_data_2 + diff_type_offset(diff_type_2);
+ }
+
+ lav_fp[0] = lav_fp[1] = 0;
+
+ p0_data_1[0] = NULL;
+ p0_data_1[1] = NULL;
+ p0_data_2[0] = NULL;
+ p0_data_2[1] = NULL;
+
+ if (in_data_1 != NULL) {
+ if (diff_type_1 == DIFF_FREQ) {
+ p0_data_1[0] = &in_data_1[0];
+ p0_data_1[1] = NULL;
+
+ num_val_1_short -= 1;
+ in_data_1_short += 1;
+ }
+
+ df_rest_flag[0] = num_val_1_short % 2;
+
+ if (df_rest_flag[0]) num_val_1_short -= 1;
+
+ for (i = 0; i < num_val_1_short - 1; i += 2) {
+ pair_vec[i][0] = in_data_1_short[i];
+ pair_vec[i][1] = in_data_1_short[i + 1];
+
+ lav_fp[0] = FDKmax(lav_fp[0], fAbs(pair_vec[i][0]));
+ lav_fp[0] = FDKmax(lav_fp[0], fAbs(pair_vec[i][1]));
+ }
+
+ tab_idx_2D[0][0] = (diff_type_1 == DIFF_TIME) ? 1 : 0;
+ tab_idx_2D[0][1] = 0;
+
+ tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
+
+ lav_fp[0] = get_next_lav_step(lav_fp[0], data_type);
+
+ if (lav_fp[0] != -1) bit_count_2D_freq += lavHuffLen[lav_fp[0]];
+ }
+
+ if (in_data_2 != NULL) {
+ if (diff_type_2 == DIFF_FREQ) {
+ p0_data_2[0] = NULL;
+ p0_data_2[1] = &in_data_2[0];
+
+ num_val_2_short -= 1;
+ in_data_2_short += 1;
+ }
+
+ df_rest_flag[1] = num_val_2_short % 2;
+
+ if (df_rest_flag[1]) num_val_2_short -= 1;
+
+ for (i = 0; i < num_val_2_short - 1; i += 2) {
+ pair_vec[i + 1][0] = in_data_2_short[i];
+ pair_vec[i + 1][1] = in_data_2_short[i + 1];
+
+ lav_fp[1] = FDKmax(lav_fp[1], fAbs(pair_vec[i + 1][0]));
+ lav_fp[1] = FDKmax(lav_fp[1], fAbs(pair_vec[i + 1][1]));
+ }
+
+ tab_idx_2D[1][0] = (diff_type_2 == DIFF_TIME) ? 1 : 0;
+ tab_idx_2D[1][1] = 0;
+
+ tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
+
+ lav_fp[1] = get_next_lav_step(lav_fp[1], data_type);
+
+ if (lav_fp[1] != -1) bit_count_2D_freq += lavHuffLen[lav_fp[1]];
+ }
+
+ if ((lav_fp[0] != -1) && (lav_fp[1] != -1)) {
+ if (in_data_1 != NULL) {
+ bit_count_2D_freq +=
+ huff_enc_2D(NULL, data_type, tab_idx_2D[0], lav_fp[0], pair_vec,
+ num_val_1_short, 2, p0_data_1);
+ }
+ if (in_data_2 != NULL) {
+ bit_count_2D_freq +=
+ huff_enc_2D(NULL, data_type, tab_idx_2D[1], lav_fp[1], pair_vec + 1,
+ num_val_2_short, 2, p0_data_2);
+ }
+ if (in_data_1 != NULL) {
+ if (df_rest_flag[0])
+ bit_count_2D_freq +=
+ huff_enc_1D(NULL, data_type, tab_idx_1D[0],
+ in_data_1_short + num_val_1_short, 1, 0);
+ }
+ if (in_data_2 != NULL) {
+ if (df_rest_flag[1])
+ bit_count_2D_freq +=
+ huff_enc_1D(NULL, data_type, tab_idx_1D[1],
+ in_data_2_short + num_val_2_short, 1, 0);
+ }
+
+ if (bit_count_2D_freq < bit_count_min) {
+ bit_count_min = bit_count_2D_freq;
+ *cdg_scheme = HUFF_2D << PAIR_SHIFT | FREQ_PAIR;
+ lav_idx[0] = lav_fp[0];
+ lav_idx[1] = lav_fp[1];
+ }
+ }
+
+ return bit_count_min;
+}
+
+static void apply_huff_coding(HANDLE_FDK_BITSTREAM strm, SHORT *const in_data_1,
+ SHORT *const in_data_2, const DATA_TYPE data_type,
+ const DIFF_TYPE diff_type_1,
+ const DIFF_TYPE diff_type_2, const SHORT num_val,
+ const SHORT *const lav_idx,
+ const SHORT cdg_scheme) {
+ SHORT tab_idx_2D[2][2] = {{0}};
+ SHORT tab_idx_1D[2] = {0};
+ SHORT df_rest_flag[2] = {0};
+ SHORT p0_flag[2] = {0};
+
+ SHORT pair_vec[MAXBANDS][2] = {{0}};
+
+ SHORT *p0_data_1[2] = {NULL};
+ SHORT *p0_data_2[2] = {NULL};
+
+ SHORT i = 0;
+
+ SHORT num_val_1_short = num_val;
+ SHORT num_val_2_short = num_val;
+
+ SHORT *in_data_1_short = NULL;
+ SHORT *in_data_2_short = NULL;
+
+ /* Offset */
+ if (in_data_1 != NULL) {
+ in_data_1_short = in_data_1 + diff_type_offset(diff_type_1);
+ }
+ if (in_data_2 != NULL) {
+ in_data_2_short = in_data_2 + diff_type_offset(diff_type_2);
+ }
+
+ /* Signalize coding scheme */
+ FDKwriteBits(strm, cdg_scheme >> PAIR_SHIFT, 1);
+
+ switch (cdg_scheme >> PAIR_SHIFT) {
+ case HUFF_1D:
+
+ p0_flag[0] = (diff_type_1 == DIFF_FREQ);
+ p0_flag[1] = (diff_type_2 == DIFF_FREQ);
+
+ tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
+ tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
+
+ if (in_data_1 != NULL) {
+ huff_enc_1D(strm, data_type, tab_idx_1D[0], in_data_1_short,
+ num_val_1_short, p0_flag[0]);
+ }
+ if (in_data_2 != NULL) {
+ huff_enc_1D(strm, data_type, tab_idx_1D[1], in_data_2_short,
+ num_val_2_short, p0_flag[1]);
+ }
+ break; /* HUFF_1D */
+
+ case HUFF_2D:
+
+ switch (cdg_scheme & PAIR_MASK) {
+ case FREQ_PAIR:
+
+ if (in_data_1 != NULL) {
+ if (diff_type_1 == DIFF_FREQ) {
+ p0_data_1[0] = &in_data_1[0];
+ p0_data_1[1] = NULL;
+
+ num_val_1_short -= 1;
+ in_data_1_short += 1;
+ }
+
+ df_rest_flag[0] = num_val_1_short % 2;
+
+ if (df_rest_flag[0]) num_val_1_short -= 1;
+
+ for (i = 0; i < num_val_1_short - 1; i += 2) {
+ pair_vec[i][0] = in_data_1_short[i];
+ pair_vec[i][1] = in_data_1_short[i + 1];
+ }
+
+ tab_idx_2D[0][0] = (diff_type_1 == DIFF_TIME) ? 1 : 0;
+ tab_idx_2D[0][1] = 0;
+
+ tab_idx_1D[0] = (diff_type_1 == DIFF_FREQ) ? 0 : 1;
+ } /* if( in_data_1 != NULL ) */
+
+ if (in_data_2 != NULL) {
+ if (diff_type_2 == DIFF_FREQ) {
+ p0_data_2[0] = NULL;
+ p0_data_2[1] = &in_data_2[0];
+
+ num_val_2_short -= 1;
+ in_data_2_short += 1;
+ }
+
+ df_rest_flag[1] = num_val_2_short % 2;
+
+ if (df_rest_flag[1]) num_val_2_short -= 1;
+
+ for (i = 0; i < num_val_2_short - 1; i += 2) {
+ pair_vec[i + 1][0] = in_data_2_short[i];
+ pair_vec[i + 1][1] = in_data_2_short[i + 1];
+ }
+
+ tab_idx_2D[1][0] = (diff_type_2 == DIFF_TIME) ? 1 : 0;
+ tab_idx_2D[1][1] = 0;
+
+ tab_idx_1D[1] = (diff_type_2 == DIFF_FREQ) ? 0 : 1;
+ } /* if( in_data_2 != NULL ) */
+
+ if (in_data_1 != NULL) {
+ FDKwriteBits(strm, lavHuffVal[lav_idx[0]], lavHuffLen[lav_idx[0]]);
+ huff_enc_2D(strm, data_type, tab_idx_2D[0], lav_idx[0], pair_vec,
+ num_val_1_short, 2, p0_data_1);
+ if (df_rest_flag[0]) {
+ huff_enc_1D(strm, data_type, tab_idx_1D[0],
+ in_data_1_short + num_val_1_short, 1, 0);
+ }
+ }
+ if (in_data_2 != NULL) {
+ FDKwriteBits(strm, lavHuffVal[lav_idx[1]], lavHuffLen[lav_idx[1]]);
+ huff_enc_2D(strm, data_type, tab_idx_2D[1], lav_idx[1],
+ pair_vec + 1, num_val_2_short, 2, p0_data_2);
+ if (df_rest_flag[1]) {
+ huff_enc_1D(strm, data_type, tab_idx_1D[1],
+ in_data_2_short + num_val_2_short, 1, 0);
+ }
+ }
+ break; /* FREQ_PAIR */
+
+ case TIME_PAIR:
+
+ if ((diff_type_1 == DIFF_FREQ) || (diff_type_2 == DIFF_FREQ)) {
+ p0_data_1[0] = &in_data_1[0];
+ p0_data_1[1] = &in_data_2[0];
+
+ in_data_1_short += 1;
+ in_data_2_short += 1;
+
+ num_val_1_short -= 1;
+ }
+
+ for (i = 0; i < num_val_1_short; i++) {
+ pair_vec[i][0] = in_data_1_short[i];
+ pair_vec[i][1] = in_data_2_short[i];
+ }
+
+ tab_idx_2D[0][0] =
+ ((diff_type_1 == DIFF_TIME) || (diff_type_2 == DIFF_TIME)) ? 1
+ : 0;
+ tab_idx_2D[0][1] = 1;
+
+ FDKwriteBits(strm, lavHuffVal[lav_idx[0]], lavHuffLen[lav_idx[0]]);
+
+ huff_enc_2D(strm, data_type, tab_idx_2D[0], lav_idx[0], pair_vec,
+ num_val_1_short, 1, p0_data_1);
+
+ break; /* TIME_PAIR */
+ } /* switch( cdg_scheme & PAIR_MASK ) */
+
+ break; /* HUFF_2D */
+
+ default:
+ break;
+ } /* switch( cdg_scheme >> PAIR_SHIFT ) */
+}
+
+INT fdk_sacenc_ecDataPairEnc(HANDLE_FDK_BITSTREAM strm,
+ SHORT aaInData[][MAXBANDS],
+ SHORT aHistory[MAXBANDS],
+ const DATA_TYPE data_type, const INT setIdx,
+ const INT startBand, const INT dataBands,
+ const INT coarse_flag,
+ const INT independency_flag) {
+ SHORT reset = 0, pb = 0;
+ SHORT quant_levels = 0, quant_offset = 0, num_pcm_val = 0;
+
+ SHORT splitLsb_flag = 0;
+ SHORT pcmCoding_flag = 0;
+
+ SHORT allowDiffTimeBack_flag = !independency_flag || (setIdx > 0);
+
+ SHORT num_lsb_bits = -1;
+ SHORT num_pcm_bits = -1;
+
+ SHORT quant_data_lsb[2][MAXBANDS];
+ SHORT quant_data_msb[2][MAXBANDS];
+
+ SHORT quant_data_hist_lsb[MAXBANDS];
+ SHORT quant_data_hist_msb[MAXBANDS];
+
+ SHORT data_diff_freq[2][MAXBANDS];
+ SHORT data_diff_time[2][MAXBANDS + 2];
+
+ SHORT *p_quant_data_msb[2];
+ SHORT *p_quant_data_hist_msb = NULL;
+
+ SHORT min_bits_all = 0;
+ SHORT min_found = 0;
+
+ SHORT min_bits_df_df = -1;
+ SHORT min_bits_df_dt = -1;
+ SHORT min_bits_dtbw_df = -1;
+ SHORT min_bits_dt_dt = -1;
+
+ SHORT lav_df_df[2] = {-1, -1};
+ SHORT lav_df_dt[2] = {-1, -1};
+ SHORT lav_dtbw_df[2] = {-1, -1};
+ SHORT lav_dt_dt[2] = {-1, -1};
+
+ SHORT coding_scheme_df_df = 0;
+ SHORT coding_scheme_df_dt = 0;
+ SHORT coding_scheme_dtbw_df = 0;
+ SHORT coding_scheme_dt_dt = 0;
+
+ switch (data_type) {
+ case t_CLD:
+ if (coarse_flag) {
+ splitLsb_flag = 0;
+ quant_levels = 15;
+ quant_offset = 7;
+ } else {
+ splitLsb_flag = 0;
+ quant_levels = 31;
+ quant_offset = 15;
+ }
+ break;
+ case t_ICC:
+ if (coarse_flag) {
+ splitLsb_flag = 0;
+ quant_levels = 4;
+ quant_offset = 0;
+ } else {
+ splitLsb_flag = 0;
+ quant_levels = 8;
+ quant_offset = 0;
+ }
+ break;
+ } /* switch( data_type ) */
+
+ /* Split off LSB */
+ if (splitLsb_flag) {
+ split_lsb(aaInData[setIdx] + startBand, quant_offset, dataBands,
+ quant_data_lsb[0], quant_data_msb[0]);
+
+ split_lsb(aaInData[setIdx + 1] + startBand, quant_offset, dataBands,
+ quant_data_lsb[1], quant_data_msb[1]);
+
+ p_quant_data_msb[0] = quant_data_msb[0];
+ p_quant_data_msb[1] = quant_data_msb[1];
+
+ num_lsb_bits = 2 * dataBands;
+ } else if (quant_offset != 0) {
+ for (pb = 0; pb < dataBands; pb++) {
+ quant_data_msb[0][pb] = aaInData[setIdx][startBand + pb] + quant_offset;
+ quant_data_msb[1][pb] =
+ aaInData[setIdx + 1][startBand + pb] + quant_offset;
+ }
+
+ p_quant_data_msb[0] = quant_data_msb[0];
+ p_quant_data_msb[1] = quant_data_msb[1];
+
+ num_lsb_bits = 0;
+ } else {
+ p_quant_data_msb[0] = aaInData[setIdx] + startBand;
+ p_quant_data_msb[1] = aaInData[setIdx + 1] + startBand;
+
+ num_lsb_bits = 0;
+ }
+
+ if (allowDiffTimeBack_flag) {
+ if (splitLsb_flag) {
+ split_lsb(aHistory + startBand, quant_offset, dataBands,
+ quant_data_hist_lsb, quant_data_hist_msb);
+
+ p_quant_data_hist_msb = quant_data_hist_msb;
+ } else if (quant_offset != 0) {
+ for (pb = 0; pb < dataBands; pb++) {
+ quant_data_hist_msb[pb] = aHistory[startBand + pb] + quant_offset;
+ }
+ p_quant_data_hist_msb = quant_data_hist_msb;
+ } else {
+ p_quant_data_hist_msb = aHistory + startBand;
+ }
+ }
+
+ /* Calculate frequency differences */
+ calc_diff_freq(p_quant_data_msb[0], data_diff_freq[0], dataBands);
+
+ calc_diff_freq(p_quant_data_msb[1], data_diff_freq[1], dataBands);
+
+ /* Calculate time differences */
+ if (allowDiffTimeBack_flag) {
+ calc_diff_time(p_quant_data_msb[0], p_quant_data_hist_msb,
+ data_diff_time[0], dataBands);
+ }
+
+ calc_diff_time(p_quant_data_msb[1], p_quant_data_msb[0], data_diff_time[1],
+ dataBands);
+
+ /* Calculate coding scheme with minumum bit consumption */
+
+ /**********************************************************/
+ num_pcm_bits = calc_pcm_bits(2 * dataBands, quant_levels);
+ num_pcm_val = 2 * dataBands;
+
+ /**********************************************************/
+
+ min_bits_all = num_pcm_bits;
+
+ /**********************************************************/
+ /**********************************************************/
+
+ /**********************************************************/
+ min_bits_df_df =
+ calc_huff_bits(data_diff_freq[0], data_diff_freq[1], data_type, DIFF_FREQ,
+ DIFF_FREQ, dataBands, lav_df_df, &coding_scheme_df_df);
+
+ min_bits_df_df += 2;
+
+ min_bits_df_df += num_lsb_bits;
+
+ if (min_bits_df_df < min_bits_all) {
+ min_bits_all = min_bits_df_df;
+ }
+ /**********************************************************/
+
+ /**********************************************************/
+ min_bits_df_dt =
+ calc_huff_bits(data_diff_freq[0], data_diff_time[1], data_type, DIFF_FREQ,
+ DIFF_TIME, dataBands, lav_df_dt, &coding_scheme_df_dt);
+
+ min_bits_df_dt += 2;
+
+ min_bits_df_dt += num_lsb_bits;
+
+ if (min_bits_df_dt < min_bits_all) {
+ min_bits_all = min_bits_df_dt;
+ }
+ /**********************************************************/
+
+ /**********************************************************/
+ /**********************************************************/
+
+ if (allowDiffTimeBack_flag) {
+ /**********************************************************/
+ min_bits_dtbw_df = calc_huff_bits(
+ data_diff_time[0], data_diff_freq[1], data_type, DIFF_TIME, DIFF_FREQ,
+ dataBands, lav_dtbw_df, &coding_scheme_dtbw_df);
+
+ min_bits_dtbw_df += 2;
+
+ min_bits_dtbw_df += num_lsb_bits;
+
+ if (min_bits_dtbw_df < min_bits_all) {
+ min_bits_all = min_bits_dtbw_df;
+ }
+ /**********************************************************/
+
+ /**********************************************************/
+ min_bits_dt_dt = calc_huff_bits(data_diff_time[0], data_diff_time[1],
+ data_type, DIFF_TIME, DIFF_TIME, dataBands,
+ lav_dt_dt, &coding_scheme_dt_dt);
+
+ min_bits_dt_dt += 2;
+
+ min_bits_dt_dt += num_lsb_bits;
+
+ if (min_bits_dt_dt < min_bits_all) {
+ min_bits_all = min_bits_dt_dt;
+ }
+ /**********************************************************/
+
+ } /* if( allowDiffTimeBack_flag ) */
+
+ /***************************/
+ /* Start actual coding now */
+ /***************************/
+
+ /* PCM or Diff/Huff Coding? */
+ pcmCoding_flag = (min_bits_all == num_pcm_bits);
+
+ FDKwriteBits(strm, pcmCoding_flag, 1);
+
+ if (pcmCoding_flag) {
+ /* Grouped PCM Coding */
+ apply_pcm_coding(strm, aaInData[setIdx] + startBand,
+ aaInData[setIdx + 1] + startBand, quant_offset,
+ num_pcm_val, quant_levels);
+ } else {
+ /* Diff/Huff Coding */
+
+ min_found = 0;
+
+ /*******************************************/
+ if (min_bits_all == min_bits_df_df) {
+ FDKwriteBits(strm, DIFF_FREQ, 1);
+ FDKwriteBits(strm, DIFF_FREQ, 1);
+
+ apply_huff_coding(strm, data_diff_freq[0], data_diff_freq[1], data_type,
+ DIFF_FREQ, DIFF_FREQ, dataBands, lav_df_df,
+ coding_scheme_df_df);
+
+ min_found = 1;
+ }
+ /*******************************************/
+
+ /*******************************************/
+ if (!min_found && (min_bits_all == min_bits_df_dt)) {
+ FDKwriteBits(strm, DIFF_FREQ, 1);
+ FDKwriteBits(strm, DIFF_TIME, 1);
+
+ apply_huff_coding(strm, data_diff_freq[0], data_diff_time[1], data_type,
+ DIFF_FREQ, DIFF_TIME, dataBands, lav_df_dt,
+ coding_scheme_df_dt);
+
+ min_found = 1;
+ }
+ /*******************************************/
+
+ /*******************************************/
+ /*******************************************/
+
+ if (allowDiffTimeBack_flag) {
+ /*******************************************/
+ if (!min_found && (min_bits_all == min_bits_dtbw_df)) {
+ FDKwriteBits(strm, DIFF_TIME, 1);
+ FDKwriteBits(strm, DIFF_FREQ, 1);
+
+ apply_huff_coding(strm, data_diff_time[0], data_diff_freq[1], data_type,
+ DIFF_TIME, DIFF_FREQ, dataBands, lav_dtbw_df,
+ coding_scheme_dtbw_df);
+
+ min_found = 1;
+ }
+ /*******************************************/
+
+ /*******************************************/
+ if (!min_found && (min_bits_all == min_bits_dt_dt)) {
+ FDKwriteBits(strm, DIFF_TIME, 1);
+ FDKwriteBits(strm, DIFF_TIME, 1);
+
+ apply_huff_coding(strm, data_diff_time[0], data_diff_time[1], data_type,
+ DIFF_TIME, DIFF_TIME, dataBands, lav_dt_dt,
+ coding_scheme_dt_dt);
+ }
+ /*******************************************/
+
+ } /* if( allowDiffTimeBack_flag ) */
+
+ /* LSB coding */
+ if (splitLsb_flag) {
+ apply_lsb_coding(strm, quant_data_lsb[0], 1, dataBands);
+
+ apply_lsb_coding(strm, quant_data_lsb[1], 1, dataBands);
+ }
+
+ } /* Diff/Huff/LSB coding */
+
+ return reset;
+}
+
+INT fdk_sacenc_ecDataSingleEnc(HANDLE_FDK_BITSTREAM strm,
+ SHORT aaInData[][MAXBANDS],
+ SHORT aHistory[MAXBANDS],
+ const DATA_TYPE data_type, const INT setIdx,
+ const INT startBand, const INT dataBands,
+ const INT coarse_flag,
+ const INT independency_flag) {
+ SHORT reset = 0, pb = 0;
+ SHORT quant_levels = 0, quant_offset = 0, num_pcm_val = 0;
+
+ SHORT splitLsb_flag = 0;
+ SHORT pcmCoding_flag = 0;
+
+ SHORT allowDiffTimeBack_flag = !independency_flag || (setIdx > 0);
+
+ SHORT num_lsb_bits = -1;
+ SHORT num_pcm_bits = -1;
+
+ SHORT quant_data_lsb[MAXBANDS];
+ SHORT quant_data_msb[MAXBANDS];
+
+ SHORT quant_data_hist_lsb[MAXBANDS];
+ SHORT quant_data_hist_msb[MAXBANDS];
+
+ SHORT data_diff_freq[MAXBANDS];
+ SHORT data_diff_time[MAXBANDS + 2];
+
+ SHORT *p_quant_data_msb;
+ SHORT *p_quant_data_hist_msb = NULL;
+
+ SHORT min_bits_all = 0;
+ SHORT min_found = 0;
+
+ SHORT min_bits_df = -1;
+ SHORT min_bits_dt = -1;
+
+ SHORT lav_df[2] = {-1, -1};
+ SHORT lav_dt[2] = {-1, -1};
+
+ SHORT coding_scheme_df = 0;
+ SHORT coding_scheme_dt = 0;
+
+ switch (data_type) {
+ case t_CLD:
+ if (coarse_flag) {
+ splitLsb_flag = 0;
+ quant_levels = 15;
+ quant_offset = 7;
+ } else {
+ splitLsb_flag = 0;
+ quant_levels = 31;
+ quant_offset = 15;
+ }
+ break;
+ case t_ICC:
+ if (coarse_flag) {
+ splitLsb_flag = 0;
+ quant_levels = 4;
+ quant_offset = 0;
+ } else {
+ splitLsb_flag = 0;
+ quant_levels = 8;
+ quant_offset = 0;
+ }
+ break;
+ } /* switch( data_type ) */
+
+ /* Split off LSB */
+ if (splitLsb_flag) {
+ split_lsb(aaInData[setIdx] + startBand, quant_offset, dataBands,
+ quant_data_lsb, quant_data_msb);
+
+ p_quant_data_msb = quant_data_msb;
+ num_lsb_bits = dataBands;
+ } else if (quant_offset != 0) {
+ for (pb = 0; pb < dataBands; pb++) {
+ quant_data_msb[pb] = aaInData[setIdx][startBand + pb] + quant_offset;
+ }
+
+ p_quant_data_msb = quant_data_msb;
+ num_lsb_bits = 0;
+ } else {
+ p_quant_data_msb = aaInData[setIdx] + startBand;
+ num_lsb_bits = 0;
+ }
+
+ if (allowDiffTimeBack_flag) {
+ if (splitLsb_flag) {
+ split_lsb(aHistory + startBand, quant_offset, dataBands,
+ quant_data_hist_lsb, quant_data_hist_msb);
+
+ p_quant_data_hist_msb = quant_data_hist_msb;
+ } else if (quant_offset != 0) {
+ for (pb = 0; pb < dataBands; pb++) {
+ quant_data_hist_msb[pb] = aHistory[startBand + pb] + quant_offset;
+ }
+ p_quant_data_hist_msb = quant_data_hist_msb;
+ } else {
+ p_quant_data_hist_msb = aHistory + startBand;
+ }
+ }
+
+ /* Calculate frequency differences */
+ calc_diff_freq(p_quant_data_msb, data_diff_freq, dataBands);
+
+ /* Calculate time differences */
+ if (allowDiffTimeBack_flag) {
+ calc_diff_time(p_quant_data_msb, p_quant_data_hist_msb, data_diff_time,
+ dataBands);
+ }
+
+ /* Calculate coding scheme with minumum bit consumption */
+
+ /**********************************************************/
+ num_pcm_bits = calc_pcm_bits(dataBands, quant_levels);
+ num_pcm_val = dataBands;
+
+ /**********************************************************/
+
+ min_bits_all = num_pcm_bits;
+
+ /**********************************************************/
+ /**********************************************************/
+
+ /**********************************************************/
+ min_bits_df = calc_huff_bits(data_diff_freq, NULL, data_type, DIFF_FREQ,
+ DIFF_FREQ, dataBands, lav_df, &coding_scheme_df);
+
+ if (allowDiffTimeBack_flag) min_bits_df += 1;
+
+ min_bits_df += num_lsb_bits;
+
+ if (min_bits_df < min_bits_all) {
+ min_bits_all = min_bits_df;
+ }
+ /**********************************************************/
+
+ /**********************************************************/
+ if (allowDiffTimeBack_flag) {
+ min_bits_dt =
+ calc_huff_bits(data_diff_time, NULL, data_type, DIFF_TIME, DIFF_TIME,
+ dataBands, lav_dt, &coding_scheme_dt);
+
+ min_bits_dt += 1;
+ min_bits_dt += num_lsb_bits;
+
+ if (min_bits_dt < min_bits_all) {
+ min_bits_all = min_bits_dt;
+ }
+ } /* if( allowDiffTimeBack_flag ) */
+
+ /***************************/
+ /* Start actual coding now */
+ /***************************/
+
+ /* PCM or Diff/Huff Coding? */
+ pcmCoding_flag = (min_bits_all == num_pcm_bits);
+
+ FDKwriteBits(strm, pcmCoding_flag, 1);
+
+ if (pcmCoding_flag) {
+ /* Grouped PCM Coding */
+ apply_pcm_coding(strm, aaInData[setIdx] + startBand, NULL, quant_offset,
+ num_pcm_val, quant_levels);
+ } else {
+ /* Diff/Huff Coding */
+
+ min_found = 0;
+
+ /*******************************************/
+ if (min_bits_all == min_bits_df) {
+ if (allowDiffTimeBack_flag) {
+ FDKwriteBits(strm, DIFF_FREQ, 1);
+ }
+
+ apply_huff_coding(strm, data_diff_freq, NULL, data_type, DIFF_FREQ,
+ DIFF_FREQ, dataBands, lav_df, coding_scheme_df);
+
+ min_found = 1;
+ } /* if( min_bits_all == min_bits_df ) */
+ /*******************************************/
+
+ /*******************************************/
+ if (allowDiffTimeBack_flag) {
+ /*******************************************/
+ if (!min_found && (min_bits_all == min_bits_dt)) {
+ FDKwriteBits(strm, DIFF_TIME, 1);
+
+ apply_huff_coding(strm, data_diff_time, NULL, data_type, DIFF_TIME,
+ DIFF_TIME, dataBands, lav_dt, coding_scheme_dt);
+ }
+ /*******************************************/
+
+ } /* if( allowDiffTimeBack_flag ) */
+
+ /* LSB coding */
+ if (splitLsb_flag) {
+ apply_lsb_coding(strm, quant_data_lsb, 1, dataBands);
+ }
+
+ } /* Diff/Huff/LSB coding */
+
+ return reset;
+}
diff --git a/fdk-aac/libSACenc/src/sacenc_nlc_enc.h b/fdk-aac/libSACenc/src/sacenc_nlc_enc.h
new file mode 100644
index 0000000..506b308
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_nlc_enc.h
@@ -0,0 +1,141 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Karsten Linzmeier
+
+ Description: Noiseless Coding
+ Huffman encoder
+
+*******************************************************************************/
+
+#ifndef SACENC_NLC_ENC_H
+#define SACENC_NLC_ENC_H
+
+/* Includes ******************************************************************/
+#include "sacenc_const.h"
+#include "FDK_bitstream.h"
+#include "sacenc_bitstream.h"
+
+/* Defines *******************************************************************/
+#define MAXBANDS MAX_NUM_BINS /* maximum number of frequency bands */
+
+/* Data Types ****************************************************************/
+typedef enum {
+ t_CLD,
+ t_ICC
+
+} DATA_TYPE;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+INT fdk_sacenc_ecDataPairEnc(HANDLE_FDK_BITSTREAM strm,
+ SHORT aaInData[][MAXBANDS],
+ SHORT aHistory[MAXBANDS],
+ const DATA_TYPE data_type, const INT setIdx,
+ const INT startBand, const INT dataBands,
+ const INT coarse_flag,
+ const INT independency_flag);
+
+INT fdk_sacenc_ecDataSingleEnc(HANDLE_FDK_BITSTREAM strm,
+ SHORT aaInData[][MAXBANDS],
+ SHORT aHistory[MAXBANDS],
+ const DATA_TYPE data_type, const INT setIdx,
+ const INT startBand, const INT dataBands,
+ const INT coarse_flag,
+ const INT independency_flag);
+
+#endif /* SACENC_NLC_ENC_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_onsetdetect.cpp b/fdk-aac/libSACenc/src/sacenc_onsetdetect.cpp
new file mode 100644
index 0000000..7e9aee1
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_onsetdetect.cpp
@@ -0,0 +1,381 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Detect Onset in current frame
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ Description of file contents
+ ******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_onsetdetect.h"
+#include "genericStds.h"
+#include "sacenc_vectorfunctions.h"
+
+/* Defines *******************************************************************/
+#define SPACE_ONSET_THRESHOLD (3.0)
+#define SPACE_ONSET_THRESHOLD_SF (3)
+#define SPACE_ONSET_THRESHOLD_SQUARE \
+ (FL2FXCONST_DBL((1.0 / (SPACE_ONSET_THRESHOLD * SPACE_ONSET_THRESHOLD)) * \
+ (float)(1 << SPACE_ONSET_THRESHOLD_SF)))
+
+/* Data Types ****************************************************************/
+struct ONSET_DETECT {
+ INT maxTimeSlots;
+ INT minTransientDistance;
+ INT avgEnergyDistance;
+ INT lowerBoundOnsetDetection;
+ INT upperBoundOnsetDetection;
+ FIXP_DBL *pEnergyHist__FDK;
+ SCHAR *pEnergyHistScale;
+ SCHAR avgEnergyDistanceScale;
+};
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Open(HANDLE_ONSET_DETECT *phOnset,
+ const UINT maxTimeSlots) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+ HANDLE_ONSET_DETECT hOnset = NULL;
+
+ if (NULL == phOnset) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Memory Allocation */
+ FDK_ALLOCATE_MEMORY_1D(hOnset, 1, struct ONSET_DETECT);
+ FDK_ALLOCATE_MEMORY_1D(hOnset->pEnergyHist__FDK, 16 + maxTimeSlots,
+ FIXP_DBL);
+ FDK_ALLOCATE_MEMORY_1D(hOnset->pEnergyHistScale, 16 + maxTimeSlots, SCHAR);
+
+ hOnset->maxTimeSlots = maxTimeSlots;
+ hOnset->minTransientDistance =
+ 8; /* minimum distance between detected transients */
+ hOnset->avgEnergyDistance = 16; /* average energy distance */
+
+ hOnset->avgEnergyDistanceScale = 4;
+ *phOnset = hOnset;
+ }
+ return error;
+
+bail:
+ fdk_sacenc_onsetDetect_Close(&hOnset);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Init(
+ HANDLE_ONSET_DETECT hOnset,
+ const ONSET_DETECT_CONFIG *const pOnsetDetectConfig, const UINT initFlags) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL == hOnset) || (pOnsetDetectConfig == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if ((pOnsetDetectConfig->maxTimeSlots > hOnset->maxTimeSlots) ||
+ (pOnsetDetectConfig->upperBoundOnsetDetection <
+ hOnset->lowerBoundOnsetDetection)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ hOnset->maxTimeSlots = pOnsetDetectConfig->maxTimeSlots;
+ hOnset->lowerBoundOnsetDetection =
+ pOnsetDetectConfig->lowerBoundOnsetDetection;
+ hOnset->upperBoundOnsetDetection =
+ pOnsetDetectConfig->upperBoundOnsetDetection;
+
+ hOnset->minTransientDistance =
+ 8; /* minimum distance between detected transients */
+ hOnset->avgEnergyDistance = 16; /* average energy distance */
+
+ hOnset->avgEnergyDistanceScale = 4;
+
+ /* Init / Reset */
+ if (initFlags) {
+ int i;
+ for (i = 0; i < hOnset->avgEnergyDistance + hOnset->maxTimeSlots; i++)
+ hOnset->pEnergyHistScale[i] = -(DFRACT_BITS - 3);
+
+ FDKmemset_flex(
+ hOnset->pEnergyHist__FDK,
+ FL2FXCONST_DBL(SACENC_FLOAT_EPSILON * (1 << (DFRACT_BITS - 3))),
+ hOnset->avgEnergyDistance + hOnset->maxTimeSlots);
+ }
+ }
+
+bail:
+ return error;
+}
+
+/**************************************************************************/
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Close(HANDLE_ONSET_DETECT *phOnset) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((NULL != phOnset) && (NULL != *phOnset)) {
+ if (NULL != (*phOnset)->pEnergyHist__FDK) {
+ FDKfree((*phOnset)->pEnergyHist__FDK);
+ }
+ (*phOnset)->pEnergyHist__FDK = NULL;
+
+ if (NULL != (*phOnset)->pEnergyHistScale) {
+ FDKfree((*phOnset)->pEnergyHistScale);
+ }
+ (*phOnset)->pEnergyHistScale = NULL;
+ FDKfree(*phOnset);
+ *phOnset = NULL;
+ }
+ return error;
+}
+
+/**************************************************************************/
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Update(HANDLE_ONSET_DETECT hOnset,
+ const INT timeSlots) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hOnset) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ if (timeSlots > hOnset->maxTimeSlots) {
+ error = SACENC_INVALID_CONFIG;
+ } else {
+ int i;
+ /* Shift old data */
+ for (i = 0; i < hOnset->avgEnergyDistance; i++) {
+ hOnset->pEnergyHist__FDK[i] = hOnset->pEnergyHist__FDK[i + timeSlots];
+ hOnset->pEnergyHistScale[i] = hOnset->pEnergyHistScale[i + timeSlots];
+ }
+
+ /* Clear for new data */
+ FDKmemset_flex(&hOnset->pEnergyHist__FDK[hOnset->avgEnergyDistance],
+ FL2FXCONST_DBL(SACENC_FLOAT_EPSILON), timeSlots);
+ }
+ }
+ return error;
+}
+
+/**************************************************************************/
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Apply(
+ HANDLE_ONSET_DETECT hOnset, const INT nTimeSlots, const INT nHybridBands,
+ FIXP_DPK *const *const ppHybridData__FDK, const INT hybridDataScale,
+ const INT prevPos, INT pTransientPos[MAX_NUM_TRANS]) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ C_ALLOC_SCRATCH_START(envs, FIXP_DBL, (16 + MAX_TIME_SLOTS))
+ FDKmemclear(envs, (16 + MAX_TIME_SLOTS) * sizeof(FIXP_DBL));
+
+ if ((hOnset == NULL) || (pTransientPos == NULL) ||
+ (ppHybridData__FDK == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i, ts, trCnt, currPos;
+
+ if ((nTimeSlots < 0) || (nTimeSlots > hOnset->maxTimeSlots) ||
+ (hOnset->lowerBoundOnsetDetection < -1) ||
+ (hOnset->upperBoundOnsetDetection > nHybridBands)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ const int lowerBoundOnsetDetection = hOnset->lowerBoundOnsetDetection;
+ const int upperBoundOnsetDetection = hOnset->upperBoundOnsetDetection;
+ const int M = hOnset->avgEnergyDistance;
+
+ {
+ SCHAR *envScale = hOnset->pEnergyHistScale;
+ FIXP_DBL *env = hOnset->pEnergyHist__FDK;
+ const FIXP_DBL threshold_square = SPACE_ONSET_THRESHOLD_SQUARE;
+
+ trCnt = 0;
+
+ /* reset transient array */
+ FDKmemset_flex(pTransientPos, -1, MAX_NUM_TRANS);
+
+ /* minimum transient distance of minTransDist QMF samples */
+ if (prevPos > 0) {
+ currPos = FDKmax(nTimeSlots,
+ prevPos - nTimeSlots + hOnset->minTransientDistance);
+ } else {
+ currPos = nTimeSlots;
+ }
+
+ /* get energy and scalefactor for each time slot */
+ int outScale;
+ int inScale = 3; /* scale factor determined empirically */
+ for (ts = 0; ts < nTimeSlots; ts++) {
+ env[M + ts] = sumUpCplxPow2(
+ &ppHybridData__FDK[ts][lowerBoundOnsetDetection + 1],
+ SUM_UP_DYNAMIC_SCALE, inScale, &outScale,
+ upperBoundOnsetDetection - lowerBoundOnsetDetection - 1);
+ envScale[M + ts] = outScale + (hybridDataScale << 1);
+ }
+
+ /* calculate common scale for all time slots */
+ SCHAR maxScale = -(DFRACT_BITS - 1);
+ for (i = 0; i < (nTimeSlots + M); i++) {
+ maxScale = fixMax(maxScale, envScale[i]);
+ }
+
+ /* apply common scale and store energy in temporary buffer */
+ for (i = 0; i < (nTimeSlots + M); i++) {
+ envs[i] = env[i] >> fixMin((maxScale - envScale[i]), (DFRACT_BITS - 1));
+ }
+
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+ for (i = 0; i < (nTimeSlots + M); i++) {
+ maxVal |= fAbs(envs[i]);
+ }
+
+ int s = fixMax(0, CntLeadingZeros(maxVal) - 1);
+
+ for (i = 0; i < (nTimeSlots + M); i++) {
+ envs[i] = envs[i] << s;
+ }
+
+ int currPosPrev = currPos;
+ FIXP_DBL p1, p2;
+ p2 = FL2FXCONST_DBL(0.0f);
+ for (; (currPos < (nTimeSlots << 1)) && (trCnt < MAX_NUM_TRANS);
+ currPos++) {
+ p1 = fMultDiv2(envs[currPos - nTimeSlots + M], threshold_square) >>
+ (SPACE_ONSET_THRESHOLD_SF - 1);
+
+ /* Calculate average of past M energy values */
+ if (currPosPrev == (currPos - 1)) {
+ /* remove last and add new element */
+ p2 -= (envs[currPosPrev - nTimeSlots] >>
+ (int)hOnset->avgEnergyDistanceScale);
+ p2 += (envs[currPos - nTimeSlots + M - 1] >>
+ (int)hOnset->avgEnergyDistanceScale);
+ } else {
+ /* calculate complete vector */
+ p2 = FL2FXCONST_DBL(0.0f);
+ for (ts = 0; ts < M; ts++) {
+ p2 += (envs[currPos - nTimeSlots + ts] >>
+ (int)hOnset->avgEnergyDistanceScale);
+ }
+ }
+ currPosPrev = currPos;
+
+ {
+ /* save position if transient found */
+ if (p1 > p2) {
+ pTransientPos[trCnt++] = currPos;
+ currPos += hOnset->minTransientDistance;
+ }
+ }
+ } /* for currPos */
+ }
+
+ } /* valid handle*/
+bail:
+
+ C_ALLOC_SCRATCH_END(envs, FIXP_DBL, (16 + MAX_TIME_SLOTS))
+
+ return error;
+}
+
+/**************************************************************************/
diff --git a/fdk-aac/libSACenc/src/sacenc_onsetdetect.h b/fdk-aac/libSACenc/src/sacenc_onsetdetect.h
new file mode 100644
index 0000000..5f3f0bd
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_onsetdetect.h
@@ -0,0 +1,154 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Determine TES flags
+
+*******************************************************************************/
+
+#ifndef SACENC_ONSETDETECT_H
+#define SACENC_ONSETDETECT_H
+
+/**************************************************************************/ /**
+ \file
+ Description of file contents
+ ******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "common_fix.h"
+#include "FDK_matrixCalloc.h"
+#include "sacenc_lib.h"
+#include "sacenc_bitstream.h" /* for def. of MAX_NUM_PARAMS */
+
+/* Defines *******************************************************************/
+#define MAX_NUM_TRANS (MAX_NUM_PARAMS / 2)
+
+/* Data Types ****************************************************************/
+typedef struct T_ONSET_DETECT_CONFIG {
+ INT maxTimeSlots;
+
+ /* calc transien detection in ]lowerBoundOnsetDetection;
+ * upperBoundOnsetDetection[ */
+ INT lowerBoundOnsetDetection;
+ INT upperBoundOnsetDetection;
+
+} ONSET_DETECT_CONFIG;
+
+typedef struct ONSET_DETECT *HANDLE_ONSET_DETECT;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Open(HANDLE_ONSET_DETECT *phOnset,
+ const UINT maxTimeSlots);
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Init(
+ HANDLE_ONSET_DETECT hOnset,
+ const ONSET_DETECT_CONFIG *const pOnsetDetectConfig, const UINT initFlags);
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Close(HANDLE_ONSET_DETECT *phOnset);
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Update(HANDLE_ONSET_DETECT hOnset,
+ const INT timeSlots);
+
+FDK_SACENC_ERROR fdk_sacenc_onsetDetect_Apply(
+ HANDLE_ONSET_DETECT hOnset, const INT nTimeSlots, const INT nHybridBands,
+ FIXP_DPK *const *const ppHybridData__FDK, const INT hybridDataScale,
+ const INT prevPos, INT pTransientPos[MAX_NUM_TRANS]);
+
+#endif /* SACENC_ONSETDETECT_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_paramextract.cpp b/fdk-aac/libSACenc/src/sacenc_paramextract.cpp
new file mode 100644
index 0000000..dcbce1e
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_paramextract.cpp
@@ -0,0 +1,725 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): M. Multrus
+
+ Description: Parameter Extraction
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_paramextract.h"
+#include "sacenc_tree.h"
+#include "sacenc_vectorfunctions.h"
+
+/* Defines *******************************************************************/
+#define LOG10_2_10 (3.01029995664f) /* 10.0f*log10(2.f) */
+#define SCALE_CLDE_SF (7) /* maxVal in Quant tab is +/- 50 */
+#define SCALE_CLDD_SF (8) /* maxVal in Quant tab is +/- 150 */
+
+/* Data Types ****************************************************************/
+typedef struct T_TTO_BOX {
+ FIXP_DBL pCld__FDK[MAX_NUM_PARAM_BANDS];
+ FIXP_DBL pIcc__FDK[MAX_NUM_PARAM_BANDS];
+ FIXP_DBL pCldQuant__FDK[MAX_NUM_PARAM_BANDS];
+
+ const FIXP_DBL *pIccQuantTable__FDK;
+ const FIXP_DBL *pCldQuantTableDec__FDK;
+ const FIXP_DBL *pCldQuantTableEnc__FDK;
+
+ SCHAR pCldEbQIdx[MAX_NUM_PARAM_BANDS];
+ SCHAR pIccDownmixIdx[MAX_NUM_PARAM_BANDS];
+
+ UCHAR *pParameterBand2HybridBandOffset;
+ const INT *pSubbandImagSign;
+ UCHAR nHybridBandsMax;
+ UCHAR nParameterBands;
+ UCHAR bFrameKeep;
+
+ UCHAR iccCorrelationCoherenceBorder;
+ BOX_QUANTMODE boxQuantMode;
+
+ UCHAR nIccQuantSteps;
+ UCHAR nIccQuantOffset;
+
+ UCHAR nCldQuantSteps;
+ UCHAR nCldQuantOffset;
+
+ UCHAR bUseCoarseQuantCld;
+ UCHAR bUseCoarseQuantIcc;
+
+} TTO_BOX;
+
+struct BOX_SUBBAND_SETUP {
+ BOX_SUBBAND_CONFIG subbandConfig;
+ UCHAR nParameterBands;
+ const UCHAR *pSubband2ParameterIndexLd;
+ UCHAR iccCorrelationCoherenceBorder;
+};
+
+/* Constants *****************************************************************/
+static const UCHAR subband2Parameter4_Ld[NUM_QMF_BANDS] = {
+ 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
+
+static const UCHAR subband2Parameter5_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
+
+static const UCHAR subband2Parameter7_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
+
+static const UCHAR subband2Parameter9_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
+
+static const UCHAR subband2Parameter12_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8,
+ 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11};
+
+static const UCHAR subband2Parameter15_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 10, 10, 11, 11,
+ 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14};
+
+static const UCHAR subband2Parameter23_Ld[NUM_QMF_BANDS] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 13,
+ 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19,
+ 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22};
+
+static const INT subbandImagSign_Ld[NUM_QMF_BANDS] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+};
+
+#define SCALE_CLDE(a) (FL2FXCONST_DBL(a / (float)(1 << SCALE_CLDE_SF)))
+static const FIXP_DBL cldQuantTableFineEnc__FDK[MAX_CLD_QUANT_FINE] = {
+ SCALE_CLDE(-50.0), SCALE_CLDE(-45.0), SCALE_CLDE(-40.0), SCALE_CLDE(-35.0),
+ SCALE_CLDE(-30.0), SCALE_CLDE(-25.0), SCALE_CLDE(-22.0), SCALE_CLDE(-19.0),
+ SCALE_CLDE(-16.0), SCALE_CLDE(-13.0), SCALE_CLDE(-10.0), SCALE_CLDE(-8.0),
+ SCALE_CLDE(-6.0), SCALE_CLDE(-4.0), SCALE_CLDE(-2.0), SCALE_CLDE(0.0),
+ SCALE_CLDE(2.0), SCALE_CLDE(4.0), SCALE_CLDE(6.0), SCALE_CLDE(8.0),
+ SCALE_CLDE(10.0), SCALE_CLDE(13.0), SCALE_CLDE(16.0), SCALE_CLDE(19.0),
+ SCALE_CLDE(22.0), SCALE_CLDE(25.0), SCALE_CLDE(30.0), SCALE_CLDE(35.0),
+ SCALE_CLDE(40.0), SCALE_CLDE(45.0), SCALE_CLDE(50.0)};
+
+static const FIXP_DBL cldQuantTableCoarseEnc__FDK[MAX_CLD_QUANT_COARSE] = {
+ SCALE_CLDE(-50.0), SCALE_CLDE(-35.0), SCALE_CLDE(-25.0), SCALE_CLDE(-19.0),
+ SCALE_CLDE(-13.0), SCALE_CLDE(-8.0), SCALE_CLDE(-4.0), SCALE_CLDE(0.0),
+ SCALE_CLDE(4.0), SCALE_CLDE(8.0), SCALE_CLDE(13.0), SCALE_CLDE(19.0),
+ SCALE_CLDE(25.0), SCALE_CLDE(35.0), SCALE_CLDE(50.0)};
+
+#define SCALE_CLDD(a) (FL2FXCONST_DBL(a / (float)(1 << SCALE_CLDD_SF)))
+static const FIXP_DBL cldQuantTableFineDec__FDK[MAX_CLD_QUANT_FINE] = {
+ SCALE_CLDD(-150.0), SCALE_CLDD(-45.0), SCALE_CLDD(-40.0), SCALE_CLDD(-35.0),
+ SCALE_CLDD(-30.0), SCALE_CLDD(-25.0), SCALE_CLDD(-22.0), SCALE_CLDD(-19.0),
+ SCALE_CLDD(-16.0), SCALE_CLDD(-13.0), SCALE_CLDD(-10.0), SCALE_CLDD(-8.0),
+ SCALE_CLDD(-6.0), SCALE_CLDD(-4.0), SCALE_CLDD(-2.0), SCALE_CLDD(0.0),
+ SCALE_CLDD(2.0), SCALE_CLDD(4.0), SCALE_CLDD(6.0), SCALE_CLDD(8.0),
+ SCALE_CLDD(10.0), SCALE_CLDD(13.0), SCALE_CLDD(16.0), SCALE_CLDD(19.0),
+ SCALE_CLDD(22.0), SCALE_CLDD(25.0), SCALE_CLDD(30.0), SCALE_CLDD(35.0),
+ SCALE_CLDD(40.0), SCALE_CLDD(45.0), SCALE_CLDD(150.0)};
+
+static const FIXP_DBL cldQuantTableCoarseDec__FDK[MAX_CLD_QUANT_COARSE] = {
+ SCALE_CLDD(-150.0), SCALE_CLDD(-35.0), SCALE_CLDD(-25.0), SCALE_CLDD(-19.0),
+ SCALE_CLDD(-13.0), SCALE_CLDD(-8.0), SCALE_CLDD(-4.0), SCALE_CLDD(0.0),
+ SCALE_CLDD(4.0), SCALE_CLDD(8.0), SCALE_CLDD(13.0), SCALE_CLDD(19.0),
+ SCALE_CLDD(25.0), SCALE_CLDD(35.0), SCALE_CLDD(150.0)};
+
+#define SCALE_ICC(a) (FL2FXCONST_DBL(a))
+static const FIXP_DBL iccQuantTableFine__FDK[MAX_ICC_QUANT_FINE] = {
+ SCALE_ICC(0.99999999953), SCALE_ICC(0.937f), SCALE_ICC(0.84118f),
+ SCALE_ICC(0.60092f), SCALE_ICC(0.36764f), SCALE_ICC(0.0f),
+ SCALE_ICC(-0.589f), SCALE_ICC(-0.99f)};
+
+static const FIXP_DBL iccQuantTableCoarse__FDK[MAX_ICC_QUANT_COARSE] = {
+ SCALE_ICC(0.99999999953), SCALE_ICC(0.84118f), SCALE_ICC(0.36764f),
+ SCALE_ICC(-0.5890f)};
+
+static const BOX_SUBBAND_SETUP boxSubbandSetup[] = {
+ {BOX_SUBBANDS_4, 4, subband2Parameter4_Ld, 1},
+ {BOX_SUBBANDS_5, 5, subband2Parameter5_Ld, 2},
+ {BOX_SUBBANDS_7, 7, subband2Parameter7_Ld, 3},
+ {BOX_SUBBANDS_9, 9, subband2Parameter9_Ld, 4},
+ {BOX_SUBBANDS_12, 12, subband2Parameter12_Ld, 4},
+ {BOX_SUBBANDS_15, 15, subband2Parameter15_Ld, 5},
+ {BOX_SUBBANDS_23, 23, subband2Parameter23_Ld, 8}};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static const BOX_SUBBAND_SETUP *getBoxSubbandSetup(
+ const BOX_SUBBAND_CONFIG subbandConfig) {
+ int i;
+ const BOX_SUBBAND_SETUP *setup = NULL;
+
+ for (i = 0; i < (int)(sizeof(boxSubbandSetup) / sizeof(BOX_SUBBAND_SETUP));
+ i++) {
+ if (boxSubbandSetup[i].subbandConfig == subbandConfig) {
+ setup = &boxSubbandSetup[i];
+ break;
+ }
+ }
+ return setup;
+}
+
+static inline void ApplyBBCuesFDK(FIXP_DBL *const pData,
+ const INT nParamBands) {
+ int i, s;
+ FIXP_DBL tmp, invParamBands;
+
+ invParamBands = fDivNormHighPrec((FIXP_DBL)1, (FIXP_DBL)nParamBands, &s);
+ s = -s;
+
+ tmp = fMult(pData[0], invParamBands) >> s;
+ for (i = 1; i < nParamBands; i++) {
+ tmp += fMult(pData[i], invParamBands) >> s;
+ }
+
+ for (i = 0; i < nParamBands; i++) {
+ pData[i] = tmp;
+ }
+}
+
+static INT getNumberParameterBands(const BOX_SUBBAND_CONFIG subbandConfig) {
+ const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
+ return ((setup == NULL) ? 0 : setup->nParameterBands);
+}
+
+static const UCHAR *getSubband2ParameterIndex(
+ const BOX_SUBBAND_CONFIG subbandConfig) {
+ const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
+
+ return ((setup == NULL) ? NULL : (setup->pSubband2ParameterIndexLd));
+}
+
+void fdk_sacenc_calcParameterBand2HybridBandOffset(
+ const BOX_SUBBAND_CONFIG subbandConfig, const INT nHybridBands,
+ UCHAR *pParameterBand2HybridBandOffset) {
+ const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
+ const UCHAR *pSubband2ParameterIndex;
+
+ int i, pb;
+
+ pSubband2ParameterIndex = setup->pSubband2ParameterIndexLd;
+
+ for (pb = 0, i = 0; i < nHybridBands - 1; i++) {
+ if (pSubband2ParameterIndex[i + 1] - pSubband2ParameterIndex[i]) {
+ pParameterBand2HybridBandOffset[pb++] = (i + 1);
+ }
+ }
+ pParameterBand2HybridBandOffset[pb++] = (i + 1);
+}
+
+const INT *fdk_sacenc_getSubbandImagSign() {
+ const INT *pImagSign = NULL;
+
+ pImagSign = subbandImagSign_Ld;
+
+ return (pImagSign);
+}
+
+static INT getIccCorrelationCoherenceBorder(
+ const BOX_SUBBAND_CONFIG subbandConfig, const INT bUseCoherenceOnly) {
+ const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
+ return (
+ (setup == NULL)
+ ? 0
+ : ((bUseCoherenceOnly) ? 0 : setup->iccCorrelationCoherenceBorder));
+}
+
+FDK_SACENC_ERROR fdk_sacenc_createTtoBox(HANDLE_TTO_BOX *hTtoBox) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hTtoBox) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDK_ALLOCATE_MEMORY_1D(*hTtoBox, 1, TTO_BOX);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_destroyTtoBox(hTtoBox);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_initTtoBox(HANDLE_TTO_BOX hTtoBox,
+ const TTO_BOX_CONFIG *const ttoBoxConfig,
+ UCHAR *pParameterBand2HybridBandOffset) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hTtoBox == NULL) || (ttoBoxConfig == NULL) ||
+ (pParameterBand2HybridBandOffset == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDKmemclear(hTtoBox, sizeof(TTO_BOX));
+
+ hTtoBox->bUseCoarseQuantCld = ttoBoxConfig->bUseCoarseQuantCld;
+ hTtoBox->bUseCoarseQuantIcc = ttoBoxConfig->bUseCoarseQuantIcc;
+ hTtoBox->boxQuantMode = ttoBoxConfig->boxQuantMode;
+ hTtoBox->iccCorrelationCoherenceBorder = getIccCorrelationCoherenceBorder(
+ ttoBoxConfig->subbandConfig, ttoBoxConfig->bUseCoherenceIccOnly);
+ hTtoBox->nHybridBandsMax = ttoBoxConfig->nHybridBandsMax;
+ hTtoBox->nParameterBands =
+ getNumberParameterBands(ttoBoxConfig->subbandConfig);
+ hTtoBox->bFrameKeep = ttoBoxConfig->bFrameKeep;
+
+ hTtoBox->nIccQuantSteps =
+ fdk_sacenc_getNumberIccQuantLevels(hTtoBox->bUseCoarseQuantIcc);
+ hTtoBox->nIccQuantOffset =
+ fdk_sacenc_getIccQuantOffset(hTtoBox->bUseCoarseQuantIcc);
+
+ hTtoBox->pIccQuantTable__FDK = hTtoBox->bUseCoarseQuantIcc
+ ? iccQuantTableCoarse__FDK
+ : iccQuantTableFine__FDK;
+ hTtoBox->pCldQuantTableDec__FDK = hTtoBox->bUseCoarseQuantCld
+ ? cldQuantTableCoarseDec__FDK
+ : cldQuantTableFineDec__FDK;
+ hTtoBox->pCldQuantTableEnc__FDK = hTtoBox->bUseCoarseQuantCld
+ ? cldQuantTableCoarseEnc__FDK
+ : cldQuantTableFineEnc__FDK;
+
+ hTtoBox->nCldQuantSteps =
+ fdk_sacenc_getNumberCldQuantLevels(hTtoBox->bUseCoarseQuantCld);
+ hTtoBox->nCldQuantOffset =
+ fdk_sacenc_getCldQuantOffset(hTtoBox->bUseCoarseQuantCld);
+
+ /* sanity */
+ if (NULL == (hTtoBox->pParameterBand2HybridBandOffset =
+ pParameterBand2HybridBandOffset)) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+
+ if (NULL == (hTtoBox->pSubbandImagSign = fdk_sacenc_getSubbandImagSign())) {
+ error = SACENC_INIT_ERROR;
+ }
+
+ if ((hTtoBox->boxQuantMode != BOX_QUANTMODE_FINE) &&
+ (hTtoBox->boxQuantMode != BOX_QUANTMODE_EBQ1) &&
+ (hTtoBox->boxQuantMode != BOX_QUANTMODE_EBQ2)) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+ }
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_destroyTtoBox(HANDLE_TTO_BOX *hTtoBox) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (*hTtoBox != NULL) {
+ FDKfree(*hTtoBox);
+ *hTtoBox = NULL;
+ }
+
+ return error;
+}
+
+static FDK_SACENC_ERROR calculateIccFDK(const INT nParamBand,
+ const INT correlationCoherenceBorder,
+ const FIXP_DBL *const pPwr1,
+ const FIXP_DBL *const pPwr2,
+ const FIXP_DBL *const pProdReal,
+ FIXP_DBL const *const pProdImag,
+ FIXP_DBL *const pIcc) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((pPwr1 == NULL) || (pPwr2 == NULL) || (pProdReal == NULL) ||
+ (pProdImag == NULL) || (pIcc == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* sanity check border */
+ if (correlationCoherenceBorder > nParamBand) {
+ error = SACENC_INVALID_CONFIG;
+ } else {
+ /* correlation */
+ FDKcalcCorrelationVec(pIcc, pProdReal, pPwr1, pPwr2,
+ correlationCoherenceBorder);
+
+ /* coherence */
+ calcCoherenceVec(&pIcc[correlationCoherenceBorder],
+ &pProdReal[correlationCoherenceBorder],
+ &pProdImag[correlationCoherenceBorder],
+ &pPwr1[correlationCoherenceBorder],
+ &pPwr2[correlationCoherenceBorder], 0, 0,
+ nParamBand - correlationCoherenceBorder);
+
+ } /* valid configuration */
+ } /* valid handle */
+
+ return error;
+}
+
+static void QuantizeCoefFDK(const FIXP_DBL *const input, const INT nBands,
+ const FIXP_DBL *const quantTable,
+ const INT idxOffset, const INT nQuantSteps,
+ SCHAR *const quantOut) {
+ int band;
+ const int reverse = (quantTable[0] > quantTable[1]);
+
+ for (band = 0; band < nBands; band++) {
+ FIXP_DBL qVal;
+ FIXP_DBL curVal = input[band];
+
+ int lower = 0;
+ int upper = nQuantSteps - 1;
+
+ if (reverse) {
+ while (upper - lower > 1) {
+ int idx = (lower + upper) >> 1;
+ qVal = quantTable[idx];
+ if (curVal >= qVal) {
+ upper = idx;
+ } else {
+ lower = idx;
+ }
+ } /* while */
+
+ if ((curVal - quantTable[lower]) >= (quantTable[upper] - curVal)) {
+ quantOut[band] = lower - idxOffset;
+ } else {
+ quantOut[band] = upper - idxOffset;
+ }
+ } /* if reverse */
+ else {
+ while (upper - lower > 1) {
+ int idx = (lower + upper) >> 1;
+ qVal = quantTable[idx];
+ if (curVal <= qVal) {
+ upper = idx;
+ } else {
+ lower = idx;
+ }
+ } /* while */
+
+ if ((curVal - quantTable[lower]) <= (quantTable[upper] - curVal)) {
+ quantOut[band] = lower - idxOffset;
+ } else {
+ quantOut[band] = upper - idxOffset;
+ }
+ } /* else reverse */
+ } /* for band */
+}
+
+static void deQuantizeCoefFDK(const SCHAR *const input, const INT nBands,
+ const FIXP_DBL *const quantTable,
+ const INT idxOffset, FIXP_DBL *const dequantOut) {
+ int band;
+
+ for (band = 0; band < nBands; band++) {
+ dequantOut[band] = quantTable[input[band] + idxOffset];
+ }
+}
+
+static void CalculateCldFDK(FIXP_DBL *const pCld, const FIXP_DBL *const pPwr1,
+ const FIXP_DBL *const pPwr2, const INT scaleCh1,
+ const INT *const pbScaleCh1, const INT scaleCh2,
+ const INT *const pbScaleCh2, const int nParamBand) {
+ INT i;
+ FIXP_DBL ldPwr1, ldPwr2, cld;
+ FIXP_DBL maxPwr = FL2FXCONST_DBL(
+ 30.0f /
+ (1 << (LD_DATA_SHIFT +
+ 1))); /* consider SACENC_FLOAT_EPSILON in power calculation */
+
+ for (i = 0; i < nParamBand; i++) {
+ ldPwr1 =
+ (CalcLdData(pPwr1[i]) >> 1) + ((FIXP_DBL)(scaleCh1 + pbScaleCh1[i])
+ << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
+ ldPwr2 =
+ (CalcLdData(pPwr2[i]) >> 1) + ((FIXP_DBL)(scaleCh2 + pbScaleCh2[i])
+ << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
+
+ ldPwr1 = fixMax(fixMin(ldPwr1, maxPwr), -maxPwr);
+ ldPwr2 = fixMax(fixMin(ldPwr2, maxPwr), -maxPwr);
+
+ /* ldPwr1 and ldPwr2 are scaled by LD_DATA_SHIFT and additional 1 bit; 1 bit
+ * scale by fMultDiv2() */
+ cld = fMultDiv2(FL2FXCONST_DBL(LOG10_2_10 / (1 << SCALE_CLDE_SF)),
+ ldPwr1 - ldPwr2);
+
+ cld =
+ fixMin(cld, (FIXP_DBL)(((FIXP_DBL)MAXVAL_DBL) >> (LD_DATA_SHIFT + 2)));
+ cld =
+ fixMax(cld, (FIXP_DBL)(((FIXP_DBL)MINVAL_DBL) >> (LD_DATA_SHIFT + 2)));
+ pCld[i] = cld << (LD_DATA_SHIFT + 2);
+ }
+}
+
+FDK_SACENC_ERROR fdk_sacenc_applyTtoBox(
+ HANDLE_TTO_BOX hTtoBox, const INT nTimeSlots, const INT startTimeSlot,
+ const INT nHybridBands, const FIXP_DPK *const *const ppHybridData1__FDK,
+ const FIXP_DPK *const *const ppHybridData2__FDK, SCHAR *const pIccIdx,
+ UCHAR *const pbIccQuantCoarse, SCHAR *const pCldIdx,
+ UCHAR *const pbCldQuantCoarse, const INT bUseBBCues, INT *scaleCh1,
+ INT *scaleCh2) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ C_ALLOC_SCRATCH_START(powerHybridData1__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(powerHybridData2__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(prodHybridDataReal__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(prodHybridDataImag__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+
+ C_ALLOC_SCRATCH_START(IccDownmix__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(IccDownmixQuant__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(pbScaleCh1, INT, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_START(pbScaleCh2, INT, MAX_NUM_PARAM_BANDS)
+
+ if ((hTtoBox == NULL) || (pCldIdx == NULL) || (pbCldQuantCoarse == NULL) ||
+ (ppHybridData1__FDK == NULL) || (ppHybridData2__FDK == NULL) ||
+ (pIccIdx == NULL) || (pbIccQuantCoarse == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int j, pb;
+ const int nParamBands = hTtoBox->nParameterBands;
+ const int bUseEbQ = (hTtoBox->boxQuantMode == BOX_QUANTMODE_EBQ1) ||
+ (hTtoBox->boxQuantMode == BOX_QUANTMODE_EBQ2);
+
+ /* sanity check */
+ if ((nHybridBands < 0) || (nHybridBands > hTtoBox->nHybridBandsMax)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ int outScale; /* scalefactor will not be evaluated */
+ int inScale = 5; /* scale factor determined empirically */
+
+ /* calculate the headroom of the hybrid data for each parameter band */
+ FDKcalcPbScaleFactor(ppHybridData1__FDK,
+ hTtoBox->pParameterBand2HybridBandOffset, pbScaleCh1,
+ startTimeSlot, nTimeSlots, nParamBands);
+ FDKcalcPbScaleFactor(ppHybridData2__FDK,
+ hTtoBox->pParameterBand2HybridBandOffset, pbScaleCh2,
+ startTimeSlot, nTimeSlots, nParamBands);
+
+ for (j = 0, pb = 0; pb < nParamBands; pb++) {
+ FIXP_DBL data1, data2;
+ data1 = data2 = (FIXP_DBL)0;
+ for (; j < hTtoBox->pParameterBand2HybridBandOffset[pb]; j++) {
+ data1 += sumUpCplxPow2Dim2(ppHybridData1__FDK, SUM_UP_STATIC_SCALE,
+ inScale + pbScaleCh1[pb], &outScale,
+ startTimeSlot, nTimeSlots, j, j + 1);
+ data2 += sumUpCplxPow2Dim2(ppHybridData2__FDK, SUM_UP_STATIC_SCALE,
+ inScale + pbScaleCh2[pb], &outScale,
+ startTimeSlot, nTimeSlots, j, j + 1);
+ } /* for j */
+ powerHybridData1__FDK[pb] = data1;
+ powerHybridData2__FDK[pb] = data2;
+ } /* pb */
+
+ {
+ for (j = 0, pb = 0; pb < nParamBands; pb++) {
+ FIXP_DBL dataReal, dataImag;
+ dataReal = dataImag = (FIXP_DBL)0;
+ for (; j < hTtoBox->pParameterBand2HybridBandOffset[pb]; j++) {
+ FIXP_DPK scalarProd;
+ cplx_cplxScalarProduct(&scalarProd, ppHybridData1__FDK,
+ ppHybridData2__FDK, inScale + pbScaleCh1[pb],
+ inScale + pbScaleCh2[pb], &outScale,
+ startTimeSlot, nTimeSlots, j, j + 1);
+ dataReal += scalarProd.v.re;
+ if (hTtoBox->pSubbandImagSign[j] < 0) {
+ dataImag -= scalarProd.v.im;
+ } else {
+ dataImag += scalarProd.v.im;
+ }
+ } /* for j */
+ prodHybridDataReal__FDK[pb] = dataReal;
+ prodHybridDataImag__FDK[pb] = dataImag;
+ } /* pb */
+
+ if (SACENC_OK != (error = calculateIccFDK(
+ nParamBands, hTtoBox->iccCorrelationCoherenceBorder,
+ powerHybridData1__FDK, powerHybridData2__FDK,
+ prodHybridDataReal__FDK, prodHybridDataImag__FDK,
+ hTtoBox->pIcc__FDK))) {
+ goto bail;
+ }
+
+ /* calculate correlation based Icc for downmix */
+ if (SACENC_OK != (error = calculateIccFDK(
+ nParamBands, nParamBands, powerHybridData1__FDK,
+ powerHybridData2__FDK, prodHybridDataReal__FDK,
+ prodHybridDataImag__FDK, IccDownmix__FDK))) {
+ goto bail;
+ }
+ }
+
+ if (!bUseEbQ) {
+ CalculateCldFDK(hTtoBox->pCld__FDK, powerHybridData1__FDK,
+ powerHybridData2__FDK, *scaleCh1 + inScale + 1,
+ pbScaleCh1, *scaleCh2 + inScale + 1, pbScaleCh2,
+ nParamBands);
+ }
+
+ if (bUseBBCues) {
+ ApplyBBCuesFDK(&hTtoBox->pCld__FDK[0], nParamBands);
+
+ { ApplyBBCuesFDK(&hTtoBox->pIcc__FDK[0], nParamBands); }
+
+ } /* bUseBBCues */
+
+ /* quantize/de-quantize icc */
+ {
+ QuantizeCoefFDK(hTtoBox->pIcc__FDK, nParamBands,
+ hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset,
+ hTtoBox->nIccQuantSteps, pIccIdx);
+ QuantizeCoefFDK(IccDownmix__FDK, nParamBands,
+ hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset,
+ hTtoBox->nIccQuantSteps, hTtoBox->pIccDownmixIdx);
+ deQuantizeCoefFDK(hTtoBox->pIccDownmixIdx, nParamBands,
+ hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset,
+ IccDownmixQuant__FDK);
+
+ *pbIccQuantCoarse = hTtoBox->bUseCoarseQuantIcc;
+ }
+
+ /* quantize/de-quantize cld */
+ if (!bUseEbQ) {
+ QuantizeCoefFDK(hTtoBox->pCld__FDK, nParamBands,
+ hTtoBox->pCldQuantTableEnc__FDK, hTtoBox->nCldQuantOffset,
+ hTtoBox->nCldQuantSteps, pCldIdx);
+ deQuantizeCoefFDK(pCldIdx, nParamBands, hTtoBox->pCldQuantTableDec__FDK,
+ hTtoBox->nCldQuantOffset, hTtoBox->pCldQuant__FDK);
+ } else {
+ FDKmemcpy(pCldIdx, hTtoBox->pCldEbQIdx, nParamBands * sizeof(SCHAR));
+ }
+ *pbCldQuantCoarse = hTtoBox->bUseCoarseQuantCld;
+
+ } /* valid handle */
+
+bail:
+ C_ALLOC_SCRATCH_END(pbScaleCh2, INT, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(pbScaleCh1, INT, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(IccDownmixQuant__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(IccDownmix__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+
+ C_ALLOC_SCRATCH_END(prodHybridDataImag__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(prodHybridDataReal__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(powerHybridData2__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+ C_ALLOC_SCRATCH_END(powerHybridData1__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
+
+ return error;
+}
+
+INT fdk_sacenc_subband2ParamBand(const BOX_SUBBAND_CONFIG boxSubbandConfig,
+ const INT nSubband) {
+ INT nParamBand = -1;
+ const UCHAR *pSubband2ParameterIndex =
+ getSubband2ParameterIndex(boxSubbandConfig);
+
+ if (pSubband2ParameterIndex != NULL) {
+ const int hybrid_resolution = 64;
+
+ if ((nSubband > -1) && (nSubband < hybrid_resolution)) {
+ nParamBand = pSubband2ParameterIndex[nSubband];
+ }
+ }
+
+ return nParamBand;
+}
diff --git a/fdk-aac/libSACenc/src/sacenc_paramextract.h b/fdk-aac/libSACenc/src/sacenc_paramextract.h
new file mode 100644
index 0000000..9ebb902
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_paramextract.h
@@ -0,0 +1,214 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): M. Multrus
+
+ Description: Parameter Extraction
+
+*******************************************************************************/
+
+#ifndef SACENC_PARAMEXTRACT_H
+#define SACENC_PARAMEXTRACT_H
+
+/* Includes ******************************************************************/
+#include "common_fix.h"
+#include "sacenc_lib.h"
+#include "sacenc_const.h"
+#include "sacenc_bitstream.h"
+
+/* Defines *******************************************************************/
+#define MAX_CLD_QUANT_FINE (31)
+#define MAX_CLD_QUANT_COARSE (15)
+#define OFFSET_CLD_QUANT_COARSE (7)
+#define OFFSET_CLD_QUANT_FINE (15)
+
+#define MAX_ICC_QUANT_COARSE (4)
+#define MAX_ICC_QUANT_FINE (8)
+#define OFFSET_ICC_QUANT_COARSE (0)
+#define OFFSET_ICC_QUANT_FINE (0)
+
+#define MAX_NUM_PARAM_BANDS (28)
+
+#define NUM_MAPPED_HYBRID_BANDS (16)
+
+/* Data Types ****************************************************************/
+typedef struct T_TTO_BOX *HANDLE_TTO_BOX;
+
+typedef enum {
+ BOX_SUBBANDS_INVALID = 0,
+ BOX_SUBBANDS_4 = 4,
+ BOX_SUBBANDS_5 = 5,
+ BOX_SUBBANDS_7 = 7,
+ BOX_SUBBANDS_9 = 9,
+ BOX_SUBBANDS_12 = 12,
+ BOX_SUBBANDS_15 = 15,
+ BOX_SUBBANDS_23 = 23
+
+} BOX_SUBBAND_CONFIG;
+
+typedef enum {
+ BOX_QUANTMODE_INVALID = -1,
+ BOX_QUANTMODE_FINE = 0,
+ BOX_QUANTMODE_EBQ1 = 1,
+ BOX_QUANTMODE_EBQ2 = 2,
+ BOX_QUANTMODE_RESERVED3 = 3,
+ BOX_QUANTMODE_RESERVED4 = 4,
+ BOX_QUANTMODE_RESERVED5 = 5,
+ BOX_QUANTMODE_RESERVED6 = 6,
+ BOX_QUANTMODE_RESERVED7 = 7
+
+} BOX_QUANTMODE;
+
+typedef struct T_TTO_BOX_CONFIG {
+ UCHAR bUseCoarseQuantCld;
+ UCHAR bUseCoarseQuantIcc;
+ UCHAR bUseCoherenceIccOnly;
+
+ BOX_SUBBAND_CONFIG subbandConfig;
+ BOX_QUANTMODE boxQuantMode;
+
+ UCHAR nHybridBandsMax;
+
+ UCHAR bFrameKeep;
+
+} TTO_BOX_CONFIG;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_createTtoBox(HANDLE_TTO_BOX *hTtoBox);
+
+FDK_SACENC_ERROR fdk_sacenc_initTtoBox(HANDLE_TTO_BOX hTtoBox,
+ const TTO_BOX_CONFIG *const ttoBoxConfig,
+ UCHAR *pParameterBand2HybridBandOffset);
+
+FDK_SACENC_ERROR fdk_sacenc_destroyTtoBox(HANDLE_TTO_BOX *hTtoBox);
+
+FDK_SACENC_ERROR fdk_sacenc_applyTtoBox(
+ HANDLE_TTO_BOX hTtoBox, const INT nTimeSlots, const INT startTimeSlot,
+ const INT nHybridBands, const FIXP_DPK *const *const ppHybridData1__FDK,
+ const FIXP_DPK *const *const ppHybridData2__FDK, SCHAR *const pIccIdx,
+ UCHAR *const pbIccQuantCoarse, SCHAR *const pCldIdx,
+ UCHAR *const pbCldQuantCoarse, const INT bUseBBCues, INT *scaleCh0,
+ INT *scaleCh1);
+
+INT fdk_sacenc_subband2ParamBand(const BOX_SUBBAND_CONFIG boxSubbandConfig,
+ const INT nSubband);
+
+const INT *fdk_sacenc_getSubbandImagSign();
+
+void fdk_sacenc_calcParameterBand2HybridBandOffset(
+ const BOX_SUBBAND_CONFIG subbandConfig, const INT nHybridBands,
+ UCHAR *pParameterBand2HybridBandOffset);
+
+/* Function / Class Definition ***********************************************/
+static inline UCHAR fdk_sacenc_getCldQuantOffset(const INT bUseCoarseQuant) {
+ return ((bUseCoarseQuant) ? OFFSET_CLD_QUANT_COARSE : OFFSET_CLD_QUANT_FINE);
+}
+static inline UCHAR fdk_sacenc_getIccQuantOffset(const INT bUseCoarseQuant) {
+ return ((bUseCoarseQuant) ? OFFSET_ICC_QUANT_COARSE : OFFSET_ICC_QUANT_FINE);
+}
+
+static inline UCHAR fdk_sacenc_getNumberCldQuantLevels(
+ const INT bUseCoarseQuant) {
+ return ((bUseCoarseQuant) ? MAX_CLD_QUANT_COARSE : MAX_CLD_QUANT_FINE);
+}
+static inline UCHAR fdk_sacenc_getNumberIccQuantLevels(
+ const INT bUseCoarseQuant) {
+ return ((bUseCoarseQuant) ? MAX_ICC_QUANT_COARSE : MAX_ICC_QUANT_FINE);
+}
+
+#endif /* SACENC_PARAMEXTRACT_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_staticgain.cpp b/fdk-aac/libSACenc/src/sacenc_staticgain.cpp
new file mode 100644
index 0000000..fef9f8d
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_staticgain.cpp
@@ -0,0 +1,446 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Christian Goettlinger
+
+ Description: Encoder Library Interface
+ gain management of the encoder
+
+*******************************************************************************/
+
+/*****************************************************************************
+\file
+This file contains all static gain infrastructure
+******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_staticgain.h"
+
+/* Defines *******************************************************************/
+#define MP4SPACEENC_DMX_GAIN_DEFAULT SACENC_DMXGAIN_3_dB
+#define GAINCF_SF (4)
+#define GAINCT1(x) FL2FXCONST_DBL(x)
+#define GAINCF(x) FL2FXCONST_DBL(x)
+
+#define GAINCT2(x) FL2FXCONST_DBL(x)
+#define FX_DBL2FX_GAIN(x) (x)
+
+/* Data Types ****************************************************************/
+struct STATIC_GAIN {
+ /* External Config Values */
+ MP4SPACEENC_MODE encMode;
+ MP4SPACEENC_DMX_GAIN fixedGainDMX;
+ INT preGainFactorDb;
+
+ /* Internal Values */
+ FIXP_GAIN PostGain__FDK;
+ FIXP_GAIN pPreGain__FDK[SACENC_MAX_INPUT_CHANNELS];
+};
+
+/* Constants *****************************************************************/
+/*
+ preGainFactorTable:
+
+ pre calculation: (float)pow(10.f,(((float) x)/20.f))/(float)(1<<GAINCF_SF), x
+ = -20 ... +20
+*/
+static const FIXP_DBL preGainFactorTable__FDK[41] = {
+ GAINCF(6.2500000931e-003), GAINCF(7.0126154460e-003),
+ GAINCF(7.8682834283e-003), GAINCF(8.8283596560e-003),
+ GAINCF(9.9055822939e-003), GAINCF(1.1114246212e-002),
+ GAINCF(1.2470389716e-002), GAINCF(1.3992006890e-002),
+ GAINCF(1.5699289739e-002), GAINCF(1.7614893615e-002),
+ GAINCF(1.9764235243e-002), GAINCF(2.2175837308e-002),
+ GAINCF(2.4881698191e-002), GAINCF(2.7917724103e-002),
+ GAINCF(3.1324200332e-002), GAINCF(3.5146333277e-002),
+ GAINCF(3.9434835315e-002), GAINCF(4.4246610254e-002),
+ GAINCF(4.9645513296e-002), GAINCF(5.5703181773e-002),
+ GAINCF(6.2500000000e-002), GAINCF(7.0126153529e-002),
+ GAINCF(7.8682839870e-002), GAINCF(8.8283598423e-002),
+ GAINCF(9.9055826664e-002), GAINCF(1.1114246398e-001),
+ GAINCF(1.2470389158e-001), GAINCF(1.3992007077e-001),
+ GAINCF(1.5699289739e-001), GAINCF(1.7614893615e-001),
+ GAINCF(1.9764235616e-001), GAINCF(2.2175836563e-001),
+ GAINCF(2.4881698191e-001), GAINCF(2.7917724848e-001),
+ GAINCF(3.1324201822e-001), GAINCF(3.5146331787e-001),
+ GAINCF(3.9434835315e-001), GAINCF(4.4246610999e-001),
+ GAINCF(4.9645513296e-001), GAINCF(5.5703181028e-001),
+ GAINCF(6.2500000000e-001)};
+
+static const FIXP_GAIN dmxGainTable__FDK[] = {
+ /* GAINCT2(1.0), */ GAINCT2(0.84089650f),
+ GAINCT2(0.70710706f),
+ GAINCT2(0.59460385f),
+ GAINCT2(0.50000000f),
+ GAINCT2(0.42044825f),
+ GAINCT2(0.35355341f),
+ GAINCT2(0.25000000f)};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_staticGain_OpenConfig()
+description: opens and sets ConfigStruct to Default Values
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_staticGain_OpenConfig(
+ HANDLE_STATIC_GAIN_CONFIG *phStaticGainConfig) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == phStaticGainConfig) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Allocate Instance */
+ FDK_ALLOCATE_MEMORY_1D(*phStaticGainConfig, 1, struct STATIC_GAIN_CONFIG);
+ }
+ return error;
+
+bail:
+ fdk_sacenc_staticGain_CloseConfig(phStaticGainConfig);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_InitDefaultConfig(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainConfig) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hStaticGainConfig) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Necessary Input Variables */
+ hStaticGainConfig->encMode = SACENC_INVALID_MODE;
+
+ /* Optional Configs Set to Default Values */
+ hStaticGainConfig->fixedGainDMX = MP4SPACEENC_DMX_GAIN_DEFAULT;
+ hStaticGainConfig->preGainFactorDb = 0;
+ }
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_staticGain_CloseConfig()
+description: destructs Static Gain Config Structure
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_staticGain_CloseConfig(
+ HANDLE_STATIC_GAIN_CONFIG *phStaticGainConfig) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((phStaticGainConfig == NULL) || (*phStaticGainConfig == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDKfree(*phStaticGainConfig);
+ *phStaticGainConfig = NULL;
+ }
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_staticGain_Open()
+description: initializes Static Gains
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Open(HANDLE_STATIC_GAIN *phStaticGain) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == phStaticGain) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ /* Allocate Instance */
+ FDK_ALLOCATE_MEMORY_1D(*phStaticGain, 1, struct STATIC_GAIN);
+ }
+ return error;
+
+bail:
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Init(
+ HANDLE_STATIC_GAIN hStaticGain,
+ const HANDLE_STATIC_GAIN_CONFIG hStaticGainConfig, INT *const scale) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hStaticGain == NULL) || (hStaticGainConfig == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ hStaticGain->encMode = hStaticGainConfig->encMode;
+ hStaticGain->fixedGainDMX = hStaticGainConfig->fixedGainDMX;
+ hStaticGain->preGainFactorDb = hStaticGainConfig->preGainFactorDb;
+
+ if ((hStaticGain->preGainFactorDb < -20) ||
+ (hStaticGain->preGainFactorDb > 20)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ FIXP_DBL fPreGainFactor__FDK;
+
+ if (hStaticGain->preGainFactorDb == 0) {
+ fPreGainFactor__FDK = (FIXP_DBL)MAXVAL_DBL;
+ *scale = 0;
+ } else {
+ int s;
+ fPreGainFactor__FDK =
+ preGainFactorTable__FDK[hStaticGain->preGainFactorDb + 20];
+ s = fixMax(0, CntLeadingZeros(fPreGainFactor__FDK) - 1);
+ fPreGainFactor__FDK = fPreGainFactor__FDK << (s);
+ *scale = GAINCF_SF - s;
+ }
+
+ if (hStaticGain->fixedGainDMX == 0)
+ hStaticGain->PostGain__FDK = MAXVAL_GAIN;
+ else
+ hStaticGain->PostGain__FDK =
+ dmxGainTable__FDK[hStaticGain->fixedGainDMX - 1];
+
+ FDKmemclear(
+ hStaticGain->pPreGain__FDK,
+ sizeof(hStaticGain->pPreGain__FDK)); /* zero all input channels */
+
+ /* Configure PreGain-Vector */
+ if (hStaticGain->encMode == SACENC_212) {
+ hStaticGain->pPreGain__FDK[0] =
+ FX_DBL2FX_GAIN(fPreGainFactor__FDK); /* L */
+ hStaticGain->pPreGain__FDK[1] =
+ FX_DBL2FX_GAIN(fPreGainFactor__FDK); /* R */
+ } else {
+ error = SACENC_INVALID_CONFIG;
+ }
+
+ } /* valid handle */
+
+bail:
+
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_staticGain_Close()
+description: destructs Static Gains
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Close(HANDLE_STATIC_GAIN *phStaticGain) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((phStaticGain == NULL) || (*phStaticGain == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ FDKfree(*phStaticGain);
+ *phStaticGain = NULL;
+ }
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_staticPostGain_Apply
+description: multiply the Output samples with the PostGain
+returns: noError on success, an apropriate error code else
+-----------------------------------------------------------------------------*/
+FDK_SACENC_ERROR fdk_sacenc_staticPostGain_ApplyFDK(
+ const HANDLE_STATIC_GAIN hStaticGain, INT_PCM *const pOutputSamples,
+ const INT nOutputSamples, const INT scale) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hStaticGain) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i;
+ FIXP_GAIN postGain = hStaticGain->PostGain__FDK;
+
+ if (scale < 0) {
+ if (postGain == MAXVAL_GAIN) {
+ for (i = 0; i < nOutputSamples; i++) {
+ pOutputSamples[i] = pOutputSamples[i] >> (-scale);
+ }
+ } else {
+ for (i = 0; i < nOutputSamples; i++) {
+ pOutputSamples[i] = FX_DBL2FX_PCM(
+ fMult(postGain, FX_PCM2FX_DBL(pOutputSamples[i])) >> (-scale));
+ }
+ }
+ } else {
+ if (postGain == MAXVAL_GAIN) {
+ for (i = 0; i < nOutputSamples; i++) {
+ pOutputSamples[i] = FX_DBL2FX_PCM(SATURATE_LEFT_SHIFT(
+ FX_PCM2FX_DBL(pOutputSamples[i]), scale, DFRACT_BITS));
+ }
+ } else {
+ for (i = 0; i < nOutputSamples; i++) {
+ pOutputSamples[i] = FX_DBL2FX_PCM(SATURATE_LEFT_SHIFT(
+ fMult(postGain, FX_PCM2FX_DBL(pOutputSamples[i])), scale,
+ DFRACT_BITS));
+ }
+ }
+ }
+ }
+ return error;
+}
+
+/*-----------------------------------------------------------------------------
+functionname: fdk_sacenc_getPreGainPtr()/ fdk_sacenc_getPostGain()
+description: get Gain-Pointers from struct
+returns: Pointer to PreGain or postGain
+-----------------------------------------------------------------------------*/
+FIXP_GAIN *fdk_sacenc_getPreGainPtrFDK(HANDLE_STATIC_GAIN hStaticGain) {
+ return ((hStaticGain == NULL) ? NULL : hStaticGain->pPreGain__FDK);
+}
+
+FIXP_GAIN fdk_sacenc_getPostGainFDK(HANDLE_STATIC_GAIN hStaticGain) {
+ return (hStaticGain->PostGain__FDK);
+}
+
+/* get fixed downmix gain and map it to bitstream enum */
+FIXEDGAINDMXCONFIG fdk_sacenc_staticGain_GetDmxGain(
+ const HANDLE_STATIC_GAIN hStaticGain) {
+ FIXEDGAINDMXCONFIG dmxGain = FIXEDGAINDMX_INVALID;
+
+ switch (hStaticGain->fixedGainDMX) {
+ case 0:
+ dmxGain = FIXEDGAINDMX_0;
+ break;
+ case 1:
+ dmxGain = FIXEDGAINDMX_1;
+ break;
+ case 2:
+ dmxGain = FIXEDGAINDMX_2;
+ break;
+ case 3:
+ dmxGain = FIXEDGAINDMX_3;
+ break;
+ case 4:
+ dmxGain = FIXEDGAINDMX_4;
+ break;
+ case 5:
+ dmxGain = FIXEDGAINDMX_5;
+ break;
+ case 6:
+ dmxGain = FIXEDGAINDMX_6;
+ break;
+ case 7:
+ dmxGain = FIXEDGAINDMX_7;
+ break;
+ default:
+ dmxGain = FIXEDGAINDMX_INVALID;
+ }
+ return dmxGain;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_SetDmxGain(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainCfg,
+ const MP4SPACEENC_DMX_GAIN dmxGain) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hStaticGainCfg) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ hStaticGainCfg->fixedGainDMX = dmxGain;
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_SetEncMode(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainCfg, const MP4SPACEENC_MODE encMode) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if (NULL == hStaticGainCfg) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ hStaticGainCfg->encMode = encMode;
+ }
+ return error;
+}
diff --git a/fdk-aac/libSACenc/src/sacenc_staticgain.h b/fdk-aac/libSACenc/src/sacenc_staticgain.h
new file mode 100644
index 0000000..5db3bec
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_staticgain.h
@@ -0,0 +1,177 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Christian Goettlinger
+
+ Description: Encoder Library Interfac
+ gain management of the encoder
+
+*******************************************************************************/
+
+/**************************************************************************/ /**
+ \file
+ ******************************************************************************/
+
+#ifndef SACENC_STATICGAIN_H
+#define SACENC_STATICGAIN_H
+
+/* Includes ******************************************************************/
+#include "common_fix.h"
+#include "sacenc_lib.h"
+#include "sacenc_const.h"
+#include "sacenc_bitstream.h"
+
+/* Defines *******************************************************************/
+#define FIXP_GAIN FIXP_DBL
+#define MAXVAL_GAIN ((FIXP_DBL)MAXVAL_DBL)
+
+/* Data Types ****************************************************************/
+struct STATIC_GAIN_CONFIG {
+ MP4SPACEENC_MODE encMode;
+ MP4SPACEENC_DMX_GAIN fixedGainDMX;
+ INT preGainFactorDb;
+};
+
+typedef struct STATIC_GAIN_CONFIG *HANDLE_STATIC_GAIN_CONFIG;
+typedef struct STATIC_GAIN *HANDLE_STATIC_GAIN;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Initializes Static Gain Computation Config */
+FDK_SACENC_ERROR fdk_sacenc_staticGain_OpenConfig(
+ HANDLE_STATIC_GAIN_CONFIG *phStaticGainConfig);
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_InitDefaultConfig(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainConfig);
+
+/* Deletes Static Gain Computation Config ~Destructor */
+FDK_SACENC_ERROR fdk_sacenc_staticGain_CloseConfig(
+ HANDLE_STATIC_GAIN_CONFIG *phStaticGainConfig);
+
+/* Initializes Static Gain Computation ~Constructor */
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Open(HANDLE_STATIC_GAIN *phStaticGain);
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Init(
+ HANDLE_STATIC_GAIN hStaticGain,
+ const HANDLE_STATIC_GAIN_CONFIG hStaticGainConfig, INT *const scale);
+
+/* Deletes Static Gain Computation Infrastucture ~Destructor */
+FDK_SACENC_ERROR fdk_sacenc_staticGain_Close(HANDLE_STATIC_GAIN *phStaticGain);
+
+/* Apply PostGain to the output PCM Downmix-Signal */
+FDK_SACENC_ERROR fdk_sacenc_staticPostGain_ApplyFDK(
+ const HANDLE_STATIC_GAIN hStaticGain, INT_PCM *const pOutputSamples,
+ const INT nOutputSamples, const INT scale);
+
+/* Get Pointer to PreGain-vector */
+FIXP_GAIN *fdk_sacenc_getPreGainPtrFDK(HANDLE_STATIC_GAIN hStaticGain);
+
+/* Get Pointer to PostGain-coef */
+FIXP_GAIN fdk_sacenc_getPostGainFDK(HANDLE_STATIC_GAIN hStaticGain);
+
+FIXEDGAINDMXCONFIG fdk_sacenc_staticGain_GetDmxGain(
+ const HANDLE_STATIC_GAIN hStaticGain);
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_SetDmxGain(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainCfg,
+ const MP4SPACEENC_DMX_GAIN dmxGain);
+
+FDK_SACENC_ERROR fdk_sacenc_staticGain_SetEncMode(
+ HANDLE_STATIC_GAIN_CONFIG hStaticGainCfg, const MP4SPACEENC_MODE encMode);
+
+#endif /* SACENC_STATICGAIN_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_tree.cpp b/fdk-aac/libSACenc/src/sacenc_tree.cpp
new file mode 100644
index 0000000..c7d3128
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_tree.cpp
@@ -0,0 +1,488 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Tree Structure for Space Encoder
+
+*******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_tree.h"
+#include "genericStds.h"
+#include "sacenc_const.h"
+#include "sacenc_paramextract.h"
+#include "sacenc_framewindowing.h"
+#include "FDK_matrixCalloc.h"
+
+/* Defines *******************************************************************/
+enum { BOX_0 = 0, BOX_1 = 1 };
+
+enum { CH_L = 0, CH_R = 1 };
+
+enum { TTO_CH_0 = 0, TTO_CH_1 = 1 };
+
+enum { WIN_INACTIV = 0, WIN_ACTIV = 1 };
+
+enum { MAX_KEEP_FRAMECOUNT = 100 };
+
+/* Data Types ****************************************************************/
+struct SPACE_TREE {
+ SPACETREE_MODE mode;
+ SPACE_TREE_DESCRIPTION descr;
+ HANDLE_TTO_BOX ttoBox[SACENC_MAX_NUM_BOXES];
+ UCHAR nParamBands;
+ UCHAR bUseCoarseQuantTtoIcc;
+ UCHAR bUseCoarseQuantTtoCld;
+ QUANTMODE quantMode;
+ INT frameCount;
+ UCHAR bFrameKeep;
+
+ /* Intermediate buffers */
+ UCHAR pCld_prev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAM_BANDS];
+ UCHAR pIcc_prev[SACENC_MAX_NUM_BOXES][MAX_NUM_PARAM_BANDS];
+
+ UCHAR nChannelsInMax;
+ UCHAR nHybridBandsMax;
+};
+
+typedef struct {
+ UCHAR boxId;
+ UCHAR inCh1;
+ UCHAR inCh2;
+ UCHAR inCh3;
+ UCHAR inCh4;
+ UCHAR wCh1;
+ UCHAR wCh2;
+
+} TTO_DESCRIPTOR;
+
+typedef struct {
+ SPACETREE_MODE mode;
+ SPACE_TREE_DESCRIPTION treeDescription;
+
+} TREE_CONFIG;
+
+typedef struct {
+ SPACETREE_MODE mode;
+ UCHAR nChannelsIn;
+ UCHAR nChannelsOut;
+ UCHAR nTtoBoxes;
+ TTO_DESCRIPTOR tto_descriptor[1];
+
+} TREE_SETUP;
+
+/* Constants *****************************************************************/
+static const TREE_CONFIG treeConfigTable[] = {
+ {SPACETREE_INVALID_MODE, {0, 0, 0}}, {SPACETREE_212, {1, 1, 2}}};
+
+static const TREE_SETUP treeSetupTable[] = {
+ {SPACETREE_INVALID_MODE, 0, 0, 0, {{0, 0, 0, 0, 0, 0, 0}}},
+ {SPACETREE_212,
+ 2,
+ 1,
+ 1,
+ {{BOX_0, CH_L, CH_R, TTO_CH_0, TTO_CH_1, WIN_ACTIV, WIN_ACTIV}}}};
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+static FDK_SACENC_ERROR getTreeConfig(
+ const SPACETREE_MODE mode, SPACE_TREE_DESCRIPTION *pTreeDescription) {
+ FDK_SACENC_ERROR error = SACENC_INIT_ERROR;
+
+ if (pTreeDescription == NULL) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int i;
+ for (i = 0; i < (int)(sizeof(treeConfigTable) / sizeof(TREE_CONFIG)); i++) {
+ if (treeConfigTable[i].mode == mode) {
+ *pTreeDescription = treeConfigTable[i].treeDescription;
+ error = SACENC_OK;
+ break;
+ }
+ }
+ } /* valid handle */
+ return error;
+}
+
+static const TREE_SETUP *getTreeSetup(const SPACETREE_MODE mode) {
+ int i;
+ const TREE_SETUP *setup = NULL;
+
+ for (i = 0; i < (int)(sizeof(treeSetupTable) / sizeof(TREE_SETUP)); i++) {
+ if (treeSetupTable[i].mode == mode) {
+ setup = &treeSetupTable[i];
+ break;
+ }
+ }
+ return setup;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Open(HANDLE_SPACE_TREE *phSpaceTree) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+ HANDLE_SPACE_TREE hSpaceTree = NULL;
+
+ if (NULL == phSpaceTree) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int box;
+
+ FDK_ALLOCATE_MEMORY_1D(hSpaceTree, 1, struct SPACE_TREE);
+
+ for (box = 0; box < SACENC_MAX_NUM_BOXES; box++) {
+ HANDLE_TTO_BOX ttoBox = NULL;
+ if (SACENC_OK != (error = fdk_sacenc_createTtoBox(&ttoBox))) {
+ goto bail;
+ }
+ if (NULL != hSpaceTree) {
+ hSpaceTree->ttoBox[box] = ttoBox;
+ }
+ }
+ *phSpaceTree = hSpaceTree;
+ }
+ return error;
+
+bail:
+ fdk_sacenc_spaceTree_Close(&hSpaceTree);
+ return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
+}
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Init(
+ HANDLE_SPACE_TREE hST, const SPACE_TREE_SETUP *const hSetup,
+ UCHAR *pParameterBand2HybridBandOffset, const INT bFrameKeep) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hST == NULL) || (hSetup == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int bTtoBoxFrontBackCombin[SACENC_MAX_NUM_BOXES] = {0};
+ int box = 0;
+
+ hST->frameCount = 0;
+ hST->bFrameKeep = bFrameKeep;
+
+ /* Init */
+ hST->mode = hSetup->mode;
+ hST->nParamBands = hSetup->nParamBands;
+ hST->bUseCoarseQuantTtoIcc = hSetup->bUseCoarseQuantTtoIcc;
+ hST->bUseCoarseQuantTtoCld = hSetup->bUseCoarseQuantTtoCld;
+ hST->quantMode = hSetup->quantMode;
+ hST->nChannelsInMax = hSetup->nChannelsInMax;
+ hST->nHybridBandsMax = hSetup->nHybridBandsMax;
+
+ if (SACENC_OK != (error = getTreeConfig(hST->mode, &hST->descr))) {
+ goto bail;
+ }
+
+ switch (hST->mode) {
+ case SPACETREE_212:
+ bTtoBoxFrontBackCombin[BOX_0] = 0;
+ break;
+ case SPACETREE_INVALID_MODE:
+ default:
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ } /* switch (hST->mode) */
+
+ if (hST->descr.nOttBoxes > SACENC_MAX_NUM_BOXES) {
+ error = SACENC_INIT_ERROR;
+ goto bail;
+ }
+
+ for (box = 0; box < hST->descr.nOttBoxes; box++) {
+ TTO_BOX_CONFIG boxConfig;
+ boxConfig.subbandConfig = (BOX_SUBBAND_CONFIG)hST->nParamBands;
+ boxConfig.bUseCoarseQuantCld = hST->bUseCoarseQuantTtoCld;
+ boxConfig.bUseCoarseQuantIcc = hST->bUseCoarseQuantTtoIcc;
+ boxConfig.bUseCoherenceIccOnly = bTtoBoxFrontBackCombin[box];
+ boxConfig.boxQuantMode = (BOX_QUANTMODE)hST->quantMode;
+ boxConfig.nHybridBandsMax = hST->nHybridBandsMax;
+ boxConfig.bFrameKeep = hST->bFrameKeep;
+
+ if (SACENC_OK !=
+ (error = fdk_sacenc_initTtoBox(hST->ttoBox[box], &boxConfig,
+ pParameterBand2HybridBandOffset))) {
+ goto bail;
+ }
+ } /* for box */
+
+ } /* valid handle */
+
+bail:
+ return error;
+}
+
+static void SpaceTree_FrameKeep212(const HANDLE_SPACE_TREE hST,
+ SPATIALFRAME *const hSTOut,
+ const INT avoid_keep) {
+ int pb;
+
+ if (avoid_keep == 0) {
+ if (hST->frameCount % 2 == 0) {
+ for (pb = 0; pb < hST->nParamBands; pb++) {
+ hST->pIcc_prev[BOX_0][pb] = hSTOut->ottData.icc[BOX_0][0][pb];
+ hSTOut->ottData.cld[BOX_0][0][pb] = hST->pCld_prev[BOX_0][pb];
+ }
+ } else {
+ for (pb = 0; pb < hST->nParamBands; pb++) {
+ hSTOut->ottData.icc[BOX_0][0][pb] = hST->pIcc_prev[BOX_0][pb];
+ hST->pCld_prev[BOX_0][pb] = hSTOut->ottData.cld[BOX_0][0][pb];
+ }
+ }
+ } else {
+ for (pb = 0; pb < hST->nParamBands; pb++) {
+ hST->pIcc_prev[BOX_0][pb] = hSTOut->ottData.icc[BOX_0][0][pb];
+ hST->pCld_prev[BOX_0][pb] = hSTOut->ottData.cld[BOX_0][0][pb];
+ }
+ }
+ hST->frameCount++;
+ if (hST->frameCount == MAX_KEEP_FRAMECOUNT) {
+ hST->frameCount = 0;
+ }
+}
+
+static FDK_SACENC_ERROR SpaceTree_FrameKeep(const HANDLE_SPACE_TREE hST,
+ SPATIALFRAME *const hSTOut,
+ const INT avoid_keep) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ switch (hST->mode) {
+ case SPACETREE_212:
+ SpaceTree_FrameKeep212(hST, hSTOut, avoid_keep);
+ break;
+ case SPACETREE_INVALID_MODE:
+ default:
+ error = SACENC_INVALID_CONFIG;
+ break;
+ }
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Apply(
+ HANDLE_SPACE_TREE hST, const INT paramSet, const INT nChannelsIn,
+ const INT nTimeSlots, const INT startTimeSlot, const INT nHybridBands,
+ FIXP_WIN *pFrameWindowAna__FDK,
+ FIXP_DPK *const *const *const pppHybrid__FDK,
+ FIXP_DPK *const *const *const pppHybridIn__FDK, SPATIALFRAME *const hSTOut,
+ const INT avoid_keep, INT *pEncoderInputChScale) {
+ /** \verbatim
+ =============================================================================================================================
+ TREE_212
+ =============================================================================================================================
+ _______
+ L -- TTO_CH_0 --| |
+ | TTO_0 |-- TTO_CH_0
+ R -- TTO_CH_1 --|_______|
+
+ \endverbatim */
+
+ FDK_SACENC_ERROR error = SACENC_OK;
+ int k;
+ const TREE_SETUP *treeSetup = NULL;
+
+ if ((hST == NULL) || (hSTOut == NULL) || (pppHybrid__FDK == NULL) ||
+ (pppHybridIn__FDK == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ if ((treeSetup = getTreeSetup(hST->mode)) == NULL) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* Sanity Checks */
+ if ((nChannelsIn != treeSetup->nChannelsIn) ||
+ (nChannelsIn > hST->nChannelsInMax) ||
+ (nHybridBands > hST->nHybridBandsMax)) {
+ error = SACENC_INVALID_CONFIG;
+ goto bail;
+ }
+
+ /* Apply all TTO boxes. */
+ for (k = 0; k < treeSetup->nTtoBoxes; k++) {
+ const TTO_DESCRIPTOR *pTTO = &treeSetup->tto_descriptor[k];
+
+ int i, inCh[2], outCh[2], win[2];
+
+ inCh[0] = pTTO->inCh1;
+ outCh[0] = pTTO->inCh3;
+ win[0] = pTTO->wCh1;
+ inCh[1] = pTTO->inCh2;
+ outCh[1] = pTTO->inCh4;
+ win[1] = pTTO->wCh2;
+
+ for (i = 0; i < 2; i++) {
+ if (win[i] == WIN_ACTIV) {
+ fdk_sacenc_analysisWindowing(
+ nTimeSlots, startTimeSlot, pFrameWindowAna__FDK,
+ pppHybrid__FDK[inCh[i]], pppHybridIn__FDK[outCh[i]], nHybridBands,
+ FW_LEAVE_DIM);
+ }
+ }
+
+ /* Calculate output downmix within last TTO box, if no TTT box is applied.
+ */
+ if (SACENC_OK !=
+ (error = fdk_sacenc_applyTtoBox(
+ hST->ttoBox[pTTO->boxId], nTimeSlots, startTimeSlot, nHybridBands,
+ pppHybridIn__FDK[pTTO->inCh3], pppHybridIn__FDK[pTTO->inCh4],
+ hSTOut->ottData.icc[pTTO->boxId][paramSet],
+ &(hSTOut->ICCLosslessData.bsQuantCoarseXXX[pTTO->boxId][paramSet]),
+ hSTOut->ottData.cld[pTTO->boxId][paramSet],
+ &(hSTOut->CLDLosslessData.bsQuantCoarseXXX[pTTO->boxId][paramSet]),
+ hSTOut->bUseBBCues, &pEncoderInputChScale[inCh[0]],
+ &pEncoderInputChScale[inCh[1]]))) {
+ goto bail;
+ }
+ }
+
+ if (hST->bFrameKeep == 1) {
+ if (SACENC_OK != (error = SpaceTree_FrameKeep(hST, hSTOut, avoid_keep))) {
+ goto bail;
+ }
+ }
+
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Close(HANDLE_SPACE_TREE *phSpaceTree) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((phSpaceTree == NULL) || (*phSpaceTree == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ int box;
+ HANDLE_SPACE_TREE const hST = *phSpaceTree;
+
+ /* for (box = 0; box < hST->descr.nOttBoxes; ++box) { */
+ for (box = 0; box < SACENC_MAX_NUM_BOXES; ++box) {
+ if (SACENC_OK != (error = fdk_sacenc_destroyTtoBox(&hST->ttoBox[box]))) {
+ goto bail;
+ }
+ }
+
+ FDKfree(*phSpaceTree);
+ *phSpaceTree = NULL;
+ }
+bail:
+ return error;
+}
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_GetDescription(
+ const HANDLE_SPACE_TREE hSpaceTree,
+ SPACE_TREE_DESCRIPTION *pSpaceTreeDescription) {
+ FDK_SACENC_ERROR error = SACENC_OK;
+
+ if ((hSpaceTree == NULL) || (pSpaceTreeDescription == NULL)) {
+ error = SACENC_INVALID_HANDLE;
+ } else {
+ *pSpaceTreeDescription = hSpaceTree->descr;
+ }
+ return error;
+}
+
+INT fdk_sacenc_spaceTree_Hybrid2ParamBand(const INT nParamBands,
+ const INT nHybridBand) {
+ return fdk_sacenc_subband2ParamBand((BOX_SUBBAND_CONFIG)nParamBands,
+ nHybridBand);
+}
+
+/*****************************************************************************
+******************************************************************************/
diff --git a/fdk-aac/libSACenc/src/sacenc_tree.h b/fdk-aac/libSACenc/src/sacenc_tree.h
new file mode 100644
index 0000000..09f5b2b
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_tree.h
@@ -0,0 +1,168 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Max Neuendorf
+
+ Description: Encoder Library Interface
+ Tree Structure for Space Encoder
+
+*******************************************************************************/
+
+#ifndef SACENC_TREE_H
+#define SACENC_TREE_H
+
+/* Includes ******************************************************************/
+#include "sacenc_framewindowing.h"
+#include "sacenc_lib.h"
+#include "sacenc_bitstream.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+typedef enum {
+ SPACETREE_INVALID_MODE = 0,
+ SPACETREE_212 = 8
+
+} SPACETREE_MODE;
+
+typedef struct SPACE_TREE *HANDLE_SPACE_TREE;
+
+typedef struct {
+ UCHAR nParamBands;
+ UCHAR bUseCoarseQuantTtoCld;
+ UCHAR bUseCoarseQuantTtoIcc;
+ QUANTMODE quantMode;
+ SPACETREE_MODE mode;
+
+ UCHAR nChannelsInMax;
+ UCHAR nHybridBandsMax;
+
+} SPACE_TREE_SETUP;
+
+typedef struct {
+ UCHAR nOttBoxes;
+ UCHAR nInChannels;
+ UCHAR nOutChannels;
+
+} SPACE_TREE_DESCRIPTION;
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Open(HANDLE_SPACE_TREE *phSpaceTree);
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Init(
+ HANDLE_SPACE_TREE hST, const SPACE_TREE_SETUP *const hSetup,
+ UCHAR *pParameterBand2HybridBandOffset, const INT bFrameKeep);
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Apply(
+ HANDLE_SPACE_TREE hST, const INT paramSet, const INT nChannelsIn,
+ const INT nTimeSlots, const INT startTimeSlot, const INT nHybridBands,
+ FIXP_WIN *pFrameWindowAna__FDK,
+ FIXP_DPK *const *const *const pppHybrid__FDK,
+ FIXP_DPK *const *const *const pppHybridIn__FDK, SPATIALFRAME *const hSTOut,
+ const INT avoid_keep, INT *pEncoderInputChScale);
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_Close(HANDLE_SPACE_TREE *phSpaceTree);
+
+FDK_SACENC_ERROR fdk_sacenc_spaceTree_GetDescription(
+ const HANDLE_SPACE_TREE hSpaceTree,
+ SPACE_TREE_DESCRIPTION *pSpaceTreeDescription);
+
+INT fdk_sacenc_spaceTree_Hybrid2ParamBand(const INT nParamBands,
+ const INT nHybridBand);
+
+#endif /* SACENC_TREE_H */
diff --git a/fdk-aac/libSACenc/src/sacenc_vectorfunctions.cpp b/fdk-aac/libSACenc/src/sacenc_vectorfunctions.cpp
new file mode 100644
index 0000000..c1e24b7
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_vectorfunctions.cpp
@@ -0,0 +1,450 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Josef Hoepfl
+
+ Description: Encoder Library Interface
+ vector functions
+
+*******************************************************************************/
+
+/*****************************************************************************
+\file
+This file contains vector functions
+******************************************************************************/
+
+/* Includes ******************************************************************/
+#include "sacenc_vectorfunctions.h"
+
+/* Defines *******************************************************************/
+
+/* Data Types ****************************************************************/
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/* Function / Class Definition ***********************************************/
+
+FIXP_DBL sumUpCplxPow2(const FIXP_DPK *const x, const INT scaleMode,
+ const INT inScaleFactor, INT *const outScaleFactor,
+ const INT n) {
+ int i, cs;
+
+ if (scaleMode == SUM_UP_DYNAMIC_SCALE) {
+ /* calculate headroom */
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+ for (i = 0; i < n; i++) {
+ maxVal |= fAbs(x[i].v.re);
+ maxVal |= fAbs(x[i].v.im);
+ }
+ cs = inScaleFactor - fixMax(0, CntLeadingZeros(maxVal) - 1);
+ } else {
+ cs = inScaleFactor;
+ }
+
+ /* consider scaling of energy and scaling in fPow2Div2 and addition */
+ *outScaleFactor = 2 * cs + 2;
+
+ /* make sure that the scalefactor is in the range of -(DFRACT_BITS-1), ... ,
+ * (DFRACT_BITS-1) */
+ cs = fixMax(fixMin(cs, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
+
+ /* sum up complex energy samples */
+ FIXP_DBL re, im, sum;
+
+ re = im = sum = FL2FXCONST_DBL(0.0);
+ if (cs < 0) {
+ cs = -cs;
+ for (i = 0; i < n; i++) {
+ re += fPow2Div2(x[i].v.re << cs);
+ im += fPow2Div2(x[i].v.im << cs);
+ }
+ } else {
+ cs = 2 * cs;
+ for (i = 0; i < n; i++) {
+ re += fPow2Div2(x[i].v.re) >> cs;
+ im += fPow2Div2(x[i].v.im) >> cs;
+ }
+ }
+
+ sum = (re >> 1) + (im >> 1);
+
+ return (sum);
+}
+
+FIXP_DBL sumUpCplxPow2Dim2(const FIXP_DPK *const *const x, const INT scaleMode,
+ const INT inScaleFactor, INT *const outScaleFactor,
+ const INT sDim1, const INT nDim1, const INT sDim2,
+ const INT nDim2) {
+ int i, j, cs;
+
+ if (scaleMode == SUM_UP_DYNAMIC_SCALE) {
+ /* calculate headroom */
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ maxVal |= fAbs(x[i][j].v.re);
+ maxVal |= fAbs(x[i][j].v.im);
+ }
+ }
+ cs = inScaleFactor - fixMax(0, CntLeadingZeros(maxVal) - 1);
+ } else {
+ cs = inScaleFactor;
+ }
+
+ /* consider scaling of energy and scaling in fPow2Div2 and addition */
+ *outScaleFactor = 2 * cs + 2;
+
+ /* make sure that the scalefactor is in the range of -(DFRACT_BITS-1), ... ,
+ * (DFRACT_BITS-1) */
+ cs = fixMax(fixMin(cs, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
+
+ /* sum up complex energy samples */
+ FIXP_DBL re, im, sum;
+
+ re = im = sum = FL2FXCONST_DBL(0.0);
+ if (cs < 0) {
+ cs = -cs;
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ re += fPow2Div2(x[i][j].v.re << cs);
+ im += fPow2Div2(x[i][j].v.im << cs);
+ }
+ }
+ } else {
+ cs = 2 * cs;
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ re += fPow2Div2(x[i][j].v.re) >> cs;
+ im += fPow2Div2(x[i][j].v.im) >> cs;
+ }
+ }
+ }
+
+ sum = (re >> 1) + (im >> 1);
+
+ return (sum);
+}
+
+void copyCplxVec(FIXP_DPK *const Z, const FIXP_DPK *const X, const INT n) {
+ FDKmemmove(Z, X, sizeof(FIXP_DPK) * n);
+}
+
+void setCplxVec(FIXP_DPK *const Z, const FIXP_DBL a, const INT n) {
+ int i;
+
+ for (i = 0; i < n; i++) {
+ Z[i].v.re = a;
+ Z[i].v.im = a;
+ }
+}
+
+void cplx_cplxScalarProduct(FIXP_DPK *const Z, const FIXP_DPK *const *const X,
+ const FIXP_DPK *const *const Y, const INT scaleX,
+ const INT scaleY, INT *const scaleZ,
+ const INT sDim1, const INT nDim1, const INT sDim2,
+ const INT nDim2) {
+ int i, j, sx, sy;
+ FIXP_DBL xre, yre, xim, yim, re, im;
+
+ /* make sure that the scalefactor is in the range of -(DFRACT_BITS-1), ... ,
+ * (DFRACT_BITS-1) */
+ sx = fixMax(fixMin(scaleX, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
+ sy = fixMax(fixMin(scaleY, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
+
+ /* consider scaling of energy and scaling in fMultDiv2 and shift of result
+ * values */
+ *scaleZ = sx + sy + 2;
+
+ re = (FIXP_DBL)0;
+ im = (FIXP_DBL)0;
+ if ((sx < 0) && (sy < 0)) {
+ sx = -sx;
+ sy = -sy;
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ xre = X[i][j].v.re << sx;
+ xim = X[i][j].v.im << sx;
+ yre = Y[i][j].v.re << sy;
+ yim = Y[i][j].v.im << sy;
+ re += fMultDiv2(xre, yre) + fMultDiv2(xim, yim);
+ im += fMultDiv2(xim, yre) - fMultDiv2(xre, yim);
+ }
+ }
+ } else if ((sx >= 0) && (sy >= 0)) {
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ xre = X[i][j].v.re;
+ xim = X[i][j].v.im;
+ yre = Y[i][j].v.re;
+ yim = Y[i][j].v.im;
+ re += (fMultDiv2(xre, yre) + fMultDiv2(xim, yim)) >> (sx + sy);
+ im += (fMultDiv2(xim, yre) - fMultDiv2(xre, yim)) >> (sx + sy);
+ }
+ }
+ } else if ((sx < 0) && (sy >= 0)) {
+ sx = -sx;
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ xre = X[i][j].v.re << sx;
+ xim = X[i][j].v.im << sx;
+ yre = Y[i][j].v.re;
+ yim = Y[i][j].v.im;
+ re += (fMultDiv2(xre, yre) + fMultDiv2(xim, yim)) >> sy;
+ im += (fMultDiv2(xim, yre) - fMultDiv2(xre, yim)) >> sy;
+ }
+ }
+ } else {
+ sy = -sy;
+ for (i = sDim1; i < nDim1; i++) {
+ for (j = sDim2; j < nDim2; j++) {
+ xre = X[i][j].v.re;
+ xim = X[i][j].v.im;
+ yre = Y[i][j].v.re << sy;
+ yim = Y[i][j].v.im << sy;
+ re += (fMultDiv2(xre, yre) + fMultDiv2(xim, yim)) >> sx;
+ im += (fMultDiv2(xim, yre) - fMultDiv2(xre, yim)) >> sx;
+ }
+ }
+ }
+
+ Z->v.re = re >> 1;
+ Z->v.im = im >> 1;
+}
+
+void FDKcalcCorrelationVec(FIXP_DBL *const z, const FIXP_DBL *const pr12,
+ const FIXP_DBL *const p1, const FIXP_DBL *const p2,
+ const INT n) {
+ int i, s;
+ FIXP_DBL p12, cor;
+
+ /* correlation */
+ for (i = 0; i < n; i++) {
+ p12 = fMult(p1[i], p2[i]);
+ if (p12 > FL2FXCONST_DBL(0.0f)) {
+ p12 = invSqrtNorm2(p12, &s);
+ cor = fMult(pr12[i], p12);
+ z[i] = SATURATE_LEFT_SHIFT(cor, s, DFRACT_BITS);
+ } else {
+ z[i] = (FIXP_DBL)MAXVAL_DBL;
+ }
+ }
+}
+
+void calcCoherenceVec(FIXP_DBL *const z, const FIXP_DBL *const p12r,
+ const FIXP_DBL *const p12i, const FIXP_DBL *const p1,
+ const FIXP_DBL *const p2, const INT scaleP12,
+ const INT scaleP, const INT n) {
+ int i, s, s1, s2;
+ FIXP_DBL coh, p12, p12ri;
+
+ for (i = 0; i < n; i++) {
+ s2 = fixMin(fixMax(0, CountLeadingBits(p12r[i]) - 1),
+ fixMax(0, CountLeadingBits(p12i[i]) - 1));
+ p12ri = sqrtFixp(fPow2Div2(p12r[i] << s2) + fPow2Div2(p12i[i] << s2));
+ s1 = fixMin(fixMax(0, CountLeadingBits(p1[i]) - 1),
+ fixMax(0, CountLeadingBits(p2[i]) - 1));
+ p12 = fMultDiv2(p1[i] << s1, p2[i] << s1);
+
+ if (p12 > FL2FXCONST_DBL(0.0f)) {
+ p12 = invSqrtNorm2(p12, &s);
+ coh = fMult(p12ri, p12);
+ s = fixMax(fixMin((scaleP12 - scaleP + s + s1 - s2), DFRACT_BITS - 1),
+ -(DFRACT_BITS - 1));
+ if (s < 0) {
+ z[i] = coh >> (-s);
+ } else {
+ z[i] = SATURATE_LEFT_SHIFT(coh, s, DFRACT_BITS);
+ }
+ } else {
+ z[i] = (FIXP_DBL)MAXVAL_DBL;
+ }
+ }
+}
+
+void addWeightedCplxVec(FIXP_DPK *const *const Z, const FIXP_DBL *const a,
+ const FIXP_DPK *const *const X, const FIXP_DBL *const b,
+ const FIXP_DPK *const *const Y, const INT scale,
+ INT *const scaleCh1, const INT scaleCh2,
+ const UCHAR *const pParameterBand2HybridBandOffset,
+ const INT nParameterBands, const INT nTimeSlots,
+ const INT startTimeSlot) {
+ int pb, j, i;
+ int cs, s1, s2;
+
+ /* determine maximum scale of both channels */
+ cs = fixMax(*scaleCh1, scaleCh2);
+ s1 = cs - (*scaleCh1);
+ s2 = cs - scaleCh2;
+
+ /* scalefactor 1 is updated with common scale of channel 1 and channel2 */
+ *scaleCh1 = cs;
+
+ /* scale of a and b; additional scale for fMultDiv2() */
+ for (j = 0, pb = 0; pb < nParameterBands; pb++) {
+ FIXP_DBL aPb, bPb;
+ aPb = a[pb], bPb = b[pb];
+ for (; j < pParameterBand2HybridBandOffset[pb]; j++) {
+ for (i = startTimeSlot; i < nTimeSlots; i++) {
+ Z[j][i].v.re = ((fMultDiv2(aPb, X[j][i].v.re) >> s1) +
+ (fMultDiv2(bPb, Y[j][i].v.re) >> s2))
+ << (scale + 1);
+ Z[j][i].v.im = ((fMultDiv2(aPb, X[j][i].v.im) >> s1) +
+ (fMultDiv2(bPb, Y[j][i].v.im) >> s2))
+ << (scale + 1);
+ }
+ }
+ }
+}
+
+void FDKcalcPbScaleFactor(const FIXP_DPK *const *const x,
+ const UCHAR *const pParameterBand2HybridBandOffset,
+ INT *const outScaleFactor, const INT startTimeSlot,
+ const INT nTimeSlots, const INT nParamBands) {
+ int i, j, pb;
+
+ /* calculate headroom */
+ for (j = 0, pb = 0; pb < nParamBands; pb++) {
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+ for (; j < pParameterBand2HybridBandOffset[pb]; j++) {
+ for (i = startTimeSlot; i < nTimeSlots; i++) {
+ maxVal |= fAbs(x[i][j].v.re);
+ maxVal |= fAbs(x[i][j].v.im);
+ }
+ }
+ outScaleFactor[pb] = -fixMax(0, CntLeadingZeros(maxVal) - 1);
+ }
+}
+
+INT FDKcalcScaleFactor(const FIXP_DBL *const x, const FIXP_DBL *const y,
+ const INT n) {
+ int i;
+
+ /* calculate headroom */
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+ if (x != NULL) {
+ for (i = 0; i < n; i++) {
+ maxVal |= fAbs(x[i]);
+ }
+ }
+
+ if (y != NULL) {
+ for (i = 0; i < n; i++) {
+ maxVal |= fAbs(y[i]);
+ }
+ }
+
+ if (maxVal == (FIXP_DBL)0)
+ return (-(DFRACT_BITS - 1));
+ else
+ return (-CountLeadingBits(maxVal));
+}
+
+INT FDKcalcScaleFactorDPK(const FIXP_DPK *RESTRICT x, const INT startBand,
+ const INT bands) {
+ INT qs, clz;
+ FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+
+ for (qs = startBand; qs < bands; qs++) {
+ maxVal |= fAbs(x[qs].v.re);
+ maxVal |= fAbs(x[qs].v.im);
+ }
+
+ clz = -fixMax(0, CntLeadingZeros(maxVal) - 1);
+
+ return (clz);
+}
diff --git a/fdk-aac/libSACenc/src/sacenc_vectorfunctions.h b/fdk-aac/libSACenc/src/sacenc_vectorfunctions.h
new file mode 100644
index 0000000..e9c4abd
--- /dev/null
+++ b/fdk-aac/libSACenc/src/sacenc_vectorfunctions.h
@@ -0,0 +1,488 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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 surround encoder library *************************
+
+ Author(s): Josef Hoepfl
+
+ Description: Encoder Library Interface
+ vector functions
+
+*******************************************************************************/
+
+/*****************************************************************************
+\file
+This file contains vector functions
+******************************************************************************/
+
+#ifndef SACENC_VECTORFUNCTIONS_H
+#define SACENC_VECTORFUNCTIONS_H
+
+/* Includes ******************************************************************/
+#include "common_fix.h"
+
+/* Defines *******************************************************************/
+#define SUM_UP_STATIC_SCALE 0
+#define SUM_UP_DYNAMIC_SCALE 1
+
+/* Data Types ****************************************************************/
+
+/* Constants *****************************************************************/
+
+/* Function / Class Declarations *********************************************/
+
+/**
+ * \brief Vector function : Sum up complex power
+ *
+ * Description : ret = sum( re{X[i]} * re{X[i]} + im{X[i]} *
+ * im{X[i]} ), i=0,...,n-1 ret is scaled by outScaleFactor
+ *
+ * \param const FIXP_DPK x[]
+ * Input: complex vector of the length n
+ *
+ * \param int scaleMode
+ * Input: choose static or dynamic scaling
+ * (SUM_UP_DYNAMIC_SCALE/SUM_UP_STATIC_SCALE)
+ *
+ * \param int inScaleFactor
+ * Input: determine headroom bits for the complex input vector
+ *
+ * \param int outScaleFactor
+ * Output: complete scaling in energy calculation
+ *
+ * \return FIXP_DBL ret
+ */
+FIXP_DBL sumUpCplxPow2(const FIXP_DPK *const x, const INT scaleMode,
+ const INT inScaleFactor, INT *const outScaleFactor,
+ const INT n);
+
+/**
+ * \brief Vector function : Sum up complex power
+ *
+ * Description : ret = sum( re{X[i][j]} * re{X[i][]} +
+ * im{X[i][]} * im{X[i][]} ), i=sDim1,...,nDim1-1 i=sDim2,...,nDim2-1 ret is
+ * scaled by outScaleFactor
+ *
+ * \param const FIXP_DPK x[]
+ * Input: complex vector of the length n
+ *
+ * \param int scaleMode
+ * Input: choose static or dynamic scaling
+ * (SUM_UP_DYNAMIC_SCALE/SUM_UP_STATIC_SCALE)
+ *
+ * \param int inScaleFactor
+ * Input: determine headroom bits for the complex input vector
+ *
+ * \param int outScaleFactor
+ * Output: complete scaling in energy calculation
+ *
+ * \param int sDim1
+ * Input: start index for loop counter in dimension 1
+ *
+ * \param int nDim1
+ * Input: loop counter in dimension 1
+ *
+ * \param int sDim2
+ * Input: start index for loop counter in dimension 2
+ *
+ * \param int nDim2
+ * Input: loop counter in dimension 2
+ *
+ * \return FIXP_DBL ret
+ */
+FIXP_DBL sumUpCplxPow2Dim2(const FIXP_DPK *const *const x, const INT scaleMode,
+ const INT inScaleFactor, INT *const outScaleFactor,
+ const INT sDim1, const INT nDim1, const INT sDim2,
+ const INT nDim2);
+
+/**
+ * \brief Vector function : Z[i] = X[i], i=0,...,n-1
+ *
+ * Description : re{Z[i]} = re{X[i]}, i=0,...,n-1
+ * im{Z[i]} = im{X[i]}, i=0,...,n-1
+ *
+ * Copy complex vector X[] to complex vector Z[].
+ * It is allowed to overlay X[] with Z[].
+ *
+ * \param FIXP_DPK Z[]
+ * Output: vector of the length n
+ *
+ * \param const FIXP_DPK X[]
+ * Input: vector of the length n
+ *
+ * \param int n
+ * Input: length of vector Z[] and X[]
+ *
+ * \return void
+ */
+void copyCplxVec(FIXP_DPK *const Z, const FIXP_DPK *const X, const INT n);
+
+/**
+ * \brief Vector function : Z[i] = a, i=0,...,n-1
+ *
+ * Description : re{Z[i]} = a, i=0,...,n-1
+ * im{Z[i]} = a, i=0,...,n-1
+ *
+ * Set real and imaginary part of the complex value Z to a.
+ *
+ * \param FIPX_DPK Z[]
+ * Output: vector of the length n
+ *
+ * \param const FIXP_DBL a
+ * Input: constant value
+ *
+ * \param int n
+ * Input: length of vector Z[]
+ *
+ * \return void
+ */
+void setCplxVec(FIXP_DPK *const Z, const FIXP_DBL a, const INT n);
+
+/**
+ * \brief Vector function : Calculate complex-valued result of complex
+ * scalar product
+ *
+ * Description : re{Z} = sum( re{X[i]} * re{Y[i]} + im{X[i]} *
+ * im{Y[i]}, i=0,...,n-1 ) im{Z} = sum( im{X[i]} * re{Y[i]} - re{X[i]} *
+ * im{Y[i]}, i=0,...,n-1 )
+ *
+ * The function returns the complex-valued result of the complex
+ * scalar product at the address of Z. The result is scaled by scaleZ.
+ *
+ * \param FIXP_DPK *Z
+ * Output: pointer to Z
+ *
+ * \param const FIXP_DPK *const *const X
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DPK *const *const Y
+ * Input: vector of the length n
+ *
+ * \param int scaleX
+ * Input: scalefactor of vector X[]
+ *
+ * \param int scaleY
+ * Input: scalefactor of vector Y[]
+ *
+ * \param int scaleZ
+ * Output: scalefactor of vector Z[]
+ *
+ * \param int sDim1
+ * Input: start index for loop counter in dimension 1
+ *
+ * \param int nDim1
+ * Input: loop counter in dimension 1
+ *
+ * \param int sDim2
+ * Input: start index for loop counter in dimension 2
+ *
+ * \param int nDim2
+ * Input: loop counter in dimension 2
+ *
+ * \return void
+ */
+void cplx_cplxScalarProduct(FIXP_DPK *const Z, const FIXP_DPK *const *const X,
+ const FIXP_DPK *const *const Y, const INT scaleX,
+ const INT scaleY, INT *const scaleZ,
+ const INT sDim1, const INT nDim1, const INT sDim2,
+ const INT nDim2);
+
+/**
+ * \brief Vector function : Calculate correlation
+ *
+ * Description : z[i] = pr12[i] / sqrt(p1[i]*p2[i]) ,
+ * i=0,...,n-1
+ *
+ * \param FIXP_DBL z[]
+ * Output: vector of length n
+ *
+ * \param const FIXP_DBL pr12[]
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DBL p1[]
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DBL p2[]
+ * Input: vector of the length n
+ *
+ * \param int n
+ * Input: length of vector pr12[], p1[] and p2[]
+ *
+ * \return void
+ */
+void FDKcalcCorrelationVec(FIXP_DBL *const z, const FIXP_DBL *const pr12,
+ const FIXP_DBL *const p1, const FIXP_DBL *const p2,
+ const INT n);
+
+/**
+ * \brief Vector function : Calculate coherence
+ *
+ * Description : z[i] = sqrt( (p12r[i]*p12r[i] +
+ * p12i[i]*p12i[i]) / (p1[i]*p2[i]) ), i=0,...,n-1
+ *
+ * \param FIXP_DBL z[]
+ * Output: vector of length n
+ *
+ * \param const FIXP_DBL p12r[]
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DBL p12i[]
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DBL p1[]
+ * Input: vector of the length n
+ *
+ * \param const FIXP_DBL p2[]
+ * Input: vector of the length n
+ *
+ * \param int scaleP12[]
+ * Input: scalefactor of p12r and p12i
+ *
+ * \param int scaleP
+ * Input: scalefactor of p1 and p2
+ *
+ * \param int n
+ * Input: length of vector p12r[], p12i[], p1[] and p2[]
+ *
+ * \return void
+ */
+void calcCoherenceVec(FIXP_DBL *const z, const FIXP_DBL *const p12r,
+ const FIXP_DBL *const p12i, const FIXP_DBL *const p1,
+ const FIXP_DBL *const p2, const INT scaleP12,
+ const INT scaleP, const INT n);
+
+/**
+ * \brief Vector function : Z[j][i] = a[pb] * X[j][i] + b[pb] *
+ * Y[j][i], j=0,...,nHybridBands-1; i=startTimeSlot,...,nTimeSlots-1;
+ * pb=0,...,nParameterBands-1
+ *
+ * Description : re{Z[j][i]} = a[pb] * re{X[j][i]} + b[pb] *
+ * re{Y[j][i]}, j=0,...,nHybridBands-1; i=startTimeSlot,...,nTimeSlots-1;
+ * pb=0,...,nParameterBands-1 im{Z[j][i]} = a[pb] * im{X[j][i]} + b[pb] *
+ * im{Y[j][i]}, j=0,...,nHybridBands-1;
+ * i=startTimeSlot,...,nTimeSlots-1; pb=0,...,nParameterBands-1
+ *
+ * It is allowed to overlay X[] or Y[] with Z[]. The scalefactor
+ * of channel 1 is updated with the common scalefactor of channel 1 and
+ * channel 2.
+ *
+ * \param FIXP_DPK **Z
+ * Output: vector of the length nHybridBands*nTimeSlots
+ *
+ * \param const FIXP_DBL *a
+ * Input: vector of length nParameterBands
+ *
+ * \param const FIXP_DPK **X
+ * Input: vector of the length nHybridBands*nTimeSlots
+ *
+ * \param const FIXP_DBL *b
+ * Input: vector of length nParameterBands
+ *
+ * \param const FIXP_DPK **Y
+ * Input: vector of the length nHybridBands*nTimeSlots
+ *
+ * \param int scale
+ * Input: scale of vector a and b
+ *
+ * \param int *scaleCh1
+ * Input: scale of ch1
+ *
+ * \param int scaleCh2
+ * Input: scale of ch2
+ *
+ * \param UCHAR *pParameterBand2HybridBandOffset
+ * Input: vector of length nParameterBands
+ *
+ * \param int nTimeSlots
+ * Input: number of time slots
+ *
+ * \param int startTimeSlot
+ * Input: start time slot
+ *
+ * \return void
+ */
+void addWeightedCplxVec(FIXP_DPK *const *const Z, const FIXP_DBL *const a,
+ const FIXP_DPK *const *const X, const FIXP_DBL *const b,
+ const FIXP_DPK *const *const Y, const INT scale,
+ INT *const scaleCh1, const INT scaleCh2,
+ const UCHAR *const pParameterBand2HybridBandOffset,
+ const INT nParameterBands, const INT nTimeSlots,
+ const INT startTimeSlot);
+
+/**
+ * \brief Vector function : Calculate the headroom of a complex vector
+ * in a parameter band grid
+ *
+ * \param FIXP_DPK **x
+ * Input: pointer to complex input vector
+ *
+ * \param UCHAR *pParameterBand2HybridBandOffset
+ * Input: pointer to hybrid band offsets
+ *
+ * \param int *outScaleFactor
+ * Input: pointer to ouput scalefactor
+ *
+ * \param int startTimeSlot
+ * Input: start time slot
+ *
+ * \param int nTimeSlots
+ * Input: number of time slot
+ *
+ * \param int nParamBands
+ * Input: number of parameter bands
+ *
+ * \return void
+ */
+void FDKcalcPbScaleFactor(const FIXP_DPK *const *const x,
+ const UCHAR *const pParameterBand2HybridBandOffset,
+ INT *const outScaleFactor, const INT startTimeSlot,
+ const INT nTimeSlots, const INT nParamBands);
+
+/**
+ * \brief Vector function : Calculate the common headroom of two
+ * sparate vectors
+ *
+ * \param FIXP_DBL *x
+ * Input: pointer to first input vector
+ *
+ * \param FIXP_DBL *y
+ * Input: pointer to second input vector
+ *
+ * \param int n
+ * Input: number of samples
+ *
+ * \return int headromm in bits
+ */
+INT FDKcalcScaleFactor(const FIXP_DBL *const x, const FIXP_DBL *const y,
+ const INT n);
+
+/**
+ * \brief Vector function : Calculate the headroom of a complex vector
+ *
+ * \param FIXP_DPK *x
+ * Input: pointer to complex input vector
+ *
+ * \param INT startBand
+ * Input: start band
+ *
+ * \param INT bands
+ * Input: number of bands
+ *
+ * \return int headromm in bits
+ */
+INT FDKcalcScaleFactorDPK(const FIXP_DPK *RESTRICT x, const INT startBand,
+ const INT bands);
+
+/* Function / Class Definition ***********************************************/
+template <class T>
+inline void FDKmemcpy_flex(T *const dst, const INT dstStride,
+ const T *const src, const INT srcStride,
+ const INT nSamples) {
+ int i;
+
+ for (i = 0; i < nSamples; i++) {
+ dst[i * dstStride] = src[i * srcStride];
+ }
+}
+
+template <class T>
+inline void FDKmemset_flex(T *const x, const T c, const INT nSamples) {
+ int i;
+
+ for (i = 0; i < nSamples; i++) {
+ x[i] = c;
+ }
+}
+
+#endif /* SACENC_VECTORFUNCTIONS_H */
diff --git a/fdk-aac/libSBRdec/include/sbrdecoder.h b/fdk-aac/libSBRdec/include/sbrdecoder.h
new file mode 100644
index 0000000..cc55572
--- /dev/null
+++ b/fdk-aac/libSBRdec/include/sbrdecoder.h
@@ -0,0 +1,401 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description: SBR decoder front-end prototypes and definitions.
+
+*******************************************************************************/
+
+#ifndef SBRDECODER_H
+#define SBRDECODER_H
+
+#include "common_fix.h"
+
+#include "FDK_bitstream.h"
+#include "FDK_audio.h"
+
+#include "FDK_qmf_domain.h"
+
+#define SBR_DEBUG_EXTHLP \
+ "\
+--- SBR ---\n\
+ 0x00000010 Ancillary data and SBR-Header\n\
+ 0x00000020 SBR-Side info\n\
+ 0x00000040 Decoded SBR-bitstream data, e.g. envelope data\n\
+ 0x00000080 SBR-Bitstream statistics\n\
+ 0x00000100 Miscellaneous SBR-messages\n\
+ 0x00000200 SBR-Energies and gains in the adjustor\n\
+ 0x00000400 Fatal SBR errors\n\
+ 0x00000800 Transposer coefficients for inverse filtering\n\
+"
+
+/* Capability flags */
+#define CAPF_SBR_LP \
+ 0x00000001 /*!< Flag indicating library's capability of Low Power mode. */
+#define CAPF_SBR_HQ \
+ 0x00000002 /*!< Flag indicating library's capability of High Quality mode. \
+ */
+#define CAPF_SBR_DRM_BS \
+ 0x00000004 /*!< Flag indicating library's capability to decode DRM SBR data. \
+ */
+#define CAPF_SBR_CONCEALMENT \
+ 0x00000008 /*!< Flag indicating library's capability to conceal erroneous \
+ frames. */
+#define CAPF_SBR_DRC \
+ 0x00000010 /*!< Flag indicating library's capability for Dynamic Range \
+ Control. */
+#define CAPF_SBR_PS_MPEG \
+ 0x00000020 /*!< Flag indicating library's capability to do MPEG Parametric \
+ Stereo. */
+#define CAPF_SBR_PS_DRM \
+ 0x00000040 /*!< Flag indicating library's capability to do DRM Parametric \
+ Stereo. */
+#define CAPF_SBR_ELD_DOWNSCALE \
+ 0x00000080 /*!< Flag indicating library's capability to do ELD decoding in \
+ downscaled mode */
+#define CAPF_SBR_HBEHQ \
+ 0x00000100 /*!< Flag indicating library's capability to do HQ Harmonic \
+ transposing */
+
+typedef enum {
+ SBRDEC_OK = 0, /*!< All fine. */
+ /* SBRDEC_CONCEAL, */
+ /* SBRDEC_NOSYNCH, */
+ /* SBRDEC_ILLEGAL_PROGRAM, */
+ /* SBRDEC_ILLEGAL_TAG, */
+ /* SBRDEC_ILLEGAL_CHN_CONFIG, */
+ /* SBRDEC_ILLEGAL_SECTION, */
+ /* SBRDEC_ILLEGAL_SCFACTORS, */
+ /* SBRDEC_ILLEGAL_PULSE_DATA, */
+ /* SBRDEC_MAIN_PROFILE_NOT_IMPLEMENTED, */
+ /* SBRDEC_GC_NOT_IMPLEMENTED, */
+ /* SBRDEC_ILLEGAL_PLUS_ELE_ID, */
+ SBRDEC_INVALID_ARGUMENT, /*!< */
+ SBRDEC_CREATE_ERROR, /*!< */
+ SBRDEC_NOT_INITIALIZED, /*!< */
+ SBRDEC_MEM_ALLOC_FAILED, /*!< Memory allocation failed. Probably not enough
+ memory available. */
+ SBRDEC_PARSE_ERROR, /*!< */
+ SBRDEC_UNSUPPORTED_CONFIG, /*!< */
+ SBRDEC_SET_PARAM_FAIL, /*!< */
+ SBRDEC_OUTPUT_BUFFER_TOO_SMALL /*!< */
+} SBR_ERROR;
+
+typedef enum {
+ SBR_SYSTEM_BITSTREAM_DELAY, /*!< System: Switch to enable an additional SBR
+ bitstream delay of one frame. */
+ SBR_QMF_MODE, /*!< Set QMF mode, either complex or low power. */
+ SBR_LD_QMF_TIME_ALIGN, /*!< Set QMF type, either LD-MPS or CLDFB. Relevant for
+ ELD streams only. */
+ SBR_FLUSH_DATA, /*!< Set internal state to flush the decoder with the next
+ process call. */
+ SBR_CLEAR_HISTORY, /*!< Clear all internal states (delay lines, QMF states,
+ ...). */
+ SBR_BS_INTERRUPTION /*!< Signal bit stream interruption. Value is ignored. */
+ ,
+ SBR_SKIP_QMF /*!< Enable skipping of QMF step: 1 skip analysis, 2 skip
+ synthesis */
+} SBRDEC_PARAM;
+
+typedef struct SBR_DECODER_INSTANCE *HANDLE_SBRDECODER;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Allocates and initializes one SBR decoder instance.
+ * \param pSelf Pointer to where a SBR decoder handle is copied into.
+ * \param pQmfDomain Pointer to QMF domain data structure.
+ *
+ * \return Error code.
+ */
+SBR_ERROR sbrDecoder_Open(HANDLE_SBRDECODER *pSelf,
+ HANDLE_FDK_QMF_DOMAIN pQmfDomain);
+
+/**
+ * \brief Initialize a SBR decoder runtime instance. Must be called before
+ * decoding starts.
+ *
+ * \param self Handle to a SBR decoder instance.
+ * \param sampleRateIn Input samplerate of the SBR decoder instance.
+ * \param sampleRateOut Output samplerate of the SBR decoder instance.
+ * \param samplesPerFrame Number of samples per frames.
+ * \param coreCodec Audio Object Type (AOT) of the core codec.
+ * \param elementID Table with MPEG-4 element Ids in canonical order.
+ * \param elementIndex SBR element index
+ * \param harmonicSBR
+ * \param stereoConfigIndex
+ * \param downscaleFactor ELD downscale factor
+ * \param configMode Table with MPEG-4 element Ids in canonical order.
+ * \param configChanged Flag that enforces a complete decoder reset.
+ *
+ * \return Error code.
+ */
+SBR_ERROR sbrDecoder_InitElement(
+ HANDLE_SBRDECODER self, const int sampleRateIn, const int sampleRateOut,
+ const int samplesPerFrame, const AUDIO_OBJECT_TYPE coreCodec,
+ const MP4_ELEMENT_ID elementID, const int elementIndex,
+ const UCHAR harmonicSBR, const UCHAR stereoConfigIndex,
+ const UCHAR configMode, UCHAR *configChanged, const INT downscaleFactor);
+
+/**
+ * \brief Free config dependent SBR memory.
+ * \param self SBR decoder instance handle
+ */
+SBR_ERROR sbrDecoder_FreeMem(HANDLE_SBRDECODER *self);
+
+/**
+ * \brief pass out of band SBR header to SBR decoder
+ *
+ * \param self Handle to a SBR decoder instance.
+ * \param hBs bit stream handle data source.
+ * \param sampleRateIn SBR input sampling rate
+ * \param sampleRateOut SBR output sampling rate
+ * \param samplesPerFrame frame length
+ * \param elementID SBR element ID.
+ * \param elementIndex SBR element index.
+ * \param harmonicSBR
+ * \param stereoConfigIndex
+ * \param downscaleFactor ELD downscale factor
+ *
+ * \return Error code.
+ */
+INT sbrDecoder_Header(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
+ const INT sampleRateIn, const INT sampleRateOut,
+ const INT samplesPerFrame,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const MP4_ELEMENT_ID elementID, const INT elementIndex,
+ const UCHAR harmonicSBR, const UCHAR stereoConfigIndex,
+ const UCHAR configMode, UCHAR *configChanged,
+ const INT downscaleFactor);
+
+/**
+ * \brief Set a parameter of the SBR decoder runtime instance.
+ * \param self SBR decoder handle.
+ * \param param Parameter which will be set if successfull.
+ * \param value New parameter value.
+ * \return Error code.
+ */
+SBR_ERROR sbrDecoder_SetParam(HANDLE_SBRDECODER self, const SBRDEC_PARAM param,
+ const INT value);
+
+/**
+ * \brief Feed DRC channel data into a SBR decoder runtime instance.
+ *
+ * \param self SBR decoder handle.
+ * \param ch Channel number to which the DRC data is
+ * associated to.
+ * \param numBands Number of DRC bands.
+ * \param pNextFact_mag Pointer to a table with the DRC factor
+ * magnitudes.
+ * \param nextFact_exp Exponent for all DRC factors.
+ * \param drcInterpolationScheme DRC interpolation scheme.
+ * \param winSequence Window sequence from core coder (eight short
+ * or one long window).
+ * \param pBandTop Pointer to a table with the top borders for
+ * all DRC bands.
+ *
+ * \return Error code.
+ */
+SBR_ERROR sbrDecoder_drcFeedChannel(HANDLE_SBRDECODER self, INT ch,
+ UINT numBands, FIXP_DBL *pNextFact_mag,
+ INT nextFact_exp,
+ SHORT drcInterpolationScheme,
+ UCHAR winSequence, USHORT *pBandTop);
+
+/**
+ * \brief Disable SBR DRC for a certain channel.
+ *
+ * \param hSbrDecoder SBR decoder handle.
+ * \param ch Number of the channel that has to be disabled.
+ *
+ * \return None.
+ */
+void sbrDecoder_drcDisable(HANDLE_SBRDECODER self, INT ch);
+
+/**
+ * \brief Parse one SBR element data extension data block. The bit stream
+ * position will be placed at the end of the SBR payload block. The remaining
+ * bits will be returned 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 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 hBs Bit stream handle as data source.
+ * \param count Pointer to an integer where the amount of parsed SBR
+ * payload bits is stored into.
+ * \param bsPayLen If > 0 this value is the SBR payload length. If < 0,
+ * the SBR payload length is unknown.
+ * \param flags CRC flag (0: EXT_SBR_DATA; 1: EXT_SBR_DATA_CRC)
+ * \param prev_element Previous MPEG-4 element ID.
+ * \param element_index Index of the current element.
+ * \param acFlags Audio codec flags
+ *
+ * \return Error code.
+ */
+SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
+ UCHAR *pDrmBsBuffer, USHORT drmBsBufferSize,
+ int *count, int bsPayLen, int crcFlag,
+ MP4_ELEMENT_ID prev_element, int element_index,
+ UINT acFlags, UINT acElFlags[]);
+
+/**
+ * \brief This function decodes the given SBR bitstreams and applies SBR to the
+ * given time data.
+ *
+ * SBR-processing works InPlace. I.e. the calling function has to provide
+ * a time domain buffer timeData which can hold the completely decoded
+ * result.
+ *
+ * Left and right channel are read and stored according to the
+ * interleaving flag, frame length and number of channels.
+ *
+ * \param self Handle of an open SBR decoder instance.
+ * \param hSbrBs SBR Bitstream handle.
+ * \param input Pointer to input data.
+ * \param timeData Pointer to upsampled output data.
+ * \param timeDataSize Size of timeData.
+ * \param numChannels Pointer to a buffer holding the number of channels in
+ * time data buffer.
+ * \param sampleRate Output samplerate.
+ * \param channelMapping Channel mapping indices.
+ * \param coreDecodedOk Flag indicating if the core decoder did not find any
+ * error (0: core decoder found errors, 1: no errors).
+ * \param psDecoded Pointer to a buffer holding a flag. Input: PS is
+ * possible, Output: PS has been rendered.
+ *
+ * \return Error code.
+ */
+SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
+ INT_PCM *timeData, const int timeDataSize,
+ int *numChannels, int *sampleRate,
+ const FDK_channelMapDescr *const mapDescr,
+ const int mapIdx, const int coreDecodedOk,
+ UCHAR *psDecoded);
+
+/**
+ * \brief Close SBR decoder instance and free memory.
+ * \param self SBR decoder handle.
+ * \return Error Code.
+ */
+SBR_ERROR sbrDecoder_Close(HANDLE_SBRDECODER *self);
+
+/**
+ * \brief Get SBR decoder library information.
+ * \param info Pointer to a LIB_INFO struct, where library information is
+ * written to.
+ * \return 0 on success, -1 if invalid handle or if no free element is
+ * available to write information to.
+ */
+INT sbrDecoder_GetLibInfo(LIB_INFO *info);
+
+/**
+ * \brief Determine the modules output signal delay in samples.
+ * \param self SBR decoder handle.
+ * \return The number of samples signal delay added by the module.
+ */
+UINT sbrDecoder_GetDelay(const HANDLE_SBRDECODER self);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/fdk-aac/libSBRdec/src/HFgen_preFlat.cpp b/fdk-aac/libSBRdec/src/HFgen_preFlat.cpp
new file mode 100644
index 0000000..96adbb9
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/HFgen_preFlat.cpp
@@ -0,0 +1,993 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s): Oliver Moser, Manuel Jander, Matthias Hildenbrand
+
+ Description: QMF frequency pre-whitening for SBR.
+ In the documentation the terms "scale factor" and "exponent"
+ mean the same. Variables containing such information have
+ the suffix "_sf".
+
+*******************************************************************************/
+
+#include "HFgen_preFlat.h"
+
+#define POLY_ORDER 3
+#define MAXLOWBANDS 32
+#define LOG10FAC 0.752574989159953f /* == 10/log2(10) * 2^-2 */
+#define LOG10FAC_INV 0.664385618977472f /* == log2(10)/20 * 2^2 */
+
+#define FIXP_CHB FIXP_SGL /* STB sinus Tab used in transformation */
+#define CHC(a) (FX_DBL2FXCONST_SGL(a))
+#define FX_CHB2FX_DBL(a) FX_SGL2FX_DBL(a)
+
+typedef struct backsubst_data {
+ FIXP_CHB Lnorm1d[3]; /*!< Normalized L matrix */
+ SCHAR Lnorm1d_sf[3];
+ FIXP_CHB Lnormii
+ [3]; /*!< The diagonal data points [i][i] of the normalized L matrix */
+ SCHAR Lnormii_sf[3];
+ FIXP_CHB Bmul0
+ [4]; /*!< To normalize L*x=b, Bmul0 is what we need to multiply b with. */
+ SCHAR Bmul0_sf[4];
+ FIXP_CHB LnormInv1d[6]; /*!< Normalized inverted L matrix (L') */
+ SCHAR LnormInv1d_sf[6];
+ FIXP_CHB
+ Bmul1[4]; /*!< To normalize L'*x=b, Bmul1 is what we need to multiply b
+ with. */
+ SCHAR Bmul1_sf[4];
+} backsubst_data;
+
+/* for each element n do, f(n) = trunc(log2(n))+1 */
+const UCHAR getLog2[32] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5};
+
+/** \def BSD_IDX_OFFSET
+ *
+ * bsd[] begins at index 0 with data for numBands=5. The correct bsd[] is
+ * indexed like bsd[numBands-BSD_IDX_OFFSET].
+ */
+#define BSD_IDX_OFFSET 5
+
+#define N_NUMBANDS \
+ MAXLOWBANDS - BSD_IDX_OFFSET + \
+ 1 /*!< Number of backsubst_data elements in bsd */
+
+const backsubst_data bsd[N_NUMBANDS] = {
+ {
+ /* numBands=5 */
+ {CHC(0x66c85a52), CHC(0x4278e587), CHC(0x697dcaff)},
+ {-1, 0, 0},
+ {CHC(0x66a61789), CHC(0x5253b8e3), CHC(0x5addad81)},
+ {3, 4, 1},
+ {CHC(0x7525ee90), CHC(0x6e2a1210), CHC(0x6523bb40), CHC(0x59822ead)},
+ {-6, -4, -2, 0},
+ {CHC(0x609e4cad), CHC(0x59c7e312), CHC(0x681eecac), CHC(0x440ea893),
+ CHC(0x4a214bb3), CHC(0x53c345a1)},
+ {1, 0, -1, -1, -3, -5},
+ {CHC(0x7525ee90), CHC(0x58587936), CHC(0x410d0b38), CHC(0x7f1519d6)},
+ {-6, -1, 2, 0},
+ },
+ {
+ /* numBands=6 */
+ {CHC(0x68943285), CHC(0x4841d2c3), CHC(0x6a6214c7)},
+ {-1, 0, 0},
+ {CHC(0x63c5923e), CHC(0x4e906e18), CHC(0x6285af8a)},
+ {3, 4, 1},
+ {CHC(0x7263940b), CHC(0x424a69a5), CHC(0x4ae8383a), CHC(0x517b7730)},
+ {-7, -4, -2, 0},
+ {CHC(0x518aee5f), CHC(0x4823a096), CHC(0x43764a39), CHC(0x6e6faf23),
+ CHC(0x61bba44f), CHC(0x59d8b132)},
+ {1, 0, -1, -2, -4, -6},
+ {CHC(0x7263940b), CHC(0x6757bff2), CHC(0x5bf40fe0), CHC(0x7d6f4292)},
+ {-7, -2, 1, 0},
+ },
+ {
+ /* numBands=7 */
+ {CHC(0x699b4c3c), CHC(0x4b8b702f), CHC(0x6ae51a4f)},
+ {-1, 0, 0},
+ {CHC(0x623a7f49), CHC(0x4ccc91fc), CHC(0x68f048dd)},
+ {3, 4, 1},
+ {CHC(0x7e6ebe18), CHC(0x5701daf2), CHC(0x74a8198b), CHC(0x4b399aa1)},
+ {-8, -5, -3, 0},
+ {CHC(0x464a64a6), CHC(0x78e42633), CHC(0x5ee174ba), CHC(0x5d0008c8),
+ CHC(0x455cff0f), CHC(0x6b9100e7)},
+ {1, -1, -2, -2, -4, -7},
+ {CHC(0x7e6ebe18), CHC(0x42c52efe), CHC(0x45fe401f), CHC(0x7b5808ef)},
+ {-8, -2, 1, 0},
+ },
+ {
+ /* numBands=8 */
+ {CHC(0x6a3fd9b4), CHC(0x4d99823f), CHC(0x6b372a94)},
+ {-1, 0, 0},
+ {CHC(0x614c6ef7), CHC(0x4bd06699), CHC(0x6e59cfca)},
+ {3, 4, 1},
+ {CHC(0x4c389cc5), CHC(0x79686681), CHC(0x5e2544c2), CHC(0x46305b43)},
+ {-8, -6, -3, 0},
+ {CHC(0x7b4ca7c6), CHC(0x68270ac5), CHC(0x467c644c), CHC(0x505c1b0f),
+ CHC(0x67a14778), CHC(0x45801767)},
+ {0, -1, -2, -2, -5, -7},
+ {CHC(0x4c389cc5), CHC(0x5c499ceb), CHC(0x6f863c9f), CHC(0x79059bfc)},
+ {-8, -3, 0, 0},
+ },
+ {
+ /* numBands=9 */
+ {CHC(0x6aad9988), CHC(0x4ef8ac18), CHC(0x6b6df116)},
+ {-1, 0, 0},
+ {CHC(0x60b159b0), CHC(0x4b33f772), CHC(0x72f5573d)},
+ {3, 4, 1},
+ {CHC(0x6206cb18), CHC(0x58a7d8dc), CHC(0x4e0b2d0b), CHC(0x4207ad84)},
+ {-9, -6, -3, 0},
+ {CHC(0x6dadadae), CHC(0x5b8b2cfc), CHC(0x6cf61db2), CHC(0x46c3c90b),
+ CHC(0x506314ea), CHC(0x5f034acd)},
+ {0, -1, -3, -2, -5, -8},
+ {CHC(0x6206cb18), CHC(0x42f8b8de), CHC(0x5bb4776f), CHC(0x769acc79)},
+ {-9, -3, 0, 0},
+ },
+ {
+ /* numBands=10 */
+ {CHC(0x6afa7252), CHC(0x4feed3ed), CHC(0x6b94504d)},
+ {-1, 0, 0},
+ {CHC(0x60467899), CHC(0x4acbafba), CHC(0x76eb327f)},
+ {3, 4, 1},
+ {CHC(0x42415b15), CHC(0x431080da), CHC(0x420f1c32), CHC(0x7d0c1aeb)},
+ {-9, -6, -3, -1},
+ {CHC(0x62b2c7a4), CHC(0x51b040a6), CHC(0x56caddb4), CHC(0x7e74a2c8),
+ CHC(0x4030adf5), CHC(0x43d1dc4f)},
+ {0, -1, -3, -3, -5, -8},
+ {CHC(0x42415b15), CHC(0x64e299b3), CHC(0x4d33b5e8), CHC(0x742cee5f)},
+ {-9, -4, 0, 0},
+ },
+ {
+ /* numBands=11 */
+ {CHC(0x6b3258bb), CHC(0x50a21233), CHC(0x6bb03c19)},
+ {-1, 0, 0},
+ {CHC(0x5ff997c6), CHC(0x4a82706e), CHC(0x7a5aae36)},
+ {3, 4, 1},
+ {CHC(0x5d2fb4fb), CHC(0x685bddd8), CHC(0x71b5e983), CHC(0x7708c90b)},
+ {-10, -7, -4, -1},
+ {CHC(0x59aceea2), CHC(0x49c428a0), CHC(0x46ca5527), CHC(0x724be884),
+ CHC(0x68e586da), CHC(0x643485b6)},
+ {0, -1, -3, -3, -6, -9},
+ {CHC(0x5d2fb4fb), CHC(0x4e3fad1a), CHC(0x42310ba2), CHC(0x71c8b3ce)},
+ {-10, -4, 0, 0},
+ },
+ {
+ /* numBands=12 */
+ {CHC(0x6b5c4726), CHC(0x5128a4a8), CHC(0x6bc52ee1)},
+ {-1, 0, 0},
+ {CHC(0x5fc06618), CHC(0x4a4ce559), CHC(0x7d5c16e9)},
+ {3, 4, 1},
+ {CHC(0x43af8342), CHC(0x531533d3), CHC(0x633660a6), CHC(0x71ce6052)},
+ {-10, -7, -4, -1},
+ {CHC(0x522373d7), CHC(0x434150cb), CHC(0x75b58afc), CHC(0x68474f2d),
+ CHC(0x575348a5), CHC(0x4c20973f)},
+ {0, -1, -4, -3, -6, -9},
+ {CHC(0x43af8342), CHC(0x7c4d3d11), CHC(0x732e13db), CHC(0x6f756ac4)},
+ {-10, -5, -1, 0},
+ },
+ {
+ /* numBands=13 */
+ {CHC(0x6b7c8953), CHC(0x51903fcd), CHC(0x6bd54d2e)},
+ {-1, 0, 0},
+ {CHC(0x5f94abf0), CHC(0x4a2480fa), CHC(0x40013553)},
+ {3, 4, 2},
+ {CHC(0x6501236e), CHC(0x436b9c4e), CHC(0x578d7881), CHC(0x6d34f92e)},
+ {-11, -7, -4, -1},
+ {CHC(0x4bc0e2b2), CHC(0x7b9d12ac), CHC(0x636c1c1b), CHC(0x5fe15c2b),
+ CHC(0x49d54879), CHC(0x7662cfa5)},
+ {0, -2, -4, -3, -6, -10},
+ {CHC(0x6501236e), CHC(0x64b059fe), CHC(0x656d8359), CHC(0x6d370900)},
+ {-11, -5, -1, 0},
+ },
+ {
+ /* numBands=14 */
+ {CHC(0x6b95e276), CHC(0x51e1b637), CHC(0x6be1f7ed)},
+ {-1, 0, 0},
+ {CHC(0x5f727a1c), CHC(0x4a053e9c), CHC(0x412e528c)},
+ {3, 4, 2},
+ {CHC(0x4d178bd4), CHC(0x6f33b4e8), CHC(0x4e028f7f), CHC(0x691ee104)},
+ {-11, -8, -4, -1},
+ {CHC(0x46473d3f), CHC(0x725bd0a6), CHC(0x55199885), CHC(0x58bcc56b),
+ CHC(0x7e7e6288), CHC(0x5ddef6eb)},
+ {0, -2, -4, -3, -7, -10},
+ {CHC(0x4d178bd4), CHC(0x52ebd467), CHC(0x5a395a6e), CHC(0x6b0f724f)},
+ {-11, -5, -1, 0},
+ },
+ {
+ /* numBands=15 */
+ {CHC(0x6baa2a22), CHC(0x5222eb91), CHC(0x6bec1a86)},
+ {-1, 0, 0},
+ {CHC(0x5f57393b), CHC(0x49ec8934), CHC(0x423b5b58)},
+ {3, 4, 2},
+ {CHC(0x77fd2486), CHC(0x5cfbdf2c), CHC(0x46153bd1), CHC(0x65757ed9)},
+ {-12, -8, -4, -1},
+ {CHC(0x41888ee6), CHC(0x6a661db3), CHC(0x49abc8c8), CHC(0x52965848),
+ CHC(0x6d9301b7), CHC(0x4bb04721)},
+ {0, -2, -4, -3, -7, -10},
+ {CHC(0x77fd2486), CHC(0x45424c68), CHC(0x50f33cc6), CHC(0x68ff43f0)},
+ {-12, -5, -1, 0},
+ },
+ {
+ /* numBands=16 */
+ {CHC(0x6bbaa499), CHC(0x5257ed94), CHC(0x6bf456e4)},
+ {-1, 0, 0},
+ {CHC(0x5f412594), CHC(0x49d8a766), CHC(0x432d1dbd)},
+ {3, 4, 2},
+ {CHC(0x5ef5cfde), CHC(0x4eafcd2d), CHC(0x7ed36893), CHC(0x62274b45)},
+ {-12, -8, -5, -1},
+ {CHC(0x7ac438f5), CHC(0x637aab21), CHC(0x4067617a), CHC(0x4d3c6ec7),
+ CHC(0x5fd6e0dd), CHC(0x7bd5f024)},
+ {-1, -2, -4, -3, -7, -11},
+ {CHC(0x5ef5cfde), CHC(0x751d0d4f), CHC(0x492b3c41), CHC(0x67065409)},
+ {-12, -6, -1, 0},
+ },
+ {
+ /* numBands=17 */
+ {CHC(0x6bc836c9), CHC(0x5283997e), CHC(0x6bfb1f5e)},
+ {-1, 0, 0},
+ {CHC(0x5f2f02b6), CHC(0x49c868e9), CHC(0x44078151)},
+ {3, 4, 2},
+ {CHC(0x4c43b65a), CHC(0x4349dcf6), CHC(0x73799e2d), CHC(0x5f267274)},
+ {-12, -8, -5, -1},
+ {CHC(0x73726394), CHC(0x5d68511a), CHC(0x7191bbcc), CHC(0x48898c70),
+ CHC(0x548956e1), CHC(0x66981ce8)},
+ {-1, -2, -5, -3, -7, -11},
+ {CHC(0x4c43b65a), CHC(0x64131116), CHC(0x429028e2), CHC(0x65240211)},
+ {-12, -6, -1, 0},
+ },
+ {
+ /* numBands=18 */
+ {CHC(0x6bd3860d), CHC(0x52a80156), CHC(0x6c00c68d)},
+ {-1, 0, 0},
+ {CHC(0x5f1fed86), CHC(0x49baf636), CHC(0x44cdb9dc)},
+ {3, 4, 2},
+ {CHC(0x7c189389), CHC(0x742666d8), CHC(0x69b8c776), CHC(0x5c67e27d)},
+ {-13, -9, -5, -1},
+ {CHC(0x6cf1ea76), CHC(0x58095703), CHC(0x64e351a9), CHC(0x4460da90),
+ CHC(0x4b1f8083), CHC(0x55f2d3e1)},
+ {-1, -2, -5, -3, -7, -11},
+ {CHC(0x7c189389), CHC(0x5651792a), CHC(0x79cb9b3d), CHC(0x635769c0)},
+ {-13, -6, -2, 0},
+ },
+ {
+ /* numBands=19 */
+ {CHC(0x6bdd0c40), CHC(0x52c6abf6), CHC(0x6c058950)},
+ {-1, 0, 0},
+ {CHC(0x5f133f88), CHC(0x49afb305), CHC(0x45826d73)},
+ {3, 4, 2},
+ {CHC(0x6621a164), CHC(0x6512528e), CHC(0x61449fc8), CHC(0x59e2a0c0)},
+ {-13, -9, -5, -1},
+ {CHC(0x6721cadb), CHC(0x53404cd4), CHC(0x5a389e91), CHC(0x40abcbd2),
+ CHC(0x43332f01), CHC(0x48b82e46)},
+ {-1, -2, -5, -3, -7, -11},
+ {CHC(0x6621a164), CHC(0x4b12cc28), CHC(0x6ffd4df8), CHC(0x619f835e)},
+ {-13, -6, -2, 0},
+ },
+ {
+ /* numBands=20 */
+ {CHC(0x6be524c5), CHC(0x52e0beb3), CHC(0x6c099552)},
+ {-1, 0, 0},
+ {CHC(0x5f087c68), CHC(0x49a62bb5), CHC(0x4627d175)},
+ {3, 4, 2},
+ {CHC(0x54ec6afe), CHC(0x58991a42), CHC(0x59e23e8c), CHC(0x578f4ef4)},
+ {-13, -9, -5, -1},
+ {CHC(0x61e78f6f), CHC(0x4ef5e1e9), CHC(0x5129c3b8), CHC(0x7ab0f7b2),
+ CHC(0x78efb076), CHC(0x7c2567ea)},
+ {-1, -2, -5, -4, -8, -12},
+ {CHC(0x54ec6afe), CHC(0x41c7812c), CHC(0x676f6f8d), CHC(0x5ffb383f)},
+ {-13, -6, -2, 0},
+ },
+ {
+ /* numBands=21 */
+ {CHC(0x6bec1542), CHC(0x52f71929), CHC(0x6c0d0d5e)},
+ {-1, 0, 0},
+ {CHC(0x5eff45c5), CHC(0x499e092d), CHC(0x46bfc0c9)},
+ {3, 4, 2},
+ {CHC(0x47457a78), CHC(0x4e2d99b3), CHC(0x53637ea5), CHC(0x5567d0e9)},
+ {-13, -9, -5, -1},
+ {CHC(0x5d2dc61b), CHC(0x4b1760c8), CHC(0x4967cf39), CHC(0x74b113d8),
+ CHC(0x6d6676b6), CHC(0x6ad114e9)},
+ {-1, -2, -5, -4, -8, -12},
+ {CHC(0x47457a78), CHC(0x740accaa), CHC(0x5feb6609), CHC(0x5e696f95)},
+ {-13, -7, -2, 0},
+ },
+ {
+ /* numBands=22 */
+ {CHC(0x6bf21387), CHC(0x530a683c), CHC(0x6c100c59)},
+ {-1, 0, 0},
+ {CHC(0x5ef752ea), CHC(0x499708c6), CHC(0x474bcd1b)},
+ {3, 4, 2},
+ {CHC(0x78a21ab7), CHC(0x45658aec), CHC(0x4da3c4fe), CHC(0x5367094b)},
+ {-14, -9, -5, -1},
+ {CHC(0x58e2df6a), CHC(0x4795990e), CHC(0x42b5e0f7), CHC(0x6f408c64),
+ CHC(0x6370bebf), CHC(0x5c91ca85)},
+ {-1, -2, -5, -4, -8, -12},
+ {CHC(0x78a21ab7), CHC(0x66f951d6), CHC(0x594605bb), CHC(0x5ce91657)},
+ {-14, -7, -2, 0},
+ },
+ {
+ /* numBands=23 */
+ {CHC(0x6bf749b2), CHC(0x531b3348), CHC(0x6c12a750)},
+ {-1, 0, 0},
+ {CHC(0x5ef06b17), CHC(0x4990f6c9), CHC(0x47cd4c5b)},
+ {3, 4, 2},
+ {CHC(0x66dede36), CHC(0x7bdf90a9), CHC(0x4885b2b9), CHC(0x5188a6b7)},
+ {-14, -10, -5, -1},
+ {CHC(0x54f85812), CHC(0x446414ae), CHC(0x79c8d519), CHC(0x6a4c2f31),
+ CHC(0x5ac8325f), CHC(0x50bf9200)},
+ {-1, -2, -6, -4, -8, -12},
+ {CHC(0x66dede36), CHC(0x5be0d90e), CHC(0x535cc453), CHC(0x5b7923f0)},
+ {-14, -7, -2, 0},
+ },
+ {
+ /* numBands=24 */
+ {CHC(0x6bfbd91d), CHC(0x5329e580), CHC(0x6c14eeed)},
+ {-1, 0, 0},
+ {CHC(0x5eea6179), CHC(0x498baa90), CHC(0x4845635d)},
+ {3, 4, 2},
+ {CHC(0x58559b7e), CHC(0x6f1b231f), CHC(0x43f1789b), CHC(0x4fc8fcb8)},
+ {-14, -10, -5, -1},
+ {CHC(0x51621775), CHC(0x417881a3), CHC(0x6f9ba9b6), CHC(0x65c412b2),
+ CHC(0x53352c61), CHC(0x46db9caf)},
+ {-1, -2, -6, -4, -8, -12},
+ {CHC(0x58559b7e), CHC(0x52636003), CHC(0x4e13b316), CHC(0x5a189cdf)},
+ {-14, -7, -2, 0},
+ },
+ {
+ /* numBands=25 */
+ {CHC(0x6bffdc73), CHC(0x5336d4af), CHC(0x6c16f084)},
+ {-1, 0, 0},
+ {CHC(0x5ee51249), CHC(0x498703cc), CHC(0x48b50e4f)},
+ {3, 4, 2},
+ {CHC(0x4c5616cf), CHC(0x641b9fad), CHC(0x7fa735e0), CHC(0x4e24e57a)},
+ {-14, -10, -6, -1},
+ {CHC(0x4e15f47a), CHC(0x7d9481d6), CHC(0x66a82f8a), CHC(0x619ae971),
+ CHC(0x4c8b2f5f), CHC(0x7d09ec11)},
+ {-1, -3, -6, -4, -8, -13},
+ {CHC(0x4c5616cf), CHC(0x4a3770fb), CHC(0x495402de), CHC(0x58c693fa)},
+ {-14, -7, -2, 0},
+ },
+ {
+ /* numBands=26 */
+ {CHC(0x6c036943), CHC(0x53424625), CHC(0x6c18b6dc)},
+ {-1, 0, 0},
+ {CHC(0x5ee060aa), CHC(0x4982e88a), CHC(0x491d277f)},
+ {3, 4, 2},
+ {CHC(0x425ada5b), CHC(0x5a9368ac), CHC(0x78380a42), CHC(0x4c99aa05)},
+ {-14, -10, -6, -1},
+ {CHC(0x4b0b569c), CHC(0x78a420da), CHC(0x5ebdf203), CHC(0x5dc57e63),
+ CHC(0x46a650ff), CHC(0x6ee13fb8)},
+ {-1, -3, -6, -4, -8, -13},
+ {CHC(0x425ada5b), CHC(0x4323073c), CHC(0x450ae92b), CHC(0x57822ad5)},
+ {-14, -7, -2, 0},
+ },
+ {
+ /* numBands=27 */
+ {CHC(0x6c06911a), CHC(0x534c7261), CHC(0x6c1a4aba)},
+ {-1, 0, 0},
+ {CHC(0x5edc3524), CHC(0x497f43c0), CHC(0x497e6cd8)},
+ {3, 4, 2},
+ {CHC(0x73fb550e), CHC(0x5244894f), CHC(0x717aad78), CHC(0x4b24ef6c)},
+ {-15, -10, -6, -1},
+ {CHC(0x483aebe4), CHC(0x74139116), CHC(0x57b58037), CHC(0x5a3a4f3c),
+ CHC(0x416950fe), CHC(0x62c7f4f2)},
+ {-1, -3, -6, -4, -8, -13},
+ {CHC(0x73fb550e), CHC(0x79efb994), CHC(0x4128cab7), CHC(0x564a919a)},
+ {-15, -8, -2, 0},
+ },
+ {
+ /* numBands=28 */
+ {CHC(0x6c096264), CHC(0x535587cd), CHC(0x6c1bb355)},
+ {-1, 0, 0},
+ {CHC(0x5ed87c76), CHC(0x497c0439), CHC(0x49d98452)},
+ {3, 4, 2},
+ {CHC(0x65dec5bf), CHC(0x4afd1ba3), CHC(0x6b58b4b3), CHC(0x49c4a7b0)},
+ {-15, -10, -6, -1},
+ {CHC(0x459e6eb1), CHC(0x6fd850b7), CHC(0x516e7be9), CHC(0x56f13d05),
+ CHC(0x79785594), CHC(0x58617de7)},
+ {-1, -3, -6, -4, -9, -13},
+ {CHC(0x65dec5bf), CHC(0x6f2168aa), CHC(0x7b41310f), CHC(0x551f0692)},
+ {-15, -8, -3, 0},
+ },
+ {
+ /* numBands=29 */
+ {CHC(0x6c0be913), CHC(0x535dacd5), CHC(0x6c1cf6a3)},
+ {-1, 0, 0},
+ {CHC(0x5ed526b4), CHC(0x49791bc5), CHC(0x4a2eff99)},
+ {3, 4, 2},
+ {CHC(0x59e44afe), CHC(0x44949ada), CHC(0x65bf36f5), CHC(0x487705a0)},
+ {-15, -10, -6, -1},
+ {CHC(0x43307779), CHC(0x6be959c4), CHC(0x4bce2122), CHC(0x53e34d89),
+ CHC(0x7115ff82), CHC(0x4f6421a1)},
+ {-1, -3, -6, -4, -9, -13},
+ {CHC(0x59e44afe), CHC(0x659eab7d), CHC(0x74cea459), CHC(0x53fed574)},
+ {-15, -8, -3, 0},
+ },
+ {
+ /* numBands=30 */
+ {CHC(0x6c0e2f17), CHC(0x53650181), CHC(0x6c1e199d)},
+ {-1, 0, 0},
+ {CHC(0x5ed2269f), CHC(0x49767e9e), CHC(0x4a7f5f0b)},
+ {3, 4, 2},
+ {CHC(0x4faa4ae6), CHC(0x7dd3bf11), CHC(0x609e2732), CHC(0x473a72e9)},
+ {-15, -11, -6, -1},
+ {CHC(0x40ec57c6), CHC(0x683ee147), CHC(0x46be261d), CHC(0x510a7983),
+ CHC(0x698a84cb), CHC(0x4794a927)},
+ {-1, -3, -6, -4, -9, -13},
+ {CHC(0x4faa4ae6), CHC(0x5d3615ad), CHC(0x6ee74773), CHC(0x52e956a1)},
+ {-15, -8, -3, 0},
+ },
+ {
+ /* numBands=31 */
+ {CHC(0x6c103cc9), CHC(0x536ba0ac), CHC(0x6c1f2070)},
+ {-1, 0, 0},
+ {CHC(0x5ecf711e), CHC(0x497422ea), CHC(0x4acb1438)},
+ {3, 4, 2},
+ {CHC(0x46e322ad), CHC(0x73c32f3c), CHC(0x5be7d172), CHC(0x460d8800)},
+ {-15, -11, -6, -1},
+ {CHC(0x7d9bf8ad), CHC(0x64d22351), CHC(0x422bdc81), CHC(0x4e6184aa),
+ CHC(0x62ba2375), CHC(0x40c325de)},
+ {-2, -3, -6, -4, -9, -13},
+ {CHC(0x46e322ad), CHC(0x55bef2a3), CHC(0x697b3135), CHC(0x51ddee4d)},
+ {-15, -8, -3, 0},
+ },
+ {
+ // numBands=32
+ {CHC(0x6c121933), CHC(0x5371a104), CHC(0x6c200ea0)},
+ {-1, 0, 0},
+ {CHC(0x5eccfcd3), CHC(0x49720060), CHC(0x4b1283f0)},
+ {3, 4, 2},
+ {CHC(0x7ea12a52), CHC(0x6aca3303), CHC(0x579072bf), CHC(0x44ef056e)},
+ {-16, -11, -6, -1},
+ {CHC(0x79a3a9ab), CHC(0x619d38fc), CHC(0x7c0f0734), CHC(0x4be3dd5d),
+ CHC(0x5c8d7163), CHC(0x7591065f)},
+ {-2, -3, -7, -4, -9, -14},
+ {CHC(0x7ea12a52), CHC(0x4f1782a6), CHC(0x647cbcb2), CHC(0x50dc0bb1)},
+ {-16, -8, -3, 0},
+ },
+};
+
+/** \def SUM_SAFETY
+ *
+ * SUM_SAFTEY defines the bits needed to right-shift every summand in
+ * order to be overflow-safe. In the two backsubst functions we sum up 4
+ * values. Since one of which is definitely not MAXVAL_DBL (the L[x][y]),
+ * we spare just 2 safety bits instead of 3.
+ */
+#define SUM_SAFETY 2
+
+/**
+ * \brief Solves L*x=b via backsubstitution according to the following
+ * structure:
+ *
+ * x[0] = b[0];
+ * x[1] = (b[1] - x[0]) / L[1][1];
+ * x[2] = (b[2] - x[1]*L[2][1] - x[0]) / L[2][2];
+ * x[3] = (b[3] - x[2]*L[3][2] - x[1]*L[3][1] - x[0]) / L[3][3];
+ *
+ * \param[in] numBands SBR crossover band index
+ * \param[in] b the b in L*x=b (one-dimensional)
+ * \param[out] x output polynomial coefficients (mantissa)
+ * \param[out] x_sf exponents of x[]
+ */
+static void backsubst_fw(const int numBands, const FIXP_DBL *const b,
+ FIXP_DBL *RESTRICT x, int *RESTRICT x_sf) {
+ int i, k;
+ int m; /* the trip counter that indexes incrementally through Lnorm1d[] */
+
+ const FIXP_CHB *RESTRICT pLnorm1d = bsd[numBands - BSD_IDX_OFFSET].Lnorm1d;
+ const SCHAR *RESTRICT pLnorm1d_sf = bsd[numBands - BSD_IDX_OFFSET].Lnorm1d_sf;
+ const FIXP_CHB *RESTRICT pLnormii = bsd[numBands - BSD_IDX_OFFSET].Lnormii;
+ const SCHAR *RESTRICT pLnormii_sf = bsd[numBands - BSD_IDX_OFFSET].Lnormii_sf;
+
+ x[0] = b[0];
+
+ for (i = 1, m = 0; i <= POLY_ORDER; ++i) {
+ FIXP_DBL sum = b[i] >> SUM_SAFETY;
+ int sum_sf = x_sf[i];
+ for (k = i - 1; k > 0; --k, ++m) {
+ int e;
+ FIXP_DBL mult = fMultNorm(FX_CHB2FX_DBL(pLnorm1d[m]), x[k], &e);
+ int mult_sf = pLnorm1d_sf[m] + x_sf[k] + e;
+
+ /* check if the new summand mult has a different sf than the sum currently
+ * has */
+ int diff = mult_sf - sum_sf;
+
+ if (diff > 0) {
+ /* yes, and it requires the sum to be adjusted (scaled down) */
+ sum >>= diff;
+ sum_sf = mult_sf;
+ } else if (diff < 0) {
+ /* yes, but here mult needs to be scaled down */
+ mult >>= -diff;
+ }
+ sum -= (mult >> SUM_SAFETY);
+ }
+
+ /* - x[0] */
+ if (x_sf[0] > sum_sf) {
+ sum >>= (x_sf[0] - sum_sf);
+ sum_sf = x_sf[0];
+ }
+ sum -= (x[0] >> (sum_sf - x_sf[0] + SUM_SAFETY));
+
+ /* instead of the division /L[i][i], we multiply by the inverse */
+ int e;
+ x[i] = fMultNorm(sum, FX_CHB2FX_DBL(pLnormii[i - 1]), &e);
+ x_sf[i] = sum_sf + pLnormii_sf[i - 1] + e + SUM_SAFETY;
+ }
+}
+
+/**
+ * \brief Solves L*x=b via backsubstitution according to the following
+ * structure:
+ *
+ * x[3] = b[3];
+ * x[2] = b[2] - L[2][3]*x[3];
+ * x[1] = b[1] - L[1][2]*x[2] - L[1][3]*x[3];
+ * x[0] = b[0] - L[0][1]*x[1] - L[0][2]*x[2] - L[0][3]*x[3];
+ *
+ * \param[in] numBands SBR crossover band index
+ * \param[in] b the b in L*x=b (one-dimensional)
+ * \param[out] x solution vector
+ * \param[out] x_sf exponents of x[]
+ */
+static void backsubst_bw(const int numBands, const FIXP_DBL *const b,
+ FIXP_DBL *RESTRICT x, int *RESTRICT x_sf) {
+ int i, k;
+ int m; /* the trip counter that indexes incrementally through LnormInv1d[] */
+
+ const FIXP_CHB *RESTRICT pLnormInv1d =
+ bsd[numBands - BSD_IDX_OFFSET].LnormInv1d;
+ const SCHAR *RESTRICT pLnormInv1d_sf =
+ bsd[numBands - BSD_IDX_OFFSET].LnormInv1d_sf;
+
+ x[POLY_ORDER] = b[POLY_ORDER];
+
+ for (i = POLY_ORDER - 1, m = 0; i >= 0; i--) {
+ FIXP_DBL sum = b[i] >> SUM_SAFETY;
+ int sum_sf = x_sf[i]; /* sum's sf but disregarding SUM_SAFETY (added at the
+ iteration's end) */
+
+ for (k = i + 1; k <= POLY_ORDER; ++k, ++m) {
+ int e;
+ FIXP_DBL mult = fMultNorm(FX_CHB2FX_DBL(pLnormInv1d[m]), x[k], &e);
+ int mult_sf = pLnormInv1d_sf[m] + x_sf[k] + e;
+
+ /* check if the new summand mult has a different sf than sum currently has
+ */
+ int diff = mult_sf - sum_sf;
+
+ if (diff > 0) {
+ /* yes, and it requires the sum v to be adjusted (scaled down) */
+ sum >>= diff;
+ sum_sf = mult_sf;
+ } else if (diff < 0) {
+ /* yes, but here mult needs to be scaled down */
+ mult >>= -diff;
+ }
+
+ /* mult has now the same sf than what it is about to be added to. */
+ /* scale mult down additionally so that building the sum is overflow-safe.
+ */
+ sum -= (mult >> SUM_SAFETY);
+ }
+
+ x_sf[i] = sum_sf + SUM_SAFETY;
+ x[i] = sum;
+ }
+}
+
+/**
+ * \brief Solves a system of linear equations (L*x=b) with the Cholesky
+ * algorithm.
+ *
+ * \param[in] numBands SBR crossover band index
+ * \param[in,out] b input: vector b, output: solution vector p.
+ * \param[in,out] b_sf input: exponent of b; output: exponent of solution
+ * p.
+ */
+static void choleskySolve(const int numBands, FIXP_DBL *RESTRICT b,
+ int *RESTRICT b_sf) {
+ int i, e;
+
+ const FIXP_CHB *RESTRICT pBmul0 = bsd[numBands - BSD_IDX_OFFSET].Bmul0;
+ const SCHAR *RESTRICT pBmul0_sf = bsd[numBands - BSD_IDX_OFFSET].Bmul0_sf;
+ const FIXP_CHB *RESTRICT pBmul1 = bsd[numBands - BSD_IDX_OFFSET].Bmul1;
+ const SCHAR *RESTRICT pBmul1_sf = bsd[numBands - BSD_IDX_OFFSET].Bmul1_sf;
+
+ /* normalize b */
+ FIXP_DBL bnormed[POLY_ORDER + 1];
+ for (i = 0; i <= POLY_ORDER; ++i) {
+ bnormed[i] = fMultNorm(b[i], FX_CHB2FX_DBL(pBmul0[i]), &e);
+ b_sf[i] += pBmul0_sf[i] + e;
+ }
+
+ backsubst_fw(numBands, bnormed, b, b_sf);
+
+ /* normalize b again */
+ for (i = 0; i <= POLY_ORDER; ++i) {
+ bnormed[i] = fMultNorm(b[i], FX_CHB2FX_DBL(pBmul1[i]), &e);
+ b_sf[i] += pBmul1_sf[i] + e;
+ }
+
+ backsubst_bw(numBands, bnormed, b, b_sf);
+}
+
+/**
+ * \brief Find polynomial approximation of vector y with implicit abscisas
+ * x=0,1,2,3..n-1
+ *
+ * The problem (V^T * V * p = V^T * y) is solved with Cholesky.
+ * V is the Vandermode Matrix constructed with x = 0...n-1;
+ * A = V^T * V; b = V^T * y;
+ *
+ * \param[in] numBands SBR crossover band index (BSD_IDX_OFFSET <= numBands <=
+ * MAXLOWBANDS)
+ * \param[in] y input vector (mantissa)
+ * \param[in] y_sf exponents of y[]
+ * \param[out] p output polynomial coefficients (mantissa)
+ * \param[out] p_sf exponents of p[]
+ */
+static void polyfit(const int numBands, const FIXP_DBL *const y, const int y_sf,
+ FIXP_DBL *RESTRICT p, int *RESTRICT p_sf) {
+ int i, k;
+ LONG v[POLY_ORDER + 1];
+ int sum_saftey = getLog2[numBands - 1];
+
+ FDK_ASSERT((numBands >= BSD_IDX_OFFSET) && (numBands <= MAXLOWBANDS));
+
+ /* construct vector b[] temporarily stored in array p[] */
+ FDKmemclear(p, (POLY_ORDER + 1) * sizeof(FIXP_DBL));
+
+ /* p[] are the sums over n values and each p[i] has its own sf */
+ for (i = 0; i <= POLY_ORDER; ++i) p_sf[i] = 1 - DFRACT_BITS;
+
+ for (k = 0; k < numBands; k++) {
+ v[0] = (LONG)1;
+ for (i = 1; i <= POLY_ORDER; i++) {
+ v[i] = k * v[i - 1];
+ }
+
+ for (i = 0; i <= POLY_ORDER; i++) {
+ if (v[POLY_ORDER - i] != 0 && y[k] != FIXP_DBL(0)) {
+ int e;
+ FIXP_DBL mult = fMultNorm((FIXP_DBL)v[POLY_ORDER - i], y[k], &e);
+ int sf = DFRACT_BITS - 1 + y_sf + e;
+
+ /* check if the new summand has a different sf than the sum p[i]
+ * currently has */
+ int diff = sf - p_sf[i];
+
+ if (diff > 0) {
+ /* yes, and it requires the sum p[i] to be adjusted (scaled down) */
+ p[i] >>= fMin(DFRACT_BITS - 1, diff);
+ p_sf[i] = sf;
+ } else if (diff < 0) {
+ /* yes, but here mult needs to be scaled down */
+ mult >>= -diff;
+ }
+
+ /* mult has now the same sf than what it is about to be added to.
+ scale mult down additionally so that building the sum is
+ overflow-safe. */
+ p[i] += mult >> sum_saftey;
+ }
+ }
+ }
+
+ p_sf[0] += sum_saftey;
+ p_sf[1] += sum_saftey;
+ p_sf[2] += sum_saftey;
+ p_sf[3] += sum_saftey;
+
+ choleskySolve(numBands, p, p_sf);
+}
+
+/**
+ * \brief Calculates the output of a POLY_ORDER-degree polynomial function
+ * with Horner scheme:
+ *
+ * y(x) = p3 + p2*x + p1*x^2 + p0*x^3
+ * = p3 + x*(p2 + x*(p1 + x*p0))
+ *
+ * The for loop iterates through the mult/add parts in y(x) as above,
+ * during which regular upscaling ensures a stable exponent of the
+ * result.
+ *
+ * \param[in] p coefficients as in y(x)
+ * \param[in] p_sf exponents of p[]
+ * \param[in] x_int non-fractional integer representation of x as in y(x)
+ * \param[out] out_sf exponent of return value
+ *
+ * \return result y(x)
+ */
+static FIXP_DBL polyval(const FIXP_DBL *const p, const int *const p_sf,
+ const int x_int, int *out_sf) {
+ FDK_ASSERT(x_int <= 31); /* otherwise getLog2[] needs more elements */
+
+ int k, x_sf;
+ int result_sf; /* working space to compute return value *out_sf */
+ FIXP_DBL x; /* fractional value of x_int */
+ FIXP_DBL result; /* return value */
+
+ /* if x == 0, then y(x) is just p3 */
+ if (x_int != 0) {
+ x_sf = getLog2[x_int];
+ x = (FIXP_DBL)x_int << (DFRACT_BITS - 1 - x_sf);
+ } else {
+ *out_sf = p_sf[3];
+ return p[3];
+ }
+
+ result = p[0];
+ result_sf = p_sf[0];
+
+ for (k = 1; k <= POLY_ORDER; ++k) {
+ FIXP_DBL mult = fMult(x, result);
+ int mult_sf = x_sf + result_sf;
+
+ int room = CountLeadingBits(mult);
+ mult <<= room;
+ mult_sf -= room;
+
+ FIXP_DBL pp = p[k];
+ int pp_sf = p_sf[k];
+
+ /* equalize the shift factors of pp and mult so that we can sum them up */
+ int diff = pp_sf - mult_sf;
+
+ if (diff > 0) {
+ diff = fMin(diff, DFRACT_BITS - 1);
+ mult >>= diff;
+ } else if (diff < 0) {
+ diff = fMax(diff, 1 - DFRACT_BITS);
+ pp >>= -diff;
+ }
+
+ /* downshift by 1 to ensure safe summation */
+ mult >>= 1;
+ mult_sf++;
+ pp >>= 1;
+ pp_sf++;
+
+ result_sf = fMax(pp_sf, mult_sf);
+
+ result = mult + pp;
+ /* rarely, mult and pp happen to be almost equal except their sign,
+ and then upon summation, result becomes so small, that it is within
+ the inaccuracy range of a few bits, and then the relative error
+ produced by this function may become HUGE */
+ }
+
+ *out_sf = result_sf;
+ return result;
+}
+
+void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal,
+ FIXP_DBL **sourceBufferImag,
+ int sourceBuf_e_overlap,
+ int sourceBuf_e_current, int overlap,
+ FIXP_DBL *RESTRICT GainVec, int *GainVec_exp,
+ int numBands, const int startSample,
+ const int stopSample) {
+ FIXP_DBL p[POLY_ORDER + 1];
+ FIXP_DBL meanNrg;
+ FIXP_DBL LowEnv[MAXLOWBANDS];
+ FIXP_DBL invNumBands = GetInvInt(numBands);
+ FIXP_DBL invNumSlots = GetInvInt(stopSample - startSample);
+ int i, loBand, exp, scale_nrg, scale_nrg_ov;
+ int sum_scale = 5, sum_scale_ov = 3;
+
+ if (overlap > 8) {
+ FDK_ASSERT(overlap <= 16);
+ sum_scale_ov += 1;
+ sum_scale += 1;
+ }
+
+ /* exponents of energy values */
+ sourceBuf_e_overlap = sourceBuf_e_overlap * 2 + sum_scale_ov;
+ sourceBuf_e_current = sourceBuf_e_current * 2 + sum_scale;
+ exp = fMax(sourceBuf_e_overlap, sourceBuf_e_current);
+ scale_nrg = sourceBuf_e_current - exp;
+ scale_nrg_ov = sourceBuf_e_overlap - exp;
+
+ meanNrg = (FIXP_DBL)0;
+ /* Calculate the spectral envelope in dB over the current copy-up frame. */
+ for (loBand = 0; loBand < numBands; loBand++) {
+ FIXP_DBL nrg_ov, nrg;
+ INT reserve = 0, exp_new;
+ FIXP_DBL maxVal = FL2FX_DBL(0.0f);
+
+ for (i = startSample; i < stopSample; i++) {
+ maxVal |=
+ (FIXP_DBL)((LONG)(sourceBufferReal[i][loBand]) ^
+ ((LONG)sourceBufferReal[i][loBand] >> (SAMPLE_BITS - 1)));
+ maxVal |=
+ (FIXP_DBL)((LONG)(sourceBufferImag[i][loBand]) ^
+ ((LONG)sourceBufferImag[i][loBand] >> (SAMPLE_BITS - 1)));
+ }
+
+ if (maxVal != FL2FX_DBL(0.0f)) {
+ reserve = fixMax(0, CntLeadingZeros(maxVal) - 2);
+ }
+
+ nrg_ov = nrg = (FIXP_DBL)0;
+ if (scale_nrg_ov > -31) {
+ for (i = startSample; i < overlap; i++) {
+ nrg_ov += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) +
+ fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >>
+ sum_scale_ov;
+ }
+ } else {
+ scale_nrg_ov = 0;
+ }
+ if (scale_nrg > -31) {
+ for (i = overlap; i < stopSample; i++) {
+ nrg += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) +
+ fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >>
+ sum_scale;
+ }
+ } else {
+ scale_nrg = 0;
+ }
+
+ nrg = (scaleValue(nrg_ov, scale_nrg_ov) >> 1) +
+ (scaleValue(nrg, scale_nrg) >> 1);
+ nrg = fMult(nrg, invNumSlots);
+
+ exp_new =
+ exp - (2 * reserve) +
+ 2; /* +1 for addition directly above, +1 for fPow2Div2 in loops above */
+
+ /* LowEnv = 10*log10(nrg) = log2(nrg) * 10/log2(10) */
+ /* exponent of logarithmic energy is 8 */
+ if (nrg > (FIXP_DBL)0) {
+ int exp_log2;
+ nrg = CalcLog2(nrg, exp_new, &exp_log2);
+ nrg = scaleValue(nrg, exp_log2 - 6);
+ nrg = fMult(FL2FXCONST_SGL(LOG10FAC), nrg);
+ } else {
+ nrg = (FIXP_DBL)0;
+ }
+ LowEnv[loBand] = nrg;
+ meanNrg += fMult(nrg, invNumBands);
+ }
+ exp = 6 + 2; /* exponent of LowEnv: +2 is exponent of LOG10FAC */
+
+ /* subtract mean before polynomial approximation to reduce dynamic of p[] */
+ for (loBand = 0; loBand < numBands; loBand++) {
+ LowEnv[loBand] = meanNrg - LowEnv[loBand];
+ }
+
+ /* For numBands < BSD_IDX_OFFSET (== POLY_ORDER+2) we dont get an
+ overdetermined equation system. The calculated polynomial will exactly fit
+ the input data and evaluating the polynomial will lead to the same vector
+ than the original input vector: lowEnvSlope[] == lowEnv[]
+ */
+ if (numBands > POLY_ORDER + 1) {
+ /* Find polynomial approximation of LowEnv */
+ int p_sf[POLY_ORDER + 1];
+
+ polyfit(numBands, LowEnv, exp, p, p_sf);
+
+ for (i = 0; i < numBands; i++) {
+ int sf;
+
+ /* lowBandEnvSlope[i] = tmp; */
+ FIXP_DBL tmp = polyval(p, p_sf, i, &sf);
+
+ /* GainVec = 10^((mean(y)-y)/20) = 2^( (mean(y)-y) * log2(10)/20 ) */
+ tmp = fMult(tmp, FL2FXCONST_SGL(LOG10FAC_INV));
+ GainVec[i] = f2Pow(tmp, sf - 2,
+ &GainVec_exp[i]); /* -2 is exponent of LOG10FAC_INV */
+ }
+ } else { /* numBands <= POLY_ORDER+1 */
+ for (i = 0; i < numBands; i++) {
+ int sf = exp; /* exponent of LowEnv[] */
+
+ /* lowBandEnvSlope[i] = LowEnv[i]; */
+ FIXP_DBL tmp = LowEnv[i];
+
+ /* GainVec = 10^((mean(y)-y)/20) = 2^( (mean(y)-y) * log2(10)/20 ) */
+ tmp = fMult(tmp, FL2FXCONST_SGL(LOG10FAC_INV));
+ GainVec[i] = f2Pow(tmp, sf - 2,
+ &GainVec_exp[i]); /* -2 is exponent of LOG10FAC_INV */
+ }
+ }
+}
diff --git a/fdk-aac/libSBRdec/src/HFgen_preFlat.h b/fdk-aac/libSBRdec/src/HFgen_preFlat.h
new file mode 100644
index 0000000..c1fc49d
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/HFgen_preFlat.h
@@ -0,0 +1,132 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s): Manuel Jander, Matthias Hildenbrand
+
+ Description: QMF frequency pre whitening for SBR
+
+*******************************************************************************/
+
+#include "common_fix.h"
+
+#ifndef HFGEN_PREFLAT_H
+#define HFGEN_PREFLAT_H
+
+#define GAIN_VEC_EXP 6 /* exponent of GainVec[] */
+
+/**
+ * \brief Find gain vector to flatten the QMF frequency bands whithout loosing
+ * the fine structure.
+ * \param[in] sourceBufferReal real part of QMF domain data.
+ * \param[in] sourceBufferImag imaginary part of QMF domain data.
+ * \param[in] sourceBuffer_e_overlap exponent of sourceBufferReal.
+ * \param[in] sourceBuffer_e_current exponent of sourceBufferImag.
+ * \param[in] overlap number of overlap samples.
+ * \param[out] GainVec array of gain values (one for each QMF band).
+ * \param[out] GainVec_exp exponents of GainVec (one for each QMF band).
+ * \param[in] numBands number of low bands (k_0).
+ * \param[in] startSample time slot start.
+ * \param[in] stopSample time slot stop.
+ */
+void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal,
+ FIXP_DBL **sourceBufferImag,
+ int sourceBuffer_e_overlap,
+ int sourceBuffer_e_current, int overlap,
+ FIXP_DBL GainVec[], int GainVec_exp[],
+ const int numBands, const int startSample,
+ const int stopSample);
+
+#endif /* __HFGEN_PREFLAT_H */
diff --git a/fdk-aac/libSBRdec/src/arm/lpp_tran_arm.cpp b/fdk-aac/libSBRdec/src/arm/lpp_tran_arm.cpp
new file mode 100644
index 0000000..db1948f
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/arm/lpp_tran_arm.cpp
@@ -0,0 +1,159 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s): Arthur Tritthart
+
+ Description: (ARM optimised) LPP transposer subroutines
+
+*******************************************************************************/
+
+#if defined(__arm__)
+
+#define FUNCTION_LPPTRANSPOSER_func1
+
+#ifdef FUNCTION_LPPTRANSPOSER_func1
+
+/* Note: This code requires only 43 cycles per iteration instead of 61 on
+ * ARM926EJ-S */
+static void lppTransposer_func1(FIXP_DBL *lowBandReal, FIXP_DBL *lowBandImag,
+ FIXP_DBL **qmfBufferReal,
+ FIXP_DBL **qmfBufferImag, int loops, int hiBand,
+ int dynamicScale, int descale, FIXP_SGL a0r,
+ FIXP_SGL a0i, FIXP_SGL a1r, FIXP_SGL a1i,
+ const int fPreWhitening,
+ FIXP_DBL preWhiteningGain,
+ int preWhiteningGains_sf) {
+ FIXP_DBL real1, real2, imag1, imag2, accu1, accu2;
+
+ real2 = lowBandReal[-2];
+ real1 = lowBandReal[-1];
+ imag2 = lowBandImag[-2];
+ imag1 = lowBandImag[-1];
+ for (int i = 0; i < loops; i++) {
+ accu1 = fMultDiv2(a0r, real1);
+ accu2 = fMultDiv2(a0i, imag1);
+ accu1 = fMultAddDiv2(accu1, a1r, real2);
+ accu2 = fMultAddDiv2(accu2, a1i, imag2);
+ real2 = fMultDiv2(a1i, real2);
+ accu1 = accu1 - accu2;
+ accu1 = accu1 >> dynamicScale;
+
+ accu2 = fMultAddDiv2(real2, a1r, imag2);
+ real2 = real1;
+ imag2 = imag1;
+ accu2 = fMultAddDiv2(accu2, a0i, real1);
+ real1 = lowBandReal[i];
+ accu2 = fMultAddDiv2(accu2, a0r, imag1);
+ imag1 = lowBandImag[i];
+ accu2 = accu2 >> dynamicScale;
+
+ accu1 <<= 1;
+ accu2 <<= 1;
+ accu1 += (real1 >> descale);
+ accu2 += (imag1 >> descale);
+ if (fPreWhitening) {
+ accu1 = scaleValueSaturate(fMultDiv2(accu1, preWhiteningGain),
+ preWhiteningGains_sf);
+ accu2 = scaleValueSaturate(fMultDiv2(accu2, preWhiteningGain),
+ preWhiteningGains_sf);
+ }
+ qmfBufferReal[i][hiBand] = accu1;
+ qmfBufferImag[i][hiBand] = accu2;
+ }
+}
+#endif /* #ifdef FUNCTION_LPPTRANSPOSER_func1 */
+
+#endif /* __arm__ */
diff --git a/fdk-aac/libSBRdec/src/env_calc.cpp b/fdk-aac/libSBRdec/src/env_calc.cpp
new file mode 100644
index 0000000..cb1474f
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/env_calc.cpp
@@ -0,0 +1,3158 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Envelope calculation
+
+ The envelope adjustor compares the energies present in the transposed
+ highband to the reference energies conveyed with the bitstream.
+ The highband is amplified (sometimes) or attenuated (mostly) to the
+ desired level.
+
+ The spectral shape of the reference energies can be changed several times per
+ frame if necessary. Each set of energy values corresponding to a certain range
+ in time will be called an <em>envelope</em> here.
+ The bitstream supports several frequency scales and two resolutions. Normally,
+ one or more QMF-subbands are grouped to one SBR-band. An envelope contains
+ reference energies for each SBR-band.
+ In addition to the energy envelopes, noise envelopes are transmitted that
+ define the ratio of energy which is generated by adding noise instead of
+ transposing the lowband. The noise envelopes are given in a coarser time
+ and frequency resolution.
+ If a signal contains strong tonal components, synthetic sines can be
+ generated in individual SBR bands.
+
+ An overlap buffer of 6 QMF-timeslots is used to allow a more
+ flexible alignment of the envelopes in time that is not restricted to the
+ core codec's frame borders.
+ Therefore the envelope adjustor has access to the spectral data of the
+ current frame as well as the last 6 QMF-timeslots of the previous frame.
+ However, in average only the data of 1 frame is being processed as
+ the adjustor is called once per frame.
+
+ Depending on the frequency range set in the bitstream, only QMF-subbands
+ between <em>lowSubband</em> and <em>highSubband</em> are adjusted.
+
+ Scaling of spectral data to maximize SNR (see #QMF_SCALE_FACTOR) as well as a
+ special Mantissa-Exponent format ( see calculateSbrEnvelope() ) are being
+ used. The main entry point for this modules is calculateSbrEnvelope().
+
+ \sa sbr_scale.h, #QMF_SCALE_FACTOR, calculateSbrEnvelope(), \ref
+ documentationOverview
+*/
+
+#include "env_calc.h"
+
+#include "sbrdec_freq_sca.h"
+#include "env_extr.h"
+#include "transcendent.h"
+#include "sbr_ram.h"
+#include "sbr_rom.h"
+
+#include "genericStds.h" /* need FDKpow() for debug outputs */
+
+typedef struct {
+ FIXP_DBL nrgRef[MAX_FREQ_COEFFS];
+ FIXP_DBL nrgEst[MAX_FREQ_COEFFS];
+ FIXP_DBL nrgGain[MAX_FREQ_COEFFS];
+ FIXP_DBL noiseLevel[MAX_FREQ_COEFFS];
+ FIXP_DBL nrgSine[MAX_FREQ_COEFFS];
+
+ SCHAR nrgRef_e[MAX_FREQ_COEFFS];
+ SCHAR nrgEst_e[MAX_FREQ_COEFFS];
+ SCHAR nrgGain_e[MAX_FREQ_COEFFS];
+ SCHAR noiseLevel_e[MAX_FREQ_COEFFS];
+ SCHAR nrgSine_e[MAX_FREQ_COEFFS];
+ /* yet another exponent [0]: for ts < no_cols; [1]: for ts >= no_cols */
+ SCHAR exponent[2];
+} ENV_CALC_NRGS;
+
+static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, SCHAR *filtBuffer_e,
+ FIXP_DBL *NrgGain, SCHAR *NrgGain_e,
+ int subbands);
+
+static void calcNrgPerSubband(FIXP_DBL **analysBufferReal,
+ FIXP_DBL **analysBufferImag, int lowSubband,
+ int highSubband, int start_pos, int next_pos,
+ SCHAR frameExp, FIXP_DBL *nrgEst,
+ SCHAR *nrgEst_e);
+
+static void calcNrgPerSfb(FIXP_DBL **analysBufferReal,
+ FIXP_DBL **analysBufferImag, int nSfb,
+ UCHAR *freqBandTable, int start_pos, int next_pos,
+ SCHAR input_e, FIXP_DBL *nrg_est, SCHAR *nrg_est_e);
+
+static void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e,
+ ENV_CALC_NRGS *nrgs, int c, FIXP_DBL tmpNoise,
+ SCHAR tmpNoise_e, UCHAR sinePresentFlag,
+ UCHAR sineMapped, int noNoiseFlag);
+
+static void calcAvgGain(ENV_CALC_NRGS *nrgs, int lowSubband, int highSubband,
+ FIXP_DBL *sumRef_m, SCHAR *sumRef_e,
+ FIXP_DBL *ptrAvgGain_m, SCHAR *ptrAvgGain_e);
+
+static void adjustTimeSlot_EldGrid(FIXP_DBL *ptrReal, ENV_CALC_NRGS *nrgs,
+ UCHAR *ptrHarmIndex, int lowSubbands,
+ int noSubbands, int scale_change,
+ int noNoiseFlag, int *ptrPhaseIndex,
+ int scale_diff_low);
+
+static void adjustTimeSlotLC(FIXP_DBL *ptrReal, ENV_CALC_NRGS *nrgs,
+ UCHAR *ptrHarmIndex, int lowSubbands,
+ int noSubbands, int scale_change, int noNoiseFlag,
+ int *ptrPhaseIndex);
+
+/**
+ * \brief Variant of adjustTimeSlotHQ() which only regards gain and noise but no
+ * additional harmonics
+ */
+static void adjustTimeSlotHQ_GainAndNoise(
+ FIXP_DBL *ptrReal, FIXP_DBL *ptrImag,
+ HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
+ int lowSubbands, int noSubbands, int scale_change, FIXP_SGL smooth_ratio,
+ int noNoiseFlag, int filtBufferNoiseShift);
+/**
+ * \brief Variant of adjustTimeSlotHQ() which only adds the additional harmonics
+ */
+static void adjustTimeSlotHQ_AddHarmonics(
+ FIXP_DBL *ptrReal, FIXP_DBL *ptrImag,
+ HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
+ int lowSubbands, int noSubbands, int scale_change);
+
+static void adjustTimeSlotHQ(FIXP_DBL *ptrReal, FIXP_DBL *ptrImag,
+ HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
+ ENV_CALC_NRGS *nrgs, int lowSubbands,
+ int noSubbands, int scale_change,
+ FIXP_SGL smooth_ratio, int noNoiseFlag,
+ int filtBufferNoiseShift);
+
+/*!
+ \brief Map sine flags from bitstream to QMF bands
+
+ The bitstream carries only 1 sine flag per band (Sfb) and frame.
+ This function maps every sine flag from the bitstream to a specific QMF
+ subband and to a specific envelope where the sine shall start. The result is
+ stored in the vector sineMapped which contains one entry per QMF subband. The
+ value of an entry specifies the envelope where a sine shall start. A value of
+ 32 indicates that no sine is present in the subband. The missing harmonics
+ flags from the previous frame (harmFlagsPrev) determine if a sine starts at
+ the beginning of the frame or at the transient position. Additionally, the
+ flags in harmFlagsPrev are being updated by this function for the next frame.
+*/
+static void mapSineFlags(
+ UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */
+ int nSfb, /*!< Number of bands in the table */
+ ULONG *addHarmonics, /*!< Packed addHarmonics of current frame (aligned to
+ the MSB) */
+ ULONG *harmFlagsPrev, /*!< Packed addHarmonics of previous frame (aligned to
+ the LSB) */
+ ULONG *harmFlagsPrevActive, /*!< Packed sineMapped of previous frame
+ (aligned to the LSB) */
+ int tranEnv, /*!< Transient position */
+ SCHAR *sineMapped) /*!< Resulting vector of sine start positions for each
+ QMF band */
+
+{
+ int i;
+ int bitcount = 31;
+ ULONG harmFlagsQmfBands[ADD_HARMONICS_FLAGS_SIZE] = {0};
+ ULONG *curFlags = addHarmonics;
+
+ /*
+ Format of addHarmonics (aligned to MSB):
+
+ Up to MAX_FREQ_COEFFS sfb bands can be flagged for a sign.
+ first word = flags for lowest 32 sfb bands in use
+ second word = flags for higest 32 sfb bands (if present)
+
+ Format of harmFlagsPrev (aligned to LSB):
+
+ Index is absolute (not relative to lsb) so it is correct even if lsb
+ changes first word = flags for lowest 32 qmf bands (0...31) second word =
+ flags for next higher 32 qmf bands (32...63)
+
+ */
+
+ /* Reset the output vector first */
+ FDKmemset(sineMapped, 32,
+ MAX_FREQ_COEFFS * sizeof(SCHAR)); /* 32 means 'no sine' */
+ FDKmemclear(harmFlagsPrevActive, ADD_HARMONICS_FLAGS_SIZE * sizeof(ULONG));
+ for (i = 0; i < nSfb; i++) {
+ ULONG maskSfb =
+ 1 << bitcount; /* mask to extract addHarmonics flag of current Sfb */
+
+ if (*curFlags & maskSfb) { /* There is a sine in this band */
+ const int lsb = freqBandTable[0]; /* start of sbr range */
+ /* qmf band to which sine should be added */
+ const int qmfBand = (freqBandTable[i] + freqBandTable[i + 1]) >> 1;
+ const int qmfBandDiv32 = qmfBand >> 5;
+ const int maskQmfBand =
+ 1 << (qmfBand &
+ 31); /* mask to extract harmonic flag from prevFlags */
+
+ /* mapping of sfb with sine to a certain qmf band -> for harmFlagsPrev */
+ harmFlagsQmfBands[qmfBandDiv32] |= maskQmfBand;
+
+ /*
+ If there was a sine in the last frame, let it continue from the first
+ envelope on else start at the transient position. Indexing of sineMapped
+ starts relative to lsb.
+ */
+ sineMapped[qmfBand - lsb] =
+ (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) ? 0 : tranEnv;
+ if (sineMapped[qmfBand - lsb] < PVC_NTIMESLOT) {
+ harmFlagsPrevActive[qmfBandDiv32] |= maskQmfBand;
+ }
+ }
+
+ if (bitcount-- == 0) {
+ bitcount = 31;
+ curFlags++;
+ }
+ }
+ FDKmemcpy(harmFlagsPrev, harmFlagsQmfBands,
+ sizeof(ULONG) * ADD_HARMONICS_FLAGS_SIZE);
+}
+
+/*!
+ \brief Restore sineMapped of previous frame
+
+ For PVC it might happen that the PVC framing (always 0) is out of sync with
+ the SBR framing. The adding of additional harmonics is done based on the SBR
+ framing. If the SBR framing is trailing the PVC framing the sine mapping of
+ the previous SBR frame needs to be used for the overlapping time slots.
+*/
+/*static*/ void mapSineFlagsPvc(
+ UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per
+ band) */
+ int nSfb, /*!< Number of bands in the table */
+ ULONG *harmFlagsPrev, /*!< Packed addHarmonics of previous frame
+ (aligned to the MSB) */
+ ULONG *harmFlagsPrevActive, /*!< Packed sineMapped of previous
+ frame (aligned to the LSB) */
+ SCHAR *sineMapped, /*!< Resulting vector of sine start positions
+ for each QMF band */
+ int sinusoidalPos, /*!< sinusoidal position */
+ SCHAR *sinusoidalPosPrev, /*!< sinusoidal position of previous
+ frame */
+ int trailingSbrFrame) /*!< indication if the SBR framing is
+ trailing the PVC framing */
+{
+ /* Reset the output vector first */
+ FDKmemset(sineMapped, 32, MAX_FREQ_COEFFS); /* 32 means 'no sine' */
+
+ if (trailingSbrFrame) {
+ /* restore sineMapped[] of previous frame */
+ int i;
+ const int lsb = freqBandTable[0];
+ const int usb = freqBandTable[nSfb];
+ for (i = lsb; i < usb; i++) {
+ const int qmfBandDiv32 = i >> 5;
+ const int maskQmfBand =
+ 1 << (i & 31); /* mask to extract harmonic flag from prevFlags */
+
+ /* Two cases need to be distinguished ... */
+ if (harmFlagsPrevActive[qmfBandDiv32] & maskQmfBand) {
+ /* the sine mapping already started last PVC frame -> seamlessly
+ * continue */
+ sineMapped[i - lsb] = 0;
+ } else if (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) {
+ /* sinusoidalPos of prev PVC frame was >= PVC_NTIMESLOT -> sine starts
+ * in this frame */
+ sineMapped[i - lsb] =
+ *sinusoidalPosPrev - PVC_NTIMESLOT; /* we are 16 sbr time slots
+ ahead of last frame now */
+ }
+ }
+ }
+ *sinusoidalPosPrev = sinusoidalPos;
+}
+
+/*!
+ \brief Reduce gain-adjustment induced aliasing for real valued filterbank.
+*/
+/*static*/ void aliasingReduction(
+ FIXP_DBL *degreeAlias, /*!< estimated aliasing for each QMF
+ channel */
+ ENV_CALC_NRGS *nrgs,
+ UCHAR *useAliasReduction, /*!< synthetic sine energy for each
+ subband, used as flag */
+ int noSubbands) /*!< number of QMF channels to process */
+{
+ FIXP_DBL *nrgGain = nrgs->nrgGain; /*!< subband gains to be modified */
+ SCHAR *nrgGain_e =
+ nrgs->nrgGain_e; /*!< subband gains to be modified (exponents) */
+ FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< subband energy before amplification */
+ SCHAR *nrgEst_e =
+ nrgs->nrgEst_e; /*!< subband energy before amplification (exponents) */
+ int grouping = 0, index = 0, noGroups, k;
+ int groupVector[MAX_FREQ_COEFFS];
+
+ /* Calculate grouping*/
+ for (k = 0; k < noSubbands - 1; k++) {
+ if ((degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k]) {
+ if (grouping == 0) {
+ groupVector[index++] = k;
+ grouping = 1;
+ } else {
+ if (groupVector[index - 1] + 3 == k) {
+ groupVector[index++] = k + 1;
+ grouping = 0;
+ }
+ }
+ } else {
+ if (grouping) {
+ if (useAliasReduction[k])
+ groupVector[index++] = k + 1;
+ else
+ groupVector[index++] = k;
+ grouping = 0;
+ }
+ }
+ }
+
+ if (grouping) {
+ groupVector[index++] = noSubbands;
+ }
+ noGroups = index >> 1;
+
+ /*Calculate new gain*/
+ for (int group = 0; group < noGroups; group++) {
+ FIXP_DBL nrgOrig = FL2FXCONST_DBL(
+ 0.0f); /* Original signal energy in current group of bands */
+ SCHAR nrgOrig_e = 0;
+ FIXP_DBL nrgAmp = FL2FXCONST_DBL(
+ 0.0f); /* Amplified signal energy in group (using current gains) */
+ SCHAR nrgAmp_e = 0;
+ FIXP_DBL nrgMod = FL2FXCONST_DBL(
+ 0.0f); /* Signal energy in group when applying modified gains */
+ SCHAR nrgMod_e = 0;
+ FIXP_DBL groupGain; /* Total energy gain in group */
+ SCHAR groupGain_e;
+ FIXP_DBL compensation; /* Compensation factor for the energy change when
+ applying modified gains */
+ SCHAR compensation_e;
+
+ int startGroup = groupVector[2 * group];
+ int stopGroup = groupVector[2 * group + 1];
+
+ /* Calculate total energy in group before and after amplification with
+ * current gains: */
+ for (k = startGroup; k < stopGroup; k++) {
+ /* Get original band energy */
+ FIXP_DBL tmp = nrgEst[k];
+ SCHAR tmp_e = nrgEst_e[k];
+
+ FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e);
+
+ /* Multiply band energy with current gain */
+ tmp = fMult(tmp, nrgGain[k]);
+ tmp_e = tmp_e + nrgGain_e[k];
+
+ FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e);
+ }
+
+ /* Calculate total energy gain in group */
+ FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgOrig, nrgOrig_e, &groupGain,
+ &groupGain_e);
+
+ for (k = startGroup; k < stopGroup; k++) {
+ FIXP_DBL tmp;
+ SCHAR tmp_e;
+
+ FIXP_DBL alpha = degreeAlias[k];
+ if (k < noSubbands - 1) {
+ if (degreeAlias[k + 1] > alpha) alpha = degreeAlias[k + 1];
+ }
+
+ /* Modify gain depending on the degree of aliasing */
+ FDK_add_MantExp(
+ fMult(alpha, groupGain), groupGain_e,
+ fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha,
+ nrgGain[k]),
+ nrgGain_e[k], &nrgGain[k], &nrgGain_e[k]);
+
+ /* Apply modified gain to original energy */
+ tmp = fMult(nrgGain[k], nrgEst[k]);
+ tmp_e = nrgGain_e[k] + nrgEst_e[k];
+
+ /* Accumulate energy with modified gains applied */
+ FDK_add_MantExp(tmp, tmp_e, nrgMod, nrgMod_e, &nrgMod, &nrgMod_e);
+ }
+
+ /* Calculate compensation factor to retain the energy of the amplified
+ * signal */
+ FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgMod, nrgMod_e, &compensation,
+ &compensation_e);
+
+ /* Apply compensation factor to all gains of the group */
+ for (k = startGroup; k < stopGroup; k++) {
+ nrgGain[k] = fMult(nrgGain[k], compensation);
+ nrgGain_e[k] = nrgGain_e[k] + compensation_e;
+ }
+ }
+}
+
+#define INTER_TES_SF_CHANGE 3
+
+typedef struct {
+ FIXP_DBL subsample_power_low[(((1024) / (32) * (4) / 2) + (3 * (4)))];
+ FIXP_DBL subsample_power_high[(((1024) / (32) * (4) / 2) + (3 * (4)))];
+ FIXP_DBL gain[(((1024) / (32) * (4) / 2) + (3 * (4)))];
+ SCHAR subsample_power_low_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))];
+ SCHAR subsample_power_high_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))];
+} ITES_TEMP;
+
+static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
+ const QMF_SCALE_FACTOR *sbrScaleFactor,
+ const SCHAR exp[2], const int RATE,
+ const int startPos, const int stopPos,
+ const int lowSubband, const int nbSubband,
+ const UCHAR gamma_idx) {
+ int highSubband = lowSubband + nbSubband;
+ FIXP_DBL *subsample_power_high, *subsample_power_low;
+ SCHAR *subsample_power_high_sf, *subsample_power_low_sf;
+ FIXP_DBL total_power_high = (FIXP_DBL)0;
+ FIXP_DBL total_power_low = (FIXP_DBL)0;
+ FIXP_DBL *gain;
+ int gain_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))];
+
+ /* gamma[gamma_idx] = {0.0f, 1.0f, 2.0f, 4.0f} */
+ int gamma_sf =
+ (int)gamma_idx - 1; /* perhaps +1 to save one bit? (0.99999f vs 1.f) */
+
+ int nbSubsample = stopPos - startPos;
+ int i, j;
+
+ C_ALLOC_SCRATCH_START(pTmp, ITES_TEMP, 1);
+ subsample_power_high = pTmp->subsample_power_high;
+ subsample_power_low = pTmp->subsample_power_low;
+ subsample_power_high_sf = pTmp->subsample_power_high_sf;
+ subsample_power_low_sf = pTmp->subsample_power_low_sf;
+ gain = pTmp->gain;
+
+ if (gamma_idx > 0) {
+ int preShift2 = 32 - fNormz((FIXP_DBL)nbSubsample);
+ int total_power_low_sf = 1 - DFRACT_BITS;
+ int total_power_high_sf = 1 - DFRACT_BITS;
+
+ for (i = 0; i < nbSubsample; ++i) {
+ FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))];
+ FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))];
+ FIXP_DBL maxVal = (FIXP_DBL)0;
+
+ int ts = startPos + i;
+
+ int low_sf = (ts < 3 * RATE) ? sbrScaleFactor->ov_lb_scale
+ : sbrScaleFactor->lb_scale;
+ low_sf = 15 - low_sf;
+
+ for (j = 0; j < lowSubband; ++j) {
+ bufferImag[j] = qmfImag[startPos + i][j];
+ maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^
+ ((LONG)bufferImag[j] >> (DFRACT_BITS - 1)));
+ bufferReal[j] = qmfReal[startPos + i][j];
+ maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^
+ ((LONG)bufferReal[j] >> (DFRACT_BITS - 1)));
+ }
+
+ subsample_power_low[i] = (FIXP_DBL)0;
+ subsample_power_low_sf[i] = 0;
+
+ if (maxVal != FL2FXCONST_DBL(0.f)) {
+ /* multiply first, then shift for safe summation */
+ int preShift = 1 - CntLeadingZeros(maxVal);
+ int postShift = 32 - fNormz((FIXP_DBL)lowSubband);
+
+ /* reduce preShift because otherwise we risk to square -1.f */
+ if (preShift != 0) preShift++;
+
+ subsample_power_low_sf[i] += (low_sf + preShift) * 2 + postShift + 1;
+
+ scaleValues(bufferReal, lowSubband, -preShift);
+ scaleValues(bufferImag, lowSubband, -preShift);
+ for (j = 0; j < lowSubband; ++j) {
+ FIXP_DBL addme;
+ addme = fPow2Div2(bufferReal[j]);
+ subsample_power_low[i] += addme >> postShift;
+ addme = fPow2Div2(bufferImag[j]);
+ subsample_power_low[i] += addme >> postShift;
+ }
+ }
+
+ /* now get high */
+
+ maxVal = (FIXP_DBL)0;
+
+ int high_sf = exp[(ts < 16 * RATE) ? 0 : 1];
+
+ for (j = lowSubband; j < highSubband; ++j) {
+ bufferImag[j] = qmfImag[startPos + i][j];
+ maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^
+ ((LONG)bufferImag[j] >> (DFRACT_BITS - 1)));
+ bufferReal[j] = qmfReal[startPos + i][j];
+ maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^
+ ((LONG)bufferReal[j] >> (DFRACT_BITS - 1)));
+ }
+
+ subsample_power_high[i] = (FIXP_DBL)0;
+ subsample_power_high_sf[i] = 0;
+
+ if (maxVal != FL2FXCONST_DBL(0.f)) {
+ int preShift = 1 - CntLeadingZeros(maxVal);
+ /* reduce preShift because otherwise we risk to square -1.f */
+ if (preShift != 0) preShift++;
+
+ int postShift = 32 - fNormz((FIXP_DBL)(highSubband - lowSubband));
+ subsample_power_high_sf[i] += (high_sf + preShift) * 2 + postShift + 1;
+
+ scaleValues(&bufferReal[lowSubband], highSubband - lowSubband,
+ -preShift);
+ scaleValues(&bufferImag[lowSubband], highSubband - lowSubband,
+ -preShift);
+ for (j = lowSubband; j < highSubband; j++) {
+ subsample_power_high[i] += fPow2Div2(bufferReal[j]) >> postShift;
+ subsample_power_high[i] += fPow2Div2(bufferImag[j]) >> postShift;
+ }
+ }
+
+ /* sum all together */
+ FIXP_DBL new_summand = subsample_power_low[i];
+ int new_summand_sf = subsample_power_low_sf[i];
+
+ /* make sure the current sum, and the new summand have the same SF */
+ if (new_summand_sf > total_power_low_sf) {
+ int diff = fMin(DFRACT_BITS - 1, new_summand_sf - total_power_low_sf);
+ total_power_low >>= diff;
+ total_power_low_sf = new_summand_sf;
+ } else if (new_summand_sf < total_power_low_sf) {
+ new_summand >>=
+ fMin(DFRACT_BITS - 1, total_power_low_sf - new_summand_sf);
+ }
+
+ total_power_low += (new_summand >> preShift2);
+
+ new_summand = subsample_power_high[i];
+ new_summand_sf = subsample_power_high_sf[i];
+ if (new_summand_sf > total_power_high_sf) {
+ total_power_high >>=
+ fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_sf);
+ total_power_high_sf = new_summand_sf;
+ } else if (new_summand_sf < total_power_high_sf) {
+ new_summand >>=
+ fMin(DFRACT_BITS - 1, total_power_high_sf - new_summand_sf);
+ }
+
+ total_power_high += (new_summand >> preShift2);
+ }
+
+ total_power_low_sf += preShift2;
+ total_power_high_sf += preShift2;
+
+ /* gain[i] = e_LOW[i] */
+ for (i = 0; i < nbSubsample; ++i) {
+ int sf2;
+ FIXP_DBL mult =
+ fMultNorm(subsample_power_low[i], (FIXP_DBL)nbSubsample, &sf2);
+ int mult_sf = subsample_power_low_sf[i] + DFRACT_BITS - 1 + sf2;
+
+ if (total_power_low != FIXP_DBL(0)) {
+ gain[i] = fDivNorm(mult, total_power_low, &sf2);
+ gain_sf[i] = mult_sf - total_power_low_sf + sf2;
+ gain[i] = sqrtFixp_lookup(gain[i], &gain_sf[i]);
+ if (gain_sf[i] < 0) {
+ gain[i] >>= -gain_sf[i];
+ gain_sf[i] = 0;
+ }
+ } else {
+ if (mult == FIXP_DBL(0)) {
+ gain[i] = FIXP_DBL(0);
+ gain_sf[i] = 0;
+ } else {
+ gain[i] = (FIXP_DBL)MAXVAL_DBL;
+ gain_sf[i] = 0;
+ }
+ }
+ }
+
+ FIXP_DBL total_power_high_after = (FIXP_DBL)0;
+ int total_power_high_after_sf = 1 - DFRACT_BITS;
+
+ /* gain[i] = g_inter[i] */
+ for (i = 0; i < nbSubsample; ++i) {
+ if (gain_sf[i] < 0) {
+ gain[i] >>= -gain_sf[i];
+ gain_sf[i] = 0;
+ }
+
+ /* calculate: gain[i] = 1.0f + gamma * (gain[i] - 1.0f); */
+ FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >>
+ gain_sf[i]; /* to substract this from gain[i] */
+
+ /* gamma is actually always 1 according to the table, so skip the
+ * fMultDiv2 */
+ FIXP_DBL mult = (gain[i] - one) >> 1;
+ int mult_sf = gain_sf[i] + gamma_sf;
+
+ one = FL2FXCONST_DBL(0.5f) >> mult_sf;
+ gain[i] = one + mult;
+ gain_sf[i] += gamma_sf + 1; /* +1 because of fMultDiv2() */
+
+ /* set gain to at least 0.2f */
+ FIXP_DBL point_two = FL2FXCONST_DBL(0.8f); /* scaled up by 2 */
+ int point_two_sf = -2;
+
+ FIXP_DBL tmp = gain[i];
+ if (point_two_sf < gain_sf[i]) {
+ point_two >>= gain_sf[i] - point_two_sf;
+ } else {
+ tmp >>= point_two_sf - gain_sf[i];
+ }
+
+ /* limit and calculate gain[i]^2 too */
+ FIXP_DBL gain_pow2;
+ int gain_pow2_sf;
+ if (tmp < point_two) {
+ gain[i] = FL2FXCONST_DBL(0.8f);
+ gain_sf[i] = -2;
+ gain_pow2 = FL2FXCONST_DBL(0.64f);
+ gain_pow2_sf = -4;
+ } else {
+ /* this upscaling seems quite important */
+ int r = CountLeadingBits(gain[i]);
+ gain[i] <<= r;
+ gain_sf[i] -= r;
+
+ gain_pow2 = fPow2(gain[i]);
+ gain_pow2_sf = gain_sf[i] << 1;
+ }
+
+ int room;
+ subsample_power_high[i] =
+ fMultNorm(subsample_power_high[i], gain_pow2, &room);
+ subsample_power_high_sf[i] =
+ subsample_power_high_sf[i] + gain_pow2_sf + room;
+
+ int new_summand_sf = subsample_power_high_sf[i]; /* + gain_pow2_sf; */
+ if (new_summand_sf > total_power_high_after_sf) {
+ total_power_high_after >>=
+ fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf);
+ total_power_high_after_sf = new_summand_sf;
+ } else if (new_summand_sf < total_power_high_after_sf) {
+ subsample_power_high[i] >>= total_power_high_after_sf - new_summand_sf;
+ }
+ total_power_high_after += subsample_power_high[i] >> preShift2;
+ }
+
+ total_power_high_after_sf += preShift2;
+
+ int sf2 = 0;
+ FIXP_DBL gain_adj_2 = FL2FX_DBL(0.5f);
+ int gain_adj_2_sf = 1;
+
+ if ((total_power_high != (FIXP_DBL)0) &&
+ (total_power_high_after != (FIXP_DBL)0)) {
+ gain_adj_2 = fDivNorm(total_power_high, total_power_high_after, &sf2);
+ gain_adj_2_sf = total_power_high_sf - total_power_high_after_sf + sf2;
+ }
+
+ FIXP_DBL gain_adj = sqrtFixp_lookup(gain_adj_2, &gain_adj_2_sf);
+ int gain_adj_sf = gain_adj_2_sf;
+
+ for (i = 0; i < nbSubsample; ++i) {
+ gain[i] = fMult(gain[i], gain_adj);
+ gain_sf[i] += gain_adj_sf;
+
+ /* limit gain */
+ if (gain_sf[i] > INTER_TES_SF_CHANGE) {
+ gain[i] = (FIXP_DBL)MAXVAL_DBL;
+ gain_sf[i] = INTER_TES_SF_CHANGE;
+ }
+ }
+
+ for (i = 0; i < nbSubsample; ++i) {
+ /* equalize gain[]'s scale factors */
+ gain[i] >>= INTER_TES_SF_CHANGE - gain_sf[i];
+
+ for (j = lowSubband; j < highSubband; j++) {
+ qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain[i]);
+ qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain[i]);
+ }
+ }
+ } else { /* gamma_idx == 0 */
+ /* Inter-TES is not active. Still perform the scale change to have a
+ * consistent scaling for all envelopes of this frame. */
+ for (i = 0; i < nbSubsample; ++i) {
+ for (j = lowSubband; j < highSubband; j++) {
+ qmfReal[startPos + i][j] >>= INTER_TES_SF_CHANGE;
+ qmfImag[startPos + i][j] >>= INTER_TES_SF_CHANGE;
+ }
+ }
+ }
+ C_ALLOC_SCRATCH_END(pTmp, ITES_TEMP, 1);
+}
+
+/*!
+ \brief Apply spectral envelope to subband samples
+
+ This function is called from sbr_dec.cpp in each frame.
+
+ To enhance accuracy and due to the usage of tables for squareroots and
+ inverse, some calculations are performed with the operands being split
+ into mantissa and exponent. The variable names in the source code carry
+ the suffixes <em>_m</em> and <em>_e</em> respectively. The control data
+ in #hFrameData containts envelope data which is represented by this format but
+ stored in single words. (See requantizeEnvelopeData() for details). This data
+ is unpacked within calculateSbrEnvelope() to follow the described suffix
+ convention.
+
+ The actual value (comparable to the corresponding float-variable in the
+ research-implementation) of a mantissa/exponent-pair can be calculated as
+
+ \f$ value = value\_m * 2^{value\_e} \f$
+
+ All energies and noise levels decoded from the bitstream suit for an
+ original signal magnitude of \f$\pm 32768 \f$ rather than \f$ \pm 1\f$.
+ Therefore, the scale factor <em>hb_scale</em> passed into this function will
+ be converted to an 'input exponent' (#input_e), which fits the internal
+ representation.
+
+ Before the actual processing, an exponent #adj_e for resulting adjusted
+ samples is derived from the maximum reference energy.
+
+ Then, for each envelope, the following steps are performed:
+
+ \li Calculate energy in the signal to be adjusted. Depending on the the value
+ of #interpolFreq (interpolation mode), this is either done seperately for each
+ QMF-subband or for each SBR-band. The resulting energies are stored in
+ #nrgEst_m[#MAX_FREQ_COEFFS] (mantissas) and #nrgEst_e[#MAX_FREQ_COEFFS]
+ (exponents). \li Calculate gain and noise level for each subband:<br> \f$ gain
+ = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) } \hspace{2cm} noise =
+ \sqrt{ nrgRef \cdot noiseRatio } \f$<br> where <em>noiseRatio</em> and
+ <em>nrgRef</em> are extracted from the bitstream and <em>nrgEst</em> is the
+ subband energy before adjustment. The resulting gains are stored in
+ #nrgGain_m[#MAX_FREQ_COEFFS] (mantissas) and #nrgGain_e[#MAX_FREQ_COEFFS]
+ (exponents), the noise levels are stored in #noiseLevel_m[#MAX_FREQ_COEFFS]
+ and #noiseLevel_e[#MAX_FREQ_COEFFS] (exponents). The sine levels are stored in
+ #nrgSine_m[#MAX_FREQ_COEFFS] and #nrgSine_e[#MAX_FREQ_COEFFS]. \li Noise
+ limiting: The gain for each subband is limited both absolutely and relatively
+ compared to the total gain over all subbands. \li Boost gain: Calculate and
+ apply boost factor for each limiter band in order to compensate for the energy
+ loss imposed by the limiting. \li Apply gains and add noise: The gains and
+ noise levels are applied to all timeslots of the current envelope. A short
+ FIR-filter (length 4 QMF-timeslots) can be used to smooth the sudden change at
+ the envelope borders. Each complex subband sample of the current timeslot is
+ multiplied by the smoothed gain, then random noise with the calculated level
+ is added.
+
+ \note
+ To reduce the stack size, some of the local arrays could be located within
+ the time output buffer. Of the 512 samples temporarily available there,
+ about half the size is already used by #SBR_FRAME_DATA. A pointer to the
+ remaining free memory could be supplied by an additional argument to
+ calculateSbrEnvelope() in sbr_dec:
+
+ \par
+ \code
+ calculateSbrEnvelope (&hSbrDec->sbrScaleFactor,
+ &hSbrDec->SbrCalculateEnvelope,
+ hHeaderData,
+ hFrameData,
+ QmfBufferReal,
+ QmfBufferImag,
+ timeOutPtr + sizeof(SBR_FRAME_DATA)/sizeof(Float) +
+ 1); \endcode
+
+ \par
+ Within calculateSbrEnvelope(), some pointers could be defined instead of the
+ arrays #nrgRef_m, #nrgRef_e, #nrgEst_m, #nrgEst_e, #noiseLevel_m:
+
+ \par
+ \code
+ fract* nrgRef_m = timeOutPtr;
+ SCHAR* nrgRef_e = nrgRef_m + MAX_FREQ_COEFFS;
+ fract* nrgEst_m = nrgRef_e + MAX_FREQ_COEFFS;
+ SCHAR* nrgEst_e = nrgEst_m + MAX_FREQ_COEFFS;
+ fract* noiseLevel_m = nrgEst_e + MAX_FREQ_COEFFS;
+ \endcode
+
+ <br>
+*/
+void calculateSbrEnvelope(
+ QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
+ HANDLE_SBR_CALCULATE_ENVELOPE
+ h_sbr_cal_env, /*!< Handle to struct filled by the create-function */
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
+ PVC_DYNAMIC_DATA *pPvcDynamicData,
+ FIXP_DBL *
+ *analysBufferReal, /*!< Real part of subband samples to be processed */
+ FIXP_DBL *
+ *analysBufferImag, /*!< Imag part of subband samples to be processed */
+ const int useLP,
+ FIXP_DBL *degreeAlias, /*!< Estimated aliasing for each QMF channel */
+ const UINT flags, const int frameErrorFlag) {
+ int c, i, i_stop, j, envNoise = 0;
+ UCHAR *borders = hFrameData->frameInfo.borders;
+ UCHAR *bordersPvc = hFrameData->frameInfo.pvcBorders;
+ int pvc_mode = pPvcDynamicData->pvc_mode;
+ int first_start =
+ ((pvc_mode > 0) ? bordersPvc[0] : borders[0]) * hHeaderData->timeStep;
+ FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel;
+ HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
+ UCHAR **pFreqBandTable = hFreq->freqBandTable;
+ UCHAR *pFreqBandTableNoise = hFreq->freqBandTableNoise;
+
+ int lowSubband = hFreq->lowSubband;
+ int highSubband = hFreq->highSubband;
+ int noSubbands = highSubband - lowSubband;
+
+ /* old high subband before headerchange
+ we asume no headerchange here */
+ int ov_highSubband = hFreq->highSubband;
+
+ int noNoiseBands = hFreq->nNfb;
+ UCHAR *noSubFrameBands = hFreq->nSfb;
+ int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep;
+
+ SCHAR sineMapped[MAX_FREQ_COEFFS];
+ SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale);
+ SCHAR adj_e = 0;
+ SCHAR output_e;
+ SCHAR final_e = 0;
+ /* inter-TES is active in one or more envelopes of the current SBR frame */
+ const int iTES_enable = hFrameData->iTESactive;
+ const int iTES_scale_change = (iTES_enable) ? INTER_TES_SF_CHANGE : 0;
+ SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP;
+
+ UCHAR smooth_length = 0;
+
+ FIXP_SGL *pIenv = hFrameData->iEnvelope;
+
+ C_ALLOC_SCRATCH_START(useAliasReduction, UCHAR, 64)
+
+ /* if values differ we had a headerchange; if old highband is bigger then new
+ one we need to patch overlap-highband-scaling for this frame (see use of
+ ov_highSubband) as overlap contains higher frequency components which would
+ get lost */
+ if (hFreq->highSubband < hFreq->ov_highSubband) {
+ ov_highSubband = hFreq->ov_highSubband;
+ }
+
+ if (pvc_mode > 0) {
+ if (hFrameData->frameInfo.bordersNoise[0] > bordersPvc[0]) {
+ /* noise envelope of previous frame is trailing into current PVC frame */
+ envNoise = -1;
+ noiseLevels = h_sbr_cal_env->prevSbrNoiseFloorLevel;
+ noNoiseBands = h_sbr_cal_env->prevNNfb;
+ noSubFrameBands = h_sbr_cal_env->prevNSfb;
+ lowSubband = h_sbr_cal_env->prevLoSubband;
+ highSubband = h_sbr_cal_env->prevHiSubband;
+
+ noSubbands = highSubband - lowSubband;
+ ov_highSubband = highSubband;
+ if (highSubband < h_sbr_cal_env->prev_ov_highSubband) {
+ ov_highSubband = h_sbr_cal_env->prev_ov_highSubband;
+ }
+
+ pFreqBandTable[0] = h_sbr_cal_env->prevFreqBandTableLo;
+ pFreqBandTable[1] = h_sbr_cal_env->prevFreqBandTableHi;
+ pFreqBandTableNoise = h_sbr_cal_env->prevFreqBandTableNoise;
+ }
+
+ mapSineFlagsPvc(pFreqBandTable[1], noSubFrameBands[1],
+ h_sbr_cal_env->harmFlagsPrev,
+ h_sbr_cal_env->harmFlagsPrevActive, sineMapped,
+ hFrameData->sinusoidal_position,
+ &h_sbr_cal_env->sinusoidal_positionPrev,
+ (borders[0] > bordersPvc[0]) ? 1 : 0);
+ } else {
+ /*
+ Extract sine flags for all QMF bands
+ */
+ mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
+ hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
+ h_sbr_cal_env->harmFlagsPrevActive,
+ hFrameData->frameInfo.tranEnv, sineMapped);
+ }
+
+ /*
+ Scan for maximum in bufferd noise levels.
+ This is needed in case that we had strong noise in the previous frame
+ which is smoothed into the current frame.
+ The resulting exponent is used as start value for the maximum search
+ in reference energies
+ */
+ if (!useLP)
+ adj_e = h_sbr_cal_env->filtBufferNoise_e -
+ getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
+
+ /*
+ Scan for maximum reference energy to be able
+ to select appropriate values for adj_e and final_e.
+ */
+ if (pvc_mode > 0) {
+ INT maxSfbNrg_e = pPvcDynamicData->predEsg_expMax;
+
+ /* Energy -> magnitude (sqrt halfens exponent) */
+ maxSfbNrg_e =
+ (maxSfbNrg_e + 1) >> 1; /* +1 to go safe (round to next higher int) */
+
+ /* Some safety margin is needed for 2 reasons:
+ - The signal energy is not equally spread over all subband samples in
+ a specific sfb of an envelope (Nrg could be too high by a factor of
+ envWidth * sfbWidth)
+ - Smoothing can smear high gains of the previous envelope into the
+ current
+ */
+ maxSfbNrg_e += 6;
+
+ adj_e = maxSfbNrg_e;
+ // final_e should not exist for PVC fixfix framing
+ } else {
+ for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
+ INT maxSfbNrg_e =
+ -FRACT_BITS + NRG_EXP_OFFSET; /* start value for maximum search */
+
+ /* Fetch frequency resolution for current envelope: */
+ for (j = noSubFrameBands[hFrameData->frameInfo.freqRes[i]]; j != 0; j--) {
+ maxSfbNrg_e = fixMax(maxSfbNrg_e, (INT)((LONG)(*pIenv++) & MASK_E));
+ }
+ maxSfbNrg_e -= NRG_EXP_OFFSET;
+
+ /* Energy -> magnitude (sqrt halfens exponent) */
+ maxSfbNrg_e =
+ (maxSfbNrg_e + 1) >> 1; /* +1 to go safe (round to next higher int) */
+
+ /* Some safety margin is needed for 2 reasons:
+ - The signal energy is not equally spread over all subband samples in
+ a specific sfb of an envelope (Nrg could be too high by a factor of
+ envWidth * sfbWidth)
+ - Smoothing can smear high gains of the previous envelope into the
+ current
+ */
+ maxSfbNrg_e += 6;
+
+ if (borders[i] < hHeaderData->numberTimeSlots)
+ /* This envelope affects timeslots that belong to the output frame */
+ adj_e = fMax(maxSfbNrg_e, adj_e);
+
+ if (borders[i + 1] > hHeaderData->numberTimeSlots)
+ /* This envelope affects timeslots after the output frame */
+ final_e = fMax(maxSfbNrg_e, final_e);
+ }
+ }
+ /*
+ Calculate adjustment factors and apply them for every envelope.
+ */
+ pIenv = hFrameData->iEnvelope;
+
+ if (pvc_mode > 0) {
+ /* iterate over SBR time slots starting with bordersPvc[i] */
+ i = bordersPvc[0]; /* usually 0; can be >0 if switching from legacy SBR to
+ PVC */
+ i_stop = PVC_NTIMESLOT;
+ FDK_ASSERT(bordersPvc[hFrameData->frameInfo.nEnvelopes] == PVC_NTIMESLOT);
+ } else {
+ /* iterate over SBR envelopes starting with 0 */
+ i = 0;
+ i_stop = hFrameData->frameInfo.nEnvelopes;
+ }
+ for (; i < i_stop; i++) {
+ int k, noNoiseFlag;
+ SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale);
+ C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1);
+
+ /*
+ Helper variables.
+ */
+ int start_pos, stop_pos, freq_res;
+ if (pvc_mode > 0) {
+ start_pos =
+ hHeaderData->timeStep *
+ i; /* Start-position in time (subband sample) for current envelope. */
+ stop_pos = hHeaderData->timeStep * (i + 1); /* Stop-position in time
+ (subband sample) for
+ current envelope. */
+ freq_res =
+ hFrameData->frameInfo
+ .freqRes[0]; /* Frequency resolution for current envelope. */
+ FDK_ASSERT(
+ freq_res ==
+ hFrameData->frameInfo.freqRes[hFrameData->frameInfo.nEnvelopes - 1]);
+ } else {
+ start_pos = hHeaderData->timeStep *
+ borders[i]; /* Start-position in time (subband sample) for
+ current envelope. */
+ stop_pos = hHeaderData->timeStep *
+ borders[i + 1]; /* Stop-position in time (subband sample) for
+ current envelope. */
+ freq_res =
+ hFrameData->frameInfo
+ .freqRes[i]; /* Frequency resolution for current envelope. */
+ }
+
+ /* Always fully initialize the temporary energy table. This prevents
+ negative energies and extreme gain factors in cases where the number of
+ limiter bands exceeds the number of subbands. The latter can be caused by
+ undetected bit errors and is tested by some streams from the
+ certification set. */
+ FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS));
+
+ if (pvc_mode > 0) {
+ /* get predicted energy values from PVC module */
+ expandPredEsg(pPvcDynamicData, i, (int)MAX_FREQ_COEFFS, pNrgs->nrgRef,
+ pNrgs->nrgRef_e);
+
+ if (i == borders[0]) {
+ mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
+ hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
+ h_sbr_cal_env->harmFlagsPrevActive,
+ hFrameData->sinusoidal_position, sineMapped);
+ }
+
+ if (i >= hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
+ if (envNoise >= 0) {
+ noiseLevels += noNoiseBands; /* The noise floor data is stored in a
+ row [noiseFloor1 noiseFloor2...].*/
+ } else {
+ /* leave trailing noise envelope of past frame */
+ noNoiseBands = hFreq->nNfb;
+ noSubFrameBands = hFreq->nSfb;
+ noiseLevels = hFrameData->sbrNoiseFloorLevel;
+
+ lowSubband = hFreq->lowSubband;
+ highSubband = hFreq->highSubband;
+
+ noSubbands = highSubband - lowSubband;
+ ov_highSubband = highSubband;
+ if (highSubband < hFreq->ov_highSubband) {
+ ov_highSubband = hFreq->ov_highSubband;
+ }
+
+ pFreqBandTable[0] = hFreq->freqBandTableLo;
+ pFreqBandTable[1] = hFreq->freqBandTableHi;
+ pFreqBandTableNoise = hFreq->freqBandTableNoise;
+ }
+ envNoise++;
+ }
+ } else {
+ /* If the start-pos of the current envelope equals the stop pos of the
+ current noise envelope, increase the pointer (i.e. choose the next
+ noise-floor).*/
+ if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
+ noiseLevels += noNoiseBands; /* The noise floor data is stored in a row
+ [noiseFloor1 noiseFloor2...].*/
+ envNoise++;
+ }
+ }
+ if (i == hFrameData->frameInfo.tranEnv ||
+ i == h_sbr_cal_env->prevTranEnv) /* attack */
+ {
+ noNoiseFlag = 1;
+ if (!useLP) smooth_length = 0; /* No smoothing on attacks! */
+ } else {
+ noNoiseFlag = 0;
+ if (!useLP)
+ smooth_length = (1 - hHeaderData->bs_data.smoothingLength)
+ << 2; /* can become either 0 or 4 */
+ }
+
+ /*
+ Energy estimation in transposed highband.
+ */
+ if (hHeaderData->bs_data.interpolFreq)
+ calcNrgPerSubband(analysBufferReal, (useLP) ? NULL : analysBufferImag,
+ lowSubband, highSubband, start_pos, stop_pos, input_e,
+ pNrgs->nrgEst, pNrgs->nrgEst_e);
+ else
+ calcNrgPerSfb(analysBufferReal, (useLP) ? NULL : analysBufferImag,
+ noSubFrameBands[freq_res], pFreqBandTable[freq_res],
+ start_pos, stop_pos, input_e, pNrgs->nrgEst,
+ pNrgs->nrgEst_e);
+
+ /*
+ Calculate subband gains
+ */
+ {
+ UCHAR *table = pFreqBandTable[freq_res];
+ UCHAR *pUiNoise =
+ &pFreqBandTableNoise[1]; /*! Upper limit of the current noise floor
+ band. */
+
+ FIXP_SGL *pNoiseLevels = noiseLevels;
+
+ FIXP_DBL tmpNoise =
+ FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
+ SCHAR tmpNoise_e =
+ (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
+
+ int cc = 0;
+ c = 0;
+ if (pvc_mode > 0) {
+ for (j = 0; j < noSubFrameBands[freq_res]; j++) {
+ UCHAR sinePresentFlag = 0;
+ int li = table[j];
+ int ui = table[j + 1];
+
+ for (k = li; k < ui; k++) {
+ sinePresentFlag |= (i >= sineMapped[cc]);
+ cc++;
+ }
+
+ for (k = li; k < ui; k++) {
+ FIXP_DBL refNrg = pNrgs->nrgRef[k - lowSubband];
+ SCHAR refNrg_e = pNrgs->nrgRef_e[k - lowSubband];
+
+ if (k >= *pUiNoise) {
+ tmpNoise =
+ FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
+ tmpNoise_e =
+ (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
+
+ pUiNoise++;
+ }
+
+ FDK_ASSERT(k >= lowSubband);
+
+ if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
+
+ pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
+ pNrgs->nrgSine_e[c] = 0;
+
+ calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
+ sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
+
+ c++;
+ }
+ }
+ } else {
+ for (j = 0; j < noSubFrameBands[freq_res]; j++) {
+ FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M));
+ SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET;
+
+ UCHAR sinePresentFlag = 0;
+ int li = table[j];
+ int ui = table[j + 1];
+
+ for (k = li; k < ui; k++) {
+ sinePresentFlag |= (i >= sineMapped[cc]);
+ cc++;
+ }
+
+ for (k = li; k < ui; k++) {
+ if (k >= *pUiNoise) {
+ tmpNoise =
+ FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
+ tmpNoise_e =
+ (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
+
+ pUiNoise++;
+ }
+
+ FDK_ASSERT(k >= lowSubband);
+
+ if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
+
+ pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
+ pNrgs->nrgSine_e[c] = 0;
+
+ calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
+ sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
+
+ pNrgs->nrgRef[c] = refNrg;
+ pNrgs->nrgRef_e[c] = refNrg_e;
+
+ c++;
+ }
+ pIenv++;
+ }
+ }
+ }
+
+ /*
+ Noise limiting
+ */
+
+ for (c = 0; c < hFreq->noLimiterBands; c++) {
+ FIXP_DBL sumRef, boostGain, maxGain;
+ FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
+ SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0;
+ int maxGainLimGainSum_e = 0;
+
+ calcAvgGain(pNrgs, hFreq->limiterBandTable[c],
+ hFreq->limiterBandTable[c + 1], &sumRef, &sumRef_e, &maxGain,
+ &maxGain_e);
+
+ /* Multiply maxGain with limiterGain: */
+ maxGain = fMult(
+ maxGain,
+ FDK_sbrDecoder_sbr_limGains_m[hHeaderData->bs_data.limiterGains]);
+ /* maxGain_e +=
+ * FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains]; */
+ /* The addition of maxGain_e and FDK_sbrDecoder_sbr_limGains_e[3] might
+ yield values greater than 127 which doesn't fit into an SCHAR! In these
+ rare situations limit maxGain_e to 127.
+ */
+ maxGainLimGainSum_e =
+ maxGain_e +
+ FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains];
+ maxGain_e =
+ (maxGainLimGainSum_e > 127) ? (SCHAR)127 : (SCHAR)maxGainLimGainSum_e;
+
+ /* Scale mantissa of MaxGain into range between 0.5 and 1: */
+ if (maxGain == FL2FXCONST_DBL(0.0f))
+ maxGain_e = -FRACT_BITS;
+ else {
+ SCHAR charTemp = CountLeadingBits(maxGain);
+ maxGain_e -= charTemp;
+ maxGain <<= (int)charTemp;
+ }
+
+ if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */
+ maxGain = FL2FXCONST_DBL(0.5f);
+ maxGain_e = maxGainLimit_e;
+ }
+
+ /* Every subband gain is compared to the scaled "average gain"
+ and limited if necessary: */
+ for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
+ k++) {
+ if ((pNrgs->nrgGain_e[k] > maxGain_e) ||
+ (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k] > maxGain)) {
+ FIXP_DBL noiseAmp;
+ SCHAR noiseAmp_e;
+
+ FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k],
+ pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e);
+ pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k], noiseAmp);
+ pNrgs->noiseLevel_e[k] += noiseAmp_e;
+ pNrgs->nrgGain[k] = maxGain;
+ pNrgs->nrgGain_e[k] = maxGain_e;
+ }
+ }
+
+ /* -- Boost gain
+ Calculate and apply boost factor for each limiter band:
+ 1. Check how much energy would be present when using the limited gain
+ 2. Calculate boost factor by comparison with reference energy
+ 3. Apply boost factor to compensate for the energy loss due to limiting
+ */
+ for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
+ k++) {
+ /* 1.a Add energy of adjusted signal (using preliminary gain) */
+ FIXP_DBL tmp = fMult(pNrgs->nrgGain[k], pNrgs->nrgEst[k]);
+ SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k];
+ FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e);
+
+ /* 1.b Add sine energy (if present) */
+ if (pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) {
+ FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e,
+ &accu, &accu_e);
+ } else {
+ /* 1.c Add noise energy (if present) */
+ if (noNoiseFlag == 0) {
+ FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu,
+ accu_e, &accu, &accu_e);
+ }
+ }
+ }
+
+ /* 2.a Calculate ratio of wanted energy and accumulated energy */
+ if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */
+ boostGain = FL2FXCONST_DBL(0.6279716f);
+ boostGain_e = 2;
+ } else {
+ INT div_e;
+ boostGain = fDivNorm(sumRef, accu, &div_e);
+ boostGain_e = sumRef_e - accu_e + div_e;
+ }
+
+ /* 2.b Result too high? --> Limit the boost factor to +4 dB */
+ if ((boostGain_e > 3) ||
+ (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) ||
+ (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f))) {
+ boostGain = FL2FXCONST_DBL(0.6279716f);
+ boostGain_e = 2;
+ }
+ /* 3. Multiply all signal components with the boost factor */
+ for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
+ k++) {
+ pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k], boostGain);
+ pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1;
+
+ pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k], boostGain);
+ pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1;
+
+ pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k], boostGain);
+ pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1;
+ }
+ }
+ /* End of noise limiting */
+
+ if (useLP)
+ aliasingReduction(degreeAlias + lowSubband, pNrgs, useAliasReduction,
+ noSubbands);
+
+ /* For the timeslots within the range for the output frame,
+ use the same scale for the noise levels.
+ Drawback: If the envelope exceeds the frame border, the noise levels
+ will have to be rescaled later to fit final_e of
+ the gain-values.
+ */
+ noise_e = (start_pos < no_cols) ? adj_e : final_e;
+
+ /*
+ Convert energies to amplitude levels
+ */
+ for (k = 0; k < noSubbands; k++) {
+ FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e);
+ FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k],
+ &pNrgs->nrgGain_e[k]);
+ FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k],
+ &noise_e);
+ }
+
+ /*
+ Apply calculated gains and adaptive noise
+ */
+
+ /* assembleHfSignals() */
+ {
+ int scale_change, sc_change;
+ FIXP_SGL smooth_ratio;
+ int filtBufferNoiseShift = 0;
+
+ /* Initialize smoothing buffers with the first valid values */
+ if (h_sbr_cal_env->startUp) {
+ if (!useLP) {
+ h_sbr_cal_env->filtBufferNoise_e = noise_e;
+
+ FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
+ noSubbands * sizeof(SCHAR));
+ FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
+ noSubbands * sizeof(FIXP_DBL));
+ FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
+ noSubbands * sizeof(FIXP_DBL));
+ }
+ h_sbr_cal_env->startUp = 0;
+ }
+
+ if (!useLP) {
+ equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer, /* buffered */
+ h_sbr_cal_env->filtBuffer_e, /* buffered */
+ pNrgs->nrgGain, /* current */
+ pNrgs->nrgGain_e, /* current */
+ noSubbands);
+
+ /* Adapt exponent of buffered noise levels to the current exponent
+ so they can easily be smoothed */
+ if ((h_sbr_cal_env->filtBufferNoise_e - noise_e) >= 0) {
+ int shift = fixMin(DFRACT_BITS - 1,
+ (int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
+ for (k = 0; k < noSubbands; k++)
+ h_sbr_cal_env->filtBufferNoise[k] <<= shift;
+ } else {
+ int shift =
+ fixMin(DFRACT_BITS - 1,
+ -(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
+ for (k = 0; k < noSubbands; k++)
+ h_sbr_cal_env->filtBufferNoise[k] >>= shift;
+ }
+
+ h_sbr_cal_env->filtBufferNoise_e = noise_e;
+ }
+
+ /* find best scaling! */
+ scale_change = -(DFRACT_BITS - 1);
+ for (k = 0; k < noSubbands; k++) {
+ scale_change = fixMax(scale_change, (int)pNrgs->nrgGain_e[k]);
+ }
+ sc_change = (start_pos < no_cols) ? adj_e - input_e : final_e - input_e;
+
+ if ((scale_change - sc_change + 1) < 0)
+ scale_change -= (scale_change - sc_change + 1);
+
+ scale_change = (scale_change - sc_change) + 1;
+
+ for (k = 0; k < noSubbands; k++) {
+ int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1);
+ pNrgs->nrgGain[k] >>= sc;
+ pNrgs->nrgGain_e[k] += sc;
+ }
+
+ if (!useLP) {
+ for (k = 0; k < noSubbands; k++) {
+ int sc =
+ scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1);
+ h_sbr_cal_env->filtBuffer[k] >>= sc;
+ }
+ }
+
+ for (j = start_pos; j < stop_pos; j++) {
+ /* This timeslot is located within the first part of the processing
+ buffer and will be fed into the QMF-synthesis for the current frame.
+ adj_e - input_e
+ This timeslot will not yet be fed into the QMF so we do not care
+ about the adj_e.
+ sc_change = final_e - input_e
+ */
+ if ((j == no_cols) && (start_pos < no_cols)) {
+ int shift = (int)(noise_e - final_e);
+ if (!useLP)
+ filtBufferNoiseShift = shift; /* shifting of
+ h_sbr_cal_env->filtBufferNoise[k]
+ will be applied in function
+ adjustTimeSlotHQ() */
+ if (shift >= 0) {
+ shift = fixMin(DFRACT_BITS - 1, shift);
+ for (k = 0; k < noSubbands; k++) {
+ pNrgs->nrgSine[k] <<= shift;
+ pNrgs->noiseLevel[k] <<= shift;
+ /*
+ if (!useLP)
+ h_sbr_cal_env->filtBufferNoise[k] <<= shift;
+ */
+ }
+ } else {
+ shift = fixMin(DFRACT_BITS - 1, -shift);
+ for (k = 0; k < noSubbands; k++) {
+ pNrgs->nrgSine[k] >>= shift;
+ pNrgs->noiseLevel[k] >>= shift;
+ /*
+ if (!useLP)
+ h_sbr_cal_env->filtBufferNoise[k] >>= shift;
+ */
+ }
+ }
+
+ /* update noise scaling */
+ noise_e = final_e;
+ if (!useLP)
+ h_sbr_cal_env->filtBufferNoise_e =
+ noise_e; /* scaling value unused! */
+
+ /* update gain buffer*/
+ sc_change -= (final_e - input_e);
+
+ if (sc_change < 0) {
+ for (k = 0; k < noSubbands; k++) {
+ pNrgs->nrgGain[k] >>= -sc_change;
+ pNrgs->nrgGain_e[k] += -sc_change;
+ }
+ if (!useLP) {
+ for (k = 0; k < noSubbands; k++) {
+ h_sbr_cal_env->filtBuffer[k] >>= -sc_change;
+ }
+ }
+ } else {
+ scale_change += sc_change;
+ }
+
+ } /* if */
+
+ if (!useLP) {
+ /* Prevent the smoothing filter from running on constant levels */
+ if (j - start_pos < smooth_length)
+ smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j - start_pos];
+ else
+ smooth_ratio = FL2FXCONST_SGL(0.0f);
+
+ if (iTES_enable) {
+ /* adjustTimeSlotHQ() without adding of additional harmonics */
+ adjustTimeSlotHQ_GainAndNoise(
+ &analysBufferReal[j][lowSubband],
+ &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
+ lowSubband, noSubbands, fMin(scale_change, DFRACT_BITS - 1),
+ smooth_ratio, noNoiseFlag, filtBufferNoiseShift);
+ } else {
+ adjustTimeSlotHQ(&analysBufferReal[j][lowSubband],
+ &analysBufferImag[j][lowSubband], h_sbr_cal_env,
+ pNrgs, lowSubband, noSubbands,
+ fMin(scale_change, DFRACT_BITS - 1), smooth_ratio,
+ noNoiseFlag, filtBufferNoiseShift);
+ }
+ } else {
+ FDK_ASSERT(!iTES_enable); /* not supported */
+ if (flags & SBRDEC_ELD_GRID) {
+ /* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */
+ adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], pNrgs,
+ &h_sbr_cal_env->harmIndex, lowSubband,
+ noSubbands,
+ fMin(scale_change, DFRACT_BITS - 1),
+ noNoiseFlag, &h_sbr_cal_env->phaseIndex,
+ EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale);
+ } else {
+ adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs,
+ &h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
+ fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
+ &h_sbr_cal_env->phaseIndex);
+ }
+ }
+ /* In case the envelope spans accross the no_cols border both exponents
+ * are needed. */
+ /* nrgGain_e[0...(noSubbands-1)] are equalized by
+ * equalizeFiltBufferExp() */
+ pNrgs->exponent[(j < no_cols) ? 0 : 1] =
+ (SCHAR)((15 - sbrScaleFactor->hb_scale) + pNrgs->nrgGain_e[0] + 1 -
+ scale_change);
+ } /* for */
+
+ if (iTES_enable) {
+ apply_inter_tes(
+ analysBufferReal, /* pABufR, */
+ analysBufferImag, /* pABufI, */
+ sbrScaleFactor, pNrgs->exponent, hHeaderData->timeStep, start_pos,
+ stop_pos, lowSubband, noSubbands,
+ hFrameData
+ ->interTempShapeMode[i] /* frameData->interTempShapeMode[env] */
+ );
+
+ /* add additional harmonics */
+ for (j = start_pos; j < stop_pos; j++) {
+ /* match exponent of additional harmonics to scale change of QMF data
+ * caused by apply_inter_tes() */
+ scale_change = 0;
+
+ if ((start_pos <= no_cols) && (stop_pos > no_cols)) {
+ /* Scaling of analysBuffers was potentially changed within this
+ envelope. The pNrgs->nrgSine_e match the second part of the
+ envelope. For (j<=no_cols) the exponent of the sine energies has
+ to be adapted. */
+ scale_change = pNrgs->exponent[1] - pNrgs->exponent[0];
+ }
+
+ adjustTimeSlotHQ_AddHarmonics(
+ &analysBufferReal[j][lowSubband],
+ &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
+ lowSubband, noSubbands,
+ -iTES_scale_change + ((j < no_cols) ? scale_change : 0));
+ }
+ }
+
+ if (!useLP) {
+ /* Update time-smoothing-buffers for gains and noise levels
+ The gains and the noise values of the current envelope are copied
+ into the buffer. This has to be done at the end of each envelope as
+ the values are required for a smooth transition to the next envelope.
+ */
+ FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
+ noSubbands * sizeof(FIXP_DBL));
+ FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
+ noSubbands * sizeof(SCHAR));
+ FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
+ noSubbands * sizeof(FIXP_DBL));
+ }
+ }
+ C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1);
+ }
+
+ /* adapt adj_e to the scale change caused by apply_inter_tes() */
+ adj_e += iTES_scale_change;
+
+ /* Rescale output samples */
+ {
+ FIXP_DBL maxVal;
+ int ov_reserve, reserve;
+
+ /* Determine headroom in old adjusted samples */
+ maxVal =
+ maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
+ lowSubband, ov_highSubband, 0, first_start);
+
+ ov_reserve = fNorm(maxVal);
+
+ /* Determine headroom in new adjusted samples */
+ maxVal =
+ maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
+ lowSubband, highSubband, first_start, no_cols);
+
+ reserve = fNorm(maxVal);
+
+ /* Determine common output exponent */
+ output_e = fMax(ov_adj_e - ov_reserve, adj_e - reserve);
+
+ /* Rescale old samples */
+ rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
+ lowSubband, ov_highSubband, 0, first_start,
+ ov_adj_e - output_e);
+
+ /* Rescale new samples */
+ rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
+ lowSubband, highSubband, first_start, no_cols,
+ adj_e - output_e);
+ }
+
+ /* Update hb_scale */
+ sbrScaleFactor->hb_scale = EXP2SCALE(output_e);
+
+ /* Save the current final exponent for the next frame: */
+ /* adapt final_e to the scale change caused by apply_inter_tes() */
+ sbrScaleFactor->ov_hb_scale = EXP2SCALE(final_e + iTES_scale_change);
+
+ /* We need to remember to the next frame that the transient
+ will occur in the first envelope (if tranEnv == nEnvelopes). */
+ if (hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes)
+ h_sbr_cal_env->prevTranEnv = 0;
+ else
+ h_sbr_cal_env->prevTranEnv = -1;
+
+ if (pvc_mode > 0) {
+ /* Not more than just the last noise envelope reaches into the next PVC
+ frame! This should be true because bs_noise_position is <= 15 */
+ FDK_ASSERT(hFrameData->frameInfo
+ .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes - 1] <
+ PVC_NTIMESLOT);
+ if (hFrameData->frameInfo
+ .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes] >
+ PVC_NTIMESLOT) {
+ FDK_ASSERT(noiseLevels ==
+ (hFrameData->sbrNoiseFloorLevel +
+ (hFrameData->frameInfo.nNoiseEnvelopes - 1) * noNoiseBands));
+ h_sbr_cal_env->prevNNfb = noNoiseBands;
+
+ h_sbr_cal_env->prevNSfb[0] = noSubFrameBands[0];
+ h_sbr_cal_env->prevNSfb[1] = noSubFrameBands[1];
+
+ h_sbr_cal_env->prevLoSubband = lowSubband;
+ h_sbr_cal_env->prevHiSubband = highSubband;
+ h_sbr_cal_env->prev_ov_highSubband = ov_highSubband;
+
+ FDKmemcpy(h_sbr_cal_env->prevFreqBandTableLo, pFreqBandTable[0],
+ noSubFrameBands[0] + 1);
+ FDKmemcpy(h_sbr_cal_env->prevFreqBandTableHi, pFreqBandTable[1],
+ noSubFrameBands[1] + 1);
+ FDKmemcpy(h_sbr_cal_env->prevFreqBandTableNoise,
+ hFreq->freqBandTableNoise, sizeof(hFreq->freqBandTableNoise));
+
+ FDKmemcpy(h_sbr_cal_env->prevSbrNoiseFloorLevel, noiseLevels,
+ MAX_NOISE_COEFFS * sizeof(FIXP_SGL));
+ }
+ }
+
+ C_ALLOC_SCRATCH_END(useAliasReduction, UCHAR, 64)
+}
+
+/*!
+ \brief Create envelope instance
+
+ Must be called once for each channel before calculateSbrEnvelope() can be
+ used.
+
+ \return errorCode, 0 if successful
+*/
+SBR_ERROR
+createSbrEnvelopeCalc(
+ HANDLE_SBR_CALCULATE_ENVELOPE hs, /*!< pointer to envelope instance */
+ HANDLE_SBR_HEADER_DATA
+ hHeaderData, /*!< static SBR control data, initialized with defaults */
+ const int chan, /*!< Channel for which to assign buffers */
+ const UINT flags) {
+ SBR_ERROR err = SBRDEC_OK;
+ int i;
+
+ /* Clear previous missing harmonics flags */
+ for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) {
+ hs->harmFlagsPrev[i] = 0;
+ hs->harmFlagsPrevActive[i] = 0;
+ }
+ hs->harmIndex = 0;
+
+ FDKmemclear(hs->prevSbrNoiseFloorLevel, sizeof(hs->prevSbrNoiseFloorLevel));
+ hs->prevNNfb = 0;
+ FDKmemclear(hs->prevFreqBandTableNoise, sizeof(hs->prevFreqBandTableNoise));
+ hs->sinusoidal_positionPrev = 0;
+
+ /*
+ Setup pointers for time smoothing.
+ The buffer itself will be initialized later triggered by the startUp-flag.
+ */
+ hs->prevTranEnv = -1;
+
+ /* initialization */
+ resetSbrEnvelopeCalc(hs);
+
+ if (chan == 0) { /* do this only once */
+ err = resetFreqBandTables(hHeaderData, flags);
+ }
+
+ return err;
+}
+
+/*!
+ \brief Create envelope instance
+
+ Must be called once for each channel before calculateSbrEnvelope() can be
+ used.
+
+ \return errorCode, 0 if successful
+*/
+int deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs) { return 0; }
+
+/*!
+ \brief Reset envelope instance
+
+ This function must be called for each channel on a change of configuration.
+ Note that resetFreqBandTables should also be called in this case.
+
+ \return errorCode, 0 if successful
+*/
+void resetSbrEnvelopeCalc(
+ HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to envelope instance */
+{
+ hCalEnv->phaseIndex = 0;
+
+ /* Noise exponent needs to be reset because the output exponent for the next
+ * frame depends on it */
+ hCalEnv->filtBufferNoise_e = 0;
+
+ hCalEnv->startUp = 1;
+}
+
+/*!
+ \brief Equalize exponents of the buffered gain values and the new ones
+
+ After equalization of exponents, the FIR-filter addition for smoothing
+ can be performed.
+ This function is called once for each envelope before adjusting.
+*/
+static void equalizeFiltBufferExp(
+ FIXP_DBL *filtBuffer, /*!< bufferd gains */
+ SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */
+ FIXP_DBL *nrgGain, /*!< gains for current envelope */
+ SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */
+ int subbands) /*!< Number of QMF subbands */
+{
+ int band;
+ int diff;
+
+ for (band = 0; band < subbands; band++) {
+ diff = (int)(nrgGain_e[band] - filtBuffer_e[band]);
+ if (diff > 0) {
+ filtBuffer[band] >>=
+ diff; /* Compensate for the scale change by shifting the mantissa. */
+ filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
+ } else if (diff < 0) {
+ /* The buffered gains seem to be larger, but maybe there
+ are some unused bits left in the mantissa */
+
+ int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band])) - 1;
+
+ if ((-diff) <= reserve) {
+ /* There is enough space in the buffered mantissa so
+ that we can take the new exponent as common.
+ */
+ filtBuffer[band] <<= (-diff);
+ filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */
+ } else {
+ filtBuffer[band] <<=
+ reserve; /* Shift the mantissa as far as possible: */
+ filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
+
+ /* For the remaining difference, change the new gain value */
+ diff = fixMin(-(reserve + diff), DFRACT_BITS - 1);
+ nrgGain[band] >>= diff;
+ nrgGain_e[band] += diff;
+ }
+ }
+ }
+}
+
+/*!
+ \brief Shift left the mantissas of all subband samples
+ in the giventime and frequency range by the specified number of bits.
+
+ This function is used to rescale the audio data in the overlap buffer
+ which has already been envelope adjusted with the last frame.
+*/
+void rescaleSubbandSamples(
+ FIXP_DBL **re, /*!< Real part of input and output subband samples */
+ FIXP_DBL **im, /*!< Imaginary part of input and output subband samples */
+ int lowSubband, /*!< Begin of frequency range to process */
+ int highSubband, /*!< End of frequency range to process */
+ int start_pos, /*!< Begin of time rage (QMF-timeslot) */
+ int next_pos, /*!< End of time rage (QMF-timeslot) */
+ int shift) /*!< number of bits to shift */
+{
+ int width = highSubband - lowSubband;
+
+ if ((width > 0) && (shift != 0)) {
+ if (im != NULL) {
+ for (int l = start_pos; l < next_pos; l++) {
+ scaleValues(&re[l][lowSubband], width, shift);
+ scaleValues(&im[l][lowSubband], width, shift);
+ }
+ } else {
+ for (int l = start_pos; l < next_pos; l++) {
+ scaleValues(&re[l][lowSubband], width, shift);
+ }
+ }
+ }
+}
+
+static inline FIXP_DBL FDK_get_maxval_real(FIXP_DBL maxVal, FIXP_DBL *reTmp,
+ INT width) {
+ maxVal = (FIXP_DBL)0;
+ while (width-- != 0) {
+ FIXP_DBL tmp = *(reTmp++);
+ maxVal |= (FIXP_DBL)((LONG)(tmp) ^ ((LONG)tmp >> (DFRACT_BITS - 1)));
+ }
+
+ return maxVal;
+}
+
+/*!
+ \brief Determine headroom for shifting
+
+ Determine by how much the spectrum can be shifted left
+ for better accuracy in later processing.
+
+ \return Number of free bits in the biggest spectral value
+*/
+
+FIXP_DBL maxSubbandSample(
+ FIXP_DBL **re, /*!< Real part of input and output subband samples */
+ FIXP_DBL **im, /*!< Real part of input and output subband samples */
+ int lowSubband, /*!< Begin of frequency range to process */
+ int highSubband, /*!< Number of QMF bands to process */
+ int start_pos, /*!< Begin of time rage (QMF-timeslot) */
+ int next_pos /*!< End of time rage (QMF-timeslot) */
+) {
+ FIXP_DBL maxVal = FL2FX_DBL(0.0f);
+ unsigned int width = highSubband - lowSubband;
+
+ FDK_ASSERT(width <= (64));
+
+ if (width > 0) {
+ if (im != NULL) {
+ for (int l = start_pos; l < next_pos; l++) {
+ int k = width;
+ FIXP_DBL *reTmp = &re[l][lowSubband];
+ FIXP_DBL *imTmp = &im[l][lowSubband];
+ do {
+ FIXP_DBL tmp1 = *(reTmp++);
+ FIXP_DBL tmp2 = *(imTmp++);
+ maxVal |=
+ (FIXP_DBL)((LONG)(tmp1) ^ ((LONG)tmp1 >> (DFRACT_BITS - 1)));
+ maxVal |=
+ (FIXP_DBL)((LONG)(tmp2) ^ ((LONG)tmp2 >> (DFRACT_BITS - 1)));
+ } while (--k != 0);
+ }
+ } else {
+ for (int l = start_pos; l < next_pos; l++) {
+ maxVal |= FDK_get_maxval_real(maxVal, &re[l][lowSubband], width);
+ }
+ }
+ }
+
+ if (maxVal > (FIXP_DBL)0) {
+ /* For negative input values, maxVal is too small by 1. Add 1 only when
+ * necessary: if maxVal is a power of 2 */
+ FIXP_DBL lowerPow2 =
+ (FIXP_DBL)(1 << (DFRACT_BITS - 1 - CntLeadingZeros(maxVal)));
+ if (maxVal == lowerPow2) maxVal += (FIXP_DBL)1;
+ }
+
+ return (maxVal);
+}
+
+/* #define SHIFT_BEFORE_SQUARE (3) */ /* (7/2) */
+/* Avoid assertion failures triggerd by overflows which occured in robustness
+ tests. Setting the SHIFT_BEFORE_SQUARE to 4 has negligible effect on (USAC)
+ conformance results. */
+#define SHIFT_BEFORE_SQUARE (4) /* ((8 - 0) / 2) */
+
+/*!<
+ If the accumulator does not provide enough overflow bits or
+ does not provide a high dynamic range, the below energy calculation
+ requires an additional shift operation for each sample.
+ On the other hand, doing the shift allows using a single-precision
+ multiplication for the square (at least 16bit x 16bit).
+ For even values of OVRFLW_BITS (0, 2, 4, 6), saturated arithmetic
+ is required for the energy accumulation.
+ Theoretically, the sample-squares can sum up to a value of 76,
+ requiring 7 overflow bits. However since such situations are *very*
+ rare, accu can be limited to 64.
+ In case native saturated arithmetic is not available, overflows
+ can be prevented by replacing the above #define by
+ #define SHIFT_BEFORE_SQUARE ((8 - OVRFLW_BITS) / 2)
+ which will result in slightly reduced accuracy.
+*/
+
+/*!
+ \brief Estimates the mean energy of each filter-bank channel for the
+ duration of the current envelope
+
+ This function is used when interpolFreq is true.
+*/
+static void calcNrgPerSubband(
+ FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
+ FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
+ int lowSubband, /*!< Begin of the SBR frequency range */
+ int highSubband, /*!< High end of the SBR frequency range */
+ int start_pos, /*!< First QMF-slot of current envelope */
+ int next_pos, /*!< Last QMF-slot of current envelope + 1 */
+ SCHAR frameExp, /*!< Common exponent for all input samples */
+ FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */
+ SCHAR *nrgEst_e) /*!< Exponent of resulting Energy */
+{
+ FIXP_SGL invWidth;
+ SCHAR preShift;
+ SCHAR shift;
+ FIXP_DBL sum;
+ int k;
+
+ /* Divide by width of envelope later: */
+ invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
+ /* The common exponent needs to be doubled because all mantissas are squared:
+ */
+ frameExp = frameExp << 1;
+
+ for (k = lowSubband; k < highSubband; k++) {
+ FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))];
+ FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))];
+ FIXP_DBL maxVal;
+
+ if (analysBufferImag != NULL) {
+ int l;
+ maxVal = FL2FX_DBL(0.0f);
+ for (l = start_pos; l < next_pos; l++) {
+ bufferImag[l] = analysBufferImag[l][k];
+ maxVal |= (FIXP_DBL)((LONG)(bufferImag[l]) ^
+ ((LONG)bufferImag[l] >> (DFRACT_BITS - 1)));
+ bufferReal[l] = analysBufferReal[l][k];
+ maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
+ ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
+ }
+ } else {
+ int l;
+ maxVal = FL2FX_DBL(0.0f);
+ for (l = start_pos; l < next_pos; l++) {
+ bufferReal[l] = analysBufferReal[l][k];
+ maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
+ ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
+ }
+ }
+
+ if (maxVal != FL2FXCONST_DBL(0.f)) {
+ /* If the accu does not provide enough overflow bits, we cannot
+ shift the samples up to the limit.
+ Instead, keep up to 3 free bits in each sample, i.e. up to
+ 6 bits after calculation of square.
+ Please note the comment on saturated arithmetic above!
+ */
+ FIXP_DBL accu;
+ preShift = CntLeadingZeros(maxVal) - 1;
+ preShift -= SHIFT_BEFORE_SQUARE;
+
+ /* Limit preShift to a maximum value to prevent accumulator overflow in
+ exceptional situations where the signal in the analysis-buffer is very
+ small (small maxVal).
+ */
+ preShift = fMin(preShift, (SCHAR)25);
+
+ accu = FL2FXCONST_DBL(0.0f);
+ if (preShift >= 0) {
+ int l;
+ if (analysBufferImag != NULL) {
+ for (l = start_pos; l < next_pos; l++) {
+ FIXP_DBL temp1 = bufferReal[l] << (int)preShift;
+ FIXP_DBL temp2 = bufferImag[l] << (int)preShift;
+ accu = fPow2AddDiv2(accu, temp1);
+ accu = fPow2AddDiv2(accu, temp2);
+ }
+ } else {
+ for (l = start_pos; l < next_pos; l++) {
+ FIXP_DBL temp = bufferReal[l] << (int)preShift;
+ accu = fPow2AddDiv2(accu, temp);
+ }
+ }
+ } else { /* if negative shift value */
+ int l;
+ int negpreShift = -preShift;
+ if (analysBufferImag != NULL) {
+ for (l = start_pos; l < next_pos; l++) {
+ FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift;
+ FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift;
+ accu = fPow2AddDiv2(accu, temp1);
+ accu = fPow2AddDiv2(accu, temp2);
+ }
+ } else {
+ for (l = start_pos; l < next_pos; l++) {
+ FIXP_DBL temp = bufferReal[l] >> (int)negpreShift;
+ accu = fPow2AddDiv2(accu, temp);
+ }
+ }
+ }
+ accu <<= 1;
+
+ /* Convert double precision to Mantissa/Exponent: */
+ shift = fNorm(accu);
+ sum = accu << (int)shift;
+
+ /* Divide by width of envelope and apply frame scale: */
+ *nrgEst++ = fMult(sum, invWidth);
+ shift += 2 * preShift;
+ if (analysBufferImag != NULL)
+ *nrgEst_e++ = frameExp - shift;
+ else
+ *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */
+ } /* maxVal!=0 */
+ else {
+ /* Prevent a zero-mantissa-number from being misinterpreted
+ due to its exponent. */
+ *nrgEst++ = FL2FXCONST_DBL(0.0f);
+ *nrgEst_e++ = 0;
+ }
+ }
+}
+
+/*!
+ \brief Estimates the mean energy of each Scale factor band for the
+ duration of the current envelope.
+
+ This function is used when interpolFreq is false.
+*/
+static void calcNrgPerSfb(
+ FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
+ FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
+ int nSfb, /*!< Number of scale factor bands */
+ UCHAR *freqBandTable, /*!< First Subband for each Sfb */
+ int start_pos, /*!< First QMF-slot of current envelope */
+ int next_pos, /*!< Last QMF-slot of current envelope + 1 */
+ SCHAR input_e, /*!< Common exponent for all input samples */
+ FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */
+ SCHAR *nrgEst_e) /*!< Exponent of resulting Energy */
+{
+ FIXP_SGL invWidth;
+ FIXP_DBL temp;
+ SCHAR preShift;
+ SCHAR shift, sum_e;
+ FIXP_DBL sum;
+
+ int j, k, l, li, ui;
+ FIXP_DBL sumAll, sumLine; /* Single precision would be sufficient,
+ but overflow bits are required for accumulation */
+
+ /* Divide by width of envelope later: */
+ invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
+ /* The common exponent needs to be doubled because all mantissas are squared:
+ */
+ input_e = input_e << 1;
+
+ for (j = 0; j < nSfb; j++) {
+ li = freqBandTable[j];
+ ui = freqBandTable[j + 1];
+
+ FIXP_DBL maxVal = maxSubbandSample(analysBufferReal, analysBufferImag, li,
+ ui, start_pos, next_pos);
+
+ if (maxVal != FL2FXCONST_DBL(0.f)) {
+ preShift = CntLeadingZeros(maxVal) - 1;
+
+ /* If the accu does not provide enough overflow bits, we cannot
+ shift the samples up to the limit.
+ Instead, keep up to 3 free bits in each sample, i.e. up to
+ 6 bits after calculation of square.
+ Please note the comment on saturated arithmetic above!
+ */
+ preShift -= SHIFT_BEFORE_SQUARE;
+
+ sumAll = FL2FXCONST_DBL(0.0f);
+
+ for (k = li; k < ui; k++) {
+ sumLine = FL2FXCONST_DBL(0.0f);
+
+ if (analysBufferImag != NULL) {
+ if (preShift >= 0) {
+ for (l = start_pos; l < next_pos; l++) {
+ temp = analysBufferReal[l][k] << (int)preShift;
+ sumLine += fPow2Div2(temp);
+ temp = analysBufferImag[l][k] << (int)preShift;
+ sumLine += fPow2Div2(temp);
+ }
+ } else {
+ for (l = start_pos; l < next_pos; l++) {
+ temp = analysBufferReal[l][k] >> -(int)preShift;
+ sumLine += fPow2Div2(temp);
+ temp = analysBufferImag[l][k] >> -(int)preShift;
+ sumLine += fPow2Div2(temp);
+ }
+ }
+ } else {
+ if (preShift >= 0) {
+ for (l = start_pos; l < next_pos; l++) {
+ temp = analysBufferReal[l][k] << (int)preShift;
+ sumLine += fPow2Div2(temp);
+ }
+ } else {
+ for (l = start_pos; l < next_pos; l++) {
+ temp = analysBufferReal[l][k] >> -(int)preShift;
+ sumLine += fPow2Div2(temp);
+ }
+ }
+ }
+
+ /* The number of QMF-channels per SBR bands may be up to 15.
+ Shift right to avoid overflows in sum over all channels. */
+ sumLine = sumLine >> (4 - 1);
+ sumAll += sumLine;
+ }
+
+ /* Convert double precision to Mantissa/Exponent: */
+ shift = fNorm(sumAll);
+ sum = sumAll << (int)shift;
+
+ /* Divide by width of envelope: */
+ sum = fMult(sum, invWidth);
+
+ /* Divide by width of Sfb: */
+ sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui - li)));
+
+ /* Set all Subband energies in the Sfb to the average energy: */
+ if (analysBufferImag != NULL)
+ sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */
+ else
+ sum_e = input_e + 4 + 1 -
+ shift; /* -4 to compensate right-shift; +1 due to missing
+ imag. part */
+
+ sum_e -= 2 * preShift;
+ } /* maxVal!=0 */
+ else {
+ /* Prevent a zero-mantissa-number from being misinterpreted
+ due to its exponent. */
+ sum = FL2FXCONST_DBL(0.0f);
+ sum_e = 0;
+ }
+
+ for (k = li; k < ui; k++) {
+ *nrgEst++ = sum;
+ *nrgEst_e++ = sum_e;
+ }
+ }
+}
+
+/*!
+ \brief Calculate gain, noise, and additional sine level for one subband.
+
+ The resulting energy gain is given by mantissa and exponent.
+*/
+static void calcSubbandGain(
+ FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */
+ SCHAR
+ nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */
+ ENV_CALC_NRGS *nrgs, int i, FIXP_DBL tmpNoise, /*!< Relative noise level */
+ SCHAR tmpNoise_e, /*!< Relative noise level (exponent) */
+ UCHAR sinePresentFlag, /*!< Indicates if sine is present on band */
+ UCHAR sineMapped, /*!< Indicates if sine must be added */
+ int noNoiseFlag) /*!< Flag to suppress noise addition */
+{
+ FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */
+ SCHAR nrgEst_e =
+ nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */
+ FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */
+ SCHAR *ptrNrgGain_e =
+ &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */
+ FIXP_DBL *ptrNoiseLevel =
+ &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */
+ SCHAR *ptrNoiseLevel_e =
+ &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */
+ FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */
+ SCHAR *ptrNrgSine_e =
+ &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */
+
+ FIXP_DBL a, b, c;
+ SCHAR a_e, b_e, c_e;
+
+ /*
+ This addition of 1 prevents divisions by zero in the reference code.
+ For very small energies in nrgEst, it prevents the gains from becoming
+ very high which could cause some trouble due to the smoothing.
+ */
+ b_e = (int)(nrgEst_e - 1);
+ if (b_e >= 0) {
+ nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
+ (nrgEst >> 1);
+ nrgEst_e += 1; /* shift by 1 bit to avoid overflow */
+
+ } else {
+ nrgEst = (nrgEst >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
+ (FL2FXCONST_DBL(0.5f) >> 1);
+ nrgEst_e = 2; /* shift by 1 bit to avoid overflow */
+ }
+
+ /* A = NrgRef * TmpNoise */
+ a = fMult(nrgRef, tmpNoise);
+ a_e = nrgRef_e + tmpNoise_e;
+
+ /* B = 1 + TmpNoise */
+ b_e = (int)(tmpNoise_e - 1);
+ if (b_e >= 0) {
+ b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
+ (tmpNoise >> 1);
+ b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */
+ } else {
+ b = (tmpNoise >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
+ (FL2FXCONST_DBL(0.5f) >> 1);
+ b_e = 2; /* shift by 1 bit to avoid overflow */
+ }
+
+ /* noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */
+ FDK_divide_MantExp(a, a_e, b, b_e, ptrNoiseLevel, ptrNoiseLevel_e);
+
+ if (sinePresentFlag) {
+ /* C = (1 + TmpNoise) * NrgEst */
+ c = fMult(b, nrgEst);
+ c_e = b_e + nrgEst_e;
+
+ /* gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */
+ FDK_divide_MantExp(a, a_e, c, c_e, ptrNrgGain, ptrNrgGain_e);
+
+ if (sineMapped) {
+ /* sineLevel = nrgRef/ (1 + TmpNoise) */
+ FDK_divide_MantExp(nrgRef, nrgRef_e, b, b_e, ptrNrgSine, ptrNrgSine_e);
+ }
+ } else {
+ if (noNoiseFlag) {
+ /* B = NrgEst */
+ b = nrgEst;
+ b_e = nrgEst_e;
+ } else {
+ /* B = NrgEst * (1 + TmpNoise) */
+ b = fMult(b, nrgEst);
+ b_e = b_e + nrgEst_e;
+ }
+
+ /* gain = nrgRef / B */
+ FDK_divide_MantExp(nrgRef, nrgRef_e, b, b_e, ptrNrgGain, ptrNrgGain_e);
+ }
+}
+
+/*!
+ \brief Calculate "average gain" for the specified subband range.
+
+ This is rather a gain of the average magnitude than the average
+ of gains!
+ The result is used as a relative limit for all gains within the
+ current "limiter band" (a certain frequency range).
+*/
+static void calcAvgGain(
+ ENV_CALC_NRGS *nrgs, int lowSubband, /*!< Begin of the limiter band */
+ int highSubband, /*!< High end of the limiter band */
+ FIXP_DBL *ptrSumRef, SCHAR *ptrSumRef_e,
+ FIXP_DBL *ptrAvgGain, /*!< Resulting overall gain (mantissa) */
+ SCHAR *ptrAvgGain_e) /*!< Resulting overall gain (exponent) */
+{
+ FIXP_DBL *nrgRef =
+ nrgs->nrgRef; /*!< Reference Energy according to envelope data */
+ SCHAR *nrgRef_e =
+ nrgs->nrgRef_e; /*!< Reference Energy according to envelope data
+ (exponent) */
+ FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */
+ SCHAR *nrgEst_e =
+ nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */
+
+ FIXP_DBL sumRef = 1;
+ FIXP_DBL sumEst = 1;
+ SCHAR sumRef_e = -FRACT_BITS;
+ SCHAR sumEst_e = -FRACT_BITS;
+ int k;
+
+ for (k = lowSubband; k < highSubband; k++) {
+ /* Add nrgRef[k] to sumRef: */
+ FDK_add_MantExp(sumRef, sumRef_e, nrgRef[k], nrgRef_e[k], &sumRef,
+ &sumRef_e);
+
+ /* Add nrgEst[k] to sumEst: */
+ FDK_add_MantExp(sumEst, sumEst_e, nrgEst[k], nrgEst_e[k], &sumEst,
+ &sumEst_e);
+ }
+
+ FDK_divide_MantExp(sumRef, sumRef_e, sumEst, sumEst_e, ptrAvgGain,
+ ptrAvgGain_e);
+
+ *ptrSumRef = sumRef;
+ *ptrSumRef_e = sumRef_e;
+}
+
+static void adjustTimeSlot_EldGrid(
+ FIXP_DBL *RESTRICT
+ 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 *RESTRICT pNoiseLevel =
+ nrgs->noiseLevel; /*!< Noise levels of current envelope */
+ FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
+
+ int phaseIndex = *ptrPhaseIndex;
+ UCHAR harmIndex = *ptrHarmIndex;
+
+ static const INT harmonicPhase[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
+
+ static const FIXP_DBL harmonicPhaseX[4][2] = {
+ {FL2FXCONST_DBL(2.0 * 1.245183154539139e-001),
+ FL2FXCONST_DBL(2.0 * 1.245183154539139e-001)},
+ {FL2FXCONST_DBL(2.0 * -1.123767859325028e-001),
+ FL2FXCONST_DBL(2.0 * 1.123767859325028e-001)},
+ {FL2FXCONST_DBL(2.0 * -1.245183154539139e-001),
+ FL2FXCONST_DBL(2.0 * -1.245183154539139e-001)},
+ {FL2FXCONST_DBL(2.0 * 1.123767859325028e-001),
+ FL2FXCONST_DBL(2.0 * -1.123767859325028e-001)}};
+
+ const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0];
+ const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0];
+
+ *(ptrReal - 1) = fAddSaturate(
+ *(ptrReal - 1),
+ SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]),
+ scale_diff_low, DFRACT_BITS));
+ FIXP_DBL pSineLevel_prev = (FIXP_DBL)0;
+
+ int idx_k = lowSubband & 1;
+
+ for (k = 0; k < noSubbands; k++) {
+ FIXP_DBL sineLevel_curr = *pSineLevel++;
+ phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
+
+ signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
+ sbNoise = *pNoiseLevel++;
+ if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
+ signalReal +=
+ (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise)
+ << 4);
+ }
+ signalReal += sineLevel_curr * p_harmonicPhase[0];
+ signalReal =
+ fMultAddDiv2(signalReal, pSineLevel_prev, p_harmonicPhaseX[idx_k]);
+ pSineLevel_prev = sineLevel_curr;
+ idx_k = !idx_k;
+ if (k < noSubbands - 1) {
+ signalReal =
+ fMultAddDiv2(signalReal, pSineLevel[0], p_harmonicPhaseX[idx_k]);
+ } else /* (k == noSubbands - 1) */
+ {
+ if (k + lowSubband + 1 < 63) {
+ *(ptrReal + 1) += fMultDiv2(pSineLevel_prev, p_harmonicPhaseX[idx_k]);
+ }
+ }
+ *ptrReal++ = signalReal;
+
+ if (pSineLevel_prev != FL2FXCONST_DBL(0.0f)) {
+ if (++tone_count == 16) {
+ k++;
+ break;
+ }
+ }
+ }
+ /* Run again, if previous loop got breaked with tone_count = 16 */
+ for (; k < noSubbands; k++) {
+ FIXP_DBL sineLevel_curr = *pSineLevel++;
+ phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
+
+ signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
+ sbNoise = *pNoiseLevel++;
+ if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
+ signalReal +=
+ (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise)
+ << 4);
+ }
+ signalReal += sineLevel_curr * p_harmonicPhase[0];
+ *ptrReal++ = signalReal;
+ }
+
+ *ptrHarmIndex = (harmIndex + 1) & 3;
+ *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1);
+}
+
+/*!
+ \brief Amplify one timeslot of the signal with the calculated gains
+ and add the noisefloor.
+*/
+
+static void adjustTimeSlotLC(
+ 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 */
+{
+ 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 k;
+ int index = *ptrPhaseIndex;
+ UCHAR harmIndex = *ptrHarmIndex;
+ UCHAR freqInvFlag = (lowSubband & 1);
+ FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
+ int tone_count = 0;
+ int sineSign = 1;
+
+#define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f))
+#define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.16773f))
+
+ /*
+ First pass for k=0 pulled out of the loop:
+ */
+
+ index = (index + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
+
+ /*
+ The next multiplication constitutes the actual envelope adjustment
+ of the signal and should be carried out with full accuracy
+ (supplying #FRACT_BITS valid bits).
+ */
+ signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
+ sineLevel = *pSineLevel++;
+ sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
+
+ if (sineLevel != FL2FXCONST_DBL(0.0f))
+ tone_count++;
+ else if (!noNoiseFlag)
+ /* Add noisefloor to the amplified signal */
+ signalReal +=
+ (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])
+ << 4);
+
+ {
+ 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 = (shift >= 0) ? (fMultDiv2(C1, sineLevel) >> shift)
+ : (fMultDiv2(C1, sineLevel) << (-shift));
+ FIXP_DBL tmp2 = fMultDiv2(C1, 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;
+ }
+ }
+
+ pNoiseLevel++;
+
+ if (noSubbands > 2) {
+ if (!(harmIndex & 0x1)) {
+ /* harmIndex 0,2 */
+ if (!harmIndex) {
+ sineSign = 0;
+ }
+
+ for (k = noSubbands - 2; k != 0; k--) {
+ FIXP_DBL sinelevel = *pSineLevel++;
+ index++;
+ if (((signalReal = (sineSign ? -sinelevel : sinelevel)) ==
+ FL2FXCONST_DBL(0.0f)) &&
+ !noNoiseFlag) {
+ /* Add noisefloor to the amplified signal */
+ index &= (SBR_NF_NO_RANDOM_VAL - 1);
+ signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0],
+ pNoiseLevel[0])
+ << 4);
+ }
+
+ /* The next multiplication constitutes the actual envelope adjustment of
+ * the signal. */
+ signalReal += fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
+
+ pNoiseLevel++;
+ *ptrReal++ = signalReal;
+ } /* for ... */
+ } else {
+ /* harmIndex 1,3 in combination with freqInvFlag */
+ if (harmIndex == 1) freqInvFlag = !freqInvFlag;
+
+ for (k = noSubbands - 2; k != 0; k--) {
+ index++;
+ /* The next multiplication constitutes the actual envelope adjustment of
+ * the signal. */
+ signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
+
+ if (*pSineLevel++ != FL2FXCONST_DBL(0.0f))
+ tone_count++;
+ else if (!noNoiseFlag) {
+ /* Add noisefloor to the amplified signal */
+ index &= (SBR_NF_NO_RANDOM_VAL - 1);
+ signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0],
+ pNoiseLevel[0])
+ << 4);
+ }
+
+ pNoiseLevel++;
+
+ if (tone_count <= 16) {
+ FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1);
+ signalReal += (freqInvFlag) ? (-addSine) : (addSine);
+ }
+
+ *ptrReal++ = signalReal;
+ freqInvFlag = !freqInvFlag;
+ } /* for ... */
+ }
+ }
+
+ if (noSubbands > -1) {
+ index++;
+ /* The next multiplication constitutes the actual envelope adjustment of the
+ * signal. */
+ signalReal = fMultDiv2(*ptrReal, *pGain) << ((int)scale_change);
+ sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f));
+ sineLevel = pSineLevel[0];
+
+ if (pSineLevel[0] != FL2FXCONST_DBL(0.0f))
+ tone_count++;
+ else if (!noNoiseFlag) {
+ /* Add noisefloor to the amplified signal */
+ index &= (SBR_NF_NO_RANDOM_VAL - 1);
+ signalReal =
+ signalReal +
+ (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])
+ << 4);
+ }
+
+ if (!(harmIndex & 0x1)) {
+ /* harmIndex 0,2 */
+ *ptrReal = signalReal + ((sineSign) ? -sineLevel : sineLevel);
+ } else {
+ /* harmIndex 1,3 in combination with freqInvFlag */
+ if (tone_count <= 16) {
+ if (freqInvFlag) {
+ *ptrReal++ = signalReal - sineLevelPrev;
+ if (noSubbands + lowSubband < 63)
+ *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel);
+ } else {
+ *ptrReal++ = signalReal + sineLevelPrev;
+ if (noSubbands + lowSubband < 63)
+ *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel);
+ }
+ } else
+ *ptrReal = signalReal;
+ }
+ }
+ *ptrHarmIndex = (harmIndex + 1) & 3;
+ *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
+}
+
+static void adjustTimeSlotHQ_GainAndNoise(
+ 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, ENV_CALC_NRGS *nrgs,
+ 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 */
+ FIXP_SGL smooth_ratio, /*!< Impact of last envelope */
+ int noNoiseFlag, /*!< Start index to random number array */
+ int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */
+{
+ FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
+ FIXP_DBL *RESTRICT noiseLevel =
+ nrgs->noiseLevel; /*!< Noise levels of current envelope */
+ FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
+
+ FIXP_DBL *RESTRICT filtBuffer =
+ h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
+ FIXP_DBL *RESTRICT filtBufferNoise =
+ h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
+ int *RESTRICT ptrPhaseIndex =
+ &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
+
+ int k;
+ FIXP_DBL signalReal, signalImag;
+ FIXP_DBL noiseReal, noiseImag;
+ FIXP_DBL smoothedGain, smoothedNoise;
+ FIXP_SGL direct_ratio =
+ /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
+ int index = *ptrPhaseIndex;
+ int shift;
+
+ *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
+
+ filtBufferNoiseShift +=
+ 1; /* due to later use of fMultDiv2 instead of fMult */
+ if (filtBufferNoiseShift < 0) {
+ shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
+ } else {
+ shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
+ }
+
+ if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
+ for (k = 0; k < noSubbands; k++) {
+ /*
+ Smoothing: The old envelope has been bufferd and a certain ratio
+ of the old gains and noise levels is used.
+ */
+ smoothedGain =
+ fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
+
+ if (filtBufferNoiseShift < 0) {
+ smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
+ fMult(direct_ratio, noiseLevel[k]);
+ } else {
+ smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
+ fMult(direct_ratio, noiseLevel[k]);
+ }
+
+ /*
+ The next 2 multiplications constitute the actual envelope adjustment
+ of the signal and should be carried out with full accuracy
+ (supplying #DFRACT_BITS valid bits).
+ */
+ signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
+ signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
+
+ index++;
+
+ if ((pSineLevel[k] != FL2FXCONST_DBL(0.0f)) || noNoiseFlag) {
+ /* Just the amplified signal is saved */
+ *ptrReal++ = signalReal;
+ *ptrImag++ = signalImag;
+ } else {
+ /* Add noisefloor to the amplified signal */
+ index &= (SBR_NF_NO_RANDOM_VAL - 1);
+ noiseReal =
+ fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise)
+ << 4;
+ noiseImag =
+ fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise)
+ << 4;
+ *ptrReal++ = (signalReal + noiseReal);
+ *ptrImag++ = (signalImag + noiseImag);
+ }
+ }
+ } else {
+ for (k = 0; k < noSubbands; k++) {
+ smoothedGain = gain[k];
+ signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
+ signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
+
+ index++;
+
+ if ((pSineLevel[k] == FL2FXCONST_DBL(0.0f)) && (noNoiseFlag == 0)) {
+ /* Add noisefloor to the amplified signal */
+ smoothedNoise = noiseLevel[k];
+ index &= (SBR_NF_NO_RANDOM_VAL - 1);
+ noiseReal =
+ fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
+ noiseImag =
+ fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
+
+ /* FDK_sbrDecoder_sbr_randomPhase is downscaled by 2^3 */
+ signalReal += noiseReal << 4;
+ signalImag += noiseImag << 4;
+ }
+ *ptrReal++ = signalReal;
+ *ptrImag++ = signalImag;
+ }
+ }
+}
+
+static void adjustTimeSlotHQ_AddHarmonics(
+ 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, ENV_CALC_NRGS *nrgs,
+ int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
+ int noSubbands, /*!< Number of QMF subbands */
+ int scale_change /*!< Scale mismatch between QMF input and sineLevel
+ exponent. */
+) {
+ FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
+ UCHAR *RESTRICT ptrHarmIndex =
+ &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
+
+ int k;
+ FIXP_DBL signalReal, signalImag;
+ UCHAR harmIndex = *ptrHarmIndex;
+ int freqInvFlag = (lowSubband & 1);
+ FIXP_DBL sineLevel;
+
+ *ptrHarmIndex = (harmIndex + 1) & 3;
+
+ for (k = 0; k < noSubbands; k++) {
+ sineLevel = pSineLevel[k];
+ freqInvFlag ^= 1;
+ if (sineLevel != FL2FXCONST_DBL(0.f)) {
+ signalReal = ptrReal[k];
+ signalImag = ptrImag[k];
+ sineLevel = scaleValue(sineLevel, scale_change);
+ if (harmIndex & 2) {
+ /* case 2,3 */
+ sineLevel = -sineLevel;
+ }
+ if (!(harmIndex & 1)) {
+ /* case 0,2: */
+ ptrReal[k] = signalReal + sineLevel;
+ } else {
+ /* case 1,3 */
+ if (!freqInvFlag) sineLevel = -sineLevel;
+ ptrImag[k] = signalImag + sineLevel;
+ }
+ }
+ }
+}
+
+static void adjustTimeSlotHQ(
+ 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, ENV_CALC_NRGS *nrgs,
+ 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 */
+ FIXP_SGL smooth_ratio, /*!< Impact of last envelope */
+ int noNoiseFlag, /*!< Start index to random number array */
+ int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */
+{
+ FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
+ FIXP_DBL *RESTRICT noiseLevel =
+ nrgs->noiseLevel; /*!< Noise levels of current envelope */
+ FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
+
+ FIXP_DBL *RESTRICT filtBuffer =
+ h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
+ FIXP_DBL *RESTRICT filtBufferNoise =
+ h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
+ UCHAR *RESTRICT ptrHarmIndex =
+ &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
+ int *RESTRICT ptrPhaseIndex =
+ &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
+
+ int k;
+ FIXP_DBL signalReal, signalImag;
+ FIXP_DBL noiseReal, noiseImag;
+ FIXP_DBL smoothedGain, smoothedNoise;
+ FIXP_SGL direct_ratio =
+ /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
+ int index = *ptrPhaseIndex;
+ UCHAR harmIndex = *ptrHarmIndex;
+ int freqInvFlag = (lowSubband & 1);
+ FIXP_DBL sineLevel;
+ int shift;
+
+ *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
+ *ptrHarmIndex = (harmIndex + 1) & 3;
+
+ /*
+ Possible optimization:
+ smooth_ratio and harmIndex stay constant during the loop.
+ It might be faster to include a separate loop in each path.
+
+ the check for smooth_ratio is now outside the loop and the workload
+ of the whole function decreased by about 20 %
+ */
+
+ filtBufferNoiseShift +=
+ 1; /* due to later use of fMultDiv2 instead of fMult */
+ if (filtBufferNoiseShift < 0)
+ shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
+ else
+ shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
+
+ if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
+ for (k = 0; k < noSubbands; k++) {
+ /*
+ Smoothing: The old envelope has been bufferd and a certain ratio
+ of the old gains and noise levels is used.
+ */
+
+ smoothedGain =
+ fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
+
+ if (filtBufferNoiseShift < 0) {
+ smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
+ fMult(direct_ratio, noiseLevel[k]);
+ } else {
+ smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
+ fMult(direct_ratio, noiseLevel[k]);
+ }
+
+ /*
+ The next 2 multiplications constitute the actual envelope adjustment
+ of the signal and should be carried out with full accuracy
+ (supplying #DFRACT_BITS valid bits).
+ */
+ signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
+ signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
+
+ index++;
+
+ if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) {
+ sineLevel = pSineLevel[k];
+
+ switch (harmIndex) {
+ case 0:
+ *ptrReal++ = (signalReal + sineLevel);
+ *ptrImag++ = (signalImag);
+ break;
+ case 2:
+ *ptrReal++ = (signalReal - sineLevel);
+ *ptrImag++ = (signalImag);
+ break;
+ case 1:
+ *ptrReal++ = (signalReal);
+ if (freqInvFlag)
+ *ptrImag++ = (signalImag - sineLevel);
+ else
+ *ptrImag++ = (signalImag + sineLevel);
+ break;
+ case 3:
+ *ptrReal++ = signalReal;
+ if (freqInvFlag)
+ *ptrImag++ = (signalImag + sineLevel);
+ else
+ *ptrImag++ = (signalImag - sineLevel);
+ break;
+ }
+ } else {
+ if (noNoiseFlag) {
+ /* Just the amplified signal is saved */
+ *ptrReal++ = (signalReal);
+ *ptrImag++ = (signalImag);
+ } else {
+ /* Add noisefloor to the amplified signal */
+ index &= (SBR_NF_NO_RANDOM_VAL - 1);
+ /* FDK_sbrDecoder_sbr_randomPhase is downscaled by 2^3 */
+ noiseReal =
+ fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise)
+ << 4;
+ noiseImag =
+ fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise)
+ << 4;
+ *ptrReal++ = (signalReal + noiseReal);
+ *ptrImag++ = (signalImag + noiseImag);
+ }
+ }
+ freqInvFlag ^= 1;
+ }
+
+ } else {
+ for (k = 0; k < noSubbands; k++) {
+ smoothedGain = gain[k];
+ signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
+ signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
+
+ index++;
+
+ if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f)) {
+ switch (harmIndex) {
+ case 0:
+ signalReal += sineLevel;
+ break;
+ case 1:
+ if (freqInvFlag)
+ signalImag -= sineLevel;
+ else
+ signalImag += sineLevel;
+ break;
+ case 2:
+ signalReal -= sineLevel;
+ break;
+ case 3:
+ if (freqInvFlag)
+ signalImag += sineLevel;
+ else
+ signalImag -= sineLevel;
+ break;
+ }
+ } else {
+ if (noNoiseFlag == 0) {
+ /* Add noisefloor to the amplified signal */
+ smoothedNoise = noiseLevel[k];
+ index &= (SBR_NF_NO_RANDOM_VAL - 1);
+ noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0],
+ smoothedNoise);
+ noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1],
+ smoothedNoise);
+
+ /* FDK_sbrDecoder_sbr_randomPhase is downscaled by 2^3 */
+ signalReal += noiseReal << 4;
+ signalImag += noiseImag << 4;
+ }
+ }
+ *ptrReal++ = signalReal;
+ *ptrImag++ = signalImag;
+
+ freqInvFlag ^= 1;
+ }
+ }
+}
+
+/*!
+ \brief Reset limiter bands.
+
+ Build frequency band table for the gain limiter dependent on
+ the previously generated transposer patch areas.
+
+ \return SBRDEC_OK if ok, SBRDEC_UNSUPPORTED_CONFIG on error
+*/
+SBR_ERROR
+ResetLimiterBands(
+ UCHAR *limiterBandTable, /*!< Resulting band borders in QMF channels */
+ UCHAR *noLimiterBands, /*!< Resulting number of limiter band */
+ UCHAR *freqBandTable, /*!< Table with possible band borders */
+ int noFreqBands, /*!< Number of bands in freqBandTable */
+ const PATCH_PARAM *patchParam, /*!< Transposer patch parameters */
+ int noPatches, /*!< Number of transposer patches */
+ int limiterBands, /*!< Selected 'band density' from bitstream */
+ UCHAR sbrPatchingMode, int xOverQmf[MAX_NUM_PATCHES], int b41Sbr) {
+ int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands;
+ UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
+ int patchBorders[MAX_NUM_PATCHES + 1];
+ int kx, k2;
+
+ int lowSubband = freqBandTable[0];
+ int highSubband = freqBandTable[noFreqBands];
+
+ /* 1 limiter band. */
+ if (limiterBands == 0) {
+ limiterBandTable[0] = 0;
+ limiterBandTable[1] = highSubband - lowSubband;
+ nBands = 1;
+ } else {
+ if (!sbrPatchingMode && xOverQmf != NULL) {
+ noPatches = 0;
+
+ if (b41Sbr == 1) {
+ for (i = 1; i < MAX_NUM_PATCHES_HBE; i++)
+ if (xOverQmf[i] != 0) noPatches++;
+ } else {
+ for (i = 1; i < MAX_STRETCH_HBE; i++)
+ if (xOverQmf[i] != 0) noPatches++;
+ }
+ for (i = 0; i < noPatches; i++) {
+ patchBorders[i] = xOverQmf[i] - lowSubband;
+ }
+ } else {
+ for (i = 0; i < noPatches; i++) {
+ patchBorders[i] = patchParam[i].guardStartBand - lowSubband;
+ }
+ }
+ patchBorders[i] = highSubband - lowSubband;
+
+ /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */
+ for (k = 0; k <= noFreqBands; k++) {
+ workLimiterBandTable[k] = freqBandTable[k] - lowSubband;
+ }
+ for (k = 1; k < noPatches; k++) {
+ workLimiterBandTable[noFreqBands + k] = patchBorders[k];
+ }
+
+ tempNoLim = nBands = noFreqBands + noPatches - 1;
+ shellsort(workLimiterBandTable, tempNoLim + 1);
+
+ loLimIndex = 0;
+ hiLimIndex = 1;
+
+ while (hiLimIndex <= tempNoLim) {
+ FIXP_DBL div_m, oct_m, temp;
+ INT div_e = 0, oct_e = 0, temp_e = 0;
+
+ k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
+ kx = workLimiterBandTable[loLimIndex] + lowSubband;
+
+ div_m = fDivNorm(k2, kx, &div_e);
+
+ /* 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 (workLimiterBandTable[hiLimIndex] ==
+ workLimiterBandTable[loLimIndex]) {
+ workLimiterBandTable[hiLimIndex] = highSubband;
+ nBands--;
+ hiLimIndex++;
+ continue;
+ }
+ isPatchBorder[0] = isPatchBorder[1] = 0;
+ for (k = 0; k <= noPatches; k++) {
+ if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) {
+ isPatchBorder[1] = 1;
+ break;
+ }
+ }
+ if (!isPatchBorder[1]) {
+ workLimiterBandTable[hiLimIndex] = highSubband;
+ nBands--;
+ hiLimIndex++;
+ continue;
+ }
+ for (k = 0; k <= noPatches; k++) {
+ if (workLimiterBandTable[loLimIndex] == patchBorders[k]) {
+ isPatchBorder[0] = 1;
+ break;
+ }
+ }
+ if (!isPatchBorder[0]) {
+ workLimiterBandTable[loLimIndex] = highSubband;
+ nBands--;
+ }
+ }
+ loLimIndex = hiLimIndex;
+ hiLimIndex++;
+ }
+ shellsort(workLimiterBandTable, tempNoLim + 1);
+
+ /* Test if algorithm exceeded maximum allowed limiterbands */
+ if (nBands > MAX_NUM_LIMITERS || nBands <= 0) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ /* Copy limiterbands from working buffer into final destination */
+ for (k = 0; k <= nBands; k++) {
+ limiterBandTable[k] = workLimiterBandTable[k];
+ }
+ }
+ *noLimiterBands = nBands;
+
+ return SBRDEC_OK;
+}
diff --git a/fdk-aac/libSBRdec/src/env_calc.h b/fdk-aac/libSBRdec/src/env_calc.h
new file mode 100644
index 0000000..cff365d
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/env_calc.h
@@ -0,0 +1,182 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Envelope calculation prototypes
+*/
+#ifndef ENV_CALC_H
+#define ENV_CALC_H
+
+#include "sbrdecoder.h"
+#include "env_extr.h" /* for HANDLE_SBR_HEADER_DATA */
+
+typedef struct {
+ FIXP_DBL filtBuffer[MAX_FREQ_COEFFS]; /*!< previous gains (required for
+ smoothing) */
+ FIXP_DBL filtBufferNoise[MAX_FREQ_COEFFS]; /*!< previous noise levels
+ (required for smoothing) */
+ SCHAR filtBuffer_e[MAX_FREQ_COEFFS]; /*!< Exponents of previous gains */
+ SCHAR filtBufferNoise_e; /*!< Common exponent of previous noise levels */
+
+ int startUp; /*!< flag to signal initial conditions in buffers */
+ int phaseIndex; /*!< Index for randomPase array */
+ int prevTranEnv; /*!< The transient envelope of the previous frame. */
+
+ ULONG harmFlagsPrev[ADD_HARMONICS_FLAGS_SIZE];
+ /*!< Words with 16 flags each indicating where a sine was added in the
+ * previous frame.*/
+ UCHAR harmIndex; /*!< Current phase of synthetic sine */
+ int sbrPatchingMode; /*!< Current patching mode */
+
+ FIXP_SGL prevSbrNoiseFloorLevel[MAX_NOISE_COEFFS];
+ UCHAR prevNNfb;
+ UCHAR prevNSfb[2];
+ UCHAR prevLoSubband;
+ UCHAR prevHiSubband;
+ UCHAR prev_ov_highSubband;
+ UCHAR *prevFreqBandTable[2];
+ UCHAR prevFreqBandTableLo[MAX_FREQ_COEFFS / 2 + 1];
+ UCHAR prevFreqBandTableHi[MAX_FREQ_COEFFS + 1];
+ UCHAR prevFreqBandTableNoise[MAX_NOISE_COEFFS + 1];
+ SCHAR sinusoidal_positionPrev;
+ ULONG harmFlagsPrevActive[ADD_HARMONICS_FLAGS_SIZE];
+} SBR_CALCULATE_ENVELOPE;
+
+typedef SBR_CALCULATE_ENVELOPE *HANDLE_SBR_CALCULATE_ENVELOPE;
+
+void calculateSbrEnvelope(
+ QMF_SCALE_FACTOR *sbrScaleFactor,
+ HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
+ HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_SBR_FRAME_DATA hFrameData,
+ PVC_DYNAMIC_DATA *pPvcDynamicData, FIXP_DBL **analysBufferReal,
+ FIXP_DBL *
+ *analysBufferImag, /*!< Imag part of subband samples to be processed */
+ const int useLP,
+ FIXP_DBL *degreeAlias, /*!< Estimated aliasing for each QMF channel */
+ const UINT flags, const int frameErrorFlag);
+
+SBR_ERROR
+createSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hSbrCalculateEnvelope,
+ HANDLE_SBR_HEADER_DATA hHeaderData, const int chan,
+ const UINT flags);
+
+int deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hSbrCalculateEnvelope);
+
+void resetSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv);
+
+SBR_ERROR
+ResetLimiterBands(UCHAR *limiterBandTable, UCHAR *noLimiterBands,
+ UCHAR *freqBandTable, int noFreqBands,
+ const PATCH_PARAM *patchParam, int noPatches,
+ int limiterBands, UCHAR sbrPatchingMode,
+ int xOverQmf[MAX_NUM_PATCHES], int sbrRatio);
+
+void rescaleSubbandSamples(FIXP_DBL **re, FIXP_DBL **im, int lowSubband,
+ int noSubbands, int start_pos, int next_pos,
+ int shift);
+
+FIXP_DBL maxSubbandSample(FIXP_DBL **analysBufferReal_m,
+ FIXP_DBL **analysBufferImag_m, int lowSubband,
+ int highSubband, int start_pos, int stop_pos);
+
+#endif // ENV_CALC_H
diff --git a/fdk-aac/libSBRdec/src/env_dec.cpp b/fdk-aac/libSBRdec/src/env_dec.cpp
new file mode 100644
index 0000000..95807c9
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/env_dec.cpp
@@ -0,0 +1,873 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief envelope decoding
+ This module provides envelope decoding and error concealment algorithms. The
+ main entry point is decodeSbrData().
+
+ \sa decodeSbrData(),\ref documentationOverview
+*/
+
+#include "env_dec.h"
+
+#include "env_extr.h"
+#include "transcendent.h"
+
+#include "genericStds.h"
+
+static void decodeEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA h_sbr_data,
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data,
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data_otherChannel);
+static void sbr_envelope_unmapping(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA h_data_left,
+ HANDLE_SBR_FRAME_DATA h_data_right);
+static void requantizeEnvelopeData(HANDLE_SBR_FRAME_DATA h_sbr_data,
+ int ampResolution);
+static void deltaToLinearPcmEnvelopeDecoding(
+ HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_SBR_FRAME_DATA h_sbr_data,
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
+static void decodeNoiseFloorlevels(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA h_sbr_data,
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
+static void timeCompensateFirstEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA h_sbr_data,
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
+static int checkEnvelopeData(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA h_sbr_data,
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
+
+#define SBR_ENERGY_PAN_OFFSET (12 << ENV_EXP_FRACT)
+#define SBR_MAX_ENERGY (35 << ENV_EXP_FRACT)
+
+#define DECAY (1 << ENV_EXP_FRACT)
+
+#if ENV_EXP_FRACT
+#define DECAY_COUPLING \
+ (1 << (ENV_EXP_FRACT - 1)) /*!< corresponds to a value of 0.5 */
+#else
+#define DECAY_COUPLING \
+ 1 /*!< If the energy data is not shifted, use 1 instead of 0.5 */
+#endif
+
+/*!
+ \brief Convert table index
+*/
+static int indexLow2High(int offset, /*!< mapping factor */
+ int index, /*!< index to scalefactor band */
+ int res) /*!< frequency resolution */
+{
+ if (res == 0) {
+ if (offset >= 0) {
+ if (index < offset)
+ return (index);
+ else
+ return (2 * index - offset);
+ } else {
+ offset = -offset;
+ if (index < offset)
+ return (2 * index + index);
+ else
+ return (2 * index + offset);
+ }
+ } else
+ return (index);
+}
+
+/*!
+ \brief Update previous envelope value for delta-coding
+
+ The current envelope values needs to be stored for delta-coding
+ in the next frame. The stored envelope is always represented with
+ the high frequency resolution. If the current envelope uses the
+ low frequency resolution, the energy value will be mapped to the
+ corresponding high-res bands.
+*/
+static void mapLowResEnergyVal(
+ FIXP_SGL currVal, /*!< current energy value */
+ FIXP_SGL *prevData, /*!< pointer to previous data vector */
+ int offset, /*!< mapping factor */
+ int index, /*!< index to scalefactor band */
+ int res) /*!< frequeny resolution */
+{
+ if (res == 0) {
+ if (offset >= 0) {
+ if (index < offset)
+ prevData[index] = currVal;
+ else {
+ prevData[2 * index - offset] = currVal;
+ prevData[2 * index + 1 - offset] = currVal;
+ }
+ } else {
+ offset = -offset;
+ if (index < offset) {
+ prevData[3 * index] = currVal;
+ prevData[3 * index + 1] = currVal;
+ prevData[3 * index + 2] = currVal;
+ } else {
+ prevData[2 * index + offset] = currVal;
+ prevData[2 * index + 1 + offset] = currVal;
+ }
+ }
+ } else
+ prevData[index] = currVal;
+}
+
+/*!
+ \brief Convert raw envelope and noisefloor data to energy levels
+
+ This function is being called by sbrDecoder_ParseElement() and provides two
+ important algorithms:
+
+ First the function decodes envelopes and noise floor levels as described in
+ requantizeEnvelopeData() and sbr_envelope_unmapping(). The function also
+ implements concealment algorithms in case there are errors within the sbr
+ data. For both operations fractional arithmetic is used. Therefore you might
+ encounter different output values on your target system compared to the
+ reference implementation.
+*/
+void decodeSbrData(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA
+ h_data_left, /*!< pointer to left channel frame data */
+ HANDLE_SBR_PREV_FRAME_DATA
+ h_prev_data_left, /*!< pointer to left channel previous frame data */
+ HANDLE_SBR_FRAME_DATA
+ h_data_right, /*!< pointer to right channel frame data */
+ HANDLE_SBR_PREV_FRAME_DATA
+ h_prev_data_right) /*!< pointer to right channel previous frame data */
+{
+ FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS];
+ int errLeft;
+
+ /* Save previous energy values to be able to reuse them later for concealment.
+ */
+ FDKmemcpy(tempSfbNrgPrev, h_prev_data_left->sfb_nrg_prev,
+ MAX_FREQ_COEFFS * sizeof(FIXP_SGL));
+
+ if (hHeaderData->frameErrorFlag || hHeaderData->bs_info.pvc_mode == 0) {
+ decodeEnvelope(hHeaderData, h_data_left, h_prev_data_left,
+ h_prev_data_right);
+ } else {
+ FDK_ASSERT(h_data_right == NULL);
+ }
+ decodeNoiseFloorlevels(hHeaderData, h_data_left, h_prev_data_left);
+
+ if (h_data_right != NULL) {
+ errLeft = hHeaderData->frameErrorFlag;
+ decodeEnvelope(hHeaderData, h_data_right, h_prev_data_right,
+ h_prev_data_left);
+ decodeNoiseFloorlevels(hHeaderData, h_data_right, h_prev_data_right);
+
+ if (!errLeft && hHeaderData->frameErrorFlag) {
+ /* If an error occurs in the right channel where the left channel seemed
+ ok, we apply concealment also on the left channel. This ensures that
+ the coupling modes of both channels match and that we have the same
+ number of envelopes in coupling mode. However, as the left channel has
+ already been processed before, the resulting energy levels are not the
+ same as if the left channel had been concealed during the first call of
+ decodeEnvelope().
+ */
+ /* Restore previous energy values for concealment, because the values have
+ been overwritten by the first call of decodeEnvelope(). */
+ FDKmemcpy(h_prev_data_left->sfb_nrg_prev, tempSfbNrgPrev,
+ MAX_FREQ_COEFFS * sizeof(FIXP_SGL));
+ /* Do concealment */
+ decodeEnvelope(hHeaderData, h_data_left, h_prev_data_left,
+ h_prev_data_right);
+ }
+
+ if (h_data_left->coupling) {
+ sbr_envelope_unmapping(hHeaderData, h_data_left, h_data_right);
+ }
+ }
+
+ /* Display the data for debugging: */
+}
+
+/*!
+ \brief Convert from coupled channels to independent L/R data
+*/
+static void sbr_envelope_unmapping(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_data_left, /*!< pointer to left channel */
+ HANDLE_SBR_FRAME_DATA h_data_right) /*!< pointer to right channel */
+{
+ int i;
+ FIXP_SGL tempL_m, tempR_m, tempRplus1_m, newL_m, newR_m;
+ SCHAR tempL_e, tempR_e, tempRplus1_e, newL_e, newR_e;
+
+ /* 1. Unmap (already dequantized) coupled envelope energies */
+
+ for (i = 0; i < h_data_left->nScaleFactors; i++) {
+ tempR_m = (FIXP_SGL)((LONG)h_data_right->iEnvelope[i] & MASK_M);
+ tempR_e = (SCHAR)((LONG)h_data_right->iEnvelope[i] & MASK_E);
+
+ tempR_e -= (18 + NRG_EXP_OFFSET); /* -18 = ld(UNMAPPING_SCALE /
+ h_data_right->nChannels) */
+ tempL_m = (FIXP_SGL)((LONG)h_data_left->iEnvelope[i] & MASK_M);
+ tempL_e = (SCHAR)((LONG)h_data_left->iEnvelope[i] & MASK_E);
+
+ tempL_e -= NRG_EXP_OFFSET;
+
+ /* Calculate tempRight+1 */
+ FDK_add_MantExp(tempR_m, tempR_e, FL2FXCONST_SGL(0.5f), 1, /* 1.0 */
+ &tempRplus1_m, &tempRplus1_e);
+
+ FDK_divide_MantExp(tempL_m, tempL_e + 1, /* 2 * tempLeft */
+ tempRplus1_m, tempRplus1_e, &newR_m, &newR_e);
+
+ if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) {
+ newR_m >>= 1;
+ newR_e += 1;
+ }
+
+ newL_m = FX_DBL2FX_SGL(fMult(tempR_m, newR_m));
+ newL_e = tempR_e + newR_e;
+
+ h_data_right->iEnvelope[i] =
+ ((FIXP_SGL)((SHORT)(FIXP_SGL)(newR_m + ROUNDING) & MASK_M)) +
+ (FIXP_SGL)((SHORT)(FIXP_SGL)(newR_e + NRG_EXP_OFFSET) & MASK_E);
+ h_data_left->iEnvelope[i] =
+ ((FIXP_SGL)((SHORT)(FIXP_SGL)(newL_m + ROUNDING) & MASK_M)) +
+ (FIXP_SGL)((SHORT)(FIXP_SGL)(newL_e + NRG_EXP_OFFSET) & MASK_E);
+ }
+
+ /* 2. Dequantize and unmap coupled noise floor levels */
+
+ for (i = 0; i < hHeaderData->freqBandData.nNfb *
+ h_data_left->frameInfo.nNoiseEnvelopes;
+ i++) {
+ tempL_e = (SCHAR)(6 - (LONG)h_data_left->sbrNoiseFloorLevel[i]);
+ tempR_e = (SCHAR)((LONG)h_data_right->sbrNoiseFloorLevel[i] -
+ 12) /*SBR_ENERGY_PAN_OFFSET*/;
+
+ /* Calculate tempR+1 */
+ FDK_add_MantExp(FL2FXCONST_SGL(0.5f), 1 + tempR_e, /* tempR */
+ FL2FXCONST_SGL(0.5f), 1, /* 1.0 */
+ &tempRplus1_m, &tempRplus1_e);
+
+ /* Calculate 2*tempLeft/(tempR+1) */
+ FDK_divide_MantExp(FL2FXCONST_SGL(0.5f), tempL_e + 2, /* 2 * tempLeft */
+ tempRplus1_m, tempRplus1_e, &newR_m, &newR_e);
+
+ /* if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) {
+ newR_m >>= 1;
+ newR_e += 1;
+ } */
+
+ /* L = tempR * R */
+ newL_m = newR_m;
+ newL_e = newR_e + tempR_e;
+ h_data_right->sbrNoiseFloorLevel[i] =
+ ((FIXP_SGL)((SHORT)(FIXP_SGL)(newR_m + ROUNDING) & MASK_M)) +
+ (FIXP_SGL)((SHORT)(FIXP_SGL)(newR_e + NOISE_EXP_OFFSET) & MASK_E);
+ h_data_left->sbrNoiseFloorLevel[i] =
+ ((FIXP_SGL)((SHORT)(FIXP_SGL)(newL_m + ROUNDING) & MASK_M)) +
+ (FIXP_SGL)((SHORT)(FIXP_SGL)(newL_e + NOISE_EXP_OFFSET) & MASK_E);
+ }
+}
+
+/*!
+ \brief Simple alternative to the real SBR concealment
+
+ If the real frameInfo is not available due to a frame loss, a replacement will
+ be constructed with 1 envelope spanning the whole frame (FIX-FIX).
+ The delta-coded energies are set to negative values, resulting in a fade-down.
+ In case of coupling, the balance-channel will move towards the center.
+*/
+static void leanSbrConcealment(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data /*!< pointer to data of last frame */
+) {
+ FIXP_SGL target; /* targeted level for sfb_nrg_prev during fade-down */
+ FIXP_SGL step; /* speed of fade */
+ int i;
+
+ int currentStartPos =
+ fMax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots);
+ int currentStopPos = hHeaderData->numberTimeSlots;
+
+ /* Use some settings of the previous frame */
+ h_sbr_data->ampResolutionCurrentFrame = h_prev_data->ampRes;
+ h_sbr_data->coupling = h_prev_data->coupling;
+ for (i = 0; i < MAX_INVF_BANDS; i++)
+ h_sbr_data->sbr_invf_mode[i] = h_prev_data->sbr_invf_mode[i];
+
+ /* Generate concealing control data */
+
+ h_sbr_data->frameInfo.nEnvelopes = 1;
+ h_sbr_data->frameInfo.borders[0] = currentStartPos;
+ h_sbr_data->frameInfo.borders[1] = currentStopPos;
+ h_sbr_data->frameInfo.freqRes[0] = 1;
+ h_sbr_data->frameInfo.tranEnv = -1; /* no transient */
+ h_sbr_data->frameInfo.nNoiseEnvelopes = 1;
+ h_sbr_data->frameInfo.bordersNoise[0] = currentStartPos;
+ h_sbr_data->frameInfo.bordersNoise[1] = currentStopPos;
+
+ h_sbr_data->nScaleFactors = hHeaderData->freqBandData.nSfb[1];
+
+ /* Generate fake envelope data */
+
+ h_sbr_data->domain_vec[0] = 1;
+
+ if (h_sbr_data->coupling == COUPLING_BAL) {
+ target = (FIXP_SGL)SBR_ENERGY_PAN_OFFSET;
+ step = (FIXP_SGL)DECAY_COUPLING;
+ } else {
+ target = FL2FXCONST_SGL(0.0f);
+ step = (FIXP_SGL)DECAY;
+ }
+ if (hHeaderData->bs_info.ampResolution == 0) {
+ target <<= 1;
+ step <<= 1;
+ }
+
+ for (i = 0; i < h_sbr_data->nScaleFactors; i++) {
+ if (h_prev_data->sfb_nrg_prev[i] > target)
+ h_sbr_data->iEnvelope[i] = -step;
+ else
+ h_sbr_data->iEnvelope[i] = step;
+ }
+
+ /* Noisefloor levels are always cleared ... */
+
+ h_sbr_data->domain_vec_noise[0] = 1;
+ FDKmemclear(h_sbr_data->sbrNoiseFloorLevel,
+ sizeof(h_sbr_data->sbrNoiseFloorLevel));
+
+ /* ... and so are the sines */
+ FDKmemclear(h_sbr_data->addHarmonics,
+ sizeof(ULONG) * ADD_HARMONICS_FLAGS_SIZE);
+}
+
+/*!
+ \brief Build reference energies and noise levels from bitstream elements
+*/
+static void decodeEnvelope(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */
+ HANDLE_SBR_PREV_FRAME_DATA
+ h_prev_data, /*!< pointer to data of last frame */
+ HANDLE_SBR_PREV_FRAME_DATA
+ otherChannel /*!< other channel's last frame data */
+) {
+ int i;
+ int fFrameError = hHeaderData->frameErrorFlag;
+ FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS];
+
+ if (!fFrameError) {
+ /*
+ To avoid distortions after bad frames, set the error flag if delta coding
+ in time occurs. However, SBR can take a little longer to come up again.
+ */
+ if (h_prev_data->frameErrorFlag) {
+ if (h_sbr_data->domain_vec[0] != 0) {
+ fFrameError = 1;
+ }
+ } else {
+ /* Check that the previous stop position and the current start position
+ match. (Could be done in checkFrameInfo(), but the previous frame data
+ is not available there) */
+ if (h_sbr_data->frameInfo.borders[0] !=
+ h_prev_data->stopPos - hHeaderData->numberTimeSlots) {
+ /* Both the previous as well as the current frame are flagged to be ok,
+ * but they do not match! */
+ if (h_sbr_data->domain_vec[0] == 1) {
+ /* Prefer concealment over delta-time coding between the mismatching
+ * frames */
+ fFrameError = 1;
+ } else {
+ /* Close the gap in time by triggering timeCompensateFirstEnvelope()
+ */
+ fFrameError = 1;
+ }
+ }
+ }
+ }
+
+ if (fFrameError) /* Error is detected */
+ {
+ leanSbrConcealment(hHeaderData, h_sbr_data, h_prev_data);
+
+ /* decode the envelope data to linear PCM */
+ deltaToLinearPcmEnvelopeDecoding(hHeaderData, h_sbr_data, h_prev_data);
+ } else /*Do a temporary dummy decoding and check that the envelope values are
+ within limits */
+ {
+ if (h_prev_data->frameErrorFlag) {
+ timeCompensateFirstEnvelope(hHeaderData, h_sbr_data, h_prev_data);
+ if (h_sbr_data->coupling != h_prev_data->coupling) {
+ /*
+ Coupling mode has changed during concealment.
+ The stored energy levels need to be converted.
+ */
+ for (i = 0; i < hHeaderData->freqBandData.nSfb[1]; i++) {
+ /* Former Level-Channel will be used for both channels */
+ if (h_prev_data->coupling == COUPLING_BAL) {
+ h_prev_data->sfb_nrg_prev[i] =
+ (otherChannel != NULL) ? otherChannel->sfb_nrg_prev[i]
+ : (FIXP_SGL)SBR_ENERGY_PAN_OFFSET;
+ }
+ /* Former L/R will be combined as the new Level-Channel */
+ else if (h_sbr_data->coupling == COUPLING_LEVEL &&
+ otherChannel != NULL) {
+ h_prev_data->sfb_nrg_prev[i] = (h_prev_data->sfb_nrg_prev[i] +
+ otherChannel->sfb_nrg_prev[i]) >>
+ 1;
+ } else if (h_sbr_data->coupling == COUPLING_BAL) {
+ h_prev_data->sfb_nrg_prev[i] = (FIXP_SGL)SBR_ENERGY_PAN_OFFSET;
+ }
+ }
+ }
+ }
+ FDKmemcpy(tempSfbNrgPrev, h_prev_data->sfb_nrg_prev,
+ MAX_FREQ_COEFFS * sizeof(FIXP_SGL));
+
+ deltaToLinearPcmEnvelopeDecoding(hHeaderData, h_sbr_data, h_prev_data);
+
+ fFrameError = checkEnvelopeData(hHeaderData, h_sbr_data, h_prev_data);
+
+ if (fFrameError) {
+ hHeaderData->frameErrorFlag = 1;
+ FDKmemcpy(h_prev_data->sfb_nrg_prev, tempSfbNrgPrev,
+ MAX_FREQ_COEFFS * sizeof(FIXP_SGL));
+ decodeEnvelope(hHeaderData, h_sbr_data, h_prev_data, otherChannel);
+ return;
+ }
+ }
+
+ requantizeEnvelopeData(h_sbr_data, h_sbr_data->ampResolutionCurrentFrame);
+
+ hHeaderData->frameErrorFlag = fFrameError;
+}
+
+/*!
+ \brief Verify that envelope energies are within the allowed range
+ \return 0 if all is fine, 1 if an envelope value was too high
+*/
+static int checkEnvelopeData(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data /*!< pointer to data of last frame */
+) {
+ FIXP_SGL *iEnvelope = h_sbr_data->iEnvelope;
+ FIXP_SGL *sfb_nrg_prev = h_prev_data->sfb_nrg_prev;
+ int i = 0, errorFlag = 0;
+ FIXP_SGL sbr_max_energy = (h_sbr_data->ampResolutionCurrentFrame == 1)
+ ? SBR_MAX_ENERGY
+ : (SBR_MAX_ENERGY << 1);
+
+ /*
+ Range check for current energies
+ */
+ for (i = 0; i < h_sbr_data->nScaleFactors; i++) {
+ if (iEnvelope[i] > sbr_max_energy) {
+ errorFlag = 1;
+ }
+ if (iEnvelope[i] < FL2FXCONST_SGL(0.0f)) {
+ errorFlag = 1;
+ /* iEnvelope[i] = FL2FXCONST_SGL(0.0f); */
+ }
+ }
+
+ /*
+ Range check for previous energies
+ */
+ for (i = 0; i < hHeaderData->freqBandData.nSfb[1]; i++) {
+ sfb_nrg_prev[i] = fixMax(sfb_nrg_prev[i], FL2FXCONST_SGL(0.0f));
+ sfb_nrg_prev[i] = fixMin(sfb_nrg_prev[i], sbr_max_energy);
+ }
+
+ return (errorFlag);
+}
+
+/*!
+ \brief Verify that the noise levels are within the allowed range
+
+ The function is equivalent to checkEnvelopeData().
+ When the noise-levels are being decoded, it is already too late for
+ concealment. Therefore the noise levels are simply limited here.
+*/
+static void limitNoiseLevels(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_sbr_data) /*!< pointer to current data */
+{
+ int i;
+ int nNfb = hHeaderData->freqBandData.nNfb;
+
+/*
+ Set range limits. The exact values depend on the coupling mode.
+ However this limitation is primarily intended to avoid unlimited
+ accumulation of the delta-coded noise levels.
+*/
+#define lowerLimit \
+ ((FIXP_SGL)0) /* lowerLimit actually refers to the _highest_ noise energy */
+#define upperLimit \
+ ((FIXP_SGL)35) /* upperLimit actually refers to the _lowest_ noise energy */
+
+ /*
+ Range check for current noise levels
+ */
+ for (i = 0; i < h_sbr_data->frameInfo.nNoiseEnvelopes * nNfb; i++) {
+ h_sbr_data->sbrNoiseFloorLevel[i] =
+ fixMin(h_sbr_data->sbrNoiseFloorLevel[i], upperLimit);
+ h_sbr_data->sbrNoiseFloorLevel[i] =
+ fixMax(h_sbr_data->sbrNoiseFloorLevel[i], lowerLimit);
+ }
+}
+
+/*!
+ \brief Compensate for the wrong timing that might occur after a frame error.
+*/
+static void timeCompensateFirstEnvelope(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to actual data */
+ HANDLE_SBR_PREV_FRAME_DATA
+ h_prev_data) /*!< pointer to data of last frame */
+{
+ int i, nScalefactors;
+ FRAME_INFO *pFrameInfo = &h_sbr_data->frameInfo;
+ UCHAR *nSfb = hHeaderData->freqBandData.nSfb;
+ int estimatedStartPos =
+ fMax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots);
+ int refLen, newLen, shift;
+ FIXP_SGL deltaExp;
+
+ /* Original length of first envelope according to bitstream */
+ refLen = pFrameInfo->borders[1] - pFrameInfo->borders[0];
+ /* Corrected length of first envelope (concealing can make the first envelope
+ * longer) */
+ newLen = pFrameInfo->borders[1] - estimatedStartPos;
+
+ if (newLen <= 0) {
+ /* An envelope length of <= 0 would not work, so we don't use it.
+ May occur if the previous frame was flagged bad due to a mismatch
+ of the old and new frame infos. */
+ newLen = refLen;
+ estimatedStartPos = pFrameInfo->borders[0];
+ }
+
+ deltaExp = FDK_getNumOctavesDiv8(newLen, refLen);
+
+ /* Shift by -3 to rescale ld-table, ampRes-1 to enable coarser steps */
+ shift = (FRACT_BITS - 1 - ENV_EXP_FRACT - 1 +
+ h_sbr_data->ampResolutionCurrentFrame - 3);
+ deltaExp = deltaExp >> shift;
+ pFrameInfo->borders[0] = estimatedStartPos;
+ pFrameInfo->bordersNoise[0] = estimatedStartPos;
+
+ if (h_sbr_data->coupling != COUPLING_BAL) {
+ nScalefactors = (pFrameInfo->freqRes[0]) ? nSfb[1] : nSfb[0];
+
+ for (i = 0; i < nScalefactors; i++)
+ h_sbr_data->iEnvelope[i] = h_sbr_data->iEnvelope[i] + deltaExp;
+ }
+}
+
+/*!
+ \brief Convert each envelope value from logarithmic to linear domain
+
+ Energy levels are transmitted in powers of 2, i.e. only the exponent
+ is extracted from the bitstream.
+ Therefore, normally only integer exponents can occur. However during
+ fading (in case of a corrupt bitstream), a fractional part can also
+ occur. The data in the array iEnvelope is shifted left by ENV_EXP_FRACT
+ compared to an integer representation so that numbers smaller than 1
+ can be represented.
+
+ This function calculates a mantissa corresponding to the fractional
+ part of the exponent for each reference energy. The array iEnvelope
+ is converted in place to save memory. Input and output data must
+ be interpreted differently, as shown in the below figure:
+
+ \image html EnvelopeData.png
+
+ The data is then used in calculateSbrEnvelope().
+*/
+static void requantizeEnvelopeData(HANDLE_SBR_FRAME_DATA h_sbr_data,
+ int ampResolution) {
+ int i;
+ FIXP_SGL mantissa;
+ int ampShift = 1 - ampResolution;
+ int exponent;
+
+ /* In case that ENV_EXP_FRACT is changed to something else but 0 or 8,
+ the initialization of this array has to be adapted!
+ */
+#if ENV_EXP_FRACT
+ static const FIXP_SGL pow2[ENV_EXP_FRACT] = {
+ FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 1))), /* 0.7071 */
+ FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 2))), /* 0.5946 */
+ FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 3))),
+ FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 4))),
+ FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 5))),
+ FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 6))),
+ FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 7))),
+ FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 8))) /* 0.5013 */
+ };
+
+ int bit, mask;
+#endif
+
+ for (i = 0; i < h_sbr_data->nScaleFactors; i++) {
+ exponent = (LONG)h_sbr_data->iEnvelope[i];
+
+#if ENV_EXP_FRACT
+
+ exponent = exponent >> ampShift;
+ mantissa = 0.5f;
+
+ /* Amplify mantissa according to the fractional part of the
+ exponent (result will be between 0.500000 and 0.999999)
+ */
+ mask = 1; /* begin with lowest bit of exponent */
+
+ for (bit = ENV_EXP_FRACT - 1; bit >= 0; bit--) {
+ if (exponent & mask) {
+ /* The current bit of the exponent is set,
+ multiply mantissa with the corresponding factor: */
+ mantissa = (FIXP_SGL)((mantissa * pow2[bit]) << 1);
+ }
+ /* Advance to next bit */
+ mask = mask << 1;
+ }
+
+ /* Make integer part of exponent right aligned */
+ exponent = exponent >> ENV_EXP_FRACT;
+
+#else
+ /* In case of the high amplitude resolution, 1 bit of the exponent gets lost
+ by the shift. This will be compensated by a mantissa of 0.5*sqrt(2)
+ instead of 0.5 if that bit is 1. */
+ mantissa = (exponent & ampShift) ? FL2FXCONST_SGL(0.707106781186548f)
+ : FL2FXCONST_SGL(0.5f);
+ exponent = exponent >> ampShift;
+#endif
+
+ /*
+ Mantissa was set to 0.5 (instead of 1.0, therefore increase exponent by
+ 1). Multiply by L=nChannels=64 by increasing exponent by another 6.
+ => Increase exponent by 7
+ */
+ exponent += 7 + NRG_EXP_OFFSET;
+
+ /* Combine mantissa and exponent and write back the result */
+ h_sbr_data->iEnvelope[i] =
+ ((FIXP_SGL)((SHORT)(FIXP_SGL)mantissa & MASK_M)) +
+ (FIXP_SGL)((SHORT)(FIXP_SGL)exponent & MASK_E);
+ }
+}
+
+/*!
+ \brief Build new reference energies from old ones and delta coded data
+*/
+static void deltaToLinearPcmEnvelopeDecoding(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data) /*!< pointer to previous data */
+{
+ int i, domain, no_of_bands, band, freqRes;
+
+ FIXP_SGL *sfb_nrg_prev = h_prev_data->sfb_nrg_prev;
+ FIXP_SGL *ptr_nrg = h_sbr_data->iEnvelope;
+
+ int offset =
+ 2 * hHeaderData->freqBandData.nSfb[0] - hHeaderData->freqBandData.nSfb[1];
+
+ for (i = 0; i < h_sbr_data->frameInfo.nEnvelopes; i++) {
+ domain = h_sbr_data->domain_vec[i];
+ freqRes = h_sbr_data->frameInfo.freqRes[i];
+
+ FDK_ASSERT(freqRes >= 0 && freqRes <= 1);
+
+ no_of_bands = hHeaderData->freqBandData.nSfb[freqRes];
+
+ FDK_ASSERT(no_of_bands < (64));
+
+ if (domain == 0) {
+ mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, 0, freqRes);
+ ptr_nrg++;
+ for (band = 1; band < no_of_bands; band++) {
+ *ptr_nrg = *ptr_nrg + *(ptr_nrg - 1);
+ mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes);
+ ptr_nrg++;
+ }
+ } else {
+ for (band = 0; band < no_of_bands; band++) {
+ *ptr_nrg =
+ *ptr_nrg + sfb_nrg_prev[indexLow2High(offset, band, freqRes)];
+ mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes);
+ ptr_nrg++;
+ }
+ }
+ }
+}
+
+/*!
+ \brief Build new noise levels from old ones and delta coded data
+*/
+static void decodeNoiseFloorlevels(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data) /*!< pointer to previous data */
+{
+ int i;
+ int nNfb = hHeaderData->freqBandData.nNfb;
+ int nNoiseFloorEnvelopes = h_sbr_data->frameInfo.nNoiseEnvelopes;
+
+ /* Decode first noise envelope */
+
+ if (h_sbr_data->domain_vec_noise[0] == 0) {
+ FIXP_SGL noiseLevel = h_sbr_data->sbrNoiseFloorLevel[0];
+ for (i = 1; i < nNfb; i++) {
+ noiseLevel += h_sbr_data->sbrNoiseFloorLevel[i];
+ h_sbr_data->sbrNoiseFloorLevel[i] = noiseLevel;
+ }
+ } else {
+ for (i = 0; i < nNfb; i++) {
+ h_sbr_data->sbrNoiseFloorLevel[i] += h_prev_data->prevNoiseLevel[i];
+ }
+ }
+
+ /* If present, decode the second noise envelope
+ Note: nNoiseFloorEnvelopes can only be 1 or 2 */
+
+ if (nNoiseFloorEnvelopes > 1) {
+ if (h_sbr_data->domain_vec_noise[1] == 0) {
+ FIXP_SGL noiseLevel = h_sbr_data->sbrNoiseFloorLevel[nNfb];
+ for (i = nNfb + 1; i < 2 * nNfb; i++) {
+ noiseLevel += h_sbr_data->sbrNoiseFloorLevel[i];
+ h_sbr_data->sbrNoiseFloorLevel[i] = noiseLevel;
+ }
+ } else {
+ for (i = 0; i < nNfb; i++) {
+ h_sbr_data->sbrNoiseFloorLevel[i + nNfb] +=
+ h_sbr_data->sbrNoiseFloorLevel[i];
+ }
+ }
+ }
+
+ limitNoiseLevels(hHeaderData, h_sbr_data);
+
+ /* Update prevNoiseLevel with the last noise envelope */
+ for (i = 0; i < nNfb; i++)
+ h_prev_data->prevNoiseLevel[i] =
+ h_sbr_data->sbrNoiseFloorLevel[i + nNfb * (nNoiseFloorEnvelopes - 1)];
+
+ /* Requantize the noise floor levels in COUPLING_OFF-mode */
+ if (!h_sbr_data->coupling) {
+ int nf_e;
+
+ for (i = 0; i < nNoiseFloorEnvelopes * nNfb; i++) {
+ nf_e = 6 - (LONG)h_sbr_data->sbrNoiseFloorLevel[i] + 1 + NOISE_EXP_OFFSET;
+ /* +1 to compensate for a mantissa of 0.5 instead of 1.0 */
+
+ h_sbr_data->sbrNoiseFloorLevel[i] =
+ (FIXP_SGL)(((LONG)FL2FXCONST_SGL(0.5f)) + /* mantissa */
+ (nf_e & MASK_E)); /* exponent */
+ }
+ }
+}
diff --git a/fdk-aac/libSBRdec/src/env_dec.h b/fdk-aac/libSBRdec/src/env_dec.h
new file mode 100644
index 0000000..0b11ce1
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/env_dec.h
@@ -0,0 +1,119 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Envelope decoding
+*/
+#ifndef ENV_DEC_H
+#define ENV_DEC_H
+
+#include "sbrdecoder.h"
+#include "env_extr.h"
+
+void decodeSbrData(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA h_data_left,
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data_left,
+ HANDLE_SBR_FRAME_DATA h_data_right,
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_data_right);
+
+#endif
diff --git a/fdk-aac/libSBRdec/src/env_extr.cpp b/fdk-aac/libSBRdec/src/env_extr.cpp
new file mode 100644
index 0000000..c72a7b6
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/env_extr.cpp
@@ -0,0 +1,1728 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Envelope extraction
+ The functions provided by this module are mostly called by applySBR(). After
+ it is determined that there is valid SBR data, sbrGetHeaderData() might be
+ called if the current SBR data contains an \ref SBR_HEADER_ELEMENT as opposed
+ to a \ref SBR_STANDARD_ELEMENT. This function may return various error codes
+ as defined in #SBR_HEADER_STATUS . Most importantly it returns HEADER_RESET
+ when decoder settings need to be recalculated according to the SBR
+ specifications. In that case applySBR() will initiatite the required
+ re-configuration.
+
+ The header data is stored in a #SBR_HEADER_DATA structure.
+
+ The actual SBR data for the current frame is decoded into SBR_FRAME_DATA
+ stuctures by sbrGetChannelPairElement() [for stereo streams] and
+ sbrGetSingleChannelElement() [for mono streams]. There is no fractional
+ arithmetic involved.
+
+ Once the information is extracted, the data needs to be further prepared
+ before the actual decoding process. This is done in decodeSbrData().
+
+ \sa Description of buffer management in applySBR(). \ref documentationOverview
+
+ <h1>About the SBR data format:</h1>
+
+ Each frame includes SBR data (side chain information), and can be either the
+ \ref SBR_HEADER_ELEMENT or the \ref SBR_STANDARD_ELEMENT. Parts of the data
+ can be protected by a CRC checksum.
+
+ \anchor SBR_HEADER_ELEMENT <h2>The SBR_HEADER_ELEMENT</h2>
+
+ The SBR_HEADER_ELEMENT can be transmitted with every frame, however, it
+ typically is send every second or so. It contains fundamental information such
+ as SBR sampling frequency and frequency range as well as control signals that
+ do not require frequent changes. It also includes the \ref
+ SBR_STANDARD_ELEMENT.
+
+ Depending on the changes between the information in a current
+ SBR_HEADER_ELEMENT and the previous SBR_HEADER_ELEMENT, the SBR decoder might
+ need to be reset and reconfigured (e.g. new tables need to be calculated).
+
+ \anchor SBR_STANDARD_ELEMENT <h2>The SBR_STANDARD_ELEMENT</h2>
+
+ This data can be subdivided into "side info" and "raw data", where side info
+ is defined as signals needed to decode the raw data and some decoder tuning
+ signals. Raw data is referred to as PCM and Huffman coded envelope and noise
+ floor estimates. The side info also includes information about the
+ time-frequency grid for the current frame.
+
+ \sa \ref documentationOverview
+*/
+
+#include "env_extr.h"
+
+#include "sbr_ram.h"
+#include "sbr_rom.h"
+#include "huff_dec.h"
+
+#include "psbitdec.h"
+
+#define DRM_PARAMETRIC_STEREO 0
+#define EXTENSION_ID_PS_CODING 2
+
+static int extractPvcFrameInfo(
+ HANDLE_FDK_BITSTREAM hBs, /*!< bitbuffer handle */
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the
+ frame-info will be stored */
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_frame_data, /*!< pointer to memory where
+ the previous frame-info
+ will be stored */
+ UCHAR pvc_mode_last, /**< PVC mode of last frame */
+ const UINT flags);
+static int extractFrameInfo(HANDLE_FDK_BITSTREAM hBs,
+ HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA h_frame_data,
+ const UINT nrOfChannels, const UINT flags);
+
+static int sbrGetPvcEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA h_frame_data,
+ HANDLE_FDK_BITSTREAM hBs, const UINT flags,
+ const UINT pvcMode);
+static int sbrGetEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA h_frame_data,
+ HANDLE_FDK_BITSTREAM hBs, const UINT flags);
+
+static void sbrGetDirectionControlData(HANDLE_SBR_FRAME_DATA hFrameData,
+ HANDLE_FDK_BITSTREAM hBs,
+ const UINT flags, const int bs_pvc_mode);
+
+static void sbrGetNoiseFloorData(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA h_frame_data,
+ HANDLE_FDK_BITSTREAM hBs);
+
+static int checkFrameInfo(FRAME_INFO *pFrameInfo, int numberOfTimeSlots,
+ int overlap, int timeStep);
+
+/* Mapping to std samplerate table according to 14496-3 (4.6.18.2.6) */
+typedef struct SR_MAPPING {
+ UINT fsRangeLo; /* If fsRangeLo(n+1)>fs>=fsRangeLo(n), it will be mapped to...
+ */
+ UINT fsMapped; /* fsMapped. */
+} SR_MAPPING;
+
+static const SR_MAPPING stdSampleRatesMapping[] = {
+ {0, 8000}, {9391, 11025}, {11502, 12000}, {13856, 16000},
+ {18783, 22050}, {23004, 24000}, {27713, 32000}, {37566, 44100},
+ {46009, 48000}, {55426, 64000}, {75132, 88200}, {92017, 96000}};
+static const SR_MAPPING stdSampleRatesMappingUsac[] = {
+ {0, 16000}, {18783, 22050}, {23004, 24000}, {27713, 32000},
+ {35777, 40000}, {42000, 44100}, {46009, 48000}, {55426, 64000},
+ {75132, 88200}, {92017, 96000}};
+
+UINT sbrdec_mapToStdSampleRate(UINT fs,
+ UINT isUsac) /*!< Output sampling frequency */
+{
+ UINT fsMapped = fs, tableSize = 0;
+ const SR_MAPPING *mappingTable;
+ int i;
+
+ if (!isUsac) {
+ mappingTable = stdSampleRatesMapping;
+ tableSize = sizeof(stdSampleRatesMapping) / sizeof(SR_MAPPING);
+ } else {
+ mappingTable = stdSampleRatesMappingUsac;
+ tableSize = sizeof(stdSampleRatesMappingUsac) / sizeof(SR_MAPPING);
+ }
+
+ for (i = tableSize - 1; i >= 0; i--) {
+ if (fs >= mappingTable[i].fsRangeLo) {
+ fsMapped = mappingTable[i].fsMapped;
+ break;
+ }
+ }
+
+ return (fsMapped);
+}
+
+SBR_ERROR
+initHeaderData(HANDLE_SBR_HEADER_DATA hHeaderData, const int sampleRateIn,
+ const int sampleRateOut, const INT downscaleFactor,
+ const int samplesPerFrame, const UINT flags,
+ const int setDefaultHdr) {
+ HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
+ SBR_ERROR sbrError = SBRDEC_OK;
+ int numAnalysisBands;
+ int sampleRateProc;
+
+ if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) {
+ sampleRateProc =
+ sbrdec_mapToStdSampleRate(sampleRateOut * downscaleFactor, 0);
+ } else {
+ sampleRateProc = sampleRateOut * downscaleFactor;
+ }
+
+ if (sampleRateIn == sampleRateOut) {
+ hHeaderData->sbrProcSmplRate = sampleRateProc << 1;
+ numAnalysisBands = 32;
+ } else {
+ hHeaderData->sbrProcSmplRate = sampleRateProc;
+ if ((sampleRateOut >> 1) == sampleRateIn) {
+ /* 1:2 */
+ numAnalysisBands = 32;
+ } else if ((sampleRateOut >> 2) == sampleRateIn) {
+ /* 1:4 */
+ numAnalysisBands = 16;
+ } else if ((sampleRateOut * 3) >> 3 == (sampleRateIn * 8) >> 3) {
+ /* 3:8, 3/4 core frame length */
+ numAnalysisBands = 24;
+ } else {
+ sbrError = SBRDEC_UNSUPPORTED_CONFIG;
+ goto bail;
+ }
+ }
+ numAnalysisBands /= downscaleFactor;
+
+ if (setDefaultHdr) {
+ /* Fill in default values first */
+ hHeaderData->syncState = SBR_NOT_INITIALIZED;
+ hHeaderData->status = 0;
+ hHeaderData->frameErrorFlag = 0;
+
+ hHeaderData->bs_info.ampResolution = 1;
+ hHeaderData->bs_info.xover_band = 0;
+ hHeaderData->bs_info.sbr_preprocessing = 0;
+ hHeaderData->bs_info.pvc_mode = 0;
+
+ hHeaderData->bs_data.startFreq = 5;
+ hHeaderData->bs_data.stopFreq = 0;
+ hHeaderData->bs_data.freqScale =
+ 0; /* previously 2; for ELD reduced delay bitstreams
+ /samplerates initializing of the sbr decoder instance fails if
+ freqScale is set to 2 because no master table can be generated; in
+ ELD reduced delay bitstreams this value is always 0; gets overwritten
+ when header is read */
+ hHeaderData->bs_data.alterScale = 1;
+ hHeaderData->bs_data.noise_bands = 2;
+ hHeaderData->bs_data.limiterBands = 2;
+ hHeaderData->bs_data.limiterGains = 2;
+ hHeaderData->bs_data.interpolFreq = 1;
+ hHeaderData->bs_data.smoothingLength = 1;
+
+ /* Patch some entries */
+ if (sampleRateOut * downscaleFactor >= 96000) {
+ hHeaderData->bs_data.startFreq =
+ 4; /* having read these frequency values from bit stream before. */
+ hHeaderData->bs_data.stopFreq = 3;
+ } else if (sampleRateOut * downscaleFactor >
+ 24000) { /* Trigger an error if SBR is going to be processed
+ without */
+ hHeaderData->bs_data.startFreq =
+ 7; /* having read these frequency values from bit stream before. */
+ hHeaderData->bs_data.stopFreq = 3;
+ }
+ }
+
+ if ((sampleRateOut >> 2) == sampleRateIn) {
+ hHeaderData->timeStep = 4;
+ } else {
+ hHeaderData->timeStep = (flags & SBRDEC_ELD_GRID) ? 1 : 2;
+ }
+
+ /* Setup pointers to frequency band tables */
+ hFreq->freqBandTable[0] = hFreq->freqBandTableLo;
+ hFreq->freqBandTable[1] = hFreq->freqBandTableHi;
+
+ /* One SBR timeslot corresponds to the amount of samples equal to the amount
+ * of analysis bands, divided by the timestep. */
+ hHeaderData->numberTimeSlots =
+ (samplesPerFrame / numAnalysisBands) >> (hHeaderData->timeStep - 1);
+ if (hHeaderData->numberTimeSlots > (16)) {
+ sbrError = SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ hHeaderData->numberOfAnalysisBands = numAnalysisBands;
+ if ((sampleRateOut >> 2) == sampleRateIn) {
+ hHeaderData->numberTimeSlots <<= 1;
+ }
+
+bail:
+ return sbrError;
+}
+
+/*!
+ \brief Initialize the SBR_PREV_FRAME_DATA struct
+*/
+void initSbrPrevFrameData(
+ HANDLE_SBR_PREV_FRAME_DATA
+ h_prev_data, /*!< handle to struct SBR_PREV_FRAME_DATA */
+ int timeSlots) /*!< Framelength in SBR-timeslots */
+{
+ int i;
+
+ /* Set previous energy and noise levels to 0 for the case
+ that decoding starts in the middle of a bitstream */
+ for (i = 0; i < MAX_FREQ_COEFFS; i++)
+ h_prev_data->sfb_nrg_prev[i] = (FIXP_DBL)0;
+ for (i = 0; i < MAX_NOISE_COEFFS; i++)
+ h_prev_data->prevNoiseLevel[i] = (FIXP_DBL)0;
+ for (i = 0; i < MAX_INVF_BANDS; i++) h_prev_data->sbr_invf_mode[i] = INVF_OFF;
+
+ h_prev_data->stopPos = timeSlots;
+ h_prev_data->coupling = COUPLING_OFF;
+ h_prev_data->ampRes = 0;
+
+ FDKmemclear(&h_prev_data->prevFrameInfo, sizeof(h_prev_data->prevFrameInfo));
+}
+
+/*!
+ \brief Read header data from bitstream
+
+ \return error status - 0 if ok
+*/
+SBR_HEADER_STATUS
+sbrGetHeaderData(HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_FDK_BITSTREAM hBs,
+ const UINT flags, const int fIsSbrData,
+ const UCHAR configMode) {
+ SBR_HEADER_DATA_BS *pBsData;
+ SBR_HEADER_DATA_BS lastHeader;
+ SBR_HEADER_DATA_BS_INFO lastInfo;
+ int headerExtra1 = 0, headerExtra2 = 0;
+
+ /* Read and discard new header in config change detection mode */
+ if (configMode & AC_CM_DET_CFG_CHANGE) {
+ if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) {
+ /* ampResolution */
+ FDKreadBits(hBs, 1);
+ }
+ /* startFreq, stopFreq */
+ FDKpushFor(hBs, 8);
+ if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) {
+ /* xover_band */
+ FDKreadBits(hBs, 3);
+ /* reserved bits */
+ FDKreadBits(hBs, 2);
+ }
+ headerExtra1 = FDKreadBit(hBs);
+ headerExtra2 = FDKreadBit(hBs);
+ FDKpushFor(hBs, 5 * headerExtra1 + 6 * headerExtra2);
+
+ return HEADER_OK;
+ }
+
+ /* Copy SBR bit stream header to temporary header */
+ lastHeader = hHeaderData->bs_data;
+ lastInfo = hHeaderData->bs_info;
+
+ /* Read new header from bitstream */
+ if ((flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC)) && !fIsSbrData) {
+ pBsData = &hHeaderData->bs_dflt;
+ } else {
+ pBsData = &hHeaderData->bs_data;
+ }
+
+ if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) {
+ hHeaderData->bs_info.ampResolution = FDKreadBits(hBs, 1);
+ }
+
+ pBsData->startFreq = FDKreadBits(hBs, 4);
+ pBsData->stopFreq = FDKreadBits(hBs, 4);
+
+ if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) {
+ hHeaderData->bs_info.xover_band = FDKreadBits(hBs, 3);
+ FDKreadBits(hBs, 2);
+ }
+
+ headerExtra1 = FDKreadBits(hBs, 1);
+ headerExtra2 = FDKreadBits(hBs, 1);
+
+ /* Handle extra header information */
+ if (headerExtra1) {
+ pBsData->freqScale = FDKreadBits(hBs, 2);
+ pBsData->alterScale = FDKreadBits(hBs, 1);
+ pBsData->noise_bands = FDKreadBits(hBs, 2);
+ } else {
+ pBsData->freqScale = 2;
+ pBsData->alterScale = 1;
+ pBsData->noise_bands = 2;
+ }
+
+ if (headerExtra2) {
+ pBsData->limiterBands = FDKreadBits(hBs, 2);
+ pBsData->limiterGains = FDKreadBits(hBs, 2);
+ pBsData->interpolFreq = FDKreadBits(hBs, 1);
+ pBsData->smoothingLength = FDKreadBits(hBs, 1);
+ } else {
+ pBsData->limiterBands = 2;
+ pBsData->limiterGains = 2;
+ pBsData->interpolFreq = 1;
+ pBsData->smoothingLength = 1;
+ }
+
+ /* Look for new settings. IEC 14496-3, 4.6.18.3.1 */
+ if (hHeaderData->syncState < SBR_HEADER ||
+ lastHeader.startFreq != pBsData->startFreq ||
+ lastHeader.stopFreq != pBsData->stopFreq ||
+ lastHeader.freqScale != pBsData->freqScale ||
+ lastHeader.alterScale != pBsData->alterScale ||
+ lastHeader.noise_bands != pBsData->noise_bands ||
+ lastInfo.xover_band != hHeaderData->bs_info.xover_band) {
+ return HEADER_RESET; /* New settings */
+ }
+
+ return HEADER_OK;
+}
+
+/*!
+ \brief Get missing harmonics parameters (only used for AAC+SBR)
+
+ \return error status - 0 if ok
+*/
+int sbrGetSyntheticCodedData(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA hFrameData,
+ HANDLE_FDK_BITSTREAM hBs, const UINT flags) {
+ int i, bitsRead = 0;
+
+ int add_harmonic_flag = FDKreadBits(hBs, 1);
+ bitsRead++;
+
+ if (add_harmonic_flag) {
+ int nSfb = hHeaderData->freqBandData.nSfb[1];
+ for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) {
+ /* read maximum 32 bits and align them to the MSB */
+ int readBits = fMin(32, nSfb);
+ nSfb -= readBits;
+ if (readBits > 0) {
+ hFrameData->addHarmonics[i] = FDKreadBits(hBs, readBits)
+ << (32 - readBits);
+ } else {
+ hFrameData->addHarmonics[i] = 0;
+ }
+
+ bitsRead += readBits;
+ }
+ /* bs_pvc_mode = 0 for Rsvd50 */
+ if (flags & SBRDEC_SYNTAX_USAC) {
+ if (hHeaderData->bs_info.pvc_mode) {
+ int bs_sinusoidal_position = 31;
+ if (FDKreadBit(hBs) /* bs_sinusoidal_position_flag */) {
+ bs_sinusoidal_position = FDKreadBits(hBs, 5);
+ }
+ hFrameData->sinusoidal_position = bs_sinusoidal_position;
+ }
+ }
+ } else {
+ for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++)
+ hFrameData->addHarmonics[i] = 0;
+ }
+
+ return (bitsRead);
+}
+
+/*!
+ \brief Reads extension data from the bitstream
+
+ The bitstream format allows up to 4 kinds of extended data element.
+ Extended data may contain several elements, each identified by a 2-bit-ID.
+ So far, no extended data elements are defined hence the first 2 parameters
+ are unused. The data should be skipped in order to update the number
+ of read bits for the consistency check in applySBR().
+*/
+static int extractExtendedData(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< handle to SBR header */
+ HANDLE_FDK_BITSTREAM hBs /*!< Handle to the bit buffer */
+ ,
+ HANDLE_PS_DEC hParametricStereoDec /*!< Parametric Stereo Decoder */
+) {
+ INT nBitsLeft;
+ int extended_data;
+ int i, frameOk = 1;
+
+ extended_data = FDKreadBits(hBs, 1);
+
+ if (extended_data) {
+ int cnt;
+ int bPsRead = 0;
+
+ cnt = FDKreadBits(hBs, 4);
+ if (cnt == (1 << 4) - 1) cnt += FDKreadBits(hBs, 8);
+
+ nBitsLeft = 8 * cnt;
+
+ /* sanity check for cnt */
+ if (nBitsLeft > (INT)FDKgetValidBits(hBs)) {
+ /* limit nBitsLeft */
+ nBitsLeft = (INT)FDKgetValidBits(hBs);
+ /* set frame error */
+ frameOk = 0;
+ }
+
+ while (nBitsLeft > 7) {
+ int extension_id = FDKreadBits(hBs, 2);
+ nBitsLeft -= 2;
+
+ switch (extension_id) {
+ case EXTENSION_ID_PS_CODING:
+
+ /* Read PS data from bitstream */
+
+ if (hParametricStereoDec != NULL) {
+ if (bPsRead &&
+ !hParametricStereoDec->bsData[hParametricStereoDec->bsReadSlot]
+ .mpeg.bPsHeaderValid) {
+ cnt = nBitsLeft >> 3; /* number of remaining bytes */
+ for (i = 0; i < cnt; i++) FDKreadBits(hBs, 8);
+ nBitsLeft -= cnt * 8;
+ } else {
+ nBitsLeft -=
+ (INT)ReadPsData(hParametricStereoDec, hBs, nBitsLeft);
+ bPsRead = 1;
+ }
+ }
+
+ /* parametric stereo detected, could set channelMode accordingly here
+ */
+ /* */
+ /* "The usage of this parametric stereo extension to HE-AAC is */
+ /* signalled implicitly in the bitstream. Hence, if an sbr_extension()
+ */
+ /* with bs_extension_id==EXTENSION_ID_PS is found in the SBR part of
+ */
+ /* the bitstream, a decoder supporting the combination of SBR and PS
+ */
+ /* shall operate the PS tool to generate a stereo output signal." */
+ /* source: ISO/IEC 14496-3:2001/FDAM 2:2004(E) */
+
+ break;
+
+ default:
+ cnt = nBitsLeft >> 3; /* number of remaining bytes */
+ for (i = 0; i < cnt; i++) FDKreadBits(hBs, 8);
+ nBitsLeft -= cnt * 8;
+ break;
+ }
+ }
+
+ if (nBitsLeft < 0) {
+ frameOk = 0;
+ goto bail;
+ } else {
+ /* Read fill bits for byte alignment */
+ FDKreadBits(hBs, nBitsLeft);
+ }
+ }
+
+bail:
+ return (frameOk);
+}
+
+/*!
+ \brief Read bitstream elements of a SBR channel element
+ \return SbrFrameOK
+*/
+int sbrGetChannelElement(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA hFrameDataLeft,
+ HANDLE_SBR_FRAME_DATA hFrameDataRight,
+ HANDLE_SBR_PREV_FRAME_DATA hFrameDataLeftPrev,
+ UCHAR pvc_mode_last, HANDLE_FDK_BITSTREAM hBs,
+ HANDLE_PS_DEC hParametricStereoDec, const UINT flags,
+ const int overlap) {
+ int i, bs_coupling = COUPLING_OFF;
+ const int nCh = (hFrameDataRight == NULL) ? 1 : 2;
+
+ if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) {
+ /* Reserved bits */
+ if (FDKreadBits(hBs, 1)) { /* bs_data_extra */
+ FDKreadBits(hBs, 4);
+ if ((flags & SBRDEC_SYNTAX_SCAL) || (nCh == 2)) {
+ FDKreadBits(hBs, 4);
+ }
+ }
+ }
+
+ if (nCh == 2) {
+ /* Read coupling flag */
+ bs_coupling = FDKreadBits(hBs, 1);
+ if (bs_coupling) {
+ hFrameDataLeft->coupling = COUPLING_LEVEL;
+ hFrameDataRight->coupling = COUPLING_BAL;
+ } else {
+ hFrameDataLeft->coupling = COUPLING_OFF;
+ hFrameDataRight->coupling = COUPLING_OFF;
+ }
+ } else {
+ if (flags & SBRDEC_SYNTAX_SCAL) {
+ FDKreadBits(hBs, 1); /* bs_coupling */
+ }
+ hFrameDataLeft->coupling = COUPLING_OFF;
+ }
+
+ if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) {
+ if (flags & SBRDEC_USAC_HARMONICSBR) {
+ hFrameDataLeft->sbrPatchingMode = FDKreadBit(hBs);
+ if (hFrameDataLeft->sbrPatchingMode == 0) {
+ hFrameDataLeft->sbrOversamplingFlag = FDKreadBit(hBs);
+ if (FDKreadBit(hBs)) { /* sbrPitchInBinsFlag */
+ hFrameDataLeft->sbrPitchInBins = FDKreadBits(hBs, 7);
+ } else {
+ hFrameDataLeft->sbrPitchInBins = 0;
+ }
+ } else {
+ hFrameDataLeft->sbrOversamplingFlag = 0;
+ hFrameDataLeft->sbrPitchInBins = 0;
+ }
+
+ if (nCh == 2) {
+ if (bs_coupling) {
+ hFrameDataRight->sbrPatchingMode = hFrameDataLeft->sbrPatchingMode;
+ hFrameDataRight->sbrOversamplingFlag =
+ hFrameDataLeft->sbrOversamplingFlag;
+ hFrameDataRight->sbrPitchInBins = hFrameDataLeft->sbrPitchInBins;
+ } else {
+ hFrameDataRight->sbrPatchingMode = FDKreadBit(hBs);
+ if (hFrameDataRight->sbrPatchingMode == 0) {
+ hFrameDataRight->sbrOversamplingFlag = FDKreadBit(hBs);
+ if (FDKreadBit(hBs)) { /* sbrPitchInBinsFlag */
+ hFrameDataRight->sbrPitchInBins = FDKreadBits(hBs, 7);
+ } else {
+ hFrameDataRight->sbrPitchInBins = 0;
+ }
+ } else {
+ hFrameDataRight->sbrOversamplingFlag = 0;
+ hFrameDataRight->sbrPitchInBins = 0;
+ }
+ }
+ }
+ } else {
+ if (nCh == 2) {
+ hFrameDataRight->sbrPatchingMode = 1;
+ hFrameDataRight->sbrOversamplingFlag = 0;
+ hFrameDataRight->sbrPitchInBins = 0;
+ }
+
+ hFrameDataLeft->sbrPatchingMode = 1;
+ hFrameDataLeft->sbrOversamplingFlag = 0;
+ hFrameDataLeft->sbrPitchInBins = 0;
+ }
+ } else {
+ if (nCh == 2) {
+ hFrameDataRight->sbrPatchingMode = 1;
+ hFrameDataRight->sbrOversamplingFlag = 0;
+ hFrameDataRight->sbrPitchInBins = 0;
+ }
+
+ hFrameDataLeft->sbrPatchingMode = 1;
+ hFrameDataLeft->sbrOversamplingFlag = 0;
+ hFrameDataLeft->sbrPitchInBins = 0;
+ }
+
+ /*
+ sbr_grid(): Grid control
+ */
+ if (hHeaderData->bs_info.pvc_mode) {
+ FDK_ASSERT(nCh == 1); /* PVC not possible for CPE */
+ if (!extractPvcFrameInfo(hBs, hHeaderData, hFrameDataLeft,
+ hFrameDataLeftPrev, pvc_mode_last, flags))
+ return 0;
+
+ if (!checkFrameInfo(&hFrameDataLeft->frameInfo,
+ hHeaderData->numberTimeSlots, overlap,
+ hHeaderData->timeStep))
+ return 0;
+ } else {
+ if (!extractFrameInfo(hBs, hHeaderData, hFrameDataLeft, 1, flags)) return 0;
+
+ if (!checkFrameInfo(&hFrameDataLeft->frameInfo,
+ hHeaderData->numberTimeSlots, overlap,
+ hHeaderData->timeStep))
+ return 0;
+ }
+ if (nCh == 2) {
+ if (hFrameDataLeft->coupling) {
+ FDKmemcpy(&hFrameDataRight->frameInfo, &hFrameDataLeft->frameInfo,
+ sizeof(FRAME_INFO));
+ hFrameDataRight->ampResolutionCurrentFrame =
+ hFrameDataLeft->ampResolutionCurrentFrame;
+ } else {
+ if (!extractFrameInfo(hBs, hHeaderData, hFrameDataRight, 2, flags))
+ return 0;
+
+ if (!checkFrameInfo(&hFrameDataRight->frameInfo,
+ hHeaderData->numberTimeSlots, overlap,
+ hHeaderData->timeStep))
+ return 0;
+ }
+ }
+
+ /*
+ sbr_dtdf(): Fetch domain vectors (time or frequency direction for
+ delta-coding)
+ */
+ sbrGetDirectionControlData(hFrameDataLeft, hBs, flags,
+ hHeaderData->bs_info.pvc_mode);
+ if (nCh == 2) {
+ sbrGetDirectionControlData(hFrameDataRight, hBs, flags, 0);
+ }
+
+ /* sbr_invf() */
+ for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) {
+ hFrameDataLeft->sbr_invf_mode[i] = (INVF_MODE)FDKreadBits(hBs, 2);
+ }
+ if (nCh == 2) {
+ if (hFrameDataLeft->coupling) {
+ for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) {
+ hFrameDataRight->sbr_invf_mode[i] = hFrameDataLeft->sbr_invf_mode[i];
+ }
+ } else {
+ for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) {
+ hFrameDataRight->sbr_invf_mode[i] = (INVF_MODE)FDKreadBits(hBs, 2);
+ }
+ }
+ }
+
+ if (nCh == 1) {
+ if (hHeaderData->bs_info.pvc_mode) {
+ if (!sbrGetPvcEnvelope(hHeaderData, hFrameDataLeft, hBs, flags,
+ hHeaderData->bs_info.pvc_mode))
+ return 0;
+ } else if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags))
+ return 0;
+
+ sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs);
+ } else if (hFrameDataLeft->coupling) {
+ if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) {
+ return 0;
+ }
+
+ sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs);
+
+ if (!sbrGetEnvelope(hHeaderData, hFrameDataRight, hBs, flags)) {
+ return 0;
+ }
+ sbrGetNoiseFloorData(hHeaderData, hFrameDataRight, hBs);
+ } else { /* nCh == 2 && no coupling */
+
+ if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) return 0;
+
+ if (!sbrGetEnvelope(hHeaderData, hFrameDataRight, hBs, flags)) return 0;
+
+ sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs);
+
+ sbrGetNoiseFloorData(hHeaderData, hFrameDataRight, hBs);
+ }
+
+ sbrGetSyntheticCodedData(hHeaderData, hFrameDataLeft, hBs, flags);
+ if (nCh == 2) {
+ sbrGetSyntheticCodedData(hHeaderData, hFrameDataRight, hBs, flags);
+ }
+
+ if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) {
+ if (!extractExtendedData(hHeaderData, hBs, hParametricStereoDec)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*!
+ \brief Read direction control data from bitstream
+*/
+void sbrGetDirectionControlData(
+ HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to struct BIT_BUF */
+ const UINT flags, const int bs_pvc_mode)
+
+{
+ int i;
+ int indepFlag = 0;
+
+ if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) {
+ indepFlag = flags & SBRDEC_USAC_INDEP;
+ }
+
+ if (bs_pvc_mode == 0) {
+ i = 0;
+ if (indepFlag) {
+ h_frame_data->domain_vec[i++] = 0;
+ }
+ for (; i < h_frame_data->frameInfo.nEnvelopes; i++) {
+ h_frame_data->domain_vec[i] = FDKreadBits(hBs, 1);
+ }
+ }
+
+ i = 0;
+ if (indepFlag) {
+ h_frame_data->domain_vec_noise[i++] = 0;
+ }
+ for (; i < h_frame_data->frameInfo.nNoiseEnvelopes; i++) {
+ h_frame_data->domain_vec_noise[i] = FDKreadBits(hBs, 1);
+ }
+}
+
+/*!
+ \brief Read noise-floor-level data from bitstream
+*/
+void sbrGetNoiseFloorData(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */
+ HANDLE_FDK_BITSTREAM hBs) /*!< handle to struct BIT_BUF */
+{
+ int i, j;
+ int delta;
+ COUPLING_MODE coupling;
+ int noNoiseBands = hHeaderData->freqBandData.nNfb;
+
+ Huffman hcb_noiseF;
+ Huffman hcb_noise;
+ int envDataTableCompFactor;
+
+ coupling = h_frame_data->coupling;
+
+ /*
+ Select huffman codebook depending on coupling mode
+ */
+ if (coupling == COUPLING_BAL) {
+ hcb_noise = (Huffman)&FDK_sbrDecoder_sbr_huffBook_NoiseBalance11T;
+ hcb_noiseF =
+ (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11F; /* "sbr_huffBook_NoiseBalance11F"
+ */
+ envDataTableCompFactor = 1;
+ } else {
+ hcb_noise = (Huffman)&FDK_sbrDecoder_sbr_huffBook_NoiseLevel11T;
+ hcb_noiseF =
+ (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11F; /* "sbr_huffBook_NoiseLevel11F"
+ */
+ envDataTableCompFactor = 0;
+ }
+
+ /*
+ Read raw noise-envelope data
+ */
+ for (i = 0; i < h_frame_data->frameInfo.nNoiseEnvelopes; i++) {
+ if (h_frame_data->domain_vec_noise[i] == 0) {
+ if (coupling == COUPLING_BAL) {
+ h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands] =
+ (FIXP_SGL)(((int)FDKreadBits(hBs, 5)) << envDataTableCompFactor);
+ } else {
+ h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands] =
+ (FIXP_SGL)(int)FDKreadBits(hBs, 5);
+ }
+
+ for (j = 1; j < noNoiseBands; j++) {
+ delta = DecodeHuffmanCW(hcb_noiseF, hBs);
+ h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands + j] =
+ (FIXP_SGL)(delta << envDataTableCompFactor);
+ }
+ } else {
+ for (j = 0; j < noNoiseBands; j++) {
+ delta = DecodeHuffmanCW(hcb_noise, hBs);
+ h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands + j] =
+ (FIXP_SGL)(delta << envDataTableCompFactor);
+ }
+ }
+ }
+}
+
+/* ns = mapNsMode2ns[pvcMode-1][nsMode] */
+static const UCHAR mapNsMode2ns[2][2] = {
+ {16, 4}, /* pvcMode = 1 */
+ {12, 3} /* pvcMode = 2 */
+};
+
+static int sbrGetPvcEnvelope(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to struct BIT_BUF */
+ const UINT flags, const UINT pvcMode) {
+ int divMode, nsMode;
+ int indepFlag = flags & SBRDEC_USAC_INDEP;
+ UCHAR *pvcID = h_frame_data->pvcID;
+
+ divMode = FDKreadBits(hBs, PVC_DIVMODE_BITS);
+ nsMode = FDKreadBit(hBs);
+ FDK_ASSERT((pvcMode == 1) || (pvcMode == 2));
+ h_frame_data->ns = mapNsMode2ns[pvcMode - 1][nsMode];
+
+ if (divMode <= 3) {
+ int i, k = 1, sum_length = 0, reuse_pcvID;
+
+ /* special treatment for first time slot k=0 */
+ indepFlag ? (reuse_pcvID = 0) : (reuse_pcvID = FDKreadBit(hBs));
+ if (reuse_pcvID) {
+ pvcID[0] = hHeaderData->pvcIDprev;
+ } else {
+ pvcID[0] = FDKreadBits(hBs, PVC_PVCID_BITS);
+ }
+
+ /* other time slots k>0 */
+ for (i = 0; i < divMode; i++) {
+ int length, numBits = 4;
+
+ if (sum_length >= 13) {
+ numBits = 1;
+ } else if (sum_length >= 11) {
+ numBits = 2;
+ } else if (sum_length >= 7) {
+ numBits = 3;
+ }
+
+ length = FDKreadBits(hBs, numBits);
+ sum_length += length + 1;
+ if (sum_length >= PVC_NTIMESLOT) {
+ return 0; /* parse error */
+ }
+ for (; length--; k++) {
+ pvcID[k] = pvcID[k - 1];
+ }
+ pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS);
+ }
+ for (; k < 16; k++) {
+ pvcID[k] = pvcID[k - 1];
+ }
+ } else { /* divMode >= 4 */
+ int num_grid_info, fixed_length, grid_info, j, k = 0;
+
+ divMode -= 4;
+ num_grid_info = 2 << divMode;
+ fixed_length = 8 >> divMode;
+ FDK_ASSERT(num_grid_info * fixed_length == PVC_NTIMESLOT);
+
+ /* special treatment for first time slot k=0 */
+ indepFlag ? (grid_info = 1) : (grid_info = FDKreadBit(hBs));
+ if (grid_info) {
+ pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS);
+ } else {
+ pvcID[k++] = hHeaderData->pvcIDprev;
+ }
+ j = fixed_length - 1;
+ for (; j--; k++) {
+ pvcID[k] = pvcID[k - 1];
+ }
+ num_grid_info--;
+
+ /* other time slots k>0 */
+ for (; num_grid_info--;) {
+ j = fixed_length;
+ grid_info = FDKreadBit(hBs);
+ if (grid_info) {
+ pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS);
+ j--;
+ }
+ for (; j--; k++) {
+ pvcID[k] = pvcID[k - 1];
+ }
+ }
+ }
+
+ hHeaderData->pvcIDprev = pvcID[PVC_NTIMESLOT - 1];
+
+ /* usage of PVC excludes inter-TES tool */
+ h_frame_data->iTESactive = (UCHAR)0;
+
+ return 1;
+}
+/*!
+ \brief Read envelope data from bitstream
+*/
+static int sbrGetEnvelope(
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to struct BIT_BUF */
+ const UINT flags) {
+ int i, j;
+ UCHAR no_band[MAX_ENVELOPES];
+ int delta = 0;
+ int offset = 0;
+ COUPLING_MODE coupling = h_frame_data->coupling;
+ int ampRes = hHeaderData->bs_info.ampResolution;
+ int nEnvelopes = h_frame_data->frameInfo.nEnvelopes;
+ int envDataTableCompFactor;
+ int start_bits, start_bits_balance;
+ Huffman hcb_t, hcb_f;
+
+ h_frame_data->nScaleFactors = 0;
+
+ if ((h_frame_data->frameInfo.frameClass == 0) && (nEnvelopes == 1)) {
+ if (flags & SBRDEC_ELD_GRID)
+ ampRes = h_frame_data->ampResolutionCurrentFrame;
+ else
+ ampRes = 0;
+ }
+ h_frame_data->ampResolutionCurrentFrame = ampRes;
+
+ /*
+ Set number of bits for first value depending on amplitude resolution
+ */
+ if (ampRes == 1) {
+ start_bits = 6;
+ start_bits_balance = 5;
+ } else {
+ start_bits = 7;
+ start_bits_balance = 6;
+ }
+
+ /*
+ Calculate number of values for each envelope and alltogether
+ */
+ for (i = 0; i < nEnvelopes; i++) {
+ no_band[i] =
+ hHeaderData->freqBandData.nSfb[h_frame_data->frameInfo.freqRes[i]];
+ h_frame_data->nScaleFactors += no_band[i];
+ }
+ if (h_frame_data->nScaleFactors > MAX_NUM_ENVELOPE_VALUES) return 0;
+
+ /*
+ Select Huffman codebook depending on coupling mode and amplitude resolution
+ */
+ if (coupling == COUPLING_BAL) {
+ envDataTableCompFactor = 1;
+ if (ampRes == 0) {
+ hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance10T;
+ hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance10F;
+ } else {
+ hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11T;
+ hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11F;
+ }
+ } else {
+ envDataTableCompFactor = 0;
+ if (ampRes == 0) {
+ hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel10T;
+ hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel10F;
+ } else {
+ hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11T;
+ hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11F;
+ }
+ }
+
+ h_frame_data->iTESactive = (UCHAR)0; /* disable inter-TES by default */
+ /*
+ Now read raw envelope data
+ */
+ for (j = 0, offset = 0; j < nEnvelopes; j++) {
+ if (h_frame_data->domain_vec[j] == 0) {
+ if (coupling == COUPLING_BAL) {
+ h_frame_data->iEnvelope[offset] =
+ (FIXP_SGL)(((int)FDKreadBits(hBs, start_bits_balance))
+ << envDataTableCompFactor);
+ } else {
+ h_frame_data->iEnvelope[offset] =
+ (FIXP_SGL)(int)FDKreadBits(hBs, start_bits);
+ }
+ }
+
+ for (i = (1 - h_frame_data->domain_vec[j]); i < no_band[j]; i++) {
+ if (h_frame_data->domain_vec[j] == 0) {
+ delta = DecodeHuffmanCW(hcb_f, hBs);
+ } else {
+ delta = DecodeHuffmanCW(hcb_t, hBs);
+ }
+
+ h_frame_data->iEnvelope[offset + i] =
+ (FIXP_SGL)(delta << envDataTableCompFactor);
+ }
+ if ((flags & SBRDEC_SYNTAX_USAC) && (flags & SBRDEC_USAC_ITES)) {
+ int bs_temp_shape = FDKreadBit(hBs);
+ FDK_ASSERT(j < 8);
+ h_frame_data->iTESactive |= (UCHAR)(bs_temp_shape << j);
+ if (bs_temp_shape) {
+ h_frame_data->interTempShapeMode[j] =
+ FDKread2Bits(hBs); /* bs_inter_temp_shape_mode */
+ } else {
+ h_frame_data->interTempShapeMode[j] = 0;
+ }
+ }
+ offset += no_band[j];
+ }
+
+#if ENV_EXP_FRACT
+ /* Convert from int to scaled fract (ENV_EXP_FRACT bits for the fractional
+ * part) */
+ for (i = 0; i < h_frame_data->nScaleFactors; i++) {
+ h_frame_data->iEnvelope[i] <<= ENV_EXP_FRACT;
+ }
+#endif
+
+ return 1;
+}
+
+/***************************************************************************/
+/*!
+ \brief Generates frame info for FIXFIXonly frame class used for low delay
+ version
+
+ \return zero for error, one for correct.
+ ****************************************************************************/
+static int generateFixFixOnly(FRAME_INFO *hSbrFrameInfo, int tranPosInternal,
+ int numberTimeSlots, const UINT flags) {
+ int nEnv, i, tranIdx;
+ const int *pTable;
+
+ switch (numberTimeSlots) {
+ case 8:
+ pTable = FDK_sbrDecoder_envelopeTable_8[tranPosInternal];
+ break;
+ case 15:
+ pTable = FDK_sbrDecoder_envelopeTable_15[tranPosInternal];
+ break;
+ case 16:
+ pTable = FDK_sbrDecoder_envelopeTable_16[tranPosInternal];
+ break;
+ default:
+ return 0;
+ }
+
+ /* look number of envelopes in table */
+ nEnv = pTable[0];
+ /* look up envelope distribution in table */
+ for (i = 1; i < nEnv; i++) hSbrFrameInfo->borders[i] = pTable[i + 2];
+ /* open and close frame border */
+ hSbrFrameInfo->borders[0] = 0;
+ hSbrFrameInfo->borders[nEnv] = numberTimeSlots;
+ hSbrFrameInfo->nEnvelopes = nEnv;
+
+ /* transient idx */
+ tranIdx = hSbrFrameInfo->tranEnv = pTable[1];
+
+ /* add noise floors */
+ hSbrFrameInfo->bordersNoise[0] = 0;
+ hSbrFrameInfo->bordersNoise[1] =
+ hSbrFrameInfo->borders[tranIdx ? tranIdx : 1];
+ hSbrFrameInfo->bordersNoise[2] = numberTimeSlots;
+ /* nEnv is always > 1, so nNoiseEnvelopes is always 2 (IEC 14496-3 4.6.19.3.2)
+ */
+ hSbrFrameInfo->nNoiseEnvelopes = 2;
+
+ return 1;
+}
+
+/*!
+ \brief Extracts LowDelaySBR control data from the bitstream.
+
+ \return zero for bitstream error, one for correct.
+*/
+static int extractLowDelayGrid(
+ HANDLE_FDK_BITSTREAM hBitBuf, /*!< bitbuffer handle */
+ HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA
+ h_frame_data, /*!< contains the FRAME_INFO struct to be filled */
+ int timeSlots, const UINT flags) {
+ FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo;
+ INT numberTimeSlots = hHeaderData->numberTimeSlots;
+ INT temp = 0, k;
+
+ /* FIXFIXonly framing case */
+ h_frame_data->frameInfo.frameClass = 0;
+
+ /* get the transient position from the bitstream */
+ switch (timeSlots) {
+ case 8:
+ /* 3bit transient position (temp={0;..;7}) */
+ temp = FDKreadBits(hBitBuf, 3);
+ break;
+
+ case 16:
+ case 15:
+ /* 4bit transient position (temp={0;..;15}) */
+ temp = FDKreadBits(hBitBuf, 4);
+ break;
+
+ default:
+ return 0;
+ }
+
+ /* For "case 15" only*/
+ if (temp >= timeSlots) {
+ return 0;
+ }
+
+ /* calculate borders according to the transient position */
+ if (!generateFixFixOnly(pFrameInfo, temp, numberTimeSlots, flags)) {
+ return 0;
+ }
+
+ /* decode freq res: */
+ for (k = 0; k < pFrameInfo->nEnvelopes; k++) {
+ pFrameInfo->freqRes[k] =
+ (UCHAR)FDKreadBits(hBitBuf, 1); /* f = F [1 bits] */
+ }
+
+ return 1;
+}
+
+/*!
+ \brief Extract the PVC frame information (structure FRAME_INFO) from the
+ bitstream \return Zero for bitstream error, one for correct.
+*/
+int extractPvcFrameInfo(
+ HANDLE_FDK_BITSTREAM hBs, /*!< bitbuffer handle */
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the
+ frame-info will be stored */
+ HANDLE_SBR_PREV_FRAME_DATA h_prev_frame_data, /*!< pointer to memory where
+ the previous frame-info
+ will be stored */
+ UCHAR pvc_mode_last, /**< PVC mode of last frame */
+ const UINT flags) {
+ FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo;
+ FRAME_INFO *pPrevFrameInfo = &h_prev_frame_data->prevFrameInfo;
+ int bs_var_len_hf, bs_noise_position;
+ bs_noise_position = FDKreadBits(hBs, 4); /* SBR_PVC_NOISEPOSITION_BITS 4 */
+ bs_var_len_hf = FDKreadBit(hBs);
+ pFrameInfo->noisePosition = bs_noise_position;
+ pFrameInfo->tranEnv = -1;
+
+ /* Init for bs_noise_position == 0 in case a parse error is found below. */
+ pFrameInfo->nEnvelopes = 1;
+ pFrameInfo->nNoiseEnvelopes = 1;
+ pFrameInfo->freqRes[0] = 0;
+
+ if (bs_var_len_hf) { /* 1 or 3 Bits */
+ pFrameInfo->varLength = FDKreadBits(hBs, 2) + 1;
+ if (pFrameInfo->varLength > 3) {
+ pFrameInfo->varLength =
+ 0; /* assume bs_var_len_hf == 0 in case of error */
+ return 0; /* reserved value -> parse error */
+ }
+ } else {
+ pFrameInfo->varLength = 0;
+ }
+
+ if (bs_noise_position) {
+ pFrameInfo->nEnvelopes = 2;
+ pFrameInfo->nNoiseEnvelopes = 2;
+ FDKmemclear(pFrameInfo->freqRes, sizeof(pFrameInfo->freqRes));
+ }
+
+ /* frame border calculation */
+ if (hHeaderData->bs_info.pvc_mode > 0) {
+ /* See "7.5.1.4 HF adjustment of SBR envelope scalefactors" for reference.
+ */
+
+ FDK_ASSERT((pFrameInfo->nEnvelopes == 1) || (pFrameInfo->nEnvelopes == 2));
+
+ /* left timeborder-offset: use the timeborder of prev SBR frame */
+ if (pPrevFrameInfo->nEnvelopes > 0) {
+ pFrameInfo->borders[0] =
+ pPrevFrameInfo->borders[pPrevFrameInfo->nEnvelopes] - PVC_NTIMESLOT;
+ FDK_ASSERT(pFrameInfo->borders[0] <= 3);
+ } else {
+ pFrameInfo->borders[0] = 0;
+ }
+
+ /* right timeborder-offset: */
+ pFrameInfo->borders[pFrameInfo->nEnvelopes] = 16 + pFrameInfo->varLength;
+
+ if (pFrameInfo->nEnvelopes == 2) {
+ pFrameInfo->borders[1] = pFrameInfo->noisePosition;
+ }
+
+ /* Calculation of PVC time borders t_EPVC */
+ if (pvc_mode_last == 0) {
+ /* there was a legacy SBR frame before this frame => use bs_var_len' for
+ * first PVC timeslot */
+ pFrameInfo->pvcBorders[0] = pFrameInfo->borders[0];
+ } else {
+ pFrameInfo->pvcBorders[0] = 0;
+ }
+ if (pFrameInfo->nEnvelopes == 2) {
+ pFrameInfo->pvcBorders[1] = pFrameInfo->borders[1];
+ }
+ pFrameInfo->pvcBorders[pFrameInfo->nEnvelopes] = 16;
+
+ /* calculation of SBR noise-floor time-border vector: */
+ for (INT i = 0; i <= pFrameInfo->nNoiseEnvelopes; i++) {
+ pFrameInfo->bordersNoise[i] = pFrameInfo->borders[i];
+ }
+
+ pFrameInfo->tranEnv = -1; /* tranEnv not used */
+ }
+ return 1;
+}
+
+/*!
+ \brief Extract the frame information (structure FRAME_INFO) from the
+ bitstream \return Zero for bitstream error, one for correct.
+*/
+int extractFrameInfo(
+ HANDLE_FDK_BITSTREAM hBs, /*!< bitbuffer handle */
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the
+ frame-info will be stored */
+ const UINT nrOfChannels, const UINT flags) {
+ FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo;
+ int numberTimeSlots = hHeaderData->numberTimeSlots;
+ int pointer_bits = 0, nEnv = 0, b = 0, border, i, n = 0, k, p, aL, aR, nL, nR,
+ temp = 0, staticFreqRes;
+ UCHAR frameClass;
+
+ if (flags & SBRDEC_ELD_GRID) {
+ /* CODEC_AACLD (LD+SBR) only uses the normal 0 Grid for non-transient Frames
+ * and the LowDelayGrid for transient Frames */
+ frameClass = FDKreadBits(hBs, 1); /* frameClass = [1 bit] */
+ if (frameClass == 1) {
+ /* if frameClass == 1, extract LowDelaySbrGrid, otherwise extract normal
+ * SBR-Grid for FIXIFX */
+ /* extract the AACLD-Sbr-Grid */
+ pFrameInfo->frameClass = frameClass;
+ int err = 1;
+ err = extractLowDelayGrid(hBs, hHeaderData, h_frame_data, numberTimeSlots,
+ flags);
+ return err;
+ }
+ } else {
+ frameClass = FDKreadBits(hBs, 2); /* frameClass = C [2 bits] */
+ }
+
+ switch (frameClass) {
+ case 0:
+ temp = FDKreadBits(hBs, 2); /* E [2 bits ] */
+ nEnv = (int)(1 << temp); /* E -> e */
+
+ if ((flags & SBRDEC_ELD_GRID) && (nEnv == 1))
+ h_frame_data->ampResolutionCurrentFrame =
+ FDKreadBits(hBs, 1); /* new ELD Syntax 07-11-09 */
+
+ staticFreqRes = FDKreadBits(hBs, 1);
+
+ if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) {
+ if (nEnv > MAX_ENVELOPES_USAC) return 0;
+ } else
+
+ b = nEnv + 1;
+ switch (nEnv) {
+ case 1:
+ switch (numberTimeSlots) {
+ case 15:
+ FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info1_15,
+ sizeof(FRAME_INFO));
+ break;
+ case 16:
+ FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info1_16,
+ sizeof(FRAME_INFO));
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+ break;
+ case 2:
+ switch (numberTimeSlots) {
+ case 15:
+ FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info2_15,
+ sizeof(FRAME_INFO));
+ break;
+ case 16:
+ FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info2_16,
+ sizeof(FRAME_INFO));
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+ break;
+ case 4:
+ switch (numberTimeSlots) {
+ case 15:
+ FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info4_15,
+ sizeof(FRAME_INFO));
+ break;
+ case 16:
+ FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info4_16,
+ sizeof(FRAME_INFO));
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+ break;
+ case 8:
+#if (MAX_ENVELOPES >= 8)
+ switch (numberTimeSlots) {
+ case 15:
+ FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info8_15,
+ sizeof(FRAME_INFO));
+ break;
+ case 16:
+ FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info8_16,
+ sizeof(FRAME_INFO));
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+ break;
+#else
+ return 0;
+#endif
+ }
+ /* Apply correct freqRes (High is default) */
+ if (!staticFreqRes) {
+ for (i = 0; i < nEnv; i++) pFrameInfo->freqRes[i] = 0;
+ }
+
+ break;
+ case 1:
+ case 2:
+ temp = FDKreadBits(hBs, 2); /* A [2 bits] */
+
+ n = FDKreadBits(hBs, 2); /* n = N [2 bits] */
+
+ nEnv = n + 1; /* # envelopes */
+ b = nEnv + 1; /* # borders */
+
+ break;
+ }
+
+ switch (frameClass) {
+ case 1:
+ /* Decode borders: */
+ pFrameInfo->borders[0] = 0; /* first border */
+ border = temp + numberTimeSlots; /* A -> aR */
+ i = b - 1; /* frame info index for last border */
+ pFrameInfo->borders[i] = border; /* last border */
+
+ for (k = 0; k < n; k++) {
+ temp = FDKreadBits(hBs, 2); /* R [2 bits] */
+ border -= (2 * temp + 2); /* R -> r */
+ pFrameInfo->borders[--i] = border;
+ }
+
+ /* Decode pointer: */
+ pointer_bits = DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(n + 1));
+ p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */
+
+ if (p > n + 1) return 0;
+
+ pFrameInfo->tranEnv = p ? n + 2 - p : -1;
+
+ /* Decode freq res: */
+ for (k = n; k >= 0; k--) {
+ pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */
+ }
+
+ /* Calculate noise floor middle border: */
+ if (p == 0 || p == 1)
+ pFrameInfo->bordersNoise[1] = pFrameInfo->borders[n];
+ else
+ pFrameInfo->bordersNoise[1] = pFrameInfo->borders[pFrameInfo->tranEnv];
+
+ break;
+
+ case 2:
+ /* Decode borders: */
+ border = temp; /* A -> aL */
+ pFrameInfo->borders[0] = border; /* first border */
+
+ for (k = 1; k <= n; k++) {
+ temp = FDKreadBits(hBs, 2); /* R [2 bits] */
+ border += (2 * temp + 2); /* R -> r */
+ pFrameInfo->borders[k] = border;
+ }
+ pFrameInfo->borders[k] = numberTimeSlots; /* last border */
+
+ /* Decode pointer: */
+ pointer_bits = DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(n + 1));
+ p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */
+ if (p > n + 1) return 0;
+
+ if (p == 0 || p == 1)
+ pFrameInfo->tranEnv = -1;
+ else
+ pFrameInfo->tranEnv = p - 1;
+
+ /* Decode freq res: */
+ for (k = 0; k <= n; k++) {
+ pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */
+ }
+
+ /* Calculate noise floor middle border: */
+ switch (p) {
+ case 0:
+ pFrameInfo->bordersNoise[1] = pFrameInfo->borders[1];
+ break;
+ case 1:
+ pFrameInfo->bordersNoise[1] = pFrameInfo->borders[n];
+ break;
+ default:
+ pFrameInfo->bordersNoise[1] =
+ pFrameInfo->borders[pFrameInfo->tranEnv];
+ break;
+ }
+
+ break;
+
+ case 3:
+ /* v_ctrlSignal = [frameClass,aL,aR,nL,nR,v_rL,v_rR,p,v_fLR]; */
+
+ aL = FDKreadBits(hBs, 2); /* AL [2 bits], AL -> aL */
+
+ aR = FDKreadBits(hBs, 2) + numberTimeSlots; /* AR [2 bits], AR -> aR */
+
+ nL = FDKreadBits(hBs, 2); /* nL = NL [2 bits] */
+
+ nR = FDKreadBits(hBs, 2); /* nR = NR [2 bits] */
+
+ /*-------------------------------------------------------------------------
+ Calculate help variables
+ --------------------------------------------------------------------------*/
+
+ /* general: */
+ nEnv = nL + nR + 1; /* # envelopes */
+ if (nEnv > MAX_ENVELOPES) return 0;
+ b = nEnv + 1; /* # borders */
+
+ /*-------------------------------------------------------------------------
+ Decode envelopes
+ --------------------------------------------------------------------------*/
+
+ /* L-borders: */
+ border = aL; /* first border */
+ pFrameInfo->borders[0] = border;
+
+ for (k = 1; k <= nL; k++) {
+ temp = FDKreadBits(hBs, 2); /* R [2 bits] */
+ border += (2 * temp + 2); /* R -> r */
+ pFrameInfo->borders[k] = border;
+ }
+
+ /* R-borders: */
+ border = aR; /* last border */
+ i = nEnv;
+
+ pFrameInfo->borders[i] = border;
+
+ for (k = 0; k < nR; k++) {
+ temp = FDKreadBits(hBs, 2); /* R [2 bits] */
+ border -= (2 * temp + 2); /* R -> r */
+ pFrameInfo->borders[--i] = border;
+ }
+
+ /* decode pointer: */
+ pointer_bits =
+ DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(nL + nR + 1));
+ p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */
+
+ if (p > nL + nR + 1) return 0;
+
+ pFrameInfo->tranEnv = p ? b - p : -1;
+
+ /* decode freq res: */
+ for (k = 0; k < nEnv; k++) {
+ pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */
+ }
+
+ /*-------------------------------------------------------------------------
+ Decode noise floors
+ --------------------------------------------------------------------------*/
+ pFrameInfo->bordersNoise[0] = aL;
+
+ if (nEnv == 1) {
+ /* 1 noise floor envelope: */
+ pFrameInfo->bordersNoise[1] = aR;
+ } else {
+ /* 2 noise floor envelopes */
+ if (p == 0 || p == 1)
+ pFrameInfo->bordersNoise[1] = pFrameInfo->borders[nEnv - 1];
+ else
+ pFrameInfo->bordersNoise[1] =
+ pFrameInfo->borders[pFrameInfo->tranEnv];
+ pFrameInfo->bordersNoise[2] = aR;
+ }
+ break;
+ }
+
+ /*
+ Store number of envelopes, noise floor envelopes and frame class
+ */
+ pFrameInfo->nEnvelopes = nEnv;
+
+ if (nEnv == 1)
+ pFrameInfo->nNoiseEnvelopes = 1;
+ else
+ pFrameInfo->nNoiseEnvelopes = 2;
+
+ pFrameInfo->frameClass = frameClass;
+
+ if (pFrameInfo->frameClass == 2 || pFrameInfo->frameClass == 1) {
+ /* calculate noise floor first and last borders: */
+ pFrameInfo->bordersNoise[0] = pFrameInfo->borders[0];
+ pFrameInfo->bordersNoise[pFrameInfo->nNoiseEnvelopes] =
+ pFrameInfo->borders[nEnv];
+ }
+
+ return 1;
+}
+
+/*!
+ \brief Check if the frameInfo vector has reasonable values.
+ \return Zero for error, one for correct
+*/
+static int checkFrameInfo(
+ FRAME_INFO *pFrameInfo, /*!< pointer to frameInfo */
+ int numberOfTimeSlots, /*!< QMF time slots per frame */
+ int overlap, /*!< Amount of overlap QMF time slots */
+ int timeStep) /*!< QMF slots to SBR slots step factor */
+{
+ int maxPos, i, j;
+ int startPos;
+ int stopPos;
+ int tranEnv;
+ int startPosNoise;
+ int stopPosNoise;
+ int nEnvelopes = pFrameInfo->nEnvelopes;
+ int nNoiseEnvelopes = pFrameInfo->nNoiseEnvelopes;
+
+ if (nEnvelopes < 1 || nEnvelopes > MAX_ENVELOPES) return 0;
+
+ if (nNoiseEnvelopes > MAX_NOISE_ENVELOPES) return 0;
+
+ startPos = pFrameInfo->borders[0];
+ stopPos = pFrameInfo->borders[nEnvelopes];
+ tranEnv = pFrameInfo->tranEnv;
+ startPosNoise = pFrameInfo->bordersNoise[0];
+ stopPosNoise = pFrameInfo->bordersNoise[nNoiseEnvelopes];
+
+ if (overlap < 0 || overlap > (3 * (4))) {
+ return 0;
+ }
+ if (timeStep < 1 || timeStep > (4)) {
+ return 0;
+ }
+ maxPos = numberOfTimeSlots + (overlap / timeStep);
+
+ /* Check that the start and stop positions of the frame are reasonable values.
+ */
+ if ((startPos < 0) || (startPos >= stopPos)) return 0;
+ if (startPos > maxPos - numberOfTimeSlots) /* First env. must start in or
+ directly after the overlap
+ buffer */
+ return 0;
+ if (stopPos < numberOfTimeSlots) /* One complete frame must be ready for
+ output after processing */
+ return 0;
+ if (stopPos > maxPos) return 0;
+
+ /* Check that the start border for every envelope is strictly later in time
+ */
+ for (i = 0; i < nEnvelopes; i++) {
+ if (pFrameInfo->borders[i] >= pFrameInfo->borders[i + 1]) return 0;
+ }
+
+ /* Check that the envelope to be shortened is actually among the envelopes */
+ if (tranEnv > nEnvelopes) return 0;
+
+ /* Check the noise borders */
+ if (nEnvelopes == 1 && nNoiseEnvelopes > 1) return 0;
+
+ if (startPos != startPosNoise || stopPos != stopPosNoise) return 0;
+
+ /* Check that the start border for every noise-envelope is strictly later in
+ * time*/
+ for (i = 0; i < nNoiseEnvelopes; i++) {
+ if (pFrameInfo->bordersNoise[i] >= pFrameInfo->bordersNoise[i + 1])
+ return 0;
+ }
+
+ /* Check that every noise border is the same as an envelope border*/
+ for (i = 0; i < nNoiseEnvelopes; i++) {
+ startPosNoise = pFrameInfo->bordersNoise[i];
+
+ for (j = 0; j < nEnvelopes; j++) {
+ if (pFrameInfo->borders[j] == startPosNoise) break;
+ }
+ if (j == nEnvelopes) return 0;
+ }
+
+ return 1;
+}
diff --git a/fdk-aac/libSBRdec/src/env_extr.h b/fdk-aac/libSBRdec/src/env_extr.h
new file mode 100644
index 0000000..38c04a3
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/env_extr.h
@@ -0,0 +1,415 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Envelope extraction prototypes
+*/
+
+#ifndef ENV_EXTR_H
+#define ENV_EXTR_H
+
+#include "sbrdecoder.h"
+
+#include "FDK_bitstream.h"
+#include "lpp_tran.h"
+
+#include "psdec.h"
+#include "pvc_dec.h"
+
+#define ENV_EXP_FRACT 0
+/*!< Shift raw envelope data to support fractional numbers.
+ Can be set to 8 instead of 0 to enhance accuracy during concealment.
+ This is not required for conformance and #requantizeEnvelopeData() will
+ become more expensive.
+*/
+
+#define EXP_BITS 6
+/*!< Size of exponent-part of a pseudo float envelope value (should be at least
+ 6). The remaining bits in each word are used for the mantissa (should be at
+ least 10). This format is used in the arrays iEnvelope[] and
+ sbrNoiseFloorLevel[] in the FRAME_DATA struct which must fit in a certain part
+ of the output buffer (See buffer management in sbr_dec.cpp). Exponents and
+ mantissas could also be stored in separate arrays. Accessing the exponent or
+ the mantissa would be simplified and the masks #MASK_E resp. #MASK_M would
+ no longer be required.
+*/
+
+#define MASK_M \
+ (((1 << (FRACT_BITS - EXP_BITS)) - 1) \
+ << EXP_BITS) /*!< Mask for extracting the mantissa of a pseudo float \
+ envelope value */
+#define MASK_E \
+ ((1 << EXP_BITS) - 1) /*!< Mask for extracting the exponent of a pseudo \
+ float envelope value */
+
+#define SIGN_EXT \
+ (((SCHAR)-1) ^ \
+ MASK_E) /*!< a CHAR-constant with all bits above our sign-bit set */
+#define ROUNDING \
+ ((FIXP_SGL)( \
+ 1 << (EXP_BITS - 1))) /*!< 0.5-offset for rounding the mantissa of a \
+ pseudo-float envelope value */
+#define NRG_EXP_OFFSET \
+ 16 /*!< Will be added to the reference energy's exponent to prevent negative \
+ numbers */
+#define NOISE_EXP_OFFSET \
+ 38 /*!< Will be added to the noise level exponent to prevent negative \
+ numbers */
+
+#define ADD_HARMONICS_FLAGS_SIZE 2 /* ceil(MAX_FREQ_COEFFS/32) */
+
+typedef enum {
+ HEADER_NOT_PRESENT,
+ HEADER_ERROR,
+ HEADER_OK,
+ HEADER_RESET
+} SBR_HEADER_STATUS;
+
+typedef enum {
+ SBR_NOT_INITIALIZED = 0,
+ UPSAMPLING = 1,
+ SBR_HEADER = 2,
+ SBR_ACTIVE = 3
+} SBR_SYNC_STATE;
+
+typedef enum { COUPLING_OFF = 0, COUPLING_LEVEL, COUPLING_BAL } COUPLING_MODE;
+
+typedef struct {
+ UCHAR nSfb[2]; /*!< Number of SBR-bands for low and high freq-resolution */
+ UCHAR nNfb; /*!< Actual number of noise bands to read from the bitstream*/
+ UCHAR numMaster; /*!< Number of SBR-bands in v_k_master */
+ UCHAR lowSubband; /*!< QMF-band where SBR frequency range starts */
+ UCHAR highSubband; /*!< QMF-band where SBR frequency range ends */
+ UCHAR ov_highSubband; /*!< if headerchange applies this value holds the old
+ highband value -> highband value of overlap area;
+ required for overlap in usac when headerchange
+ occurs between XVAR and VARX frame */
+ UCHAR limiterBandTable[MAX_NUM_LIMITERS + 1]; /*!< Limiter band table. */
+ UCHAR noLimiterBands; /*!< Number of limiter bands. */
+ UCHAR nInvfBands; /*!< Number of bands for inverse filtering */
+ UCHAR
+ *freqBandTable[2]; /*!< Pointers to freqBandTableLo and freqBandTableHi */
+ UCHAR freqBandTableLo[MAX_FREQ_COEFFS / 2 + 1];
+ /*!< Mapping of SBR bands to QMF bands for low frequency resolution */
+ UCHAR freqBandTableHi[MAX_FREQ_COEFFS + 1];
+ /*!< Mapping of SBR bands to QMF bands for high frequency resolution */
+ UCHAR freqBandTableNoise[MAX_NOISE_COEFFS + 1];
+ /*!< Mapping of SBR noise bands to QMF bands */
+ UCHAR v_k_master[MAX_FREQ_COEFFS + 1];
+ /*!< Master BandTable which freqBandTable is derived from */
+} FREQ_BAND_DATA;
+
+typedef FREQ_BAND_DATA *HANDLE_FREQ_BAND_DATA;
+
+#define SBRDEC_ELD_GRID 1
+#define SBRDEC_SYNTAX_SCAL 2
+#define SBRDEC_SYNTAX_USAC 4
+#define SBRDEC_SYNTAX_RSVD50 8
+#define SBRDEC_USAC_INDEP \
+ 16 /* Flag indicating that USAC global independency flag is active. */
+#define SBRDEC_LOW_POWER \
+ 32 /* Flag indicating that Low Power QMF mode shall be used. */
+#define SBRDEC_PS_DECODED \
+ 64 /* Flag indicating that PS was decoded and rendered. */
+#define SBRDEC_QUAD_RATE \
+ 128 /* Flag indicating that USAC SBR 4:1 is active. \
+ */
+#define SBRDEC_USAC_HARMONICSBR \
+ 256 /* Flag indicating that USAC HBE tool is active. */
+#define SBRDEC_LD_MPS_QMF \
+ 512 /* Flag indicating that the LD-MPS QMF shall be used. */
+#define SBRDEC_USAC_ITES \
+ 1024 /* Flag indicating that USAC inter TES tool is active. */
+#define SBRDEC_SYNTAX_DRM \
+ 2048 /* Flag indicating that DRM30/DRM+ reverse syntax is being used. */
+#define SBRDEC_ELD_DOWNSCALE \
+ 4096 /* Flag indicating that ELD downscaled mode decoding 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_FORCE_RESET \
+ 32768 /* Flag is used to force a reset of all elements in use. */
+#define SBRDEC_SKIP_QMF_ANA \
+ (1 << 21) /* Flag indicating that the input data is provided in the QMF \
+ domain. */
+#define SBRDEC_SKIP_QMF_SYN \
+ (1 << 22) /* Flag indicating that the output data is exported in the QMF \
+ domain. */
+
+#define SBRDEC_HDR_STAT_RESET 1
+#define SBRDEC_HDR_STAT_UPDATE 2
+
+typedef struct {
+ UCHAR ampResolution; /*!< Amplitude resolution of envelope values (0: 1.5dB,
+ 1: 3dB) */
+ UCHAR
+ xover_band; /*!< Start index in #v_k_master[] used for dynamic crossover
+ frequency */
+ UCHAR sbr_preprocessing; /*!< SBR prewhitening flag. */
+ UCHAR pvc_mode; /*!< Predictive vector coding mode */
+} SBR_HEADER_DATA_BS_INFO;
+
+typedef struct {
+ /* Changes in these variables causes a reset of the decoder */
+ UCHAR startFreq; /*!< Index for SBR start frequency */
+ UCHAR stopFreq; /*!< Index for SBR highest frequency */
+ UCHAR freqScale; /*!< 0: linear scale, 1-3 logarithmic scales */
+ UCHAR alterScale; /*!< Flag for coarser frequency resolution */
+ UCHAR noise_bands; /*!< Noise bands per octave, read from bitstream*/
+
+ /* don't require reset */
+ UCHAR limiterBands; /*!< Index for number of limiter bands per octave */
+ UCHAR limiterGains; /*!< Index to select gain limit */
+ UCHAR interpolFreq; /*!< Select gain calculation method (1: per QMF channel,
+ 0: per SBR band) */
+ UCHAR smoothingLength; /*!< Smoothing of gains over time (0: on 1: off) */
+
+} SBR_HEADER_DATA_BS;
+
+typedef struct {
+ SBR_SYNC_STATE
+ syncState; /*!< The current initialization status of the header */
+
+ UCHAR status; /*!< Flags field used for signaling a reset right before the
+ processing starts and an update from config (e.g. ASC). */
+ UCHAR
+ frameErrorFlag; /*!< Frame data valid flag. CAUTION: This variable will be
+ overwritten by the flag stored in the element
+ structure. This is necessary because of the frame
+ delay. There it might happen that different slots use
+ the same header. */
+ UCHAR numberTimeSlots; /*!< AAC: 16,15 */
+ UCHAR numberOfAnalysisBands; /*!< Number of QMF analysis bands */
+ UCHAR timeStep; /*!< Time resolution of SBR in QMF-slots */
+ UINT
+ sbrProcSmplRate; /*!< SBR processing sampling frequency (!=
+ OutputSamplingRate) (always: CoreSamplingRate *
+ UpSamplingFactor; even in single rate mode) */
+
+ SBR_HEADER_DATA_BS bs_data; /*!< current SBR header. */
+ SBR_HEADER_DATA_BS bs_dflt; /*!< Default sbr header. */
+ SBR_HEADER_DATA_BS_INFO bs_info; /*!< SBR info. */
+
+ FREQ_BAND_DATA freqBandData; /*!< Pointer to struct #FREQ_BAND_DATA */
+ UCHAR pvcIDprev;
+} SBR_HEADER_DATA;
+
+typedef SBR_HEADER_DATA *HANDLE_SBR_HEADER_DATA;
+
+typedef struct {
+ UCHAR frameClass; /*!< Select grid type */
+ UCHAR nEnvelopes; /*!< Number of envelopes */
+ UCHAR borders[MAX_ENVELOPES + 1]; /*!< Envelope borders (in SBR-timeslots,
+ e.g. mp3PRO: 0..11) */
+ UCHAR freqRes[MAX_ENVELOPES]; /*!< Frequency resolution for each envelope
+ (0=low, 1=high) */
+ SCHAR tranEnv; /*!< Transient envelope, -1 if none */
+ UCHAR nNoiseEnvelopes; /*!< Number of noise envelopes */
+ UCHAR
+ bordersNoise[MAX_NOISE_ENVELOPES + 1]; /*!< borders of noise envelopes */
+ UCHAR pvcBorders[MAX_PVC_ENVELOPES + 1];
+ UCHAR noisePosition;
+ UCHAR varLength;
+} FRAME_INFO;
+
+typedef struct {
+ FIXP_SGL sfb_nrg_prev[MAX_FREQ_COEFFS]; /*!< Previous envelope (required for
+ differential-coded values) */
+ FIXP_SGL
+ prevNoiseLevel[MAX_NOISE_COEFFS]; /*!< Previous noise envelope (required
+ for differential-coded values) */
+ COUPLING_MODE coupling; /*!< Stereo-mode of previous frame */
+ INVF_MODE sbr_invf_mode[MAX_INVF_BANDS]; /*!< Previous strength of filtering
+ in transposer */
+ UCHAR ampRes; /*!< Previous amplitude resolution (0: 1.5dB, 1: 3dB) */
+ UCHAR stopPos; /*!< Position in time where last envelope ended */
+ UCHAR frameErrorFlag; /*!< Previous frame status */
+ UCHAR prevSbrPitchInBins; /*!< Previous frame pitchInBins */
+ FRAME_INFO prevFrameInfo;
+} SBR_PREV_FRAME_DATA;
+
+typedef SBR_PREV_FRAME_DATA *HANDLE_SBR_PREV_FRAME_DATA;
+
+typedef struct {
+ int nScaleFactors; /*!< total number of scalefactors in frame */
+
+ FRAME_INFO frameInfo; /*!< time grid for current frame */
+ UCHAR domain_vec[MAX_ENVELOPES]; /*!< Bitfield containing direction of
+ delta-coding for each envelope
+ (0:frequency, 1:time) */
+ UCHAR domain_vec_noise
+ [MAX_NOISE_ENVELOPES]; /*!< Same as above, but for noise envelopes */
+
+ INVF_MODE
+ sbr_invf_mode[MAX_INVF_BANDS]; /*!< Strength of filtering in transposer */
+ COUPLING_MODE coupling; /*!< Stereo-mode */
+ int ampResolutionCurrentFrame; /*!< Amplitude resolution of envelope values
+ (0: 1.5dB, 1: 3dB) */
+
+ ULONG addHarmonics[ADD_HARMONICS_FLAGS_SIZE]; /*!< Flags for synthetic sine
+ addition (aligned to MSB) */
+
+ FIXP_SGL iEnvelope[MAX_NUM_ENVELOPE_VALUES]; /*!< Envelope data */
+ FIXP_SGL sbrNoiseFloorLevel[MAX_NUM_NOISE_VALUES]; /*!< Noise envelope data */
+ UCHAR iTESactive; /*!< One flag for each envelope to enable USAC inter-TES */
+ UCHAR
+ interTempShapeMode[MAX_ENVELOPES]; /*!< USAC inter-TES:
+ bs_inter_temp_shape_mode[ch][env]
+ value */
+ UCHAR pvcID[PVC_NTIMESLOT]; /*!< One PVC ID value for each time slot */
+ UCHAR ns;
+ UCHAR sinusoidal_position;
+
+ UCHAR sbrPatchingMode;
+ UCHAR sbrOversamplingFlag;
+ UCHAR sbrPitchInBins;
+} SBR_FRAME_DATA;
+
+typedef SBR_FRAME_DATA *HANDLE_SBR_FRAME_DATA;
+
+/*!
+\brief Maps sampling frequencies to frequencies for which setup tables are
+available
+
+Maps arbitary sampling frequency to nearest neighbors for which setup tables
+are available (e.g. 25600 -> 24000).
+Used for startFreq calculation.
+The mapping is defined in 14496-3 (4.6.18.2.6), fs(SBR), and table 4.82
+
+\return mapped sampling frequency
+*/
+UINT sbrdec_mapToStdSampleRate(UINT fs,
+ UINT isUsac); /*!< Output sampling frequency */
+
+void initSbrPrevFrameData(HANDLE_SBR_PREV_FRAME_DATA h_prev_data,
+ int timeSlots);
+
+int sbrGetChannelElement(HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_FRAME_DATA hFrameDataLeft,
+ HANDLE_SBR_FRAME_DATA hFrameDataRight,
+ HANDLE_SBR_PREV_FRAME_DATA hFrameDataLeftPrev,
+ UCHAR pvc_mode_last, HANDLE_FDK_BITSTREAM hBitBuf,
+ HANDLE_PS_DEC hParametricStereoDec, const UINT flags,
+ const int overlap);
+
+SBR_HEADER_STATUS
+sbrGetHeaderData(HANDLE_SBR_HEADER_DATA headerData,
+ HANDLE_FDK_BITSTREAM hBitBuf, const UINT flags,
+ const int fIsSbrData, const UCHAR configMode);
+
+/*!
+ \brief Initialize SBR header data
+
+ Copy default values to the header data struct and patch some entries
+ depending on the core codec.
+*/
+SBR_ERROR
+initHeaderData(HANDLE_SBR_HEADER_DATA hHeaderData, const int sampleRateIn,
+ const int sampleRateOut, const INT downscaleFactor,
+ const int samplesPerFrame, const UINT flags,
+ const int setDefaultHdr);
+#endif
+
+/* Convert headroom bits to exponent */
+#define SCALE2EXP(s) (15 - (s))
+#define EXP2SCALE(e) (15 - (e))
diff --git a/fdk-aac/libSBRdec/src/hbe.cpp b/fdk-aac/libSBRdec/src/hbe.cpp
new file mode 100644
index 0000000..3310dcd
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/hbe.cpp
@@ -0,0 +1,2202 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Fast FFT routines prototypes
+ \author Fabian Haussel
+*/
+
+#include "hbe.h"
+#include "qmf.h"
+#include "env_extr.h"
+
+#define HBE_MAX_QMF_BANDS (40)
+
+#define HBE_MAX_OUT_SLOTS (11)
+
+#define QMF_WIN_LEN \
+ (12 + 6 - 4 - 1) /* 6 subband slots extra delay to align with HQ - 4 slots \
+ to compensate for critical sampling delay - 1 slot to \
+ align critical sampling exactly (w additional time \
+ domain delay)*/
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+
+static const int xProducts[MAX_STRETCH_HBE - 1] = {
+ 1, 1, 1}; /* Cross products on(1)/off(0) for T=2,3,4. */
+static const int startSubband2kL[33] = {
+ 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6,
+ 6, 8, 8, 8, 8, 8, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12};
+
+static const int pmin = 12;
+
+static const FIXP_DBL hintReal_F[4][3] = {
+ {FL2FXCONST_DBL(0.39840335f), FL2FXCONST_DBL(0.39840335f),
+ FL2FXCONST_DBL(-0.39840335f)},
+ {FL2FXCONST_DBL(0.39840335f), FL2FXCONST_DBL(-0.39840335f),
+ FL2FXCONST_DBL(-0.39840335f)},
+ {FL2FXCONST_DBL(-0.39840335f), FL2FXCONST_DBL(-0.39840335f),
+ FL2FXCONST_DBL(0.39840335f)},
+ {FL2FXCONST_DBL(-0.39840335f), FL2FXCONST_DBL(0.39840335f),
+ FL2FXCONST_DBL(0.39840335f)}};
+
+static const FIXP_DBL factors[4] = {
+ FL2FXCONST_DBL(0.39840335f), FL2FXCONST_DBL(-0.39840335f),
+ FL2FXCONST_DBL(-0.39840335f), FL2FXCONST_DBL(0.39840335f)};
+
+#define PSCALE 32
+
+static const FIXP_DBL p_F[128] = {FL2FXCONST_DBL(0.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(1.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(2.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(3.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(4.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(5.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(6.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(7.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(8.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(9.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(10.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(11.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(12.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(13.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(14.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(15.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(16.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(17.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(18.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(19.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(20.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(21.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(22.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(23.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(24.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(25.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(26.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(27.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(28.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(29.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(30.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(31.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(32.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(33.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(34.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(35.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(36.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(37.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(38.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(39.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(40.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(41.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(42.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(43.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(44.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(45.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(46.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(47.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(48.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(49.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(50.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(51.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(52.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(53.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(54.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(55.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(56.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(57.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(58.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(59.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(60.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(61.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(62.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(63.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(64.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(65.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(66.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(67.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(68.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(69.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(70.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(71.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(72.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(73.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(74.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(75.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(76.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(77.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(78.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(79.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(80.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(81.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(82.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(83.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(84.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(85.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(86.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(87.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(88.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(89.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(90.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(91.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(92.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(93.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(94.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(95.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(96.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(97.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(98.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(99.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(100.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(101.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(102.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(103.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(104.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(105.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(106.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(107.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(108.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(109.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(110.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(111.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(112.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(113.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(114.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(115.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(116.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(117.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(118.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(119.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(120.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(121.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(122.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(123.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(124.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(125.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(126.f / (PSCALE * 12.f)),
+ FL2FXCONST_DBL(127.f / (PSCALE * 12.f))};
+
+static const FIXP_DBL band_F[64] = {
+ FL2FXCONST_DBL((0.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((1.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((2.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((3.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((4.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((5.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((6.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((7.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((8.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((9.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((10.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((11.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((12.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((13.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((14.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((15.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((16.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((17.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((18.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((19.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((20.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((21.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((22.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((23.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((24.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((25.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((26.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((27.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((28.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((29.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((30.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((31.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((32.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((33.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((34.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((35.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((36.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((37.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((38.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((39.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((40.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((41.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((42.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((43.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((44.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((45.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((46.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((47.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((48.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((49.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((50.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((51.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((52.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((53.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((54.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((55.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((56.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((57.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((58.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((59.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((60.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((61.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((62.f * 2.f + 1) / (PSCALE << 2)),
+ FL2FXCONST_DBL((63.f * 2.f + 1) / (PSCALE << 2))};
+
+static const FIXP_DBL tr_str[3] = {FL2FXCONST_DBL(1.f / 4.f),
+ FL2FXCONST_DBL(2.f / 4.f),
+ FL2FXCONST_DBL(3.f / 4.f)};
+
+static const FIXP_DBL stretchfac[3] = {FL2FXCONST_DBL(1.f / 2.f),
+ FL2FXCONST_DBL(1.f / 3.f),
+ FL2FXCONST_DBL(1.f / 4.f)};
+
+static const FIXP_DBL cos_F[64] = {
+ 26353028, -79043208, 131685776, -184244944, 236697216, -289006912,
+ 341142496, -393072608, 444773984, -496191392, 547325824, -598114752,
+ 648559104, -698597248, 748230016, -797411904, 846083200, -894275136,
+ 941928192, -989013760, 1035474624, -1081340672, 1126555136, -1171063296,
+ 1214893696, -1257992192, 1300332544, -1341889408, 1382612736, -1422503808,
+ 1461586944, -1499741440, 1537039104, -1573364864, 1608743808, -1643196672,
+ 1676617344, -1709028992, 1740450560, -1770784896, 1800089472, -1828273536,
+ 1855357440, -1881356288, 1906190080, -1929876608, 1952428928, -1973777664,
+ 1993962880, -2012922240, 2030670208, -2047216000, 2062508288, -2076559488,
+ 2089376128, -2100932224, 2111196800, -2120214784, 2127953792, -2134394368,
+ 2139565056, -2143444864, 2146026624, -2147321856};
+
+static const FIXP_DBL twiddle[121] = {1073741824,
+ 1071442860,
+ 1064555814,
+ 1053110176,
+ 1037154959,
+ 1016758484,
+ 992008094,
+ 963009773,
+ 929887697,
+ 892783698,
+ 851856663,
+ 807281846,
+ 759250125,
+ 707967178,
+ 653652607,
+ 596538995,
+ 536870912,
+ 474903865,
+ 410903207,
+ 345142998,
+ 277904834,
+ 209476638,
+ 140151432,
+ 70226075,
+ 0,
+ -70226075,
+ -140151432,
+ -209476638,
+ -277904834,
+ -345142998,
+ -410903207,
+ -474903865,
+ -536870912,
+ -596538995,
+ -653652607,
+ -707967178,
+ -759250125,
+ -807281846,
+ -851856663,
+ -892783698,
+ -929887697,
+ -963009773,
+ -992008094,
+ -1016758484,
+ -1037154959,
+ -1053110176,
+ -1064555814,
+ -1071442860,
+ -1073741824,
+ -1071442860,
+ -1064555814,
+ -1053110176,
+ -1037154959,
+ -1016758484,
+ -992008094,
+ -963009773,
+ -929887697,
+ -892783698,
+ -851856663,
+ -807281846,
+ -759250125,
+ -707967178,
+ -653652607,
+ -596538995,
+ -536870912,
+ -474903865,
+ -410903207,
+ -345142998,
+ -277904834,
+ -209476638,
+ -140151432,
+ -70226075,
+ 0,
+ 70226075,
+ 140151432,
+ 209476638,
+ 277904834,
+ 345142998,
+ 410903207,
+ 474903865,
+ 536870912,
+ 596538995,
+ 653652607,
+ 707967178,
+ 759250125,
+ 807281846,
+ 851856663,
+ 892783698,
+ 929887697,
+ 963009773,
+ 992008094,
+ 1016758484,
+ 1037154959,
+ 1053110176,
+ 1064555814,
+ 1071442860,
+ 1073741824,
+ 1071442860,
+ 1064555814,
+ 1053110176,
+ 1037154959,
+ 1016758484,
+ 992008094,
+ 963009773,
+ 929887697,
+ 892783698,
+ 851856663,
+ 807281846,
+ 759250125,
+ 707967178,
+ 653652607,
+ 596538995,
+ 536870912,
+ 474903865,
+ 410903207,
+ 345142998,
+ 277904834,
+ 209476638,
+ 140151432,
+ 70226075,
+ 0};
+
+#if FIXP_QTW == FIXP_SGL
+#define HTW(x) (x)
+#else
+#define HTW(x) FX_DBL2FX_QTW(FX_SGL2FX_DBL((const FIXP_SGL)x))
+#endif
+
+static const FIXP_QTW post_twiddle_cos_8[8] = {
+ HTW(-1606), HTW(4756), HTW(-7723), HTW(10394),
+ HTW(-12665), HTW(14449), HTW(-15679), HTW(16305)};
+
+static const FIXP_QTW post_twiddle_cos_16[16] = {
+ HTW(-804), HTW(2404), HTW(-3981), HTW(5520), HTW(-7005), HTW(8423),
+ HTW(-9760), HTW(11003), HTW(-12140), HTW(13160), HTW(-14053), HTW(14811),
+ HTW(-15426), HTW(15893), HTW(-16207), HTW(16364)};
+
+static const FIXP_QTW post_twiddle_cos_24[24] = {
+ HTW(-536), HTW(1606), HTW(-2669), HTW(3720), HTW(-4756), HTW(5771),
+ HTW(-6762), HTW(7723), HTW(-8652), HTW(9543), HTW(-10394), HTW(11200),
+ HTW(-11958), HTW(12665), HTW(-13318), HTW(13913), HTW(-14449), HTW(14924),
+ HTW(-15334), HTW(15679), HTW(-15956), HTW(16165), HTW(-16305), HTW(16375)};
+
+static const FIXP_QTW post_twiddle_cos_32[32] = {
+ HTW(-402), HTW(1205), HTW(-2006), HTW(2801), HTW(-3590), HTW(4370),
+ HTW(-5139), HTW(5897), HTW(-6639), HTW(7366), HTW(-8076), HTW(8765),
+ HTW(-9434), HTW(10080), HTW(-10702), HTW(11297), HTW(-11866), HTW(12406),
+ HTW(-12916), HTW(13395), HTW(-13842), HTW(14256), HTW(-14635), HTW(14978),
+ HTW(-15286), HTW(15557), HTW(-15791), HTW(15986), HTW(-16143), HTW(16261),
+ HTW(-16340), HTW(16379)};
+
+static const FIXP_QTW post_twiddle_cos_40[40] = {
+ HTW(-322), HTW(965), HTW(-1606), HTW(2245), HTW(-2880), HTW(3511),
+ HTW(-4137), HTW(4756), HTW(-5368), HTW(5971), HTW(-6566), HTW(7150),
+ HTW(-7723), HTW(8285), HTW(-8833), HTW(9368), HTW(-9889), HTW(10394),
+ HTW(-10883), HTW(11356), HTW(-11810), HTW(12247), HTW(-12665), HTW(13063),
+ HTW(-13441), HTW(13799), HTW(-14135), HTW(14449), HTW(-14741), HTW(15011),
+ HTW(-15257), HTW(15480), HTW(-15679), HTW(15853), HTW(-16003), HTW(16129),
+ HTW(-16229), HTW(16305), HTW(-16356), HTW(16381)};
+
+static const FIXP_QTW post_twiddle_sin_8[8] = {
+ HTW(16305), HTW(-15679), HTW(14449), HTW(-12665),
+ HTW(10394), HTW(-7723), HTW(4756), HTW(-1606)};
+
+static const FIXP_QTW post_twiddle_sin_16[16] = {
+ HTW(16364), HTW(-16207), HTW(15893), HTW(-15426), HTW(14811), HTW(-14053),
+ HTW(13160), HTW(-12140), HTW(11003), HTW(-9760), HTW(8423), HTW(-7005),
+ HTW(5520), HTW(-3981), HTW(2404), HTW(-804)};
+
+static const FIXP_QTW post_twiddle_sin_24[24] = {
+ HTW(16375), HTW(-16305), HTW(16165), HTW(-15956), HTW(15679), HTW(-15334),
+ HTW(14924), HTW(-14449), HTW(13913), HTW(-13318), HTW(12665), HTW(-11958),
+ HTW(11200), HTW(-10394), HTW(9543), HTW(-8652), HTW(7723), HTW(-6762),
+ HTW(5771), HTW(-4756), HTW(3720), HTW(-2669), HTW(1606), HTW(-536)};
+
+static const FIXP_QTW post_twiddle_sin_32[32] = {
+ HTW(16379), HTW(-16340), HTW(16261), HTW(-16143), HTW(15986), HTW(-15791),
+ HTW(15557), HTW(-15286), HTW(14978), HTW(-14635), HTW(14256), HTW(-13842),
+ HTW(13395), HTW(-12916), HTW(12406), HTW(-11866), HTW(11297), HTW(-10702),
+ HTW(10080), HTW(-9434), HTW(8765), HTW(-8076), HTW(7366), HTW(-6639),
+ HTW(5897), HTW(-5139), HTW(4370), HTW(-3590), HTW(2801), HTW(-2006),
+ HTW(1205), HTW(-402)};
+
+static const FIXP_QTW post_twiddle_sin_40[40] = {
+ HTW(16381), HTW(-16356), HTW(16305), HTW(-16229), HTW(16129), HTW(-16003),
+ HTW(15853), HTW(-15679), HTW(15480), HTW(-15257), HTW(15011), HTW(-14741),
+ HTW(14449), HTW(-14135), HTW(13799), HTW(-13441), HTW(13063), HTW(-12665),
+ HTW(12247), HTW(-11810), HTW(11356), HTW(-10883), HTW(10394), HTW(-9889),
+ HTW(9368), HTW(-8833), HTW(8285), HTW(-7723), HTW(7150), HTW(-6566),
+ HTW(5971), HTW(-5368), HTW(4756), HTW(-4137), HTW(3511), HTW(-2880),
+ HTW(2245), HTW(-1606), HTW(965), HTW(-322)};
+
+static const FIXP_DBL preModCos[32] = {
+ -749875776, 786681536, 711263552, -821592064, -670937792, 854523392,
+ 628995648, -885396032, -585538240, 914135680, 540670208, -940673088,
+ -494499680, 964944384, 447137824, -986891008, -398698816, 1006460096,
+ 349299264, -1023604544, -299058240, 1038283072, 248096752, -1050460288,
+ -196537584, 1060106816, 144504928, -1067199488, -92124160, 1071721152,
+ 39521456, -1073660992};
+
+static const FIXP_DBL preModSin[32] = {
+ 768510144, 730789760, -804379072, -691308864, 838310208, 650162560,
+ -870221760, -607449920, 900036928, 563273856, -927683776, -517740896,
+ 953095808, 470960608, -976211712, -423045728, 996975808, 374111712,
+ -1015338112, -324276416, 1031254400, 273659904, -1044686336, -222384144,
+ 1055601472, 170572640, -1063973632, -118350192, 1069782528, 65842640,
+ -1073014208, -13176464};
+
+/* The cube root function */
+/*****************************************************************************
+
+ functionname: invCubeRootNorm2
+ description: delivers 1/cuberoot(op) in Q1.31 format and modified exponent
+
+*****************************************************************************/
+#define CUBE_ROOT_BITS 7
+#define CUBE_ROOT_VALUES (128 + 2)
+#define CUBE_ROOT_BITS_MASK 0x7f
+#define CUBE_ROOT_FRACT_BITS_MASK 0x007FFFFF
+/* Inverse cube root table for operands running from 0.5 to 1.0 */
+/* (INT) (1.0/cuberoot((op))); */
+/* Implicit exponent is 1. */
+
+LNK_SECTION_CONSTDATA
+static const FIXP_DBL invCubeRootTab[CUBE_ROOT_VALUES] = {
+ (0x50a28be6), (0x506d1172), (0x503823c4), (0x5003c05a), (0x4fcfe4c0),
+ (0x4f9c8e92), (0x4f69bb7d), (0x4f37693b), (0x4f059594), (0x4ed43e5f),
+ (0x4ea36181), (0x4e72fcea), (0x4e430e98), (0x4e139495), (0x4de48cf5),
+ (0x4db5f5db), (0x4d87cd73), (0x4d5a11f2), (0x4d2cc19c), (0x4cffdabb),
+ (0x4cd35ba4), (0x4ca742b7), (0x4c7b8e5c), (0x4c503d05), (0x4c254d2a),
+ (0x4bfabd50), (0x4bd08c00), (0x4ba6b7cd), (0x4b7d3f53), (0x4b542134),
+ (0x4b2b5c18), (0x4b02eeb1), (0x4adad7b8), (0x4ab315ea), (0x4a8ba80d),
+ (0x4a648cec), (0x4a3dc35b), (0x4a174a30), (0x49f1204a), (0x49cb448d),
+ (0x49a5b5e2), (0x49807339), (0x495b7b86), (0x4936cdc2), (0x491268ec),
+ (0x48ee4c08), (0x48ca761f), (0x48a6e63e), (0x48839b76), (0x486094de),
+ (0x483dd190), (0x481b50ad), (0x47f91156), (0x47d712b3), (0x47b553f0),
+ (0x4793d43c), (0x477292c9), (0x47518ece), (0x4730c785), (0x47103c2d),
+ (0x46efec06), (0x46cfd655), (0x46affa61), (0x46905777), (0x4670ece4),
+ (0x4651b9f9), (0x4632be0b), (0x4613f871), (0x45f56885), (0x45d70da5),
+ (0x45b8e72f), (0x459af487), (0x457d3511), (0x455fa835), (0x45424d5d),
+ (0x452523f6), (0x45082b6e), (0x44eb6337), (0x44cecac5), (0x44b2618d),
+ (0x44962708), (0x447a1ab1), (0x445e3c02), (0x44428a7c), (0x4427059e),
+ (0x440bacec), (0x43f07fe9), (0x43d57e1c), (0x43baa70e), (0x439ffa48),
+ (0x43857757), (0x436b1dc8), (0x4350ed2b), (0x4336e511), (0x431d050c),
+ (0x43034cb2), (0x42e9bb98), (0x42d05156), (0x42b70d85), (0x429defc0),
+ (0x4284f7a2), (0x426c24cb), (0x425376d8), (0x423aed6a), (0x42228823),
+ (0x420a46a6), (0x41f22898), (0x41da2d9f), (0x41c25561), (0x41aa9f86),
+ (0x41930bba), (0x417b99a5), (0x416448f5), (0x414d1956), (0x41360a76),
+ (0x411f1c06), (0x41084db5), (0x40f19f35), (0x40db1039), (0x40c4a074),
+ (0x40ae4f9b), (0x40981d64), (0x40820985), (0x406c13b6), (0x40563bb1),
+ (0x4040812e), (0x402ae3e7), (0x40156399), (0x40000000), (0x3FEAB8D9)};
+/* n.a. */
+static const FIXP_DBL invCubeRootCorrection[3] = {0x40000000, 0x50A28BE6,
+ 0x6597FA95};
+
+/*****************************************************************************
+ * \brief calculate 1.0/cube_root(op), op contains mantissa and exponent
+ * \param op_m: (i) mantissa of operand, must not be zero (0x0000.0000) or
+ * negative
+ * \param op_e: (i) pointer to the exponent of the operand (must be initialized)
+ * and .. (o) pointer to the exponent of the result
+ * \return: (o) mantissa of the result
+ * \description:
+ * This routine calculates the cube root of the input operand, that is
+ * given with its mantissa in Q31 format (FIXP_DBL) and its exponent (INT).
+ * The resulting mantissa is returned in format Q31. The exponent (*op_e)
+ * is modified accordingly. It is not assured, that the result is fully
+ * left-aligned but assumed to have not more than 2 bits headroom. There is one
+ * macro to activate the use of this algorithm: FUNCTION_invCubeRootNorm2 By
+ * means of activating the macro INVCUBEROOTNORM2_LINEAR_INTERPOLATE_HQ, a
+ * slightly higher precision is reachable (by default, not active). For DEBUG
+ * purpose only: a FDK_ASSERT macro validates, if the input mantissa is greater
+ * zero.
+ *
+ */
+static
+#ifdef __arm__
+ FIXP_DBL FDK_FORCEINLINE
+ invCubeRootNorm2(FIXP_DBL op_m, INT* op_e)
+#else
+ FIXP_DBL
+ invCubeRootNorm2(FIXP_DBL op_m, INT* op_e)
+#endif
+{
+ FDK_ASSERT(op_m > FIXP_DBL(0));
+
+ /* normalize input, calculate shift value */
+ INT exponent = (INT)fNormz(op_m) - 1;
+ op_m <<= exponent;
+
+ INT index = (INT)(op_m >> (DFRACT_BITS - 1 - (CUBE_ROOT_BITS + 1))) &
+ CUBE_ROOT_BITS_MASK;
+ FIXP_DBL fract = (FIXP_DBL)(((INT)op_m & CUBE_ROOT_FRACT_BITS_MASK)
+ << (CUBE_ROOT_BITS + 1));
+ FIXP_DBL diff = invCubeRootTab[index + 1] - invCubeRootTab[index];
+ op_m = fMultAddDiv2(invCubeRootTab[index], diff << 1, fract);
+#if defined(INVCUBEROOTNORM2_LINEAR_INTERPOLATE_HQ)
+ /* reg1 = t[i] + (t[i+1]-t[i])*fract ... already computed ... +
+ * (1-fract)fract*(t[i+2]-t[i+1])/2 */
+ if (fract != (FIXP_DBL)0) {
+ /* fract = fract * (1 - fract) */
+ fract = fMultDiv2(fract, (FIXP_DBL)((LONG)0x80000000 - (LONG)fract)) << 1;
+ diff = diff - (invCubeRootTab[index + 2] - invCubeRootTab[index + 1]);
+ op_m = fMultAddDiv2(op_m, fract, diff);
+ }
+#endif /* INVCUBEROOTNORM2_LINEAR_INTERPOLATE_HQ */
+
+ /* calculate the output exponent = input * exp/3 = cubicroot(m)*2^(exp/3)
+ * where 2^(exp/3) = 2^k'*2 or 2^k'*2^(1/3) or 2^k'*2^(2/3) */
+ exponent = exponent - *op_e + 3;
+ INT shift_tmp =
+ ((INT)fMultDiv2((FIXP_SGL)fAbs(exponent), (FIXP_SGL)0x5556)) >> 16;
+ if (exponent < 0) {
+ shift_tmp = -shift_tmp;
+ }
+ INT rem = exponent - 3 * shift_tmp;
+ if (rem < 0) {
+ rem += 3;
+ shift_tmp--;
+ }
+
+ *op_e = shift_tmp;
+ op_m = fMultDiv2(op_m, invCubeRootCorrection[rem]) << 2;
+
+ return (op_m);
+}
+
+ /*****************************************************************************
+
+ functionname: invFourthRootNorm2
+ description: delivers 1/FourthRoot(op) in Q1.31 format and modified
+ exponent
+
+ *****************************************************************************/
+
+#define FOURTHROOT_BITS 7
+#define FOURTHROOT_VALUES (128 + 2)
+#define FOURTHROOT_BITS_MASK 0x7f
+#define FOURTHROOT_FRACT_BITS_MASK 0x007FFFFF
+
+LNK_SECTION_CONSTDATA
+static const FIXP_DBL invFourthRootTab[FOURTHROOT_VALUES] = {
+ (0x4c1bf829), (0x4bf61977), (0x4bd09843), (0x4bab72ef), (0x4b86a7eb),
+ (0x4b6235ac), (0x4b3e1ab6), (0x4b1a5592), (0x4af6e4d4), (0x4ad3c718),
+ (0x4ab0fb03), (0x4a8e7f42), (0x4a6c5288), (0x4a4a7393), (0x4a28e126),
+ (0x4a079a0c), (0x49e69d16), (0x49c5e91f), (0x49a57d04), (0x498557ac),
+ (0x49657802), (0x4945dcf9), (0x49268588), (0x490770ac), (0x48e89d6a),
+ (0x48ca0ac9), (0x48abb7d6), (0x488da3a6), (0x486fcd4f), (0x485233ed),
+ (0x4834d6a3), (0x4817b496), (0x47faccf0), (0x47de1ee0), (0x47c1a999),
+ (0x47a56c51), (0x47896643), (0x476d96af), (0x4751fcd6), (0x473697ff),
+ (0x471b6773), (0x47006a81), (0x46e5a079), (0x46cb08ae), (0x46b0a279),
+ (0x46966d34), (0x467c683d), (0x466292f4), (0x4648ecbc), (0x462f74fe),
+ (0x46162b20), (0x45fd0e91), (0x45e41ebe), (0x45cb5b19), (0x45b2c315),
+ (0x459a562a), (0x458213cf), (0x4569fb81), (0x45520cbc), (0x453a4701),
+ (0x4522a9d1), (0x450b34b0), (0x44f3e726), (0x44dcc0ba), (0x44c5c0f7),
+ (0x44aee768), (0x4498339e), (0x4481a527), (0x446b3b96), (0x4454f67e),
+ (0x443ed576), (0x4428d815), (0x4412fdf3), (0x43fd46ad), (0x43e7b1de),
+ (0x43d23f23), (0x43bcee1e), (0x43a7be6f), (0x4392afb8), (0x437dc19d),
+ (0x4368f3c5), (0x435445d6), (0x433fb779), (0x432b4856), (0x4316f81a),
+ (0x4302c66f), (0x42eeb305), (0x42dabd8a), (0x42c6e5ad), (0x42b32b21),
+ (0x429f8d96), (0x428c0cc2), (0x4278a859), (0x42656010), (0x4252339e),
+ (0x423f22bc), (0x422c2d23), (0x4219528b), (0x420692b2), (0x41f3ed51),
+ (0x41e16228), (0x41cef0f2), (0x41bc9971), (0x41aa5b62), (0x41983687),
+ (0x41862aa2), (0x41743775), (0x41625cc3), (0x41509a50), (0x413eefe2),
+ (0x412d5d3e), (0x411be22b), (0x410a7e70), (0x40f931d5), (0x40e7fc23),
+ (0x40d6dd24), (0x40c5d4a2), (0x40b4e268), (0x40a40642), (0x40933ffc),
+ (0x40828f64), (0x4071f447), (0x40616e73), (0x4050fdb9), (0x4040a1e6),
+ (0x40305acc), (0x4020283c), (0x40100a08), (0x40000000), (0x3ff009f9),
+};
+
+static const FIXP_DBL invFourthRootCorrection[4] = {0x40000000, 0x4C1BF829,
+ 0x5A82799A, 0x6BA27E65};
+
+/* The fourth root function */
+/*****************************************************************************
+ * \brief calculate 1.0/fourth_root(op), op contains mantissa and exponent
+ * \param op_m: (i) mantissa of operand, must not be zero (0x0000.0000) or
+ * negative
+ * \param op_e: (i) pointer to the exponent of the operand (must be initialized)
+ * and .. (o) pointer to the exponent of the result
+ * \return: (o) mantissa of the result
+ * \description:
+ * This routine calculates the cube root of the input operand, that is
+ * given with its mantissa in Q31 format (FIXP_DBL) and its exponent (INT).
+ * The resulting mantissa is returned in format Q31. The exponent (*op_e)
+ * is modified accordingly. It is not assured, that the result is fully
+ * left-aligned but assumed to have not more than 2 bits headroom. There is one
+ * macro to activate the use of this algorithm: FUNCTION_invFourthRootNorm2 By
+ * means of activating the macro INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ, a
+ * slightly higher precision is reachable (by default, not active). For DEBUG
+ * purpose only: a FDK_ASSERT macro validates, if the input mantissa is greater
+ * zero.
+ *
+ */
+
+/* #define INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ */
+
+static
+#ifdef __arm__
+ FIXP_DBL FDK_FORCEINLINE
+ invFourthRootNorm2(FIXP_DBL op_m, INT* op_e)
+#else
+ FIXP_DBL
+ invFourthRootNorm2(FIXP_DBL op_m, INT* op_e)
+#endif
+{
+ FDK_ASSERT(op_m > FL2FXCONST_DBL(0.0));
+
+ /* normalize input, calculate shift value */
+ INT exponent = (INT)fNormz(op_m) - 1;
+ op_m <<= exponent;
+
+ INT index = (INT)(op_m >> (DFRACT_BITS - 1 - (FOURTHROOT_BITS + 1))) &
+ FOURTHROOT_BITS_MASK;
+ FIXP_DBL fract = (FIXP_DBL)(((INT)op_m & FOURTHROOT_FRACT_BITS_MASK)
+ << (FOURTHROOT_BITS + 1));
+ FIXP_DBL diff = invFourthRootTab[index + 1] - invFourthRootTab[index];
+ op_m = invFourthRootTab[index] + (fMultDiv2(diff, fract) << 1);
+
+#if defined(INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ)
+ /* reg1 = t[i] + (t[i+1]-t[i])*fract ... already computed ... +
+ * (1-fract)fract*(t[i+2]-t[i+1])/2 */
+ if (fract != (FIXP_DBL)0) {
+ /* fract = fract * (1 - fract) */
+ fract = fMultDiv2(fract, (FIXP_DBL)((LONG)0x80000000 - (LONG)fract)) << 1;
+ diff = diff - (invFourthRootTab[index + 2] - invFourthRootTab[index + 1]);
+ op_m = fMultAddDiv2(op_m, fract, diff);
+ }
+#endif /* INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ */
+
+ exponent = exponent - *op_e + 4;
+ INT rem = exponent & 0x00000003;
+ INT shift_tmp = (exponent >> 2);
+
+ *op_e = shift_tmp;
+ op_m = fMultDiv2(op_m, invFourthRootCorrection[rem]) << 2;
+
+ return (op_m);
+}
+
+/*****************************************************************************
+
+ functionname: inv3EigthRootNorm2
+ description: delivers 1/cubert(op) normalized to .5...1 and the shift value
+of the OUTPUT
+
+*****************************************************************************/
+#define THREEIGTHROOT_BITS 7
+#define THREEIGTHROOT_VALUES (128 + 2)
+#define THREEIGTHROOT_BITS_MASK 0x7f
+#define THREEIGTHROOT_FRACT_BITS_MASK 0x007FFFFF
+
+LNK_SECTION_CONSTDATA
+static const FIXP_DBL inv3EigthRootTab[THREEIGTHROOT_VALUES] = {
+ (0x45cae0f2), (0x45b981bf), (0x45a8492a), (0x45973691), (0x45864959),
+ (0x457580e6), (0x4564dca4), (0x45545c00), (0x4543fe6b), (0x4533c35a),
+ (0x4523aa44), (0x4513b2a4), (0x4503dbf7), (0x44f425be), (0x44e48f7b),
+ (0x44d518b6), (0x44c5c0f7), (0x44b687c8), (0x44a76cb8), (0x44986f58),
+ (0x44898f38), (0x447acbef), (0x446c2514), (0x445d9a3f), (0x444f2b0d),
+ (0x4440d71a), (0x44329e07), (0x44247f73), (0x44167b04), (0x4408905e),
+ (0x43fabf28), (0x43ed070b), (0x43df67b0), (0x43d1e0c5), (0x43c471f7),
+ (0x43b71af6), (0x43a9db71), (0x439cb31c), (0x438fa1ab), (0x4382a6d2),
+ (0x4375c248), (0x4368f3c5), (0x435c3b03), (0x434f97bc), (0x434309ac),
+ (0x43369091), (0x432a2c28), (0x431ddc30), (0x4311a06c), (0x4305789c),
+ (0x42f96483), (0x42ed63e5), (0x42e17688), (0x42d59c30), (0x42c9d4a6),
+ (0x42be1fb1), (0x42b27d1a), (0x42a6ecac), (0x429b6e2f), (0x42900172),
+ (0x4284a63f), (0x42795c64), (0x426e23b0), (0x4262fbf2), (0x4257e4f9),
+ (0x424cde96), (0x4241e89a), (0x423702d8), (0x422c2d23), (0x4221674d),
+ (0x4216b12c), (0x420c0a94), (0x4201735b), (0x41f6eb57), (0x41ec725f),
+ (0x41e2084b), (0x41d7acf3), (0x41cd6030), (0x41c321db), (0x41b8f1ce),
+ (0x41aecfe5), (0x41a4bbf8), (0x419ab5e6), (0x4190bd89), (0x4186d2bf),
+ (0x417cf565), (0x41732558), (0x41696277), (0x415faca1), (0x415603b4),
+ (0x414c6792), (0x4142d818), (0x4139552a), (0x412fdea6), (0x41267470),
+ (0x411d1668), (0x4113c472), (0x410a7e70), (0x41014445), (0x40f815d4),
+ (0x40eef302), (0x40e5dbb4), (0x40dccfcd), (0x40d3cf33), (0x40cad9cb),
+ (0x40c1ef7b), (0x40b9102a), (0x40b03bbd), (0x40a7721c), (0x409eb32e),
+ (0x4095feda), (0x408d5508), (0x4084b5a0), (0x407c208b), (0x407395b2),
+ (0x406b14fd), (0x40629e56), (0x405a31a6), (0x4051ced8), (0x404975d5),
+ (0x40412689), (0x4038e0dd), (0x4030a4bd), (0x40287215), (0x402048cf),
+ (0x401828d7), (0x4010121a), (0x40080483), (0x40000000), (0x3ff8047d),
+};
+
+/* The last value is rounded in order to avoid any overflow due to the values
+ * range of the root table */
+static const FIXP_DBL inv3EigthRootCorrection[8] = {
+ 0x40000000, 0x45CAE0F2, 0x4C1BF829, 0x52FF6B55,
+ 0x5A82799A, 0x62B39509, 0x6BA27E65, 0x75606373};
+
+/* The 3/8 root function */
+/*****************************************************************************
+ * \brief calculate 1.0/3Eigth_root(op) = 1.0/(x)^(3/8), op contains mantissa
+ * and exponent
+ * \param op_m: (i) mantissa of operand, must not be zero (0x0000.0000) or
+ * negative
+ * \param op_e: (i) pointer to the exponent of the operand (must be initialized)
+ * and .. (o) pointer to the exponent of the result
+ * \return: (o) mantissa of the result
+ * \description:
+ * This routine calculates the cube root of the input operand, that is
+ * given with its mantissa in Q31 format (FIXP_DBL) and its exponent (INT).
+ * The resulting mantissa is returned in format Q31. The exponent (*op_e)
+ * is modified accordingly. It is not assured, that the result is fully
+ * left-aligned but assumed to have not more than 2 bits headroom. There is one
+ * macro to activate the use of this algorithm: FUNCTION_inv3EigthRootNorm2 By
+ * means of activating the macro INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ, a
+ * slightly higher precision is reachable (by default, not active). For DEBUG
+ * purpose only: a FDK_ASSERT macro validates, if the input mantissa is greater
+ * zero.
+ *
+ */
+
+/* #define INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ */
+
+static
+#ifdef __arm__
+ FIXP_DBL FDK_FORCEINLINE
+ inv3EigthRootNorm2(FIXP_DBL op_m, INT* op_e)
+#else
+ FIXP_DBL
+ inv3EigthRootNorm2(FIXP_DBL op_m, INT* op_e)
+#endif
+{
+ FDK_ASSERT(op_m > FL2FXCONST_DBL(0.0));
+
+ /* normalize input, calculate shift op_mue */
+ INT exponent = (INT)fNormz(op_m) - 1;
+ op_m <<= exponent;
+
+ INT index = (INT)(op_m >> (DFRACT_BITS - 1 - (THREEIGTHROOT_BITS + 1))) &
+ THREEIGTHROOT_BITS_MASK;
+ FIXP_DBL fract = (FIXP_DBL)(((INT)op_m & THREEIGTHROOT_FRACT_BITS_MASK)
+ << (THREEIGTHROOT_BITS + 1));
+ FIXP_DBL diff = inv3EigthRootTab[index + 1] - inv3EigthRootTab[index];
+ op_m = inv3EigthRootTab[index] + (fMultDiv2(diff, fract) << 1);
+
+#if defined(INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ)
+ /* op_m = t[i] + (t[i+1]-t[i])*fract ... already computed ... +
+ * (1-fract)fract*(t[i+2]-t[i+1])/2 */
+ if (fract != (FIXP_DBL)0) {
+ /* fract = fract * (1 - fract) */
+ fract = fMultDiv2(fract, (FIXP_DBL)((LONG)0x80000000 - (LONG)fract)) << 1;
+ diff = diff - (inv3EigthRootTab[index + 2] - inv3EigthRootTab[index + 1]);
+ op_m = fMultAddDiv2(op_m, fract, diff);
+ }
+#endif /* INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ */
+
+ exponent = exponent - *op_e + 8;
+ INT rem = exponent & 0x00000007;
+ INT shift_tmp = (exponent >> 3);
+
+ *op_e = shift_tmp * 3;
+ op_m = fMultDiv2(op_m, inv3EigthRootCorrection[rem]) << 2;
+
+ return (fMult(op_m, fMult(op_m, op_m)));
+}
+
+SBR_ERROR
+QmfTransposerCreate(HANDLE_HBE_TRANSPOSER* hQmfTransposer, const int frameSize,
+ int bDisableCrossProducts, int bSbr41) {
+ HANDLE_HBE_TRANSPOSER hQmfTran = NULL;
+
+ int i;
+
+ if (hQmfTransposer != NULL) {
+ /* Memory allocation */
+ /*--------------------------------------------------------------------------------------------*/
+ hQmfTran =
+ (HANDLE_HBE_TRANSPOSER)FDKcalloc(1, sizeof(struct hbeTransposer));
+ if (hQmfTran == NULL) {
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+
+ for (i = 0; i < MAX_STRETCH_HBE - 1; i++) {
+ hQmfTran->bXProducts[i] = (bDisableCrossProducts ? 0 : xProducts[i]);
+ }
+
+ hQmfTran->timeDomainWinLen = frameSize;
+ if (frameSize == 768) {
+ hQmfTran->noCols =
+ (8 * frameSize / 3) / QMF_SYNTH_CHANNELS; /* 32 for 24:64 */
+ } else {
+ hQmfTran->noCols =
+ (bSbr41 + 1) * 2 * frameSize /
+ QMF_SYNTH_CHANNELS; /* 32 for 32:64 and 64 for 16:64 -> identical to
+ sbrdec->no_cols */
+ }
+
+ hQmfTran->noChannels = frameSize / hQmfTran->noCols;
+
+ hQmfTran->qmfInBufSize = QMF_WIN_LEN;
+ hQmfTran->qmfOutBufSize = 2 * (hQmfTran->noCols / 2 + QMF_WIN_LEN - 1);
+
+ hQmfTran->inBuf_F =
+ (INT_PCM*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(INT_PCM));
+ /* buffered time signal needs to be delayed by synthesis_size; max
+ * synthesis_size = 20; */
+ if (hQmfTran->inBuf_F == NULL) {
+ QmfTransposerClose(hQmfTran);
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+
+ hQmfTran->qmfInBufReal_F =
+ (FIXP_DBL**)FDKcalloc(hQmfTran->qmfInBufSize, sizeof(FIXP_DBL*));
+ hQmfTran->qmfInBufImag_F =
+ (FIXP_DBL**)FDKcalloc(hQmfTran->qmfInBufSize, sizeof(FIXP_DBL*));
+
+ if (hQmfTran->qmfInBufReal_F == NULL) {
+ QmfTransposerClose(hQmfTran);
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+ if (hQmfTran->qmfInBufImag_F == NULL) {
+ QmfTransposerClose(hQmfTran);
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+
+ for (i = 0; i < hQmfTran->qmfInBufSize; i++) {
+ hQmfTran->qmfInBufReal_F[i] = (FIXP_DBL*)FDKaalloc(
+ QMF_SYNTH_CHANNELS * sizeof(FIXP_DBL), ALIGNMENT_DEFAULT);
+ hQmfTran->qmfInBufImag_F[i] = (FIXP_DBL*)FDKaalloc(
+ QMF_SYNTH_CHANNELS * sizeof(FIXP_DBL), ALIGNMENT_DEFAULT);
+ if (hQmfTran->qmfInBufReal_F[i] == NULL) {
+ QmfTransposerClose(hQmfTran);
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+ if (hQmfTran->qmfInBufImag_F[i] == NULL) {
+ QmfTransposerClose(hQmfTran);
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+ }
+
+ hQmfTran->qmfHBEBufReal_F =
+ (FIXP_DBL**)FDKcalloc(HBE_MAX_OUT_SLOTS, sizeof(FIXP_DBL*));
+ hQmfTran->qmfHBEBufImag_F =
+ (FIXP_DBL**)FDKcalloc(HBE_MAX_OUT_SLOTS, sizeof(FIXP_DBL*));
+
+ if (hQmfTran->qmfHBEBufReal_F == NULL) {
+ QmfTransposerClose(hQmfTran);
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+ if (hQmfTran->qmfHBEBufImag_F == NULL) {
+ QmfTransposerClose(hQmfTran);
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+
+ for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) {
+ hQmfTran->qmfHBEBufReal_F[i] =
+ (FIXP_DBL*)FDKcalloc(QMF_SYNTH_CHANNELS, sizeof(FIXP_DBL));
+ hQmfTran->qmfHBEBufImag_F[i] =
+ (FIXP_DBL*)FDKcalloc(QMF_SYNTH_CHANNELS, sizeof(FIXP_DBL));
+ if (hQmfTran->qmfHBEBufReal_F[i] == NULL) {
+ QmfTransposerClose(hQmfTran);
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+ if (hQmfTran->qmfHBEBufImag_F[i] == NULL) {
+ QmfTransposerClose(hQmfTran);
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+ }
+
+ hQmfTran->qmfBufferCodecTempSlot_F =
+ (FIXP_DBL*)FDKcalloc(QMF_SYNTH_CHANNELS / 2, sizeof(FIXP_DBL));
+ if (hQmfTran->qmfBufferCodecTempSlot_F == NULL) {
+ QmfTransposerClose(hQmfTran);
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+
+ hQmfTran->bSbr41 = bSbr41;
+
+ hQmfTran->highband_exp[0] = 0;
+ hQmfTran->highband_exp[1] = 0;
+ hQmfTran->target_exp[0] = 0;
+ hQmfTran->target_exp[1] = 0;
+
+ *hQmfTransposer = hQmfTran;
+ }
+
+ return SBRDEC_OK;
+}
+
+SBR_ERROR QmfTransposerReInit(HANDLE_HBE_TRANSPOSER hQmfTransposer,
+ UCHAR* FreqBandTable[2], UCHAR NSfb[2])
+/* removed bSbr41 from parameterlist:
+ don't know where to get this value from
+ at call-side */
+{
+ int L, sfb, patch, stopPatch, qmfErr;
+
+ if (hQmfTransposer != NULL) {
+ const FIXP_QTW* tmp_t_cos;
+ const FIXP_QTW* tmp_t_sin;
+
+ hQmfTransposer->startBand = FreqBandTable[0][0];
+ FDK_ASSERT((!hQmfTransposer->bSbr41 && hQmfTransposer->startBand <= 32) ||
+ (hQmfTransposer->bSbr41 &&
+ hQmfTransposer->startBand <=
+ 16)); /* is checked by resetFreqBandTables() */
+ hQmfTransposer->stopBand = FreqBandTable[0][NSfb[0]];
+
+ hQmfTransposer->synthSize =
+ 4 * ((hQmfTransposer->startBand + 4) / 8 + 1); /* 8, 12, 16, 20 */
+ hQmfTransposer->kstart = startSubband2kL[hQmfTransposer->startBand];
+
+ /* don't know where to take this information from */
+ /* hQmfTransposer->bSbr41 = bSbr41; */
+
+ if (hQmfTransposer->bSbr41) {
+ if (hQmfTransposer->kstart + hQmfTransposer->synthSize > 16)
+ hQmfTransposer->kstart = 16 - hQmfTransposer->synthSize;
+ } else if (hQmfTransposer->timeDomainWinLen == 768) {
+ if (hQmfTransposer->kstart + hQmfTransposer->synthSize > 24)
+ hQmfTransposer->kstart = 24 - hQmfTransposer->synthSize;
+ }
+
+ hQmfTransposer->synthesisQmfPreModCos_F =
+ &preModCos[hQmfTransposer->kstart];
+ hQmfTransposer->synthesisQmfPreModSin_F =
+ &preModSin[hQmfTransposer->kstart];
+
+ L = 2 * hQmfTransposer->synthSize; /* 8, 16, 24, 32, 40 */
+ /* Change analysis post twiddles */
+
+ switch (L) {
+ case 8:
+ tmp_t_cos = post_twiddle_cos_8;
+ tmp_t_sin = post_twiddle_sin_8;
+ break;
+ case 16:
+ tmp_t_cos = post_twiddle_cos_16;
+ tmp_t_sin = post_twiddle_sin_16;
+ break;
+ case 24:
+ tmp_t_cos = post_twiddle_cos_24;
+ tmp_t_sin = post_twiddle_sin_24;
+ break;
+ case 32:
+ tmp_t_cos = post_twiddle_cos_32;
+ tmp_t_sin = post_twiddle_sin_32;
+ break;
+ case 40:
+ tmp_t_cos = post_twiddle_cos_40;
+ tmp_t_sin = post_twiddle_sin_40;
+ break;
+ default:
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ qmfErr = qmfInitSynthesisFilterBank(
+ &hQmfTransposer->HBESynthesisQMF, hQmfTransposer->synQmfStates,
+ hQmfTransposer->noCols, 0, hQmfTransposer->synthSize,
+ hQmfTransposer->synthSize, 1);
+ if (qmfErr != 0) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ qmfErr = qmfInitAnalysisFilterBank(
+ &hQmfTransposer->HBEAnalysiscQMF, hQmfTransposer->anaQmfStates,
+ hQmfTransposer->noCols / 2, 0, 2 * hQmfTransposer->synthSize,
+ 2 * hQmfTransposer->synthSize, 0);
+
+ if (qmfErr != 0) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ hQmfTransposer->HBEAnalysiscQMF.t_cos = tmp_t_cos;
+ hQmfTransposer->HBEAnalysiscQMF.t_sin = tmp_t_sin;
+
+ FDKmemset(hQmfTransposer->xOverQmf, 0,
+ MAX_NUM_PATCHES * sizeof(int)); /* global */
+ sfb = 0;
+ if (hQmfTransposer->bSbr41) {
+ stopPatch = MAX_NUM_PATCHES;
+ hQmfTransposer->maxStretch = MAX_STRETCH_HBE;
+ } else {
+ stopPatch = MAX_STRETCH_HBE;
+ }
+
+ for (patch = 1; patch <= stopPatch; patch++) {
+ while (sfb <= NSfb[0] &&
+ FreqBandTable[0][sfb] <= patch * hQmfTransposer->startBand)
+ sfb++;
+ if (sfb <= NSfb[0]) {
+ /* If the distance is larger than three QMF bands - try aligning to high
+ * resolution frequency bands instead. */
+ if ((patch * hQmfTransposer->startBand - FreqBandTable[0][sfb - 1]) <=
+ 3) {
+ hQmfTransposer->xOverQmf[patch - 1] = FreqBandTable[0][sfb - 1];
+ } else {
+ int sfb_tmp = 0;
+ while (sfb_tmp <= NSfb[1] &&
+ FreqBandTable[1][sfb_tmp] <= patch * hQmfTransposer->startBand)
+ sfb_tmp++;
+ hQmfTransposer->xOverQmf[patch - 1] = FreqBandTable[1][sfb_tmp - 1];
+ }
+ } else {
+ hQmfTransposer->xOverQmf[patch - 1] = hQmfTransposer->stopBand;
+ hQmfTransposer->maxStretch = fMin(patch, MAX_STRETCH_HBE);
+ break;
+ }
+ }
+
+ hQmfTransposer->highband_exp[0] = 0;
+ hQmfTransposer->highband_exp[1] = 0;
+ hQmfTransposer->target_exp[0] = 0;
+ hQmfTransposer->target_exp[1] = 0;
+ }
+
+ return SBRDEC_OK;
+}
+
+void QmfTransposerClose(HANDLE_HBE_TRANSPOSER hQmfTransposer) {
+ int i;
+
+ if (hQmfTransposer != NULL) {
+ if (hQmfTransposer->inBuf_F) FDKfree(hQmfTransposer->inBuf_F);
+
+ if (hQmfTransposer->qmfInBufReal_F) {
+ for (i = 0; i < hQmfTransposer->qmfInBufSize; i++) {
+ FDKafree(hQmfTransposer->qmfInBufReal_F[i]);
+ }
+ FDKfree(hQmfTransposer->qmfInBufReal_F);
+ }
+
+ if (hQmfTransposer->qmfInBufImag_F) {
+ for (i = 0; i < hQmfTransposer->qmfInBufSize; i++) {
+ FDKafree(hQmfTransposer->qmfInBufImag_F[i]);
+ }
+ FDKfree(hQmfTransposer->qmfInBufImag_F);
+ }
+
+ if (hQmfTransposer->qmfHBEBufReal_F) {
+ for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) {
+ FDKfree(hQmfTransposer->qmfHBEBufReal_F[i]);
+ }
+ FDKfree(hQmfTransposer->qmfHBEBufReal_F);
+ }
+
+ if (hQmfTransposer->qmfHBEBufImag_F) {
+ for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) {
+ FDKfree(hQmfTransposer->qmfHBEBufImag_F[i]);
+ }
+ FDKfree(hQmfTransposer->qmfHBEBufImag_F);
+ }
+
+ FDKfree(hQmfTransposer->qmfBufferCodecTempSlot_F);
+
+ FDKfree(hQmfTransposer);
+ }
+}
+
+inline void scaleUp(FIXP_DBL* real_m, FIXP_DBL* imag_m, INT* _e) {
+ INT reserve;
+ /* shift gc_r and gc_i up if possible */
+ reserve = CntLeadingZeros((INT(*real_m) ^ INT((*real_m >> 31))) |
+ (INT(*imag_m) ^ INT((*imag_m >> 31)))) -
+ 1;
+ reserve = fMax(reserve - 1,
+ 0); /* Leave one bit headroom such that (real_m^2 + imag_m^2)
+ does not overflow later if both are 0x80000000. */
+ reserve = fMin(reserve, *_e);
+ FDK_ASSERT(reserve >= 0);
+ *real_m <<= reserve;
+ *imag_m <<= reserve;
+ *_e -= reserve;
+}
+
+static void calculateCenterFIXP(FIXP_DBL gammaVecReal, FIXP_DBL gammaVecImag,
+ FIXP_DBL* centerReal, FIXP_DBL* centerImag,
+ INT* exponent, int stretch, int mult) {
+ scaleUp(&gammaVecReal, &gammaVecImag, exponent);
+ FIXP_DBL energy = fPow2Div2(gammaVecReal) + fPow2Div2(gammaVecImag);
+
+ if (energy != FL2FXCONST_DBL(0.f)) {
+ FIXP_DBL gc_r_m, gc_i_m, factor_m = (FIXP_DBL)0;
+ INT factor_e, gc_e;
+ factor_e = 2 * (*exponent) + 1;
+
+ switch (stretch) {
+ case 2:
+ factor_m = invFourthRootNorm2(energy, &factor_e);
+ break;
+ case 3:
+ factor_m = invCubeRootNorm2(energy, &factor_e);
+ break;
+ case 4:
+ factor_m = inv3EigthRootNorm2(energy, &factor_e);
+ break;
+ }
+
+ gc_r_m = fMultDiv2(gammaVecReal,
+ factor_m); /* exponent = HBE_SCALE + factor_e + 1 */
+ gc_i_m = fMultDiv2(gammaVecImag,
+ factor_m); /* exponent = HBE_SCALE + factor_e + 1*/
+ gc_e = *exponent + factor_e + 1;
+
+ scaleUp(&gc_r_m, &gc_i_m, &gc_e);
+
+ switch (mult) {
+ case 0:
+ *centerReal = gc_r_m;
+ *centerImag = gc_i_m;
+ break;
+ case 1:
+ *centerReal = fPow2Div2(gc_r_m) - fPow2Div2(gc_i_m);
+ *centerImag = fMult(gc_r_m, gc_i_m);
+ gc_e = 2 * gc_e + 1;
+ break;
+ case 2:
+ FIXP_DBL tmp_r = gc_r_m;
+ FIXP_DBL tmp_i = gc_i_m;
+ gc_r_m = fPow2Div2(gc_r_m) - fPow2Div2(gc_i_m);
+ gc_i_m = fMult(tmp_r, gc_i_m);
+ gc_e = 3 * gc_e + 1 + 1;
+ cplxMultDiv2(&centerReal[0], &centerImag[0], gc_r_m, gc_i_m, tmp_r,
+ tmp_i);
+ break;
+ }
+
+ scaleUp(centerReal, centerImag, &gc_e);
+
+ FDK_ASSERT(gc_e >= 0);
+ *exponent = gc_e;
+ } else {
+ *centerReal = energy; /* energy = 0 */
+ *centerImag = energy; /* energy = 0 */
+ *exponent = (INT)energy;
+ }
+}
+
+static int getHBEScaleFactorFrame(const int bSbr41, const int maxStretch,
+ const int pitchInBins) {
+ if (pitchInBins >= pmin * (1 + bSbr41)) {
+ /* crossproducts enabled */
+ return 26;
+ } else {
+ return (maxStretch == 2) ? 24 : 25;
+ }
+}
+
+static void addHighBandPart(FIXP_DBL g_r_m, FIXP_DBL g_i_m, INT g_e,
+ FIXP_DBL mult, FIXP_DBL gammaCenterReal_m,
+ FIXP_DBL gammaCenterImag_m, INT gammaCenter_e,
+ INT stretch, INT scale_factor_hbe,
+ FIXP_DBL* qmfHBEBufReal_F,
+ FIXP_DBL* qmfHBEBufImag_F) {
+ if ((g_r_m | g_i_m) != FL2FXCONST_DBL(0.f)) {
+ FIXP_DBL factor_m = (FIXP_DBL)0;
+ INT factor_e;
+ INT add = (stretch == 4) ? 1 : 0;
+ INT shift = (stretch == 4) ? 1 : 2;
+
+ scaleUp(&g_r_m, &g_i_m, &g_e);
+ FIXP_DBL energy = fPow2AddDiv2(fPow2Div2(g_r_m), g_i_m);
+ factor_e = 2 * g_e + 1;
+
+ switch (stretch) {
+ case 2:
+ factor_m = invFourthRootNorm2(energy, &factor_e);
+ break;
+ case 3:
+ factor_m = invCubeRootNorm2(energy, &factor_e);
+ break;
+ case 4:
+ factor_m = inv3EigthRootNorm2(energy, &factor_e);
+ break;
+ }
+
+ factor_m = fMult(factor_m, mult);
+
+ FIXP_DBL tmp_r, tmp_i;
+ cplxMultDiv2(&tmp_r, &tmp_i, g_r_m, g_i_m, gammaCenterReal_m,
+ gammaCenterImag_m);
+
+ g_r_m = fMultDiv2(tmp_r, factor_m) << shift;
+ g_i_m = fMultDiv2(tmp_i, factor_m) << shift;
+ g_e = scale_factor_hbe - (g_e + factor_e + gammaCenter_e + add);
+ fMax((INT)0, g_e);
+ *qmfHBEBufReal_F += g_r_m >> g_e;
+ *qmfHBEBufImag_F += g_i_m >> g_e;
+ }
+}
+
+void QmfTransposerApply(HANDLE_HBE_TRANSPOSER hQmfTransposer,
+ FIXP_DBL** qmfBufferCodecReal,
+ FIXP_DBL** qmfBufferCodecImag, int nColsIn,
+ FIXP_DBL** ppQmfBufferOutReal_F,
+ FIXP_DBL** ppQmfBufferOutImag_F,
+ FIXP_DBL lpcFilterStatesReal[2 + (3 * (4))][(64)],
+ FIXP_DBL lpcFilterStatesImag[2 + (3 * (4))][(64)],
+ int pitchInBins, int scale_lb, int scale_hbe,
+ int* scale_hb, int timeStep, int firstSlotOffsset,
+ int ov_len,
+ KEEP_STATES_SYNCED_MODE keepStatesSyncedMode) {
+ int i, j, stretch, band, sourceband, r, s;
+ int qmfVocoderColsIn = hQmfTransposer->noCols / 2;
+ int bSbr41 = hQmfTransposer->bSbr41;
+
+ const int winLength[3] = {10, 8, 6};
+ const int slotOffset = 6; /* hQmfTransposer->winLen-6; */
+
+ int qmfOffset = 2 * hQmfTransposer->kstart;
+ int scale_border = (nColsIn == 64) ? 32 : nColsIn;
+
+ INT slot_stretch4[9] = {0, 0, 0, 0, 2, 4, 6, 8, 10};
+ INT slot_stretch2[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+ INT slot_stretch3[10] = {0, 0, 0, 1, 3, 4, 6, 7, 9, 10};
+ INT filt_stretch3[10] = {0, 0, 0, 1, 0, 1, 0, 1, 0, 1};
+ INT filt_dummy[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ INT* pSlotStretch;
+ INT* pFilt;
+
+ int offset = 0; /* where to take QmfTransposer data */
+
+ int signPreMod =
+ (hQmfTransposer->synthesisQmfPreModCos_F[0] < FL2FXCONST_DBL(0.f)) ? 1
+ : -1;
+
+ int scale_factor_hbe =
+ getHBEScaleFactorFrame(bSbr41, hQmfTransposer->maxStretch, pitchInBins);
+
+ if (keepStatesSyncedMode != KEEP_STATES_SYNCED_OFF) {
+ offset = hQmfTransposer->noCols - ov_len - LPC_ORDER;
+ }
+
+ hQmfTransposer->highband_exp[0] = hQmfTransposer->highband_exp[1];
+ hQmfTransposer->target_exp[0] = hQmfTransposer->target_exp[1];
+
+ hQmfTransposer->highband_exp[1] = scale_factor_hbe;
+ hQmfTransposer->target_exp[1] =
+ fixMax(hQmfTransposer->highband_exp[1], hQmfTransposer->highband_exp[0]);
+
+ scale_factor_hbe = hQmfTransposer->target_exp[1];
+
+ int shift_ov = hQmfTransposer->target_exp[0] - hQmfTransposer->target_exp[1];
+
+ if (shift_ov != 0) {
+ for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) {
+ for (band = 0; band < QMF_SYNTH_CHANNELS; band++) {
+ if (shift_ov >= 0) {
+ hQmfTransposer->qmfHBEBufReal_F[i][band] <<= shift_ov;
+ hQmfTransposer->qmfHBEBufImag_F[i][band] <<= shift_ov;
+ } else {
+ hQmfTransposer->qmfHBEBufReal_F[i][band] >>= (-shift_ov);
+ hQmfTransposer->qmfHBEBufImag_F[i][band] >>= (-shift_ov);
+ }
+ }
+ }
+ }
+
+ if ((keepStatesSyncedMode == KEEP_STATES_SYNCED_OFF) && shift_ov != 0) {
+ for (i = timeStep * firstSlotOffsset; i < ov_len; i++) {
+ for (band = hQmfTransposer->startBand; band < hQmfTransposer->stopBand;
+ band++) {
+ if (shift_ov >= 0) {
+ ppQmfBufferOutReal_F[i][band] <<= shift_ov;
+ ppQmfBufferOutImag_F[i][band] <<= shift_ov;
+ } else {
+ ppQmfBufferOutReal_F[i][band] >>= (-shift_ov);
+ ppQmfBufferOutImag_F[i][band] >>= (-shift_ov);
+ }
+ }
+ }
+
+ /* shift lpc filterstates */
+ for (i = 0; i < timeStep * firstSlotOffsset + LPC_ORDER; i++) {
+ for (band = 0; band < (64); band++) {
+ if (shift_ov >= 0) {
+ lpcFilterStatesReal[i][band] <<= shift_ov;
+ lpcFilterStatesImag[i][band] <<= shift_ov;
+ } else {
+ lpcFilterStatesReal[i][band] >>= (-shift_ov);
+ lpcFilterStatesImag[i][band] >>= (-shift_ov);
+ }
+ }
+ }
+ }
+
+ FIXP_DBL twid_m_new[3][2]; /* [stretch][cos/sin] */
+ INT stepsize = 1 + !bSbr41, sine_offset = 24, mod = 96;
+ INT mult[3] = {1, 2, 3};
+
+ for (s = 0; s <= MAX_STRETCH_HBE - 2; s++) {
+ twid_m_new[s][0] = twiddle[(mult[s] * (stepsize * pitchInBins)) % mod];
+ twid_m_new[s][1] =
+ twiddle[((mult[s] * (stepsize * pitchInBins)) + sine_offset) % mod];
+ }
+
+ /* Time-stretch */
+ for (j = 0; j < qmfVocoderColsIn; j++) {
+ int sign = -1, k, z, addrshift, codecTemp_e;
+ /* update inbuf */
+ for (i = 0; i < hQmfTransposer->synthSize; i++) {
+ hQmfTransposer->inBuf_F[i] =
+ hQmfTransposer->inBuf_F[i + 2 * hQmfTransposer->synthSize];
+ }
+
+ /* run synthesis for two sbr slots as transposer uses
+ half slots double bands representation */
+ for (z = 0; z < 2; z++) {
+ int scale_factor = ((nColsIn == 64) && ((2 * j + z) < scale_border))
+ ? scale_lb
+ : scale_hbe;
+ codecTemp_e = scale_factor - 1; /* -2 for Div2 and cos/sin scale of 1 */
+
+ for (k = 0; k < hQmfTransposer->synthSize; k++) {
+ int ki = hQmfTransposer->kstart + k;
+ hQmfTransposer->qmfBufferCodecTempSlot_F[k] =
+ fMultDiv2(signPreMod * hQmfTransposer->synthesisQmfPreModCos_F[k],
+ qmfBufferCodecReal[2 * j + z][ki]);
+ hQmfTransposer->qmfBufferCodecTempSlot_F[k] +=
+ fMultDiv2(signPreMod * hQmfTransposer->synthesisQmfPreModSin_F[k],
+ qmfBufferCodecImag[2 * j + z][ki]);
+ }
+
+ C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1));
+
+ qmfSynthesisFilteringSlot(
+ &hQmfTransposer->HBESynthesisQMF,
+ hQmfTransposer->qmfBufferCodecTempSlot_F, NULL, 0,
+ -7 - hQmfTransposer->HBESynthesisQMF.filterScale - codecTemp_e + 1,
+ hQmfTransposer->inBuf_F + hQmfTransposer->synthSize * (z + 1), 1,
+ pWorkBuffer);
+
+ C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1));
+ }
+
+ C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1));
+
+ qmfAnalysisFilteringSlot(&hQmfTransposer->HBEAnalysiscQMF,
+ hQmfTransposer->qmfInBufReal_F[QMF_WIN_LEN - 1],
+ hQmfTransposer->qmfInBufImag_F[QMF_WIN_LEN - 1],
+ hQmfTransposer->inBuf_F + 1, 1, pWorkBuffer);
+
+ C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1));
+
+ if ((keepStatesSyncedMode == KEEP_STATES_SYNCED_NORMAL) &&
+ j <= qmfVocoderColsIn - ((LPC_ORDER + ov_len + QMF_WIN_LEN - 1) >> 1)) {
+ /* update in buffer */
+ for (i = 0; i < QMF_WIN_LEN - 1; i++) {
+ FDKmemcpy(
+ hQmfTransposer->qmfInBufReal_F[i],
+ hQmfTransposer->qmfInBufReal_F[i + 1],
+ sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels);
+ FDKmemcpy(
+ hQmfTransposer->qmfInBufImag_F[i],
+ hQmfTransposer->qmfInBufImag_F[i + 1],
+ sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels);
+ }
+ continue;
+ }
+
+ for (stretch = 2; stretch <= hQmfTransposer->maxStretch; stretch++) {
+ int start = slotOffset - winLength[stretch - 2] / 2;
+ int stop = slotOffset + winLength[stretch - 2] / 2;
+
+ FIXP_DBL factor = FL2FXCONST_DBL(1.f / 3.f);
+
+ for (band = hQmfTransposer->xOverQmf[stretch - 2];
+ band < hQmfTransposer->xOverQmf[stretch - 1]; band++) {
+ FIXP_DBL gammaCenterReal_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0},
+ gammaCenterImag_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0};
+ INT gammaCenter_e[2] = {0, 0};
+
+ FIXP_DBL gammaVecReal_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0},
+ gammaVecImag_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0};
+ INT gammaVec_e[2] = {0, 0};
+
+ FIXP_DBL wingain = (FIXP_DBL)0;
+
+ gammaCenter_e[0] =
+ SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+ gammaCenter_e[1] =
+ SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+
+ /* interpolation filters for 3rd order */
+ sourceband = 2 * band / stretch - qmfOffset;
+ FDK_ASSERT(sourceband >= 0);
+
+ /* maximum gammaCenter_e == 20 */
+ calculateCenterFIXP(
+ hQmfTransposer->qmfInBufReal_F[slotOffset][sourceband],
+ hQmfTransposer->qmfInBufImag_F[slotOffset][sourceband],
+ &gammaCenterReal_m[0], &gammaCenterImag_m[0], &gammaCenter_e[0],
+ stretch, stretch - 2);
+
+ if (stretch == 4) {
+ r = band - 2 * (band / 2);
+ sourceband += (r == 0) ? -1 : 1;
+ pSlotStretch = slot_stretch4;
+ factor = FL2FXCONST_DBL(2.f / 3.f);
+ pFilt = filt_dummy;
+ } else if (stretch == 2) {
+ r = 0;
+ sourceband = 2 * band / stretch - qmfOffset;
+ pSlotStretch = slot_stretch2;
+ factor = FL2FXCONST_DBL(1.f / 3.f);
+ pFilt = filt_dummy;
+ } else {
+ r = 2 * band - 3 * (2 * band / 3);
+ sourceband = 2 * band / stretch - qmfOffset;
+ pSlotStretch = slot_stretch3;
+ factor = FL2FXCONST_DBL(1.4142f / 3.0f);
+ pFilt = filt_stretch3;
+ }
+
+ if (r == 2) {
+ calculateCenterFIXP(
+ hQmfTransposer->qmfInBufReal_F[slotOffset][sourceband + 1],
+ hQmfTransposer->qmfInBufImag_F[slotOffset][sourceband + 1],
+ &gammaCenterReal_m[1], &gammaCenterImag_m[1], &gammaCenter_e[1],
+ stretch, stretch - 2);
+
+ factor = FL2FXCONST_DBL(1.4142f / 6.0f);
+ }
+
+ if (r == 2) {
+ for (k = start; k < stop; k++) {
+ gammaVecReal_m[0] =
+ hQmfTransposer->qmfInBufReal_F[pSlotStretch[k]][sourceband];
+ gammaVecReal_m[1] =
+ hQmfTransposer->qmfInBufReal_F[pSlotStretch[k]][sourceband + 1];
+ gammaVecImag_m[0] =
+ hQmfTransposer->qmfInBufImag_F[pSlotStretch[k]][sourceband];
+ gammaVecImag_m[1] =
+ hQmfTransposer->qmfInBufImag_F[pSlotStretch[k]][sourceband + 1];
+ gammaVec_e[0] = gammaVec_e[1] =
+ SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+
+ if (pFilt[k] == 1) {
+ FIXP_DBL tmpRealF = gammaVecReal_m[0], tmpImagF;
+ gammaVecReal_m[0] =
+ (fMult(gammaVecReal_m[0], hintReal_F[sourceband % 4][1]) -
+ fMult(gammaVecImag_m[0],
+ hintReal_F[(sourceband + 3) % 4][1])) >>
+ 1; /* sum should be <= 1 because of sin/cos multiplication */
+ gammaVecImag_m[0] =
+ (fMult(tmpRealF, hintReal_F[(sourceband + 3) % 4][1]) +
+ fMult(gammaVecImag_m[0], hintReal_F[sourceband % 4][1])) >>
+ 1; /* sum should be <= 1 because of sin/cos multiplication */
+
+ tmpRealF = hQmfTransposer
+ ->qmfInBufReal_F[pSlotStretch[k] + 1][sourceband];
+ tmpImagF = hQmfTransposer
+ ->qmfInBufImag_F[pSlotStretch[k] + 1][sourceband];
+
+ gammaVecReal_m[0] +=
+ (fMult(tmpRealF, hintReal_F[sourceband % 4][1]) -
+ fMult(tmpImagF, hintReal_F[(sourceband + 1) % 4][1])) >>
+ 1; /* sum should be <= 1 because of sin/cos multiplication */
+ gammaVecImag_m[0] +=
+ (fMult(tmpRealF, hintReal_F[(sourceband + 1) % 4][1]) +
+ fMult(tmpImagF, hintReal_F[sourceband % 4][1])) >>
+ 1; /* sum should be <= 1 because of sin/cos multiplication */
+ gammaVec_e[0]++;
+
+ tmpRealF = gammaVecReal_m[1];
+
+ gammaVecReal_m[1] =
+ (fMult(gammaVecReal_m[1], hintReal_F[sourceband % 4][2]) -
+ fMult(gammaVecImag_m[1],
+ hintReal_F[(sourceband + 3) % 4][2])) >>
+ 1;
+ gammaVecImag_m[1] =
+ (fMult(tmpRealF, hintReal_F[(sourceband + 3) % 4][2]) +
+ fMult(gammaVecImag_m[1], hintReal_F[sourceband % 4][2])) >>
+ 1;
+
+ tmpRealF =
+ hQmfTransposer
+ ->qmfInBufReal_F[pSlotStretch[k] + 1][sourceband + 1];
+ tmpImagF =
+ hQmfTransposer
+ ->qmfInBufImag_F[pSlotStretch[k] + 1][sourceband + 1];
+
+ gammaVecReal_m[1] +=
+ (fMult(tmpRealF, hintReal_F[sourceband % 4][2]) -
+ fMult(tmpImagF, hintReal_F[(sourceband + 1) % 4][2])) >>
+ 1;
+ gammaVecImag_m[1] +=
+ (fMult(tmpRealF, hintReal_F[(sourceband + 1) % 4][2]) +
+ fMult(tmpImagF, hintReal_F[sourceband % 4][2])) >>
+ 1;
+ gammaVec_e[1]++;
+ }
+
+ addHighBandPart(gammaVecReal_m[1], gammaVecImag_m[1], gammaVec_e[1],
+ factor, gammaCenterReal_m[0], gammaCenterImag_m[0],
+ gammaCenter_e[0], stretch, scale_factor_hbe,
+ &hQmfTransposer->qmfHBEBufReal_F[k][band],
+ &hQmfTransposer->qmfHBEBufImag_F[k][band]);
+
+ addHighBandPart(gammaVecReal_m[0], gammaVecImag_m[0], gammaVec_e[0],
+ factor, gammaCenterReal_m[1], gammaCenterImag_m[1],
+ gammaCenter_e[1], stretch, scale_factor_hbe,
+ &hQmfTransposer->qmfHBEBufReal_F[k][band],
+ &hQmfTransposer->qmfHBEBufImag_F[k][band]);
+ }
+ } else {
+ for (k = start; k < stop; k++) {
+ gammaVecReal_m[0] =
+ hQmfTransposer->qmfInBufReal_F[pSlotStretch[k]][sourceband];
+ gammaVecImag_m[0] =
+ hQmfTransposer->qmfInBufImag_F[pSlotStretch[k]][sourceband];
+ gammaVec_e[0] =
+ SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+
+ if (pFilt[k] == 1) {
+ FIXP_DBL tmpRealF = gammaVecReal_m[0], tmpImagF;
+ gammaVecReal_m[0] =
+ (fMult(gammaVecReal_m[0], hintReal_F[sourceband % 4][1]) -
+ fMult(gammaVecImag_m[0],
+ hintReal_F[(sourceband + 3) % 4][1])) >>
+ 1; /* sum should be <= 1 because of sin/cos multiplication */
+ gammaVecImag_m[0] =
+ (fMult(tmpRealF, hintReal_F[(sourceband + 3) % 4][1]) +
+ fMult(gammaVecImag_m[0], hintReal_F[sourceband % 4][1])) >>
+ 1; /* sum should be <= 1 because of sin/cos multiplication */
+
+ tmpRealF = hQmfTransposer
+ ->qmfInBufReal_F[pSlotStretch[k] + 1][sourceband];
+ tmpImagF = hQmfTransposer
+ ->qmfInBufImag_F[pSlotStretch[k] + 1][sourceband];
+
+ gammaVecReal_m[0] +=
+ (fMult(tmpRealF, hintReal_F[sourceband % 4][1]) -
+ fMult(tmpImagF, hintReal_F[(sourceband + 1) % 4][1])) >>
+ 1; /* sum should be <= 1 because of sin/cos multiplication */
+ gammaVecImag_m[0] +=
+ (fMult(tmpRealF, hintReal_F[(sourceband + 1) % 4][1]) +
+ fMult(tmpImagF, hintReal_F[sourceband % 4][1])) >>
+ 1; /* sum should be <= 1 because of sin/cos multiplication */
+ gammaVec_e[0]++;
+ }
+
+ addHighBandPart(gammaVecReal_m[0], gammaVecImag_m[0], gammaVec_e[0],
+ factor, gammaCenterReal_m[0], gammaCenterImag_m[0],
+ gammaCenter_e[0], stretch, scale_factor_hbe,
+ &hQmfTransposer->qmfHBEBufReal_F[k][band],
+ &hQmfTransposer->qmfHBEBufImag_F[k][band]);
+ }
+ }
+
+ /* pitchInBins is given with the resolution of a 768 bins FFT and we
+ * need 64 QMF units so factor 768/64 = 12 */
+ if (pitchInBins >= pmin * (1 + bSbr41)) {
+ int tr, ti1, ti2, mTr = 0, ts1 = 0, ts2 = 0, mVal_e = 0, temp_e = 0;
+ int sqmag0_e =
+ SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+
+ FIXP_DBL mVal_F = FL2FXCONST_DBL(0.f), sqmag0_F, sqmag1_F, sqmag2_F,
+ temp_F, f1_F; /* all equal exponent */
+ sign = -1;
+
+ sourceband = 2 * band / stretch - qmfOffset; /* consistent with the
+ already computed for
+ stretch = 3,4. */
+ FDK_ASSERT(sourceband >= 0);
+
+ FIXP_DBL sqmag0R_F =
+ hQmfTransposer->qmfInBufReal_F[slotOffset][sourceband];
+ FIXP_DBL sqmag0I_F =
+ hQmfTransposer->qmfInBufImag_F[slotOffset][sourceband];
+ scaleUp(&sqmag0R_F, &sqmag0I_F, &sqmag0_e);
+
+ sqmag0_F = fPow2Div2(sqmag0R_F);
+ sqmag0_F += fPow2Div2(sqmag0I_F);
+ sqmag0_e = 2 * sqmag0_e + 1;
+
+ for (tr = 1; tr < stretch; tr++) {
+ int sqmag1_e =
+ SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+ int sqmag2_e =
+ SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+
+ FIXP_DBL tmp_band = band_F[band];
+ FIXP_DBL tr_p =
+ fMult(p_F[pitchInBins] >> bSbr41, tr_str[tr - 1]); /* scale 7 */
+ f1_F =
+ fMult(tmp_band - tr_p, stretchfac[stretch - 2]); /* scale 7 */
+ ti1 = (INT)(f1_F >> (DFRACT_BITS - 1 - 7)) - qmfOffset;
+ ti2 = (INT)(((f1_F) + ((p_F[pitchInBins] >> bSbr41) >> 2)) >>
+ (DFRACT_BITS - 1 - 7)) -
+ qmfOffset;
+
+ if (ti1 >= 0 && ti2 < 2 * hQmfTransposer->synthSize) {
+ FIXP_DBL sqmag1R_F =
+ hQmfTransposer->qmfInBufReal_F[slotOffset][ti1];
+ FIXP_DBL sqmag1I_F =
+ hQmfTransposer->qmfInBufImag_F[slotOffset][ti1];
+ scaleUp(&sqmag1R_F, &sqmag1I_F, &sqmag1_e);
+ sqmag1_F = fPow2Div2(sqmag1R_F);
+ sqmag1_F += fPow2Div2(sqmag1I_F);
+ sqmag1_e = 2 * sqmag1_e + 1;
+
+ FIXP_DBL sqmag2R_F =
+ hQmfTransposer->qmfInBufReal_F[slotOffset][ti2];
+ FIXP_DBL sqmag2I_F =
+ hQmfTransposer->qmfInBufImag_F[slotOffset][ti2];
+ scaleUp(&sqmag2R_F, &sqmag2I_F, &sqmag2_e);
+ sqmag2_F = fPow2Div2(sqmag2R_F);
+ sqmag2_F += fPow2Div2(sqmag2I_F);
+ sqmag2_e = 2 * sqmag2_e + 1;
+
+ int shift1 = fMin(fMax(sqmag1_e, sqmag2_e) - sqmag1_e, 31);
+ int shift2 = fMin(fMax(sqmag1_e, sqmag2_e) - sqmag2_e, 31);
+
+ temp_F = fMin((sqmag1_F >> shift1), (sqmag2_F >> shift2));
+ temp_e = fMax(sqmag1_e, sqmag2_e);
+
+ int shift3 = fMin(fMax(temp_e, mVal_e) - temp_e, 31);
+ int shift4 = fMin(fMax(temp_e, mVal_e) - mVal_e, 31);
+
+ if ((temp_F >> shift3) > (mVal_F >> shift4)) {
+ mVal_F = temp_F;
+ mVal_e = temp_e; /* equals sqmag2_e + shift2 */
+ mTr = tr;
+ ts1 = ti1;
+ ts2 = ti2;
+ }
+ }
+ }
+
+ int shift1 = fMin(fMax(sqmag0_e, mVal_e) - sqmag0_e, 31);
+ int shift2 = fMin(fMax(sqmag0_e, mVal_e) - mVal_e, 31);
+
+ if ((mVal_F >> shift2) > (sqmag0_F >> shift1) && ts1 >= 0 &&
+ ts2 < 2 * hQmfTransposer->synthSize) {
+ INT gammaOut_e[2];
+ FIXP_DBL gammaOutReal_m[2], gammaOutImag_m[2];
+ FIXP_DBL tmpReal_m = (FIXP_DBL)0, tmpImag_m = (FIXP_DBL)0;
+
+ int Tcenter, Tvec;
+
+ Tcenter = stretch - mTr; /* default phase power parameters */
+ Tvec = mTr;
+ switch (stretch) /* 2 tap block creation design depends on stretch
+ order */
+ {
+ case 2:
+ wingain =
+ FL2FXCONST_DBL(5.f / 12.f); /* sum of taps divided by two */
+
+ if (hQmfTransposer->bXProducts[0]) {
+ gammaCenterReal_m[0] =
+ hQmfTransposer->qmfInBufReal_F[slotOffset][ts1];
+ gammaCenterImag_m[0] =
+ hQmfTransposer->qmfInBufImag_F[slotOffset][ts1];
+
+ for (k = 0; k < 2; k++) {
+ gammaVecReal_m[k] =
+ hQmfTransposer->qmfInBufReal_F[slotOffset - 1 + k][ts2];
+ gammaVecImag_m[k] =
+ hQmfTransposer->qmfInBufImag_F[slotOffset - 1 + k][ts2];
+ }
+
+ gammaCenter_e[0] = SCALE2EXP(
+ -hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+ gammaVec_e[0] = gammaVec_e[1] = SCALE2EXP(
+ -hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+ }
+ break;
+
+ case 4:
+ wingain =
+ FL2FXCONST_DBL(6.f / 12.f); /* sum of taps divided by two */
+ if (hQmfTransposer->bXProducts[2]) {
+ if (mTr == 1) {
+ gammaCenterReal_m[0] =
+ hQmfTransposer->qmfInBufReal_F[slotOffset][ts1];
+ gammaCenterImag_m[0] =
+ hQmfTransposer->qmfInBufImag_F[slotOffset][ts1];
+
+ for (k = 0; k < 2; k++) {
+ gammaVecReal_m[k] =
+ hQmfTransposer
+ ->qmfInBufReal_F[slotOffset + 2 * (k - 1)][ts2];
+ gammaVecImag_m[k] =
+ hQmfTransposer
+ ->qmfInBufImag_F[slotOffset + 2 * (k - 1)][ts2];
+ }
+ } else if (mTr == 2) {
+ gammaCenterReal_m[0] =
+ hQmfTransposer->qmfInBufReal_F[slotOffset][ts1];
+ gammaCenterImag_m[0] =
+ hQmfTransposer->qmfInBufImag_F[slotOffset][ts1];
+
+ for (k = 0; k < 2; k++) {
+ gammaVecReal_m[k] =
+ hQmfTransposer
+ ->qmfInBufReal_F[slotOffset + (k - 1)][ts2];
+ gammaVecImag_m[k] =
+ hQmfTransposer
+ ->qmfInBufImag_F[slotOffset + (k - 1)][ts2];
+ }
+ } else /* (mTr == 3) */
+ {
+ sign = 1;
+ Tcenter = mTr; /* opposite phase power parameters as ts2 is
+ center */
+ Tvec = stretch - mTr;
+
+ gammaCenterReal_m[0] =
+ hQmfTransposer->qmfInBufReal_F[slotOffset][ts2];
+ gammaCenterImag_m[0] =
+ hQmfTransposer->qmfInBufImag_F[slotOffset][ts2];
+
+ for (k = 0; k < 2; k++) {
+ gammaVecReal_m[k] =
+ hQmfTransposer
+ ->qmfInBufReal_F[slotOffset + 2 * (k - 1)][ts1];
+ gammaVecImag_m[k] =
+ hQmfTransposer
+ ->qmfInBufImag_F[slotOffset + 2 * (k - 1)][ts1];
+ }
+ }
+
+ gammaCenter_e[0] = SCALE2EXP(
+ -hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+ gammaVec_e[0] = gammaVec_e[1] = SCALE2EXP(
+ -hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+ }
+ break;
+
+ case 3:
+ wingain = FL2FXCONST_DBL(5.6568f /
+ 12.f); /* sum of taps divided by two */
+
+ if (hQmfTransposer->bXProducts[1]) {
+ FIXP_DBL tmpReal_F, tmpImag_F;
+ if (mTr == 1) {
+ gammaCenterReal_m[0] =
+ hQmfTransposer->qmfInBufReal_F[slotOffset][ts1];
+ gammaCenterImag_m[0] =
+ hQmfTransposer->qmfInBufImag_F[slotOffset][ts1];
+ gammaVecReal_m[1] =
+ hQmfTransposer->qmfInBufReal_F[slotOffset][ts2];
+ gammaVecImag_m[1] =
+ hQmfTransposer->qmfInBufImag_F[slotOffset][ts2];
+
+ addrshift = -2;
+ tmpReal_F =
+ hQmfTransposer
+ ->qmfInBufReal_F[addrshift + slotOffset][ts2];
+ tmpImag_F =
+ hQmfTransposer
+ ->qmfInBufImag_F[addrshift + slotOffset][ts2];
+
+ gammaVecReal_m[0] =
+ (fMult(factors[ts2 % 4], tmpReal_F) -
+ fMult(factors[(ts2 + 3) % 4], tmpImag_F)) >>
+ 1;
+ gammaVecImag_m[0] =
+ (fMult(factors[(ts2 + 3) % 4], tmpReal_F) +
+ fMult(factors[ts2 % 4], tmpImag_F)) >>
+ 1;
+
+ tmpReal_F =
+ hQmfTransposer
+ ->qmfInBufReal_F[addrshift + 1 + slotOffset][ts2];
+ tmpImag_F =
+ hQmfTransposer
+ ->qmfInBufImag_F[addrshift + 1 + slotOffset][ts2];
+
+ gammaVecReal_m[0] +=
+ (fMult(factors[ts2 % 4], tmpReal_F) -
+ fMult(factors[(ts2 + 1) % 4], tmpImag_F)) >>
+ 1;
+ gammaVecImag_m[0] +=
+ (fMult(factors[(ts2 + 1) % 4], tmpReal_F) +
+ fMult(factors[ts2 % 4], tmpImag_F)) >>
+ 1;
+
+ } else /* (mTr == 2) */
+ {
+ sign = 1;
+ Tcenter = mTr; /* opposite phase power parameters as ts2 is
+ center */
+ Tvec = stretch - mTr;
+
+ gammaCenterReal_m[0] =
+ hQmfTransposer->qmfInBufReal_F[slotOffset][ts2];
+ gammaCenterImag_m[0] =
+ hQmfTransposer->qmfInBufImag_F[slotOffset][ts2];
+ gammaVecReal_m[1] =
+ hQmfTransposer->qmfInBufReal_F[slotOffset][ts1];
+ gammaVecImag_m[1] =
+ hQmfTransposer->qmfInBufImag_F[slotOffset][ts1];
+
+ addrshift = -2;
+ tmpReal_F =
+ hQmfTransposer
+ ->qmfInBufReal_F[addrshift + slotOffset][ts1];
+ tmpImag_F =
+ hQmfTransposer
+ ->qmfInBufImag_F[addrshift + slotOffset][ts1];
+
+ gammaVecReal_m[0] =
+ (fMult(factors[ts1 % 4], tmpReal_F) -
+ fMult(factors[(ts1 + 3) % 4], tmpImag_F)) >>
+ 1;
+ gammaVecImag_m[0] =
+ (fMult(factors[(ts1 + 3) % 4], tmpReal_F) +
+ fMult(factors[ts1 % 4], tmpImag_F)) >>
+ 1;
+
+ tmpReal_F =
+ hQmfTransposer
+ ->qmfInBufReal_F[addrshift + 1 + slotOffset][ts1];
+ tmpImag_F =
+ hQmfTransposer
+ ->qmfInBufImag_F[addrshift + 1 + slotOffset][ts1];
+
+ gammaVecReal_m[0] +=
+ (fMult(factors[ts1 % 4], tmpReal_F) -
+ fMult(factors[(ts1 + 1) % 4], tmpImag_F)) >>
+ 1;
+ gammaVecImag_m[0] +=
+ (fMult(factors[(ts1 + 1) % 4], tmpReal_F) +
+ fMult(factors[ts1 % 4], tmpImag_F)) >>
+ 1;
+ }
+
+ gammaCenter_e[0] = gammaVec_e[1] = SCALE2EXP(
+ -hQmfTransposer->HBEAnalysiscQMF.outScalefactor);
+ gammaVec_e[0] =
+ SCALE2EXP(
+ -hQmfTransposer->HBEAnalysiscQMF.outScalefactor) +
+ 1;
+ }
+ break;
+ default:
+ FDK_ASSERT(0);
+ break;
+ } /* stretch cases */
+
+ /* parameter controlled phase modification parts */
+ /* maximum *_e == 20 */
+ calculateCenterFIXP(gammaCenterReal_m[0], gammaCenterImag_m[0],
+ &gammaCenterReal_m[0], &gammaCenterImag_m[0],
+ &gammaCenter_e[0], stretch, Tcenter - 1);
+ calculateCenterFIXP(gammaVecReal_m[0], gammaVecImag_m[0],
+ &gammaVecReal_m[0], &gammaVecImag_m[0],
+ &gammaVec_e[0], stretch, Tvec - 1);
+ calculateCenterFIXP(gammaVecReal_m[1], gammaVecImag_m[1],
+ &gammaVecReal_m[1], &gammaVecImag_m[1],
+ &gammaVec_e[1], stretch, Tvec - 1);
+
+ /* Final multiplication of prepared parts */
+ for (k = 0; k < 2; k++) {
+ gammaOutReal_m[k] =
+ fMultDiv2(gammaVecReal_m[k], gammaCenterReal_m[0]) -
+ fMultDiv2(gammaVecImag_m[k], gammaCenterImag_m[0]);
+ gammaOutImag_m[k] =
+ fMultDiv2(gammaVecReal_m[k], gammaCenterImag_m[0]) +
+ fMultDiv2(gammaVecImag_m[k], gammaCenterReal_m[0]);
+ gammaOut_e[k] = gammaCenter_e[0] + gammaVec_e[k] + 1;
+ }
+
+ scaleUp(&gammaOutReal_m[0], &gammaOutImag_m[0], &gammaOut_e[0]);
+ scaleUp(&gammaOutReal_m[1], &gammaOutImag_m[1], &gammaOut_e[1]);
+ FDK_ASSERT(gammaOut_e[0] >= 0);
+ FDK_ASSERT(gammaOut_e[0] < 32);
+
+ tmpReal_m = gammaOutReal_m[0];
+ tmpImag_m = gammaOutImag_m[0];
+
+ INT modstretch4 = ((stretch == 4) && (mTr == 2));
+
+ FIXP_DBL cos_twid = twid_m_new[stretch - 2 - modstretch4][0];
+ FIXP_DBL sin_twid = sign * twid_m_new[stretch - 2 - modstretch4][1];
+
+ gammaOutReal_m[0] =
+ fMult(tmpReal_m, cos_twid) -
+ fMult(tmpImag_m, sin_twid); /* sum should be <= 1 because of
+ sin/cos multiplication */
+ gammaOutImag_m[0] =
+ fMult(tmpImag_m, cos_twid) +
+ fMult(tmpReal_m, sin_twid); /* sum should be <= 1 because of
+ sin/cos multiplication */
+
+ /* wingain */
+ for (k = 0; k < 2; k++) {
+ gammaOutReal_m[k] = (fMult(gammaOutReal_m[k], wingain) << 1);
+ gammaOutImag_m[k] = (fMult(gammaOutImag_m[k], wingain) << 1);
+ }
+
+ gammaOutReal_m[1] >>= 1;
+ gammaOutImag_m[1] >>= 1;
+ gammaOut_e[0] += 2;
+ gammaOut_e[1] += 2;
+
+ /* OLA including window scaling by wingain/3 */
+ for (k = 0; k < 2; k++) /* need k=1 to correspond to
+ grainModImag[slotOffset] -> out to
+ j*2+(slotOffset-offset) */
+ {
+ hQmfTransposer->qmfHBEBufReal_F[(k + slotOffset - 1)][band] +=
+ gammaOutReal_m[k] >> (scale_factor_hbe - gammaOut_e[k]);
+ hQmfTransposer->qmfHBEBufImag_F[(k + slotOffset - 1)][band] +=
+ gammaOutImag_m[k] >> (scale_factor_hbe - gammaOut_e[k]);
+ }
+ } /* mVal > qThrQMF * qThrQMF * sqmag0 && ts1 > 0 && ts2 < 64 */
+ } /* p >= pmin */
+ } /* for band */
+ } /* for stretch */
+
+ for (i = 0; i < QMF_WIN_LEN - 1; i++) {
+ FDKmemcpy(hQmfTransposer->qmfInBufReal_F[i],
+ hQmfTransposer->qmfInBufReal_F[i + 1],
+ sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels);
+ FDKmemcpy(hQmfTransposer->qmfInBufImag_F[i],
+ hQmfTransposer->qmfInBufImag_F[i + 1],
+ sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels);
+ }
+
+ if (keepStatesSyncedMode != KEEP_STATES_SYNCED_NOOUT) {
+ if (2 * j >= offset) {
+ /* copy first two slots of internal buffer to output */
+ if (keepStatesSyncedMode == KEEP_STATES_SYNCED_OUTDIFF) {
+ for (i = 0; i < 2; i++) {
+ FDKmemcpy(&ppQmfBufferOutReal_F[2 * j - offset + i]
+ [hQmfTransposer->xOverQmf[0]],
+ &hQmfTransposer
+ ->qmfHBEBufReal_F[i][hQmfTransposer->xOverQmf[0]],
+ (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) *
+ sizeof(FIXP_DBL));
+ FDKmemcpy(&ppQmfBufferOutImag_F[2 * j - offset + i]
+ [hQmfTransposer->xOverQmf[0]],
+ &hQmfTransposer
+ ->qmfHBEBufImag_F[i][hQmfTransposer->xOverQmf[0]],
+ (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) *
+ sizeof(FIXP_DBL));
+ }
+ } else {
+ for (i = 0; i < 2; i++) {
+ FDKmemcpy(&ppQmfBufferOutReal_F[2 * j + i + ov_len]
+ [hQmfTransposer->xOverQmf[0]],
+ &hQmfTransposer
+ ->qmfHBEBufReal_F[i][hQmfTransposer->xOverQmf[0]],
+ (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) *
+ sizeof(FIXP_DBL));
+ FDKmemcpy(&ppQmfBufferOutImag_F[2 * j + i + ov_len]
+ [hQmfTransposer->xOverQmf[0]],
+ &hQmfTransposer
+ ->qmfHBEBufImag_F[i][hQmfTransposer->xOverQmf[0]],
+ (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) *
+ sizeof(FIXP_DBL));
+ }
+ }
+ }
+ }
+
+ /* move slots up */
+ for (i = 0; i < HBE_MAX_OUT_SLOTS - 2; i++) {
+ FDKmemcpy(
+ &hQmfTransposer->qmfHBEBufReal_F[i][hQmfTransposer->xOverQmf[0]],
+ &hQmfTransposer->qmfHBEBufReal_F[i + 2][hQmfTransposer->xOverQmf[0]],
+ (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) *
+ sizeof(FIXP_DBL));
+ FDKmemcpy(
+ &hQmfTransposer->qmfHBEBufImag_F[i][hQmfTransposer->xOverQmf[0]],
+ &hQmfTransposer->qmfHBEBufImag_F[i + 2][hQmfTransposer->xOverQmf[0]],
+ (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) *
+ sizeof(FIXP_DBL));
+ }
+
+ /* finally set last two slot to zero */
+ for (i = 0; i < 2; i++) {
+ FDKmemset(&hQmfTransposer->qmfHBEBufReal_F[HBE_MAX_OUT_SLOTS - 1 - i]
+ [hQmfTransposer->xOverQmf[0]],
+ 0,
+ (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) *
+ sizeof(FIXP_DBL));
+ FDKmemset(&hQmfTransposer->qmfHBEBufImag_F[HBE_MAX_OUT_SLOTS - 1 - i]
+ [hQmfTransposer->xOverQmf[0]],
+ 0,
+ (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) *
+ sizeof(FIXP_DBL));
+ }
+ } /* qmfVocoderColsIn */
+
+ if (keepStatesSyncedMode != KEEP_STATES_SYNCED_NOOUT) {
+ if (keepStatesSyncedMode == KEEP_STATES_SYNCED_OUTDIFF) {
+ for (i = 0; i < ov_len + LPC_ORDER; i++) {
+ for (band = hQmfTransposer->startBand; band < hQmfTransposer->stopBand;
+ band++) {
+ FIXP_DBL tmpR = ppQmfBufferOutReal_F[i][band];
+ FIXP_DBL tmpI = ppQmfBufferOutImag_F[i][band];
+
+ ppQmfBufferOutReal_F[i][band] =
+ fMult(tmpR, cos_F[band]) -
+ fMult(tmpI, (-cos_F[64 - band - 1])); /* sum should be <= 1
+ because of sin/cos
+ multiplication */
+ ppQmfBufferOutImag_F[i][band] =
+ fMult(tmpR, (-cos_F[64 - band - 1])) +
+ fMult(tmpI, cos_F[band]); /* sum should by <= 1 because of sin/cos
+ multiplication */
+ }
+ }
+ } else {
+ for (i = offset; i < hQmfTransposer->noCols; i++) {
+ for (band = hQmfTransposer->startBand; band < hQmfTransposer->stopBand;
+ band++) {
+ FIXP_DBL tmpR = ppQmfBufferOutReal_F[i + ov_len][band];
+ FIXP_DBL tmpI = ppQmfBufferOutImag_F[i + ov_len][band];
+
+ ppQmfBufferOutReal_F[i + ov_len][band] =
+ fMult(tmpR, cos_F[band]) -
+ fMult(tmpI, (-cos_F[64 - band - 1])); /* sum should be <= 1
+ because of sin/cos
+ multiplication */
+ ppQmfBufferOutImag_F[i + ov_len][band] =
+ fMult(tmpR, (-cos_F[64 - band - 1])) +
+ fMult(tmpI, cos_F[band]); /* sum should by <= 1 because of sin/cos
+ multiplication */
+ }
+ }
+ }
+ }
+
+ *scale_hb = EXP2SCALE(scale_factor_hbe);
+}
+
+int* GetxOverBandQmfTransposer(HANDLE_HBE_TRANSPOSER hQmfTransposer) {
+ if (hQmfTransposer)
+ return hQmfTransposer->xOverQmf;
+ else
+ return NULL;
+}
+
+int Get41SbrQmfTransposer(HANDLE_HBE_TRANSPOSER hQmfTransposer) {
+ if (hQmfTransposer != NULL)
+ return hQmfTransposer->bSbr41;
+ else
+ return 0;
+}
diff --git a/fdk-aac/libSBRdec/src/hbe.h b/fdk-aac/libSBRdec/src/hbe.h
new file mode 100644
index 0000000..fdffe1e
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/hbe.h
@@ -0,0 +1,200 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef HBE_H
+#define HBE_H
+
+#include "sbrdecoder.h"
+
+#ifndef QMF_SYNTH_CHANNELS
+#define QMF_SYNTH_CHANNELS (64)
+#endif
+
+#define HBE_QMF_FILTER_STATE_ANA_SIZE (400)
+#define HBE_QMF_FILTER_STATE_SYN_SIZE (200)
+
+#ifndef MAX_NUM_PATCHES_HBE
+#define MAX_NUM_PATCHES_HBE (6)
+#endif
+#define MAX_STRETCH_HBE (4)
+
+typedef enum {
+ KEEP_STATES_SYNCED_OFF = 0, /*!< normal QMF transposer behaviour */
+ KEEP_STATES_SYNCED_NORMAL = 1, /*!< QMF transposer called for syncing of
+ states the last 8/14 slots are calculated in
+ case next frame is HBE */
+ KEEP_STATES_SYNCED_OUTDIFF =
+ 2, /*!< QMF transposer behaviour as in normal case, but the calculated
+ slots are directly written to overlap area of buffer; only used in
+ resetSbrDec function */
+ KEEP_STATES_SYNCED_NOOUT =
+ 3 /*!< QMF transposer is called for syncing of states only, not output
+ is generated at all; only used in resetSbrDec function */
+} KEEP_STATES_SYNCED_MODE;
+
+struct hbeTransposer {
+ int xOverQmf[MAX_NUM_PATCHES_HBE];
+
+ int maxStretch;
+ int timeDomainWinLen;
+ int qmfInBufSize;
+ int qmfOutBufSize;
+ int noCols;
+ int noChannels;
+ int startBand;
+ int stopBand;
+ int bSbr41;
+
+ INT_PCM *inBuf_F;
+ FIXP_DBL **qmfInBufReal_F;
+ FIXP_DBL **qmfInBufImag_F;
+
+ FIXP_DBL *qmfBufferCodecTempSlot_F;
+
+ QMF_FILTER_BANK HBEAnalysiscQMF;
+ QMF_FILTER_BANK HBESynthesisQMF;
+
+ FIXP_DBL const *synthesisQmfPreModCos_F;
+ FIXP_DBL const *synthesisQmfPreModSin_F;
+
+ FIXP_QAS anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE];
+ FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE];
+
+ FIXP_DBL **qmfHBEBufReal_F;
+ FIXP_DBL **qmfHBEBufImag_F;
+
+ int bXProducts[MAX_STRETCH_HBE];
+
+ int kstart;
+ int synthSize;
+
+ int highband_exp[2];
+ int target_exp[2];
+};
+
+typedef struct hbeTransposer *HANDLE_HBE_TRANSPOSER;
+
+SBR_ERROR QmfTransposerCreate(HANDLE_HBE_TRANSPOSER *hQmfTransposer,
+ const int frameSize, int bDisableCrossProducts,
+ int bSbr41);
+
+SBR_ERROR QmfTransposerReInit(HANDLE_HBE_TRANSPOSER hQmfTransposer,
+ UCHAR *FreqBandTable[2], UCHAR NSfb[2]);
+
+void QmfTransposerClose(HANDLE_HBE_TRANSPOSER hQmfTransposer);
+
+void QmfTransposerApply(HANDLE_HBE_TRANSPOSER hQmfTransposer,
+ FIXP_DBL **qmfBufferCodecReal,
+ FIXP_DBL **qmfBufferCodecImag, int nColsIn,
+ FIXP_DBL **ppQmfBufferOutReal_F,
+ FIXP_DBL **ppQmfBufferOutImag_F,
+ FIXP_DBL lpcFilterStatesReal[2 + (3 * (4))][(64)],
+ FIXP_DBL lpcFilterStatesImag[2 + (3 * (4))][(64)],
+ int pitchInBins, int scale_lb, int scale_hbe,
+ int *scale_hb, int timeStep, int firstSlotOffsset,
+ int ov_len,
+ KEEP_STATES_SYNCED_MODE keepStatesSyncedMode);
+
+int *GetxOverBandQmfTransposer(HANDLE_HBE_TRANSPOSER hQmfTransposer);
+
+int Get41SbrQmfTransposer(HANDLE_HBE_TRANSPOSER hQmfTransposer);
+#endif /* HBE_H */
diff --git a/fdk-aac/libSBRdec/src/huff_dec.cpp b/fdk-aac/libSBRdec/src/huff_dec.cpp
new file mode 100644
index 0000000..90c9541
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/huff_dec.cpp
@@ -0,0 +1,137 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Huffman Decoder
+*/
+
+#include "huff_dec.h"
+
+/***************************************************************************/
+/*!
+ \brief Decodes one huffman code word
+
+ Reads bits from the bitstream until a valid codeword is found.
+ The table entries are interpreted either as index to the next entry
+ or - if negative - as the codeword.
+
+ \return decoded value
+
+ \author
+
+****************************************************************************/
+int DecodeHuffmanCW(Huffman h, /*!< pointer to huffman codebook table */
+ HANDLE_FDK_BITSTREAM hBs) /*!< Handle to Bitbuffer */
+{
+ SCHAR index = 0;
+ int value, bit;
+
+ while (index >= 0) {
+ bit = FDKreadBits(hBs, 1);
+ index = h[index][bit];
+ }
+
+ value = index + 64; /* Add offset */
+
+ return value;
+}
diff --git a/fdk-aac/libSBRdec/src/huff_dec.h b/fdk-aac/libSBRdec/src/huff_dec.h
new file mode 100644
index 0000000..9aa62b4
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/huff_dec.h
@@ -0,0 +1,117 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Huffman Decoder
+*/
+#ifndef HUFF_DEC_H
+#define HUFF_DEC_H
+
+#include "sbrdecoder.h"
+#include "FDK_bitstream.h"
+
+typedef const SCHAR (*Huffman)[2];
+
+int DecodeHuffmanCW(Huffman h, HANDLE_FDK_BITSTREAM hBitBuf);
+
+#endif
diff --git a/fdk-aac/libSBRdec/src/lpp_tran.cpp b/fdk-aac/libSBRdec/src/lpp_tran.cpp
new file mode 100644
index 0000000..2ef07eb
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/lpp_tran.cpp
@@ -0,0 +1,1471 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Low Power Profile Transposer
+ This module provides the transposer. The main entry point is lppTransposer().
+ The function generates high frequency content by copying data from the low
+ band (provided by core codec) into the high band. This process is also
+ referred to as "patching". The function also implements spectral whitening by
+ means of inverse filtering based on LPC coefficients.
+
+ Together with the QMF filterbank the transposer can be tested using a supplied
+ test program. See main_audio.cpp for details. This module does use fractional
+ arithmetic and the accuracy of the computations has an impact on the overall
+ sound quality. The module also needs to take into account the different
+ scaling of spectral data.
+
+ \sa lppTransposer(), main_audio.cpp, sbr_scale.h, \ref documentationOverview
+*/
+
+#ifdef __ANDROID__
+#include "log/log.h"
+#endif
+
+#include "lpp_tran.h"
+
+#include "sbr_ram.h"
+#include "sbr_rom.h"
+
+#include "genericStds.h"
+#include "autocorr2nd.h"
+
+#include "HFgen_preFlat.h"
+
+#if defined(__arm__)
+#include "arm/lpp_tran_arm.cpp"
+#endif
+
+#define LPC_SCALE_FACTOR 2
+
+/*!
+ *
+ * \brief Get bandwidth expansion factor from filtering level
+ *
+ * Returns a filter parameter (bandwidth expansion factor) depending on
+ * the desired filtering level signalled in the bitstream.
+ * When switching the filtering level from LOW to OFF, an additional
+ * level is being inserted to achieve a smooth transition.
+ */
+
+static FIXP_DBL mapInvfMode(INVF_MODE mode, INVF_MODE prevMode,
+ WHITENING_FACTORS whFactors) {
+ switch (mode) {
+ case INVF_LOW_LEVEL:
+ if (prevMode == INVF_OFF)
+ return whFactors.transitionLevel;
+ else
+ return whFactors.lowLevel;
+
+ case INVF_MID_LEVEL:
+ return whFactors.midLevel;
+
+ case INVF_HIGH_LEVEL:
+ return whFactors.highLevel;
+
+ default:
+ if (prevMode == INVF_LOW_LEVEL)
+ return whFactors.transitionLevel;
+ else
+ return whFactors.off;
+ }
+}
+
+/*!
+ *
+ * \brief Perform inverse filtering level emphasis
+ *
+ * Retrieve bandwidth expansion factor and apply smoothing for each filter band
+ *
+ */
+
+static void inverseFilteringLevelEmphasis(
+ HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */
+ UCHAR nInvfBands, /*!< Number of bands for inverse filtering */
+ INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */
+ INVF_MODE *sbr_invf_mode_prev, /*!< Previous inverse filtering modes */
+ FIXP_DBL *bwVector /*!< Resulting filtering levels */
+) {
+ for (int i = 0; i < nInvfBands; i++) {
+ FIXP_DBL accu;
+ FIXP_DBL bwTmp = mapInvfMode(sbr_invf_mode[i], sbr_invf_mode_prev[i],
+ hLppTrans->pSettings->whFactors);
+
+ if (bwTmp < hLppTrans->bwVectorOld[i]) {
+ accu = fMultDiv2(FL2FXCONST_DBL(0.75f), bwTmp) +
+ fMultDiv2(FL2FXCONST_DBL(0.25f), hLppTrans->bwVectorOld[i]);
+ } else {
+ accu = fMultDiv2(FL2FXCONST_DBL(0.90625f), bwTmp) +
+ fMultDiv2(FL2FXCONST_DBL(0.09375f), hLppTrans->bwVectorOld[i]);
+ }
+
+ if (accu<FL2FXCONST_DBL(0.015625f)>> 1) {
+ bwVector[i] = FL2FXCONST_DBL(0.0f);
+ } else {
+ bwVector[i] = fixMin(accu << 1, FL2FXCONST_DBL(0.99609375f));
+ }
+ }
+}
+
+/* Resulting autocorrelation determinant exponent */
+#define ACDET_EXP \
+ (2 * (DFRACT_BITS + sbrScaleFactor->lb_scale + 10 - ac.det_scale))
+#define AC_EXP (-sbrScaleFactor->lb_scale + LPC_SCALE_FACTOR)
+#define ALPHA_EXP (-sbrScaleFactor->lb_scale + LPC_SCALE_FACTOR + 1)
+/* Resulting transposed QMF values exponent 16 bit normalized samplebits
+ * assumed. */
+#define QMFOUT_EXP ((SAMPLE_BITS - 15) - sbrScaleFactor->lb_scale)
+
+static inline void calc_qmfBufferReal(FIXP_DBL **qmfBufferReal,
+ const FIXP_DBL *const lowBandReal,
+ const int startSample,
+ const int stopSample, const UCHAR hiBand,
+ const int dynamicScale, const int descale,
+ const FIXP_SGL a0r, const FIXP_SGL a1r) {
+ FIXP_DBL accu1, accu2;
+ int i;
+
+ for (i = 0; i < stopSample - startSample; i++) {
+ accu1 = fMultDiv2(a1r, lowBandReal[i]);
+ accu1 = (fMultDiv2(a0r, lowBandReal[i + 1]) + accu1);
+ accu1 = accu1 >> dynamicScale;
+
+ accu1 <<= 1;
+ accu2 = (lowBandReal[i + 2] >> descale);
+ qmfBufferReal[i + startSample][hiBand] = accu1 + accu2;
+ }
+}
+
+/*!
+ *
+ * \brief Perform transposition by patching of subband samples.
+ * This function serves as the main entry point into the module. The function
+ * determines the areas for the patching process (these are the source range as
+ * well as the target range) and implements spectral whitening by means of
+ * inverse filtering. The function autoCorrelation2nd() is an auxiliary function
+ * for calculating the LPC coefficients for the filtering. The actual
+ * calculation of the LPC coefficients and the implementation of the filtering
+ * are done as part of lppTransposer().
+ *
+ * Note that the filtering is done on all available QMF subsamples, whereas the
+ * patching is only done on those QMF subsamples that will be used in the next
+ * QMF synthesis. The filtering is also implemented before the patching includes
+ * further dependencies on parameters from the SBR data.
+ *
+ */
+
+void lppTransposer(
+ HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */
+ QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
+ FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband
+ samples (source) */
+
+ FIXP_DBL *degreeAlias, /*!< Vector for results of aliasing estimation */
+ FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of
+ subband samples (source) */
+ const int useLP, const int fPreWhitening, const int v_k_master0,
+ const int timeStep, /*!< Time step of envelope */
+ const int firstSlotOffs, /*!< Start position in time */
+ const int lastSlotOffs, /*!< Number of overlap-slots into next frame */
+ const int nInvfBands, /*!< Number of bands for inverse filtering */
+ INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */
+ INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */
+) {
+ INT bwIndex[MAX_NUM_PATCHES];
+ FIXP_DBL bwVector[MAX_NUM_PATCHES]; /*!< pole moving factors */
+ FIXP_DBL preWhiteningGains[(64) / 2];
+ int preWhiteningGains_exp[(64) / 2];
+
+ int i;
+ int loBand, start, stop;
+ TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
+ PATCH_PARAM *patchParam = pSettings->patchParam;
+ int patch;
+
+ FIXP_SGL alphar[LPC_ORDER], a0r, a1r;
+ FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0;
+ FIXP_SGL bw = FL2FXCONST_SGL(0.0f);
+
+ int autoCorrLength;
+
+ FIXP_DBL k1, k1_below = 0, k1_below2 = 0;
+
+ ACORR_COEFS ac;
+ int startSample;
+ int stopSample;
+ int stopSampleClear;
+
+ int comLowBandScale;
+ int ovLowBandShift;
+ int lowBandShift;
+ /* int ovHighBandShift;*/
+
+ alphai[0] = FL2FXCONST_SGL(0.0f);
+ alphai[1] = FL2FXCONST_SGL(0.0f);
+
+ startSample = firstSlotOffs * timeStep;
+ stopSample = pSettings->nCols + lastSlotOffs * timeStep;
+ FDK_ASSERT((lastSlotOffs * timeStep) <= pSettings->overlap);
+
+ inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode,
+ sbr_invf_mode_prev, bwVector);
+
+ stopSampleClear = stopSample;
+
+ autoCorrLength = pSettings->nCols + pSettings->overlap;
+
+ if (pSettings->noOfPatches > 0) {
+ /* Set upper subbands to zero:
+ This is required in case that the patches do not cover the complete
+ highband (because the last patch would be too short). Possible
+ optimization: Clearing bands up to usb would be sufficient here. */
+ int targetStopBand =
+ patchParam[pSettings->noOfPatches - 1].targetStartBand +
+ patchParam[pSettings->noOfPatches - 1].numBandsInPatch;
+
+ int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL);
+
+ if (!useLP) {
+ for (i = startSample; i < stopSampleClear; i++) {
+ FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
+ FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize);
+ }
+ } else {
+ for (i = startSample; i < stopSampleClear; i++) {
+ FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
+ }
+ }
+ }
+#ifdef __ANDROID__
+ else {
+ // Safetynet logging
+ android_errorWriteLog(0x534e4554, "112160868");
+ }
+#endif
+
+ /* init bwIndex for each patch */
+ FDKmemclear(bwIndex, sizeof(bwIndex));
+
+ /*
+ Calc common low band scale factor
+ */
+ comLowBandScale =
+ fixMin(sbrScaleFactor->ov_lb_scale, sbrScaleFactor->lb_scale);
+
+ ovLowBandShift = sbrScaleFactor->ov_lb_scale - comLowBandScale;
+ lowBandShift = sbrScaleFactor->lb_scale - comLowBandScale;
+ /* ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/
+
+ if (fPreWhitening) {
+ sbrDecoder_calculateGainVec(
+ qmfBufferReal, qmfBufferImag,
+ DFRACT_BITS - 1 - 16 -
+ sbrScaleFactor->ov_lb_scale, /* convert scale to exponent */
+ DFRACT_BITS - 1 - 16 -
+ sbrScaleFactor->lb_scale, /* convert scale to exponent */
+ pSettings->overlap, preWhiteningGains, preWhiteningGains_exp,
+ v_k_master0, startSample, stopSample);
+ }
+
+ /* outer loop over bands to do analysis only once for each band */
+
+ if (!useLP) {
+ start = pSettings->lbStartPatching;
+ stop = pSettings->lbStopPatching;
+ } else {
+ start = fixMax(1, pSettings->lbStartPatching - 2);
+ stop = patchParam[0].targetStartBand;
+ }
+
+ for (loBand = start; loBand < stop; loBand++) {
+ FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
+ FIXP_DBL *plowBandReal = lowBandReal;
+ FIXP_DBL **pqmfBufferReal =
+ qmfBufferReal + firstSlotOffs * timeStep /* + pSettings->overlap */;
+ FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
+ FIXP_DBL *plowBandImag = lowBandImag;
+ FIXP_DBL **pqmfBufferImag =
+ qmfBufferImag + firstSlotOffs * timeStep /* + pSettings->overlap */;
+ int resetLPCCoeffs = 0;
+ int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR;
+ int acDetScale = 0; /* scaling of autocorrelation determinant */
+
+ for (i = 0;
+ i < LPC_ORDER + firstSlotOffs * timeStep /*+pSettings->overlap*/;
+ i++) {
+ *plowBandReal++ = hLppTrans->lpcFilterStatesRealLegSBR[i][loBand];
+ if (!useLP)
+ *plowBandImag++ = hLppTrans->lpcFilterStatesImagLegSBR[i][loBand];
+ }
+
+ /*
+ Take old slope length qmf slot source values out of (overlap)qmf buffer
+ */
+ if (!useLP) {
+ for (i = 0;
+ i < pSettings->nCols + pSettings->overlap - firstSlotOffs * timeStep;
+ i++) {
+ *plowBandReal++ = (*pqmfBufferReal++)[loBand];
+ *plowBandImag++ = (*pqmfBufferImag++)[loBand];
+ }
+ } else {
+ /* pSettings->overlap is always even */
+ FDK_ASSERT((pSettings->overlap & 1) == 0);
+ for (i = 0; i < ((pSettings->nCols + pSettings->overlap -
+ firstSlotOffs * timeStep) >>
+ 1);
+ i++) {
+ *plowBandReal++ = (*pqmfBufferReal++)[loBand];
+ *plowBandReal++ = (*pqmfBufferReal++)[loBand];
+ }
+ if (pSettings->nCols & 1) {
+ *plowBandReal++ = (*pqmfBufferReal++)[loBand];
+ }
+ }
+
+ /*
+ Determine dynamic scaling value.
+ */
+ dynamicScale =
+ fixMin(dynamicScale,
+ getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) +
+ ovLowBandShift);
+ dynamicScale =
+ fixMin(dynamicScale,
+ getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap],
+ pSettings->nCols) +
+ lowBandShift);
+ if (!useLP) {
+ dynamicScale =
+ fixMin(dynamicScale,
+ getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) +
+ ovLowBandShift);
+ dynamicScale =
+ fixMin(dynamicScale,
+ getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap],
+ pSettings->nCols) +
+ lowBandShift);
+ }
+ dynamicScale = fixMax(
+ 0, dynamicScale - 1); /* one additional bit headroom to prevent -1.0 */
+
+ /*
+ Scale temporal QMF buffer.
+ */
+ scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap,
+ dynamicScale - ovLowBandShift);
+ scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols,
+ dynamicScale - lowBandShift);
+
+ if (!useLP) {
+ scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap,
+ dynamicScale - ovLowBandShift);
+ scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap],
+ pSettings->nCols, dynamicScale - lowBandShift);
+ }
+
+ if (!useLP) {
+ acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER,
+ lowBandImag + LPC_ORDER, autoCorrLength);
+ } else {
+ acDetScale +=
+ autoCorr2nd_real(&ac, lowBandReal + LPC_ORDER, autoCorrLength);
+ }
+
+ /* Examine dynamic of determinant in autocorrelation. */
+ acDetScale += 2 * (comLowBandScale + dynamicScale);
+ acDetScale *= 2; /* two times reflection coefficent scaling */
+ acDetScale += ac.det_scale; /* ac scaling of determinant */
+
+ /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */
+ if (acDetScale > 126) {
+ resetLPCCoeffs = 1;
+ }
+
+ alphar[1] = FL2FXCONST_SGL(0.0f);
+ if (!useLP) alphai[1] = FL2FXCONST_SGL(0.0f);
+
+ if (ac.det != FL2FXCONST_DBL(0.0f)) {
+ FIXP_DBL tmp, absTmp, absDet;
+
+ absDet = fixp_abs(ac.det);
+
+ if (!useLP) {
+ tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
+ ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >>
+ (LPC_SCALE_FACTOR - 1));
+ } else {
+ tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
+ (fMultDiv2(ac.r02r, ac.r11r) >> (LPC_SCALE_FACTOR - 1));
+ }
+ absTmp = fixp_abs(tmp);
+
+ /*
+ Quick check: is first filter coeff >= 1(4)
+ */
+ {
+ INT scale;
+ FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
+ scale = scale + ac.det_scale;
+
+ if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
+ resetLPCCoeffs = 1;
+ } else {
+ alphar[1] = FX_DBL2FX_SGL(scaleValue(result, scale));
+ if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
+ alphar[1] = -alphar[1];
+ }
+ }
+ }
+
+ if (!useLP) {
+ tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) +
+ ((fMultDiv2(ac.r01r, ac.r12i) -
+ (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >>
+ (LPC_SCALE_FACTOR - 1));
+
+ absTmp = fixp_abs(tmp);
+
+ /*
+ Quick check: is second filter coeff >= 1(4)
+ */
+ {
+ INT scale;
+ FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
+ scale = scale + ac.det_scale;
+
+ if ((scale > 0) &&
+ (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >>
+ scale)) {
+ resetLPCCoeffs = 1;
+ } else {
+ alphai[1] = FX_DBL2FX_SGL(scaleValue(result, scale));
+ if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
+ alphai[1] = -alphai[1];
+ }
+ }
+ }
+ }
+ }
+
+ alphar[0] = FL2FXCONST_SGL(0.0f);
+ if (!useLP) alphai[0] = FL2FXCONST_SGL(0.0f);
+
+ if (ac.r11r != FL2FXCONST_DBL(0.0f)) {
+ /* ac.r11r is always >=0 */
+ FIXP_DBL tmp, absTmp;
+
+ if (!useLP) {
+ tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
+ (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i));
+ } else {
+ if (ac.r01r >= FL2FXCONST_DBL(0.0f))
+ tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
+ fMultDiv2(alphar[1], ac.r12r);
+ else
+ tmp = -((-ac.r01r) >> (LPC_SCALE_FACTOR + 1)) +
+ fMultDiv2(alphar[1], ac.r12r);
+ }
+
+ absTmp = fixp_abs(tmp);
+
+ /*
+ Quick check: is first filter coeff >= 1(4)
+ */
+
+ if (absTmp >= (ac.r11r >> 1)) {
+ resetLPCCoeffs = 1;
+ } else {
+ INT scale;
+ FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
+ alphar[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1));
+
+ if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
+ alphar[0] = -alphar[0];
+ }
+
+ if (!useLP) {
+ tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) +
+ (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i));
+
+ absTmp = fixp_abs(tmp);
+
+ /*
+ Quick check: is second filter coeff >= 1(4)
+ */
+ if (absTmp >= (ac.r11r >> 1)) {
+ resetLPCCoeffs = 1;
+ } else {
+ INT scale;
+ FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
+ alphai[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1));
+ if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
+ alphai[0] = -alphai[0];
+ }
+ }
+ }
+
+ if (!useLP) {
+ /* Now check the quadratic criteria */
+ if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >=
+ FL2FXCONST_DBL(0.5f))
+ resetLPCCoeffs = 1;
+ if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >=
+ FL2FXCONST_DBL(0.5f))
+ resetLPCCoeffs = 1;
+ }
+
+ if (resetLPCCoeffs) {
+ alphar[0] = FL2FXCONST_SGL(0.0f);
+ alphar[1] = FL2FXCONST_SGL(0.0f);
+ if (!useLP) {
+ alphai[0] = FL2FXCONST_SGL(0.0f);
+ alphai[1] = FL2FXCONST_SGL(0.0f);
+ }
+ }
+
+ if (useLP) {
+ /* Aliasing detection */
+ if (ac.r11r == FL2FXCONST_DBL(0.0f)) {
+ k1 = FL2FXCONST_DBL(0.0f);
+ } else {
+ if (fixp_abs(ac.r01r) >= fixp_abs(ac.r11r)) {
+ if (fMultDiv2(ac.r01r, ac.r11r) < FL2FX_DBL(0.0f)) {
+ k1 = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_SGL(1.0f)*/;
+ } else {
+ /* Since this value is squared later, it must not ever become -1.0f.
+ */
+ k1 = (FIXP_DBL)(MINVAL_DBL + 1) /*FL2FXCONST_SGL(-1.0f)*/;
+ }
+ } else {
+ INT scale;
+ FIXP_DBL result =
+ fDivNorm(fixp_abs(ac.r01r), fixp_abs(ac.r11r), &scale);
+ k1 = scaleValue(result, scale);
+
+ if (!((ac.r01r < FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))) {
+ k1 = -k1;
+ }
+ }
+ }
+ if ((loBand > 1) && (loBand < v_k_master0)) {
+ /* Check if the gain should be locked */
+ FIXP_DBL deg =
+ /*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - fPow2(k1_below);
+ degreeAlias[loBand] = FL2FXCONST_DBL(0.0f);
+ if (((loBand & 1) == 0) && (k1 < FL2FXCONST_DBL(0.0f))) {
+ if (k1_below < FL2FXCONST_DBL(0.0f)) { /* 2-Ch Aliasing Detection */
+ degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/;
+ if (k1_below2 >
+ FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */
+ degreeAlias[loBand - 1] = deg;
+ }
+ } else if (k1_below2 >
+ FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */
+ degreeAlias[loBand] = deg;
+ }
+ }
+ if (((loBand & 1) == 1) && (k1 > FL2FXCONST_DBL(0.0f))) {
+ if (k1_below > FL2FXCONST_DBL(0.0f)) { /* 2-CH Aliasing Detection */
+ degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/;
+ if (k1_below2 <
+ FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */
+ degreeAlias[loBand - 1] = deg;
+ }
+ } else if (k1_below2 <
+ FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */
+ degreeAlias[loBand] = deg;
+ }
+ }
+ }
+ /* remember k1 values of the 2 QMF channels below the current channel */
+ k1_below2 = k1_below;
+ k1_below = k1;
+ }
+
+ patch = 0;
+
+ while (patch < pSettings->noOfPatches) { /* inner loop over every patch */
+
+ int hiBand = loBand + patchParam[patch].targetBandOffs;
+
+ if (loBand < patchParam[patch].sourceStartBand ||
+ loBand >= patchParam[patch].sourceStopBand
+ //|| hiBand >= hLppTrans->pSettings->noChannels
+ ) {
+ /* Lowband not in current patch - proceed */
+ patch++;
+ continue;
+ }
+
+ FDK_ASSERT(hiBand < (64));
+
+ /* bwIndex[patch] is already initialized with value from previous band
+ * inside this patch */
+ while (hiBand >= pSettings->bwBorders[bwIndex[patch]] &&
+ bwIndex[patch] < MAX_NUM_PATCHES - 1) {
+ bwIndex[patch]++;
+ }
+
+ /*
+ Filter Step 2: add the left slope with the current filter to the buffer
+ pure source values are already in there
+ */
+ bw = FX_DBL2FX_SGL(bwVector[bwIndex[patch]]);
+
+ a0r = FX_DBL2FX_SGL(
+ fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */
+
+ if (!useLP) a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0]));
+ bw = FX_DBL2FX_SGL(fPow2(bw));
+ a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1]));
+ if (!useLP) a1i = FX_DBL2FX_SGL(fMult(bw, alphai[1]));
+
+ /*
+ Filter Step 3: insert the middle part which won't be windowed
+ */
+ if (bw <= FL2FXCONST_SGL(0.0f)) {
+ if (!useLP) {
+ int descale =
+ fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
+ for (i = startSample; i < stopSample; i++) {
+ FIXP_DBL accu1, accu2;
+ accu1 = lowBandReal[LPC_ORDER + i] >> descale;
+ accu2 = lowBandImag[LPC_ORDER + i] >> descale;
+ if (fPreWhitening) {
+ accu1 = scaleValueSaturate(
+ fMultDiv2(accu1, preWhiteningGains[loBand]),
+ preWhiteningGains_exp[loBand] + 1);
+ accu2 = scaleValueSaturate(
+ fMultDiv2(accu2, preWhiteningGains[loBand]),
+ preWhiteningGains_exp[loBand] + 1);
+ }
+ qmfBufferReal[i][hiBand] = accu1;
+ qmfBufferImag[i][hiBand] = accu2;
+ }
+ } else {
+ int descale =
+ fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
+ for (i = startSample; i < stopSample; i++) {
+ qmfBufferReal[i][hiBand] = lowBandReal[LPC_ORDER + i] >> descale;
+ }
+ }
+ } else { /* bw <= 0 */
+
+ if (!useLP) {
+ int descale =
+ fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
+#ifdef FUNCTION_LPPTRANSPOSER_func1
+ lppTransposer_func1(
+ lowBandReal + LPC_ORDER + startSample,
+ lowBandImag + LPC_ORDER + startSample,
+ qmfBufferReal + startSample, qmfBufferImag + startSample,
+ stopSample - startSample, (int)hiBand, dynamicScale, descale, a0r,
+ a0i, a1r, a1i, fPreWhitening, preWhiteningGains[loBand],
+ preWhiteningGains_exp[loBand] + 1);
+#else
+ for (i = startSample; i < stopSample; i++) {
+ FIXP_DBL accu1, accu2;
+
+ accu1 = (fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) -
+ fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1]) +
+ fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) -
+ fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >>
+ dynamicScale;
+ accu2 = (fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) +
+ fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1]) +
+ fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) +
+ fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >>
+ dynamicScale;
+
+ accu1 = (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1);
+ accu2 = (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1);
+ if (fPreWhitening) {
+ accu1 = scaleValueSaturate(
+ fMultDiv2(accu1, preWhiteningGains[loBand]),
+ preWhiteningGains_exp[loBand] + 1);
+ accu2 = scaleValueSaturate(
+ fMultDiv2(accu2, preWhiteningGains[loBand]),
+ preWhiteningGains_exp[loBand] + 1);
+ }
+ qmfBufferReal[i][hiBand] = accu1;
+ qmfBufferImag[i][hiBand] = accu2;
+ }
+#endif
+ } else {
+ FDK_ASSERT(dynamicScale >= 0);
+ calc_qmfBufferReal(
+ qmfBufferReal, &(lowBandReal[LPC_ORDER + startSample - 2]),
+ startSample, stopSample, hiBand, dynamicScale,
+ fMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)), a0r,
+ a1r);
+ }
+ } /* bw <= 0 */
+
+ patch++;
+
+ } /* inner loop over patches */
+
+ /*
+ * store the unmodified filter coefficients if there is
+ * an overlapping envelope
+ *****************************************************************/
+
+ } /* outer loop over bands (loBand) */
+
+ if (useLP) {
+ for (loBand = pSettings->lbStartPatching;
+ loBand < pSettings->lbStopPatching; loBand++) {
+ patch = 0;
+ while (patch < pSettings->noOfPatches) {
+ UCHAR hiBand = loBand + patchParam[patch].targetBandOffs;
+
+ if (loBand < patchParam[patch].sourceStartBand ||
+ loBand >= patchParam[patch].sourceStopBand ||
+ hiBand >= (64) /* Highband out of range (biterror) */
+ ) {
+ /* Lowband not in current patch or highband out of range (might be
+ * caused by biterrors)- proceed */
+ patch++;
+ continue;
+ }
+
+ if (hiBand != patchParam[patch].targetStartBand)
+ degreeAlias[hiBand] = degreeAlias[loBand];
+
+ patch++;
+ }
+ } /* end for loop */
+ }
+
+ for (i = 0; i < nInvfBands; i++) {
+ hLppTrans->bwVectorOld[i] = bwVector[i];
+ }
+
+ /*
+ set high band scale factor
+ */
+ sbrScaleFactor->hb_scale = comLowBandScale - (LPC_SCALE_FACTOR);
+}
+
+void lppTransposerHBE(
+ HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */
+ HANDLE_HBE_TRANSPOSER hQmfTransposer,
+ QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
+ FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband
+ samples (source) */
+ FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of
+ subband samples (source) */
+ const int timeStep, /*!< Time step of envelope */
+ const int firstSlotOffs, /*!< Start position in time */
+ const int lastSlotOffs, /*!< Number of overlap-slots into next frame */
+ const int nInvfBands, /*!< Number of bands for inverse filtering */
+ INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */
+ INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */
+) {
+ INT bwIndex;
+ FIXP_DBL bwVector[MAX_NUM_PATCHES_HBE]; /*!< pole moving factors */
+
+ int i;
+ int loBand, start, stop;
+ TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
+ PATCH_PARAM *patchParam = pSettings->patchParam;
+
+ FIXP_SGL alphar[LPC_ORDER], a0r, a1r;
+ FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0;
+ FIXP_SGL bw = FL2FXCONST_SGL(0.0f);
+
+ int autoCorrLength;
+
+ ACORR_COEFS ac;
+ int startSample;
+ int stopSample;
+ int stopSampleClear;
+
+ int comBandScale;
+ int ovLowBandShift;
+ int lowBandShift;
+ /* int ovHighBandShift;*/
+
+ alphai[0] = FL2FXCONST_SGL(0.0f);
+ alphai[1] = FL2FXCONST_SGL(0.0f);
+
+ startSample = firstSlotOffs * timeStep;
+ stopSample = pSettings->nCols + lastSlotOffs * timeStep;
+
+ inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode,
+ sbr_invf_mode_prev, bwVector);
+
+ stopSampleClear = stopSample;
+
+ autoCorrLength = pSettings->nCols + pSettings->overlap;
+
+ if (pSettings->noOfPatches > 0) {
+ /* Set upper subbands to zero:
+ This is required in case that the patches do not cover the complete
+ highband (because the last patch would be too short). Possible
+ optimization: Clearing bands up to usb would be sufficient here. */
+ int targetStopBand =
+ patchParam[pSettings->noOfPatches - 1].targetStartBand +
+ patchParam[pSettings->noOfPatches - 1].numBandsInPatch;
+
+ int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL);
+
+ for (i = startSample; i < stopSampleClear; i++) {
+ FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize);
+ FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize);
+ }
+ }
+#ifdef __ANDROID__
+ else {
+ // Safetynet logging
+ android_errorWriteLog(0x534e4554, "112160868");
+ }
+#endif
+
+ /*
+ Calc common low band scale factor
+ */
+ comBandScale = sbrScaleFactor->hb_scale;
+
+ ovLowBandShift = sbrScaleFactor->hb_scale - comBandScale;
+ lowBandShift = sbrScaleFactor->hb_scale - comBandScale;
+ /* ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/
+
+ /* outer loop over bands to do analysis only once for each band */
+
+ start = hQmfTransposer->startBand;
+ stop = hQmfTransposer->stopBand;
+
+ for (loBand = start; loBand < stop; loBand++) {
+ bwIndex = 0;
+
+ FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
+ FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER];
+
+ int resetLPCCoeffs = 0;
+ int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR;
+ int acDetScale = 0; /* scaling of autocorrelation determinant */
+
+ for (i = 0; i < LPC_ORDER; i++) {
+ lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand];
+ lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand];
+ }
+
+ for (; i < LPC_ORDER + firstSlotOffs * timeStep; i++) {
+ lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand];
+ lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand];
+ }
+
+ /*
+ Take old slope length qmf slot source values out of (overlap)qmf buffer
+ */
+ for (i = firstSlotOffs * timeStep;
+ i < pSettings->nCols + pSettings->overlap; i++) {
+ lowBandReal[i + LPC_ORDER] = qmfBufferReal[i][loBand];
+ lowBandImag[i + LPC_ORDER] = qmfBufferImag[i][loBand];
+ }
+
+ /* store unmodified values to buffer */
+ for (i = 0; i < LPC_ORDER + pSettings->overlap; i++) {
+ hLppTrans->lpcFilterStatesRealHBE[i][loBand] =
+ qmfBufferReal[pSettings->nCols - LPC_ORDER + i][loBand];
+ hLppTrans->lpcFilterStatesImagHBE[i][loBand] =
+ qmfBufferImag[pSettings->nCols - LPC_ORDER + i][loBand];
+ }
+
+ /*
+ Determine dynamic scaling value.
+ */
+ dynamicScale =
+ fixMin(dynamicScale,
+ getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) +
+ ovLowBandShift);
+ dynamicScale =
+ fixMin(dynamicScale,
+ getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap],
+ pSettings->nCols) +
+ lowBandShift);
+ dynamicScale =
+ fixMin(dynamicScale,
+ getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) +
+ ovLowBandShift);
+ dynamicScale =
+ fixMin(dynamicScale,
+ getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap],
+ pSettings->nCols) +
+ lowBandShift);
+
+ dynamicScale = fixMax(
+ 0, dynamicScale - 1); /* one additional bit headroom to prevent -1.0 */
+
+ /*
+ Scale temporal QMF buffer.
+ */
+ scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap,
+ dynamicScale - ovLowBandShift);
+ scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols,
+ dynamicScale - lowBandShift);
+ scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap,
+ dynamicScale - ovLowBandShift);
+ scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap], pSettings->nCols,
+ dynamicScale - lowBandShift);
+
+ acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER,
+ lowBandImag + LPC_ORDER, autoCorrLength);
+
+ /* Examine dynamic of determinant in autocorrelation. */
+ acDetScale += 2 * (comBandScale + dynamicScale);
+ acDetScale *= 2; /* two times reflection coefficent scaling */
+ acDetScale += ac.det_scale; /* ac scaling of determinant */
+
+ /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */
+ if (acDetScale > 126) {
+ resetLPCCoeffs = 1;
+ }
+
+ alphar[1] = FL2FXCONST_SGL(0.0f);
+ alphai[1] = FL2FXCONST_SGL(0.0f);
+
+ if (ac.det != FL2FXCONST_DBL(0.0f)) {
+ FIXP_DBL tmp, absTmp, absDet;
+
+ absDet = fixp_abs(ac.det);
+
+ tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) -
+ ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >>
+ (LPC_SCALE_FACTOR - 1));
+ absTmp = fixp_abs(tmp);
+
+ /*
+ Quick check: is first filter coeff >= 1(4)
+ */
+ {
+ INT scale;
+ FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
+ scale = scale + ac.det_scale;
+
+ if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
+ resetLPCCoeffs = 1;
+ } else {
+ alphar[1] = FX_DBL2FX_SGL(scaleValue(result, scale));
+ if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
+ alphar[1] = -alphar[1];
+ }
+ }
+ }
+
+ tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) +
+ ((fMultDiv2(ac.r01r, ac.r12i) -
+ (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >>
+ (LPC_SCALE_FACTOR - 1));
+
+ absTmp = fixp_abs(tmp);
+
+ /*
+ Quick check: is second filter coeff >= 1(4)
+ */
+ {
+ INT scale;
+ FIXP_DBL result = fDivNorm(absTmp, absDet, &scale);
+ scale = scale + ac.det_scale;
+
+ if ((scale > 0) &&
+ (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> scale)) {
+ resetLPCCoeffs = 1;
+ } else {
+ alphai[1] = FX_DBL2FX_SGL(scaleValue(result, scale));
+ if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
+ alphai[1] = -alphai[1];
+ }
+ }
+ }
+ }
+
+ alphar[0] = FL2FXCONST_SGL(0.0f);
+ alphai[0] = FL2FXCONST_SGL(0.0f);
+
+ if (ac.r11r != FL2FXCONST_DBL(0.0f)) {
+ /* ac.r11r is always >=0 */
+ FIXP_DBL tmp, absTmp;
+
+ tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) +
+ (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i));
+
+ absTmp = fixp_abs(tmp);
+
+ /*
+ Quick check: is first filter coeff >= 1(4)
+ */
+
+ if (absTmp >= (ac.r11r >> 1)) {
+ resetLPCCoeffs = 1;
+ } else {
+ INT scale;
+ FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
+ alphar[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1));
+
+ if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
+ alphar[0] = -alphar[0];
+ }
+
+ tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) +
+ (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i));
+
+ absTmp = fixp_abs(tmp);
+
+ /*
+ Quick check: is second filter coeff >= 1(4)
+ */
+ if (absTmp >= (ac.r11r >> 1)) {
+ resetLPCCoeffs = 1;
+ } else {
+ INT scale;
+ FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
+ alphai[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1));
+ if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) {
+ alphai[0] = -alphai[0];
+ }
+ }
+ }
+
+ /* Now check the quadratic criteria */
+ if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >=
+ FL2FXCONST_DBL(0.5f)) {
+ resetLPCCoeffs = 1;
+ }
+ if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >=
+ FL2FXCONST_DBL(0.5f)) {
+ resetLPCCoeffs = 1;
+ }
+
+ if (resetLPCCoeffs) {
+ alphar[0] = FL2FXCONST_SGL(0.0f);
+ alphar[1] = FL2FXCONST_SGL(0.0f);
+ alphai[0] = FL2FXCONST_SGL(0.0f);
+ alphai[1] = FL2FXCONST_SGL(0.0f);
+ }
+
+ while (bwIndex < MAX_NUM_PATCHES - 1 &&
+ loBand >= pSettings->bwBorders[bwIndex]) {
+ bwIndex++;
+ }
+
+ /*
+ Filter Step 2: add the left slope with the current filter to the buffer
+ pure source values are already in there
+ */
+ bw = FX_DBL2FX_SGL(bwVector[bwIndex]);
+
+ a0r = FX_DBL2FX_SGL(
+ fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */
+ a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0]));
+ bw = FX_DBL2FX_SGL(fPow2(bw));
+ a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1]));
+ a1i = FX_DBL2FX_SGL(fMult(bw, alphai[1]));
+
+ /*
+ Filter Step 3: insert the middle part which won't be windowed
+ */
+ if (bw <= FL2FXCONST_SGL(0.0f)) {
+ int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
+ for (i = startSample; i < stopSample; i++) {
+ qmfBufferReal[i][loBand] = lowBandReal[LPC_ORDER + i] >> descale;
+ qmfBufferImag[i][loBand] = lowBandImag[LPC_ORDER + i] >> descale;
+ }
+ } else { /* bw <= 0 */
+
+ int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
+
+ for (i = startSample; i < stopSample; i++) {
+ FIXP_DBL accu1, accu2;
+
+ accu1 = (fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) -
+ fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1]) +
+ fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) -
+ fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >>
+ dynamicScale;
+ accu2 = (fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) +
+ fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1]) +
+ fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) +
+ fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >>
+ dynamicScale;
+
+ qmfBufferReal[i][loBand] =
+ (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1);
+ qmfBufferImag[i][loBand] =
+ (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1);
+ }
+ } /* bw <= 0 */
+
+ /*
+ * store the unmodified filter coefficients if there is
+ * an overlapping envelope
+ *****************************************************************/
+
+ } /* outer loop over bands (loBand) */
+
+ for (i = 0; i < nInvfBands; i++) {
+ hLppTrans->bwVectorOld[i] = bwVector[i];
+ }
+
+ /*
+ set high band scale factor
+ */
+ sbrScaleFactor->hb_scale = comBandScale - (LPC_SCALE_FACTOR);
+}
+
+/*!
+ *
+ * \brief Initialize one low power transposer instance
+ *
+ *
+ */
+SBR_ERROR
+createLppTransposer(
+ HANDLE_SBR_LPP_TRANS hs, /*!< Handle of low power transposer */
+ TRANSPOSER_SETTINGS *pSettings, /*!< Pointer to settings */
+ const int highBandStartSb, /*!< ? */
+ UCHAR *v_k_master, /*!< Master table */
+ const int numMaster, /*!< Valid entries in master table */
+ const int usb, /*!< Highband area stop subband */
+ const int timeSlots, /*!< Number of time slots */
+ const int nCols, /*!< Number of colums (codec qmf bank) */
+ UCHAR *noiseBandTable, /*!< Mapping of SBR noise bands to QMF bands */
+ const int noNoiseBands, /*!< Number of noise bands */
+ UINT fs, /*!< Sample Frequency */
+ const int chan, /*!< Channel number */
+ const int overlap) {
+ /* FB inverse filtering settings */
+ hs->pSettings = pSettings;
+
+ pSettings->nCols = nCols;
+ pSettings->overlap = overlap;
+
+ switch (timeSlots) {
+ case 15:
+ case 16:
+ break;
+
+ default:
+ return SBRDEC_UNSUPPORTED_CONFIG; /* Unimplemented */
+ }
+
+ if (chan == 0) {
+ /* Init common data only once */
+ hs->pSettings->nCols = nCols;
+
+ return resetLppTransposer(hs, highBandStartSb, v_k_master, numMaster,
+ noiseBandTable, noNoiseBands, usb, fs);
+ }
+ return SBRDEC_OK;
+}
+
+static int findClosestEntry(UCHAR goalSb, UCHAR *v_k_master, UCHAR numMaster,
+ UCHAR direction) {
+ int index;
+
+ if (goalSb <= v_k_master[0]) return v_k_master[0];
+
+ if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster];
+
+ if (direction) {
+ index = 0;
+ while (v_k_master[index] < goalSb) {
+ index++;
+ }
+ } else {
+ index = numMaster;
+ while (v_k_master[index] > goalSb) {
+ index--;
+ }
+ }
+
+ return v_k_master[index];
+}
+
+/*!
+ *
+ * \brief Reset memory for one lpp transposer instance
+ *
+ * \return SBRDEC_OK on success, SBRDEC_UNSUPPORTED_CONFIG on error
+ */
+SBR_ERROR
+resetLppTransposer(
+ HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */
+ UCHAR highBandStartSb, /*!< High band area: start subband */
+ UCHAR *v_k_master, /*!< Master table */
+ UCHAR numMaster, /*!< Valid entries in master table */
+ UCHAR *noiseBandTable, /*!< Mapping of SBR noise bands to QMF bands */
+ UCHAR noNoiseBands, /*!< Number of noise bands */
+ UCHAR usb, /*!< High band area: stop subband */
+ UINT fs /*!< SBR output sampling frequency */
+) {
+ TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings;
+ PATCH_PARAM *patchParam = pSettings->patchParam;
+
+ int i, patch;
+ int targetStopBand;
+ int sourceStartBand;
+ int patchDistance;
+ int numBandsInPatch;
+
+ int lsb = v_k_master[0]; /* Start subband expressed in "non-critical" sampling
+ terms*/
+ int xoverOffset = highBandStartSb -
+ lsb; /* Calculate distance in QMF bands between k0 and kx */
+ int startFreqHz;
+
+ int desiredBorder;
+
+ usb = fixMin(usb, v_k_master[numMaster]); /* Avoid endless loops (compare with
+ float code). */
+
+ /*
+ * Plausibility check
+ */
+
+ if (pSettings->nCols == 64) {
+ if (lsb < 4) {
+ /* 4:1 SBR Requirement k0 >= 4 missed! */
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+ } else if (lsb - SHIFT_START_SB < 4) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ /*
+ * Initialize the patching parameter
+ */
+ /* ISO/IEC 14496-3 (Figure 4.48): goalSb = round( 2.048e6 / fs ) */
+ desiredBorder = (((2048000 * 2) / fs) + 1) >> 1;
+
+ desiredBorder = findClosestEntry(desiredBorder, v_k_master, numMaster,
+ 1); /* Adapt region to master-table */
+
+ /* First patch */
+ sourceStartBand = SHIFT_START_SB + xoverOffset;
+ targetStopBand = lsb + xoverOffset; /* upperBand */
+
+ /* Even (odd) numbered channel must be patched to even (odd) numbered channel
+ */
+ patch = 0;
+ while (targetStopBand < usb) {
+ /* Too many patches?
+ Allow MAX_NUM_PATCHES+1 patches here.
+ we need to check later again, since patch might be the highest patch
+ AND contain less than 3 bands => actual number of patches will be reduced
+ by 1.
+ */
+ if (patch > MAX_NUM_PATCHES) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ patchParam[patch].guardStartBand = targetStopBand;
+ patchParam[patch].targetStartBand = targetStopBand;
+
+ numBandsInPatch =
+ desiredBorder - targetStopBand; /* Get the desired range of the patch */
+
+ if (numBandsInPatch >= lsb - sourceStartBand) {
+ /* Desired number bands are not available -> patch whole source range */
+ patchDistance =
+ targetStopBand - sourceStartBand; /* Get the targetOffset */
+ patchDistance =
+ patchDistance & ~1; /* Rounding off odd numbers and make all even */
+ numBandsInPatch =
+ lsb - (targetStopBand -
+ patchDistance); /* Update number of bands to be patched */
+ numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch,
+ v_k_master, numMaster, 0) -
+ targetStopBand; /* Adapt region to master-table */
+ }
+
+ if (pSettings->nCols == 64) {
+ if (numBandsInPatch == 0 && sourceStartBand == SHIFT_START_SB) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+ }
+
+ /* Desired number bands are available -> get the minimal even patching
+ * distance */
+ patchDistance =
+ numBandsInPatch + targetStopBand - lsb; /* Get minimal distance */
+ patchDistance = (patchDistance + 1) &
+ ~1; /* Rounding up odd numbers and make all even */
+
+ if (numBandsInPatch > 0) {
+ patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
+ patchParam[patch].targetBandOffs = patchDistance;
+ patchParam[patch].numBandsInPatch = numBandsInPatch;
+ patchParam[patch].sourceStopBand =
+ patchParam[patch].sourceStartBand + numBandsInPatch;
+
+ targetStopBand += patchParam[patch].numBandsInPatch;
+ patch++;
+ }
+
+ /* All patches but first */
+ sourceStartBand = SHIFT_START_SB;
+
+ /* Check if we are close to desiredBorder */
+ if (desiredBorder - targetStopBand < 3) /* MPEG doc */
+ {
+ desiredBorder = usb;
+ }
+ }
+
+ patch--;
+
+ /* If highest patch contains less than three subband: skip it */
+ if ((patch > 0) && (patchParam[patch].numBandsInPatch < 3)) {
+ patch--;
+ targetStopBand =
+ patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch;
+ }
+
+ /* now check if we don't have one too many */
+ if (patch >= MAX_NUM_PATCHES) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ pSettings->noOfPatches = patch + 1;
+
+ /* Check lowest and highest source subband */
+ pSettings->lbStartPatching = targetStopBand;
+ pSettings->lbStopPatching = 0;
+ for (patch = 0; patch < pSettings->noOfPatches; patch++) {
+ pSettings->lbStartPatching =
+ fixMin(pSettings->lbStartPatching, patchParam[patch].sourceStartBand);
+ pSettings->lbStopPatching =
+ fixMax(pSettings->lbStopPatching, patchParam[patch].sourceStopBand);
+ }
+
+ for (i = 0; i < noNoiseBands; i++) {
+ pSettings->bwBorders[i] = noiseBandTable[i + 1];
+ }
+ for (; i < MAX_NUM_NOISE_VALUES; i++) {
+ pSettings->bwBorders[i] = 255;
+ }
+
+ /*
+ * Choose whitening factors
+ */
+
+ startFreqHz =
+ ((lsb + xoverOffset) * fs) >> 7; /* Shift does a division by 2*(64) */
+
+ for (i = 1; i < NUM_WHFACTOR_TABLE_ENTRIES; i++) {
+ if (startFreqHz < FDK_sbrDecoder_sbr_whFactorsIndex[i]) break;
+ }
+ i--;
+
+ pSettings->whFactors.off = FDK_sbrDecoder_sbr_whFactorsTable[i][0];
+ pSettings->whFactors.transitionLevel =
+ FDK_sbrDecoder_sbr_whFactorsTable[i][1];
+ pSettings->whFactors.lowLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][2];
+ pSettings->whFactors.midLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][3];
+ pSettings->whFactors.highLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][4];
+
+ return SBRDEC_OK;
+}
diff --git a/fdk-aac/libSBRdec/src/lpp_tran.h b/fdk-aac/libSBRdec/src/lpp_tran.h
new file mode 100644
index 0000000..51b4395
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/lpp_tran.h
@@ -0,0 +1,275 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Low Power Profile Transposer
+*/
+
+#ifndef LPP_TRAN_H
+#define LPP_TRAN_H
+
+#include "sbrdecoder.h"
+#include "hbe.h"
+#include "qmf.h"
+
+/*
+ Common
+*/
+#define QMF_OUT_SCALE 8
+
+/*
+ Frequency scales
+*/
+
+/*
+ Env-Adjust
+*/
+#define MAX_NOISE_ENVELOPES 2
+#define MAX_NOISE_COEFFS 5
+#define MAX_NUM_NOISE_VALUES (MAX_NOISE_ENVELOPES * MAX_NOISE_COEFFS)
+#define MAX_NUM_LIMITERS 12
+
+/* Set MAX_ENVELOPES to the largest value of all supported BSFORMATs
+ by overriding MAX_ENVELOPES in the correct order: */
+#define MAX_ENVELOPES_LEGACY 5
+#define MAX_ENVELOPES_USAC 8
+#define MAX_ENVELOPES MAX_ENVELOPES_USAC
+
+#define MAX_FREQ_COEFFS_DUAL_RATE 48
+#define MAX_FREQ_COEFFS_QUAD_RATE 56
+#define MAX_FREQ_COEFFS MAX_FREQ_COEFFS_QUAD_RATE
+
+#define MAX_FREQ_COEFFS_FS44100 35
+#define MAX_FREQ_COEFFS_FS48000 32
+
+#define MAX_NUM_ENVELOPE_VALUES (MAX_ENVELOPES * MAX_FREQ_COEFFS)
+
+#define MAX_GAIN_EXP 34
+/* Maximum gain will be sqrt(0.5 * 2^MAX_GAIN_EXP)
+ example: 34=99dB */
+#define MAX_GAIN_CONCEAL_EXP 1
+/* Maximum gain will be sqrt(0.5 * 2^MAX_GAIN_CONCEAL_EXP) in concealment case
+ * (0dB) */
+
+/*
+ LPP Transposer
+*/
+#define LPC_ORDER 2
+
+#define MAX_INVF_BANDS MAX_NOISE_COEFFS
+
+#define MAX_NUM_PATCHES 6
+#define SHIFT_START_SB 1 /*!< lowest subband of source range */
+
+typedef enum {
+ INVF_OFF = 0,
+ INVF_LOW_LEVEL,
+ INVF_MID_LEVEL,
+ INVF_HIGH_LEVEL,
+ INVF_SWITCHED /* not a real choice but used here to control behaviour */
+} INVF_MODE;
+
+/** parameter set for one single patch */
+typedef struct {
+ UCHAR sourceStartBand; /*!< first band in lowbands where to take the samples
+ from */
+ UCHAR
+ sourceStopBand; /*!< first band in lowbands which is not included in the
+ patch anymore */
+ UCHAR guardStartBand; /*!< first band in highbands to be filled with zeros in
+ order to reduce interferences between patches */
+ UCHAR
+ targetStartBand; /*!< first band in highbands to be filled with whitened
+ lowband signal */
+ UCHAR targetBandOffs; /*!< difference between 'startTargetBand' and
+ 'startSourceBand' */
+ UCHAR numBandsInPatch; /*!< number of consecutive bands in this one patch */
+} PATCH_PARAM;
+
+/** whitening factors for different levels of whitening
+ need to be initialized corresponding to crossover frequency */
+typedef struct {
+ FIXP_DBL off; /*!< bw factor for signal OFF */
+ FIXP_DBL transitionLevel;
+ FIXP_DBL lowLevel; /*!< bw factor for signal LOW_LEVEL */
+ FIXP_DBL midLevel; /*!< bw factor for signal MID_LEVEL */
+ FIXP_DBL highLevel; /*!< bw factor for signal HIGH_LEVEL */
+} WHITENING_FACTORS;
+
+/*! The transposer settings are calculated on a header reset and are shared by
+ * both channels. */
+typedef struct {
+ UCHAR nCols; /*!< number subsamples of a codec frame */
+ UCHAR noOfPatches; /*!< number of patches */
+ UCHAR lbStartPatching; /*!< first band of lowbands that will be patched */
+ UCHAR lbStopPatching; /*!< first band that won't be patched anymore*/
+ UCHAR bwBorders[MAX_NUM_NOISE_VALUES]; /*!< spectral bands with different
+ inverse filtering levels */
+
+ PATCH_PARAM
+ patchParam[MAX_NUM_PATCHES]; /*!< new parameter set for patching */
+ WHITENING_FACTORS
+ whFactors; /*!< the pole moving factors for certain
+ whitening levels as indicated in the bitstream
+ depending on the crossover frequency */
+ UCHAR overlap; /*!< Overlap size */
+} TRANSPOSER_SETTINGS;
+
+typedef struct {
+ TRANSPOSER_SETTINGS *pSettings; /*!< Common settings for both channels */
+ FIXP_DBL
+ bwVectorOld[MAX_NUM_PATCHES]; /*!< pole moving factors of past frame */
+ FIXP_DBL lpcFilterStatesRealLegSBR[LPC_ORDER + (3 * (4))][(
+ 32)]; /*!< pointer array to save filter states */
+
+ FIXP_DBL lpcFilterStatesImagLegSBR[LPC_ORDER + (3 * (4))][(
+ 32)]; /*!< pointer array to save filter states */
+
+ FIXP_DBL lpcFilterStatesRealHBE[LPC_ORDER + (3 * (4))][(
+ 64)]; /*!< pointer array to save filter states */
+ FIXP_DBL lpcFilterStatesImagHBE[LPC_ORDER + (3 * (4))][(
+ 64)]; /*!< pointer array to save filter states */
+} SBR_LPP_TRANS;
+
+typedef SBR_LPP_TRANS *HANDLE_SBR_LPP_TRANS;
+
+void lppTransposer(HANDLE_SBR_LPP_TRANS hLppTrans,
+ QMF_SCALE_FACTOR *sbrScaleFactor, FIXP_DBL **qmfBufferReal,
+
+ FIXP_DBL *degreeAlias, FIXP_DBL **qmfBufferImag,
+ const int useLP, const int fPreWhitening,
+ const int v_k_master0, const int timeStep,
+ const int firstSlotOffset, const int lastSlotOffset,
+ const int nInvfBands, INVF_MODE *sbr_invf_mode,
+ INVF_MODE *sbr_invf_mode_prev);
+
+void lppTransposerHBE(
+ HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */
+ HANDLE_HBE_TRANSPOSER hQmfTransposer,
+ QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
+ FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband
+ samples (source) */
+ FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of
+ subband samples (source) */
+ const int timeStep, /*!< Time step of envelope */
+ const int firstSlotOffs, /*!< Start position in time */
+ const int lastSlotOffs, /*!< Number of overlap-slots into next frame */
+ const int nInvfBands, /*!< Number of bands for inverse filtering */
+ INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */
+ INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */
+);
+
+SBR_ERROR
+createLppTransposer(HANDLE_SBR_LPP_TRANS hLppTrans,
+ TRANSPOSER_SETTINGS *pSettings, const int highBandStartSb,
+ UCHAR *v_k_master, const int numMaster, const int usb,
+ const int timeSlots, const int nCols, UCHAR *noiseBandTable,
+ const int noNoiseBands, UINT fs, const int chan,
+ const int overlap);
+
+SBR_ERROR
+resetLppTransposer(HANDLE_SBR_LPP_TRANS hLppTrans, UCHAR highBandStartSb,
+ UCHAR *v_k_master, UCHAR numMaster, UCHAR *noiseBandTable,
+ UCHAR noNoiseBands, UCHAR usb, UINT fs);
+
+#endif /* LPP_TRAN_H */
diff --git a/fdk-aac/libSBRdec/src/psbitdec.cpp b/fdk-aac/libSBRdec/src/psbitdec.cpp
new file mode 100644
index 0000000..82bb65b
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/psbitdec.cpp
@@ -0,0 +1,594 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "psbitdec.h"
+
+#include "sbr_rom.h"
+#include "huff_dec.h"
+
+/* PS dec privat functions */
+SBR_ERROR ResetPsDec(HANDLE_PS_DEC h_ps_d);
+
+/***************************************************************************/
+/*!
+ \brief huffman decoding by codebook table
+
+ \return index of huffman codebook table
+
+****************************************************************************/
+static SCHAR decode_huff_cw(
+ Huffman h, /*!< pointer to huffman codebook table */
+ HANDLE_FDK_BITSTREAM hBitBuf, /*!< Handle to Bitbuffer */
+ int *length) /*!< length of huffman codeword (or NULL) */
+{
+ UCHAR bit = 0;
+ SCHAR index = 0;
+ UCHAR bitCount = 0;
+
+ while (index >= 0) {
+ bit = FDKreadBits(hBitBuf, 1);
+ bitCount++;
+ index = h[index][bit];
+ }
+ if (length) {
+ *length = bitCount;
+ }
+ return (index + 64); /* Add offset */
+}
+
+/***************************************************************************/
+/*!
+ \brief helper function - limiting of value to min/max values
+
+ \return limited value
+
+****************************************************************************/
+
+static SCHAR limitMinMax(SCHAR i, SCHAR min, SCHAR max) {
+ if (i < min)
+ return min;
+ else if (i > max)
+ return max;
+ else
+ return i;
+}
+
+/***************************************************************************/
+/*!
+ \brief Decodes delta values in-place and updates
+ data buffers according to quantization classes.
+
+ When delta coded in frequency the first element is deltacode from zero.
+ aIndex buffer is decoded from delta values to actual values.
+
+ \return none
+
+****************************************************************************/
+static void deltaDecodeArray(
+ SCHAR enable, SCHAR *aIndex, /*!< ICC/IID parameters */
+ SCHAR *aPrevFrameIndex, /*!< ICC/IID parameters of previous frame */
+ SCHAR DtDf, UCHAR nrElements, /*!< as conveyed in bitstream */
+ /*!< output array size: nrElements*stride */
+ UCHAR stride, /*!< 1=dflt, 2=half freq. resolution */
+ SCHAR minIdx, SCHAR maxIdx) {
+ int i;
+
+ /* Delta decode */
+ if (enable == 1) {
+ if (DtDf == 0) { /* Delta coded in freq */
+ aIndex[0] = 0 + aIndex[0];
+ aIndex[0] = limitMinMax(aIndex[0], minIdx, maxIdx);
+ for (i = 1; i < nrElements; i++) {
+ aIndex[i] = aIndex[i - 1] + aIndex[i];
+ aIndex[i] = limitMinMax(aIndex[i], minIdx, maxIdx);
+ }
+ } else { /* Delta time */
+ for (i = 0; i < nrElements; i++) {
+ aIndex[i] = aPrevFrameIndex[i * stride] + aIndex[i];
+ aIndex[i] = limitMinMax(aIndex[i], minIdx, maxIdx);
+ }
+ }
+ } else { /* No data is sent, set index to zero */
+ for (i = 0; i < nrElements; i++) {
+ aIndex[i] = 0;
+ }
+ }
+ if (stride == 2) {
+ for (i = nrElements * stride - 1; i > 0; i--) {
+ aIndex[i] = aIndex[i >> 1];
+ }
+ }
+}
+
+/***************************************************************************/
+/*!
+ \brief Mapping of ICC/IID parameters to 20 stereo bands
+
+ \return none
+
+****************************************************************************/
+static void map34IndexTo20(SCHAR *aIndex, /*!< decoded ICC/IID parameters */
+ UCHAR noBins) /*!< number of stereo bands */
+{
+ aIndex[0] = (2 * aIndex[0] + aIndex[1]) / 3;
+ aIndex[1] = (aIndex[1] + 2 * aIndex[2]) / 3;
+ aIndex[2] = (2 * aIndex[3] + aIndex[4]) / 3;
+ aIndex[3] = (aIndex[4] + 2 * aIndex[5]) / 3;
+ aIndex[4] = (aIndex[6] + aIndex[7]) / 2;
+ aIndex[5] = (aIndex[8] + aIndex[9]) / 2;
+ aIndex[6] = aIndex[10];
+ aIndex[7] = aIndex[11];
+ aIndex[8] = (aIndex[12] + aIndex[13]) / 2;
+ aIndex[9] = (aIndex[14] + aIndex[15]) / 2;
+ aIndex[10] = aIndex[16];
+ /* For IPD/OPD it stops here */
+
+ if (noBins == NO_HI_RES_BINS) {
+ aIndex[11] = aIndex[17];
+ aIndex[12] = aIndex[18];
+ aIndex[13] = aIndex[19];
+ aIndex[14] = (aIndex[20] + aIndex[21]) / 2;
+ aIndex[15] = (aIndex[22] + aIndex[23]) / 2;
+ aIndex[16] = (aIndex[24] + aIndex[25]) / 2;
+ aIndex[17] = (aIndex[26] + aIndex[27]) / 2;
+ aIndex[18] = (aIndex[28] + aIndex[29] + aIndex[30] + aIndex[31]) / 4;
+ aIndex[19] = (aIndex[32] + aIndex[33]) / 2;
+ }
+}
+
+/***************************************************************************/
+/*!
+ \brief Decodes delta coded IID, ICC, IPD and OPD indices
+
+ \return PS processing flag. If set to 1
+
+****************************************************************************/
+int DecodePs(struct PS_DEC *h_ps_d, /*!< PS handle */
+ const UCHAR frameError, /*!< Flag telling that frame had errors */
+ PS_DEC_COEFFICIENTS *pScratch) {
+ MPEG_PS_BS_DATA *pBsData;
+ UCHAR gr, env;
+ int bPsHeaderValid, bPsDataAvail;
+
+ /* Assign Scratch */
+ h_ps_d->specificTo.mpeg.pCoef = pScratch;
+
+ /* Shortcuts to avoid deferencing and keep the code readable */
+ pBsData = &h_ps_d->bsData[h_ps_d->processSlot].mpeg;
+ bPsHeaderValid = pBsData->bPsHeaderValid;
+ bPsDataAvail =
+ (h_ps_d->bPsDataAvail[h_ps_d->processSlot] == ppt_mpeg) ? 1 : 0;
+
+ /***************************************************************************************
+ * Decide whether to process or to conceal PS data or not. */
+
+ if ((h_ps_d->psDecodedPrv && !frameError && !bPsDataAvail) ||
+ (!h_ps_d->psDecodedPrv &&
+ (frameError || !bPsDataAvail || !bPsHeaderValid))) {
+ /* Don't apply PS processing.
+ * Declare current PS header and bitstream data invalid. */
+ pBsData->bPsHeaderValid = 0;
+ h_ps_d->bPsDataAvail[h_ps_d->processSlot] = ppt_none;
+ return (0);
+ }
+
+ if (frameError ||
+ !bPsHeaderValid) { /* no new PS data available (e.g. frame loss) */
+ /* => keep latest data constant (i.e. FIX with noEnv=0) */
+ pBsData->noEnv = 0;
+ }
+
+ /***************************************************************************************
+ * Decode bitstream payload or prepare parameter for concealment:
+ */
+ for (env = 0; env < pBsData->noEnv; env++) {
+ SCHAR *aPrevIidIndex;
+ SCHAR *aPrevIccIndex;
+
+ UCHAR noIidSteps = pBsData->bFineIidQ ? NO_IID_STEPS_FINE : NO_IID_STEPS;
+
+ if (env == 0) {
+ aPrevIidIndex = h_ps_d->specificTo.mpeg.aIidPrevFrameIndex;
+ aPrevIccIndex = h_ps_d->specificTo.mpeg.aIccPrevFrameIndex;
+ } else {
+ aPrevIidIndex = pBsData->aaIidIndex[env - 1];
+ aPrevIccIndex = pBsData->aaIccIndex[env - 1];
+ }
+
+ deltaDecodeArray(pBsData->bEnableIid, pBsData->aaIidIndex[env],
+ aPrevIidIndex, pBsData->abIidDtFlag[env],
+ FDK_sbrDecoder_aNoIidBins[pBsData->freqResIid],
+ (pBsData->freqResIid) ? 1 : 2, -noIidSteps, noIidSteps);
+
+ deltaDecodeArray(pBsData->bEnableIcc, pBsData->aaIccIndex[env],
+ aPrevIccIndex, pBsData->abIccDtFlag[env],
+ FDK_sbrDecoder_aNoIccBins[pBsData->freqResIcc],
+ (pBsData->freqResIcc) ? 1 : 2, 0, NO_ICC_STEPS - 1);
+ } /* for (env=0; env<pBsData->noEnv; env++) */
+
+ /* handling of FIX noEnv=0 */
+ if (pBsData->noEnv == 0) {
+ /* set noEnv=1, keep last parameters or force 0 if not enabled */
+ pBsData->noEnv = 1;
+
+ if (pBsData->bEnableIid) {
+ pBsData->bFineIidQ = h_ps_d->specificTo.mpeg.bPrevFrameFineIidQ;
+ pBsData->freqResIid = h_ps_d->specificTo.mpeg.prevFreqResIid;
+ for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) {
+ pBsData->aaIidIndex[pBsData->noEnv - 1][gr] =
+ h_ps_d->specificTo.mpeg.aIidPrevFrameIndex[gr];
+ }
+ } else {
+ for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) {
+ pBsData->aaIidIndex[pBsData->noEnv - 1][gr] = 0;
+ }
+ }
+
+ if (pBsData->bEnableIcc) {
+ pBsData->freqResIcc = h_ps_d->specificTo.mpeg.prevFreqResIcc;
+ for (gr = 0; gr < NO_HI_RES_ICC_BINS; gr++) {
+ pBsData->aaIccIndex[pBsData->noEnv - 1][gr] =
+ h_ps_d->specificTo.mpeg.aIccPrevFrameIndex[gr];
+ }
+ } else {
+ for (gr = 0; gr < NO_HI_RES_ICC_BINS; gr++) {
+ pBsData->aaIccIndex[pBsData->noEnv - 1][gr] = 0;
+ }
+ }
+ }
+
+ /* Update previous frame Iid quantization */
+ h_ps_d->specificTo.mpeg.bPrevFrameFineIidQ = pBsData->bFineIidQ;
+
+ /* Update previous frequency resolution for IID */
+ h_ps_d->specificTo.mpeg.prevFreqResIid = pBsData->freqResIid;
+
+ /* Update previous frequency resolution for ICC */
+ h_ps_d->specificTo.mpeg.prevFreqResIcc = pBsData->freqResIcc;
+
+ /* Update previous frame index buffers */
+ for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) {
+ h_ps_d->specificTo.mpeg.aIidPrevFrameIndex[gr] =
+ pBsData->aaIidIndex[pBsData->noEnv - 1][gr];
+ }
+ for (gr = 0; gr < NO_HI_RES_ICC_BINS; gr++) {
+ h_ps_d->specificTo.mpeg.aIccPrevFrameIndex[gr] =
+ pBsData->aaIccIndex[pBsData->noEnv - 1][gr];
+ }
+
+ /* PS data from bitstream (if avail) was decoded now */
+ h_ps_d->bPsDataAvail[h_ps_d->processSlot] = ppt_none;
+
+ /* handling of env borders for FIX & VAR */
+ if (pBsData->bFrameClass == 0) {
+ /* FIX_BORDERS NoEnv=0,1,2,4 */
+ pBsData->aEnvStartStop[0] = 0;
+ for (env = 1; env < pBsData->noEnv; env++) {
+ pBsData->aEnvStartStop[env] =
+ (env * h_ps_d->noSubSamples) / pBsData->noEnv;
+ }
+ pBsData->aEnvStartStop[pBsData->noEnv] = h_ps_d->noSubSamples;
+ /* 1024 (32 slots) env borders: 0, 8, 16, 24, 32 */
+ /* 960 (30 slots) env borders: 0, 7, 15, 22, 30 */
+ } else { /* if (h_ps_d->bFrameClass == 0) */
+ /* VAR_BORDERS NoEnv=1,2,3,4 */
+ pBsData->aEnvStartStop[0] = 0;
+
+ /* handle case aEnvStartStop[noEnv]<noSubSample for VAR_BORDERS by
+ duplicating last PS parameters and incrementing noEnv */
+ if (pBsData->aEnvStartStop[pBsData->noEnv] < h_ps_d->noSubSamples) {
+ for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) {
+ pBsData->aaIidIndex[pBsData->noEnv][gr] =
+ pBsData->aaIidIndex[pBsData->noEnv - 1][gr];
+ }
+ for (gr = 0; gr < NO_HI_RES_ICC_BINS; gr++) {
+ pBsData->aaIccIndex[pBsData->noEnv][gr] =
+ pBsData->aaIccIndex[pBsData->noEnv - 1][gr];
+ }
+ pBsData->noEnv++;
+ pBsData->aEnvStartStop[pBsData->noEnv] = h_ps_d->noSubSamples;
+ }
+
+ /* enforce strictly monotonic increasing borders */
+ for (env = 1; env < pBsData->noEnv; env++) {
+ UCHAR thr;
+ thr = (UCHAR)h_ps_d->noSubSamples - (pBsData->noEnv - env);
+ if (pBsData->aEnvStartStop[env] > thr) {
+ pBsData->aEnvStartStop[env] = thr;
+ } else {
+ thr = pBsData->aEnvStartStop[env - 1] + 1;
+ if (pBsData->aEnvStartStop[env] < thr) {
+ pBsData->aEnvStartStop[env] = thr;
+ }
+ }
+ }
+ } /* if (h_ps_d->bFrameClass == 0) ... else */
+
+ /* copy data prior to possible 20<->34 in-place mapping */
+ for (env = 0; env < pBsData->noEnv; env++) {
+ UCHAR i;
+ for (i = 0; i < NO_HI_RES_IID_BINS; i++) {
+ h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env][i] =
+ pBsData->aaIidIndex[env][i];
+ }
+ for (i = 0; i < NO_HI_RES_ICC_BINS; i++) {
+ h_ps_d->specificTo.mpeg.pCoef->aaIccIndexMapped[env][i] =
+ pBsData->aaIccIndex[env][i];
+ }
+ }
+
+ /* MPEG baseline PS */
+ /* Baseline version of PS always uses the hybrid filter structure with 20
+ * stereo bands. */
+ /* If ICC/IID parameters for 34 stereo bands are decoded they have to be
+ * mapped to 20 */
+ /* stereo bands. */
+ /* Additionaly the IPD/OPD parameters won't be used. */
+
+ for (env = 0; env < pBsData->noEnv; env++) {
+ if (pBsData->freqResIid == 2)
+ map34IndexTo20(h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env],
+ NO_HI_RES_IID_BINS);
+ if (pBsData->freqResIcc == 2)
+ map34IndexTo20(h_ps_d->specificTo.mpeg.pCoef->aaIccIndexMapped[env],
+ NO_HI_RES_ICC_BINS);
+
+ /* IPD/OPD is disabled in baseline version and thus was removed here */
+ }
+
+ return (1);
+}
+
+/***************************************************************************/
+/*!
+
+ \brief Reads parametric stereo data from bitstream
+
+ \return
+
+****************************************************************************/
+unsigned int ReadPsData(
+ HANDLE_PS_DEC h_ps_d, /*!< handle to struct PS_DEC */
+ HANDLE_FDK_BITSTREAM hBitBuf, /*!< handle to struct BIT_BUF */
+ int nBitsLeft /*!< max number of bits available */
+) {
+ MPEG_PS_BS_DATA *pBsData;
+
+ UCHAR gr, env;
+ SCHAR dtFlag;
+ INT startbits;
+ Huffman CurrentTable;
+ SCHAR bEnableHeader;
+
+ if (!h_ps_d) return 0;
+
+ pBsData = &h_ps_d->bsData[h_ps_d->bsReadSlot].mpeg;
+
+ if (h_ps_d->bsReadSlot != h_ps_d->bsLastSlot) {
+ /* Copy last header data */
+ FDKmemcpy(pBsData, &h_ps_d->bsData[h_ps_d->bsLastSlot].mpeg,
+ sizeof(MPEG_PS_BS_DATA));
+ }
+
+ startbits = (INT)FDKgetValidBits(hBitBuf);
+
+ bEnableHeader = (SCHAR)FDKreadBits(hBitBuf, 1);
+
+ /* Read header */
+ if (bEnableHeader) {
+ pBsData->bPsHeaderValid = 1;
+ pBsData->bEnableIid = (UCHAR)FDKreadBits(hBitBuf, 1);
+ if (pBsData->bEnableIid) {
+ pBsData->modeIid = (UCHAR)FDKreadBits(hBitBuf, 3);
+ }
+
+ pBsData->bEnableIcc = (UCHAR)FDKreadBits(hBitBuf, 1);
+ if (pBsData->bEnableIcc) {
+ pBsData->modeIcc = (UCHAR)FDKreadBits(hBitBuf, 3);
+ }
+
+ pBsData->bEnableExt = (UCHAR)FDKreadBits(hBitBuf, 1);
+ }
+
+ pBsData->bFrameClass = (UCHAR)FDKreadBits(hBitBuf, 1);
+ if (pBsData->bFrameClass == 0) {
+ /* FIX_BORDERS NoEnv=0,1,2,4 */
+ pBsData->noEnv =
+ FDK_sbrDecoder_aFixNoEnvDecode[(UCHAR)FDKreadBits(hBitBuf, 2)];
+ /* all additional handling of env borders is now in DecodePs() */
+ } else {
+ /* VAR_BORDERS NoEnv=1,2,3,4 */
+ pBsData->noEnv = 1 + (UCHAR)FDKreadBits(hBitBuf, 2);
+ for (env = 1; env < pBsData->noEnv + 1; env++)
+ pBsData->aEnvStartStop[env] = ((UCHAR)FDKreadBits(hBitBuf, 5)) + 1;
+ /* all additional handling of env borders is now in DecodePs() */
+ }
+
+ /* verify that IID & ICC modes (quant grid, freq res) are supported */
+ if ((pBsData->modeIid > 5) || (pBsData->modeIcc > 5)) {
+ /* no useful PS data could be read from bitstream */
+ h_ps_d->bPsDataAvail[h_ps_d->bsReadSlot] = ppt_none;
+ /* discard all remaining bits */
+ nBitsLeft -= startbits - (INT)FDKgetValidBits(hBitBuf);
+ while (nBitsLeft > 0) {
+ int i = nBitsLeft;
+ if (i > 8) {
+ i = 8;
+ }
+ FDKreadBits(hBitBuf, i);
+ nBitsLeft -= i;
+ }
+ return (UINT)(startbits - (INT)FDKgetValidBits(hBitBuf));
+ }
+
+ if (pBsData->modeIid > 2) {
+ pBsData->freqResIid = pBsData->modeIid - 3;
+ pBsData->bFineIidQ = 1;
+ } else {
+ pBsData->freqResIid = pBsData->modeIid;
+ pBsData->bFineIidQ = 0;
+ }
+
+ if (pBsData->modeIcc > 2) {
+ pBsData->freqResIcc = pBsData->modeIcc - 3;
+ } else {
+ pBsData->freqResIcc = pBsData->modeIcc;
+ }
+
+ /* Extract IID data */
+ if (pBsData->bEnableIid) {
+ for (env = 0; env < pBsData->noEnv; env++) {
+ dtFlag = (SCHAR)FDKreadBits(hBitBuf, 1);
+ if (!dtFlag) {
+ if (pBsData->bFineIidQ)
+ CurrentTable = (Huffman)&aBookPsIidFineFreqDecode;
+ else
+ CurrentTable = (Huffman)&aBookPsIidFreqDecode;
+ } else {
+ if (pBsData->bFineIidQ)
+ CurrentTable = (Huffman)&aBookPsIidFineTimeDecode;
+ else
+ CurrentTable = (Huffman)&aBookPsIidTimeDecode;
+ }
+
+ for (gr = 0; gr < FDK_sbrDecoder_aNoIidBins[pBsData->freqResIid]; gr++)
+ pBsData->aaIidIndex[env][gr] =
+ decode_huff_cw(CurrentTable, hBitBuf, NULL);
+ pBsData->abIidDtFlag[env] = dtFlag;
+ }
+ }
+
+ /* Extract ICC data */
+ if (pBsData->bEnableIcc) {
+ for (env = 0; env < pBsData->noEnv; env++) {
+ dtFlag = (SCHAR)FDKreadBits(hBitBuf, 1);
+ if (!dtFlag)
+ CurrentTable = (Huffman)&aBookPsIccFreqDecode;
+ else
+ CurrentTable = (Huffman)&aBookPsIccTimeDecode;
+
+ for (gr = 0; gr < FDK_sbrDecoder_aNoIccBins[pBsData->freqResIcc]; gr++)
+ pBsData->aaIccIndex[env][gr] =
+ decode_huff_cw(CurrentTable, hBitBuf, NULL);
+ pBsData->abIccDtFlag[env] = dtFlag;
+ }
+ }
+
+ if (pBsData->bEnableExt) {
+ /*!
+ Decoders that support only the baseline version of the PS tool are allowed
+ to ignore the IPD/OPD data, but according header data has to be parsed.
+ ISO/IEC 14496-3 Subpart 8 Annex 4
+ */
+
+ int cnt = FDKreadBits(hBitBuf, PS_EXTENSION_SIZE_BITS);
+ if (cnt == (1 << PS_EXTENSION_SIZE_BITS) - 1) {
+ cnt += FDKreadBits(hBitBuf, PS_EXTENSION_ESC_COUNT_BITS);
+ }
+ while (cnt--) FDKreadBits(hBitBuf, 8);
+ }
+
+ /* new PS data was read from bitstream */
+ h_ps_d->bPsDataAvail[h_ps_d->bsReadSlot] = ppt_mpeg;
+
+ return (startbits - (INT)FDKgetValidBits(hBitBuf));
+}
diff --git a/fdk-aac/libSBRdec/src/psbitdec.h b/fdk-aac/libSBRdec/src/psbitdec.h
new file mode 100644
index 0000000..f0fc43a
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/psbitdec.h
@@ -0,0 +1,116 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef PSBITDEC_H
+#define PSBITDEC_H
+
+#include "sbrdecoder.h"
+
+#include "psdec.h"
+
+unsigned int ReadPsData(struct PS_DEC *h_ps_d, HANDLE_FDK_BITSTREAM hBs,
+ int nBitsLeft);
+
+int DecodePs(struct PS_DEC *h_ps_d, const UCHAR frameError,
+ PS_DEC_COEFFICIENTS *pCoef);
+
+#endif /* PSBITDEC_H */
diff --git a/fdk-aac/libSBRdec/src/psdec.cpp b/fdk-aac/libSBRdec/src/psdec.cpp
new file mode 100644
index 0000000..b31b310
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/psdec.cpp
@@ -0,0 +1,722 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief parametric stereo decoder
+*/
+
+#include "psdec.h"
+
+#include "FDK_bitbuffer.h"
+
+#include "sbr_rom.h"
+#include "sbr_ram.h"
+
+#include "FDK_tools_rom.h"
+
+#include "genericStds.h"
+
+#include "FDK_trigFcts.h"
+
+/********************************************************************/
+/* MLQUAL DEFINES */
+/********************************************************************/
+
+#define FRACT_ZERO FRACT_BITS - 1
+/********************************************************************/
+
+SBR_ERROR ResetPsDec(HANDLE_PS_DEC h_ps_d);
+
+/***** HELPERS *****/
+
+/***************************************************************************/
+/*!
+ \brief Creates one instance of the PS_DEC struct
+
+ \return Error info
+
+****************************************************************************/
+int CreatePsDec(HANDLE_PS_DEC *h_PS_DEC, /*!< pointer to the module state */
+ int aacSamplesPerFrame) {
+ SBR_ERROR errorInfo = SBRDEC_OK;
+ HANDLE_PS_DEC h_ps_d;
+ int i;
+
+ if (*h_PS_DEC == NULL) {
+ /* Get ps dec ram */
+ h_ps_d = GetRam_ps_dec();
+ if (h_ps_d == NULL) {
+ goto bail;
+ }
+ } else {
+ /* Reset an open instance */
+ h_ps_d = *h_PS_DEC;
+ }
+
+ /*
+ * Create Analysis Hybrid filterbank.
+ */
+ FDKhybridAnalysisOpen(&h_ps_d->specificTo.mpeg.hybridAnalysis,
+ h_ps_d->specificTo.mpeg.pHybridAnaStatesLFdmx,
+ sizeof(h_ps_d->specificTo.mpeg.pHybridAnaStatesLFdmx),
+ NULL, 0);
+
+ /* initialisation */
+ switch (aacSamplesPerFrame) {
+ case 960:
+ h_ps_d->noSubSamples = 30; /* col */
+ break;
+ case 1024:
+ h_ps_d->noSubSamples = 32; /* col */
+ break;
+ default:
+ h_ps_d->noSubSamples = -1;
+ break;
+ }
+
+ if (h_ps_d->noSubSamples > MAX_NUM_COL || h_ps_d->noSubSamples <= 0) {
+ goto bail;
+ }
+ h_ps_d->noChannels = NO_QMF_CHANNELS; /* row */
+
+ h_ps_d->psDecodedPrv = 0;
+ h_ps_d->procFrameBased = -1;
+ for (i = 0; i < (1) + 1; i++) {
+ h_ps_d->bPsDataAvail[i] = ppt_none;
+ }
+ {
+ int error;
+ error = FDKdecorrelateOpen(&(h_ps_d->specificTo.mpeg.apDecor),
+ h_ps_d->specificTo.mpeg.decorrBufferCplx,
+ (2 * ((825) + (373))));
+ if (error) goto bail;
+ }
+
+ for (i = 0; i < (1) + 1; i++) {
+ FDKmemclear(&h_ps_d->bsData[i].mpeg, sizeof(MPEG_PS_BS_DATA));
+ }
+
+ errorInfo = ResetPsDec(h_ps_d);
+
+ if (errorInfo != SBRDEC_OK) goto bail;
+
+ *h_PS_DEC = h_ps_d;
+
+ return 0;
+
+bail:
+ if (h_ps_d != NULL) {
+ DeletePsDec(&h_ps_d);
+ }
+
+ return -1;
+} /*END CreatePsDec */
+
+/***************************************************************************/
+/*!
+ \brief Delete one instance of the PS_DEC struct
+
+ \return Error info
+
+****************************************************************************/
+int DeletePsDec(HANDLE_PS_DEC *h_PS_DEC) /*!< pointer to the module state */
+{
+ if (*h_PS_DEC == NULL) {
+ return -1;
+ }
+
+ {
+ HANDLE_PS_DEC h_ps_d = *h_PS_DEC;
+ FDKdecorrelateClose(&(h_ps_d->specificTo.mpeg.apDecor));
+ }
+
+ FreeRam_ps_dec(h_PS_DEC);
+
+ return 0;
+} /*END DeletePsDec */
+
+/***************************************************************************/
+/*!
+ \brief resets some values of the PS handle to default states
+
+ \return
+
+****************************************************************************/
+SBR_ERROR ResetPsDec(HANDLE_PS_DEC h_ps_d) /*!< pointer to the module state */
+{
+ SBR_ERROR errorInfo = SBRDEC_OK;
+ INT i;
+
+ /* explicitly init state variables to safe values (until first ps header
+ * arrives) */
+
+ h_ps_d->specificTo.mpeg.lastUsb = 0;
+
+ /*
+ * Initialize Analysis Hybrid filterbank.
+ */
+ FDKhybridAnalysisInit(&h_ps_d->specificTo.mpeg.hybridAnalysis, THREE_TO_TEN,
+ NO_QMF_BANDS_HYBRID20, NO_QMF_BANDS_HYBRID20, 1);
+
+ /*
+ * Initialize Synthesis Hybrid filterbank.
+ */
+ for (i = 0; i < 2; i++) {
+ FDKhybridSynthesisInit(&h_ps_d->specificTo.mpeg.hybridSynthesis[i],
+ THREE_TO_TEN, NO_QMF_CHANNELS, NO_QMF_CHANNELS);
+ }
+ {
+ INT error;
+ error = FDKdecorrelateInit(&h_ps_d->specificTo.mpeg.apDecor, 71, DECORR_PS,
+ DUCKER_AUTOMATIC, 0, 0, 0, 0, 1, /* isLegacyPS */
+ 1);
+ if (error) return SBRDEC_NOT_INITIALIZED;
+ }
+
+ for (i = 0; i < NO_IID_GROUPS; i++) {
+ h_ps_d->specificTo.mpeg.h11rPrev[i] = FL2FXCONST_DBL(0.5f);
+ h_ps_d->specificTo.mpeg.h12rPrev[i] = FL2FXCONST_DBL(0.5f);
+ }
+
+ FDKmemclear(h_ps_d->specificTo.mpeg.h21rPrev,
+ sizeof(h_ps_d->specificTo.mpeg.h21rPrev));
+ FDKmemclear(h_ps_d->specificTo.mpeg.h22rPrev,
+ sizeof(h_ps_d->specificTo.mpeg.h22rPrev));
+
+ return errorInfo;
+}
+
+/***************************************************************************/
+/*!
+ \brief Feed delaylines when parametric stereo is switched on.
+ \return
+****************************************************************************/
+void PreparePsProcessing(HANDLE_PS_DEC h_ps_d,
+ const FIXP_DBL *const *const rIntBufferLeft,
+ const FIXP_DBL *const *const iIntBufferLeft,
+ const int scaleFactorLowBand) {
+ if (h_ps_d->procFrameBased ==
+ 1) /* If we have switched from frame to slot based processing */
+ { /* fill hybrid delay buffer. */
+ int i, j;
+
+ for (i = 0; i < HYBRID_FILTER_DELAY; i++) {
+ FIXP_DBL qmfInputData[2][NO_QMF_BANDS_HYBRID20];
+ FIXP_DBL hybridOutputData[2][NO_SUB_QMF_CHANNELS];
+
+ for (j = 0; j < NO_QMF_BANDS_HYBRID20; j++) {
+ qmfInputData[0][j] =
+ scaleValue(rIntBufferLeft[i][j], scaleFactorLowBand);
+ qmfInputData[1][j] =
+ scaleValue(iIntBufferLeft[i][j], scaleFactorLowBand);
+ }
+
+ FDKhybridAnalysisApply(&h_ps_d->specificTo.mpeg.hybridAnalysis,
+ qmfInputData[0], qmfInputData[1],
+ hybridOutputData[0], hybridOutputData[1]);
+ }
+ h_ps_d->procFrameBased = 0; /* switch to slot based processing. */
+
+ } /* procFrameBased==1 */
+}
+
+void initSlotBasedRotation(
+ HANDLE_PS_DEC h_ps_d, /*!< pointer to the module state */
+ int env, int usb) {
+ INT group = 0;
+ INT bin = 0;
+ INT noIidSteps, noFactors;
+
+ FIXP_SGL invL;
+ FIXP_DBL ScaleL, ScaleR;
+ FIXP_DBL Alpha, Beta, AlphasValue;
+ FIXP_DBL h11r, h12r, h21r, h22r;
+
+ const FIXP_DBL *PScaleFactors;
+
+ if (h_ps_d->bsData[h_ps_d->processSlot].mpeg.bFineIidQ) {
+ PScaleFactors = ScaleFactorsFine; /* values are shiftet right by one */
+ noIidSteps = NO_IID_STEPS_FINE;
+ noFactors = NO_IID_LEVELS_FINE;
+ } else {
+ PScaleFactors = ScaleFactors; /* values are shiftet right by one */
+ noIidSteps = NO_IID_STEPS;
+ noFactors = NO_IID_LEVELS;
+ }
+
+ /* dequantize and decode */
+ for (group = 0; group < NO_IID_GROUPS; group++) {
+ bin = bins2groupMap20[group];
+
+ /*!
+ <h3> type 'A' rotation </h3>
+ mixing procedure R_a, used in baseline version<br>
+
+ Scale-factor vectors c1 and c2 are precalculated in initPsTables () and
+ stored in scaleFactors[] and scaleFactorsFine[] = pScaleFactors []. From the
+ linearized IID parameters (intensity differences), two scale factors are
+ calculated. They are used to obtain the coefficients h11... h22.
+ */
+
+ /* ScaleR and ScaleL are scaled by 1 shift right */
+
+ ScaleL = ScaleR = 0;
+ if (noIidSteps + h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env][bin] >= 0 && noIidSteps + h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env][bin] < noFactors)
+ ScaleR = PScaleFactors[noIidSteps + h_ps_d->specificTo.mpeg.pCoef
+ ->aaIidIndexMapped[env][bin]];
+ if (noIidSteps - h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env][bin] >= 0 && noIidSteps - h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env][bin] < noFactors)
+ ScaleL = PScaleFactors[noIidSteps - h_ps_d->specificTo.mpeg.pCoef
+ ->aaIidIndexMapped[env][bin]];
+
+ AlphasValue = 0;
+ if (h_ps_d->specificTo.mpeg.pCoef->aaIccIndexMapped[env][bin] >= 0)
+ AlphasValue = Alphas[h_ps_d->specificTo.mpeg.pCoef->aaIccIndexMapped[env][bin]];
+ Beta = fMult(
+ fMult(AlphasValue,
+ (ScaleR - ScaleL)),
+ FIXP_SQRT05);
+ Alpha =
+ AlphasValue >> 1;
+
+ /* Alpha and Beta are now both scaled by 2 shifts right */
+
+ /* calculate the coefficients h11... h22 from scale-factors and ICC
+ * parameters */
+
+ /* h values are scaled by 1 shift right */
+ {
+ FIXP_DBL trigData[4];
+
+ inline_fixp_cos_sin(Beta + Alpha, Beta - Alpha, 2, trigData);
+ h11r = fMult(ScaleL, trigData[0]);
+ h12r = fMult(ScaleR, trigData[2]);
+ h21r = fMult(ScaleL, trigData[1]);
+ h22r = fMult(ScaleR, trigData[3]);
+ }
+ /*****************************************************************************************/
+ /* Interpolation of the matrices H11... H22: */
+ /* */
+ /* H11(k,n) = H11(k,n[e]) + (n-n[e]) * (H11(k,n[e+1] - H11(k,n[e])) /
+ * (n[e+1] - n[e]) */
+ /* ... */
+ /*****************************************************************************************/
+
+ /* invL = 1/(length of envelope) */
+ invL = FX_DBL2FX_SGL(GetInvInt(
+ h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env + 1] -
+ h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env]));
+
+ h_ps_d->specificTo.mpeg.pCoef->H11r[group] =
+ h_ps_d->specificTo.mpeg.h11rPrev[group];
+ h_ps_d->specificTo.mpeg.pCoef->H12r[group] =
+ h_ps_d->specificTo.mpeg.h12rPrev[group];
+ h_ps_d->specificTo.mpeg.pCoef->H21r[group] =
+ h_ps_d->specificTo.mpeg.h21rPrev[group];
+ h_ps_d->specificTo.mpeg.pCoef->H22r[group] =
+ h_ps_d->specificTo.mpeg.h22rPrev[group];
+
+ h_ps_d->specificTo.mpeg.pCoef->DeltaH11r[group] =
+ fMult(h11r - h_ps_d->specificTo.mpeg.pCoef->H11r[group], invL);
+ h_ps_d->specificTo.mpeg.pCoef->DeltaH12r[group] =
+ fMult(h12r - h_ps_d->specificTo.mpeg.pCoef->H12r[group], invL);
+ h_ps_d->specificTo.mpeg.pCoef->DeltaH21r[group] =
+ fMult(h21r - h_ps_d->specificTo.mpeg.pCoef->H21r[group], invL);
+ h_ps_d->specificTo.mpeg.pCoef->DeltaH22r[group] =
+ fMult(h22r - h_ps_d->specificTo.mpeg.pCoef->H22r[group], invL);
+
+ /* update prev coefficients for interpolation in next envelope */
+
+ h_ps_d->specificTo.mpeg.h11rPrev[group] = h11r;
+ h_ps_d->specificTo.mpeg.h12rPrev[group] = h12r;
+ h_ps_d->specificTo.mpeg.h21rPrev[group] = h21r;
+ h_ps_d->specificTo.mpeg.h22rPrev[group] = h22r;
+
+ } /* group loop */
+}
+
+static const UCHAR groupTable[NO_IID_GROUPS + 1] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 18, 21, 25, 30, 42, 71};
+
+static void applySlotBasedRotation(
+ HANDLE_PS_DEC h_ps_d, /*!< pointer to the module state */
+
+ FIXP_DBL *mHybridRealLeft, /*!< hybrid values real left */
+ FIXP_DBL *mHybridImagLeft, /*!< hybrid values imag left */
+
+ FIXP_DBL *mHybridRealRight, /*!< hybrid values real right */
+ FIXP_DBL *mHybridImagRight /*!< hybrid values imag right */
+) {
+ INT group;
+ INT subband;
+
+ /**********************************************************************************************/
+ /*!
+ <h2> Mapping </h2>
+
+ The number of stereo bands that is actually used depends on the number of
+ availble parameters for IID and ICC: <pre> nr. of IID para.| nr. of ICC para.
+ | nr. of Stereo bands
+ ----------------|------------------|-------------------
+ 10,20 | 10,20 | 20
+ 10,20 | 34 | 34
+ 34 | 10,20 | 34
+ 34 | 34 | 34
+ </pre>
+ In the case the number of parameters for IIS and ICC differs from the number
+ of stereo bands, a mapping from the lower number to the higher number of
+ parameters is applied. Index mapping of IID and ICC parameters is already done
+ in psbitdec.cpp. Further mapping is not needed here in baseline version.
+ **********************************************************************************************/
+
+ /************************************************************************************************/
+ /*!
+ <h2> Mixing </h2>
+
+ To generate the QMF subband signals for the subband samples n = n[e]+1 ,,,
+ n_[e+1] the parameters at position n[e] and n[e+1] are required as well as the
+ subband domain signals s_k(n) and d_k(n) for n = n[e]+1... n_[e+1]. n[e]
+ represents the start position for envelope e. The border positions n[e] are
+ handled in DecodePS().
+
+ The stereo sub subband signals are constructed as:
+ <pre>
+ l_k(n) = H11(k,n) s_k(n) + H21(k,n) d_k(n)
+ r_k(n) = H21(k,n) s_k(n) + H22(k,n) d_k(n)
+ </pre>
+ In order to obtain the matrices H11(k,n)... H22 (k,n), the vectors h11(b)...
+ h22(b) need to be calculated first (b: parameter index). Depending on ICC mode
+ either mixing procedure R_a or R_b is used for that. For both procedures, the
+ parameters for parameter position n[e+1] is used.
+ ************************************************************************************************/
+
+ /************************************************************************************************/
+ /*!
+ <h2>Phase parameters </h2>
+ With disabled phase parameters (which is the case in baseline version), the
+ H-matrices are just calculated by:
+
+ <pre>
+ H11(k,n[e+1] = h11(b(k))
+ (...)
+ b(k): parameter index according to mapping table
+ </pre>
+
+ <h2>Processing of the samples in the sub subbands </h2>
+ this loop includes the interpolation of the coefficients Hxx
+ ************************************************************************************************/
+
+ /******************************************************/
+ /* construct stereo sub subband signals according to: */
+ /* */
+ /* l_k(n) = H11(k,n) s_k(n) + H21(k,n) d_k(n) */
+ /* r_k(n) = H12(k,n) s_k(n) + H22(k,n) d_k(n) */
+ /******************************************************/
+ PS_DEC_COEFFICIENTS *pCoef = h_ps_d->specificTo.mpeg.pCoef;
+
+ for (group = 0; group < NO_IID_GROUPS; group++) {
+ pCoef->H11r[group] += pCoef->DeltaH11r[group];
+ pCoef->H12r[group] += pCoef->DeltaH12r[group];
+ pCoef->H21r[group] += pCoef->DeltaH21r[group];
+ pCoef->H22r[group] += pCoef->DeltaH22r[group];
+
+ const int start = groupTable[group];
+ const int stop = groupTable[group + 1];
+ for (subband = start; subband < stop; subband++) {
+ FIXP_DBL tmpLeft =
+ fMultAdd(fMultDiv2(pCoef->H11r[group], mHybridRealLeft[subband]),
+ pCoef->H21r[group], mHybridRealRight[subband]);
+ FIXP_DBL tmpRight =
+ fMultAdd(fMultDiv2(pCoef->H12r[group], mHybridRealLeft[subband]),
+ pCoef->H22r[group], mHybridRealRight[subband]);
+ mHybridRealLeft[subband] = tmpLeft;
+ mHybridRealRight[subband] = tmpRight;
+
+ tmpLeft =
+ fMultAdd(fMultDiv2(pCoef->H11r[group], mHybridImagLeft[subband]),
+ pCoef->H21r[group], mHybridImagRight[subband]);
+ tmpRight =
+ fMultAdd(fMultDiv2(pCoef->H12r[group], mHybridImagLeft[subband]),
+ pCoef->H22r[group], mHybridImagRight[subband]);
+ mHybridImagLeft[subband] = tmpLeft;
+ mHybridImagRight[subband] = tmpRight;
+ } /* subband */
+ }
+}
+
+/***************************************************************************/
+/*!
+ \brief Applies IID, ICC, IPD and OPD parameters to the current frame.
+
+ \return none
+
+****************************************************************************/
+void ApplyPsSlot(
+ HANDLE_PS_DEC h_ps_d, /*!< handle PS_DEC*/
+ FIXP_DBL **rIntBufferLeft, /*!< real bands left qmf channel (38x64) */
+ FIXP_DBL **iIntBufferLeft, /*!< imag bands left qmf channel (38x64) */
+ FIXP_DBL *rIntBufferRight, /*!< real bands right qmf channel (38x64) */
+ FIXP_DBL *iIntBufferRight, /*!< imag bands right qmf channel (38x64) */
+ const int scaleFactorLowBand_no_ov, const int scaleFactorLowBand,
+ const int scaleFactorHighBand, const int lsb, const int usb) {
+/*!
+The 64-band QMF representation of the monaural signal generated by the SBR tool
+is used as input of the PS tool. After the PS processing, the outputs of the
+left and right hybrid synthesis filterbanks are used to generate the stereo
+output signal.
+
+<pre>
+
+ ------------- ---------- -------------
+ | Hybrid | M_n[k,m] | | L_n[k,m] | Hybrid | l[n]
+ m[n] --->| analysis |--------->| |--------->| synthesis |----->
+ ------------- | Stereo | -------------
+ | | recon- |
+ | | stuction |
+ \|/ | |
+ ------------- | |
+ | De- | D_n[k,m] | |
+ | correlation |--------->| |
+ ------------- | | -------------
+ | | R_n[k,m] | Hybrid | r[n]
+ | |--------->| synthesis |----->
+ IID, ICC ------------------------>| | | filter bank |
+(IPD, OPD) ---------- -------------
+
+m[n]: QMF represantation of the mono input
+M_n[k,m]: (sub-)sub-band domain signals of the mono input
+D_n[k,m]: decorrelated (sub-)sub-band domain signals
+L_n[k,m]: (sub-)sub-band domain signals of the left output
+R_n[k,m]: (sub-)sub-band domain signals of the right output
+l[n],r[n]: left/right output signals
+
+</pre>
+*/
+#define NO_HYBRID_DATA_BANDS (71)
+
+ int i;
+ FIXP_DBL qmfInputData[2][NO_QMF_BANDS_HYBRID20];
+ FIXP_DBL *hybridData[2][2];
+ C_ALLOC_SCRATCH_START(pHybridData, FIXP_DBL, 4 * NO_HYBRID_DATA_BANDS);
+
+ hybridData[0][0] =
+ pHybridData + 0 * NO_HYBRID_DATA_BANDS; /* left real hybrid data */
+ hybridData[0][1] =
+ pHybridData + 1 * NO_HYBRID_DATA_BANDS; /* left imag hybrid data */
+ hybridData[1][0] =
+ pHybridData + 2 * NO_HYBRID_DATA_BANDS; /* right real hybrid data */
+ hybridData[1][1] =
+ pHybridData + 3 * NO_HYBRID_DATA_BANDS; /* right imag hybrid data */
+
+ /*!
+ Hybrid analysis filterbank:
+ The lower 3 (5) of the 64 QMF subbands are further split to provide better
+ frequency resolution. for PS processing. For the 10 and 20 stereo bands
+ configuration, the QMF band H_0(w) is split up into 8 (sub-) sub-bands and the
+ QMF bands H_1(w) and H_2(w) are spit into 2 (sub-) 4th. (See figures 8.20
+ and 8.22 of ISO/IEC 14496-3:2001/FDAM 2:2004(E) )
+ */
+
+ /*
+ * Hybrid analysis.
+ */
+
+ /* Get qmf input data and apply descaling */
+ for (i = 0; i < NO_QMF_BANDS_HYBRID20; i++) {
+ qmfInputData[0][i] = scaleValue(rIntBufferLeft[HYBRID_FILTER_DELAY][i],
+ scaleFactorLowBand_no_ov);
+ qmfInputData[1][i] = scaleValue(iIntBufferLeft[HYBRID_FILTER_DELAY][i],
+ scaleFactorLowBand_no_ov);
+ }
+
+ /* LF - part */
+ FDKhybridAnalysisApply(&h_ps_d->specificTo.mpeg.hybridAnalysis,
+ qmfInputData[0], qmfInputData[1], hybridData[0][0],
+ hybridData[0][1]);
+
+ /* HF - part */
+ /* bands up to lsb */
+ scaleValues(&hybridData[0][0][NO_SUB_QMF_CHANNELS - 2],
+ &rIntBufferLeft[0][NO_QMF_BANDS_HYBRID20],
+ lsb - NO_QMF_BANDS_HYBRID20, scaleFactorLowBand);
+ scaleValues(&hybridData[0][1][NO_SUB_QMF_CHANNELS - 2],
+ &iIntBufferLeft[0][NO_QMF_BANDS_HYBRID20],
+ lsb - NO_QMF_BANDS_HYBRID20, scaleFactorLowBand);
+
+ /* bands from lsb to usb */
+ scaleValues(&hybridData[0][0][lsb + (NO_SUB_QMF_CHANNELS - 2 -
+ NO_QMF_BANDS_HYBRID20)],
+ &rIntBufferLeft[0][lsb], usb - lsb, scaleFactorHighBand);
+ scaleValues(&hybridData[0][1][lsb + (NO_SUB_QMF_CHANNELS - 2 -
+ NO_QMF_BANDS_HYBRID20)],
+ &iIntBufferLeft[0][lsb], usb - lsb, scaleFactorHighBand);
+
+ /* bands from usb to NO_SUB_QMF_CHANNELS which should be zero for non-overlap
+ slots but can be non-zero for overlap slots */
+ FDKmemcpy(
+ &hybridData[0][0]
+ [usb + (NO_SUB_QMF_CHANNELS - 2 - NO_QMF_BANDS_HYBRID20)],
+ &rIntBufferLeft[0][usb], sizeof(FIXP_DBL) * (NO_QMF_CHANNELS - usb));
+ FDKmemcpy(
+ &hybridData[0][1]
+ [usb + (NO_SUB_QMF_CHANNELS - 2 - NO_QMF_BANDS_HYBRID20)],
+ &iIntBufferLeft[0][usb], sizeof(FIXP_DBL) * (NO_QMF_CHANNELS - usb));
+
+ /*!
+ Decorrelation:
+ By means of all-pass filtering and delaying, the (sub-)sub-band samples s_k(n)
+ are converted into de-correlated (sub-)sub-band samples d_k(n).
+ - k: frequency in hybrid spectrum
+ - n: time index
+ */
+
+ FDKdecorrelateApply(&h_ps_d->specificTo.mpeg.apDecor,
+ &hybridData[0][0][0], /* left real hybrid data */
+ &hybridData[0][1][0], /* left imag hybrid data */
+ &hybridData[1][0][0], /* right real hybrid data */
+ &hybridData[1][1][0], /* right imag hybrid data */
+ 0 /* startHybBand */
+ );
+
+ /*!
+ Stereo Processing:
+ The sets of (sub-)sub-band samples s_k(n) and d_k(n) are processed according
+ to the stereo cues which are defined per stereo band.
+ */
+
+ applySlotBasedRotation(h_ps_d,
+ &hybridData[0][0][0], /* left real hybrid data */
+ &hybridData[0][1][0], /* left imag hybrid data */
+ &hybridData[1][0][0], /* right real hybrid data */
+ &hybridData[1][1][0] /* right imag hybrid data */
+ );
+
+ /*!
+ Hybrid synthesis filterbank:
+ The stereo processed hybrid subband signals l_k(n) and r_k(n) are fed into the
+ hybrid synthesis filterbanks which are identical to the 64 complex synthesis
+ filterbank of the SBR tool. The input to the filterbank are slots of 64 QMF
+ samples. For each slot the filterbank outputs one block of 64 samples of one
+ reconstructed stereo channel. The hybrid synthesis filterbank is computed
+ seperatly for the left and right channel.
+ */
+
+ /*
+ * Hybrid synthesis.
+ */
+ for (i = 0; i < 2; i++) {
+ FDKhybridSynthesisApply(
+ &h_ps_d->specificTo.mpeg.hybridSynthesis[i],
+ hybridData[i][0], /* real hybrid data */
+ hybridData[i][1], /* imag hybrid data */
+ (i == 0) ? rIntBufferLeft[0]
+ : rIntBufferRight, /* output real qmf buffer */
+ (i == 0) ? iIntBufferLeft[0]
+ : iIntBufferRight /* output imag qmf buffer */
+ );
+ }
+
+ /* free temporary hybrid qmf values of one timeslot */
+ C_ALLOC_SCRATCH_END(pHybridData, FIXP_DBL, 4 * NO_HYBRID_DATA_BANDS);
+
+} /* END ApplyPsSlot */
diff --git a/fdk-aac/libSBRdec/src/psdec.h b/fdk-aac/libSBRdec/src/psdec.h
new file mode 100644
index 0000000..029eac4
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/psdec.h
@@ -0,0 +1,333 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Sbr decoder
+*/
+#ifndef PSDEC_H
+#define PSDEC_H
+
+#include "sbrdecoder.h"
+#include "FDK_hybrid.h"
+
+#include "FDK_decorrelate.h"
+
+/* This PS decoder implements the baseline version. So it always uses the */
+/* hybrid filter structure for 20 stereo bands and does not implemet IPD/OPD */
+/* synthesis. The baseline version has to support the complete PS bitstream */
+/* syntax. But IPD/OPD data is ignored and set to 0. If 34 stereo band config */
+/* is used in the bitstream for IIS/ICC the decoded parameters are mapped to */
+/* 20 stereo bands. */
+
+#include "FDK_bitstream.h"
+
+#define SCAL_HEADROOM (2)
+
+#define PS_EXTENSION_SIZE_BITS (4)
+#define PS_EXTENSION_ESC_COUNT_BITS (8)
+
+#define NO_QMF_CHANNELS (64)
+#define MAX_NUM_COL (32)
+
+#define NO_QMF_BANDS_HYBRID20 (3)
+#define NO_SUB_QMF_CHANNELS (12)
+#define HYBRID_FILTER_DELAY (6)
+
+#define MAX_NO_PS_ENV (4 + 1) /* +1 needed for VAR_BORDER */
+
+#define NO_HI_RES_BINS (34)
+#define NO_MID_RES_BINS (20)
+#define NO_LOW_RES_BINS (10)
+
+#define NO_HI_RES_IID_BINS (NO_HI_RES_BINS)
+#define NO_HI_RES_ICC_BINS (NO_HI_RES_BINS)
+
+#define NO_MID_RES_IID_BINS (NO_MID_RES_BINS)
+#define NO_MID_RES_ICC_BINS (NO_MID_RES_BINS)
+
+#define NO_LOW_RES_IID_BINS (NO_LOW_RES_BINS)
+#define NO_LOW_RES_ICC_BINS (NO_LOW_RES_BINS)
+
+#define SUBQMF_GROUPS (10)
+#define QMF_GROUPS (12)
+
+//#define SUBQMF_GROUPS_HI_RES ( 32 )
+//#define QMF_GROUPS_HI_RES ( 18 )
+
+#define NO_IID_GROUPS (SUBQMF_GROUPS + QMF_GROUPS)
+//#define NO_IID_GROUPS_HI_RES ( SUBQMF_GROUPS_HI_RES +
+// QMF_GROUPS_HI_RES )
+
+#define NO_IID_STEPS (7) /* 1 .. + 7 */
+#define NO_IID_STEPS_FINE (15) /* 1 .. +15 */
+#define NO_ICC_STEPS (8) /* 0 .. + 7 */
+
+#define NO_IID_LEVELS (2 * NO_IID_STEPS + 1) /* - 7 .. + 7 */
+#define NO_IID_LEVELS_FINE (2 * NO_IID_STEPS_FINE + 1) /* -15 .. +15 */
+#define NO_ICC_LEVELS (NO_ICC_STEPS) /* 0 .. + 7 */
+
+#define FIXP_SQRT05 ((FIXP_DBL)0x5a827980) /* 1/SQRT2 */
+
+struct PS_DEC_COEFFICIENTS {
+ FIXP_DBL H11r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */
+ FIXP_DBL H12r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */
+ FIXP_DBL H21r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */
+ FIXP_DBL H22r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */
+
+ FIXP_DBL
+ DeltaH11r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */
+ FIXP_DBL
+ DeltaH12r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */
+ FIXP_DBL
+ DeltaH21r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */
+ FIXP_DBL
+ DeltaH22r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */
+
+ SCHAR
+ aaIidIndexMapped[MAX_NO_PS_ENV]
+ [NO_HI_RES_IID_BINS]; /*!< The mapped IID index for all
+ envelopes and all IID bins */
+ SCHAR
+ aaIccIndexMapped[MAX_NO_PS_ENV]
+ [NO_HI_RES_ICC_BINS]; /*!< The mapped ICC index for all
+ envelopes and all ICC bins */
+};
+
+typedef enum { ppt_none = 0, ppt_mpeg = 1, ppt_drm = 2 } PS_PAYLOAD_TYPE;
+
+typedef struct {
+ UCHAR bPsHeaderValid; /*!< set if new header is available from bitstream */
+
+ UCHAR bEnableIid; /*!< One bit denoting the presence of IID parameters */
+ UCHAR bEnableIcc; /*!< One bit denoting the presence of ICC parameters */
+ UCHAR bEnableExt; /*!< The PS extension layer is enabled using the enable_ext
+ bit. If it is set to %1 the IPD and OPD parameters are
+ sent. If it is disabled, i.e. %0, the extension layer is
+ skipped. */
+
+ UCHAR
+ modeIid; /*!< The configuration of IID parameters (number of bands and
+ quantisation grid, iid_quant) is determined by iid_mode. */
+ UCHAR modeIcc; /*!< The configuration of Inter-channel Coherence parameters
+ (number of bands and quantisation grid) is determined by
+ icc_mode. */
+
+ UCHAR freqResIid; /*!< 0=low, 1=mid or 2=high frequency resolution for iid */
+ UCHAR freqResIcc; /*!< 0=low, 1=mid or 2=high frequency resolution for icc */
+
+ UCHAR bFineIidQ; /*!< Use fine Iid quantisation. */
+
+ UCHAR bFrameClass; /*!< The frame_class bit determines whether the parameter
+ positions of the current frame are uniformly spaced
+ accross the frame or they are defined using the
+ positions described by border_position.
+ */
+
+ UCHAR noEnv; /*!< The number of envelopes per frame */
+ UCHAR aEnvStartStop[MAX_NO_PS_ENV + 1]; /*!< In case of variable parameter
+ spacing the parameter positions are
+ determined by border_position */
+
+ SCHAR abIidDtFlag[MAX_NO_PS_ENV]; /*!< Deltacoding time/freq flag for IID, 0
+ => freq */
+ SCHAR abIccDtFlag[MAX_NO_PS_ENV]; /*!< Deltacoding time/freq flag for ICC, 0
+ => freq */
+
+ SCHAR
+ aaIidIndex[MAX_NO_PS_ENV]
+ [NO_HI_RES_IID_BINS]; /*!< The IID index for all envelopes and
+ all IID bins */
+ SCHAR
+ aaIccIndex[MAX_NO_PS_ENV]
+ [NO_HI_RES_ICC_BINS]; /*!< The ICC index for all envelopes and
+ all ICC bins */
+
+} MPEG_PS_BS_DATA;
+
+struct PS_DEC {
+ SCHAR noSubSamples;
+ SCHAR noChannels;
+
+ SCHAR procFrameBased; /*!< Helper to detected switching from frame based to
+ slot based processing
+ */
+
+ PS_PAYLOAD_TYPE
+ bPsDataAvail[(1) + 1]; /*!< set if new data available from bitstream */
+ UCHAR psDecodedPrv; /*!< set if PS has been processed in the last frame */
+
+ /* helpers for frame delay line */
+ UCHAR bsLastSlot; /*!< Index of last read slot. */
+ UCHAR bsReadSlot; /*!< Index of current read slot for additional delay. */
+ UCHAR processSlot; /*!< Index of current slot for processing (need for add.
+ delay). */
+
+ union { /* Bitstream data */
+ MPEG_PS_BS_DATA
+ mpeg; /*!< Struct containing all MPEG specific PS data from bitstream.
+ */
+ } bsData[(1) + 1];
+
+ shouldBeUnion { /* Static data */
+ struct {
+ SCHAR aIidPrevFrameIndex[NO_HI_RES_IID_BINS]; /*!< The IID index for
+ previous frame */
+ SCHAR aIccPrevFrameIndex[NO_HI_RES_ICC_BINS]; /*!< The ICC index for
+ previous frame */
+ UCHAR
+ bPrevFrameFineIidQ; /*!< The IID quantization of the previous frame */
+ UCHAR prevFreqResIid; /*!< Frequency resolution for IID of the previous
+ frame */
+ UCHAR prevFreqResIcc; /*!< Frequency resolution for ICC of the previous
+ frame */
+ UCHAR lastUsb; /*!< uppermost WMF delay band of last frame */
+
+ FIXP_DBL pHybridAnaStatesLFdmx
+ [2 * 13 * NO_QMF_BANDS_HYBRID20]; /*!< Memory used in hybrid analysis
+ for filter states. */
+ FDK_ANA_HYB_FILTER hybridAnalysis;
+ FDK_SYN_HYB_FILTER hybridSynthesis[2];
+
+ DECORR_DEC apDecor; /*!< Decorrelator instance. */
+ FIXP_DBL decorrBufferCplx[(2 * ((825) + (373)))];
+
+ FIXP_DBL h11rPrev[NO_IID_GROUPS]; /*!< previous calculated h(xy)
+ coefficients */
+ FIXP_DBL h12rPrev[NO_IID_GROUPS]; /*!< previous calculated h(xy)
+ coefficients */
+ FIXP_DBL h21rPrev[NO_IID_GROUPS]; /*!< previous calculated h(xy)
+ coefficients */
+ FIXP_DBL h22rPrev[NO_IID_GROUPS]; /*!< previous calculated h(xy)
+ coefficients */
+
+ PS_DEC_COEFFICIENTS
+ *pCoef; /*!< temporal coefficients are on reusable scratch memory */
+
+ } mpeg;
+ }
+ specificTo;
+};
+
+typedef struct PS_DEC *HANDLE_PS_DEC;
+
+int CreatePsDec(HANDLE_PS_DEC *h_PS_DEC, int aacSamplesPerFrame);
+
+int DeletePsDec(HANDLE_PS_DEC *h_PS_DEC);
+
+void PreparePsProcessing(HANDLE_PS_DEC h_ps_d,
+ const FIXP_DBL *const *const rIntBufferLeft,
+ const FIXP_DBL *const *const iIntBufferLeft,
+ const int scaleFactorLowBand);
+
+void initSlotBasedRotation(HANDLE_PS_DEC h_ps_d, int env, int usb);
+
+void ApplyPsSlot(
+ HANDLE_PS_DEC h_ps_d, /* parametric stereo decoder handle */
+ FIXP_DBL **rIntBufferLeft, /* real values of left qmf timeslot */
+ FIXP_DBL **iIntBufferLeft, /* imag values of left qmf timeslot */
+ FIXP_DBL *rIntBufferRight, /* real values of right qmf timeslot */
+ FIXP_DBL *iIntBufferRight, /* imag values of right qmf timeslot */
+ const int scaleFactorLowBand_no_ov, const int scaleFactorLowBand,
+ const int scaleFactorHighBand, const int lsb, const int usb);
+
+#endif /* PSDEC_H */
diff --git a/fdk-aac/libSBRdec/src/psdec_drm.cpp b/fdk-aac/libSBRdec/src/psdec_drm.cpp
new file mode 100644
index 0000000..6971f53
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/psdec_drm.cpp
@@ -0,0 +1,108 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief parametric stereo decoder for Digital radio mondial
+*/
+
+#include "psdec_drm.h"
diff --git a/fdk-aac/libSBRdec/src/psdec_drm.h b/fdk-aac/libSBRdec/src/psdec_drm.h
new file mode 100644
index 0000000..5e2575d
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/psdec_drm.h
@@ -0,0 +1,113 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief parametric stereo decoder for digital radio mondial
+*/
+
+#ifndef PSDEC_DRM_H
+#define PSDEC_DRM_H
+
+#include "sbrdecoder.h"
+
+#endif /* PSDEC_DRM_H */
diff --git a/fdk-aac/libSBRdec/src/psdecrom_drm.cpp b/fdk-aac/libSBRdec/src/psdecrom_drm.cpp
new file mode 100644
index 0000000..2033a83
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/psdecrom_drm.cpp
@@ -0,0 +1,108 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief rom tables for Drm parametric stereo decoder
+*/
+
+#include "psdec_drm.h"
diff --git a/fdk-aac/libSBRdec/src/pvc_dec.cpp b/fdk-aac/libSBRdec/src/pvc_dec.cpp
new file mode 100644
index 0000000..b477122
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/pvc_dec.cpp
@@ -0,0 +1,683 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: Decode Predictive Vector Coding Data
+
+*******************************************************************************/
+
+#include "pvc_dec.h"
+
+/* PVC interal definitions */
+#define PVC_DIVMODE_BITS 3
+#define PVC_NSMODE_BITS 1
+#define PVC_REUSEPVCID_BITS 1
+#define PVC_PVCID_BITS 7
+#define PVC_GRIDINFO_BITS 1
+#define PVC_NQMFBAND 64
+#define PVC_NBLOW 3 /* max. number of grouped QMF subbands below SBR range */
+
+#define PVC_NTAB1 3
+#define PVC_NTAB2 128
+#define PVC_ID_NBIT 7
+
+/* Exponent of pPvcStaticData->Esg and predictedEsg in dB domain.
+ max(Esg) = 10*log10(2^15*2^15) = 90.30;
+ min(Esg) = 10*log10(0.1) = -10
+ max of predicted Esg seems to be higher than 90dB but 7 Bit should be enough.
+*/
+#define PVC_ESG_EXP 7
+
+#define LOG10FAC 0.752574989159953f /* == 10/log2(10) * 2^-2 */
+#define LOG10FAC_INV 0.664385618977472f /* == log2(10)/10 * 2^1 */
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+static const FIXP_SGL pvc_SC_16[] = {
+ FX_DBL2FXCONST_SGL(0x14413695), FX_DBL2FXCONST_SGL(0x1434b6cb),
+ FX_DBL2FXCONST_SGL(0x140f27c7), FX_DBL2FXCONST_SGL(0x13d0591d),
+ FX_DBL2FXCONST_SGL(0x1377f502), FX_DBL2FXCONST_SGL(0x130577d6),
+ FX_DBL2FXCONST_SGL(0x12782266), FX_DBL2FXCONST_SGL(0x11cee459),
+ FX_DBL2FXCONST_SGL(0x11083a2a), FX_DBL2FXCONST_SGL(0x1021f5e9),
+ FX_DBL2FXCONST_SGL(0x0f18e17c), FX_DBL2FXCONST_SGL(0x0de814ca),
+ FX_DBL2FXCONST_SGL(0x0c87a568), FX_DBL2FXCONST_SGL(0x0ae9b167),
+ FX_DBL2FXCONST_SGL(0x08f24226), FX_DBL2FXCONST_SGL(0x06575ed5),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+static const FIXP_SGL pvc_SC_12[] = {
+ FX_DBL2FXCONST_SGL(0x1aba6b3e), FX_DBL2FXCONST_SGL(0x1a9d164e),
+ FX_DBL2FXCONST_SGL(0x1a44d56d), FX_DBL2FXCONST_SGL(0x19b0d742),
+ FX_DBL2FXCONST_SGL(0x18df969a), FX_DBL2FXCONST_SGL(0x17ce91a0),
+ FX_DBL2FXCONST_SGL(0x1679c3fa), FX_DBL2FXCONST_SGL(0x14daabfc),
+ FX_DBL2FXCONST_SGL(0x12e65221), FX_DBL2FXCONST_SGL(0x1088d125),
+ FX_DBL2FXCONST_SGL(0x0d9907b3), FX_DBL2FXCONST_SGL(0x09a80e9d),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+static const FIXP_SGL pvc_SC_4[] = {
+ FX_DBL2FXCONST_SGL(0x4ad6ab0f),
+ FX_DBL2FXCONST_SGL(0x47ef0dbe),
+ FX_DBL2FXCONST_SGL(0x3eee7496),
+ FX_DBL2FXCONST_SGL(0x2e4bd29d),
+};
+
+RAM_ALIGN
+LNK_SECTION_CONSTDATA
+static const FIXP_SGL pvc_SC_3[] = {
+ FX_DBL2FXCONST_SGL(0x610dc761),
+ FX_DBL2FXCONST_SGL(0x5a519a3d),
+ FX_DBL2FXCONST_SGL(0x44a09e62),
+};
+
+static const UCHAR g_3a_pvcTab1_mode1[PVC_NTAB1][PVC_NBLOW][PVC_NBHIGH_MODE1] =
+ {{{0x4F, 0x5B, 0x57, 0x52, 0x4D, 0x65, 0x45, 0x57},
+ {0xF3, 0x0F, 0x18, 0x20, 0x19, 0x4F, 0x3D, 0x23},
+ {0x78, 0x57, 0x55, 0x50, 0x50, 0x20, 0x36, 0x37}},
+ {{0x4C, 0x5F, 0x53, 0x37, 0x1E, 0xFD, 0x15, 0x0A},
+ {0x05, 0x0E, 0x28, 0x41, 0x48, 0x6E, 0x54, 0x5B},
+ {0x59, 0x47, 0x40, 0x40, 0x3D, 0x33, 0x3F, 0x39}},
+ {{0x47, 0x5F, 0x57, 0x34, 0x3C, 0x2E, 0x2E, 0x31},
+ {0xFA, 0x13, 0x23, 0x4E, 0x44, 0x7C, 0x34, 0x38},
+ {0x63, 0x43, 0x41, 0x3D, 0x35, 0x19, 0x3D, 0x33}}};
+
+static const UCHAR g_2a_pvcTab2_mode1[PVC_NTAB2][PVC_NBHIGH_MODE1] = {
+ {0xCB, 0xD1, 0xCC, 0xD2, 0xE2, 0xEB, 0xE7, 0xE8},
+ {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+ {0x84, 0x8C, 0x88, 0x83, 0x90, 0x93, 0x86, 0x80},
+ {0xD7, 0xD8, 0xC0, 0xC7, 0xCF, 0xE5, 0xF1, 0xF6},
+ {0xA5, 0xA6, 0xAA, 0xA8, 0xB0, 0xB1, 0xB8, 0xB8},
+ {0xD7, 0xCB, 0xC1, 0xC3, 0xC5, 0xC9, 0xC9, 0xCE},
+ {0xCA, 0xB5, 0xB8, 0xB3, 0xAC, 0xB6, 0xBB, 0xB8},
+ {0xC1, 0xC4, 0xC3, 0xC5, 0xC6, 0xCA, 0xCA, 0xCB},
+ {0xE0, 0xE1, 0xD8, 0xCD, 0xCB, 0xCB, 0xCE, 0xCC},
+ {0xDB, 0xE1, 0xDF, 0xDB, 0xDC, 0xD9, 0xD9, 0xD6},
+ {0xE0, 0xDE, 0xDD, 0xDD, 0xE0, 0xE3, 0xE5, 0xE6},
+ {0xCA, 0xD2, 0xCD, 0xCE, 0xD5, 0xDB, 0xD9, 0xDB},
+ {0xD2, 0xE0, 0xDB, 0xD5, 0xDB, 0xDE, 0xE3, 0xE1},
+ {0xE5, 0xDB, 0xD0, 0xD2, 0xD8, 0xDD, 0xDB, 0xDD},
+ {0xC0, 0xB5, 0xBF, 0xDD, 0xE3, 0xDC, 0xDC, 0xE4},
+ {0xDB, 0xCE, 0xC6, 0xCF, 0xCF, 0xD1, 0xD3, 0xD4},
+ {0xC9, 0xD7, 0xDA, 0xE2, 0xE9, 0xE7, 0xDF, 0xDC},
+ {0x0A, 0x07, 0x0A, 0x08, 0x19, 0x24, 0x1F, 0x22},
+ {0x1E, 0x1F, 0x11, 0x0E, 0x22, 0x2D, 0x33, 0x32},
+ {0xF0, 0xDA, 0xDC, 0x18, 0x1F, 0x19, 0x0A, 0x1E},
+ {0x09, 0xF8, 0xE6, 0x05, 0x19, 0x11, 0x0E, 0x0B},
+ {0x09, 0x10, 0x0E, 0xE6, 0xF4, 0x20, 0x22, 0xFA},
+ {0xF2, 0xE5, 0xF8, 0x0E, 0x18, 0x15, 0x0D, 0x10},
+ {0x15, 0x13, 0x16, 0x0A, 0x0D, 0x1F, 0x1D, 0x1B},
+ {0xFA, 0xFF, 0xFE, 0xFF, 0x09, 0x11, 0x03, 0x0B},
+ {0xFE, 0xFA, 0xF2, 0xF8, 0x0C, 0x1E, 0x11, 0x12},
+ {0xFA, 0xF8, 0x0B, 0x17, 0x1D, 0x17, 0x0E, 0x16},
+ {0x00, 0xF3, 0xFD, 0x0A, 0x1C, 0x17, 0xFD, 0x08},
+ {0xEA, 0xEA, 0x03, 0x12, 0x1E, 0x14, 0x09, 0x04},
+ {0x02, 0xFE, 0x04, 0xFB, 0x0C, 0x0E, 0x07, 0x02},
+ {0xF6, 0x02, 0x07, 0x0B, 0x17, 0x17, 0x01, 0xFF},
+ {0xF5, 0xFB, 0xFE, 0x04, 0x12, 0x14, 0x0C, 0x0D},
+ {0x10, 0x10, 0x0E, 0x04, 0x07, 0x11, 0x0F, 0x13},
+ {0x0C, 0x0F, 0xFB, 0xF2, 0x0A, 0x12, 0x09, 0x0D},
+ {0x0D, 0x1D, 0xF1, 0xF4, 0x2A, 0x06, 0x3B, 0x32},
+ {0xFC, 0x08, 0x06, 0x02, 0x0E, 0x17, 0x08, 0x0E},
+ {0x07, 0x02, 0xEE, 0xEE, 0x2B, 0xF6, 0x23, 0x13},
+ {0x04, 0x02, 0x05, 0x08, 0x0B, 0x0E, 0xFB, 0xFB},
+ {0x00, 0x04, 0x10, 0x18, 0x22, 0x25, 0x1D, 0x1F},
+ {0xFB, 0x0D, 0x07, 0x00, 0x0C, 0x0F, 0xFC, 0x02},
+ {0x00, 0x00, 0x00, 0x01, 0x05, 0x07, 0x03, 0x05},
+ {0x04, 0x05, 0x08, 0x13, 0xFF, 0xEB, 0x0C, 0x06},
+ {0x05, 0x13, 0x0E, 0x0B, 0x12, 0x15, 0x09, 0x0A},
+ {0x09, 0x03, 0x09, 0x05, 0x12, 0x16, 0x11, 0x12},
+ {0x14, 0x1A, 0x06, 0x01, 0x10, 0x11, 0xFE, 0x02},
+ {0x01, 0x0B, 0x0B, 0x0C, 0x18, 0x21, 0x10, 0x13},
+ {0x12, 0x0D, 0x0A, 0x10, 0x1C, 0x1D, 0x0D, 0x10},
+ {0x03, 0x09, 0x14, 0x15, 0x1B, 0x1A, 0x01, 0xFF},
+ {0x08, 0x12, 0x13, 0x0E, 0x16, 0x1D, 0x14, 0x1B},
+ {0x07, 0x15, 0x1C, 0x1B, 0x20, 0x21, 0x11, 0x0E},
+ {0x12, 0x18, 0x19, 0x17, 0x20, 0x25, 0x1A, 0x1E},
+ {0x0C, 0x1A, 0x1D, 0x22, 0x2F, 0x33, 0x27, 0x28},
+ {0x0E, 0x1A, 0x17, 0x10, 0x0A, 0x0E, 0xFF, 0x06},
+ {0x1A, 0x1C, 0x18, 0x14, 0x1A, 0x16, 0x0A, 0x0E},
+ {0x1E, 0x27, 0x25, 0x26, 0x27, 0x2A, 0x21, 0x21},
+ {0xF1, 0x0A, 0x16, 0x1C, 0x28, 0x25, 0x15, 0x19},
+ {0x08, 0x12, 0x09, 0x08, 0x16, 0x17, 0xEF, 0xF6},
+ {0x0C, 0x0B, 0x00, 0xFC, 0x04, 0x09, 0xFC, 0x03},
+ {0xFB, 0xF1, 0xF8, 0x26, 0x24, 0x18, 0x1D, 0x20},
+ {0xF9, 0x01, 0x0C, 0x0F, 0x07, 0x08, 0x06, 0x07},
+ {0x07, 0x06, 0x08, 0x04, 0x07, 0x0D, 0x07, 0x09},
+ {0xFE, 0x01, 0x06, 0x05, 0x13, 0x1B, 0x14, 0x19},
+ {0x09, 0x0C, 0x0E, 0x01, 0x08, 0x05, 0xFB, 0xFD},
+ {0x07, 0x06, 0x03, 0x0A, 0x16, 0x12, 0x04, 0x07},
+ {0x04, 0x01, 0x00, 0x04, 0x1F, 0x20, 0x0E, 0x0A},
+ {0x03, 0xFF, 0xF6, 0xFB, 0x15, 0x1A, 0x00, 0x03},
+ {0xFC, 0x18, 0x0B, 0x2D, 0x35, 0x23, 0x12, 0x09},
+ {0x02, 0xFE, 0x01, 0xFF, 0x0C, 0x11, 0x0D, 0x0F},
+ {0xFA, 0xE9, 0xD9, 0xFF, 0x0D, 0x05, 0x0D, 0x10},
+ {0xF1, 0xE0, 0xF0, 0x01, 0x06, 0x06, 0x06, 0x10},
+ {0xE9, 0xD4, 0xD7, 0x0F, 0x14, 0x0B, 0x0D, 0x16},
+ {0x00, 0xFF, 0xEE, 0xE5, 0xFF, 0x08, 0x02, 0xF9},
+ {0xE0, 0xDA, 0xE5, 0xFE, 0x09, 0x02, 0xF9, 0x04},
+ {0xE0, 0xE2, 0xF4, 0x09, 0x13, 0x0C, 0x0D, 0x09},
+ {0xFC, 0x02, 0x04, 0xFF, 0x00, 0xFF, 0xF8, 0xF7},
+ {0xFE, 0xFB, 0xED, 0xF2, 0xFE, 0xFE, 0x08, 0x0C},
+ {0xF3, 0xEF, 0xD0, 0xE3, 0x05, 0x11, 0xFD, 0xFF},
+ {0xFA, 0xEF, 0xEA, 0xFE, 0x0D, 0x0E, 0xFE, 0x02},
+ {0xF7, 0xFB, 0xDB, 0xDF, 0x14, 0xDD, 0x07, 0xFE},
+ {0xFE, 0x08, 0x00, 0xDB, 0xE5, 0x1A, 0x13, 0xED},
+ {0xF9, 0xFE, 0xFF, 0xF4, 0xF3, 0x00, 0x05, 0x02},
+ {0xEF, 0xDE, 0xD8, 0xEB, 0xEA, 0xF5, 0x0E, 0x19},
+ {0xFB, 0xFC, 0xFA, 0xEC, 0xEB, 0xED, 0xEE, 0xE8},
+ {0xEE, 0xFC, 0xFD, 0x00, 0x04, 0xFC, 0xF0, 0xF5},
+ {0x00, 0xFA, 0xF4, 0xF1, 0xF5, 0xFA, 0xFB, 0xF9},
+ {0xEB, 0xF0, 0xDF, 0xE3, 0xEF, 0x07, 0x02, 0x05},
+ {0xF7, 0xF0, 0xE6, 0xE7, 0x06, 0x15, 0x06, 0x0C},
+ {0xF1, 0xE4, 0xD8, 0xEA, 0x06, 0xF2, 0x07, 0x09},
+ {0xFF, 0xFE, 0xFE, 0xF9, 0xFF, 0xFF, 0x02, 0xF9},
+ {0xDD, 0xF4, 0xF0, 0xF1, 0xFF, 0xFF, 0xEA, 0xF1},
+ {0xF0, 0xF1, 0xFD, 0x03, 0x03, 0xFE, 0x00, 0x05},
+ {0xF1, 0xF6, 0xE0, 0xDF, 0xF5, 0x01, 0xF4, 0xF8},
+ {0x02, 0x03, 0xE5, 0xDC, 0xE7, 0xFD, 0x02, 0x08},
+ {0xEC, 0xF1, 0xF5, 0xEC, 0xF2, 0xF8, 0xF6, 0xEE},
+ {0xF3, 0xF4, 0xF6, 0xF4, 0xF5, 0xF1, 0xE7, 0xEA},
+ {0xF7, 0xF3, 0xEC, 0xEA, 0xEF, 0xF0, 0xEE, 0xF1},
+ {0xEB, 0xF6, 0xFB, 0xFA, 0xEF, 0xF3, 0xF3, 0xF7},
+ {0x01, 0x03, 0xF1, 0xF6, 0x05, 0xF8, 0xE1, 0xEB},
+ {0xF5, 0xF6, 0xF6, 0xF4, 0xFB, 0xFB, 0xFF, 0x00},
+ {0xF8, 0x01, 0xFB, 0xFA, 0xFF, 0x03, 0xFE, 0x04},
+ {0x04, 0xFB, 0x03, 0xFD, 0xF5, 0xF7, 0xF6, 0xFB},
+ {0x06, 0x09, 0xFB, 0xF4, 0xF9, 0xFA, 0xFC, 0xFF},
+ {0xF5, 0xF6, 0xF1, 0xEE, 0xF5, 0xF8, 0xF5, 0xF9},
+ {0xF5, 0xF9, 0xFA, 0xFC, 0x07, 0x09, 0x01, 0xFB},
+ {0xD7, 0xE9, 0xE8, 0xEC, 0x00, 0x0C, 0xFE, 0xF1},
+ {0xEC, 0x04, 0xE9, 0xDF, 0x03, 0xE8, 0x00, 0xFA},
+ {0xE6, 0xE2, 0xFF, 0x0A, 0x13, 0x01, 0x00, 0xF7},
+ {0xF1, 0xFA, 0xF7, 0xF5, 0x01, 0x06, 0x05, 0x0A},
+ {0xF6, 0xF6, 0xFC, 0xF6, 0xE8, 0x11, 0xF2, 0xFE},
+ {0xFE, 0x08, 0x05, 0x12, 0xFD, 0xD0, 0x0E, 0x07},
+ {0xF1, 0xFE, 0xF7, 0xF2, 0xFB, 0x02, 0xFA, 0xF8},
+ {0xF4, 0xEA, 0xEC, 0xF3, 0xFE, 0x01, 0xF7, 0xF6},
+ {0xFF, 0xFA, 0xFB, 0xF9, 0xFF, 0x01, 0x04, 0x03},
+ {0x00, 0xF9, 0xF4, 0xFC, 0x05, 0xFC, 0xF7, 0xFB},
+ {0xF8, 0xFF, 0xEF, 0xEC, 0xFB, 0x04, 0xF8, 0x03},
+ {0xEB, 0xF1, 0xED, 0xF4, 0x02, 0x0E, 0x0B, 0x04},
+ {0xF7, 0x01, 0xF8, 0xF4, 0xF8, 0xEF, 0xF8, 0x04},
+ {0xEB, 0xF0, 0xF7, 0xFC, 0x10, 0x0D, 0xF8, 0xF8},
+ {0xE8, 0xFE, 0xEE, 0xE8, 0xED, 0xF7, 0xF5, 0xF8},
+ {0xED, 0xEB, 0xE9, 0xEA, 0xF2, 0xF5, 0xF4, 0xF9},
+ {0xEA, 0xF2, 0xEF, 0xEE, 0xF9, 0xFE, 0xFD, 0x02},
+ {0xFA, 0xFD, 0x02, 0x0D, 0xFA, 0xE4, 0x0F, 0x01},
+ {0xFF, 0x08, 0x05, 0xF6, 0xF7, 0xFB, 0xF1, 0xF1},
+ {0xF4, 0xEC, 0xEE, 0xF6, 0xEE, 0xEE, 0xF8, 0x06},
+ {0xE8, 0xFA, 0xF8, 0xE8, 0xF8, 0xE9, 0xEE, 0xF9},
+ {0xE5, 0xE9, 0xF0, 0x00, 0x00, 0xEF, 0xF3, 0xF8},
+ {0xF7, 0xFB, 0xFB, 0xF7, 0xF9, 0xF9, 0xF5, 0xF0},
+ {0xFD, 0xFF, 0xF2, 0xEE, 0xF2, 0xF5, 0xF1, 0xF3}};
+
+static const UCHAR g_3a_pvcTab1_mode2[PVC_NTAB1][PVC_NBLOW][PVC_NBHIGH_MODE2] =
+ {{{0x11, 0x27, 0x0F, 0xFD, 0x04, 0xFC},
+ {0x00, 0xBE, 0xE3, 0xF4, 0xDB, 0xF0},
+ {0x09, 0x1E, 0x18, 0x1A, 0x21, 0x1B}},
+ {{0x16, 0x28, 0x2B, 0x29, 0x25, 0x32},
+ {0xF2, 0xE9, 0xE4, 0xE5, 0xE2, 0xD4},
+ {0x0E, 0x0B, 0x0C, 0x0D, 0x0D, 0x0E}},
+ {{0x2E, 0x3C, 0x20, 0x16, 0x1B, 0x1A},
+ {0xE4, 0xC6, 0xE5, 0xF4, 0xDC, 0xDC},
+ {0x0F, 0x1B, 0x18, 0x14, 0x1E, 0x1A}}};
+
+static const UCHAR g_2a_pvcTab2_mode2[PVC_NTAB2][PVC_NBHIGH_MODE2] = {
+ {0x26, 0x25, 0x11, 0x0C, 0xFA, 0x15}, {0x1B, 0x18, 0x11, 0x0E, 0x0E, 0x0E},
+ {0x12, 0x10, 0x10, 0x10, 0x11, 0x10}, {0x1E, 0x24, 0x19, 0x15, 0x14, 0x12},
+ {0x24, 0x16, 0x12, 0x13, 0x15, 0x1C}, {0xEA, 0xED, 0xEB, 0xEA, 0xEC, 0xEB},
+ {0xFC, 0xFD, 0xFD, 0xFC, 0xFE, 0xFE}, {0x0F, 0x0C, 0x0B, 0x0A, 0x0B, 0x0B},
+ {0x22, 0x0B, 0x16, 0x18, 0x13, 0x19}, {0x1C, 0x14, 0x1D, 0x20, 0x19, 0x1A},
+ {0x10, 0x08, 0x00, 0xFF, 0x02, 0x05}, {0x06, 0x07, 0x05, 0x03, 0x05, 0x04},
+ {0x2A, 0x1F, 0x12, 0x12, 0x11, 0x18}, {0x19, 0x19, 0x02, 0x04, 0x00, 0x04},
+ {0x18, 0x17, 0x17, 0x15, 0x16, 0x15}, {0x21, 0x1E, 0x1B, 0x19, 0x1C, 0x1B},
+ {0x3C, 0x35, 0x20, 0x1D, 0x30, 0x34}, {0x3A, 0x1F, 0x37, 0x38, 0x33, 0x31},
+ {0x37, 0x34, 0x25, 0x27, 0x35, 0x34}, {0x34, 0x2E, 0x32, 0x31, 0x34, 0x31},
+ {0x36, 0x33, 0x2F, 0x2F, 0x32, 0x2F}, {0x35, 0x20, 0x2F, 0x32, 0x2F, 0x2C},
+ {0x2E, 0x2B, 0x2F, 0x34, 0x36, 0x30}, {0x3F, 0x39, 0x30, 0x28, 0x29, 0x29},
+ {0x3C, 0x30, 0x32, 0x37, 0x39, 0x36}, {0x37, 0x36, 0x30, 0x2B, 0x26, 0x24},
+ {0x44, 0x38, 0x2F, 0x2D, 0x2D, 0x2D}, {0x38, 0x2B, 0x2C, 0x2C, 0x30, 0x2D},
+ {0x37, 0x36, 0x2F, 0x23, 0x2D, 0x32}, {0x3C, 0x39, 0x29, 0x2E, 0x38, 0x37},
+ {0x3B, 0x3A, 0x35, 0x32, 0x31, 0x2D}, {0x32, 0x31, 0x2F, 0x2C, 0x2D, 0x28},
+ {0x2C, 0x31, 0x32, 0x30, 0x32, 0x2D}, {0x35, 0x34, 0x34, 0x34, 0x35, 0x33},
+ {0x34, 0x38, 0x3B, 0x3C, 0x3E, 0x3A}, {0x3E, 0x3C, 0x3B, 0x3A, 0x3C, 0x39},
+ {0x3D, 0x41, 0x46, 0x41, 0x3D, 0x38}, {0x44, 0x41, 0x40, 0x3E, 0x3F, 0x3A},
+ {0x47, 0x47, 0x47, 0x42, 0x44, 0x40}, {0x4C, 0x4A, 0x4A, 0x46, 0x49, 0x45},
+ {0x53, 0x52, 0x52, 0x4C, 0x4E, 0x49}, {0x41, 0x3D, 0x39, 0x2C, 0x2E, 0x2E},
+ {0x2D, 0x37, 0x36, 0x30, 0x28, 0x36}, {0x3B, 0x32, 0x2E, 0x2D, 0x2D, 0x29},
+ {0x40, 0x39, 0x36, 0x35, 0x36, 0x32}, {0x30, 0x2D, 0x2D, 0x2E, 0x31, 0x30},
+ {0x38, 0x3D, 0x3B, 0x37, 0x35, 0x34}, {0x44, 0x3D, 0x3C, 0x38, 0x37, 0x33},
+ {0x3A, 0x36, 0x37, 0x37, 0x39, 0x36}, {0x32, 0x36, 0x37, 0x30, 0x2E, 0x2A},
+ {0x3C, 0x33, 0x33, 0x31, 0x33, 0x30}, {0x30, 0x31, 0x36, 0x37, 0x38, 0x34},
+ {0x26, 0x27, 0x2E, 0x29, 0x1C, 0x16}, {0x14, 0x15, 0x1F, 0x17, 0x15, 0x1C},
+ {0x38, 0x2D, 0x18, 0x13, 0x1E, 0x2B}, {0x30, 0x22, 0x17, 0x1A, 0x26, 0x2B},
+ {0x24, 0x20, 0x1F, 0x10, 0x0C, 0x11}, {0x27, 0x1F, 0x13, 0x17, 0x24, 0x2A},
+ {0x2F, 0x13, 0x18, 0x13, 0x2A, 0x32}, {0x31, 0x1E, 0x1E, 0x1E, 0x21, 0x28},
+ {0x2A, 0x12, 0x19, 0x17, 0x16, 0x24}, {0x27, 0x0F, 0x16, 0x1D, 0x17, 0x1C},
+ {0x2F, 0x26, 0x25, 0x22, 0x20, 0x22}, {0x1E, 0x1B, 0x1E, 0x18, 0x1E, 0x24},
+ {0x31, 0x26, 0x0E, 0x15, 0x15, 0x25}, {0x2D, 0x22, 0x1E, 0x14, 0x10, 0x22},
+ {0x25, 0x1B, 0x18, 0x11, 0x13, 0x1F}, {0x2F, 0x1B, 0x13, 0x1B, 0x18, 0x22},
+ {0x21, 0x24, 0x1D, 0x1C, 0x1D, 0x1B}, {0x23, 0x1E, 0x28, 0x29, 0x27, 0x25},
+ {0x2E, 0x2A, 0x1D, 0x17, 0x26, 0x2D}, {0x31, 0x2C, 0x1A, 0x0E, 0x1A, 0x24},
+ {0x26, 0x16, 0x20, 0x1D, 0x14, 0x1E}, {0x29, 0x20, 0x1B, 0x1B, 0x17, 0x17},
+ {0x1D, 0x06, 0x1A, 0x1E, 0x1B, 0x1D}, {0x2B, 0x23, 0x1F, 0x1F, 0x1D, 0x1C},
+ {0x27, 0x1A, 0x0C, 0x0E, 0x0F, 0x1A}, {0x29, 0x1D, 0x1E, 0x22, 0x22, 0x24},
+ {0x20, 0x21, 0x1B, 0x18, 0x13, 0x21}, {0x27, 0x0E, 0x10, 0x14, 0x10, 0x1A},
+ {0x26, 0x24, 0x25, 0x25, 0x26, 0x28}, {0x1A, 0x24, 0x25, 0x29, 0x26, 0x24},
+ {0x1D, 0x1D, 0x15, 0x12, 0x0F, 0x18}, {0x1E, 0x14, 0x13, 0x12, 0x14, 0x18},
+ {0x16, 0x13, 0x13, 0x1A, 0x1B, 0x1D}, {0x20, 0x27, 0x22, 0x24, 0x1A, 0x19},
+ {0x1F, 0x17, 0x19, 0x18, 0x17, 0x18}, {0x20, 0x1B, 0x1C, 0x1C, 0x1B, 0x1A},
+ {0x23, 0x19, 0x1D, 0x1F, 0x1E, 0x21}, {0x26, 0x1F, 0x1D, 0x1B, 0x19, 0x1A},
+ {0x23, 0x1E, 0x1F, 0x20, 0x1F, 0x1E}, {0x29, 0x20, 0x22, 0x20, 0x20, 0x1F},
+ {0x26, 0x23, 0x21, 0x22, 0x23, 0x23}, {0x29, 0x1F, 0x24, 0x25, 0x26, 0x29},
+ {0x2B, 0x22, 0x25, 0x27, 0x23, 0x21}, {0x29, 0x21, 0x19, 0x0E, 0x22, 0x2D},
+ {0x32, 0x29, 0x1F, 0x1C, 0x1B, 0x21}, {0x1E, 0x1A, 0x1E, 0x24, 0x25, 0x25},
+ {0x24, 0x1D, 0x21, 0x22, 0x22, 0x25}, {0x2C, 0x25, 0x21, 0x22, 0x23, 0x25},
+ {0x24, 0x1E, 0x21, 0x26, 0x2B, 0x2C}, {0x28, 0x24, 0x1B, 0x1F, 0x28, 0x2D},
+ {0x23, 0x13, 0x16, 0x22, 0x22, 0x29}, {0x1B, 0x23, 0x1C, 0x20, 0x14, 0x0D},
+ {0x1E, 0x16, 0x1A, 0x1E, 0x1C, 0x1D}, {0x2B, 0x1C, 0x1D, 0x20, 0x1B, 0x1C},
+ {0x1C, 0x1B, 0x23, 0x1F, 0x19, 0x1E}, {0x21, 0x23, 0x26, 0x20, 0x20, 0x22},
+ {0x1D, 0x0B, 0x19, 0x1E, 0x11, 0x19}, {0x18, 0x17, 0x16, 0x17, 0x14, 0x16},
+ {0x16, 0x19, 0x1C, 0x20, 0x21, 0x22}, {0x30, 0x1E, 0x22, 0x24, 0x25, 0x26},
+ {0x1B, 0x1F, 0x17, 0x1D, 0x1E, 0x21}, {0x32, 0x2B, 0x27, 0x1F, 0x1B, 0x1A},
+ {0x28, 0x20, 0x1A, 0x1B, 0x1F, 0x23}, {0x32, 0x21, 0x20, 0x21, 0x1D, 0x1F},
+ {0x22, 0x18, 0x12, 0x15, 0x1B, 0x20}, {0x27, 0x27, 0x2A, 0x24, 0x21, 0x21},
+ {0x1E, 0x0F, 0x0D, 0x1A, 0x1D, 0x23}, {0x28, 0x25, 0x27, 0x21, 0x17, 0x25},
+ {0x2B, 0x27, 0x23, 0x19, 0x13, 0x14}, {0x25, 0x2B, 0x22, 0x22, 0x20, 0x21},
+ {0x27, 0x1B, 0x16, 0x17, 0x0F, 0x15}, {0x29, 0x26, 0x23, 0x15, 0x1E, 0x28},
+ {0x24, 0x1C, 0x19, 0x1A, 0x18, 0x19}, {0x2D, 0x15, 0x27, 0x2B, 0x24, 0x23},
+ {0x2C, 0x12, 0x1F, 0x23, 0x1F, 0x20}, {0x25, 0x0F, 0x22, 0x27, 0x1F, 0x21}};
+
+static const UCHAR g_a_pvcTab1_dp_mode1[PVC_NTAB1 - 1] = {17, 68};
+static const UCHAR g_a_pvcTab1_dp_mode2[PVC_NTAB1 - 1] = {16, 52};
+/* fractional exponent which corresponds to Q representation value */
+static const SCHAR g_a_scalingCoef_mode1[PVC_NBLOW + 1] = {
+ -1, -1, 0, 6}; /* { 8, 8, 7, 1 }; Q scaling */
+static const SCHAR g_a_scalingCoef_mode2[PVC_NBLOW + 1] = {
+ 0, 0, 1, 7}; /* { 7, 7, 6, 0 }; Q scaling */
+
+int pvcInitFrame(PVC_STATIC_DATA *pPvcStaticData,
+ PVC_DYNAMIC_DATA *pPvcDynamicData, const UCHAR pvcMode,
+ const UCHAR ns, const int RATE, const int kx,
+ const int pvcBorder0, const UCHAR *pPvcID) {
+ int lbw, hbw, i, temp;
+ pPvcDynamicData->pvc_mode = pvcMode;
+ pPvcDynamicData->kx = kx;
+ pPvcDynamicData->RATE = RATE;
+
+ switch (pvcMode) {
+ case 0:
+ /* legacy SBR, nothing to do */
+ return 0;
+ case 1:
+ pPvcDynamicData->nbHigh = 8;
+ pPvcDynamicData->pPVCTab1 = (const UCHAR *)g_3a_pvcTab1_mode1;
+ pPvcDynamicData->pPVCTab2 = (const UCHAR *)g_2a_pvcTab2_mode1;
+ pPvcDynamicData->pPVCTab1_dp = g_a_pvcTab1_dp_mode1;
+ pPvcDynamicData->pScalingCoef = g_a_scalingCoef_mode1;
+ hbw = 8 / RATE;
+ break;
+ case 2:
+ pPvcDynamicData->nbHigh = 6;
+ pPvcDynamicData->pPVCTab1 = (const UCHAR *)g_3a_pvcTab1_mode2;
+ pPvcDynamicData->pPVCTab2 = (const UCHAR *)g_2a_pvcTab2_mode2;
+ pPvcDynamicData->pPVCTab1_dp = g_a_pvcTab1_dp_mode2;
+ pPvcDynamicData->pScalingCoef = g_a_scalingCoef_mode2;
+ hbw = 12 / RATE;
+ break;
+ default:
+ /* invalid pvcMode */
+ return 1;
+ }
+
+ pPvcDynamicData->pvcBorder0 = pvcBorder0;
+ UCHAR pvcBorder0_last = pPvcStaticData->pvcBorder0;
+ pPvcStaticData->pvcBorder0 = pvcBorder0;
+ pPvcDynamicData->pPvcID = pPvcID;
+
+ pPvcDynamicData->ns = ns;
+ switch (ns) {
+ case 16:
+ pPvcDynamicData->pSCcoeffs = pvc_SC_16;
+ break;
+ case 12:
+ pPvcDynamicData->pSCcoeffs = pvc_SC_12;
+ break;
+ case 4:
+ pPvcDynamicData->pSCcoeffs = pvc_SC_4;
+ break;
+ case 3:
+ pPvcDynamicData->pSCcoeffs = pvc_SC_3;
+ break;
+ default:
+ return 1;
+ }
+
+ /* in the lower part of Esg-array there are previous values of Esg (from last
+ call to this function In case of an previous legay-SBR frame, or if there
+ was a change in cross-over FQ the value of first PVC SBR timeslot is
+ propagated to prev-values in order to have reasonable values for
+ smooth-filtering
+ */
+ if ((pPvcStaticData->pvc_mode_last == 0) || (pPvcStaticData->kx_last != kx)) {
+ pPvcDynamicData->pastEsgSlotsAvail = 0;
+ } else {
+ pPvcDynamicData->pastEsgSlotsAvail = PVC_NS_MAX - pvcBorder0_last;
+ }
+
+ lbw = 8 / RATE;
+
+ temp = kx;
+ for (i = PVC_NBLOW; i >= 0; i--) {
+ pPvcDynamicData->sg_offset_low[i] = temp;
+ temp -= lbw;
+ }
+
+ temp = 0;
+ for (i = 0; i <= pPvcDynamicData->nbHigh; i++) {
+ pPvcDynamicData->sg_offset_high_kx[i] = temp;
+ temp += hbw;
+ }
+
+ return 0;
+}
+
+/* call if pvcMode = 1,2 */
+void pvcDecodeFrame(PVC_STATIC_DATA *pPvcStaticData,
+ PVC_DYNAMIC_DATA *pPvcDynamicData, FIXP_DBL **qmfBufferReal,
+ FIXP_DBL **qmfBufferImag, const int overlap,
+ const int qmfExponentOverlap,
+ const int qmfExponentCurrent) {
+ int t;
+ FIXP_DBL *predictedEsgSlot;
+ int RATE = pPvcDynamicData->RATE;
+ int pvcBorder0 = pPvcDynamicData->pvcBorder0;
+
+ for (t = pvcBorder0; t < PVC_NTIMESLOT; t++) {
+ int *pPredEsg_exp = &pPvcDynamicData->predEsg_exp[t];
+ predictedEsgSlot = pPvcDynamicData->predEsg[t];
+
+ pvcDecodeTimeSlot(
+ pPvcStaticData, pPvcDynamicData, &qmfBufferReal[t * RATE],
+ &qmfBufferImag[t * RATE],
+ (t * RATE < overlap) ? qmfExponentOverlap : qmfExponentCurrent,
+ pvcBorder0, t, predictedEsgSlot, pPredEsg_exp);
+ }
+
+ return;
+}
+
+void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
+ PVC_DYNAMIC_DATA *pPvcDynamicData,
+ FIXP_DBL **qmfSlotReal, FIXP_DBL **qmfSlotImag,
+ const int qmfExponent, const int pvcBorder0,
+ const int timeSlotNumber, FIXP_DBL predictedEsgSlot[],
+ int *predictedEsg_exp) {
+ int i, band, ksg, ksg_start = 0;
+ int RATE = pPvcDynamicData->RATE;
+ int Esg_index = pPvcStaticData->Esg_slot_index;
+ const SCHAR *sg_borders = pPvcDynamicData->sg_offset_low;
+ FIXP_DBL *pEsg = pPvcStaticData->Esg[Esg_index];
+ FIXP_DBL E[PVC_NBLOW] = {0};
+
+ /* Subband grouping in QMF subbands below SBR range */
+ /* Within one timeslot ( i = [0...(RATE-1)] QMF subsamples) calculate energy
+ E(ib,t) and group them to Esg(ksg,t). Then transfer values to logarithmical
+ domain and store them for time domain smoothing. (7.5.6.3 Subband grouping
+ in QMF subbands below SBR range)
+ */
+ for (ksg = 0; sg_borders[ksg] < 0; ksg++) {
+ pEsg[ksg] = FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)); /* 10*log10(0.1) */
+ ksg_start++;
+ }
+
+ for (i = 0; i < RATE; i++) {
+ FIXP_DBL *qmfR, *qmfI;
+ qmfR = qmfSlotReal[i];
+ qmfI = qmfSlotImag[i];
+ for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
+ for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) {
+ /* The division by 8 == (RATE*lbw) is required algorithmically */
+ E[ksg] += (fPow2Div2(qmfR[band]) + fPow2Div2(qmfI[band])) >> 2;
+ }
+ }
+ }
+ for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
+ if (E[ksg] > (FIXP_DBL)0) {
+ /* 10/log2(10) = 0.752574989159953 * 2^2 */
+ int exp_log;
+ FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent, &exp_log);
+ nrg = fMult(nrg, FL2FXCONST_SGL(LOG10FAC));
+ nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2);
+ pEsg[ksg] = fMax(nrg, FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)));
+ } else {
+ pEsg[ksg] =
+ FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)); /* 10*log10(0.1) */
+ }
+ }
+
+ /* Time domain smoothing of subband-grouped energy */
+ {
+ int idx = pPvcStaticData->Esg_slot_index;
+ FIXP_DBL *pEsg_filt;
+ FIXP_SGL SCcoeff;
+
+ E[0] = E[1] = E[2] = (FIXP_DBL)0;
+ for (i = 0; i < pPvcDynamicData->ns; i++) {
+ SCcoeff = pPvcDynamicData->pSCcoeffs[i];
+ pEsg_filt = pPvcStaticData->Esg[idx];
+ /* Div2 is compensated by scaling of coeff table */
+ E[0] = fMultAddDiv2(E[0], pEsg_filt[0], SCcoeff);
+ E[1] = fMultAddDiv2(E[1], pEsg_filt[1], SCcoeff);
+ E[2] = fMultAddDiv2(E[2], pEsg_filt[2], SCcoeff);
+ if (i >= pPvcDynamicData->pastEsgSlotsAvail) {
+ /* if past Esg values are not available use the ones from the last valid
+ * slot */
+ continue;
+ }
+ if (idx > 0) {
+ idx--;
+ } else {
+ idx += PVC_NS_MAX - 1;
+ }
+ }
+ }
+
+ /* SBR envelope scalefactor prediction */
+ {
+ int E_high_exp[PVC_NBHIGH_MAX];
+ int E_high_exp_max = 0;
+ int pvcTab1ID;
+ int pvcTab2ID = (int)pPvcDynamicData->pPvcID[timeSlotNumber];
+ const UCHAR *pTab1, *pTab2;
+ if (pvcTab2ID < pPvcDynamicData->pPVCTab1_dp[0]) {
+ pvcTab1ID = 0;
+ } else if (pvcTab2ID < pPvcDynamicData->pPVCTab1_dp[1]) {
+ pvcTab1ID = 1;
+ } else {
+ pvcTab1ID = 2;
+ }
+ pTab1 = &(pPvcDynamicData
+ ->pPVCTab1[pvcTab1ID * PVC_NBLOW * pPvcDynamicData->nbHigh]);
+ pTab2 = &(pPvcDynamicData->pPVCTab2[pvcTab2ID * pPvcDynamicData->nbHigh]);
+ for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
+ FIXP_SGL predCoeff;
+ FIXP_DBL accu;
+ int predCoeff_exp, kb;
+ E_high_exp[ksg] = 0;
+
+ /* residual part */
+ accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP +
+ pPvcDynamicData->pScalingCoef[3]);
+
+ /* linear combination of lower grouped energies part */
+ for (kb = 0; kb < PVC_NBLOW; kb++) {
+ predCoeff = (FIXP_SGL)(
+ (SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8);
+ predCoeff_exp = pPvcDynamicData->pScalingCoef[kb] +
+ 1; /* +1 to compensate for Div2 */
+ accu += fMultDiv2(E[kb], predCoeff) << predCoeff_exp;
+ }
+ /* convert back to linear domain */
+ accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV));
+ accu = f2Pow(
+ accu, PVC_ESG_EXP - 1,
+ &predCoeff_exp); /* -1 compensates for exponent of LOG10FAC_INV */
+ predictedEsgSlot[ksg] = accu;
+ E_high_exp[ksg] = predCoeff_exp;
+ if (predCoeff_exp > E_high_exp_max) {
+ E_high_exp_max = predCoeff_exp;
+ }
+ }
+
+ /* rescale output vector according to largest exponent */
+ for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
+ int scale = E_high_exp[ksg] - E_high_exp_max;
+ predictedEsgSlot[ksg] = scaleValue(predictedEsgSlot[ksg], scale);
+ }
+ *predictedEsg_exp = E_high_exp_max;
+ }
+
+ pPvcStaticData->Esg_slot_index =
+ (pPvcStaticData->Esg_slot_index + 1) & (PVC_NS_MAX - 1);
+ pPvcDynamicData->pastEsgSlotsAvail =
+ fMin(pPvcDynamicData->pastEsgSlotsAvail + 1, PVC_NS_MAX - 1);
+ return;
+}
+
+/* call if pvcMode = 0,1,2 */
+void pvcEndFrame(PVC_STATIC_DATA *pPvcStaticData,
+ PVC_DYNAMIC_DATA *pPvcDynamicData) {
+ pPvcStaticData->pvc_mode_last = pPvcDynamicData->pvc_mode;
+ pPvcStaticData->kx_last = pPvcDynamicData->kx;
+
+ if (pPvcDynamicData->pvc_mode == 0) return;
+
+ {
+ int t, max = -100;
+ for (t = pPvcDynamicData->pvcBorder0; t < PVC_NTIMESLOT; t++) {
+ if (pPvcDynamicData->predEsg_exp[t] > max) {
+ max = pPvcDynamicData->predEsg_exp[t];
+ }
+ }
+ pPvcDynamicData->predEsg_expMax = max;
+ }
+ return;
+}
+
+void expandPredEsg(const PVC_DYNAMIC_DATA *pPvcDynamicData, const int timeSlot,
+ const int lengthOutputVector, FIXP_DBL *pOutput,
+ SCHAR *pOutput_exp) {
+ int k = 0, ksg;
+ const FIXP_DBL *predEsg = pPvcDynamicData->predEsg[timeSlot];
+
+ for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
+ for (; k < pPvcDynamicData->sg_offset_high_kx[ksg + 1]; k++) {
+ pOutput[k] = predEsg[ksg];
+ pOutput_exp[k] = (SCHAR)pPvcDynamicData->predEsg_exp[timeSlot];
+ }
+ }
+ ksg--;
+ for (; k < lengthOutputVector; k++) {
+ pOutput[k] = predEsg[ksg];
+ pOutput_exp[k] = (SCHAR)pPvcDynamicData->predEsg_exp[timeSlot];
+ }
+
+ return;
+}
diff --git a/fdk-aac/libSBRdec/src/pvc_dec.h b/fdk-aac/libSBRdec/src/pvc_dec.h
new file mode 100644
index 0000000..f5a467f
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/pvc_dec.h
@@ -0,0 +1,238 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: Decode Predictive Vector Coding Data
+
+*******************************************************************************/
+
+#ifndef PVC_DEC_H
+#define PVC_DEC_H
+
+#include "common_fix.h"
+
+#define PVC_DIVMODE_BITS 3
+#define PVC_REUSEPVCID_BITS 1
+#define PVC_PVCID_BITS 7
+#define PVC_GRIDINFO_BITS 1
+
+#define MAX_PVC_ENVELOPES 2
+#define PVC_NTIMESLOT 16
+#define PVC_NBLOW 3 /* max. number of grouped QMF subbands below SBR range */
+
+#define PVC_NBHIGH_MODE1 8
+#define PVC_NBHIGH_MODE2 6
+#define PVC_NBHIGH_MAX (PVC_NBHIGH_MODE1)
+#define PVC_NS_MAX 16
+
+/** Data for each PVC instance which needs to be persistent accross SBR frames
+ */
+typedef struct {
+ UCHAR kx_last; /**< Xover frequency of last frame */
+ UCHAR pvc_mode_last; /**< PVC mode of last frame */
+ UCHAR Esg_slot_index; /**< Ring buffer index to current Esg time slot */
+ UCHAR pvcBorder0; /**< Start SBR time slot of PVC frame */
+ FIXP_DBL Esg[PVC_NS_MAX][PVC_NBLOW]; /**< Esg(ksg,t) of current and 15
+ previous time slots (ring buffer) in
+ logarithmical domain */
+} PVC_STATIC_DATA;
+
+/** Data for each PVC instance which is valid during one SBR frame */
+typedef struct {
+ UCHAR pvc_mode; /**< PVC mode 1 or 2, 0 means legacy SBR */
+ UCHAR pvcBorder0; /**< Start SBR time slot of PVC frame */
+ UCHAR kx; /**< Index of the first QMF subband in the SBR range */
+ UCHAR RATE; /**< Number of QMF subband samples per time slot (2 or 4) */
+ UCHAR ns; /**< Number of time slots for time-domain smoothing of Esg(ksg,t) */
+ const UCHAR
+ *pPvcID; /**< Pointer to prediction coefficient matrix index table */
+ UCHAR pastEsgSlotsAvail; /**< Number of past Esg(ksg,t) which are available
+ for smoothing filter */
+ const FIXP_SGL *pSCcoeffs; /**< Pointer to smoothing window table */
+ SCHAR
+ sg_offset_low[PVC_NBLOW + 1]; /**< Offset table for PVC grouping of SBR
+ subbands below SBR range */
+ SCHAR sg_offset_high_kx[PVC_NBHIGH_MAX + 1]; /**< Offset table for PVC
+ grouping of SBR subbands in
+ SBR range (relativ to kx) */
+ UCHAR nbHigh; /**< Number of grouped QMF subbands in the SBR range */
+ const SCHAR *pScalingCoef; /**< Pointer to scaling coeff table */
+ const UCHAR *pPVCTab1; /**< PVC mode 1 table */
+ const UCHAR *pPVCTab2; /**< PVC mode 2 table */
+ const UCHAR *pPVCTab1_dp; /**< Mapping of pvcID to PVC mode 1 table */
+ FIXP_DBL predEsg[PVC_NTIMESLOT]
+ [PVC_NBHIGH_MAX]; /**< Predicted Energy in linear domain */
+ int predEsg_exp[PVC_NTIMESLOT]; /**< Exponent of predicted Energy in linear
+ domain */
+ int predEsg_expMax; /**< Maximum of predEsg_exp[] */
+} PVC_DYNAMIC_DATA;
+
+/**
+ * \brief Initialize PVC data structures for current frame (call if pvcMode =
+ * 0,1,2)
+ * \param[in] pPvcStaticData Pointer to PVC persistent data
+ * \param[out] pPvcDynamicData Pointer to PVC dynamic data
+ * \param[in] pvcMode PVC mode 1 or 2, 0 means legacy SBR
+ * \param[in] ns Number of time slots for time-domain smoothing of Esg(ksg,t)
+ * \param[in] RATE Number of QMF subband samples per time slot (2 or 4)
+ * \param[in] kx Index of the first QMF subband in the SBR range
+ * \param[in] pvcBorder0 Start SBR time slot of PVC frame
+ * \param[in] pPvcID Pointer to array of PvcIDs read from bitstream
+ */
+int pvcInitFrame(PVC_STATIC_DATA *pPvcStaticData,
+ PVC_DYNAMIC_DATA *pPvcDynamicData, const UCHAR pvcMode,
+ const UCHAR ns, const int RATE, const int kx,
+ const int pvcBorder0, const UCHAR *pPvcID);
+
+/**
+ * \brief Wrapper function for pvcDecodeTimeSlot() to decode PVC data of one
+ * frame (call if pvcMode = 1,2)
+ * \param[in,out] pPvcStaticData Pointer to PVC persistent data
+ * \param[in,out] pPvcDynamicData Pointer to PVC dynamic data
+ * \param[in] qmfBufferReal Pointer to array with real QMF subbands
+ * \param[in] qmfBufferImag Pointer to array with imag QMF subbands
+ * \param[in] overlap Number of QMF overlap slots
+ * \param[in] qmfExponentOverlap Exponent of qmfBuffer (low part) of overlap
+ * slots
+ * \param[in] qmfExponentCurrent Exponent of qmfBuffer (low part)
+ */
+void pvcDecodeFrame(PVC_STATIC_DATA *pPvcStaticData,
+ PVC_DYNAMIC_DATA *pPvcDynamicData, FIXP_DBL **qmfBufferReal,
+ FIXP_DBL **qmfBufferImag, const int overlap,
+ const int qmfExponentOverlap, const int qmfExponentCurrent);
+
+/**
+ * \brief Decode PVC data for one SBR time slot (call if pvcMode = 1,2)
+ * \param[in,out] pPvcStaticData Pointer to PVC persistent data
+ * \param[in,out] pPvcDynamicData Pointer to PVC dynamic data
+ * \param[in] qmfBufferReal Pointer to array with real QMF subbands
+ * \param[in] qmfBufferImag Pointer to array with imag QMF subbands
+ * \param[in] qmfExponent Exponent of qmfBuffer of current time slot
+ * \param[in] pvcBorder0 Start SBR time slot of PVC frame
+ * \param[in] timeSlotNumber Number of current SBR time slot (0..15)
+ * \param[out] predictedEsgSlot Predicted Energy of current time slot
+ * \param[out] predictedEsg_exp Exponent of predicted Energy of current time
+ * slot
+ */
+void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
+ PVC_DYNAMIC_DATA *pPvcDynamicData,
+ FIXP_DBL **qmfSlotReal, FIXP_DBL **qmfSlotImag,
+ const int qmfExponent, const int pvcBorder0,
+ const int timeSlotNumber, FIXP_DBL predictedEsgSlot[],
+ int *predictedEsg_exp);
+
+/**
+ * \brief Finish the current PVC frame (call if pvcMode = 0,1,2)
+ * \param[in,out] pPvcStaticData Pointer to PVC persistent data
+ * \param[in,out] pPvcDynamicData Pointer to PVC dynamic data
+ */
+void pvcEndFrame(PVC_STATIC_DATA *pPvcStaticData,
+ PVC_DYNAMIC_DATA *pPvcDynamicData);
+
+/**
+ * \brief Expand predicted PVC grouped energies to full QMF subband resolution
+ * \param[in] pPvcDynamicData Pointer to PVC dynamic data
+ * \param[in] timeSlot Number of current SBR time slot (0..15)
+ * \param[in] lengthOutputVector Lenght of output vector
+ * \param[out] pOutput Output array for predicted energies
+ * \param[out] pOutput_exp Exponent of predicted energies
+ */
+void expandPredEsg(const PVC_DYNAMIC_DATA *pPvcDynamicData, const int timeSlot,
+ const int lengthOutputVector, FIXP_DBL *pOutput,
+ SCHAR *pOutput_exp);
+
+#endif /* PVC_DEC_H*/
diff --git a/fdk-aac/libSBRdec/src/sbr_crc.cpp b/fdk-aac/libSBRdec/src/sbr_crc.cpp
new file mode 100644
index 0000000..ba0fd05
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbr_crc.cpp
@@ -0,0 +1,192 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief CRC check coutines
+*/
+
+#include "sbr_crc.h"
+
+#include "FDK_bitstream.h"
+#include "transcendent.h"
+
+#define MAXCRCSTEP 16
+#define MAXCRCSTEP_LD 4
+
+/*!
+ \brief crc calculation
+*/
+static ULONG calcCRC(HANDLE_CRC hCrcBuf, ULONG bValue, int nBits) {
+ int i;
+ ULONG bMask = (1UL << (nBits - 1));
+
+ for (i = 0; i < nBits; i++, bMask >>= 1) {
+ USHORT flag = (hCrcBuf->crcState & hCrcBuf->crcMask) ? 1 : 0;
+ USHORT flag1 = (bMask & bValue) ? 1 : 0;
+
+ flag ^= flag1;
+ hCrcBuf->crcState <<= 1;
+ if (flag) hCrcBuf->crcState ^= hCrcBuf->crcPoly;
+ }
+
+ return (hCrcBuf->crcState);
+}
+
+/*!
+ \brief crc
+*/
+static int getCrc(HANDLE_FDK_BITSTREAM hBs, ULONG NrBits) {
+ int i;
+ CRC_BUFFER CrcBuf;
+
+ CrcBuf.crcState = SBR_CRC_START;
+ CrcBuf.crcPoly = SBR_CRC_POLY;
+ CrcBuf.crcMask = SBR_CRC_MASK;
+
+ int CrcStep = NrBits >> MAXCRCSTEP_LD;
+
+ int CrcNrBitsRest = (NrBits - CrcStep * MAXCRCSTEP);
+ ULONG bValue;
+
+ for (i = 0; i < CrcStep; i++) {
+ bValue = FDKreadBits(hBs, MAXCRCSTEP);
+ calcCRC(&CrcBuf, bValue, MAXCRCSTEP);
+ }
+
+ bValue = FDKreadBits(hBs, CrcNrBitsRest);
+ calcCRC(&CrcBuf, bValue, CrcNrBitsRest);
+
+ return (CrcBuf.crcState & SBR_CRC_RANGE);
+}
+
+/*!
+ \brief crc interface
+ \return 1: CRC OK, 0: CRC check failure
+*/
+int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBs, /*!< handle to bit-buffer */
+ LONG NrBits) /*!< max. CRC length */
+{
+ int crcResult = 1;
+ ULONG NrCrcBits;
+ ULONG crcCheckResult;
+ LONG NrBitsAvailable;
+ ULONG crcCheckSum;
+
+ crcCheckSum = FDKreadBits(hBs, 10);
+
+ NrBitsAvailable = FDKgetValidBits(hBs);
+ if (NrBitsAvailable <= 0) {
+ return 0;
+ }
+
+ NrCrcBits = fixMin((INT)NrBits, (INT)NrBitsAvailable);
+
+ crcCheckResult = getCrc(hBs, NrCrcBits);
+ FDKpushBack(hBs, (NrBitsAvailable - FDKgetValidBits(hBs)));
+
+ if (crcCheckResult != crcCheckSum) {
+ crcResult = 0;
+ }
+
+ return (crcResult);
+}
diff --git a/fdk-aac/libSBRdec/src/sbr_crc.h b/fdk-aac/libSBRdec/src/sbr_crc.h
new file mode 100644
index 0000000..9633717
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbr_crc.h
@@ -0,0 +1,138 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief CRC checking routines
+*/
+#ifndef SBR_CRC_H
+#define SBR_CRC_H
+
+#include "sbrdecoder.h"
+
+#include "FDK_bitstream.h"
+
+/* some useful crc polynoms:
+
+crc5: x^5+x^4+x^2+x^1+1
+crc6: x^6+x^5+x^3+x^2+x+1
+crc7: x^7+x^6+x^2+1
+crc8: x^8+x^2+x+x+1
+*/
+
+/* default SBR CRC */ /* G(x) = x^10 + x^9 + x^5 + x^4 + x + 1 */
+#define SBR_CRC_POLY 0x0233
+#define SBR_CRC_MASK 0x0200
+#define SBR_CRC_START 0x0000
+#define SBR_CRC_RANGE 0x03FF
+
+typedef struct {
+ USHORT crcState;
+ USHORT crcMask;
+ USHORT crcPoly;
+} CRC_BUFFER;
+
+typedef CRC_BUFFER *HANDLE_CRC;
+
+int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBitBuf, LONG NrCrcBits);
+
+#endif
diff --git a/fdk-aac/libSBRdec/src/sbr_deb.cpp b/fdk-aac/libSBRdec/src/sbr_deb.cpp
new file mode 100644
index 0000000..13cd211
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbr_deb.cpp
@@ -0,0 +1,108 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Print selected debug messages
+*/
+
+#include "sbr_deb.h"
diff --git a/fdk-aac/libSBRdec/src/sbr_deb.h b/fdk-aac/libSBRdec/src/sbr_deb.h
new file mode 100644
index 0000000..97d572a
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbr_deb.h
@@ -0,0 +1,113 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Debugging aids
+*/
+
+#ifndef SBR_DEB_H
+#define SBR_DEB_H
+
+#include "sbrdecoder.h"
+
+#endif
diff --git a/fdk-aac/libSBRdec/src/sbr_dec.cpp b/fdk-aac/libSBRdec/src/sbr_dec.cpp
new file mode 100644
index 0000000..30611e7
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbr_dec.cpp
@@ -0,0 +1,1480 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Sbr decoder
+ This module provides the actual decoder implementation. The SBR data (side
+ information) is already decoded. Only three functions are provided:
+
+ \li 1.) createSbrDec(): One time initialization
+ \li 2.) resetSbrDec(): Called by sbr_Apply() when the information contained in
+ an SBR_HEADER_ELEMENT requires a reset and recalculation of important SBR
+ structures. \li 3.) sbr_dec(): The actual decoder. Calls the different tools
+ such as filterbanks, lppTransposer(), and calculateSbrEnvelope() [the envelope
+ adjuster].
+
+ \sa sbr_dec(), \ref documentationOverview
+*/
+
+#include "sbr_dec.h"
+
+#include "sbr_ram.h"
+#include "env_extr.h"
+#include "env_calc.h"
+#include "scale.h"
+#include "FDK_matrixCalloc.h"
+#include "hbe.h"
+
+#include "genericStds.h"
+
+#include "sbrdec_drc.h"
+
+static void copyHarmonicSpectrum(int *xOverQmf, FIXP_DBL **qmfReal,
+ FIXP_DBL **qmfImag, int noCols, int overlap,
+ KEEP_STATES_SYNCED_MODE keepStatesSynced) {
+ int patchBands;
+ int patch, band, col, target, sourceBands, i;
+ int numPatches = 0;
+ int slotOffset = 0;
+
+ FIXP_DBL **ppqmfReal = qmfReal + overlap;
+ FIXP_DBL **ppqmfImag = qmfImag + overlap;
+
+ if (keepStatesSynced == KEEP_STATES_SYNCED_NORMAL) {
+ slotOffset = noCols - overlap - LPC_ORDER;
+ }
+
+ if (keepStatesSynced == KEEP_STATES_SYNCED_OUTDIFF) {
+ ppqmfReal = qmfReal;
+ ppqmfImag = qmfImag;
+ }
+
+ for (i = 1; i < MAX_NUM_PATCHES; i++) {
+ if (xOverQmf[i] != 0) {
+ numPatches++;
+ }
+ }
+
+ for (patch = (MAX_STRETCH_HBE - 1); patch < numPatches; patch++) {
+ patchBands = xOverQmf[patch + 1] - xOverQmf[patch];
+ target = xOverQmf[patch];
+ sourceBands = xOverQmf[MAX_STRETCH_HBE - 1] - xOverQmf[MAX_STRETCH_HBE - 2];
+
+ while (patchBands > 0) {
+ int numBands = sourceBands;
+ int startBand = xOverQmf[MAX_STRETCH_HBE - 1] - 1;
+ if (target + numBands >= xOverQmf[patch + 1]) {
+ numBands = xOverQmf[patch + 1] - target;
+ }
+ if ((((target + numBands - 1) % 2) +
+ ((xOverQmf[MAX_STRETCH_HBE - 1] - 1) % 2)) %
+ 2) {
+ if (numBands == sourceBands) {
+ numBands--;
+ } else {
+ startBand--;
+ }
+ }
+ if (keepStatesSynced == KEEP_STATES_SYNCED_OUTDIFF) {
+ for (col = slotOffset; col < overlap + LPC_ORDER; col++) {
+ i = 0;
+ for (band = numBands; band > 0; band--) {
+ if ((target + band - 1 < 64) &&
+ (target + band - 1 < xOverQmf[patch + 1])) {
+ ppqmfReal[col][target + band - 1] = ppqmfReal[col][startBand - i];
+ ppqmfImag[col][target + band - 1] = ppqmfImag[col][startBand - i];
+ i++;
+ }
+ }
+ }
+ } else {
+ for (col = slotOffset; col < noCols; col++) {
+ i = 0;
+ for (band = numBands; band > 0; band--) {
+ if ((target + band - 1 < 64) &&
+ (target + band - 1 < xOverQmf[patch + 1])) {
+ ppqmfReal[col][target + band - 1] = ppqmfReal[col][startBand - i];
+ ppqmfImag[col][target + band - 1] = ppqmfImag[col][startBand - i];
+ i++;
+ }
+ }
+ }
+ }
+ target += numBands;
+ patchBands -= numBands;
+ }
+ }
+}
+
+/*!
+ \brief SBR decoder core function for one channel
+
+ \image html BufferMgmtDetailed-1632.png
+
+ Besides the filter states of the QMF filter bank and the LPC-states of
+ the LPP-Transposer, processing is mainly based on four buffers:
+ #timeIn, #timeOut, #WorkBuffer2 and #OverlapBuffer. The #WorkBuffer2
+ is reused for all channels and might be used by the core decoder, a
+ static overlap buffer is required for each channel. Due to in-place
+ processing, #timeIn and #timeOut point to identical locations.
+
+ The spectral data is organized in so-called slots. Each slot
+ contains 64 bands of complex data. The number of slots per frame
+ depends on the frame size. For mp3PRO, there are 18 slots per frame
+ and 6 slots per #OverlapBuffer. It is not necessary to have the slots
+ in located consecutive address ranges.
+
+ To optimize memory usage and to minimize the number of memory
+ accesses, the memory management is organized as follows (slot numbers
+ based on mp3PRO):
+
+ 1.) Input time domain signal is located in #timeIn. The last slots
+ (0..5) of the spectral data of the previous frame are located in the
+ #OverlapBuffer. In addition, #frameData of the current frame resides
+ in the upper part of #timeIn.
+
+ 2.) During the cplxAnalysisQmfFiltering(), 32 samples from #timeIn are
+ transformed into a slot of up to 32 complex spectral low band values at a
+ time. The first spectral slot -- nr. 6 -- is written at slot number
+ zero of #WorkBuffer2. #WorkBuffer2 will be completely filled with
+ spectral data.
+
+ 3.) LPP-Transposition in lppTransposer() is processed on 24 slots. During the
+ transposition, the high band part of the spectral data is replicated
+ based on the low band data.
+
+ Envelope Adjustment is processed on the high band part of the spectral
+ data only by calculateSbrEnvelope().
+
+ 4.) The cplxSynthesisQmfFiltering() creates 64 time domain samples out
+ of a slot of 64 complex spectral values at a time. The first 6 slots
+ in #timeOut are filled from the results of spectral slots 0..5 in the
+ #OverlapBuffer. The consecutive slots in timeOut are now filled with
+ the results of spectral slots 6..17.
+
+ 5.) The preprocessed slots 18..23 have to be stored in the
+ #OverlapBuffer.
+
+*/
+
+void sbr_dec(
+ HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
+ INT_PCM *timeIn, /*!< pointer to input time signal */
+ INT_PCM *timeOut, /*!< pointer to output time signal */
+ HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */
+ INT_PCM *timeOutRight, /*!< pointer to output time signal */
+ const int strideOut, /*!< Time data traversal strideOut */
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
+ HANDLE_SBR_PREV_FRAME_DATA
+ hPrevFrameData, /*!< Some control data of last frame */
+ const int applyProcessing, /*!< Flag for SBR operation */
+ HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize) {
+ int i, slot, reserve;
+ int saveLbScale;
+ int lastSlotOffs;
+ FIXP_DBL maxVal;
+
+ /* temporary pointer / variable for QMF;
+ required as we want to use temporary buffer
+ creating one frame delay for HBE in LP mode */
+ INT_PCM *pTimeInQmf = timeIn;
+
+ /* Number of QMF timeslots in the overlap buffer: */
+ int ov_len = hSbrDec->LppTrans.pSettings->overlap;
+
+ /* Number of QMF slots per frame */
+ int noCols = hHeaderData->numberTimeSlots * hHeaderData->timeStep;
+
+ /* create pointer array for data to use for HBE and legacy sbr */
+ FIXP_DBL *pLowBandReal[(3 * 4) + 2 * ((1024) / (32) * (4) / 2)];
+ FIXP_DBL *pLowBandImag[(3 * 4) + 2 * ((1024) / (32) * (4) / 2)];
+
+ /* set pReal to where QMF analysis writes in case of legacy SBR */
+ FIXP_DBL **pReal = pLowBandReal + ov_len;
+ FIXP_DBL **pImag = pLowBandImag + ov_len;
+
+ /* map QMF buffer to pointer array (Overlap + Frame)*/
+ for (i = 0; i < noCols + ov_len; i++) {
+ pLowBandReal[i] = hSbrDec->qmfDomainInCh->hQmfSlotsReal[i];
+ pLowBandImag[i] = hSbrDec->qmfDomainInCh->hQmfSlotsImag[i];
+ }
+
+ if ((flags & SBRDEC_USAC_HARMONICSBR)) {
+ /* in case of harmonic SBR and no HBE_LP map additional buffer for
+ one more frame to pointer arry */
+ for (i = 0; i < noCols; i++) {
+ pLowBandReal[i + noCols + ov_len] = hSbrDec->hQmfHBESlotsReal[i];
+ pLowBandImag[i + noCols + ov_len] = hSbrDec->hQmfHBESlotsImag[i];
+ }
+
+ /* shift scale values according to buffer */
+ hSbrDec->scale_ov = hSbrDec->scale_lb;
+ hSbrDec->scale_lb = hSbrDec->scale_hbe;
+
+ /* set pReal to where QMF analysis writes in case of HBE */
+ pReal += noCols;
+ pImag += noCols;
+ if (flags & SBRDEC_SKIP_QMF_ANA) {
+ /* stereoCfgIndex3 with HBE */
+ FDK_QmfDomain_QmfData2HBE(hSbrDec->qmfDomainInCh,
+ hSbrDec->hQmfHBESlotsReal,
+ hSbrDec->hQmfHBESlotsImag);
+ } else {
+ /* We have to move old hbe frame data to lb area of buffer */
+ for (i = 0; i < noCols; i++) {
+ FDKmemcpy(pLowBandReal[ov_len + i], hSbrDec->hQmfHBESlotsReal[i],
+ hHeaderData->numberOfAnalysisBands * sizeof(FIXP_DBL));
+ FDKmemcpy(pLowBandImag[ov_len + i], hSbrDec->hQmfHBESlotsImag[i],
+ hHeaderData->numberOfAnalysisBands * sizeof(FIXP_DBL));
+ }
+ }
+ }
+
+ /*
+ low band codec signal subband filtering
+ */
+
+ if (flags & SBRDEC_SKIP_QMF_ANA) {
+ if (!(flags & SBRDEC_USAC_HARMONICSBR)) /* stereoCfgIndex3 w/o HBE */
+ FDK_QmfDomain_WorkBuffer2ProcChannel(hSbrDec->qmfDomainInCh);
+ } else {
+ C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * (64));
+ qmfAnalysisFiltering(&hSbrDec->qmfDomainInCh->fb, pReal, pImag,
+ &hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, 0, 1,
+ qmfTemp);
+
+ C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * (64));
+ }
+
+ /*
+ Clear upper half of spectrum
+ */
+ if (!((flags & SBRDEC_USAC_HARMONICSBR) &&
+ (hFrameData->sbrPatchingMode == 0))) {
+ int nAnalysisBands = hHeaderData->numberOfAnalysisBands;
+
+ if (!(flags & SBRDEC_LOW_POWER)) {
+ for (slot = ov_len; slot < noCols + ov_len; slot++) {
+ FDKmemclear(&pLowBandReal[slot][nAnalysisBands],
+ ((64) - nAnalysisBands) * sizeof(FIXP_DBL));
+ FDKmemclear(&pLowBandImag[slot][nAnalysisBands],
+ ((64) - nAnalysisBands) * sizeof(FIXP_DBL));
+ }
+ } else {
+ for (slot = ov_len; slot < noCols + ov_len; slot++) {
+ FDKmemclear(&pLowBandReal[slot][nAnalysisBands],
+ ((64) - nAnalysisBands) * sizeof(FIXP_DBL));
+ }
+ }
+ }
+
+ /*
+ Shift spectral data left to gain accuracy in transposer and adjustor
+ */
+ /* Range was increased from lsb to no_channels because in some cases (e.g.
+ USAC conf eSbr_4_Pvc.mp4 and some HBE cases) it could be observed that the
+ signal between lsb and no_channels is used for the patching process.
+ */
+ maxVal = maxSubbandSample(pReal, (flags & SBRDEC_LOW_POWER) ? NULL : pImag, 0,
+ hSbrDec->qmfDomainInCh->fb.no_channels, 0, noCols);
+
+ reserve = fixMax(0, CntLeadingZeros(maxVal) - 1);
+ reserve = fixMin(reserve,
+ DFRACT_BITS - 1 - hSbrDec->qmfDomainInCh->scaling.lb_scale);
+
+ /* If all data is zero, lb_scale could become too large */
+ rescaleSubbandSamples(pReal, (flags & SBRDEC_LOW_POWER) ? NULL : pImag, 0,
+ hSbrDec->qmfDomainInCh->fb.no_channels, 0, noCols,
+ reserve);
+
+ hSbrDec->qmfDomainInCh->scaling.lb_scale += reserve;
+
+ if ((flags & SBRDEC_USAC_HARMONICSBR)) {
+ /* actually this is our hbe_scale */
+ hSbrDec->scale_hbe = hSbrDec->qmfDomainInCh->scaling.lb_scale;
+ /* the real lb_scale is stored in scale_lb from sbr */
+ hSbrDec->qmfDomainInCh->scaling.lb_scale = hSbrDec->scale_lb;
+ }
+ /*
+ save low band scale, wavecoding or parametric stereo may modify it
+ */
+ saveLbScale = hSbrDec->qmfDomainInCh->scaling.lb_scale;
+
+ if (applyProcessing) {
+ UCHAR *borders = hFrameData->frameInfo.borders;
+ lastSlotOffs = borders[hFrameData->frameInfo.nEnvelopes] -
+ hHeaderData->numberTimeSlots;
+
+ FIXP_DBL degreeAlias[(64)];
+ PVC_DYNAMIC_DATA pvcDynamicData;
+ pvcInitFrame(
+ &hSbrDec->PvcStaticData, &pvcDynamicData,
+ (hHeaderData->frameErrorFlag ? 0 : hHeaderData->bs_info.pvc_mode),
+ hFrameData->ns, hHeaderData->timeStep,
+ hHeaderData->freqBandData.lowSubband,
+ hFrameData->frameInfo.pvcBorders[0], hFrameData->pvcID);
+
+ if (!hHeaderData->frameErrorFlag && (hHeaderData->bs_info.pvc_mode > 0)) {
+ pvcDecodeFrame(&hSbrDec->PvcStaticData, &pvcDynamicData, pLowBandReal,
+ pLowBandImag, ov_len,
+ SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale),
+ SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.lb_scale));
+ }
+ pvcEndFrame(&hSbrDec->PvcStaticData, &pvcDynamicData);
+
+ /* The transposer will override most values in degreeAlias[].
+ The array needs to be cleared at least from lowSubband to highSubband
+ before. */
+ if (flags & SBRDEC_LOW_POWER)
+ FDKmemclear(&degreeAlias[hHeaderData->freqBandData.lowSubband],
+ (hHeaderData->freqBandData.highSubband -
+ hHeaderData->freqBandData.lowSubband) *
+ sizeof(FIXP_DBL));
+
+ /*
+ Inverse filtering of lowband and transposition into the SBR-frequency
+ range
+ */
+
+ {
+ KEEP_STATES_SYNCED_MODE keepStatesSyncedMode =
+ ((flags & SBRDEC_USAC_HARMONICSBR) &&
+ (hFrameData->sbrPatchingMode != 0))
+ ? KEEP_STATES_SYNCED_NORMAL
+ : KEEP_STATES_SYNCED_OFF;
+
+ if (flags & SBRDEC_USAC_HARMONICSBR) {
+ if (flags & SBRDEC_QUAD_RATE) {
+ pReal -= 32;
+ pImag -= 32;
+ }
+
+ if ((hSbrDec->savedStates == 0) && (hFrameData->sbrPatchingMode == 1)) {
+ /* copy saved states from previous frame to legacy SBR lpc filterstate
+ * buffer */
+ for (i = 0; i < LPC_ORDER + ov_len; i++) {
+ FDKmemcpy(
+ hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i],
+ hSbrDec->codecQMFBufferReal[noCols - LPC_ORDER - ov_len + i],
+ hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
+ FDKmemcpy(
+ hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i],
+ hSbrDec->codecQMFBufferImag[noCols - LPC_ORDER - ov_len + i],
+ hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
+ }
+ }
+
+ /* saving unmodified QMF states in case we are switching from legacy SBR
+ * to HBE */
+ for (i = 0; i < hSbrDec->hHBE->noCols; i++) {
+ FDKmemcpy(hSbrDec->codecQMFBufferReal[i], pLowBandReal[ov_len + i],
+ hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
+ FDKmemcpy(hSbrDec->codecQMFBufferImag[i], pLowBandImag[ov_len + i],
+ hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
+ }
+
+ QmfTransposerApply(
+ hSbrDec->hHBE, pReal, pImag, noCols, pLowBandReal, pLowBandImag,
+ hSbrDec->LppTrans.lpcFilterStatesRealHBE,
+ hSbrDec->LppTrans.lpcFilterStatesImagHBE,
+ hFrameData->sbrPitchInBins, hSbrDec->scale_lb, hSbrDec->scale_hbe,
+ &hSbrDec->qmfDomainInCh->scaling.hb_scale, hHeaderData->timeStep,
+ borders[0], ov_len, keepStatesSyncedMode);
+
+ if (flags & SBRDEC_QUAD_RATE) {
+ int *xOverQmf = GetxOverBandQmfTransposer(hSbrDec->hHBE);
+
+ copyHarmonicSpectrum(xOverQmf, pLowBandReal, pLowBandImag, noCols,
+ ov_len, keepStatesSyncedMode);
+ }
+ }
+ }
+
+ if ((flags & SBRDEC_USAC_HARMONICSBR) &&
+ (hFrameData->sbrPatchingMode == 0)) {
+ hSbrDec->prev_frame_lSbr = 0;
+ hSbrDec->prev_frame_hbeSbr = 1;
+
+ lppTransposerHBE(
+ &hSbrDec->LppTrans, hSbrDec->hHBE, &hSbrDec->qmfDomainInCh->scaling,
+ pLowBandReal, pLowBandImag, hHeaderData->timeStep, borders[0],
+ lastSlotOffs, hHeaderData->freqBandData.nInvfBands,
+ hFrameData->sbr_invf_mode, hPrevFrameData->sbr_invf_mode);
+
+ } else {
+ if (flags & SBRDEC_USAC_HARMONICSBR) {
+ for (i = 0; i < LPC_ORDER + hSbrDec->LppTrans.pSettings->overlap; i++) {
+ /*
+ Store the unmodified qmf Slots values for upper part of spectrum
+ (required for LPC filtering) required if next frame is a HBE frame
+ */
+ FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealHBE[i],
+ hSbrDec->qmfDomainInCh
+ ->hQmfSlotsReal[hSbrDec->hHBE->noCols - LPC_ORDER + i],
+ (64) * sizeof(FIXP_DBL));
+ FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesImagHBE[i],
+ hSbrDec->qmfDomainInCh
+ ->hQmfSlotsImag[hSbrDec->hHBE->noCols - LPC_ORDER + i],
+ (64) * sizeof(FIXP_DBL));
+ }
+ }
+ {
+ hSbrDec->prev_frame_lSbr = 1;
+ hSbrDec->prev_frame_hbeSbr = 0;
+ }
+
+ lppTransposer(
+ &hSbrDec->LppTrans, &hSbrDec->qmfDomainInCh->scaling, pLowBandReal,
+ degreeAlias, // only used if useLP = 1
+ pLowBandImag, flags & SBRDEC_LOW_POWER,
+ hHeaderData->bs_info.sbr_preprocessing,
+ hHeaderData->freqBandData.v_k_master[0], hHeaderData->timeStep,
+ borders[0], lastSlotOffs, hHeaderData->freqBandData.nInvfBands,
+ hFrameData->sbr_invf_mode, hPrevFrameData->sbr_invf_mode);
+ }
+
+ /*
+ Adjust envelope of current frame.
+ */
+
+ if ((hFrameData->sbrPatchingMode !=
+ hSbrDec->SbrCalculateEnvelope.sbrPatchingMode)) {
+ ResetLimiterBands(hHeaderData->freqBandData.limiterBandTable,
+ &hHeaderData->freqBandData.noLimiterBands,
+ hHeaderData->freqBandData.freqBandTable[0],
+ hHeaderData->freqBandData.nSfb[0],
+ hSbrDec->LppTrans.pSettings->patchParam,
+ hSbrDec->LppTrans.pSettings->noOfPatches,
+ hHeaderData->bs_data.limiterBands,
+ hFrameData->sbrPatchingMode,
+ (flags & SBRDEC_USAC_HARMONICSBR) &&
+ (hFrameData->sbrPatchingMode == 0)
+ ? GetxOverBandQmfTransposer(hSbrDec->hHBE)
+ : NULL,
+ Get41SbrQmfTransposer(hSbrDec->hHBE));
+
+ hSbrDec->SbrCalculateEnvelope.sbrPatchingMode =
+ hFrameData->sbrPatchingMode;
+ }
+
+ calculateSbrEnvelope(
+ &hSbrDec->qmfDomainInCh->scaling, &hSbrDec->SbrCalculateEnvelope,
+ hHeaderData, hFrameData, &pvcDynamicData, pLowBandReal, pLowBandImag,
+ flags & SBRDEC_LOW_POWER,
+
+ degreeAlias, flags,
+ (hHeaderData->frameErrorFlag || hPrevFrameData->frameErrorFlag));
+
+#if (SBRDEC_MAX_HB_FADE_FRAMES > 0)
+ /* Avoid hard onsets of high band */
+ if (hHeaderData->frameErrorFlag) {
+ if (hSbrDec->highBandFadeCnt < SBRDEC_MAX_HB_FADE_FRAMES) {
+ hSbrDec->highBandFadeCnt += 1;
+ }
+ } else {
+ if (hSbrDec->highBandFadeCnt >
+ 0) { /* Manipulate high band scale factor to get a smooth fade-in */
+ hSbrDec->qmfDomainInCh->scaling.hb_scale += hSbrDec->highBandFadeCnt;
+ hSbrDec->qmfDomainInCh->scaling.hb_scale =
+ fMin(hSbrDec->qmfDomainInCh->scaling.hb_scale, DFRACT_BITS - 1);
+ hSbrDec->highBandFadeCnt -= 1;
+ }
+ }
+
+#endif
+ /*
+ Update hPrevFrameData (to be used in the next frame)
+ */
+ for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) {
+ hPrevFrameData->sbr_invf_mode[i] = hFrameData->sbr_invf_mode[i];
+ }
+ hPrevFrameData->coupling = hFrameData->coupling;
+ hPrevFrameData->stopPos = borders[hFrameData->frameInfo.nEnvelopes];
+ hPrevFrameData->ampRes = hFrameData->ampResolutionCurrentFrame;
+ hPrevFrameData->prevSbrPitchInBins = hFrameData->sbrPitchInBins;
+ /* could be done in extractFrameInfo_pvc() but hPrevFrameData is not
+ * available there */
+ FDKmemcpy(&hPrevFrameData->prevFrameInfo, &hFrameData->frameInfo,
+ sizeof(FRAME_INFO));
+ } else {
+ /* rescale from lsb to nAnalysisBands in order to compensate scaling with
+ * hb_scale in this area, done by synthesisFiltering*/
+ int rescale;
+ int lsb;
+ int length;
+
+ /* Reset hb_scale if no highband is present, because hb_scale is considered
+ * in the QMF-synthesis */
+ hSbrDec->qmfDomainInCh->scaling.hb_scale = saveLbScale;
+
+ rescale = hSbrDec->qmfDomainInCh->scaling.hb_scale -
+ hSbrDec->qmfDomainInCh->scaling.ov_lb_scale;
+ lsb = hSbrDec->qmfDomainOutCh->fb.lsb;
+ length = (hSbrDec->qmfDomainInCh->fb.no_channels - lsb);
+
+ if ((rescale < 0) && (length > 0)) {
+ if (!(flags & SBRDEC_LOW_POWER)) {
+ for (i = 0; i < ov_len; i++) {
+ scaleValues(&pLowBandReal[i][lsb], length, rescale);
+ scaleValues(&pLowBandImag[i][lsb], length, rescale);
+ }
+ } else {
+ for (i = 0; i < ov_len; i++) {
+ scaleValues(&pLowBandReal[i][lsb], length, rescale);
+ }
+ }
+ }
+ }
+
+ if (!(flags & SBRDEC_USAC_HARMONICSBR)) {
+ int length = hSbrDec->qmfDomainInCh->fb.lsb;
+ if (flags & SBRDEC_SYNTAX_USAC) {
+ length = hSbrDec->qmfDomainInCh->fb.no_channels;
+ }
+
+ /* in case of legacy sbr saving of filter states here */
+ for (i = 0; i < LPC_ORDER + ov_len; i++) {
+ /*
+ Store the unmodified qmf Slots values (required for LPC filtering)
+ */
+ if (!(flags & SBRDEC_LOW_POWER)) {
+ FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i],
+ pLowBandReal[noCols - LPC_ORDER + i],
+ length * sizeof(FIXP_DBL));
+ FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i],
+ pLowBandImag[noCols - LPC_ORDER + i],
+ length * sizeof(FIXP_DBL));
+ } else
+ FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i],
+ pLowBandReal[noCols - LPC_ORDER + i],
+ length * sizeof(FIXP_DBL));
+ }
+ }
+
+ /*
+ Synthesis subband filtering.
+ */
+
+ if (!(flags & SBRDEC_PS_DECODED)) {
+ if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
+ int outScalefactor = 0;
+
+ if (h_ps_d != NULL) {
+ h_ps_d->procFrameBased = 1; /* we here do frame based processing */
+ }
+
+ sbrDecoder_drcApply(&hSbrDec->sbrDrcChannel, pLowBandReal,
+ (flags & SBRDEC_LOW_POWER) ? NULL : pLowBandImag,
+ hSbrDec->qmfDomainOutCh->fb.no_col, &outScalefactor);
+
+ qmfChangeOutScalefactor(&hSbrDec->qmfDomainOutCh->fb, outScalefactor);
+
+ {
+ HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
+ int save_usb = hSbrDec->qmfDomainOutCh->fb.usb;
+
+#if (QMF_MAX_SYNTHESIS_BANDS <= 64)
+ C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
+#else
+ C_AALLOC_STACK_START(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
+#endif
+ if (hSbrDec->qmfDomainOutCh->fb.usb < hFreq->ov_highSubband) {
+ /* we need to patch usb for this frame as overlap may contain higher
+ frequency range if headerchange occured; fb. usb is always limited
+ to maximum fb.no_channels; In case of wrongly decoded headers it
+ might be that ov_highSubband is higher than the number of synthesis
+ channels (fb.no_channels), which is forbidden, therefore we need to
+ limit ov_highSubband with fMin function to avoid not allowed usb in
+ synthesis filterbank. */
+ hSbrDec->qmfDomainOutCh->fb.usb =
+ fMin((UINT)hFreq->ov_highSubband,
+ (UINT)hSbrDec->qmfDomainOutCh->fb.no_channels);
+ }
+ {
+ qmfSynthesisFiltering(
+ &hSbrDec->qmfDomainOutCh->fb, pLowBandReal,
+ (flags & SBRDEC_LOW_POWER) ? NULL : pLowBandImag,
+ &hSbrDec->qmfDomainInCh->scaling,
+ hSbrDec->LppTrans.pSettings->overlap, timeOut, strideOut,
+ qmfTemp);
+ }
+ /* restore saved value */
+ hSbrDec->qmfDomainOutCh->fb.usb = save_usb;
+ hFreq->ov_highSubband = save_usb;
+#if (QMF_MAX_SYNTHESIS_BANDS <= 64)
+ C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
+#else
+ C_AALLOC_STACK_END(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
+#endif
+ }
+ }
+
+ } else { /* (flags & SBRDEC_PS_DECODED) */
+ INT sdiff;
+ INT scaleFactorHighBand, scaleFactorLowBand_ov, scaleFactorLowBand_no_ov;
+
+ HANDLE_QMF_FILTER_BANK synQmf = &hSbrDec->qmfDomainOutCh->fb;
+ HANDLE_QMF_FILTER_BANK synQmfRight = &hSbrDecRight->qmfDomainOutCh->fb;
+
+ /* adapt scaling */
+ sdiff = hSbrDec->qmfDomainInCh->scaling.lb_scale -
+ reserve; /* Scaling difference */
+ scaleFactorHighBand = sdiff - hSbrDec->qmfDomainInCh->scaling.hb_scale;
+ scaleFactorLowBand_ov = sdiff - hSbrDec->qmfDomainInCh->scaling.ov_lb_scale;
+ scaleFactorLowBand_no_ov = sdiff - hSbrDec->qmfDomainInCh->scaling.lb_scale;
+
+ /* Scale of low band overlapping QMF data */
+ scaleFactorLowBand_ov =
+ fMin(DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorLowBand_ov));
+ /* Scale of low band current QMF data */
+ scaleFactorLowBand_no_ov = fMin(
+ DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorLowBand_no_ov));
+ /* Scale of current high band */
+ scaleFactorHighBand =
+ fMin(DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorHighBand));
+
+ if (h_ps_d->procFrameBased == 1) /* If we have switched from frame to slot
+ based processing copy filter states */
+ { /* procFrameBased will be unset later */
+ /* copy filter states from left to right */
+ /* was ((640)-(64))*sizeof(FIXP_QSS)
+ flexible amount of synthesis bands needed for QMF based resampling
+ */
+ FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <=
+ QMF_MAX_SYNTHESIS_BANDS);
+ FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates,
+ 9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis *
+ sizeof(FIXP_QSS));
+ }
+
+ /* Feed delaylines when parametric stereo is switched on. */
+ PreparePsProcessing(h_ps_d, pLowBandReal, pLowBandImag,
+ scaleFactorLowBand_ov);
+
+ /* use the same synthese qmf values for left and right channel */
+ synQmfRight->no_col = synQmf->no_col;
+ synQmfRight->lsb = synQmf->lsb;
+ synQmfRight->usb = synQmf->usb;
+
+ int env = 0;
+
+ {
+#if (QMF_MAX_SYNTHESIS_BANDS <= 64)
+ C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL,
+ 2 * QMF_MAX_SYNTHESIS_BANDS);
+#else
+ C_AALLOC_STACK_START(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
+#endif
+
+ int maxShift = 0;
+
+ if (hSbrDec->sbrDrcChannel.enable != 0) {
+ if (hSbrDec->sbrDrcChannel.prevFact_exp > maxShift) {
+ maxShift = hSbrDec->sbrDrcChannel.prevFact_exp;
+ }
+ if (hSbrDec->sbrDrcChannel.currFact_exp > maxShift) {
+ maxShift = hSbrDec->sbrDrcChannel.currFact_exp;
+ }
+ if (hSbrDec->sbrDrcChannel.nextFact_exp > maxShift) {
+ maxShift = hSbrDec->sbrDrcChannel.nextFact_exp;
+ }
+ }
+
+ /* copy DRC data to right channel (with PS both channels use the same DRC
+ * gains) */
+ FDKmemcpy(&hSbrDecRight->sbrDrcChannel, &hSbrDec->sbrDrcChannel,
+ sizeof(SBRDEC_DRC_CHANNEL));
+
+ for (i = 0; i < synQmf->no_col; i++) { /* ----- no_col loop ----- */
+
+ INT outScalefactorR, outScalefactorL;
+
+ /* qmf timeslot of right channel */
+ FIXP_DBL *rQmfReal = pWorkBuffer;
+ FIXP_DBL *rQmfImag = pWorkBuffer + synQmf->no_channels;
+
+ {
+ if (i ==
+ h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env]) {
+ initSlotBasedRotation(h_ps_d, env,
+ hHeaderData->freqBandData.highSubband);
+ env++;
+ }
+
+ ApplyPsSlot(
+ h_ps_d, /* parametric stereo decoder handle */
+ (pLowBandReal + i), /* one timeslot of left/mono channel */
+ (pLowBandImag + i), /* one timeslot of left/mono channel */
+ rQmfReal, /* one timeslot or right channel */
+ rQmfImag, /* one timeslot or right channel */
+ scaleFactorLowBand_no_ov,
+ (i < hSbrDec->LppTrans.pSettings->overlap)
+ ? scaleFactorLowBand_ov
+ : scaleFactorLowBand_no_ov,
+ scaleFactorHighBand, synQmf->lsb, synQmf->usb);
+
+ outScalefactorL = outScalefactorR = 1; /* psDiffScale! (MPEG-PS) */
+ }
+
+ sbrDecoder_drcApplySlot(/* right channel */
+ &hSbrDecRight->sbrDrcChannel, rQmfReal,
+ rQmfImag, i, synQmfRight->no_col, maxShift);
+
+ outScalefactorR += maxShift;
+
+ sbrDecoder_drcApplySlot(/* left channel */
+ &hSbrDec->sbrDrcChannel, *(pLowBandReal + i),
+ *(pLowBandImag + i), i, synQmf->no_col,
+ maxShift);
+
+ outScalefactorL += maxShift;
+
+ if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
+ qmfSynthesisFilteringSlot(
+ synQmfRight, rQmfReal, /* QMF real buffer */
+ rQmfImag, /* QMF imag buffer */
+ outScalefactorL, outScalefactorL,
+ timeOutRight + (i * synQmf->no_channels * strideOut), strideOut,
+ pWorkBuffer);
+
+ qmfSynthesisFilteringSlot(
+ synQmf, *(pLowBandReal + i), /* QMF real buffer */
+ *(pLowBandImag + i), /* QMF imag buffer */
+ outScalefactorR, outScalefactorR,
+ timeOut + (i * synQmf->no_channels * strideOut), strideOut,
+ pWorkBuffer);
+ }
+ } /* no_col loop i */
+#if (QMF_MAX_SYNTHESIS_BANDS <= 64)
+ C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
+#else
+ C_AALLOC_STACK_END(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS);
+#endif
+ }
+ }
+
+ sbrDecoder_drcUpdateChannel(&hSbrDec->sbrDrcChannel);
+
+ /*
+ Update overlap buffer
+ Even bands above usb are copied to avoid outdated spectral data in case
+ the stop frequency raises.
+ */
+
+ if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
+ {
+ FDK_QmfDomain_SaveOverlap(hSbrDec->qmfDomainInCh, 0);
+ FDK_ASSERT(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale == saveLbScale);
+ }
+ }
+
+ hSbrDec->savedStates = 0;
+
+ /* Save current frame status */
+ hPrevFrameData->frameErrorFlag = hHeaderData->frameErrorFlag;
+ hSbrDec->applySbrProc_old = applyProcessing;
+
+} /* sbr_dec() */
+
+/*!
+ \brief Creates sbr decoder structure
+ \return errorCode, 0 if successful
+*/
+SBR_ERROR
+createSbrDec(SBR_CHANNEL *hSbrChannel,
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ TRANSPOSER_SETTINGS *pSettings,
+ const int downsampleFac, /*!< Downsampling factor */
+ const UINT qmfFlags, /*!< flags -> 1: HQ/LP selector, 2: CLDFB */
+ const UINT flags, const int overlap,
+ int chan, /*!< Channel for which to assign buffers etc. */
+ int codecFrameSize)
+
+{
+ SBR_ERROR err = SBRDEC_OK;
+ int timeSlots =
+ hHeaderData->numberTimeSlots; /* Number of SBR slots per frame */
+ int noCols =
+ timeSlots * hHeaderData->timeStep; /* Number of QMF slots per frame */
+ HANDLE_SBR_DEC hs = &(hSbrChannel->SbrDec);
+
+#if (SBRDEC_MAX_HB_FADE_FRAMES > 0)
+ hs->highBandFadeCnt = SBRDEC_MAX_HB_FADE_FRAMES;
+
+#endif
+ hs->scale_hbe = 15;
+ hs->scale_lb = 15;
+ hs->scale_ov = 15;
+
+ hs->prev_frame_lSbr = 0;
+ hs->prev_frame_hbeSbr = 0;
+
+ hs->codecFrameSize = codecFrameSize;
+
+ /*
+ create envelope calculator
+ */
+ err = createSbrEnvelopeCalc(&hs->SbrCalculateEnvelope, hHeaderData, chan,
+ flags);
+ if (err != SBRDEC_OK) {
+ return err;
+ }
+
+ initSbrPrevFrameData(&hSbrChannel->prevFrameData, timeSlots);
+
+ /*
+ create transposer
+ */
+ err = createLppTransposer(
+ &hs->LppTrans, pSettings, hHeaderData->freqBandData.lowSubband,
+ hHeaderData->freqBandData.v_k_master, hHeaderData->freqBandData.numMaster,
+ hHeaderData->freqBandData.highSubband, timeSlots, noCols,
+ hHeaderData->freqBandData.freqBandTableNoise,
+ hHeaderData->freqBandData.nNfb, hHeaderData->sbrProcSmplRate, chan,
+ overlap);
+ if (err != SBRDEC_OK) {
+ return err;
+ }
+
+ if (flags & SBRDEC_USAC_HARMONICSBR) {
+ int noChannels, bSbr41 = flags & SBRDEC_QUAD_RATE ? 1 : 0;
+
+ noChannels =
+ QMF_SYNTH_CHANNELS /
+ ((bSbr41 + 1) * 2); /* 32 for (32:64 and 24:64) and 16 for 16:64 */
+
+ /* shared memory between hbeLightTimeDelayBuffer and hQmfHBESlotsReal if
+ * SBRDEC_HBE_ENABLE */
+ hSbrChannel->SbrDec.tmp_memory = (FIXP_DBL **)fdkCallocMatrix2D_aligned(
+ noCols, noChannels, sizeof(FIXP_DBL));
+ if (hSbrChannel->SbrDec.tmp_memory == NULL) {
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+
+ hSbrChannel->SbrDec.hQmfHBESlotsReal = hSbrChannel->SbrDec.tmp_memory;
+ hSbrChannel->SbrDec.hQmfHBESlotsImag =
+ (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels,
+ sizeof(FIXP_DBL));
+ if (hSbrChannel->SbrDec.hQmfHBESlotsImag == NULL) {
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+
+ /* buffers containing unmodified qmf data; required when switching from
+ * legacy SBR to HBE */
+ /* buffer can be used as LPCFilterstates buffer because legacy SBR needs
+ * exactly these values for LPC filtering */
+ hSbrChannel->SbrDec.codecQMFBufferReal =
+ (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels,
+ sizeof(FIXP_DBL));
+ if (hSbrChannel->SbrDec.codecQMFBufferReal == NULL) {
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+
+ hSbrChannel->SbrDec.codecQMFBufferImag =
+ (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels,
+ sizeof(FIXP_DBL));
+ if (hSbrChannel->SbrDec.codecQMFBufferImag == NULL) {
+ return SBRDEC_MEM_ALLOC_FAILED;
+ }
+
+ err = QmfTransposerCreate(&hs->hHBE, codecFrameSize, 0, bSbr41);
+ if (err != SBRDEC_OK) {
+ return err;
+ }
+ }
+
+ return err;
+}
+
+/*!
+ \brief Delete sbr decoder structure
+ \return errorCode, 0 if successful
+*/
+int deleteSbrDec(SBR_CHANNEL *hSbrChannel) {
+ HANDLE_SBR_DEC hs = &hSbrChannel->SbrDec;
+
+ deleteSbrEnvelopeCalc(&hs->SbrCalculateEnvelope);
+
+ if (hs->tmp_memory != NULL) {
+ FDK_FREE_MEMORY_2D_ALIGNED(hs->tmp_memory);
+ }
+
+ /* modify here */
+ FDK_FREE_MEMORY_2D_ALIGNED(hs->hQmfHBESlotsImag);
+
+ if (hs->hHBE != NULL) QmfTransposerClose(hs->hHBE);
+
+ if (hs->codecQMFBufferReal != NULL) {
+ FDK_FREE_MEMORY_2D_ALIGNED(hs->codecQMFBufferReal);
+ }
+
+ if (hs->codecQMFBufferImag != NULL) {
+ FDK_FREE_MEMORY_2D_ALIGNED(hs->codecQMFBufferImag);
+ }
+
+ return 0;
+}
+
+/*!
+ \brief resets sbr decoder structure
+ \return errorCode, 0 if successful
+*/
+SBR_ERROR
+resetSbrDec(HANDLE_SBR_DEC hSbrDec, HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, const int downsampleFac,
+ const UINT flags, HANDLE_SBR_FRAME_DATA hFrameData) {
+ SBR_ERROR sbrError = SBRDEC_OK;
+ int i;
+ FIXP_DBL *pLowBandReal[128];
+ FIXP_DBL *pLowBandImag[128];
+ int useLP = flags & SBRDEC_LOW_POWER;
+
+ int old_lsb = hSbrDec->qmfDomainInCh->fb.lsb;
+ int old_usb = hSbrDec->qmfDomainInCh->fb.usb;
+ int new_lsb = hHeaderData->freqBandData.lowSubband;
+ /* int new_usb = hHeaderData->freqBandData.highSubband; */
+ int l, startBand, stopBand, startSlot, size;
+
+ FIXP_DBL **OverlapBufferReal = hSbrDec->qmfDomainInCh->hQmfSlotsReal;
+ FIXP_DBL **OverlapBufferImag = hSbrDec->qmfDomainInCh->hQmfSlotsImag;
+
+ /* in case the previous frame was not active in terms of SBR processing, the
+ full band from 0 to no_channels was rescaled and not overwritten. Thats why
+ the scaling factor lb_scale can be seen as assigned to all bands from 0 to
+ no_channels in the previous frame. The same states for the current frame if
+ the current frame is not active in terms of SBR processing
+ */
+ int applySbrProc = (hHeaderData->syncState == SBR_ACTIVE ||
+ (hHeaderData->frameErrorFlag == 0 &&
+ hHeaderData->syncState == SBR_HEADER));
+ int applySbrProc_old = hSbrDec->applySbrProc_old;
+
+ if (!applySbrProc) {
+ new_lsb = (hSbrDec->qmfDomainInCh->fb).no_channels;
+ }
+ if (!applySbrProc_old) {
+ old_lsb = (hSbrDec->qmfDomainInCh->fb).no_channels;
+ old_usb = old_lsb;
+ }
+
+ resetSbrEnvelopeCalc(&hSbrDec->SbrCalculateEnvelope);
+
+ /* Change lsb and usb */
+ /* Synthesis */
+ FDK_ASSERT(hSbrDec->qmfDomainOutCh != NULL);
+ hSbrDec->qmfDomainOutCh->fb.lsb =
+ fixMin((INT)hSbrDec->qmfDomainOutCh->fb.no_channels,
+ (INT)hHeaderData->freqBandData.lowSubband);
+ hSbrDec->qmfDomainOutCh->fb.usb =
+ fixMin((INT)hSbrDec->qmfDomainOutCh->fb.no_channels,
+ (INT)hHeaderData->freqBandData.highSubband);
+ /* Analysis */
+ FDK_ASSERT(hSbrDec->qmfDomainInCh != NULL);
+ hSbrDec->qmfDomainInCh->fb.lsb = hSbrDec->qmfDomainOutCh->fb.lsb;
+ hSbrDec->qmfDomainInCh->fb.usb = hSbrDec->qmfDomainOutCh->fb.usb;
+
+ /*
+ The following initialization of spectral data in the overlap buffer
+ is required for dynamic x-over or a change of the start-freq for 2 reasons:
+
+ 1. If the lowband gets _wider_, unadjusted data would remain
+
+ 2. If the lowband becomes _smaller_, the highest bands of the old lowband
+ must be cleared because the whitening would be affected
+ */
+ startBand = old_lsb;
+ stopBand = new_lsb;
+ startSlot = fMax(0, hHeaderData->timeStep * (hPrevFrameData->stopPos -
+ hHeaderData->numberTimeSlots));
+ size = fMax(0, stopBand - startBand);
+
+ /* in case of USAC we don't want to zero out the memory, as this can lead to
+ holes in the spectrum; fix shall only be applied for USAC not for MPEG-4
+ SBR, in this case setting zero remains */
+ if (!(flags & SBRDEC_SYNTAX_USAC)) {
+ /* keep already adjusted data in the x-over-area */
+ if (!useLP) {
+ for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) {
+ FDKmemclear(&OverlapBufferReal[l][startBand], size * sizeof(FIXP_DBL));
+ FDKmemclear(&OverlapBufferImag[l][startBand], size * sizeof(FIXP_DBL));
+ }
+ } else {
+ for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) {
+ FDKmemclear(&OverlapBufferReal[l][startBand], size * sizeof(FIXP_DBL));
+ }
+ }
+
+ /*
+ reset LPC filter states
+ */
+ startBand = fixMin(old_lsb, new_lsb);
+ stopBand = fixMax(old_lsb, new_lsb);
+ size = fixMax(0, stopBand - startBand);
+
+ FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[0][startBand],
+ size * sizeof(FIXP_DBL));
+ FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[1][startBand],
+ size * sizeof(FIXP_DBL));
+ if (!useLP) {
+ FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[0][startBand],
+ size * sizeof(FIXP_DBL));
+ FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[1][startBand],
+ size * sizeof(FIXP_DBL));
+ }
+ }
+
+ if (startSlot != 0) {
+ int source_exp, target_exp, delta_exp, target_lsb, target_usb, reserve;
+ FIXP_DBL maxVal;
+
+ /*
+ Rescale already processed spectral data between old and new x-over
+ frequency. This must be done because of the separate scalefactors for
+ lowband and highband.
+ */
+
+ /* We have four relevant transitions to cover:
+ 1. old_usb is lower than new_lsb; old SBR area is completely below new SBR
+ area.
+ -> entire old area was highband and belongs to lowband now
+ and has to be rescaled.
+ 2. old_lsb is higher than new_usb; new SBR area is completely below old SBR
+ area.
+ -> old area between new_lsb and old_lsb was lowband and belongs to
+ highband now and has to be rescaled to match new highband scale.
+ 3. old_lsb is lower and old_usb is higher than new_lsb; old and new SBR
+ areas overlap.
+ -> old area between old_lsb and new_lsb was highband and belongs to
+ lowband now and has to be rescaled to match new lowband scale.
+ 4. new_lsb is lower and new_usb_is higher than old_lsb; old and new SBR
+ areas overlap.
+ -> old area between new_lsb and old_usb was lowband and belongs to
+ highband now and has to be rescaled to match new highband scale.
+ */
+
+ if (new_lsb > old_lsb) {
+ /* case 1 and 3 */
+ source_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_hb_scale);
+ target_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale);
+
+ startBand = old_lsb;
+
+ if (new_lsb >= old_usb) {
+ /* case 1 */
+ stopBand = old_usb;
+ } else {
+ /* case 3 */
+ stopBand = new_lsb;
+ }
+
+ target_lsb = 0;
+ target_usb = old_lsb;
+ } else {
+ /* case 2 and 4 */
+ source_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale);
+ target_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_hb_scale);
+
+ startBand = new_lsb;
+ stopBand = old_lsb;
+
+ target_lsb = old_lsb;
+ target_usb = old_usb;
+ }
+
+ maxVal =
+ maxSubbandSample(OverlapBufferReal, (useLP) ? NULL : OverlapBufferImag,
+ startBand, stopBand, 0, startSlot);
+
+ reserve = ((LONG)maxVal != 0 ? CntLeadingZeros(maxVal) - 1 : 0);
+ reserve = fixMin(
+ reserve,
+ DFRACT_BITS - 1 -
+ EXP2SCALE(
+ source_exp)); /* what is this line for, why do we need it? */
+
+ /* process only if x-over-area is not dominant after rescale;
+ otherwise I'm not sure if all buffers are scaled correctly;
+ */
+ if (target_exp - (source_exp - reserve) >= 0) {
+ rescaleSubbandSamples(OverlapBufferReal,
+ (useLP) ? NULL : OverlapBufferImag, startBand,
+ stopBand, 0, startSlot, reserve);
+ source_exp -= reserve;
+ }
+
+ delta_exp = target_exp - source_exp;
+
+ if (delta_exp < 0) { /* x-over-area is dominant */
+ startBand = target_lsb;
+ stopBand = target_usb;
+ delta_exp = -delta_exp;
+
+ if (new_lsb > old_lsb) {
+ /* The lowband has to be rescaled */
+ hSbrDec->qmfDomainInCh->scaling.ov_lb_scale = EXP2SCALE(source_exp);
+ } else {
+ /* The highband has to be rescaled */
+ hSbrDec->qmfDomainInCh->scaling.ov_hb_scale = EXP2SCALE(source_exp);
+ }
+ }
+
+ FDK_ASSERT(startBand <= stopBand);
+
+ if (!useLP) {
+ for (l = 0; l < startSlot; l++) {
+ scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand,
+ -delta_exp);
+ scaleValues(OverlapBufferImag[l] + startBand, stopBand - startBand,
+ -delta_exp);
+ }
+ } else
+ for (l = 0; l < startSlot; l++) {
+ scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand,
+ -delta_exp);
+ }
+ } /* startSlot != 0 */
+
+ /*
+ Initialize transposer and limiter
+ */
+ sbrError = resetLppTransposer(
+ &hSbrDec->LppTrans, hHeaderData->freqBandData.lowSubband,
+ hHeaderData->freqBandData.v_k_master, hHeaderData->freqBandData.numMaster,
+ hHeaderData->freqBandData.freqBandTableNoise,
+ hHeaderData->freqBandData.nNfb, hHeaderData->freqBandData.highSubband,
+ hHeaderData->sbrProcSmplRate);
+ if (sbrError != SBRDEC_OK) return sbrError;
+
+ hSbrDec->savedStates = 0;
+
+ if ((flags & SBRDEC_USAC_HARMONICSBR) && applySbrProc) {
+ sbrError = QmfTransposerReInit(hSbrDec->hHBE,
+ hHeaderData->freqBandData.freqBandTable,
+ hHeaderData->freqBandData.nSfb);
+ if (sbrError != SBRDEC_OK) return sbrError;
+
+ /* copy saved states from previous frame to legacy SBR lpc filterstate
+ * buffer */
+ for (i = 0; i < LPC_ORDER + hSbrDec->LppTrans.pSettings->overlap; i++) {
+ FDKmemcpy(
+ hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i],
+ hSbrDec->codecQMFBufferReal[hSbrDec->hHBE->noCols - LPC_ORDER -
+ hSbrDec->LppTrans.pSettings->overlap + i],
+ hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
+ FDKmemcpy(
+ hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i],
+ hSbrDec->codecQMFBufferImag[hSbrDec->hHBE->noCols - LPC_ORDER -
+ hSbrDec->LppTrans.pSettings->overlap + i],
+ hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL));
+ }
+ hSbrDec->savedStates = 1;
+
+ {
+ /* map QMF buffer to pointer array (Overlap + Frame)*/
+ for (i = 0; i < hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER; i++) {
+ pLowBandReal[i] = hSbrDec->LppTrans.lpcFilterStatesRealHBE[i];
+ pLowBandImag[i] = hSbrDec->LppTrans.lpcFilterStatesImagHBE[i];
+ }
+
+ /* map QMF buffer to pointer array (Overlap + Frame)*/
+ for (i = 0; i < hSbrDec->hHBE->noCols; i++) {
+ pLowBandReal[i + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
+ hSbrDec->codecQMFBufferReal[i];
+ pLowBandImag[i + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
+ hSbrDec->codecQMFBufferImag[i];
+ }
+
+ if (flags & SBRDEC_QUAD_RATE) {
+ if (hFrameData->sbrPatchingMode == 0) {
+ int *xOverQmf = GetxOverBandQmfTransposer(hSbrDec->hHBE);
+
+ /* in case of harmonic SBR and no HBE_LP map additional buffer for
+ one more frame to pointer arry */
+ for (i = 0; i < hSbrDec->hHBE->noCols / 2; i++) {
+ pLowBandReal[i + hSbrDec->hHBE->noCols +
+ hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
+ hSbrDec->hQmfHBESlotsReal[i];
+ pLowBandImag[i + hSbrDec->hHBE->noCols +
+ hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
+ hSbrDec->hQmfHBESlotsImag[i];
+ }
+
+ QmfTransposerApply(
+ hSbrDec->hHBE,
+ pLowBandReal + hSbrDec->LppTrans.pSettings->overlap +
+ hSbrDec->hHBE->noCols / 2 + LPC_ORDER,
+ pLowBandImag + hSbrDec->LppTrans.pSettings->overlap +
+ hSbrDec->hHBE->noCols / 2 + LPC_ORDER,
+ hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag,
+ hSbrDec->LppTrans.lpcFilterStatesRealHBE,
+ hSbrDec->LppTrans.lpcFilterStatesImagHBE,
+ hPrevFrameData->prevSbrPitchInBins, hSbrDec->scale_lb,
+ hSbrDec->scale_hbe, &hSbrDec->qmfDomainInCh->scaling.hb_scale,
+ hHeaderData->timeStep, hFrameData->frameInfo.borders[0],
+ hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF);
+
+ copyHarmonicSpectrum(
+ xOverQmf, pLowBandReal, pLowBandImag, hSbrDec->hHBE->noCols,
+ hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF);
+ }
+ } else {
+ /* in case of harmonic SBR and no HBE_LP map additional buffer for
+ one more frame to pointer arry */
+ for (i = 0; i < hSbrDec->hHBE->noCols; i++) {
+ pLowBandReal[i + hSbrDec->hHBE->noCols +
+ hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
+ hSbrDec->hQmfHBESlotsReal[i];
+ pLowBandImag[i + hSbrDec->hHBE->noCols +
+ hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] =
+ hSbrDec->hQmfHBESlotsImag[i];
+ }
+
+ if (hFrameData->sbrPatchingMode == 0) {
+ QmfTransposerApply(
+ hSbrDec->hHBE,
+ pLowBandReal + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER,
+ pLowBandImag + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER,
+ hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag,
+ hSbrDec->LppTrans.lpcFilterStatesRealHBE,
+ hSbrDec->LppTrans.lpcFilterStatesImagHBE,
+ 0 /* not required for keeping states updated in this frame*/,
+ hSbrDec->scale_lb, hSbrDec->scale_lb,
+ &hSbrDec->qmfDomainInCh->scaling.hb_scale, hHeaderData->timeStep,
+ hFrameData->frameInfo.borders[0],
+ hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_NOOUT);
+ }
+
+ QmfTransposerApply(
+ hSbrDec->hHBE,
+ pLowBandReal + hSbrDec->LppTrans.pSettings->overlap +
+ hSbrDec->hHBE->noCols + LPC_ORDER,
+ pLowBandImag + hSbrDec->LppTrans.pSettings->overlap +
+ hSbrDec->hHBE->noCols + LPC_ORDER,
+ hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag,
+ hSbrDec->LppTrans.lpcFilterStatesRealHBE,
+ hSbrDec->LppTrans.lpcFilterStatesImagHBE,
+ hPrevFrameData->prevSbrPitchInBins, hSbrDec->scale_lb,
+ hSbrDec->scale_hbe, &hSbrDec->qmfDomainInCh->scaling.hb_scale,
+ hHeaderData->timeStep, hFrameData->frameInfo.borders[0],
+ hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF);
+ }
+
+ if (hFrameData->sbrPatchingMode == 0) {
+ for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) {
+ /*
+ Store the unmodified qmf Slots values for upper part of spectrum
+ (required for LPC filtering) required if next frame is a HBE frame
+ */
+ FDKmemcpy(hSbrDec->qmfDomainInCh->hQmfSlotsReal[i],
+ hSbrDec->LppTrans.lpcFilterStatesRealHBE[i + LPC_ORDER],
+ (64) * sizeof(FIXP_DBL));
+ FDKmemcpy(hSbrDec->qmfDomainInCh->hQmfSlotsImag[i],
+ hSbrDec->LppTrans.lpcFilterStatesImagHBE[i + LPC_ORDER],
+ (64) * sizeof(FIXP_DBL));
+ }
+
+ for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) {
+ /*
+ Store the unmodified qmf Slots values for upper part of spectrum
+ (required for LPC filtering) required if next frame is a HBE frame
+ */
+ FDKmemcpy(
+ hSbrDec->qmfDomainInCh->hQmfSlotsReal[i],
+ hSbrDec->codecQMFBufferReal[hSbrDec->hHBE->noCols -
+ hSbrDec->LppTrans.pSettings->overlap +
+ i],
+ new_lsb * sizeof(FIXP_DBL));
+ FDKmemcpy(
+ hSbrDec->qmfDomainInCh->hQmfSlotsImag[i],
+ hSbrDec->codecQMFBufferImag[hSbrDec->hHBE->noCols -
+ hSbrDec->LppTrans.pSettings->overlap +
+ i],
+ new_lsb * sizeof(FIXP_DBL));
+ }
+ }
+ }
+ }
+
+ {
+ int adapt_lb = 0, diff = 0,
+ new_scale = hSbrDec->qmfDomainInCh->scaling.ov_lb_scale;
+
+ if ((hSbrDec->qmfDomainInCh->scaling.ov_lb_scale !=
+ hSbrDec->qmfDomainInCh->scaling.lb_scale) &&
+ startSlot != 0) {
+ /* we need to adapt spectrum to have equal scale factor, always larger
+ * than zero */
+ diff = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale) -
+ SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.lb_scale);
+
+ if (diff > 0) {
+ adapt_lb = 1;
+ diff = -diff;
+ new_scale = hSbrDec->qmfDomainInCh->scaling.ov_lb_scale;
+ }
+
+ stopBand = new_lsb;
+ }
+
+ if (hFrameData->sbrPatchingMode == 1) {
+ /* scale states from LegSBR filterstates buffer */
+ for (i = 0; i < hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER; i++) {
+ scaleValues(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], new_lsb,
+ diff);
+ if (!useLP) {
+ scaleValues(hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i], new_lsb,
+ diff);
+ }
+ }
+
+ if (flags & SBRDEC_SYNTAX_USAC) {
+ /* get missing states between old and new x_over from LegSBR
+ * filterstates buffer */
+ /* in case of legacy SBR we leave these values zeroed out */
+ for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) {
+ FDKmemcpy(&OverlapBufferReal[i][old_lsb],
+ &hSbrDec->LppTrans
+ .lpcFilterStatesRealLegSBR[LPC_ORDER + i][old_lsb],
+ fMax(new_lsb - old_lsb, 0) * sizeof(FIXP_DBL));
+ if (!useLP) {
+ FDKmemcpy(&OverlapBufferImag[i][old_lsb],
+ &hSbrDec->LppTrans
+ .lpcFilterStatesImagLegSBR[LPC_ORDER + i][old_lsb],
+ fMax(new_lsb - old_lsb, 0) * sizeof(FIXP_DBL));
+ }
+ }
+ }
+
+ if (new_lsb > old_lsb) {
+ stopBand = old_lsb;
+ }
+ }
+ if ((adapt_lb == 1) && (stopBand > startBand)) {
+ for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) {
+ scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand,
+ diff);
+ if (!useLP) {
+ scaleValues(OverlapBufferImag[l] + startBand, stopBand - startBand,
+ diff);
+ }
+ }
+ }
+ hSbrDec->qmfDomainInCh->scaling.ov_lb_scale = new_scale;
+ }
+
+ sbrError = ResetLimiterBands(hHeaderData->freqBandData.limiterBandTable,
+ &hHeaderData->freqBandData.noLimiterBands,
+ hHeaderData->freqBandData.freqBandTable[0],
+ hHeaderData->freqBandData.nSfb[0],
+ hSbrDec->LppTrans.pSettings->patchParam,
+ hSbrDec->LppTrans.pSettings->noOfPatches,
+ hHeaderData->bs_data.limiterBands,
+ hFrameData->sbrPatchingMode,
+ GetxOverBandQmfTransposer(hSbrDec->hHBE),
+ Get41SbrQmfTransposer(hSbrDec->hHBE));
+
+ hSbrDec->SbrCalculateEnvelope.sbrPatchingMode = hFrameData->sbrPatchingMode;
+
+ return sbrError;
+}
diff --git a/fdk-aac/libSBRdec/src/sbr_dec.h b/fdk-aac/libSBRdec/src/sbr_dec.h
new file mode 100644
index 0000000..156da03
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbr_dec.h
@@ -0,0 +1,204 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Sbr decoder
+*/
+#ifndef SBR_DEC_H
+#define SBR_DEC_H
+
+#include "sbrdecoder.h"
+
+#include "lpp_tran.h"
+#include "qmf.h"
+#include "env_calc.h"
+#include "FDK_audio.h"
+
+#include "sbrdec_drc.h"
+
+#include "pvc_dec.h"
+
+#include "hbe.h"
+
+enum SBRDEC_QMF_SKIP {
+ qmfSkipNothing = 0,
+ qmfSkipAnalysis = 1 << 0,
+ qmfSkipSynthesis = 1 << 1
+};
+
+typedef struct {
+ SBR_CALCULATE_ENVELOPE SbrCalculateEnvelope;
+ SBR_LPP_TRANS LppTrans;
+ PVC_STATIC_DATA PvcStaticData;
+
+ /* do scale handling in sbr an not in qmf */
+ SHORT scale_ov;
+ SHORT scale_lb;
+ SHORT scale_hbe;
+
+ SHORT prev_frame_lSbr;
+ SHORT prev_frame_hbeSbr;
+
+ int codecFrameSize;
+
+ HANDLE_HBE_TRANSPOSER hHBE;
+
+ HANDLE_FDK_QMF_DOMAIN_IN qmfDomainInCh;
+ HANDLE_FDK_QMF_DOMAIN_OUT qmfDomainOutCh;
+
+ SBRDEC_DRC_CHANNEL sbrDrcChannel;
+
+#if (SBRDEC_MAX_HB_FADE_FRAMES > 0)
+ INT highBandFadeCnt; /* counter for fading in high-band signal smoothly */
+
+#endif
+ FIXP_DBL **tmp_memory; /* shared memory between hbeLightTimeDelayBuffer and
+ hQmfHBESlotsReal */
+
+ FIXP_DBL **hQmfHBESlotsReal;
+ FIXP_DBL **hQmfHBESlotsImag;
+
+ FIXP_DBL **codecQMFBufferReal;
+ FIXP_DBL **codecQMFBufferImag;
+ UCHAR savedStates;
+ int applySbrProc_old;
+} SBR_DEC;
+
+typedef SBR_DEC *HANDLE_SBR_DEC;
+
+typedef struct {
+ SBR_FRAME_DATA frameData[(1) + 1];
+ SBR_PREV_FRAME_DATA prevFrameData;
+ SBR_DEC SbrDec;
+} SBR_CHANNEL;
+
+typedef SBR_CHANNEL *HANDLE_SBR_CHANNEL;
+
+void sbr_dec(
+ HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
+ INT_PCM *timeIn, /*!< pointer to input time signal */
+ INT_PCM *timeOut, /*!< pointer to output time signal */
+ HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */
+ INT_PCM *timeOutRight, /*!< pointer to output time signal */
+ INT strideOut, /*!< Time data traversal strideOut */
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
+ HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
+ HANDLE_SBR_PREV_FRAME_DATA
+ hPrevFrameData, /*!< Some control data of last frame */
+ const int applyProcessing, /*!< Flag for SBR operation */
+ HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize);
+
+SBR_ERROR
+createSbrDec(SBR_CHANNEL *hSbrChannel, HANDLE_SBR_HEADER_DATA hHeaderData,
+ TRANSPOSER_SETTINGS *pSettings, const int downsampleFac,
+ const UINT qmfFlags, const UINT flags, const int overlap, int chan,
+ int codecFrameSize);
+
+int deleteSbrDec(SBR_CHANNEL *hSbrChannel);
+
+SBR_ERROR
+resetSbrDec(HANDLE_SBR_DEC hSbrDec, HANDLE_SBR_HEADER_DATA hHeaderData,
+ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, const int downsampleFac,
+ const UINT flags, HANDLE_SBR_FRAME_DATA hFrameData);
+
+#endif
diff --git a/fdk-aac/libSBRdec/src/sbr_ram.cpp b/fdk-aac/libSBRdec/src/sbr_ram.cpp
new file mode 100644
index 0000000..8b35fd2
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbr_ram.cpp
@@ -0,0 +1,191 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Memory layout
+
+ This module declares all static and dynamic memory spaces
+*/
+
+#include "sbr_ram.h"
+
+#define WORKBUFFER1_TAG 2
+#define WORKBUFFER2_TAG 3
+
+/*!
+ \name StaticSbrData
+
+ Static memory areas, must not be overwritten in other sections of the decoder
+*/
+/* @{ */
+
+/*! SBR Decoder main structure */
+C_ALLOC_MEM(Ram_SbrDecoder, struct SBR_DECODER_INSTANCE, 1)
+/*! SBR Decoder element data <br>
+ Dimension: (8) */
+C_ALLOC_MEM2(Ram_SbrDecElement, SBR_DECODER_ELEMENT, 1, (8))
+/*! SBR Decoder individual channel data <br>
+ Dimension: (8) */
+C_ALLOC_MEM2(Ram_SbrDecChannel, SBR_CHANNEL, 1, (8) + 1)
+
+/*! Static Data of PS */
+
+C_ALLOC_MEM(Ram_ps_dec, struct PS_DEC, 1)
+
+/* @} */
+
+/*!
+ \name DynamicSbrData
+
+ Dynamic memory areas, might be reused in other algorithm sections,
+ e.g. the core decoder
+ <br>
+ Depending on the mode set by DONT_USE_CORE_WORKBUFFER, workbuffers are
+ defined additionally to the CoreWorkbuffer.
+ <br>
+ The size of WorkBuffers is ((1024) / (32) * (4) / 2)*(64) = 2048.
+ <br>
+ WorkBuffer2 is a pointer to the CoreWorkBuffer wich is reused here in the SBR
+ part. In case of DONT_USE_CORE_WORKBUFFER, the CoreWorkbuffer is not used and
+ the according Workbuffer2 is defined locally in this file. <br> WorkBuffer1 is
+ reused in the AAC core (-> aacdecoder.cpp, aac_ram.cpp) <br>
+
+ Use of WorkBuffers:
+ <pre>
+
+ -------------------------------------------------------------
+ AAC core:
+
+ CoreWorkbuffer: spectral coefficients
+ WorkBuffer1: CAacDecoderChannelInfo, CAacDecoderDynamicData
+
+ -------------------------------------------------------------
+ SBR part:
+ ----------------------------------------------
+ Low Power Mode (useLP=1 or LOW_POWER_SBR_ONLY), see assignLcTimeSlots()
+
+ SLOT_BASED_PROTOTYPE_SYN_FILTER
+
+ WorkBuffer1 WorkBuffer2(=CoreWorkbuffer)
+ ________________ ________________
+ | RealLeft | | RealRight |
+ |________________| |________________|
+
+ ----------------------------------------------
+ High Quality Mode (!LOW_POWER_SBR_ONLY and useLP=0), see
+ assignHqTimeSlots()
+
+ SLOTBASED_PS
+
+ WorkBuffer1 WorkBuffer2(=CoreWorkbuffer)
+ ________________ ________________
+ | Real/Imag | interleaved | Real/Imag |
+ interleaved
+ |________________| first half actual ch |________________| second
+ half actual ch
+
+ -------------------------------------------------------------
+
+ </pre>
+
+*/
diff --git a/fdk-aac/libSBRdec/src/sbr_ram.h b/fdk-aac/libSBRdec/src/sbr_ram.h
new file mode 100644
index 0000000..e00f8b5
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbr_ram.h
@@ -0,0 +1,186 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+\file
+\brief Memory layout
+*/
+#ifndef SBR_RAM_H
+#define SBR_RAM_H
+
+#include "sbrdecoder.h"
+
+#include "env_extr.h"
+#include "sbr_dec.h"
+
+#define SBRDEC_MAX_CH_PER_ELEMENT (2)
+
+#define FRAME_OK (0)
+#define FRAME_ERROR (1)
+#define FRAME_ERROR_ALLSLOTS (2)
+
+typedef struct {
+ SBR_CHANNEL *pSbrChannel[SBRDEC_MAX_CH_PER_ELEMENT];
+ TRANSPOSER_SETTINGS
+ transposerSettings; /* Common transport settings for each individual
+ channel of an element */
+ HANDLE_FDK_BITSTREAM hBs;
+
+ MP4_ELEMENT_ID
+ elementID; /* Element ID set during initialization. Can be used for
+ concealment */
+ int nChannels; /* Number of elements output channels (=2 in case of PS) */
+
+ UCHAR frameErrorFlag[(1) + 1]; /* Frame error status (for every slot in the
+ delay line). Will be copied into header at
+ the very beginning of decodeElement()
+ routine. */
+
+ UCHAR useFrameSlot; /* Index which defines which slot will be decoded/filled
+ next (used with additional delay) */
+ UCHAR useHeaderSlot[(1) + 1]; /* Index array that provides the link between
+ header and frame data (important when
+ processing with additional delay). */
+} SBR_DECODER_ELEMENT;
+
+struct SBR_DECODER_INSTANCE {
+ SBR_DECODER_ELEMENT *pSbrElement[(8)];
+ SBR_HEADER_DATA sbrHeader[(
+ 8)][(1) + 1]; /* Sbr header for each individual channel of an element */
+
+ HANDLE_FDK_QMF_DOMAIN pQmfDomain;
+
+ HANDLE_PS_DEC hParametricStereoDec;
+
+ /* Global parameters */
+ AUDIO_OBJECT_TYPE coreCodec; /* AOT of core codec */
+ int numSbrElements;
+ int numSbrChannels;
+ INT sampleRateIn; /* SBR decoder input sampling rate; might be different than
+ the transposer input sampling rate. */
+ INT sampleRateOut; /* Sampling rate of the SBR decoder output audio samples.
+ */
+ USHORT codecFrameSize;
+ UCHAR synDownsampleFac;
+ INT downscaleFactor;
+ UCHAR numDelayFrames; /* The current number of additional delay frames used
+ for processing. */
+ UCHAR harmonicSBR;
+ UCHAR
+ numFlushedFrames; /* The variable counts the number of frames which are
+ flushed consecutively. */
+
+ UINT flags;
+};
+
+H_ALLOC_MEM(Ram_SbrDecElement, SBR_DECODER_ELEMENT)
+H_ALLOC_MEM(Ram_SbrDecChannel, SBR_CHANNEL)
+H_ALLOC_MEM(Ram_SbrDecoder, struct SBR_DECODER_INSTANCE)
+
+H_ALLOC_MEM(Ram_sbr_QmfStatesSynthesis, FIXP_QSS)
+H_ALLOC_MEM(Ram_sbr_OverlapBuffer, FIXP_DBL)
+
+H_ALLOC_MEM(Ram_sbr_HBEOverlapBuffer, FIXP_DBL)
+
+H_ALLOC_MEM(Ram_ps_dec, PS_DEC)
+
+#endif /* SBR_RAM_H */
diff --git a/fdk-aac/libSBRdec/src/sbr_rom.cpp b/fdk-aac/libSBRdec/src/sbr_rom.cpp
new file mode 100644
index 0000000..8a6688a
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbr_rom.cpp
@@ -0,0 +1,1705 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Definition of constant tables
+
+ This module contains most of the constant data that can be stored in ROM.
+*/
+
+#include "sbr_rom.h"
+
+/*!
+ \name StartStopBands
+ \brief Start and stop subbands of the highband.
+
+ k_o = startMin + offset[bs_start_freq];
+ startMin = {3000,4000,5000} * (128/FS_sbr) / FS_sbr < 32Khz, 32Khz <= FS_sbr <
+ 64KHz, 64KHz <= FS_sbr The stop subband can also be calculated to save memory
+ by defining #CALC_STOP_BAND.
+*/
+//@{
+/* tables were created with ../addon/octave/sbr_start_freq_table.m */
+const UCHAR FDK_sbrDecoder_sbr_start_freq_16[][16] = {
+ {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
+ {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}};
+const UCHAR FDK_sbrDecoder_sbr_start_freq_22[][16] = {
+ {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 28, 30},
+ {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22}};
+const UCHAR FDK_sbrDecoder_sbr_start_freq_24[][16] = {
+ {11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 27, 29, 32},
+ {3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 19, 21, 24}};
+const UCHAR FDK_sbrDecoder_sbr_start_freq_32[][16] = {
+ {10, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 27, 29, 32},
+ {2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 19, 21, 24}};
+const UCHAR FDK_sbrDecoder_sbr_start_freq_40[][16] = {
+ {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 26, 28, 30, 32},
+ {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 19, 21, 23, 25}};
+const UCHAR FDK_sbrDecoder_sbr_start_freq_44[][16] = {
+ {8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 25, 28, 32},
+ {2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19, 22, 26}};
+const UCHAR FDK_sbrDecoder_sbr_start_freq_48[][16] = {
+ {7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 27, 31},
+ {1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 21, 25}};
+const UCHAR FDK_sbrDecoder_sbr_start_freq_64[][16] = {
+ {6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, 23, 26, 30},
+ {1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 21, 25}};
+const UCHAR FDK_sbrDecoder_sbr_start_freq_88[][16] = {
+ {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 23, 27, 31},
+ {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 20, 24, 28}};
+const UCHAR FDK_sbrDecoder_sbr_start_freq_192[16] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 19, 23, 27};
+const UCHAR FDK_sbrDecoder_sbr_start_freq_176[16] = {
+ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 20, 24, 28};
+const UCHAR FDK_sbrDecoder_sbr_start_freq_128[16] = {
+ 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 21, 25};
+
+//@}
+
+/*!
+ \name Whitening
+ \brief Coefficients for spectral whitening in the transposer
+*/
+//@{
+/*! Assignment of whitening tuning depending on the crossover frequency */
+const USHORT FDK_sbrDecoder_sbr_whFactorsIndex[NUM_WHFACTOR_TABLE_ENTRIES] = {
+ 0, 5000, 6000, 6500, 7000, 7500, 8000, 9000, 10000};
+
+/*!
+ \brief Whithening levels tuning table
+
+ With the current tuning, there are some redundant entries:
+
+ \li NUM_WHFACTOR_TABLE_ENTRIES can be reduced by 3,
+ \li the first coloumn can be eliminated.
+
+*/
+const FIXP_DBL
+ FDK_sbrDecoder_sbr_whFactorsTable[NUM_WHFACTOR_TABLE_ENTRIES][6] = {
+ /* OFF_LEVEL, TRANSITION_LEVEL, LOW_LEVEL, MID_LEVEL, HIGH_LEVEL */
+ {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f),
+ FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* < 5000 */
+ {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f),
+ FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 5000 < 6000 */
+ {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f),
+ FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 6000 < 6500 */
+ {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f),
+ FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 6500 < 7000 */
+ {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f),
+ FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 7000 < 7500 */
+ {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f),
+ FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 7500 < 8000 */
+ {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f),
+ FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 8000 < 9000 */
+ {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f),
+ FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 9000 < 10000 */
+ {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f),
+ FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* > 10000 */
+};
+
+//@}
+
+/*!
+ \name EnvAdj
+ \brief Constants and tables used for envelope adjustment
+*/
+//@{
+
+/*! Mantissas of gain limits */
+const FIXP_SGL FDK_sbrDecoder_sbr_limGains_m[4] = {
+ FL2FXCONST_SGL(0.5011932025f), /*!< -3 dB. Gain limit when limiterGains in
+ frameData is 0 */
+ FL2FXCONST_SGL(
+ 0.5f), /*!< 0 dB. Gain limit when limiterGains in frameData is 1 */
+ FL2FXCONST_SGL(0.9976346258f), /*!< +3 dB. Gain limit when limiterGains in
+ frameData is 2 */
+ FL2FXCONST_SGL(0.6776263578f) /*!< Inf. Gain limit when limiterGains in
+ frameData is 3 */
+};
+
+/*! Exponents of gain limits */
+const UCHAR FDK_sbrDecoder_sbr_limGains_e[4] = {0, 1, 1, 67};
+
+/*! Constants for calculating the number of limiter bands */
+const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4] = {
+ FL2FXCONST_SGL(1.0f / 4.0f), FL2FXCONST_SGL(1.2f / 4.0f),
+ FL2FXCONST_SGL(2.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
+ */
+const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4] = {
+ FL2FXCONST_SGL(0.66666666666666f), FL2FXCONST_SGL(0.36516383427084f),
+ FL2FXCONST_SGL(0.14699433520835f), FL2FXCONST_SGL(0.03183050093751f)};
+
+/*! Real and imaginary part of random noise which will be modulated
+ to the desired level. An accuracy of 13 bits is sufficient for these
+ random numbers.
+*/
+const FIXP_SGL FDK_sbrDecoder_sbr_randomPhase[SBR_NF_NO_RANDOM_VAL][2] = {
+ {FL2FXCONST_SGL(-0.99948153278296f / 8.0),
+ FL2FXCONST_SGL(-0.59483417516607f / 8.0)},
+ {FL2FXCONST_SGL(0.97113454393991f / 8.0),
+ FL2FXCONST_SGL(-0.67528515225647f / 8.0)},
+ {FL2FXCONST_SGL(0.14130051758487f / 8.0),
+ FL2FXCONST_SGL(-0.95090983575689f / 8.0)},
+ {FL2FXCONST_SGL(-0.47005496701697f / 8.0),
+ FL2FXCONST_SGL(-0.37340549728647f / 8.0)},
+ {FL2FXCONST_SGL(0.80705063769351f / 8.0),
+ FL2FXCONST_SGL(0.29653668284408f / 8.0)},
+ {FL2FXCONST_SGL(-0.38981478896926f / 8.0),
+ FL2FXCONST_SGL(0.89572605717087f / 8.0)},
+ {FL2FXCONST_SGL(-0.01053049862020f / 8.0),
+ FL2FXCONST_SGL(-0.66959058036166f / 8.0)},
+ {FL2FXCONST_SGL(-0.91266367957293f / 8.0),
+ FL2FXCONST_SGL(-0.11522938140034f / 8.0)},
+ {FL2FXCONST_SGL(0.54840422910309f / 8.0),
+ FL2FXCONST_SGL(0.75221367176302f / 8.0)},
+ {FL2FXCONST_SGL(0.40009252867955f / 8.0),
+ FL2FXCONST_SGL(-0.98929400334421f / 8.0)},
+ {FL2FXCONST_SGL(-0.99867974711855f / 8.0),
+ FL2FXCONST_SGL(-0.88147068645358f / 8.0)},
+ {FL2FXCONST_SGL(-0.95531076805040f / 8.0),
+ FL2FXCONST_SGL(0.90908757154593f / 8.0)},
+ {FL2FXCONST_SGL(-0.45725933317144f / 8.0),
+ FL2FXCONST_SGL(-0.56716323646760f / 8.0)},
+ {FL2FXCONST_SGL(-0.72929675029275f / 8.0),
+ FL2FXCONST_SGL(-0.98008272727324f / 8.0)},
+ {FL2FXCONST_SGL(0.75622801399036f / 8.0),
+ FL2FXCONST_SGL(0.20950329995549f / 8.0)},
+ {FL2FXCONST_SGL(0.07069442601050f / 8.0),
+ FL2FXCONST_SGL(-0.78247898470706f / 8.0)},
+ {FL2FXCONST_SGL(0.74496252926055f / 8.0),
+ FL2FXCONST_SGL(-0.91169004445807f / 8.0)},
+ {FL2FXCONST_SGL(-0.96440182703856f / 8.0),
+ FL2FXCONST_SGL(-0.94739918296622f / 8.0)},
+ {FL2FXCONST_SGL(0.30424629369539f / 8.0),
+ FL2FXCONST_SGL(-0.49438267012479f / 8.0)},
+ {FL2FXCONST_SGL(0.66565033746925f / 8.0),
+ FL2FXCONST_SGL(0.64652935542491f / 8.0)},
+ {FL2FXCONST_SGL(0.91697008020594f / 8.0),
+ FL2FXCONST_SGL(0.17514097332009f / 8.0)},
+ {FL2FXCONST_SGL(-0.70774918760427f / 8.0),
+ FL2FXCONST_SGL(0.52548653416543f / 8.0)},
+ {FL2FXCONST_SGL(-0.70051415345560f / 8.0),
+ FL2FXCONST_SGL(-0.45340028808763f / 8.0)},
+ {FL2FXCONST_SGL(-0.99496513054797f / 8.0),
+ FL2FXCONST_SGL(-0.90071908066973f / 8.0)},
+ {FL2FXCONST_SGL(0.98164490790123f / 8.0),
+ FL2FXCONST_SGL(-0.77463155528697f / 8.0)},
+ {FL2FXCONST_SGL(-0.54671580548181f / 8.0),
+ FL2FXCONST_SGL(-0.02570928536004f / 8.0)},
+ {FL2FXCONST_SGL(-0.01689629065389f / 8.0),
+ FL2FXCONST_SGL(0.00287506445732f / 8.0)},
+ {FL2FXCONST_SGL(-0.86110349531986f / 8.0),
+ FL2FXCONST_SGL(0.42548583726477f / 8.0)},
+ {FL2FXCONST_SGL(-0.98892980586032f / 8.0),
+ FL2FXCONST_SGL(-0.87881132267556f / 8.0)},
+ {FL2FXCONST_SGL(0.51756627678691f / 8.0),
+ FL2FXCONST_SGL(0.66926784710139f / 8.0)},
+ {FL2FXCONST_SGL(-0.99635026409640f / 8.0),
+ FL2FXCONST_SGL(-0.58107730574765f / 8.0)},
+ {FL2FXCONST_SGL(-0.99969370862163f / 8.0),
+ FL2FXCONST_SGL(0.98369989360250f / 8.0)},
+ {FL2FXCONST_SGL(0.55266258627194f / 8.0),
+ FL2FXCONST_SGL(0.59449057465591f / 8.0)},
+ {FL2FXCONST_SGL(0.34581177741673f / 8.0),
+ FL2FXCONST_SGL(0.94879421061866f / 8.0)},
+ {FL2FXCONST_SGL(0.62664209577999f / 8.0),
+ FL2FXCONST_SGL(-0.74402970906471f / 8.0)},
+ {FL2FXCONST_SGL(-0.77149701404973f / 8.0),
+ FL2FXCONST_SGL(-0.33883658042801f / 8.0)},
+ {FL2FXCONST_SGL(-0.91592244254432f / 8.0),
+ FL2FXCONST_SGL(0.03687901376713f / 8.0)},
+ {FL2FXCONST_SGL(-0.76285492357887f / 8.0),
+ FL2FXCONST_SGL(-0.91371867919124f / 8.0)},
+ {FL2FXCONST_SGL(0.79788337195331f / 8.0),
+ FL2FXCONST_SGL(-0.93180971199849f / 8.0)},
+ {FL2FXCONST_SGL(0.54473080610200f / 8.0),
+ FL2FXCONST_SGL(-0.11919206037186f / 8.0)},
+ {FL2FXCONST_SGL(-0.85639281671058f / 8.0),
+ FL2FXCONST_SGL(0.42429854760451f / 8.0)},
+ {FL2FXCONST_SGL(-0.92882402971423f / 8.0),
+ FL2FXCONST_SGL(0.27871809078609f / 8.0)},
+ {FL2FXCONST_SGL(-0.11708371046774f / 8.0),
+ FL2FXCONST_SGL(-0.99800843444966f / 8.0)},
+ {FL2FXCONST_SGL(0.21356749817493f / 8.0),
+ FL2FXCONST_SGL(-0.90716295627033f / 8.0)},
+ {FL2FXCONST_SGL(-0.76191692573909f / 8.0),
+ FL2FXCONST_SGL(0.99768118356265f / 8.0)},
+ {FL2FXCONST_SGL(0.98111043100884f / 8.0),
+ FL2FXCONST_SGL(-0.95854459734407f / 8.0)},
+ {FL2FXCONST_SGL(-0.85913269895572f / 8.0),
+ FL2FXCONST_SGL(0.95766566168880f / 8.0)},
+ {FL2FXCONST_SGL(-0.93307242253692f / 8.0),
+ FL2FXCONST_SGL(0.49431757696466f / 8.0)},
+ {FL2FXCONST_SGL(0.30485754879632f / 8.0),
+ FL2FXCONST_SGL(-0.70540034357529f / 8.0)},
+ {FL2FXCONST_SGL(0.85289650925190f / 8.0),
+ FL2FXCONST_SGL(0.46766131791044f / 8.0)},
+ {FL2FXCONST_SGL(0.91328082618125f / 8.0),
+ FL2FXCONST_SGL(-0.99839597361769f / 8.0)},
+ {FL2FXCONST_SGL(-0.05890199924154f / 8.0),
+ FL2FXCONST_SGL(0.70741827819497f / 8.0)},
+ {FL2FXCONST_SGL(0.28398686150148f / 8.0),
+ FL2FXCONST_SGL(0.34633555702188f / 8.0)},
+ {FL2FXCONST_SGL(0.95258164539612f / 8.0),
+ FL2FXCONST_SGL(-0.54893416026939f / 8.0)},
+ {FL2FXCONST_SGL(-0.78566324168507f / 8.0),
+ FL2FXCONST_SGL(-0.75568541079691f / 8.0)},
+ {FL2FXCONST_SGL(-0.95789495447877f / 8.0),
+ FL2FXCONST_SGL(-0.20423194696966f / 8.0)},
+ {FL2FXCONST_SGL(0.82411158711197f / 8.0),
+ FL2FXCONST_SGL(0.96654618432562f / 8.0)},
+ {FL2FXCONST_SGL(-0.65185446735885f / 8.0),
+ FL2FXCONST_SGL(-0.88734990773289f / 8.0)},
+ {FL2FXCONST_SGL(-0.93643603134666f / 8.0),
+ FL2FXCONST_SGL(0.99870790442385f / 8.0)},
+ {FL2FXCONST_SGL(0.91427159529618f / 8.0),
+ FL2FXCONST_SGL(-0.98290505544444f / 8.0)},
+ {FL2FXCONST_SGL(-0.70395684036886f / 8.0),
+ FL2FXCONST_SGL(0.58796798221039f / 8.0)},
+ {FL2FXCONST_SGL(0.00563771969365f / 8.0),
+ FL2FXCONST_SGL(0.61768196727244f / 8.0)},
+ {FL2FXCONST_SGL(0.89065051931895f / 8.0),
+ FL2FXCONST_SGL(0.52783352697585f / 8.0)},
+ {FL2FXCONST_SGL(-0.68683707712762f / 8.0),
+ FL2FXCONST_SGL(0.80806944710339f / 8.0)},
+ {FL2FXCONST_SGL(0.72165342518718f / 8.0),
+ FL2FXCONST_SGL(-0.69259857349564f / 8.0)},
+ {FL2FXCONST_SGL(-0.62928247730667f / 8.0),
+ FL2FXCONST_SGL(0.13627037407335f / 8.0)},
+ {FL2FXCONST_SGL(0.29938434065514f / 8.0),
+ FL2FXCONST_SGL(-0.46051329682246f / 8.0)},
+ {FL2FXCONST_SGL(-0.91781958879280f / 8.0),
+ FL2FXCONST_SGL(-0.74012716684186f / 8.0)},
+ {FL2FXCONST_SGL(0.99298717043688f / 8.0),
+ FL2FXCONST_SGL(0.40816610075661f / 8.0)},
+ {FL2FXCONST_SGL(0.82368298622748f / 8.0),
+ FL2FXCONST_SGL(-0.74036047190173f / 8.0)},
+ {FL2FXCONST_SGL(-0.98512833386833f / 8.0),
+ FL2FXCONST_SGL(-0.99972330709594f / 8.0)},
+ {FL2FXCONST_SGL(-0.95915368242257f / 8.0),
+ FL2FXCONST_SGL(-0.99237800466040f / 8.0)},
+ {FL2FXCONST_SGL(-0.21411126572790f / 8.0),
+ FL2FXCONST_SGL(-0.93424819052545f / 8.0)},
+ {FL2FXCONST_SGL(-0.68821476106884f / 8.0),
+ FL2FXCONST_SGL(-0.26892306315457f / 8.0)},
+ {FL2FXCONST_SGL(0.91851997982317f / 8.0),
+ FL2FXCONST_SGL(0.09358228901785f / 8.0)},
+ {FL2FXCONST_SGL(-0.96062769559127f / 8.0),
+ FL2FXCONST_SGL(0.36099095133739f / 8.0)},
+ {FL2FXCONST_SGL(0.51646184922287f / 8.0),
+ FL2FXCONST_SGL(-0.71373332873917f / 8.0)},
+ {FL2FXCONST_SGL(0.61130721139669f / 8.0),
+ FL2FXCONST_SGL(0.46950141175917f / 8.0)},
+ {FL2FXCONST_SGL(0.47336129371299f / 8.0),
+ FL2FXCONST_SGL(-0.27333178296162f / 8.0)},
+ {FL2FXCONST_SGL(0.90998308703519f / 8.0),
+ FL2FXCONST_SGL(0.96715662938132f / 8.0)},
+ {FL2FXCONST_SGL(0.44844799194357f / 8.0),
+ FL2FXCONST_SGL(0.99211574628306f / 8.0)},
+ {FL2FXCONST_SGL(0.66614891079092f / 8.0),
+ FL2FXCONST_SGL(0.96590176169121f / 8.0)},
+ {FL2FXCONST_SGL(0.74922239129237f / 8.0),
+ FL2FXCONST_SGL(-0.89879858826087f / 8.0)},
+ {FL2FXCONST_SGL(-0.99571588506485f / 8.0),
+ FL2FXCONST_SGL(0.52785521494349f / 8.0)},
+ {FL2FXCONST_SGL(0.97401082477563f / 8.0),
+ FL2FXCONST_SGL(-0.16855870075190f / 8.0)},
+ {FL2FXCONST_SGL(0.72683747733879f / 8.0),
+ FL2FXCONST_SGL(-0.48060774432251f / 8.0)},
+ {FL2FXCONST_SGL(0.95432193457128f / 8.0),
+ FL2FXCONST_SGL(0.68849603408441f / 8.0)},
+ {FL2FXCONST_SGL(-0.72962208425191f / 8.0),
+ FL2FXCONST_SGL(-0.76608443420917f / 8.0)},
+ {FL2FXCONST_SGL(-0.85359479233537f / 8.0),
+ FL2FXCONST_SGL(0.88738125901579f / 8.0)},
+ {FL2FXCONST_SGL(-0.81412430338535f / 8.0),
+ FL2FXCONST_SGL(-0.97480768049637f / 8.0)},
+ {FL2FXCONST_SGL(-0.87930772356786f / 8.0),
+ FL2FXCONST_SGL(0.74748307690436f / 8.0)},
+ {FL2FXCONST_SGL(-0.71573331064977f / 8.0),
+ FL2FXCONST_SGL(-0.98570608178923f / 8.0)},
+ {FL2FXCONST_SGL(0.83524300028228f / 8.0),
+ FL2FXCONST_SGL(0.83702537075163f / 8.0)},
+ {FL2FXCONST_SGL(-0.48086065601423f / 8.0),
+ FL2FXCONST_SGL(-0.98848504923531f / 8.0)},
+ {FL2FXCONST_SGL(0.97139128574778f / 8.0),
+ FL2FXCONST_SGL(0.80093621198236f / 8.0)},
+ {FL2FXCONST_SGL(0.51992825347895f / 8.0),
+ FL2FXCONST_SGL(0.80247631400510f / 8.0)},
+ {FL2FXCONST_SGL(-0.00848591195325f / 8.0),
+ FL2FXCONST_SGL(-0.76670128000486f / 8.0)},
+ {FL2FXCONST_SGL(-0.70294374303036f / 8.0),
+ FL2FXCONST_SGL(0.55359910445577f / 8.0)},
+ {FL2FXCONST_SGL(-0.95894428168140f / 8.0),
+ FL2FXCONST_SGL(-0.43265504344783f / 8.0)},
+ {FL2FXCONST_SGL(0.97079252950321f / 8.0),
+ FL2FXCONST_SGL(0.09325857238682f / 8.0)},
+ {FL2FXCONST_SGL(-0.92404293670797f / 8.0),
+ FL2FXCONST_SGL(0.85507704027855f / 8.0)},
+ {FL2FXCONST_SGL(-0.69506469500450f / 8.0),
+ FL2FXCONST_SGL(0.98633412625459f / 8.0)},
+ {FL2FXCONST_SGL(0.26559203620024f / 8.0),
+ FL2FXCONST_SGL(0.73314307966524f / 8.0)},
+ {FL2FXCONST_SGL(0.28038443336943f / 8.0),
+ FL2FXCONST_SGL(0.14537913654427f / 8.0)},
+ {FL2FXCONST_SGL(-0.74138124825523f / 8.0),
+ FL2FXCONST_SGL(0.99310339807762f / 8.0)},
+ {FL2FXCONST_SGL(-0.01752795995444f / 8.0),
+ FL2FXCONST_SGL(-0.82616635284178f / 8.0)},
+ {FL2FXCONST_SGL(-0.55126773094930f / 8.0),
+ FL2FXCONST_SGL(-0.98898543862153f / 8.0)},
+ {FL2FXCONST_SGL(0.97960898850996f / 8.0),
+ FL2FXCONST_SGL(-0.94021446752851f / 8.0)},
+ {FL2FXCONST_SGL(-0.99196309146936f / 8.0),
+ FL2FXCONST_SGL(0.67019017358456f / 8.0)},
+ {FL2FXCONST_SGL(-0.67684928085260f / 8.0),
+ FL2FXCONST_SGL(0.12631491649378f / 8.0)},
+ {FL2FXCONST_SGL(0.09140039465500f / 8.0),
+ FL2FXCONST_SGL(-0.20537731453108f / 8.0)},
+ {FL2FXCONST_SGL(-0.71658965751996f / 8.0),
+ FL2FXCONST_SGL(-0.97788200391224f / 8.0)},
+ {FL2FXCONST_SGL(0.81014640078925f / 8.0),
+ FL2FXCONST_SGL(0.53722648362443f / 8.0)},
+ {FL2FXCONST_SGL(0.40616991671205f / 8.0),
+ FL2FXCONST_SGL(-0.26469008598449f / 8.0)},
+ {FL2FXCONST_SGL(-0.67680188682972f / 8.0),
+ FL2FXCONST_SGL(0.94502052337695f / 8.0)},
+ {FL2FXCONST_SGL(0.86849774348749f / 8.0),
+ FL2FXCONST_SGL(-0.18333598647899f / 8.0)},
+ {FL2FXCONST_SGL(-0.99500381284851f / 8.0),
+ FL2FXCONST_SGL(-0.02634122068550f / 8.0)},
+ {FL2FXCONST_SGL(0.84329189340667f / 8.0),
+ FL2FXCONST_SGL(0.10406957462213f / 8.0)},
+ {FL2FXCONST_SGL(-0.09215968531446f / 8.0),
+ FL2FXCONST_SGL(0.69540012101253f / 8.0)},
+ {FL2FXCONST_SGL(0.99956173327206f / 8.0),
+ FL2FXCONST_SGL(-0.12358542001404f / 8.0)},
+ {FL2FXCONST_SGL(-0.79732779473535f / 8.0),
+ FL2FXCONST_SGL(-0.91582524736159f / 8.0)},
+ {FL2FXCONST_SGL(0.96349973642406f / 8.0),
+ FL2FXCONST_SGL(0.96640458041000f / 8.0)},
+ {FL2FXCONST_SGL(-0.79942778496547f / 8.0),
+ FL2FXCONST_SGL(0.64323902822857f / 8.0)},
+ {FL2FXCONST_SGL(-0.11566039853896f / 8.0),
+ FL2FXCONST_SGL(0.28587846253726f / 8.0)},
+ {FL2FXCONST_SGL(-0.39922954514662f / 8.0),
+ FL2FXCONST_SGL(0.94129601616966f / 8.0)},
+ {FL2FXCONST_SGL(0.99089197565987f / 8.0),
+ FL2FXCONST_SGL(-0.92062625581587f / 8.0)},
+ {FL2FXCONST_SGL(0.28631285179909f / 8.0),
+ FL2FXCONST_SGL(-0.91035047143603f / 8.0)},
+ {FL2FXCONST_SGL(-0.83302725605608f / 8.0),
+ FL2FXCONST_SGL(-0.67330410892084f / 8.0)},
+ {FL2FXCONST_SGL(0.95404443402072f / 8.0),
+ FL2FXCONST_SGL(0.49162765398743f / 8.0)},
+ {FL2FXCONST_SGL(-0.06449863579434f / 8.0),
+ FL2FXCONST_SGL(0.03250560813135f / 8.0)},
+ {FL2FXCONST_SGL(-0.99575054486311f / 8.0),
+ FL2FXCONST_SGL(0.42389784469507f / 8.0)},
+ {FL2FXCONST_SGL(-0.65501142790847f / 8.0),
+ FL2FXCONST_SGL(0.82546114655624f / 8.0)},
+ {FL2FXCONST_SGL(-0.81254441908887f / 8.0),
+ FL2FXCONST_SGL(-0.51627234660629f / 8.0)},
+ {FL2FXCONST_SGL(-0.99646369485481f / 8.0),
+ FL2FXCONST_SGL(0.84490533520752f / 8.0)},
+ {FL2FXCONST_SGL(0.00287840603348f / 8.0),
+ FL2FXCONST_SGL(0.64768261158166f / 8.0)},
+ {FL2FXCONST_SGL(0.70176989408455f / 8.0),
+ FL2FXCONST_SGL(-0.20453028573322f / 8.0)},
+ {FL2FXCONST_SGL(0.96361882270190f / 8.0),
+ FL2FXCONST_SGL(0.40706967140989f / 8.0)},
+ {FL2FXCONST_SGL(-0.68883758192426f / 8.0),
+ FL2FXCONST_SGL(0.91338958840772f / 8.0)},
+ {FL2FXCONST_SGL(-0.34875585502238f / 8.0),
+ FL2FXCONST_SGL(0.71472290693300f / 8.0)},
+ {FL2FXCONST_SGL(0.91980081243087f / 8.0),
+ FL2FXCONST_SGL(0.66507455644919f / 8.0)},
+ {FL2FXCONST_SGL(-0.99009048343881f / 8.0),
+ FL2FXCONST_SGL(0.85868021604848f / 8.0)},
+ {FL2FXCONST_SGL(0.68865791458395f / 8.0),
+ FL2FXCONST_SGL(0.55660316809678f / 8.0)},
+ {FL2FXCONST_SGL(-0.99484402129368f / 8.0),
+ FL2FXCONST_SGL(-0.20052559254934f / 8.0)},
+ {FL2FXCONST_SGL(0.94214511408023f / 8.0),
+ FL2FXCONST_SGL(-0.99696425367461f / 8.0)},
+ {FL2FXCONST_SGL(-0.67414626793544f / 8.0),
+ FL2FXCONST_SGL(0.49548221180078f / 8.0)},
+ {FL2FXCONST_SGL(-0.47339353684664f / 8.0),
+ FL2FXCONST_SGL(-0.85904328834047f / 8.0)},
+ {FL2FXCONST_SGL(0.14323651387360f / 8.0),
+ FL2FXCONST_SGL(-0.94145598222488f / 8.0)},
+ {FL2FXCONST_SGL(-0.29268293575672f / 8.0),
+ FL2FXCONST_SGL(0.05759224927952f / 8.0)},
+ {FL2FXCONST_SGL(0.43793861458754f / 8.0),
+ FL2FXCONST_SGL(-0.78904969892724f / 8.0)},
+ {FL2FXCONST_SGL(-0.36345126374441f / 8.0),
+ FL2FXCONST_SGL(0.64874435357162f / 8.0)},
+ {FL2FXCONST_SGL(-0.08750604656825f / 8.0),
+ FL2FXCONST_SGL(0.97686944362527f / 8.0)},
+ {FL2FXCONST_SGL(-0.96495267812511f / 8.0),
+ FL2FXCONST_SGL(-0.53960305946511f / 8.0)},
+ {FL2FXCONST_SGL(0.55526940659947f / 8.0),
+ FL2FXCONST_SGL(0.78891523734774f / 8.0)},
+ {FL2FXCONST_SGL(0.73538215752630f / 8.0),
+ FL2FXCONST_SGL(0.96452072373404f / 8.0)},
+ {FL2FXCONST_SGL(-0.30889773919437f / 8.0),
+ FL2FXCONST_SGL(-0.80664389776860f / 8.0)},
+ {FL2FXCONST_SGL(0.03574995626194f / 8.0),
+ FL2FXCONST_SGL(-0.97325616900959f / 8.0)},
+ {FL2FXCONST_SGL(0.98720684660488f / 8.0),
+ FL2FXCONST_SGL(0.48409133691962f / 8.0)},
+ {FL2FXCONST_SGL(-0.81689296271203f / 8.0),
+ FL2FXCONST_SGL(-0.90827703628298f / 8.0)},
+ {FL2FXCONST_SGL(0.67866860118215f / 8.0),
+ FL2FXCONST_SGL(0.81284503870856f / 8.0)},
+ {FL2FXCONST_SGL(-0.15808569732583f / 8.0),
+ FL2FXCONST_SGL(0.85279555024382f / 8.0)},
+ {FL2FXCONST_SGL(0.80723395114371f / 8.0),
+ FL2FXCONST_SGL(-0.24717418514605f / 8.0)},
+ {FL2FXCONST_SGL(0.47788757329038f / 8.0),
+ FL2FXCONST_SGL(-0.46333147839295f / 8.0)},
+ {FL2FXCONST_SGL(0.96367554763201f / 8.0),
+ FL2FXCONST_SGL(0.38486749303242f / 8.0)},
+ {FL2FXCONST_SGL(-0.99143875716818f / 8.0),
+ FL2FXCONST_SGL(-0.24945277239809f / 8.0)},
+ {FL2FXCONST_SGL(0.83081876925833f / 8.0),
+ FL2FXCONST_SGL(-0.94780851414763f / 8.0)},
+ {FL2FXCONST_SGL(-0.58753191905341f / 8.0),
+ FL2FXCONST_SGL(0.01290772389163f / 8.0)},
+ {FL2FXCONST_SGL(0.95538108220960f / 8.0),
+ FL2FXCONST_SGL(-0.85557052096538f / 8.0)},
+ {FL2FXCONST_SGL(-0.96490920476211f / 8.0),
+ FL2FXCONST_SGL(-0.64020970923102f / 8.0)},
+ {FL2FXCONST_SGL(-0.97327101028521f / 8.0),
+ FL2FXCONST_SGL(0.12378128133110f / 8.0)},
+ {FL2FXCONST_SGL(0.91400366022124f / 8.0),
+ FL2FXCONST_SGL(0.57972471346930f / 8.0)},
+ {FL2FXCONST_SGL(-0.99925837363824f / 8.0),
+ FL2FXCONST_SGL(0.71084847864067f / 8.0)},
+ {FL2FXCONST_SGL(-0.86875903507313f / 8.0),
+ FL2FXCONST_SGL(-0.20291699203564f / 8.0)},
+ {FL2FXCONST_SGL(-0.26240034795124f / 8.0),
+ FL2FXCONST_SGL(-0.68264554369108f / 8.0)},
+ {FL2FXCONST_SGL(-0.24664412953388f / 8.0),
+ FL2FXCONST_SGL(-0.87642273115183f / 8.0)},
+ {FL2FXCONST_SGL(0.02416275806869f / 8.0),
+ FL2FXCONST_SGL(0.27192914288905f / 8.0)},
+ {FL2FXCONST_SGL(0.82068619590515f / 8.0),
+ FL2FXCONST_SGL(-0.85087787994476f / 8.0)},
+ {FL2FXCONST_SGL(0.88547373760759f / 8.0),
+ FL2FXCONST_SGL(-0.89636802901469f / 8.0)},
+ {FL2FXCONST_SGL(-0.18173078152226f / 8.0),
+ FL2FXCONST_SGL(-0.26152145156800f / 8.0)},
+ {FL2FXCONST_SGL(0.09355476558534f / 8.0),
+ FL2FXCONST_SGL(0.54845123045604f / 8.0)},
+ {FL2FXCONST_SGL(-0.54668414224090f / 8.0),
+ FL2FXCONST_SGL(0.95980774020221f / 8.0)},
+ {FL2FXCONST_SGL(0.37050990604091f / 8.0),
+ FL2FXCONST_SGL(-0.59910140383171f / 8.0)},
+ {FL2FXCONST_SGL(-0.70373594262891f / 8.0),
+ FL2FXCONST_SGL(0.91227665827081f / 8.0)},
+ {FL2FXCONST_SGL(-0.34600785879594f / 8.0),
+ FL2FXCONST_SGL(-0.99441426144200f / 8.0)},
+ {FL2FXCONST_SGL(-0.68774481731008f / 8.0),
+ FL2FXCONST_SGL(-0.30238837956299f / 8.0)},
+ {FL2FXCONST_SGL(-0.26843291251234f / 8.0),
+ FL2FXCONST_SGL(0.83115668004362f / 8.0)},
+ {FL2FXCONST_SGL(0.49072334613242f / 8.0),
+ FL2FXCONST_SGL(-0.45359708737775f / 8.0)},
+ {FL2FXCONST_SGL(0.38975993093975f / 8.0),
+ FL2FXCONST_SGL(0.95515358099121f / 8.0)},
+ {FL2FXCONST_SGL(-0.97757125224150f / 8.0),
+ FL2FXCONST_SGL(0.05305894580606f / 8.0)},
+ {FL2FXCONST_SGL(-0.17325552859616f / 8.0),
+ FL2FXCONST_SGL(-0.92770672250494f / 8.0)},
+ {FL2FXCONST_SGL(0.99948035025744f / 8.0),
+ FL2FXCONST_SGL(0.58285545563426f / 8.0)},
+ {FL2FXCONST_SGL(-0.64946246527458f / 8.0),
+ FL2FXCONST_SGL(0.68645507104960f / 8.0)},
+ {FL2FXCONST_SGL(-0.12016920576437f / 8.0),
+ FL2FXCONST_SGL(-0.57147322153312f / 8.0)},
+ {FL2FXCONST_SGL(-0.58947456517751f / 8.0),
+ FL2FXCONST_SGL(-0.34847132454388f / 8.0)},
+ {FL2FXCONST_SGL(-0.41815140454465f / 8.0),
+ FL2FXCONST_SGL(0.16276422358861f / 8.0)},
+ {FL2FXCONST_SGL(0.99885650204884f / 8.0),
+ FL2FXCONST_SGL(0.11136095490444f / 8.0)},
+ {FL2FXCONST_SGL(-0.56649614128386f / 8.0),
+ FL2FXCONST_SGL(-0.90494866361587f / 8.0)},
+ {FL2FXCONST_SGL(0.94138021032330f / 8.0),
+ FL2FXCONST_SGL(0.35281916733018f / 8.0)},
+ {FL2FXCONST_SGL(-0.75725076534641f / 8.0),
+ FL2FXCONST_SGL(0.53650549640587f / 8.0)},
+ {FL2FXCONST_SGL(0.20541973692630f / 8.0),
+ FL2FXCONST_SGL(-0.94435144369918f / 8.0)},
+ {FL2FXCONST_SGL(0.99980371023351f / 8.0),
+ FL2FXCONST_SGL(0.79835913565599f / 8.0)},
+ {FL2FXCONST_SGL(0.29078277605775f / 8.0),
+ FL2FXCONST_SGL(0.35393777921520f / 8.0)},
+ {FL2FXCONST_SGL(-0.62858772103030f / 8.0),
+ FL2FXCONST_SGL(0.38765693387102f / 8.0)},
+ {FL2FXCONST_SGL(0.43440904467688f / 8.0),
+ FL2FXCONST_SGL(-0.98546330463232f / 8.0)},
+ {FL2FXCONST_SGL(-0.98298583762390f / 8.0),
+ FL2FXCONST_SGL(0.21021524625209f / 8.0)},
+ {FL2FXCONST_SGL(0.19513029146934f / 8.0),
+ FL2FXCONST_SGL(-0.94239832251867f / 8.0)},
+ {FL2FXCONST_SGL(-0.95476662400101f / 8.0),
+ FL2FXCONST_SGL(0.98364554179143f / 8.0)},
+ {FL2FXCONST_SGL(0.93379635304810f / 8.0),
+ FL2FXCONST_SGL(-0.70881994583682f / 8.0)},
+ {FL2FXCONST_SGL(-0.85235410573336f / 8.0),
+ FL2FXCONST_SGL(-0.08342347966410f / 8.0)},
+ {FL2FXCONST_SGL(-0.86425093011245f / 8.0),
+ FL2FXCONST_SGL(-0.45795025029466f / 8.0)},
+ {FL2FXCONST_SGL(0.38879779059045f / 8.0),
+ FL2FXCONST_SGL(0.97274429344593f / 8.0)},
+ {FL2FXCONST_SGL(0.92045124735495f / 8.0),
+ FL2FXCONST_SGL(-0.62433652524220f / 8.0)},
+ {FL2FXCONST_SGL(0.89162532251878f / 8.0),
+ FL2FXCONST_SGL(0.54950955570563f / 8.0)},
+ {FL2FXCONST_SGL(-0.36834336949252f / 8.0),
+ FL2FXCONST_SGL(0.96458298020975f / 8.0)},
+ {FL2FXCONST_SGL(0.93891760988045f / 8.0),
+ FL2FXCONST_SGL(-0.89968353740388f / 8.0)},
+ {FL2FXCONST_SGL(0.99267657565094f / 8.0),
+ FL2FXCONST_SGL(-0.03757034316958f / 8.0)},
+ {FL2FXCONST_SGL(-0.94063471614176f / 8.0),
+ FL2FXCONST_SGL(0.41332338538963f / 8.0)},
+ {FL2FXCONST_SGL(0.99740224117019f / 8.0),
+ FL2FXCONST_SGL(-0.16830494996370f / 8.0)},
+ {FL2FXCONST_SGL(-0.35899413170555f / 8.0),
+ FL2FXCONST_SGL(-0.46633226649613f / 8.0)},
+ {FL2FXCONST_SGL(0.05237237274947f / 8.0),
+ FL2FXCONST_SGL(-0.25640361602661f / 8.0)},
+ {FL2FXCONST_SGL(0.36703583957424f / 8.0),
+ FL2FXCONST_SGL(-0.38653265641875f / 8.0)},
+ {FL2FXCONST_SGL(0.91653180367913f / 8.0),
+ FL2FXCONST_SGL(-0.30587628726597f / 8.0)},
+ {FL2FXCONST_SGL(0.69000803499316f / 8.0),
+ FL2FXCONST_SGL(0.90952171386132f / 8.0)},
+ {FL2FXCONST_SGL(-0.38658751133527f / 8.0),
+ FL2FXCONST_SGL(0.99501571208985f / 8.0)},
+ {FL2FXCONST_SGL(-0.29250814029851f / 8.0),
+ FL2FXCONST_SGL(0.37444994344615f / 8.0)},
+ {FL2FXCONST_SGL(-0.60182204677608f / 8.0),
+ FL2FXCONST_SGL(0.86779651036123f / 8.0)},
+ {FL2FXCONST_SGL(-0.97418588163217f / 8.0),
+ FL2FXCONST_SGL(0.96468523666475f / 8.0)},
+ {FL2FXCONST_SGL(0.88461574003963f / 8.0),
+ FL2FXCONST_SGL(0.57508405276414f / 8.0)},
+ {FL2FXCONST_SGL(0.05198933055162f / 8.0),
+ FL2FXCONST_SGL(0.21269661669964f / 8.0)},
+ {FL2FXCONST_SGL(-0.53499621979720f / 8.0),
+ FL2FXCONST_SGL(0.97241553731237f / 8.0)},
+ {FL2FXCONST_SGL(-0.49429560226497f / 8.0),
+ FL2FXCONST_SGL(0.98183865291903f / 8.0)},
+ {FL2FXCONST_SGL(-0.98935142339139f / 8.0),
+ FL2FXCONST_SGL(-0.40249159006933f / 8.0)},
+ {FL2FXCONST_SGL(-0.98081380091130f / 8.0),
+ FL2FXCONST_SGL(-0.72856895534041f / 8.0)},
+ {FL2FXCONST_SGL(-0.27338148835532f / 8.0),
+ FL2FXCONST_SGL(0.99950922447209f / 8.0)},
+ {FL2FXCONST_SGL(0.06310802338302f / 8.0),
+ FL2FXCONST_SGL(-0.54539587529618f / 8.0)},
+ {FL2FXCONST_SGL(-0.20461677199539f / 8.0),
+ FL2FXCONST_SGL(-0.14209977628489f / 8.0)},
+ {FL2FXCONST_SGL(0.66223843141647f / 8.0),
+ FL2FXCONST_SGL(0.72528579940326f / 8.0)},
+ {FL2FXCONST_SGL(-0.84764345483665f / 8.0),
+ FL2FXCONST_SGL(0.02372316801261f / 8.0)},
+ {FL2FXCONST_SGL(-0.89039863483811f / 8.0),
+ FL2FXCONST_SGL(0.88866581484602f / 8.0)},
+ {FL2FXCONST_SGL(0.95903308477986f / 8.0),
+ FL2FXCONST_SGL(0.76744927173873f / 8.0)},
+ {FL2FXCONST_SGL(0.73504123909879f / 8.0),
+ FL2FXCONST_SGL(-0.03747203173192f / 8.0)},
+ {FL2FXCONST_SGL(-0.31744434966056f / 8.0),
+ FL2FXCONST_SGL(-0.36834111883652f / 8.0)},
+ {FL2FXCONST_SGL(-0.34110827591623f / 8.0),
+ FL2FXCONST_SGL(0.40211222807691f / 8.0)},
+ {FL2FXCONST_SGL(0.47803883714199f / 8.0),
+ FL2FXCONST_SGL(-0.39423219786288f / 8.0)},
+ {FL2FXCONST_SGL(0.98299195879514f / 8.0),
+ FL2FXCONST_SGL(0.01989791390047f / 8.0)},
+ {FL2FXCONST_SGL(-0.30963073129751f / 8.0),
+ FL2FXCONST_SGL(-0.18076720599336f / 8.0)},
+ {FL2FXCONST_SGL(0.99992588229018f / 8.0),
+ FL2FXCONST_SGL(-0.26281872094289f / 8.0)},
+ {FL2FXCONST_SGL(-0.93149731080767f / 8.0),
+ FL2FXCONST_SGL(-0.98313162570490f / 8.0)},
+ {FL2FXCONST_SGL(0.99923472302773f / 8.0),
+ FL2FXCONST_SGL(-0.80142993767554f / 8.0)},
+ {FL2FXCONST_SGL(-0.26024169633417f / 8.0),
+ FL2FXCONST_SGL(-0.75999759855752f / 8.0)},
+ {FL2FXCONST_SGL(-0.35712514743563f / 8.0),
+ FL2FXCONST_SGL(0.19298963768574f / 8.0)},
+ {FL2FXCONST_SGL(-0.99899084509530f / 8.0),
+ FL2FXCONST_SGL(0.74645156992493f / 8.0)},
+ {FL2FXCONST_SGL(0.86557171579452f / 8.0),
+ FL2FXCONST_SGL(0.55593866696299f / 8.0)},
+ {FL2FXCONST_SGL(0.33408042438752f / 8.0),
+ FL2FXCONST_SGL(0.86185953874709f / 8.0)},
+ {FL2FXCONST_SGL(0.99010736374716f / 8.0),
+ FL2FXCONST_SGL(0.04602397576623f / 8.0)},
+ {FL2FXCONST_SGL(-0.66694269691195f / 8.0),
+ FL2FXCONST_SGL(-0.91643611810148f / 8.0)},
+ {FL2FXCONST_SGL(0.64016792079480f / 8.0),
+ FL2FXCONST_SGL(0.15649530836856f / 8.0)},
+ {FL2FXCONST_SGL(0.99570534804836f / 8.0),
+ FL2FXCONST_SGL(0.45844586038111f / 8.0)},
+ {FL2FXCONST_SGL(-0.63431466947340f / 8.0),
+ FL2FXCONST_SGL(0.21079116459234f / 8.0)},
+ {FL2FXCONST_SGL(-0.07706847005931f / 8.0),
+ FL2FXCONST_SGL(-0.89581437101329f / 8.0)},
+ {FL2FXCONST_SGL(0.98590090577724f / 8.0),
+ FL2FXCONST_SGL(0.88241721133981f / 8.0)},
+ {FL2FXCONST_SGL(0.80099335254678f / 8.0),
+ FL2FXCONST_SGL(-0.36851896710853f / 8.0)},
+ {FL2FXCONST_SGL(0.78368131392666f / 8.0),
+ FL2FXCONST_SGL(0.45506999802597f / 8.0)},
+ {FL2FXCONST_SGL(0.08707806671691f / 8.0),
+ FL2FXCONST_SGL(0.80938994918745f / 8.0)},
+ {FL2FXCONST_SGL(-0.86811883080712f / 8.0),
+ FL2FXCONST_SGL(0.39347308654705f / 8.0)},
+ {FL2FXCONST_SGL(-0.39466529740375f / 8.0),
+ FL2FXCONST_SGL(-0.66809432114456f / 8.0)},
+ {FL2FXCONST_SGL(0.97875325649683f / 8.0),
+ FL2FXCONST_SGL(-0.72467840967746f / 8.0)},
+ {FL2FXCONST_SGL(-0.95038560288864f / 8.0),
+ FL2FXCONST_SGL(0.89563219587625f / 8.0)},
+ {FL2FXCONST_SGL(0.17005239424212f / 8.0),
+ FL2FXCONST_SGL(0.54683053962658f / 8.0)},
+ {FL2FXCONST_SGL(-0.76910792026848f / 8.0),
+ FL2FXCONST_SGL(-0.96226617549298f / 8.0)},
+ {FL2FXCONST_SGL(0.99743281016846f / 8.0),
+ FL2FXCONST_SGL(0.42697157037567f / 8.0)},
+ {FL2FXCONST_SGL(0.95437383549973f / 8.0),
+ FL2FXCONST_SGL(0.97002324109952f / 8.0)},
+ {FL2FXCONST_SGL(0.99578905365569f / 8.0),
+ FL2FXCONST_SGL(-0.54106826257356f / 8.0)},
+ {FL2FXCONST_SGL(0.28058259829990f / 8.0),
+ FL2FXCONST_SGL(-0.85361420634036f / 8.0)},
+ {FL2FXCONST_SGL(0.85256524470573f / 8.0),
+ FL2FXCONST_SGL(-0.64567607735589f / 8.0)},
+ {FL2FXCONST_SGL(-0.50608540105128f / 8.0),
+ FL2FXCONST_SGL(-0.65846015480300f / 8.0)},
+ {FL2FXCONST_SGL(-0.97210735183243f / 8.0),
+ FL2FXCONST_SGL(-0.23095213067791f / 8.0)},
+ {FL2FXCONST_SGL(0.95424048234441f / 8.0),
+ FL2FXCONST_SGL(-0.99240147091219f / 8.0)},
+ {FL2FXCONST_SGL(-0.96926570524023f / 8.0),
+ FL2FXCONST_SGL(0.73775654896574f / 8.0)},
+ {FL2FXCONST_SGL(0.30872163214726f / 8.0),
+ FL2FXCONST_SGL(0.41514960556126f / 8.0)},
+ {FL2FXCONST_SGL(-0.24523839572639f / 8.0),
+ FL2FXCONST_SGL(0.63206633394807f / 8.0)},
+ {FL2FXCONST_SGL(-0.33813265086024f / 8.0),
+ FL2FXCONST_SGL(-0.38661779441897f / 8.0)},
+ {FL2FXCONST_SGL(-0.05826828420146f / 8.0),
+ FL2FXCONST_SGL(-0.06940774188029f / 8.0)},
+ {FL2FXCONST_SGL(-0.22898461455054f / 8.0),
+ FL2FXCONST_SGL(0.97054853316316f / 8.0)},
+ {FL2FXCONST_SGL(-0.18509915019881f / 8.0),
+ FL2FXCONST_SGL(0.47565762892084f / 8.0)},
+ {FL2FXCONST_SGL(-0.10488238045009f / 8.0),
+ FL2FXCONST_SGL(-0.87769947402394f / 8.0)},
+ {FL2FXCONST_SGL(-0.71886586182037f / 8.0),
+ FL2FXCONST_SGL(0.78030982480538f / 8.0)},
+ {FL2FXCONST_SGL(0.99793873738654f / 8.0),
+ FL2FXCONST_SGL(0.90041310491497f / 8.0)},
+ {FL2FXCONST_SGL(0.57563307626120f / 8.0),
+ FL2FXCONST_SGL(-0.91034337352097f / 8.0)},
+ {FL2FXCONST_SGL(0.28909646383717f / 8.0),
+ FL2FXCONST_SGL(0.96307783970534f / 8.0)},
+ {FL2FXCONST_SGL(0.42188998312520f / 8.0),
+ FL2FXCONST_SGL(0.48148651230437f / 8.0)},
+ {FL2FXCONST_SGL(0.93335049681047f / 8.0),
+ FL2FXCONST_SGL(-0.43537023883588f / 8.0)},
+ {FL2FXCONST_SGL(-0.97087374418267f / 8.0),
+ FL2FXCONST_SGL(0.86636445711364f / 8.0)},
+ {FL2FXCONST_SGL(0.36722871286923f / 8.0),
+ FL2FXCONST_SGL(0.65291654172961f / 8.0)},
+ {FL2FXCONST_SGL(-0.81093025665696f / 8.0),
+ FL2FXCONST_SGL(0.08778370229363f / 8.0)},
+ {FL2FXCONST_SGL(-0.26240603062237f / 8.0),
+ FL2FXCONST_SGL(-0.92774095379098f / 8.0)},
+ {FL2FXCONST_SGL(0.83996497984604f / 8.0),
+ FL2FXCONST_SGL(0.55839849139647f / 8.0)},
+ {FL2FXCONST_SGL(-0.99909615720225f / 8.0),
+ FL2FXCONST_SGL(-0.96024605713970f / 8.0)},
+ {FL2FXCONST_SGL(0.74649464155061f / 8.0),
+ FL2FXCONST_SGL(0.12144893606462f / 8.0)},
+ {FL2FXCONST_SGL(-0.74774595569805f / 8.0),
+ FL2FXCONST_SGL(-0.26898062008959f / 8.0)},
+ {FL2FXCONST_SGL(0.95781667469567f / 8.0),
+ FL2FXCONST_SGL(-0.79047927052628f / 8.0)},
+ {FL2FXCONST_SGL(0.95472308713099f / 8.0),
+ FL2FXCONST_SGL(-0.08588776019550f / 8.0)},
+ {FL2FXCONST_SGL(0.48708332746299f / 8.0),
+ FL2FXCONST_SGL(0.99999041579432f / 8.0)},
+ {FL2FXCONST_SGL(0.46332038247497f / 8.0),
+ FL2FXCONST_SGL(0.10964126185063f / 8.0)},
+ {FL2FXCONST_SGL(-0.76497004940162f / 8.0),
+ FL2FXCONST_SGL(0.89210929242238f / 8.0)},
+ {FL2FXCONST_SGL(0.57397389364339f / 8.0),
+ FL2FXCONST_SGL(0.35289703373760f / 8.0)},
+ {FL2FXCONST_SGL(0.75374316974495f / 8.0),
+ FL2FXCONST_SGL(0.96705214651335f / 8.0)},
+ {FL2FXCONST_SGL(-0.59174397685714f / 8.0),
+ FL2FXCONST_SGL(-0.89405370422752f / 8.0)},
+ {FL2FXCONST_SGL(0.75087906691890f / 8.0),
+ FL2FXCONST_SGL(-0.29612672982396f / 8.0)},
+ {FL2FXCONST_SGL(-0.98607857336230f / 8.0),
+ FL2FXCONST_SGL(0.25034911730023f / 8.0)},
+ {FL2FXCONST_SGL(-0.40761056640505f / 8.0),
+ FL2FXCONST_SGL(-0.90045573444695f / 8.0)},
+ {FL2FXCONST_SGL(0.66929266740477f / 8.0),
+ FL2FXCONST_SGL(0.98629493401748f / 8.0)},
+ {FL2FXCONST_SGL(-0.97463695257310f / 8.0),
+ FL2FXCONST_SGL(-0.00190223301301f / 8.0)},
+ {FL2FXCONST_SGL(0.90145509409859f / 8.0),
+ FL2FXCONST_SGL(0.99781390365446f / 8.0)},
+ {FL2FXCONST_SGL(-0.87259289048043f / 8.0),
+ FL2FXCONST_SGL(0.99233587353666f / 8.0)},
+ {FL2FXCONST_SGL(-0.91529461447692f / 8.0),
+ FL2FXCONST_SGL(-0.15698707534206f / 8.0)},
+ {FL2FXCONST_SGL(-0.03305738840705f / 8.0),
+ FL2FXCONST_SGL(-0.37205262859764f / 8.0)},
+ {FL2FXCONST_SGL(0.07223051368337f / 8.0),
+ FL2FXCONST_SGL(-0.88805001733626f / 8.0)},
+ {FL2FXCONST_SGL(0.99498012188353f / 8.0),
+ FL2FXCONST_SGL(0.97094358113387f / 8.0)},
+ {FL2FXCONST_SGL(-0.74904939500519f / 8.0),
+ FL2FXCONST_SGL(0.99985483641521f / 8.0)},
+ {FL2FXCONST_SGL(0.04585228574211f / 8.0),
+ FL2FXCONST_SGL(0.99812337444082f / 8.0)},
+ {FL2FXCONST_SGL(-0.89054954257993f / 8.0),
+ FL2FXCONST_SGL(-0.31791913188064f / 8.0)},
+ {FL2FXCONST_SGL(-0.83782144651251f / 8.0),
+ FL2FXCONST_SGL(0.97637632547466f / 8.0)},
+ {FL2FXCONST_SGL(0.33454804933804f / 8.0),
+ FL2FXCONST_SGL(-0.86231516800408f / 8.0)},
+ {FL2FXCONST_SGL(-0.99707579362824f / 8.0),
+ FL2FXCONST_SGL(0.93237990079441f / 8.0)},
+ {FL2FXCONST_SGL(-0.22827527843994f / 8.0),
+ FL2FXCONST_SGL(0.18874759397997f / 8.0)},
+ {FL2FXCONST_SGL(0.67248046289143f / 8.0),
+ FL2FXCONST_SGL(-0.03646211390569f / 8.0)},
+ {FL2FXCONST_SGL(-0.05146538187944f / 8.0),
+ FL2FXCONST_SGL(-0.92599700120679f / 8.0)},
+ {FL2FXCONST_SGL(0.99947295749905f / 8.0),
+ FL2FXCONST_SGL(0.93625229707912f / 8.0)},
+ {FL2FXCONST_SGL(0.66951124390363f / 8.0),
+ FL2FXCONST_SGL(0.98905825623893f / 8.0)},
+ {FL2FXCONST_SGL(-0.99602956559179f / 8.0),
+ FL2FXCONST_SGL(-0.44654715757688f / 8.0)},
+ {FL2FXCONST_SGL(0.82104905483590f / 8.0),
+ FL2FXCONST_SGL(0.99540741724928f / 8.0)},
+ {FL2FXCONST_SGL(0.99186510988782f / 8.0),
+ FL2FXCONST_SGL(0.72023001312947f / 8.0)},
+ {FL2FXCONST_SGL(-0.65284592392918f / 8.0),
+ FL2FXCONST_SGL(0.52186723253637f / 8.0)},
+ {FL2FXCONST_SGL(0.93885443798188f / 8.0),
+ FL2FXCONST_SGL(-0.74895312615259f / 8.0)},
+ {FL2FXCONST_SGL(0.96735248738388f / 8.0),
+ FL2FXCONST_SGL(0.90891816978629f / 8.0)},
+ {FL2FXCONST_SGL(-0.22225968841114f / 8.0),
+ FL2FXCONST_SGL(0.57124029781228f / 8.0)},
+ {FL2FXCONST_SGL(-0.44132783753414f / 8.0),
+ FL2FXCONST_SGL(-0.92688840659280f / 8.0)},
+ {FL2FXCONST_SGL(-0.85694974219574f / 8.0),
+ FL2FXCONST_SGL(0.88844532719844f / 8.0)},
+ {FL2FXCONST_SGL(0.91783042091762f / 8.0),
+ FL2FXCONST_SGL(-0.46356892383970f / 8.0)},
+ {FL2FXCONST_SGL(0.72556974415690f / 8.0),
+ FL2FXCONST_SGL(-0.99899555770747f / 8.0)},
+ {FL2FXCONST_SGL(-0.99711581834508f / 8.0),
+ FL2FXCONST_SGL(0.58211560180426f / 8.0)},
+ {FL2FXCONST_SGL(0.77638976371966f / 8.0),
+ FL2FXCONST_SGL(0.94321834873819f / 8.0)},
+ {FL2FXCONST_SGL(0.07717324253925f / 8.0),
+ FL2FXCONST_SGL(0.58638399856595f / 8.0)},
+ {FL2FXCONST_SGL(-0.56049829194163f / 8.0),
+ FL2FXCONST_SGL(0.82522301569036f / 8.0)},
+ {FL2FXCONST_SGL(0.98398893639988f / 8.0),
+ FL2FXCONST_SGL(0.39467440420569f / 8.0)},
+ {FL2FXCONST_SGL(0.47546946844938f / 8.0),
+ FL2FXCONST_SGL(0.68613044836811f / 8.0)},
+ {FL2FXCONST_SGL(0.65675089314631f / 8.0),
+ FL2FXCONST_SGL(0.18331637134880f / 8.0)},
+ {FL2FXCONST_SGL(0.03273375457980f / 8.0),
+ FL2FXCONST_SGL(-0.74933109564108f / 8.0)},
+ {FL2FXCONST_SGL(-0.38684144784738f / 8.0),
+ FL2FXCONST_SGL(0.51337349030406f / 8.0)},
+ {FL2FXCONST_SGL(-0.97346267944545f / 8.0),
+ FL2FXCONST_SGL(-0.96549364384098f / 8.0)},
+ {FL2FXCONST_SGL(-0.53282156061942f / 8.0),
+ FL2FXCONST_SGL(-0.91423265091354f / 8.0)},
+ {FL2FXCONST_SGL(0.99817310731176f / 8.0),
+ FL2FXCONST_SGL(0.61133572482148f / 8.0)},
+ {FL2FXCONST_SGL(-0.50254500772635f / 8.0),
+ FL2FXCONST_SGL(-0.88829338134294f / 8.0)},
+ {FL2FXCONST_SGL(0.01995873238855f / 8.0),
+ FL2FXCONST_SGL(0.85223515096765f / 8.0)},
+ {FL2FXCONST_SGL(0.99930381973804f / 8.0),
+ FL2FXCONST_SGL(0.94578896296649f / 8.0)},
+ {FL2FXCONST_SGL(0.82907767600783f / 8.0),
+ FL2FXCONST_SGL(-0.06323442598128f / 8.0)},
+ {FL2FXCONST_SGL(-0.58660709669728f / 8.0),
+ FL2FXCONST_SGL(0.96840773806582f / 8.0)},
+ {FL2FXCONST_SGL(-0.17573736667267f / 8.0),
+ FL2FXCONST_SGL(-0.48166920859485f / 8.0)},
+ {FL2FXCONST_SGL(0.83434292401346f / 8.0),
+ FL2FXCONST_SGL(-0.13023450646997f / 8.0)},
+ {FL2FXCONST_SGL(0.05946491307025f / 8.0),
+ FL2FXCONST_SGL(0.20511047074866f / 8.0)},
+ {FL2FXCONST_SGL(0.81505484574602f / 8.0),
+ FL2FXCONST_SGL(-0.94685947861369f / 8.0)},
+ {FL2FXCONST_SGL(-0.44976380954860f / 8.0),
+ FL2FXCONST_SGL(0.40894572671545f / 8.0)},
+ {FL2FXCONST_SGL(-0.89746474625671f / 8.0),
+ FL2FXCONST_SGL(0.99846578838537f / 8.0)},
+ {FL2FXCONST_SGL(0.39677256130792f / 8.0),
+ FL2FXCONST_SGL(-0.74854668609359f / 8.0)},
+ {FL2FXCONST_SGL(-0.07588948563079f / 8.0),
+ FL2FXCONST_SGL(0.74096214084170f / 8.0)},
+ {FL2FXCONST_SGL(0.76343198951445f / 8.0),
+ FL2FXCONST_SGL(0.41746629422634f / 8.0)},
+ {FL2FXCONST_SGL(-0.74490104699626f / 8.0),
+ FL2FXCONST_SGL(0.94725911744610f / 8.0)},
+ {FL2FXCONST_SGL(0.64880119792759f / 8.0),
+ FL2FXCONST_SGL(0.41336660830571f / 8.0)},
+ {FL2FXCONST_SGL(0.62319537462542f / 8.0),
+ FL2FXCONST_SGL(-0.93098313552599f / 8.0)},
+ {FL2FXCONST_SGL(0.42215817594807f / 8.0),
+ FL2FXCONST_SGL(-0.07712787385208f / 8.0)},
+ {FL2FXCONST_SGL(0.02704554141885f / 8.0),
+ FL2FXCONST_SGL(-0.05417518053666f / 8.0)},
+ {FL2FXCONST_SGL(0.80001773566818f / 8.0),
+ FL2FXCONST_SGL(0.91542195141039f / 8.0)},
+ {FL2FXCONST_SGL(-0.79351832348816f / 8.0),
+ FL2FXCONST_SGL(-0.36208897989136f / 8.0)},
+ {FL2FXCONST_SGL(0.63872359151636f / 8.0),
+ FL2FXCONST_SGL(0.08128252493444f / 8.0)},
+ {FL2FXCONST_SGL(0.52890520960295f / 8.0),
+ FL2FXCONST_SGL(0.60048872455592f / 8.0)},
+ {FL2FXCONST_SGL(0.74238552914587f / 8.0),
+ FL2FXCONST_SGL(0.04491915291044f / 8.0)},
+ {FL2FXCONST_SGL(0.99096131449250f / 8.0),
+ FL2FXCONST_SGL(-0.19451182854402f / 8.0)},
+ {FL2FXCONST_SGL(-0.80412329643109f / 8.0),
+ FL2FXCONST_SGL(-0.88513818199457f / 8.0)},
+ {FL2FXCONST_SGL(-0.64612616129736f / 8.0),
+ FL2FXCONST_SGL(0.72198674804544f / 8.0)},
+ {FL2FXCONST_SGL(0.11657770663191f / 8.0),
+ FL2FXCONST_SGL(-0.83662833815041f / 8.0)},
+ {FL2FXCONST_SGL(-0.95053182488101f / 8.0),
+ FL2FXCONST_SGL(-0.96939905138082f / 8.0)},
+ {FL2FXCONST_SGL(-0.62228872928622f / 8.0),
+ FL2FXCONST_SGL(0.82767262846661f / 8.0)},
+ {FL2FXCONST_SGL(0.03004475787316f / 8.0),
+ FL2FXCONST_SGL(-0.99738896333384f / 8.0)},
+ {FL2FXCONST_SGL(-0.97987214341034f / 8.0),
+ FL2FXCONST_SGL(0.36526129686425f / 8.0)},
+ {FL2FXCONST_SGL(-0.99986980746200f / 8.0),
+ FL2FXCONST_SGL(-0.36021610299715f / 8.0)},
+ {FL2FXCONST_SGL(0.89110648599879f / 8.0),
+ FL2FXCONST_SGL(-0.97894250343044f / 8.0)},
+ {FL2FXCONST_SGL(0.10407960510582f / 8.0),
+ FL2FXCONST_SGL(0.77357793811619f / 8.0)},
+ {FL2FXCONST_SGL(0.95964737821728f / 8.0),
+ FL2FXCONST_SGL(-0.35435818285502f / 8.0)},
+ {FL2FXCONST_SGL(0.50843233159162f / 8.0),
+ FL2FXCONST_SGL(0.96107691266205f / 8.0)},
+ {FL2FXCONST_SGL(0.17006334670615f / 8.0),
+ FL2FXCONST_SGL(-0.76854025314829f / 8.0)},
+ {FL2FXCONST_SGL(0.25872675063360f / 8.0),
+ FL2FXCONST_SGL(0.99893303933816f / 8.0)},
+ {FL2FXCONST_SGL(-0.01115998681937f / 8.0),
+ FL2FXCONST_SGL(0.98496019742444f / 8.0)},
+ {FL2FXCONST_SGL(-0.79598702973261f / 8.0),
+ FL2FXCONST_SGL(0.97138411318894f / 8.0)},
+ {FL2FXCONST_SGL(-0.99264708948101f / 8.0),
+ FL2FXCONST_SGL(-0.99542822402536f / 8.0)},
+ {FL2FXCONST_SGL(-0.99829663752818f / 8.0),
+ FL2FXCONST_SGL(0.01877138824311f / 8.0)},
+ {FL2FXCONST_SGL(-0.70801016548184f / 8.0),
+ FL2FXCONST_SGL(0.33680685948117f / 8.0)},
+ {FL2FXCONST_SGL(-0.70467057786826f / 8.0),
+ FL2FXCONST_SGL(0.93272777501857f / 8.0)},
+ {FL2FXCONST_SGL(0.99846021905254f / 8.0),
+ FL2FXCONST_SGL(-0.98725746254433f / 8.0)},
+ {FL2FXCONST_SGL(-0.63364968534650f / 8.0),
+ FL2FXCONST_SGL(-0.16473594423746f / 8.0)},
+ {FL2FXCONST_SGL(-0.16258217500792f / 8.0),
+ FL2FXCONST_SGL(-0.95939125400802f / 8.0)},
+ {FL2FXCONST_SGL(-0.43645594360633f / 8.0),
+ FL2FXCONST_SGL(-0.94805030113284f / 8.0)},
+ {FL2FXCONST_SGL(-0.99848471702976f / 8.0),
+ FL2FXCONST_SGL(0.96245166923809f / 8.0)},
+ {FL2FXCONST_SGL(-0.16796458968998f / 8.0),
+ FL2FXCONST_SGL(-0.98987511890470f / 8.0)},
+ {FL2FXCONST_SGL(-0.87979225745213f / 8.0),
+ FL2FXCONST_SGL(-0.71725725041680f / 8.0)},
+ {FL2FXCONST_SGL(0.44183099021786f / 8.0),
+ FL2FXCONST_SGL(-0.93568974498761f / 8.0)},
+ {FL2FXCONST_SGL(0.93310180125532f / 8.0),
+ FL2FXCONST_SGL(-0.99913308068246f / 8.0)},
+ {FL2FXCONST_SGL(-0.93941931782002f / 8.0),
+ FL2FXCONST_SGL(-0.56409379640356f / 8.0)},
+ {FL2FXCONST_SGL(-0.88590003188677f / 8.0),
+ FL2FXCONST_SGL(0.47624600491382f / 8.0)},
+ {FL2FXCONST_SGL(0.99971463703691f / 8.0),
+ FL2FXCONST_SGL(-0.83889954253462f / 8.0)},
+ {FL2FXCONST_SGL(-0.75376385639978f / 8.0),
+ FL2FXCONST_SGL(0.00814643438625f / 8.0)},
+ {FL2FXCONST_SGL(0.93887685615875f / 8.0),
+ FL2FXCONST_SGL(-0.11284528204636f / 8.0)},
+ {FL2FXCONST_SGL(0.85126435782309f / 8.0),
+ FL2FXCONST_SGL(0.52349251543547f / 8.0)},
+ {FL2FXCONST_SGL(0.39701421446381f / 8.0),
+ FL2FXCONST_SGL(0.81779634174316f / 8.0)},
+ {FL2FXCONST_SGL(-0.37024464187437f / 8.0),
+ FL2FXCONST_SGL(-0.87071656222959f / 8.0)},
+ {FL2FXCONST_SGL(-0.36024828242896f / 8.0),
+ FL2FXCONST_SGL(0.34655735648287f / 8.0)},
+ {FL2FXCONST_SGL(-0.93388812549209f / 8.0),
+ FL2FXCONST_SGL(-0.84476541096429f / 8.0)},
+ {FL2FXCONST_SGL(-0.65298804552119f / 8.0),
+ FL2FXCONST_SGL(-0.18439575450921f / 8.0)},
+ {FL2FXCONST_SGL(0.11960319006843f / 8.0),
+ FL2FXCONST_SGL(0.99899346780168f / 8.0)},
+ {FL2FXCONST_SGL(0.94292565553160f / 8.0),
+ FL2FXCONST_SGL(0.83163906518293f / 8.0)},
+ {FL2FXCONST_SGL(0.75081145286948f / 8.0),
+ FL2FXCONST_SGL(-0.35533223142265f / 8.0)},
+ {FL2FXCONST_SGL(0.56721979748394f / 8.0),
+ FL2FXCONST_SGL(-0.24076836414499f / 8.0)},
+ {FL2FXCONST_SGL(0.46857766746029f / 8.0),
+ FL2FXCONST_SGL(-0.30140233457198f / 8.0)},
+ {FL2FXCONST_SGL(0.97312313923635f / 8.0),
+ FL2FXCONST_SGL(-0.99548191630031f / 8.0)},
+ {FL2FXCONST_SGL(-0.38299976567017f / 8.0),
+ FL2FXCONST_SGL(0.98516909715427f / 8.0)},
+ {FL2FXCONST_SGL(0.41025800019463f / 8.0),
+ FL2FXCONST_SGL(0.02116736935734f / 8.0)},
+ {FL2FXCONST_SGL(0.09638062008048f / 8.0),
+ FL2FXCONST_SGL(0.04411984381457f / 8.0)},
+ {FL2FXCONST_SGL(-0.85283249275397f / 8.0),
+ FL2FXCONST_SGL(0.91475563922421f / 8.0)},
+ {FL2FXCONST_SGL(0.88866808958124f / 8.0),
+ FL2FXCONST_SGL(-0.99735267083226f / 8.0)},
+ {FL2FXCONST_SGL(-0.48202429536989f / 8.0),
+ FL2FXCONST_SGL(-0.96805608884164f / 8.0)},
+ {FL2FXCONST_SGL(0.27572582416567f / 8.0),
+ FL2FXCONST_SGL(0.58634753335832f / 8.0)},
+ {FL2FXCONST_SGL(-0.65889129659168f / 8.0),
+ FL2FXCONST_SGL(0.58835634138583f / 8.0)},
+ {FL2FXCONST_SGL(0.98838086953732f / 8.0),
+ FL2FXCONST_SGL(0.99994349600236f / 8.0)},
+ {FL2FXCONST_SGL(-0.20651349620689f / 8.0),
+ FL2FXCONST_SGL(0.54593044066355f / 8.0)},
+ {FL2FXCONST_SGL(-0.62126416356920f / 8.0),
+ FL2FXCONST_SGL(-0.59893681700392f / 8.0)},
+ {FL2FXCONST_SGL(0.20320105410437f / 8.0),
+ FL2FXCONST_SGL(-0.86879180355289f / 8.0)},
+ {FL2FXCONST_SGL(-0.97790548600584f / 8.0),
+ FL2FXCONST_SGL(0.96290806999242f / 8.0)},
+ {FL2FXCONST_SGL(0.11112534735126f / 8.0),
+ FL2FXCONST_SGL(0.21484763313301f / 8.0)},
+ {FL2FXCONST_SGL(-0.41368337314182f / 8.0),
+ FL2FXCONST_SGL(0.28216837680365f / 8.0)},
+ {FL2FXCONST_SGL(0.24133038992960f / 8.0),
+ FL2FXCONST_SGL(0.51294362630238f / 8.0)},
+ {FL2FXCONST_SGL(-0.66393410674885f / 8.0),
+ FL2FXCONST_SGL(-0.08249679629081f / 8.0)},
+ {FL2FXCONST_SGL(-0.53697829178752f / 8.0),
+ FL2FXCONST_SGL(-0.97649903936228f / 8.0)},
+ {FL2FXCONST_SGL(-0.97224737889348f / 8.0),
+ FL2FXCONST_SGL(0.22081333579837f / 8.0)},
+ {FL2FXCONST_SGL(0.87392477144549f / 8.0),
+ FL2FXCONST_SGL(-0.12796173740361f / 8.0)},
+ {FL2FXCONST_SGL(0.19050361015753f / 8.0),
+ FL2FXCONST_SGL(0.01602615387195f / 8.0)},
+ {FL2FXCONST_SGL(-0.46353441212724f / 8.0),
+ FL2FXCONST_SGL(-0.95249041539006f / 8.0)},
+ {FL2FXCONST_SGL(-0.07064096339021f / 8.0),
+ FL2FXCONST_SGL(-0.94479803205886f / 8.0)},
+ {FL2FXCONST_SGL(-0.92444085484466f / 8.0),
+ FL2FXCONST_SGL(-0.10457590187436f / 8.0)},
+ {FL2FXCONST_SGL(-0.83822593578728f / 8.0),
+ FL2FXCONST_SGL(-0.01695043208885f / 8.0)},
+ {FL2FXCONST_SGL(0.75214681811150f / 8.0),
+ FL2FXCONST_SGL(-0.99955681042665f / 8.0)},
+ {FL2FXCONST_SGL(-0.42102998829339f / 8.0),
+ FL2FXCONST_SGL(0.99720941999394f / 8.0)},
+ {FL2FXCONST_SGL(-0.72094786237696f / 8.0),
+ FL2FXCONST_SGL(-0.35008961934255f / 8.0)},
+ {FL2FXCONST_SGL(0.78843311019251f / 8.0),
+ FL2FXCONST_SGL(0.52851398958271f / 8.0)},
+ {FL2FXCONST_SGL(0.97394027897442f / 8.0),
+ FL2FXCONST_SGL(-0.26695944086561f / 8.0)},
+ {FL2FXCONST_SGL(0.99206463477946f / 8.0),
+ FL2FXCONST_SGL(-0.57010120849429f / 8.0)},
+ {FL2FXCONST_SGL(0.76789609461795f / 8.0),
+ FL2FXCONST_SGL(-0.76519356730966f / 8.0)},
+ {FL2FXCONST_SGL(-0.82002421836409f / 8.0),
+ FL2FXCONST_SGL(-0.73530179553767f / 8.0)},
+ {FL2FXCONST_SGL(0.81924990025724f / 8.0),
+ FL2FXCONST_SGL(0.99698425250579f / 8.0)},
+ {FL2FXCONST_SGL(-0.26719850873357f / 8.0),
+ FL2FXCONST_SGL(0.68903369776193f / 8.0)},
+ {FL2FXCONST_SGL(-0.43311260380975f / 8.0),
+ FL2FXCONST_SGL(0.85321815947490f / 8.0)},
+ {FL2FXCONST_SGL(0.99194979673836f / 8.0),
+ FL2FXCONST_SGL(0.91876249766422f / 8.0)},
+ {FL2FXCONST_SGL(-0.80692001248487f / 8.0),
+ FL2FXCONST_SGL(-0.32627540663214f / 8.0)},
+ {FL2FXCONST_SGL(0.43080003649976f / 8.0),
+ FL2FXCONST_SGL(-0.21919095636638f / 8.0)},
+ {FL2FXCONST_SGL(0.67709491937357f / 8.0),
+ FL2FXCONST_SGL(-0.95478075822906f / 8.0)},
+ {FL2FXCONST_SGL(0.56151770568316f / 8.0),
+ FL2FXCONST_SGL(-0.70693811747778f / 8.0)},
+ {FL2FXCONST_SGL(0.10831862810749f / 8.0),
+ FL2FXCONST_SGL(-0.08628837174592f / 8.0)},
+ {FL2FXCONST_SGL(0.91229417540436f / 8.0),
+ FL2FXCONST_SGL(-0.65987351408410f / 8.0)},
+ {FL2FXCONST_SGL(-0.48972893932274f / 8.0),
+ FL2FXCONST_SGL(0.56289246362686f / 8.0)},
+ {FL2FXCONST_SGL(-0.89033658689697f / 8.0),
+ FL2FXCONST_SGL(-0.71656563987082f / 8.0)},
+ {FL2FXCONST_SGL(0.65269447475094f / 8.0),
+ FL2FXCONST_SGL(0.65916004833932f / 8.0)},
+ {FL2FXCONST_SGL(0.67439478141121f / 8.0),
+ FL2FXCONST_SGL(-0.81684380846796f / 8.0)},
+ {FL2FXCONST_SGL(-0.47770832416973f / 8.0),
+ FL2FXCONST_SGL(-0.16789556203025f / 8.0)},
+ {FL2FXCONST_SGL(-0.99715979260878f / 8.0),
+ FL2FXCONST_SGL(-0.93565784007648f / 8.0)},
+ {FL2FXCONST_SGL(-0.90889593602546f / 8.0),
+ FL2FXCONST_SGL(0.62034397054380f / 8.0)},
+ {FL2FXCONST_SGL(-0.06618622548177f / 8.0),
+ FL2FXCONST_SGL(-0.23812217221359f / 8.0)},
+ {FL2FXCONST_SGL(0.99430266919728f / 8.0),
+ FL2FXCONST_SGL(0.18812555317553f / 8.0)},
+ {FL2FXCONST_SGL(0.97686402381843f / 8.0),
+ FL2FXCONST_SGL(-0.28664534366620f / 8.0)},
+ {FL2FXCONST_SGL(0.94813650221268f / 8.0),
+ FL2FXCONST_SGL(-0.97506640027128f / 8.0)},
+ {FL2FXCONST_SGL(-0.95434497492853f / 8.0),
+ FL2FXCONST_SGL(-0.79607978501983f / 8.0)},
+ {FL2FXCONST_SGL(-0.49104783137150f / 8.0),
+ FL2FXCONST_SGL(0.32895214359663f / 8.0)},
+ {FL2FXCONST_SGL(0.99881175120751f / 8.0),
+ FL2FXCONST_SGL(0.88993983831354f / 8.0)},
+ {FL2FXCONST_SGL(0.50449166760303f / 8.0),
+ FL2FXCONST_SGL(-0.85995072408434f / 8.0)},
+ {FL2FXCONST_SGL(0.47162891065108f / 8.0),
+ FL2FXCONST_SGL(-0.18680204049569f / 8.0)},
+ {FL2FXCONST_SGL(-0.62081581361840f / 8.0),
+ FL2FXCONST_SGL(0.75000676218956f / 8.0)},
+ {FL2FXCONST_SGL(-0.43867015250812f / 8.0),
+ FL2FXCONST_SGL(0.99998069244322f / 8.0)},
+ {FL2FXCONST_SGL(0.98630563232075f / 8.0),
+ FL2FXCONST_SGL(-0.53578899600662f / 8.0)},
+ {FL2FXCONST_SGL(-0.61510362277374f / 8.0),
+ FL2FXCONST_SGL(-0.89515019899997f / 8.0)},
+ {FL2FXCONST_SGL(-0.03841517601843f / 8.0),
+ FL2FXCONST_SGL(-0.69888815681179f / 8.0)},
+ {FL2FXCONST_SGL(-0.30102157304644f / 8.0),
+ FL2FXCONST_SGL(-0.07667808922205f / 8.0)},
+ {FL2FXCONST_SGL(0.41881284182683f / 8.0),
+ FL2FXCONST_SGL(0.02188098922282f / 8.0)},
+ {FL2FXCONST_SGL(-0.86135454941237f / 8.0),
+ FL2FXCONST_SGL(0.98947480909359f / 8.0)},
+ {FL2FXCONST_SGL(0.67226861393788f / 8.0),
+ FL2FXCONST_SGL(-0.13494389011014f / 8.0)},
+ {FL2FXCONST_SGL(-0.70737398842068f / 8.0),
+ FL2FXCONST_SGL(-0.76547349325992f / 8.0)},
+ {FL2FXCONST_SGL(0.94044946687963f / 8.0),
+ FL2FXCONST_SGL(0.09026201157416f / 8.0)},
+ {FL2FXCONST_SGL(-0.82386352534327f / 8.0),
+ FL2FXCONST_SGL(0.08924768823676f / 8.0)},
+ {FL2FXCONST_SGL(-0.32070666698656f / 8.0),
+ FL2FXCONST_SGL(0.50143421908753f / 8.0)},
+ {FL2FXCONST_SGL(0.57593163224487f / 8.0),
+ FL2FXCONST_SGL(-0.98966422921509f / 8.0)},
+ {FL2FXCONST_SGL(-0.36326018419965f / 8.0),
+ FL2FXCONST_SGL(0.07440243123228f / 8.0)},
+ {FL2FXCONST_SGL(0.99979044674350f / 8.0),
+ FL2FXCONST_SGL(-0.14130287347405f / 8.0)},
+ {FL2FXCONST_SGL(-0.92366023326932f / 8.0),
+ FL2FXCONST_SGL(-0.97979298068180f / 8.0)},
+ {FL2FXCONST_SGL(-0.44607178518598f / 8.0),
+ FL2FXCONST_SGL(-0.54233252016394f / 8.0)},
+ {FL2FXCONST_SGL(0.44226800932956f / 8.0),
+ FL2FXCONST_SGL(0.71326756742752f / 8.0)},
+ {FL2FXCONST_SGL(0.03671907158312f / 8.0),
+ FL2FXCONST_SGL(0.63606389366675f / 8.0)},
+ {FL2FXCONST_SGL(0.52175424682195f / 8.0),
+ FL2FXCONST_SGL(-0.85396826735705f / 8.0)},
+ {FL2FXCONST_SGL(-0.94701139690956f / 8.0),
+ FL2FXCONST_SGL(-0.01826348194255f / 8.0)},
+ {FL2FXCONST_SGL(-0.98759606946049f / 8.0),
+ FL2FXCONST_SGL(0.82288714303073f / 8.0)},
+ {FL2FXCONST_SGL(0.87434794743625f / 8.0),
+ FL2FXCONST_SGL(0.89399495655433f / 8.0)},
+ {FL2FXCONST_SGL(-0.93412041758744f / 8.0),
+ FL2FXCONST_SGL(0.41374052024363f / 8.0)},
+ {FL2FXCONST_SGL(0.96063943315511f / 8.0),
+ FL2FXCONST_SGL(0.93116709541280f / 8.0)},
+ {FL2FXCONST_SGL(0.97534253457837f / 8.0),
+ FL2FXCONST_SGL(0.86150930812689f / 8.0)},
+ {FL2FXCONST_SGL(0.99642466504163f / 8.0),
+ FL2FXCONST_SGL(0.70190043427512f / 8.0)},
+ {FL2FXCONST_SGL(-0.94705089665984f / 8.0),
+ FL2FXCONST_SGL(-0.29580042814306f / 8.0)},
+ {FL2FXCONST_SGL(0.91599807087376f / 8.0),
+ FL2FXCONST_SGL(-0.98147830385781f / 8.0)}};
+//@}
+
+/*
+static const FIXP_SGL harmonicPhase [2][4] = {
+ { 1.0, 0.0, -1.0, 0.0},
+ { 0.0, 1.0, 0.0, -1.0}
+};
+*/
+
+/* tables for SBR and AAC LD */
+/* table for 8 time slot index */
+const int FDK_sbrDecoder_envelopeTable_8[8][5] = {
+ /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */
+ /* borders from left to right side; -1 = not in use */
+ /*[|T-|------]*/ {2, 0, 0, 1, -1},
+ /*[|-T-|-----]*/ {2, 0, 0, 2, -1},
+ /*[--|T-|----]*/ {3, 1, 1, 2, 4},
+ /*[---|T-|---]*/ {3, 1, 1, 3, 5},
+ /*[----|T-|--]*/ {3, 1, 1, 4, 6},
+ /*[-----|T--|]*/ {2, 1, 1, 5, -1},
+ /*[------|T-|]*/ {2, 1, 1, 6, -1},
+ /*[-------|T|]*/ {2, 1, 1, 7, -1},
+};
+
+/* table for 15 time slot index */
+const int FDK_sbrDecoder_envelopeTable_15[15][6] = {
+ /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */
+ /* length from left to right side; -1 = not in use */
+ /*[|T---|------------]*/ {2, 0, 0, 4, -1, -1},
+ /*[|-T---|-----------]*/ {2, 0, 0, 5, -1, -1},
+ /*[|--|T---|---------]*/ {3, 1, 1, 2, 6, -1},
+ /*[|---|T---|--------]*/ {3, 1, 1, 3, 7, -1},
+ /*[|----|T---|-------]*/ {3, 1, 1, 4, 8, -1},
+ /*[|-----|T---|------]*/ {3, 1, 1, 5, 9, -1},
+ /*[|------|T---|-----]*/ {3, 1, 1, 6, 10, -1},
+ /*[|-------|T---|----]*/ {3, 1, 1, 7, 11, -1},
+ /*[|--------|T---|---]*/ {3, 1, 1, 8, 12, -1},
+ /*[|---------|T---|--]*/ {3, 1, 1, 9, 13, -1},
+ /*[|----------|T----|]*/ {2, 1, 1, 10, -1, -1},
+ /*[|-----------|T---|]*/ {2, 1, 1, 11, -1, -1},
+ /*[|------------|T--|]*/ {2, 1, 1, 12, -1, -1},
+ /*[|-------------|T-|]*/ {2, 1, 1, 13, -1, -1},
+ /*[|--------------|T|]*/ {2, 1, 1, 14, -1, -1},
+};
+
+/* table for 16 time slot index */
+const int FDK_sbrDecoder_envelopeTable_16[16][6] = {
+ /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */
+ /* length from left to right side; -1 = not in use */
+ /*[|T---|------------|]*/ {2, 0, 0, 4, -1, -1},
+ /*[|-T---|-----------|]*/ {2, 0, 0, 5, -1, -1},
+ /*[|--|T---|----------]*/ {3, 1, 1, 2, 6, -1},
+ /*[|---|T---|---------]*/ {3, 1, 1, 3, 7, -1},
+ /*[|----|T---|--------]*/ {3, 1, 1, 4, 8, -1},
+ /*[|-----|T---|-------]*/ {3, 1, 1, 5, 9, -1},
+ /*[|------|T---|------]*/ {3, 1, 1, 6, 10, -1},
+ /*[|-------|T---|-----]*/ {3, 1, 1, 7, 11, -1},
+ /*[|--------|T---|----]*/ {3, 1, 1, 8, 12, -1},
+ /*[|---------|T---|---]*/ {3, 1, 1, 9, 13, -1},
+ /*[|----------|T---|--]*/ {3, 1, 1, 10, 14, -1},
+ /*[|-----------|T----|]*/ {2, 1, 1, 11, -1, -1},
+ /*[|------------|T---|]*/ {2, 1, 1, 12, -1, -1},
+ /*[|-------------|T--|]*/ {2, 1, 1, 13, -1, -1},
+ /*[|--------------|T-|]*/ {2, 1, 1, 14, -1, -1},
+ /*[|---------------|T|]*/ {2, 1, 1, 15, -1, -1},
+};
+
+/*!
+ \name FrameInfoDefaults
+
+ Predefined envelope positions for the FIX-FIX case (static framing)
+*/
+//@{
+const FRAME_INFO FDK_sbrDecoder_sbr_frame_info1_15 = {
+ 0, 1, {0, 15, 0, 0, 0, 0}, {1, 0, 0, 0, 0}, -1, 1, {0, 15, 0}, {0, 0, 0},
+ 0, 0};
+const FRAME_INFO FDK_sbrDecoder_sbr_frame_info2_15 = {
+ 0, 2, {0, 8, 15, 0, 0, 0}, {1, 1, 0, 0, 0}, -1, 2, {0, 8, 15}, {0, 0, 0},
+ 0, 0};
+const FRAME_INFO FDK_sbrDecoder_sbr_frame_info4_15 = {
+ 0, 4, {0, 4, 8, 12, 15, 0}, {1, 1, 1, 1, 0}, -1, 2, {0, 8, 15}, {0, 0, 0},
+ 0, 0};
+#if (MAX_ENVELOPES >= 8)
+const FRAME_INFO FDK_sbrDecoder_sbr_frame_info8_15 = {
+ 0,
+ 8,
+ {0, 2, 4, 6, 8, 10, 12, 14, 15},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+ -1,
+ 2,
+ {0, 8, 15},
+ {0, 0, 0},
+ 0,
+ 0};
+#endif
+
+const FRAME_INFO FDK_sbrDecoder_sbr_frame_info1_16 = {
+ 0, 1, {0, 16, 0, 0, 0, 0}, {1, 0, 0, 0, 0}, -1, 1, {0, 16, 0}, {0, 0, 0},
+ 0, 0};
+const FRAME_INFO FDK_sbrDecoder_sbr_frame_info2_16 = {
+ 0, 2, {0, 8, 16, 0, 0, 0}, {1, 1, 0, 0, 0}, -1, 2, {0, 8, 16}, {0, 0, 0},
+ 0, 0};
+const FRAME_INFO FDK_sbrDecoder_sbr_frame_info4_16 = {
+ 0, 4, {0, 4, 8, 12, 16, 0}, {1, 1, 1, 1, 0}, -1, 2, {0, 8, 16}, {0, 0, 0},
+ 0, 0};
+
+#if (MAX_ENVELOPES >= 8)
+const FRAME_INFO FDK_sbrDecoder_sbr_frame_info8_16 = {
+ 0,
+ 8,
+ {0, 2, 4, 6, 8, 10, 12, 14, 16},
+ {1, 1, 1, 1, 1, 1, 1, 1},
+ -1,
+ 2,
+ {0, 8, 16},
+ {0, 0, 0},
+ 0,
+ 0};
+#endif
+
+//@}
+
+/*!
+ \name SBR_HuffmanTables
+
+ SBR Huffman Table Overview: \n
+ \n
+ o envelope level, 1.5 dB: \n
+ 1) sbr_huffBook_EnvLevel10T[120][2] \n
+ 2) sbr_huffBook_EnvLevel10F[120][2] \n
+ \n
+ o envelope balance, 1.5 dB: \n
+ 3) sbr_huffBook_EnvBalance10T[48][2] \n
+ 4) sbr_huffBook_EnvBalance10F[48][2] \n
+ \n
+ o envelope level, 3.0 dB: \n
+ 5) sbr_huffBook_EnvLevel11T[62][2] \n
+ 6) sbr_huffBook_EnvLevel11F[62][2] \n
+ \n
+ o envelope balance, 3.0 dB: \n
+ 7) sbr_huffBook_EnvBalance11T[24][2] \n
+ 8) sbr_huffBook_EnvBalance11F[24][2] \n
+ \n
+ o noise level, 3.0 dB: \n
+ 9) sbr_huffBook_NoiseLevel11T[62][2] \n
+ -) (sbr_huffBook_EnvLevel11F[62][2] is used for freq dir)\n
+ \n
+ o noise balance, 3.0 dB: \n
+ 10) sbr_huffBook_NoiseBalance11T[24][2]\n
+ -) (sbr_huffBook_EnvBalance11F[24][2] is used for freq dir)\n
+ \n
+ (1.5 dB is never used for noise)
+
+*/
+//@{
+const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel10T[120][2] = {
+ {1, 2}, {-64, -65}, {3, 4}, {-63, -66}, {5, 6},
+ {-62, -67}, {7, 8}, {-61, -68}, {9, 10}, {-60, -69},
+ {11, 12}, {-59, -70}, {13, 14}, {-58, -71}, {15, 16},
+ {-57, -72}, {17, 18}, {-73, -56}, {19, 21}, {-74, 20},
+ {-55, -75}, {22, 26}, {23, 24}, {-54, -76}, {-77, 25},
+ {-53, -78}, {27, 34}, {28, 29}, {-52, -79}, {30, 31},
+ {-80, -51}, {32, 33}, {-83, -82}, {-81, -50}, {35, 57},
+ {36, 40}, {37, 38}, {-88, -84}, {-48, 39}, {-90, -85},
+ {41, 46}, {42, 43}, {-49, -87}, {44, 45}, {-89, -86},
+ {-124, -123}, {47, 50}, {48, 49}, {-122, -121}, {-120, -119},
+ {51, 54}, {52, 53}, {-118, -117}, {-116, -115}, {55, 56},
+ {-114, -113}, {-112, -111}, {58, 89}, {59, 74}, {60, 67},
+ {61, 64}, {62, 63}, {-110, -109}, {-108, -107}, {65, 66},
+ {-106, -105}, {-104, -103}, {68, 71}, {69, 70}, {-102, -101},
+ {-100, -99}, {72, 73}, {-98, -97}, {-96, -95}, {75, 82},
+ {76, 79}, {77, 78}, {-94, -93}, {-92, -91}, {80, 81},
+ {-47, -46}, {-45, -44}, {83, 86}, {84, 85}, {-43, -42},
+ {-41, -40}, {87, 88}, {-39, -38}, {-37, -36}, {90, 105},
+ {91, 98}, {92, 95}, {93, 94}, {-35, -34}, {-33, -32},
+ {96, 97}, {-31, -30}, {-29, -28}, {99, 102}, {100, 101},
+ {-27, -26}, {-25, -24}, {103, 104}, {-23, -22}, {-21, -20},
+ {106, 113}, {107, 110}, {108, 109}, {-19, -18}, {-17, -16},
+ {111, 112}, {-15, -14}, {-13, -12}, {114, 117}, {115, 116},
+ {-11, -10}, {-9, -8}, {118, 119}, {-7, -6}, {-5, -4}};
+
+const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel10F[120][2] = {
+ {1, 2}, {-64, -65}, {3, 4}, {-63, -66}, {5, 6},
+ {-67, -62}, {7, 8}, {-68, -61}, {9, 10}, {-69, -60},
+ {11, 13}, {-70, 12}, {-59, -71}, {14, 16}, {-58, 15},
+ {-72, -57}, {17, 19}, {-73, 18}, {-56, -74}, {20, 23},
+ {21, 22}, {-55, -75}, {-54, -53}, {24, 27}, {25, 26},
+ {-76, -52}, {-77, -51}, {28, 31}, {29, 30}, {-50, -78},
+ {-79, -49}, {32, 36}, {33, 34}, {-48, -47}, {-80, 35},
+ {-81, -82}, {37, 47}, {38, 41}, {39, 40}, {-83, -46},
+ {-45, -84}, {42, 44}, {-85, 43}, {-44, -43}, {45, 46},
+ {-88, -87}, {-86, -90}, {48, 66}, {49, 56}, {50, 53},
+ {51, 52}, {-92, -42}, {-41, -39}, {54, 55}, {-105, -89},
+ {-38, -37}, {57, 60}, {58, 59}, {-94, -91}, {-40, -36},
+ {61, 63}, {-20, 62}, {-115, -110}, {64, 65}, {-108, -107},
+ {-101, -97}, {67, 89}, {68, 75}, {69, 72}, {70, 71},
+ {-95, -93}, {-34, -27}, {73, 74}, {-22, -17}, {-16, -124},
+ {76, 82}, {77, 79}, {-123, 78}, {-122, -121}, {80, 81},
+ {-120, -119}, {-118, -117}, {83, 86}, {84, 85}, {-116, -114},
+ {-113, -112}, {87, 88}, {-111, -109}, {-106, -104}, {90, 105},
+ {91, 98}, {92, 95}, {93, 94}, {-103, -102}, {-100, -99},
+ {96, 97}, {-98, -96}, {-35, -33}, {99, 102}, {100, 101},
+ {-32, -31}, {-30, -29}, {103, 104}, {-28, -26}, {-25, -24},
+ {106, 113}, {107, 110}, {108, 109}, {-23, -21}, {-19, -18},
+ {111, 112}, {-15, -14}, {-13, -12}, {114, 117}, {115, 116},
+ {-11, -10}, {-9, -8}, {118, 119}, {-7, -6}, {-5, -4}};
+
+const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance10T[48][2] = {
+ {-64, 1}, {-63, 2}, {-65, 3}, {-62, 4}, {-66, 5}, {-61, 6},
+ {-67, 7}, {-60, 8}, {-68, 9}, {10, 11}, {-69, -59}, {12, 13},
+ {-70, -58}, {14, 28}, {15, 21}, {16, 18}, {-57, 17}, {-71, -56},
+ {19, 20}, {-88, -87}, {-86, -85}, {22, 25}, {23, 24}, {-84, -83},
+ {-82, -81}, {26, 27}, {-80, -79}, {-78, -77}, {29, 36}, {30, 33},
+ {31, 32}, {-76, -75}, {-74, -73}, {34, 35}, {-72, -55}, {-54, -53},
+ {37, 41}, {38, 39}, {-52, -51}, {-50, 40}, {-49, -48}, {42, 45},
+ {43, 44}, {-47, -46}, {-45, -44}, {46, 47}, {-43, -42}, {-41, -40}};
+
+const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance10F[48][2] = {
+ {-64, 1}, {-65, 2}, {-63, 3}, {-66, 4}, {-62, 5}, {-61, 6},
+ {-67, 7}, {-68, 8}, {-60, 9}, {10, 11}, {-69, -59}, {-70, 12},
+ {-58, 13}, {14, 17}, {-71, 15}, {-57, 16}, {-56, -73}, {18, 32},
+ {19, 25}, {20, 22}, {-72, 21}, {-88, -87}, {23, 24}, {-86, -85},
+ {-84, -83}, {26, 29}, {27, 28}, {-82, -81}, {-80, -79}, {30, 31},
+ {-78, -77}, {-76, -75}, {33, 40}, {34, 37}, {35, 36}, {-74, -55},
+ {-54, -53}, {38, 39}, {-52, -51}, {-50, -49}, {41, 44}, {42, 43},
+ {-48, -47}, {-46, -45}, {45, 46}, {-44, -43}, {-42, 47}, {-41, -40}};
+
+const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel11T[62][2] = {
+ {-64, 1}, {-65, 2}, {-63, 3}, {-66, 4}, {-62, 5}, {-67, 6},
+ {-61, 7}, {-68, 8}, {-60, 9}, {10, 11}, {-69, -59}, {12, 14},
+ {-70, 13}, {-71, -58}, {15, 18}, {16, 17}, {-72, -57}, {-73, -74},
+ {19, 22}, {-56, 20}, {-55, 21}, {-54, -77}, {23, 31}, {24, 25},
+ {-75, -76}, {26, 27}, {-78, -53}, {28, 29}, {-52, -95}, {-94, 30},
+ {-93, -92}, {32, 47}, {33, 40}, {34, 37}, {35, 36}, {-91, -90},
+ {-89, -88}, {38, 39}, {-87, -86}, {-85, -84}, {41, 44}, {42, 43},
+ {-83, -82}, {-81, -80}, {45, 46}, {-79, -51}, {-50, -49}, {48, 55},
+ {49, 52}, {50, 51}, {-48, -47}, {-46, -45}, {53, 54}, {-44, -43},
+ {-42, -41}, {56, 59}, {57, 58}, {-40, -39}, {-38, -37}, {60, 61},
+ {-36, -35}, {-34, -33}};
+
+const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel11F[62][2] = {
+ {-64, 1}, {-65, 2}, {-63, 3}, {-66, 4}, {-62, 5}, {-67, 6},
+ {7, 8}, {-61, -68}, {9, 10}, {-60, -69}, {11, 12}, {-59, -70},
+ {13, 14}, {-58, -71}, {15, 16}, {-57, -72}, {17, 19}, {-56, 18},
+ {-55, -73}, {20, 24}, {21, 22}, {-74, -54}, {-53, 23}, {-75, -76},
+ {25, 30}, {26, 27}, {-52, -51}, {28, 29}, {-77, -79}, {-50, -49},
+ {31, 39}, {32, 35}, {33, 34}, {-78, -46}, {-82, -88}, {36, 37},
+ {-83, -48}, {-47, 38}, {-86, -85}, {40, 47}, {41, 44}, {42, 43},
+ {-80, -44}, {-43, -42}, {45, 46}, {-39, -87}, {-84, -40}, {48, 55},
+ {49, 52}, {50, 51}, {-95, -94}, {-93, -92}, {53, 54}, {-91, -90},
+ {-89, -81}, {56, 59}, {57, 58}, {-45, -41}, {-38, -37}, {60, 61},
+ {-36, -35}, {-34, -33}};
+
+const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance11T[24][2] = {
+ {-64, 1}, {-63, 2}, {-65, 3}, {-66, 4}, {-62, 5}, {-61, 6},
+ {-67, 7}, {-68, 8}, {-60, 9}, {10, 16}, {11, 13}, {-69, 12},
+ {-76, -75}, {14, 15}, {-74, -73}, {-72, -71}, {17, 20}, {18, 19},
+ {-70, -59}, {-58, -57}, {21, 22}, {-56, -55}, {-54, 23}, {-53, -52}};
+
+const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance11F[24][2] = {
+ {-64, 1}, {-65, 2}, {-63, 3}, {-66, 4}, {-62, 5}, {-61, 6},
+ {-67, 7}, {-68, 8}, {-60, 9}, {10, 13}, {-69, 11}, {-59, 12},
+ {-58, -76}, {14, 17}, {15, 16}, {-75, -74}, {-73, -72}, {18, 21},
+ {19, 20}, {-71, -70}, {-57, -56}, {22, 23}, {-55, -54}, {-53, -52}};
+
+const SCHAR FDK_sbrDecoder_sbr_huffBook_NoiseLevel11T[62][2] = {
+ {-64, 1}, {-63, 2}, {-65, 3}, {-66, 4}, {-62, 5}, {-67, 6},
+ {7, 8}, {-61, -68}, {9, 30}, {10, 15}, {-60, 11}, {-69, 12},
+ {13, 14}, {-59, -53}, {-95, -94}, {16, 23}, {17, 20}, {18, 19},
+ {-93, -92}, {-91, -90}, {21, 22}, {-89, -88}, {-87, -86}, {24, 27},
+ {25, 26}, {-85, -84}, {-83, -82}, {28, 29}, {-81, -80}, {-79, -78},
+ {31, 46}, {32, 39}, {33, 36}, {34, 35}, {-77, -76}, {-75, -74},
+ {37, 38}, {-73, -72}, {-71, -70}, {40, 43}, {41, 42}, {-58, -57},
+ {-56, -55}, {44, 45}, {-54, -52}, {-51, -50}, {47, 54}, {48, 51},
+ {49, 50}, {-49, -48}, {-47, -46}, {52, 53}, {-45, -44}, {-43, -42},
+ {55, 58}, {56, 57}, {-41, -40}, {-39, -38}, {59, 60}, {-37, -36},
+ {-35, 61}, {-34, -33}};
+
+const SCHAR FDK_sbrDecoder_sbr_huffBook_NoiseBalance11T[24][2] = {
+ {-64, 1}, {-65, 2}, {-63, 3}, {4, 9}, {-66, 5}, {-62, 6},
+ {7, 8}, {-76, -75}, {-74, -73}, {10, 17}, {11, 14}, {12, 13},
+ {-72, -71}, {-70, -69}, {15, 16}, {-68, -67}, {-61, -60}, {18, 21},
+ {19, 20}, {-59, -58}, {-57, -56}, {22, 23}, {-55, -54}, {-53, -52}};
+//@}
+
+/*!
+ \name parametric stereo
+ \brief constants used by the parametric stereo part of the decoder
+
+*/
+
+/* constants used in psbitdec.cpp */
+
+/* FIX_BORDER can have 0, 1, 2, 4 envelopes */
+const UCHAR FDK_sbrDecoder_aFixNoEnvDecode[4] = {0, 1, 2, 4};
+
+/* IID & ICC Huffman codebooks */
+const SCHAR aBookPsIidTimeDecode[28][2] = {
+ {-64, 1}, {-65, 2}, {-63, 3}, {-66, 4}, {-62, 5}, {-67, 6},
+ {-61, 7}, {-68, 8}, {-60, 9}, {-69, 10}, {-59, 11}, {-70, 12},
+ {-58, 13}, {-57, 14}, {-71, 15}, {16, 17}, {-56, -72}, {18, 21},
+ {19, 20}, {-55, -78}, {-77, -76}, {22, 25}, {23, 24}, {-75, -74},
+ {-73, -54}, {26, 27}, {-53, -52}, {-51, -50}};
+
+const SCHAR aBookPsIidFreqDecode[28][2] = {
+ {-64, 1}, {2, 3}, {-63, -65}, {4, 5}, {-62, -66}, {6, 7},
+ {-61, -67}, {8, 9}, {-68, -60}, {-59, 10}, {-69, 11}, {-58, 12},
+ {-70, 13}, {-71, 14}, {-57, 15}, {16, 17}, {-56, -72}, {18, 19},
+ {-55, -54}, {20, 21}, {-73, -53}, {22, 24}, {-74, 23}, {-75, -78},
+ {25, 26}, {-77, -76}, {-52, 27}, {-51, -50}};
+
+const SCHAR aBookPsIccTimeDecode[14][2] = {
+ {-64, 1}, {-63, 2}, {-65, 3}, {-62, 4}, {-66, 5}, {-61, 6}, {-67, 7},
+ {-60, 8}, {-68, 9}, {-59, 10}, {-69, 11}, {-58, 12}, {-70, 13}, {-71, -57}};
+
+const SCHAR aBookPsIccFreqDecode[14][2] = {
+ {-64, 1}, {-63, 2}, {-65, 3}, {-62, 4}, {-66, 5}, {-61, 6}, {-67, 7},
+ {-60, 8}, {-59, 9}, {-68, 10}, {-58, 11}, {-69, 12}, {-57, 13}, {-70, -71}};
+
+/* IID-fine Huffman codebooks */
+
+const SCHAR aBookPsIidFineTimeDecode[60][2] = {
+ {1, -64}, {-63, 2}, {3, -65}, {4, 59}, {5, 7}, {6, -67},
+ {-68, -60}, {-61, 8}, {9, 11}, {-59, 10}, {-70, -58}, {12, 41},
+ {13, 20}, {14, -71}, {-55, 15}, {-53, 16}, {17, -77}, {18, 19},
+ {-85, -84}, {-46, -45}, {-57, 21}, {22, 40}, {23, 29}, {-51, 24},
+ {25, 26}, {-83, -82}, {27, 28}, {-90, -38}, {-92, -91}, {30, 37},
+ {31, 34}, {32, 33}, {-35, -34}, {-37, -36}, {35, 36}, {-94, -93},
+ {-89, -39}, {38, -79}, {39, -81}, {-88, -40}, {-74, -54}, {42, -69},
+ {43, 44}, {-72, -56}, {45, 52}, {46, 50}, {47, -76}, {-49, 48},
+ {-47, 49}, {-87, -41}, {-52, 51}, {-78, -50}, {53, -73}, {54, -75},
+ {55, 57}, {56, -80}, {-86, -42}, {-48, 58}, {-44, -43}, {-66, -62}};
+
+const SCHAR aBookPsIidFineFreqDecode[60][2] = {
+ {1, -64}, {2, 4}, {3, -65}, {-66, -62}, {-63, 5}, {6, 7},
+ {-67, -61}, {8, 9}, {-68, -60}, {10, 11}, {-69, -59}, {12, 13},
+ {-70, -58}, {14, 18}, {-57, 15}, {16, -72}, {-54, 17}, {-75, -53},
+ {19, 37}, {-56, 20}, {21, -73}, {22, 29}, {23, -76}, {24, -78},
+ {25, 28}, {26, 27}, {-85, -43}, {-83, -45}, {-81, -47}, {-52, 30},
+ {-50, 31}, {32, -79}, {33, 34}, {-82, -46}, {35, 36}, {-90, -89},
+ {-92, -91}, {38, -71}, {-55, 39}, {40, -74}, {41, 50}, {42, -77},
+ {-49, 43}, {44, 47}, {45, 46}, {-86, -42}, {-88, -87}, {48, 49},
+ {-39, -38}, {-41, -40}, {-51, 51}, {52, 59}, {53, 56}, {54, 55},
+ {-35, -34}, {-37, -36}, {57, 58}, {-94, -93}, {-84, -44}, {-80, -48}};
+
+/* constants used in psdec.cpp */
+
+/* the values of the following 3 tables are shiftet right by 1 ! */
+const FIXP_DBL ScaleFactors[NO_IID_LEVELS] = {
+
+ 0x5a5ded00, 0x59cd0400, 0x58c29680, 0x564c2e80, 0x52a3d480,
+ 0x4c8be080, 0x46df3080, 0x40000000, 0x384ba5c0, 0x304c2980,
+ 0x24e9f640, 0x1b4a2940, 0x11b5c0a0, 0x0b4e2540, 0x0514ea90};
+
+const FIXP_DBL ScaleFactorsFine[NO_IID_LEVELS_FINE] = {
+
+ 0x5a825c00, 0x5a821c00, 0x5a815100, 0x5a7ed000, 0x5a76e600, 0x5a5ded00,
+ 0x5a39b880, 0x59f1fd00, 0x5964d680, 0x5852ca00, 0x564c2e80, 0x54174480,
+ 0x50ea7500, 0x4c8be080, 0x46df3080, 0x40000000, 0x384ba5c0, 0x304c2980,
+ 0x288dd240, 0x217a2900, 0x1b4a2940, 0x13c5ece0, 0x0e2b0090, 0x0a178ef0,
+ 0x072ab798, 0x0514ea90, 0x02dc5944, 0x019bf87c, 0x00e7b173, 0x00824b8b,
+ 0x00494568};
+const FIXP_DBL Alphas[NO_ICC_LEVELS] = {
+
+ 0x00000000, 0x0b6b5be0, 0x12485f80, 0x1da2fa40,
+ 0x2637ebc0, 0x3243f6c0, 0x466b7480, 0x6487ed80};
+
+const UCHAR bins2groupMap20[NO_IID_GROUPS] = {
+ 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
+
+const UCHAR FDK_sbrDecoder_aNoIidBins[3] = {
+ NO_LOW_RES_IID_BINS, NO_MID_RES_IID_BINS, NO_HI_RES_IID_BINS};
+
+const UCHAR FDK_sbrDecoder_aNoIccBins[3] = {
+ NO_LOW_RES_ICC_BINS, NO_MID_RES_ICC_BINS, NO_HI_RES_ICC_BINS};
+
+/************************************************************************/
+/*!
+ \brief Create lookup tables for some arithmetic functions
+
+ The tables would normally be defined as const arrays,
+ but initialization at run time allows to specify their accuracy.
+*/
+/************************************************************************/
+
+/* 1/x-table: (example for INV_TABLE_BITS 8)
+
+ The table covers an input range from 0.5 to 1.0 with a step size of 1/512,
+ starting at 0.5 + 1/512.
+ Each table entry corresponds to an input interval starting 1/1024 below the
+ exact value and ending 1/1024 above it.
+
+ The table is actually a 0.5/x-table, so that the output range is again
+ 0.5...1.0 and the exponent of the result must be increased by 1.
+
+ Input range Index in table result
+ -------------------------------------------------------------------
+ 0.500000...0.500976 - 0.5 / 0.500000 = 1.000000
+ 0.500976...0.502930 0 0.5 / 0.501953 = 0.996109
+ 0.502930...0.500488 1 0.5 / 0.503906 = 0.992248
+ ...
+ 0.999023...1.000000 255 0.5 / 1.000000 = 0.500000
+
+ for (i=0; i<INV_TABLE_SIZE; i++) {
+ d = 0.5f / ( 0.5f+(double)(i+1)/(INV_TABLE_SIZE*2) ) ;
+ invTable[i] = FL2FX_SGL(d);
+ }
+*/
+const FIXP_SGL FDK_sbrDecoder_invTable[INV_TABLE_SIZE] = {
+ 0x7f80, 0x7f01, 0x7e83, 0x7e07, 0x7d8b, 0x7d11, 0x7c97, 0x7c1e, 0x7ba6,
+ 0x7b2f, 0x7ab9, 0x7a44, 0x79cf, 0x795c, 0x78e9, 0x7878, 0x7807, 0x7796,
+ 0x7727, 0x76b9, 0x764b, 0x75de, 0x7572, 0x7506, 0x749c, 0x7432, 0x73c9,
+ 0x7360, 0x72f9, 0x7292, 0x722c, 0x71c6, 0x7161, 0x70fd, 0x709a, 0x7037,
+ 0x6fd5, 0x6f74, 0x6f13, 0x6eb3, 0x6e54, 0x6df5, 0x6d97, 0x6d39, 0x6cdc,
+ 0x6c80, 0x6c24, 0x6bc9, 0x6b6f, 0x6b15, 0x6abc, 0x6a63, 0x6a0b, 0x69b3,
+ 0x695c, 0x6906, 0x68b0, 0x685a, 0x6806, 0x67b1, 0x675e, 0x670a, 0x66b8,
+ 0x6666, 0x6614, 0x65c3, 0x6572, 0x6522, 0x64d2, 0x6483, 0x6434, 0x63e6,
+ 0x6399, 0x634b, 0x62fe, 0x62b2, 0x6266, 0x621b, 0x61d0, 0x6185, 0x613b,
+ 0x60f2, 0x60a8, 0x6060, 0x6017, 0x5fcf, 0x5f88, 0x5f41, 0x5efa, 0x5eb4,
+ 0x5e6e, 0x5e28, 0x5de3, 0x5d9f, 0x5d5a, 0x5d17, 0x5cd3, 0x5c90, 0x5c4d,
+ 0x5c0b, 0x5bc9, 0x5b87, 0x5b46, 0x5b05, 0x5ac4, 0x5a84, 0x5a44, 0x5a05,
+ 0x59c6, 0x5987, 0x5949, 0x590a, 0x58cd, 0x588f, 0x5852, 0x5815, 0x57d9,
+ 0x579d, 0x5761, 0x5725, 0x56ea, 0x56af, 0x5675, 0x563b, 0x5601, 0x55c7,
+ 0x558e, 0x5555, 0x551c, 0x54e3, 0x54ab, 0x5473, 0x543c, 0x5405, 0x53ce,
+ 0x5397, 0x5360, 0x532a, 0x52f4, 0x52bf, 0x5289, 0x5254, 0x521f, 0x51eb,
+ 0x51b7, 0x5183, 0x514f, 0x511b, 0x50e8, 0x50b5, 0x5082, 0x5050, 0x501d,
+ 0x4feb, 0x4fba, 0x4f88, 0x4f57, 0x4f26, 0x4ef5, 0x4ec4, 0x4e94, 0x4e64,
+ 0x4e34, 0x4e04, 0x4dd5, 0x4da6, 0x4d77, 0x4d48, 0x4d19, 0x4ceb, 0x4cbd,
+ 0x4c8f, 0x4c61, 0x4c34, 0x4c07, 0x4bd9, 0x4bad, 0x4b80, 0x4b54, 0x4b27,
+ 0x4afb, 0x4acf, 0x4aa4, 0x4a78, 0x4a4d, 0x4a22, 0x49f7, 0x49cd, 0x49a2,
+ 0x4978, 0x494e, 0x4924, 0x48fa, 0x48d1, 0x48a7, 0x487e, 0x4855, 0x482d,
+ 0x4804, 0x47dc, 0x47b3, 0x478b, 0x4763, 0x473c, 0x4714, 0x46ed, 0x46c5,
+ 0x469e, 0x4677, 0x4651, 0x462a, 0x4604, 0x45de, 0x45b8, 0x4592, 0x456c,
+ 0x4546, 0x4521, 0x44fc, 0x44d7, 0x44b2, 0x448d, 0x4468, 0x4444, 0x441f,
+ 0x43fb, 0x43d7, 0x43b3, 0x4390, 0x436c, 0x4349, 0x4325, 0x4302, 0x42df,
+ 0x42bc, 0x4299, 0x4277, 0x4254, 0x4232, 0x4210, 0x41ee, 0x41cc, 0x41aa,
+ 0x4189, 0x4167, 0x4146, 0x4125, 0x4104, 0x40e3, 0x40c2, 0x40a1, 0x4081,
+ 0x4060, 0x4040, 0x4020, 0x4000};
diff --git a/fdk-aac/libSBRdec/src/sbr_rom.h b/fdk-aac/libSBRdec/src/sbr_rom.h
new file mode 100644
index 0000000..039743c
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbr_rom.h
@@ -0,0 +1,216 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+\file
+\brief Declaration of constant tables
+*/
+#ifndef SBR_ROM_H
+#define SBR_ROM_H
+
+#include "sbrdecoder.h"
+#include "env_extr.h"
+#include "qmf.h"
+
+#define INV_INT_TABLE_SIZE 49
+#define SBR_NF_NO_RANDOM_VAL \
+ 512 /*!< Size of random number array for noise floor */
+
+/*
+ Frequency scales
+*/
+
+/* if defined(SBRDEC_RATIO_16_64_ENABLE) ((4) = 4) else ((4) = 2) */
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_16[(4) / 2][16];
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_22[(4) / 2][16];
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_24[(4) / 2][16];
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_32[(4) / 2][16];
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_40[(4) / 2][16];
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_44[(4) / 2][16];
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_48[(4) / 2][16];
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_64[(4) / 2][16];
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_88[(4) / 2][16];
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_192[16];
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_176[16];
+extern const UCHAR FDK_sbrDecoder_sbr_start_freq_128[16];
+
+/*
+ Low-Power-Profile Transposer
+*/
+#define NUM_WHFACTOR_TABLE_ENTRIES 9
+extern const USHORT
+ FDK_sbrDecoder_sbr_whFactorsIndex[NUM_WHFACTOR_TABLE_ENTRIES];
+extern const FIXP_DBL
+ FDK_sbrDecoder_sbr_whFactorsTable[NUM_WHFACTOR_TABLE_ENTRIES][6];
+
+/*
+ Envelope Adjustor
+*/
+extern const FIXP_SGL FDK_sbrDecoder_sbr_limGains_m[4];
+extern const UCHAR FDK_sbrDecoder_sbr_limGains_e[4];
+extern const FIXP_SGL FDK_sbrDecoder_sbr_limGainsPvc_m[4];
+extern const UCHAR FDK_sbrDecoder_sbr_limGainsPvc_e[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_randomPhase[SBR_NF_NO_RANDOM_VAL][2];
+
+/*
+ Envelope Extractor
+*/
+extern const int FDK_sbrDecoder_envelopeTable_8[8][5];
+extern const int FDK_sbrDecoder_envelopeTable_15[15][6];
+extern const int FDK_sbrDecoder_envelopeTable_16[16][6];
+extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info1_15;
+extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info2_15;
+extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info4_15;
+extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info8_15;
+extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info1_16;
+extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info2_16;
+extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info4_16;
+extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info8_16;
+
+extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel10T[120][2];
+extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel10F[120][2];
+extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance10T[48][2];
+extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance10F[48][2];
+extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel11T[62][2];
+extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel11F[62][2];
+extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance11T[24][2];
+extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance11F[24][2];
+extern const SCHAR FDK_sbrDecoder_sbr_huffBook_NoiseLevel11T[62][2];
+extern const SCHAR FDK_sbrDecoder_sbr_huffBook_NoiseBalance11T[24][2];
+
+/*
+ Parametric stereo
+*/
+
+/* FIX_BORDER can have 0, 1, 2, 4 envelops */
+extern const UCHAR FDK_sbrDecoder_aFixNoEnvDecode[4];
+
+/* IID & ICC Huffman codebooks */
+extern const SCHAR aBookPsIidTimeDecode[28][2];
+extern const SCHAR aBookPsIidFreqDecode[28][2];
+extern const SCHAR aBookPsIccTimeDecode[14][2];
+extern const SCHAR aBookPsIccFreqDecode[14][2];
+
+/* IID-fine Huffman codebooks */
+
+extern const SCHAR aBookPsIidFineTimeDecode[60][2];
+extern const SCHAR aBookPsIidFineFreqDecode[60][2];
+
+/* the values of the following 3 tables are shiftet right by 1 ! */
+extern const FIXP_DBL ScaleFactors[NO_IID_LEVELS];
+extern const FIXP_DBL ScaleFactorsFine[NO_IID_LEVELS_FINE];
+extern const FIXP_DBL Alphas[NO_ICC_LEVELS];
+
+extern const UCHAR bins2groupMap20[NO_IID_GROUPS];
+extern const UCHAR FDK_sbrDecoder_aNoIidBins[3];
+extern const UCHAR FDK_sbrDecoder_aNoIccBins[3];
+
+/* Lookup tables for some arithmetic functions */
+
+#define INV_TABLE_BITS 8
+#define INV_TABLE_SIZE (1 << INV_TABLE_BITS)
+extern const FIXP_SGL FDK_sbrDecoder_invTable[INV_TABLE_SIZE];
+
+#endif // SBR_ROM_H
diff --git a/fdk-aac/libSBRdec/src/sbrdec_drc.cpp b/fdk-aac/libSBRdec/src/sbrdec_drc.cpp
new file mode 100644
index 0000000..2d73f32
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbrdec_drc.cpp
@@ -0,0 +1,528 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s): Christian Griebel
+
+ Description: Dynamic range control (DRC) decoder tool for SBR
+
+*******************************************************************************/
+
+#include "sbrdec_drc.h"
+
+/* DRC - Offset table for QMF interpolation. Shifted by one index position.
+ The table defines the (short) window borders rounded to the nearest QMF
+ timeslot. It has the size 16 because it is accessed with the
+ drcInterpolationScheme that is read from the bitstream with 4 bit. */
+static const UCHAR winBorderToColMappingTab[2][16] = {
+ /*-1, 0, 1, 2, 3, 4, 5, 6, 7, 8 */
+ {0, 0, 4, 8, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32,
+ 32}, /* 1024 framing */
+ {0, 0, 4, 8, 11, 15, 19, 23, 26, 30, 30, 30, 30, 30, 30,
+ 30} /* 960 framing */
+};
+
+/*!
+ \brief Initialize DRC QMF factors
+
+ \hDrcData Handle to DRC channel data.
+
+ \return none
+*/
+void sbrDecoder_drcInitChannel(HANDLE_SBR_DRC_CHANNEL hDrcData) {
+ int band;
+
+ if (hDrcData == NULL) {
+ return;
+ }
+
+ for (band = 0; band < (64); band++) {
+ hDrcData->prevFact_mag[band] = FL2FXCONST_DBL(0.5f);
+ }
+
+ for (band = 0; band < SBRDEC_MAX_DRC_BANDS; band++) {
+ hDrcData->currFact_mag[band] = FL2FXCONST_DBL(0.5f);
+ hDrcData->nextFact_mag[band] = FL2FXCONST_DBL(0.5f);
+ }
+
+ hDrcData->prevFact_exp = 1;
+ hDrcData->currFact_exp = 1;
+ hDrcData->nextFact_exp = 1;
+
+ hDrcData->numBandsCurr = 1;
+ hDrcData->numBandsNext = 1;
+
+ hDrcData->winSequenceCurr = 0;
+ hDrcData->winSequenceNext = 0;
+
+ hDrcData->drcInterpolationSchemeCurr = 0;
+ hDrcData->drcInterpolationSchemeNext = 0;
+
+ hDrcData->enable = 0;
+}
+
+/*!
+ \brief Swap DRC QMF scaling factors after they have been applied.
+
+ \hDrcData Handle to DRC channel data.
+
+ \return none
+*/
+void sbrDecoder_drcUpdateChannel(HANDLE_SBR_DRC_CHANNEL hDrcData) {
+ if (hDrcData == NULL) {
+ return;
+ }
+ if (hDrcData->enable != 1) {
+ return;
+ }
+
+ /* swap previous data */
+ FDKmemcpy(hDrcData->currFact_mag, hDrcData->nextFact_mag,
+ SBRDEC_MAX_DRC_BANDS * sizeof(FIXP_DBL));
+
+ hDrcData->currFact_exp = hDrcData->nextFact_exp;
+
+ hDrcData->numBandsCurr = hDrcData->numBandsNext;
+
+ FDKmemcpy(hDrcData->bandTopCurr, hDrcData->bandTopNext,
+ SBRDEC_MAX_DRC_BANDS * sizeof(USHORT));
+
+ hDrcData->drcInterpolationSchemeCurr = hDrcData->drcInterpolationSchemeNext;
+
+ hDrcData->winSequenceCurr = hDrcData->winSequenceNext;
+}
+
+/*!
+ \brief Apply DRC factors slot based.
+
+ \hDrcData Handle to DRC channel data.
+ \qmfRealSlot Pointer to real valued QMF data of one time slot.
+ \qmfImagSlot Pointer to the imaginary QMF data of one time slot.
+ \col Number of the time slot.
+ \numQmfSubSamples Total number of time slots for one frame.
+ \scaleFactor Pointer to the out scale factor of the time slot.
+
+ \return None.
+*/
+void sbrDecoder_drcApplySlot(HANDLE_SBR_DRC_CHANNEL hDrcData,
+ FIXP_DBL *qmfRealSlot, FIXP_DBL *qmfImagSlot,
+ int col, int numQmfSubSamples, int maxShift) {
+ const UCHAR *winBorderToColMap;
+
+ int band, bottomMdct, topMdct, bin, useLP;
+ int indx = numQmfSubSamples - (numQmfSubSamples >> 1) - 10; /* l_border */
+ int frameLenFlag = (numQmfSubSamples == 30) ? 1 : 0;
+ int frameSize = (frameLenFlag == 1) ? 960 : 1024;
+
+ const FIXP_DBL *fact_mag = NULL;
+ INT fact_exp = 0;
+ UINT numBands = 0;
+ USHORT *bandTop = NULL;
+ int shortDrc = 0;
+
+ FIXP_DBL alphaValue = FL2FXCONST_DBL(0.0f);
+
+ if (hDrcData == NULL) {
+ return;
+ }
+ if (hDrcData->enable != 1) {
+ return;
+ }
+
+ winBorderToColMap = winBorderToColMappingTab[frameLenFlag];
+
+ useLP = (qmfImagSlot == NULL) ? 1 : 0;
+
+ col += indx;
+ bottomMdct = 0;
+
+ /* get respective data and calc interpolation factor */
+ if (col < (numQmfSubSamples >> 1)) { /* first half of current frame */
+ if (hDrcData->winSequenceCurr != 2) { /* long window */
+ int j = col + (numQmfSubSamples >> 1);
+
+ if (hDrcData->drcInterpolationSchemeCurr == 0) {
+ INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
+
+ alphaValue = (FIXP_DBL)(j * k);
+ } else {
+ if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeCurr]) {
+ alphaValue = (FIXP_DBL)MAXVAL_DBL;
+ }
+ }
+ } else { /* short windows */
+ shortDrc = 1;
+ }
+
+ fact_mag = hDrcData->currFact_mag;
+ fact_exp = hDrcData->currFact_exp;
+ numBands = hDrcData->numBandsCurr;
+ bandTop = hDrcData->bandTopCurr;
+ } else if (col < numQmfSubSamples) { /* second half of current frame */
+ if (hDrcData->winSequenceNext != 2) { /* next: long window */
+ int j = col - (numQmfSubSamples >> 1);
+
+ if (hDrcData->drcInterpolationSchemeNext == 0) {
+ INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
+
+ alphaValue = (FIXP_DBL)(j * k);
+ } else {
+ if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) {
+ alphaValue = (FIXP_DBL)MAXVAL_DBL;
+ }
+ }
+
+ fact_mag = hDrcData->nextFact_mag;
+ fact_exp = hDrcData->nextFact_exp;
+ numBands = hDrcData->numBandsNext;
+ bandTop = hDrcData->bandTopNext;
+ } else { /* next: short windows */
+ if (hDrcData->winSequenceCurr != 2) { /* current: long window */
+ alphaValue = (FIXP_DBL)0;
+
+ fact_mag = hDrcData->nextFact_mag;
+ fact_exp = hDrcData->nextFact_exp;
+ numBands = hDrcData->numBandsNext;
+ bandTop = hDrcData->bandTopNext;
+ } else { /* current: short windows */
+ shortDrc = 1;
+
+ fact_mag = hDrcData->currFact_mag;
+ fact_exp = hDrcData->currFact_exp;
+ numBands = hDrcData->numBandsCurr;
+ bandTop = hDrcData->bandTopCurr;
+ }
+ }
+ } else { /* first half of next frame */
+ if (hDrcData->winSequenceNext != 2) { /* long window */
+ int j = col - (numQmfSubSamples >> 1);
+
+ if (hDrcData->drcInterpolationSchemeNext == 0) {
+ INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
+
+ alphaValue = (FIXP_DBL)(j * k);
+ } else {
+ if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) {
+ alphaValue = (FIXP_DBL)MAXVAL_DBL;
+ }
+ }
+ } else { /* short windows */
+ shortDrc = 1;
+ }
+
+ fact_mag = hDrcData->nextFact_mag;
+ fact_exp = hDrcData->nextFact_exp;
+ numBands = hDrcData->numBandsNext;
+ bandTop = hDrcData->bandTopNext;
+
+ col -= numQmfSubSamples;
+ }
+
+ /* process bands */
+ for (band = 0; band < (int)numBands; band++) {
+ int bottomQmf, topQmf;
+
+ FIXP_DBL drcFact_mag = (FIXP_DBL)MAXVAL_DBL;
+
+ topMdct = (bandTop[band] + 1) << 2;
+
+ if (!shortDrc) { /* long window */
+ if (frameLenFlag) {
+ /* 960 framing */
+ bottomQmf = fMultIfloor((FIXP_DBL)0x4444445, bottomMdct);
+ topQmf = fMultIfloor((FIXP_DBL)0x4444445, topMdct);
+
+ topMdct = 30 * topQmf;
+ } else {
+ /* 1024 framing */
+ topMdct &= ~0x1f;
+
+ bottomQmf = bottomMdct >> 5;
+ topQmf = topMdct >> 5;
+ }
+
+ if (band == ((int)numBands - 1)) {
+ topQmf = (64);
+ }
+
+ for (bin = bottomQmf; bin < topQmf; bin++) {
+ FIXP_DBL drcFact1_mag = hDrcData->prevFact_mag[bin];
+ FIXP_DBL drcFact2_mag = fact_mag[band];
+
+ /* normalize scale factors */
+ if (hDrcData->prevFact_exp < maxShift) {
+ drcFact1_mag >>= maxShift - hDrcData->prevFact_exp;
+ }
+ if (fact_exp < maxShift) {
+ drcFact2_mag >>= maxShift - fact_exp;
+ }
+
+ /* interpolate */
+ if (alphaValue == (FIXP_DBL)0) {
+ drcFact_mag = drcFact1_mag;
+ } else if (alphaValue == (FIXP_DBL)MAXVAL_DBL) {
+ drcFact_mag = drcFact2_mag;
+ } else {
+ drcFact_mag =
+ fMult(alphaValue, drcFact2_mag) +
+ fMult(((FIXP_DBL)MAXVAL_DBL - alphaValue), drcFact1_mag);
+ }
+
+ /* apply scaling */
+ qmfRealSlot[bin] = fMult(qmfRealSlot[bin], drcFact_mag);
+ if (!useLP) {
+ qmfImagSlot[bin] = fMult(qmfImagSlot[bin], drcFact_mag);
+ }
+
+ /* save previous factors */
+ if (col == (numQmfSubSamples >> 1) - 1) {
+ hDrcData->prevFact_mag[bin] = fact_mag[band];
+ }
+ }
+ } else { /* short windows */
+ unsigned startWinIdx, stopWinIdx;
+ int startCol, stopCol;
+ FIXP_DBL invFrameSizeDiv8 =
+ (frameLenFlag) ? (FIXP_DBL)0x1111112 : (FIXP_DBL)0x1000000;
+
+ /* limit top at the frame borders */
+ if (topMdct < 0) {
+ topMdct = 0;
+ }
+ if (topMdct >= frameSize) {
+ topMdct = frameSize - 1;
+ }
+
+ if (frameLenFlag) {
+ /* 960 framing */
+ topMdct = fMultIfloor((FIXP_DBL)0x78000000,
+ fMultIfloor((FIXP_DBL)0x22222223, topMdct) << 2);
+
+ startWinIdx = fMultIfloor(invFrameSizeDiv8, bottomMdct) +
+ 1; /* winBorderToColMap table has offset of 1 */
+ stopWinIdx = fMultIceil(invFrameSizeDiv8 - (FIXP_DBL)1, topMdct) + 1;
+ } else {
+ /* 1024 framing */
+ topMdct &= ~0x03;
+
+ startWinIdx = fMultIfloor(invFrameSizeDiv8, bottomMdct) + 1;
+ stopWinIdx = fMultIceil(invFrameSizeDiv8, topMdct) + 1;
+ }
+
+ /* startCol is truncated to the nearest corresponding start subsample in
+ the QMF of the short window bottom is present in:*/
+ startCol = (int)winBorderToColMap[startWinIdx];
+
+ /* stopCol is rounded upwards to the nearest corresponding stop subsample
+ in the QMF of the short window top is present in. */
+ stopCol = (int)winBorderToColMap[stopWinIdx];
+
+ bottomQmf = fMultIfloor(invFrameSizeDiv8,
+ ((bottomMdct % (numQmfSubSamples << 2)) << 5));
+ topQmf = fMultIfloor(invFrameSizeDiv8,
+ ((topMdct % (numQmfSubSamples << 2)) << 5));
+
+ /* extend last band */
+ if (band == ((int)numBands - 1)) {
+ topQmf = (64);
+ stopCol = numQmfSubSamples;
+ stopWinIdx = 10;
+ }
+
+ if (topQmf == 0) {
+ if (frameLenFlag) {
+ FIXP_DBL rem = fMult(invFrameSizeDiv8,
+ (FIXP_DBL)(topMdct << (DFRACT_BITS - 12)));
+ if ((LONG)rem & (LONG)0x1F) {
+ stopWinIdx -= 1;
+ stopCol = (int)winBorderToColMap[stopWinIdx];
+ }
+ }
+ topQmf = (64);
+ }
+
+ /* save previous factors */
+ if (stopCol == numQmfSubSamples) {
+ int tmpBottom = bottomQmf;
+
+ if ((int)winBorderToColMap[8] > startCol) {
+ tmpBottom = 0; /* band starts in previous short window */
+ }
+
+ for (bin = tmpBottom; bin < topQmf; bin++) {
+ hDrcData->prevFact_mag[bin] = fact_mag[band];
+ }
+ }
+
+ /* apply */
+ if ((col >= startCol) && (col < stopCol)) {
+ if (col >= (int)winBorderToColMap[startWinIdx + 1]) {
+ bottomQmf = 0; /* band starts in previous short window */
+ }
+ if (col < (int)winBorderToColMap[stopWinIdx - 1]) {
+ topQmf = (64); /* band ends in next short window */
+ }
+
+ drcFact_mag = fact_mag[band];
+
+ /* normalize scale factor */
+ if (fact_exp < maxShift) {
+ drcFact_mag >>= maxShift - fact_exp;
+ }
+
+ /* apply scaling */
+ for (bin = bottomQmf; bin < topQmf; bin++) {
+ qmfRealSlot[bin] = fMult(qmfRealSlot[bin], drcFact_mag);
+ if (!useLP) {
+ qmfImagSlot[bin] = fMult(qmfImagSlot[bin], drcFact_mag);
+ }
+ }
+ }
+ }
+
+ bottomMdct = topMdct;
+ } /* end of bands loop */
+
+ if (col == (numQmfSubSamples >> 1) - 1) {
+ hDrcData->prevFact_exp = fact_exp;
+ }
+}
+
+/*!
+ \brief Apply DRC factors frame based.
+
+ \hDrcData Handle to DRC channel data.
+ \qmfRealSlot Pointer to real valued QMF data of the whole frame.
+ \qmfImagSlot Pointer to the imaginary QMF data of the whole frame.
+ \numQmfSubSamples Total number of time slots for one frame.
+ \scaleFactor Pointer to the out scale factor of the frame.
+
+ \return None.
+*/
+void sbrDecoder_drcApply(HANDLE_SBR_DRC_CHANNEL hDrcData,
+ FIXP_DBL **QmfBufferReal, FIXP_DBL **QmfBufferImag,
+ int numQmfSubSamples, int *scaleFactor) {
+ int col;
+ int maxShift = 0;
+
+ if (hDrcData == NULL) {
+ return;
+ }
+ if (hDrcData->enable == 0) {
+ return; /* Avoid changing the scaleFactor even though the processing is
+ disabled. */
+ }
+
+ /* get max scale factor */
+ if (hDrcData->prevFact_exp > maxShift) {
+ maxShift = hDrcData->prevFact_exp;
+ }
+ if (hDrcData->currFact_exp > maxShift) {
+ maxShift = hDrcData->currFact_exp;
+ }
+ if (hDrcData->nextFact_exp > maxShift) {
+ maxShift = hDrcData->nextFact_exp;
+ }
+
+ for (col = 0; col < numQmfSubSamples; col++) {
+ FIXP_DBL *qmfSlotReal = QmfBufferReal[col];
+ FIXP_DBL *qmfSlotImag = (QmfBufferImag == NULL) ? NULL : QmfBufferImag[col];
+
+ sbrDecoder_drcApplySlot(hDrcData, qmfSlotReal, qmfSlotImag, col,
+ numQmfSubSamples, maxShift);
+ }
+
+ *scaleFactor += maxShift;
+}
diff --git a/fdk-aac/libSBRdec/src/sbrdec_drc.h b/fdk-aac/libSBRdec/src/sbrdec_drc.h
new file mode 100644
index 0000000..2eb0e20
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbrdec_drc.h
@@ -0,0 +1,149 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s): Christian Griebel
+
+ Description: Dynamic range control (DRC) decoder tool for SBR
+
+*******************************************************************************/
+
+#ifndef SBRDEC_DRC_H
+#define SBRDEC_DRC_H
+
+#include "sbrdecoder.h"
+
+#define SBRDEC_MAX_DRC_CHANNELS (8)
+#define SBRDEC_MAX_DRC_BANDS (16)
+
+typedef struct {
+ FIXP_DBL prevFact_mag[(64)];
+ INT prevFact_exp;
+
+ FIXP_DBL currFact_mag[SBRDEC_MAX_DRC_BANDS];
+ FIXP_DBL nextFact_mag[SBRDEC_MAX_DRC_BANDS];
+ INT currFact_exp;
+ INT nextFact_exp;
+
+ UINT numBandsCurr;
+ UINT numBandsNext;
+ USHORT bandTopCurr[SBRDEC_MAX_DRC_BANDS];
+ USHORT bandTopNext[SBRDEC_MAX_DRC_BANDS];
+
+ SHORT drcInterpolationSchemeCurr;
+ SHORT drcInterpolationSchemeNext;
+
+ SHORT enable;
+
+ UCHAR winSequenceCurr;
+ UCHAR winSequenceNext;
+
+} SBRDEC_DRC_CHANNEL;
+
+typedef SBRDEC_DRC_CHANNEL *HANDLE_SBR_DRC_CHANNEL;
+
+void sbrDecoder_drcInitChannel(HANDLE_SBR_DRC_CHANNEL hDrcData);
+
+void sbrDecoder_drcUpdateChannel(HANDLE_SBR_DRC_CHANNEL hDrcData);
+
+void sbrDecoder_drcApplySlot(HANDLE_SBR_DRC_CHANNEL hDrcData,
+ FIXP_DBL *qmfRealSlot, FIXP_DBL *qmfImagSlot,
+ int col, int numQmfSubSamples, int maxShift);
+
+void sbrDecoder_drcApply(HANDLE_SBR_DRC_CHANNEL hDrcData,
+ FIXP_DBL **QmfBufferReal, FIXP_DBL **QmfBufferImag,
+ int numQmfSubSamples, int *scaleFactor);
+
+#endif /* SBRDEC_DRC_H */
diff --git a/fdk-aac/libSBRdec/src/sbrdec_freq_sca.cpp b/fdk-aac/libSBRdec/src/sbrdec_freq_sca.cpp
new file mode 100644
index 0000000..165f94b
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbrdec_freq_sca.cpp
@@ -0,0 +1,835 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Frequency scale calculation
+*/
+
+#include "sbrdec_freq_sca.h"
+
+#include "transcendent.h"
+#include "sbr_rom.h"
+#include "env_extr.h"
+
+#include "genericStds.h" /* need log() for debug-code only */
+
+#define MAX_OCTAVE 29
+#define MAX_SECOND_REGION 50
+
+static int numberOfBands(FIXP_SGL bpo_div16, int start, int stop, int warpFlag);
+static void CalcBands(UCHAR *diff, UCHAR start, UCHAR stop, UCHAR num_bands);
+static SBR_ERROR modifyBands(UCHAR max_band, UCHAR *diff, UCHAR length);
+static void cumSum(UCHAR start_value, UCHAR *diff, UCHAR length,
+ UCHAR *start_adress);
+
+/*!
+ \brief Retrieve QMF-band where the SBR range starts
+
+ Convert startFreq which was read from the bitstream into a
+ QMF-channel number.
+
+ \return Number of start band
+*/
+static UCHAR getStartBand(
+ UINT fs, /*!< Output sampling frequency */
+ UCHAR startFreq, /*!< Index to table of possible start bands */
+ UINT headerDataFlags) /*!< Info to SBR mode */
+{
+ INT band;
+ UINT fsMapped = fs;
+ SBR_RATE rate = DUAL;
+
+ if (headerDataFlags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) {
+ if (headerDataFlags & SBRDEC_QUAD_RATE) {
+ rate = QUAD;
+ }
+ fsMapped = sbrdec_mapToStdSampleRate(fs, 1);
+ }
+
+ FDK_ASSERT(2 * (rate + 1) <= (4));
+
+ switch (fsMapped) {
+ case 192000:
+ band = FDK_sbrDecoder_sbr_start_freq_192[startFreq];
+ break;
+ case 176400:
+ band = FDK_sbrDecoder_sbr_start_freq_176[startFreq];
+ break;
+ case 128000:
+ band = FDK_sbrDecoder_sbr_start_freq_128[startFreq];
+ break;
+ case 96000:
+ case 88200:
+ band = FDK_sbrDecoder_sbr_start_freq_88[rate][startFreq];
+ break;
+ case 64000:
+ band = FDK_sbrDecoder_sbr_start_freq_64[rate][startFreq];
+ break;
+ case 48000:
+ band = FDK_sbrDecoder_sbr_start_freq_48[rate][startFreq];
+ break;
+ case 44100:
+ band = FDK_sbrDecoder_sbr_start_freq_44[rate][startFreq];
+ break;
+ case 40000:
+ band = FDK_sbrDecoder_sbr_start_freq_40[rate][startFreq];
+ break;
+ case 32000:
+ band = FDK_sbrDecoder_sbr_start_freq_32[rate][startFreq];
+ break;
+ case 24000:
+ band = FDK_sbrDecoder_sbr_start_freq_24[rate][startFreq];
+ break;
+ case 22050:
+ band = FDK_sbrDecoder_sbr_start_freq_22[rate][startFreq];
+ break;
+ case 16000:
+ band = FDK_sbrDecoder_sbr_start_freq_16[rate][startFreq];
+ break;
+ default:
+ band = 255;
+ }
+
+ return band;
+}
+
+/*!
+ \brief Retrieve QMF-band where the SBR range starts
+
+ Convert startFreq which was read from the bitstream into a
+ QMF-channel number.
+
+ \return Number of start band
+*/
+static UCHAR getStopBand(
+ UINT fs, /*!< Output sampling frequency */
+ UCHAR stopFreq, /*!< Index to table of possible start bands */
+ UINT headerDataFlags, /*!< Info to SBR mode */
+ UCHAR k0) /*!< Start freq index */
+{
+ UCHAR k2;
+
+ if (stopFreq < 14) {
+ INT stopMin;
+ INT num = 2 * (64);
+ UCHAR diff_tot[MAX_OCTAVE + MAX_SECOND_REGION];
+ UCHAR *diff0 = diff_tot;
+ UCHAR *diff1 = diff_tot + MAX_OCTAVE;
+
+ if (headerDataFlags & SBRDEC_QUAD_RATE) {
+ num >>= 1;
+ }
+
+ if (fs < 32000) {
+ stopMin = (((2 * 6000 * num) / fs) + 1) >> 1;
+ } else {
+ if (fs < 64000) {
+ stopMin = (((2 * 8000 * num) / fs) + 1) >> 1;
+ } else {
+ stopMin = (((2 * 10000 * num) / fs) + 1) >> 1;
+ }
+ }
+
+ /*
+ Choose a stop band between k1 and 64 depending on stopFreq (0..13),
+ based on a logarithmic scale.
+ The vectors diff0 and diff1 are used temporarily here.
+ */
+ CalcBands(diff0, stopMin, 64, 13);
+ shellsort(diff0, 13);
+ cumSum(stopMin, diff0, 13, diff1);
+ k2 = diff1[stopFreq];
+ } else if (stopFreq == 14)
+ k2 = 2 * k0;
+ else
+ k2 = 3 * k0;
+
+ /* Limit to Nyquist */
+ if (k2 > (64)) k2 = (64);
+
+ /* Range checks */
+ /* 1 <= difference <= 48; 1 <= fs <= 96000 */
+ {
+ UCHAR max_freq_coeffs = (headerDataFlags & SBRDEC_QUAD_RATE)
+ ? MAX_FREQ_COEFFS_QUAD_RATE
+ : MAX_FREQ_COEFFS;
+ if (((k2 - k0) > max_freq_coeffs) || (k2 <= k0)) {
+ return 255;
+ }
+ }
+
+ if (headerDataFlags & SBRDEC_QUAD_RATE) {
+ return k2; /* skip other checks: (k2 - k0) must be <=
+ MAX_FREQ_COEFFS_QUAD_RATE for all fs */
+ }
+ if (headerDataFlags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) {
+ /* 1 <= difference <= 35; 42000 <= fs <= 96000 */
+ if ((fs >= 42000) && ((k2 - k0) > MAX_FREQ_COEFFS_FS44100)) {
+ return 255;
+ }
+ /* 1 <= difference <= 32; 46009 <= fs <= 96000 */
+ if ((fs >= 46009) && ((k2 - k0) > MAX_FREQ_COEFFS_FS48000)) {
+ return 255;
+ }
+ } else {
+ /* 1 <= difference <= 35; fs == 44100 */
+ if ((fs == 44100) && ((k2 - k0) > MAX_FREQ_COEFFS_FS44100)) {
+ return 255;
+ }
+ /* 1 <= difference <= 32; 48000 <= fs <= 96000 */
+ if ((fs >= 48000) && ((k2 - k0) > MAX_FREQ_COEFFS_FS48000)) {
+ return 255;
+ }
+ }
+
+ return k2;
+}
+
+/*!
+ \brief Generates master frequency tables
+
+ Frequency tables are calculated according to the selected domain
+ (linear/logarithmic) and granularity.
+ IEC 14496-3 4.6.18.3.2.1
+
+ \return errorCode, 0 if successful
+*/
+SBR_ERROR
+sbrdecUpdateFreqScale(
+ UCHAR *v_k_master, /*!< Master table to be created */
+ UCHAR *numMaster, /*!< Number of entries in master table */
+ UINT fs, /*!< SBR working sampling rate */
+ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Control data from bitstream */
+ UINT flags) {
+ FIXP_SGL bpo_div16; /* bands_per_octave divided by 16 */
+ INT dk = 0;
+
+ /* Internal variables */
+ UCHAR k0, k2, i;
+ UCHAR num_bands0 = 0;
+ UCHAR num_bands1 = 0;
+ UCHAR diff_tot[MAX_OCTAVE + MAX_SECOND_REGION];
+ UCHAR *diff0 = diff_tot;
+ UCHAR *diff1 = diff_tot + MAX_OCTAVE;
+ INT k2_achived;
+ INT k2_diff;
+ INT incr = 0;
+
+ /*
+ Determine start band
+ */
+ if (flags & SBRDEC_QUAD_RATE) {
+ fs >>= 1;
+ }
+
+ k0 = getStartBand(fs, hHeaderData->bs_data.startFreq, flags);
+ if (k0 == 255) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ /*
+ Determine stop band
+ */
+ k2 = getStopBand(fs, hHeaderData->bs_data.stopFreq, flags, k0);
+ if (k2 == 255) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ if (hHeaderData->bs_data.freqScale > 0) { /* Bark */
+ INT k1;
+
+ if (hHeaderData->bs_data.freqScale == 1) {
+ bpo_div16 = FL2FXCONST_SGL(12.0f / 16.0f);
+ } else if (hHeaderData->bs_data.freqScale == 2) {
+ bpo_div16 = FL2FXCONST_SGL(10.0f / 16.0f);
+ } else {
+ bpo_div16 = FL2FXCONST_SGL(8.0f / 16.0f);
+ }
+
+ /* Ref: ISO/IEC 23003-3, Figure 12 - Flowchart calculation of fMaster for
+ * 4:1 system when bs_freq_scale > 0 */
+ if (flags & SBRDEC_QUAD_RATE) {
+ if ((SHORT)k0 < (SHORT)(bpo_div16 >> ((FRACT_BITS - 1) - 4))) {
+ bpo_div16 = (FIXP_SGL)(k0 & (UCHAR)0xfe)
+ << ((FRACT_BITS - 1) - 4); /* bpo_div16 = floor(k0/2)*2 */
+ }
+ }
+
+ if (1000 * k2 > 2245 * k0) { /* Two or more regions */
+ k1 = 2 * k0;
+
+ num_bands0 = numberOfBands(bpo_div16, k0, k1, 0);
+ num_bands1 =
+ numberOfBands(bpo_div16, k1, k2, hHeaderData->bs_data.alterScale);
+ if (num_bands0 < 1) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+ if (num_bands1 < 1) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ CalcBands(diff0, k0, k1, num_bands0);
+ shellsort(diff0, num_bands0);
+ if (diff0[0] == 0) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ cumSum(k0, diff0, num_bands0, v_k_master);
+
+ CalcBands(diff1, k1, k2, num_bands1);
+ shellsort(diff1, num_bands1);
+ if (diff0[num_bands0 - 1] > diff1[0]) {
+ SBR_ERROR err;
+
+ err = modifyBands(diff0[num_bands0 - 1], diff1, num_bands1);
+ if (err) return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ /* Add 2nd region */
+ cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]);
+ *numMaster = num_bands0 + num_bands1; /* Output nr of bands */
+
+ } else { /* Only one region */
+ k1 = k2;
+
+ num_bands0 = numberOfBands(bpo_div16, k0, k1, 0);
+ if (num_bands0 < 1) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+ CalcBands(diff0, k0, k1, num_bands0);
+ shellsort(diff0, num_bands0);
+ if (diff0[0] == 0) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ cumSum(k0, diff0, num_bands0, v_k_master);
+ *numMaster = num_bands0; /* Output nr of bands */
+ }
+ } else { /* Linear mode */
+ if (hHeaderData->bs_data.alterScale == 0) {
+ dk = 1;
+ /* FLOOR to get to few number of bands (next lower even number) */
+ num_bands0 = (k2 - k0) & 254;
+ } else {
+ dk = 2;
+ num_bands0 = (((k2 - k0) >> 1) + 1) & 254; /* ROUND to the closest fit */
+ }
+
+ if (num_bands0 < 1) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ /* We must return already here because 'i' can become negative below. */
+ }
+
+ k2_achived = k0 + num_bands0 * dk;
+ k2_diff = k2 - k2_achived;
+
+ for (i = 0; i < num_bands0; i++) diff_tot[i] = dk;
+
+ /* If linear scale wasn't achieved */
+ /* and we got too wide SBR area */
+ if (k2_diff < 0) {
+ incr = 1;
+ i = 0;
+ }
+
+ /* If linear scale wasn't achieved */
+ /* and we got too small SBR area */
+ if (k2_diff > 0) {
+ incr = -1;
+ i = num_bands0 - 1;
+ }
+
+ /* Adjust diff vector to get sepc. SBR range */
+ while (k2_diff != 0) {
+ diff_tot[i] = diff_tot[i] - incr;
+ i = i + incr;
+ k2_diff = k2_diff + incr;
+ }
+
+ cumSum(k0, diff_tot, num_bands0, v_k_master); /* cumsum */
+ *numMaster = num_bands0; /* Output nr of bands */
+ }
+
+ if (*numMaster < 1) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ /* Ref: ISO/IEC 23003-3 Cor.3, "In 7.5.5.2, add to the requirements:"*/
+ if (flags & SBRDEC_QUAD_RATE) {
+ int k;
+ for (k = 1; k < *numMaster; k++) {
+ if (!(v_k_master[k] - v_k_master[k - 1] <= k0 - 2)) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+ }
+ }
+
+ /*
+ Print out the calculated table
+ */
+
+ return SBRDEC_OK;
+}
+
+/*!
+ \brief Calculate frequency ratio of one SBR band
+
+ All SBR bands should span a constant frequency range in the logarithmic
+ domain. This function calculates the ratio of any SBR band's upper and lower
+ frequency.
+
+ \return num_band-th root of k_start/k_stop
+*/
+static FIXP_SGL calcFactorPerBand(int k_start, int k_stop, int num_bands) {
+ /* Scaled bandfactor and step 1 bit right to avoid overflow
+ * use double data type */
+ FIXP_DBL bandfactor = FL2FXCONST_DBL(0.25f); /* Start value */
+ FIXP_DBL step = FL2FXCONST_DBL(0.125f); /* Initial increment for factor */
+
+ int direction = 1;
+
+ /* Because saturation can't be done in INT IIS,
+ * changed start and stop data type from FIXP_SGL to FIXP_DBL */
+ FIXP_DBL start = k_start << (DFRACT_BITS - 8);
+ FIXP_DBL stop = k_stop << (DFRACT_BITS - 8);
+
+ FIXP_DBL temp;
+
+ int j, i = 0;
+
+ while (step > FL2FXCONST_DBL(0.0f)) {
+ i++;
+ temp = stop;
+
+ /* Calculate temp^num_bands: */
+ for (j = 0; j < num_bands; j++)
+ // temp = fMult(temp,bandfactor);
+ temp = fMultDiv2(temp, bandfactor) << 2;
+
+ if (temp < start) { /* Factor too strong, make it weaker */
+ if (direction == 0)
+ /* Halfen step. Right shift is not done as fract because otherwise the
+ lowest bit cannot be cleared due to rounding */
+ step = (FIXP_DBL)((LONG)step >> 1);
+ direction = 1;
+ bandfactor = bandfactor + step;
+ } else { /* Factor is too weak: make it stronger */
+ if (direction == 1) step = (FIXP_DBL)((LONG)step >> 1);
+ direction = 0;
+ bandfactor = bandfactor - step;
+ }
+
+ if (i > 100) {
+ step = FL2FXCONST_DBL(0.0f);
+ }
+ }
+ return FX_DBL2FX_SGL(bandfactor << 1);
+}
+
+/*!
+ \brief Calculate number of SBR bands between start and stop band
+
+ Given the number of bands per octave, this function calculates how many
+ bands fit in the given frequency range.
+ When the warpFlag is set, the 'band density' is decreased by a factor
+ of 1/1.3
+
+ \return number of bands
+*/
+static int numberOfBands(
+ FIXP_SGL bpo_div16, /*!< Input: number of bands per octave divided by 16 */
+ int start, /*!< First QMF band of SBR frequency range */
+ int stop, /*!< Last QMF band of SBR frequency range + 1 */
+ int warpFlag) /*!< Stretching flag */
+{
+ FIXP_SGL num_bands_div128;
+ int num_bands;
+
+ num_bands_div128 =
+ FX_DBL2FX_SGL(fMult(FDK_getNumOctavesDiv8(start, stop), bpo_div16));
+
+ if (warpFlag) {
+ /* Apply the warp factor of 1.3 to get wider bands. We use a value
+ of 32768/25200 instead of the exact value to avoid critical cases
+ of rounding.
+ */
+ num_bands_div128 = FX_DBL2FX_SGL(
+ fMult(num_bands_div128, FL2FXCONST_SGL(25200.0 / 32768.0)));
+ }
+
+ /* add scaled 1 for rounding to even numbers: */
+ num_bands_div128 = num_bands_div128 + FL2FXCONST_SGL(1.0f / 128.0f);
+ /* scale back to right aligned integer and double the value: */
+ num_bands = 2 * ((LONG)num_bands_div128 >> (FRACT_BITS - 7));
+
+ return (num_bands);
+}
+
+/*!
+ \brief Calculate width of SBR bands
+
+ Given the desired number of bands within the SBR frequency range,
+ this function calculates the width of each SBR band in QMF channels.
+ The bands get wider from start to stop (bark scale).
+*/
+static void CalcBands(UCHAR *diff, /*!< Vector of widths to be calculated */
+ UCHAR start, /*!< Lower end of subband range */
+ UCHAR stop, /*!< Upper end of subband range */
+ UCHAR num_bands) /*!< Desired number of bands */
+{
+ int i;
+ int previous;
+ int current;
+ FIXP_SGL exact, temp;
+ FIXP_SGL bandfactor = calcFactorPerBand(start, stop, num_bands);
+
+ previous = stop; /* Start with highest QMF channel */
+ exact = (FIXP_SGL)(
+ stop << (FRACT_BITS - 8)); /* Shift left to gain some accuracy */
+
+ for (i = num_bands - 1; i >= 0; i--) {
+ /* Calculate border of next lower sbr band */
+ exact = FX_DBL2FX_SGL(fMult(exact, bandfactor));
+
+ /* Add scaled 0.5 for rounding:
+ We use a value 128/256 instead of 0.5 to avoid some critical cases of
+ rounding. */
+ temp = exact + FL2FXCONST_SGL(128.0 / 32768.0);
+
+ /* scale back to right alinged integer: */
+ current = (LONG)temp >> (FRACT_BITS - 8);
+
+ /* Save width of band i */
+ diff[i] = previous - current;
+ previous = current;
+ }
+}
+
+/*!
+ \brief Calculate cumulated sum vector from delta vector
+*/
+static void cumSum(UCHAR start_value, UCHAR *diff, UCHAR length,
+ UCHAR *start_adress) {
+ int i;
+ start_adress[0] = start_value;
+ for (i = 1; i <= length; i++)
+ start_adress[i] = start_adress[i - 1] + diff[i - 1];
+}
+
+/*!
+ \brief Adapt width of frequency bands in the second region
+
+ If SBR spans more than 2 octaves, the upper part of a bark-frequency-scale
+ is calculated separately. This function tries to avoid that the second region
+ starts with a band smaller than the highest band of the first region.
+*/
+static SBR_ERROR modifyBands(UCHAR max_band_previous, UCHAR *diff,
+ UCHAR length) {
+ int change = max_band_previous - diff[0];
+
+ /* Limit the change so that the last band cannot get narrower than the first
+ * one */
+ if (change > (diff[length - 1] - diff[0]) >> 1)
+ change = (diff[length - 1] - diff[0]) >> 1;
+
+ diff[0] += change;
+ diff[length - 1] -= change;
+ shellsort(diff, length);
+
+ return SBRDEC_OK;
+}
+
+/*!
+ \brief Update high resolution frequency band table
+*/
+static void sbrdecUpdateHiRes(UCHAR *h_hires, UCHAR *num_hires,
+ UCHAR *v_k_master, UCHAR num_bands,
+ UCHAR xover_band) {
+ UCHAR i;
+
+ *num_hires = num_bands - xover_band;
+
+ for (i = xover_band; i <= num_bands; i++) {
+ h_hires[i - xover_band] = v_k_master[i];
+ }
+}
+
+/*!
+ \brief Build low resolution table out of high resolution table
+*/
+static void sbrdecUpdateLoRes(UCHAR *h_lores, UCHAR *num_lores, UCHAR *h_hires,
+ UCHAR num_hires) {
+ UCHAR i;
+
+ if ((num_hires & 1) == 0) {
+ /* If even number of hires bands */
+ *num_lores = num_hires >> 1;
+ /* Use every second lores=hires[0,2,4...] */
+ for (i = 0; i <= *num_lores; i++) h_lores[i] = h_hires[i * 2];
+ } else {
+ /* Odd number of hires, which means xover is odd */
+ *num_lores = (num_hires + 1) >> 1;
+ /* Use lores=hires[0,1,3,5 ...] */
+ h_lores[0] = h_hires[0];
+ for (i = 1; i <= *num_lores; i++) {
+ h_lores[i] = h_hires[i * 2 - 1];
+ }
+ }
+}
+
+/*!
+ \brief Derive a low-resolution frequency-table from the master frequency
+ table
+*/
+void sbrdecDownSampleLoRes(UCHAR *v_result, UCHAR num_result,
+ UCHAR *freqBandTableRef, UCHAR num_Ref) {
+ int step;
+ int i, j;
+ int org_length, result_length;
+ int v_index[MAX_FREQ_COEFFS >> 1];
+
+ /* init */
+ org_length = num_Ref;
+ result_length = num_result;
+
+ v_index[0] = 0; /* Always use left border */
+ i = 0;
+ while (org_length > 0) {
+ /* Create downsample vector */
+ i++;
+ step = org_length / result_length;
+ org_length = org_length - step;
+ result_length--;
+ v_index[i] = v_index[i - 1] + step;
+ }
+
+ for (j = 0; j <= i; j++) {
+ /* Use downsample vector to index LoResolution vector */
+ v_result[j] = freqBandTableRef[v_index[j]];
+ }
+}
+
+/*!
+ \brief Sorting routine
+*/
+void shellsort(UCHAR *in, UCHAR n) {
+ int i, j, v, w;
+ int inc = 1;
+
+ do
+ inc = 3 * inc + 1;
+ while (inc <= n);
+
+ do {
+ inc = inc / 3;
+ for (i = inc; i < n; i++) {
+ v = in[i];
+ j = i;
+ while ((w = in[j - inc]) > v) {
+ in[j] = w;
+ j -= inc;
+ if (j < inc) break;
+ }
+ in[j] = v;
+ }
+ } while (inc > 1);
+}
+
+/*!
+ \brief Reset frequency band tables
+ \return errorCode, 0 if successful
+*/
+SBR_ERROR
+resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) {
+ SBR_ERROR err = SBRDEC_OK;
+ int k2, kx, lsb, usb;
+ int intTemp;
+ UCHAR nBandsLo, nBandsHi;
+ HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
+
+ /* Calculate master frequency function */
+ err = sbrdecUpdateFreqScale(hFreq->v_k_master, &hFreq->numMaster,
+ hHeaderData->sbrProcSmplRate, hHeaderData, flags);
+
+ if (err || (hHeaderData->bs_info.xover_band > hFreq->numMaster)) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ /* Derive Hiresolution from master frequency function */
+ sbrdecUpdateHiRes(hFreq->freqBandTable[1], &nBandsHi, hFreq->v_k_master,
+ hFreq->numMaster, hHeaderData->bs_info.xover_band);
+ /* Derive Loresolution from Hiresolution */
+ sbrdecUpdateLoRes(hFreq->freqBandTable[0], &nBandsLo, hFreq->freqBandTable[1],
+ nBandsHi);
+
+ hFreq->nSfb[0] = nBandsLo;
+ hFreq->nSfb[1] = nBandsHi;
+
+ /* Check index to freqBandTable[0] */
+ if (!(nBandsLo > 0) ||
+ (nBandsLo > (((hHeaderData->numberOfAnalysisBands == 16)
+ ? MAX_FREQ_COEFFS_QUAD_RATE
+ : MAX_FREQ_COEFFS_DUAL_RATE) >>
+ 1))) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ lsb = hFreq->freqBandTable[0][0];
+ usb = hFreq->freqBandTable[0][nBandsLo];
+
+ /* Check for start frequency border k_x:
+ - ISO/IEC 14496-3 4.6.18.3.6 Requirements
+ - ISO/IEC 23003-3 7.5.5.2 Modifications and additions to the MPEG-4 SBR
+ tool
+ */
+ /* Note that lsb > as hHeaderData->numberOfAnalysisBands is a valid SBR config
+ * for 24 band QMF analysis. */
+ if ((lsb > ((flags & SBRDEC_QUAD_RATE) ? 16 : (32))) || (lsb >= usb)) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ /* Calculate number of noise bands */
+
+ k2 = hFreq->freqBandTable[1][nBandsHi];
+ kx = hFreq->freqBandTable[1][0];
+
+ if (hHeaderData->bs_data.noise_bands == 0) {
+ hFreq->nNfb = 1;
+ } else /* Calculate no of noise bands 1,2 or 3 bands/octave */
+ {
+ /* Fetch number of octaves divided by 32 */
+ intTemp = (LONG)FDK_getNumOctavesDiv8(kx, k2) >> 2;
+
+ /* Integer-Multiplication with number of bands: */
+ intTemp = intTemp * hHeaderData->bs_data.noise_bands;
+
+ /* Add scaled 0.5 for rounding: */
+ intTemp = intTemp + (LONG)FL2FXCONST_SGL(0.5f / 32.0f);
+
+ /* Convert to right-aligned integer: */
+ intTemp = intTemp >> (FRACT_BITS - 1 /*sign*/ - 5 /* rescale */);
+
+ if (intTemp == 0) intTemp = 1;
+
+ hFreq->nNfb = intTemp;
+ }
+
+ hFreq->nInvfBands = hFreq->nNfb;
+
+ if (hFreq->nNfb > MAX_NOISE_COEFFS) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ /* Get noise bands */
+ sbrdecDownSampleLoRes(hFreq->freqBandTableNoise, hFreq->nNfb,
+ hFreq->freqBandTable[0], nBandsLo);
+
+ /* save old highband; required for overlap in usac
+ when headerchange occurs at XVAR and VARX frame; */
+ hFreq->ov_highSubband = hFreq->highSubband;
+
+ hFreq->lowSubband = lsb;
+ hFreq->highSubband = usb;
+
+ return SBRDEC_OK;
+}
diff --git a/fdk-aac/libSBRdec/src/sbrdec_freq_sca.h b/fdk-aac/libSBRdec/src/sbrdec_freq_sca.h
new file mode 100644
index 0000000..7e6b8e8
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbrdec_freq_sca.h
@@ -0,0 +1,127 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Frequency scale prototypes
+*/
+#ifndef SBRDEC_FREQ_SCA_H
+#define SBRDEC_FREQ_SCA_H
+
+#include "sbrdecoder.h"
+#include "env_extr.h"
+
+typedef enum { DUAL, QUAD } SBR_RATE;
+
+SBR_ERROR
+sbrdecUpdateFreqScale(UCHAR *v_k_master, UCHAR *numMaster, UINT fs,
+ HANDLE_SBR_HEADER_DATA headerData, UINT flags);
+
+void sbrdecDownSampleLoRes(UCHAR *v_result, UCHAR num_result,
+ UCHAR *freqBandTableRef, UCHAR num_Ref);
+
+void shellsort(UCHAR *in, UCHAR n);
+
+SBR_ERROR
+resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags);
+
+#endif
diff --git a/fdk-aac/libSBRdec/src/sbrdecoder.cpp b/fdk-aac/libSBRdec/src/sbrdecoder.cpp
new file mode 100644
index 0000000..4bc6f69
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/sbrdecoder.cpp
@@ -0,0 +1,2023 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief SBR decoder frontend
+ This module provides a frontend to the SBR decoder. The function openSBR() is
+ called for initialization. The function sbrDecoder_Apply() is called for each
+ frame. sbr_Apply() will call the required functions to decode the raw SBR data
+ (provided by env_extr.cpp), to decode the envelope data and noise floor levels
+ [decodeSbrData()], and to finally apply SBR to the current frame [sbr_dec()].
+
+ \sa sbrDecoder_Apply(), \ref documentationOverview
+*/
+
+/*!
+ \page documentationOverview Overview of important information resources and
+ source code documentation
+
+ As part of this documentation you can find more extensive descriptions about
+ key concepts and algorithms at the following locations:
+
+ <h2>Programming</h2>
+
+ \li Buffer management: sbrDecoder_Apply() and sbr_dec()
+ \li Internal scale factors to maximize SNR on fixed point processors:
+ #QMF_SCALE_FACTOR \li Special mantissa-exponent format: Created in
+ requantizeEnvelopeData() and used in calculateSbrEnvelope()
+
+ <h2>Algorithmic details</h2>
+ \li About the SBR data format: \ref SBR_HEADER_ELEMENT and \ref
+ SBR_STANDARD_ELEMENT \li Details about the bitstream decoder: env_extr.cpp \li
+ Details about the QMF filterbank and the provided polyphase implementation:
+ qmf_dec.cpp \li Details about the transposer: lpp_tran.cpp \li Details about
+ the envelope adjuster: env_calc.cpp
+
+*/
+
+#include "sbrdecoder.h"
+
+#include "FDK_bitstream.h"
+
+#include "sbrdec_freq_sca.h"
+#include "env_extr.h"
+#include "sbr_dec.h"
+#include "env_dec.h"
+#include "sbr_crc.h"
+#include "sbr_ram.h"
+#include "sbr_rom.h"
+#include "lpp_tran.h"
+#include "transcendent.h"
+
+#include "FDK_crc.h"
+
+#include "sbrdec_drc.h"
+
+#include "psbitdec.h"
+
+/* Decoder library info */
+#define SBRDECODER_LIB_VL0 3
+#define SBRDECODER_LIB_VL1 0
+#define SBRDECODER_LIB_VL2 0
+#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_TIME __TIME__
+#endif
+
+static void setFrameErrorFlag(SBR_DECODER_ELEMENT *pSbrElement, UCHAR value) {
+ if (pSbrElement != NULL) {
+ switch (value) {
+ case FRAME_ERROR_ALLSLOTS:
+ FDKmemset(pSbrElement->frameErrorFlag, FRAME_ERROR,
+ sizeof(pSbrElement->frameErrorFlag));
+ break;
+ default:
+ pSbrElement->frameErrorFlag[pSbrElement->useFrameSlot] = value;
+ }
+ }
+}
+
+static UCHAR getHeaderSlot(UCHAR currentSlot, UCHAR hdrSlotUsage[(1) + 1]) {
+ UINT occupied = 0;
+ int s;
+ UCHAR slot = hdrSlotUsage[currentSlot];
+
+ FDK_ASSERT((1) + 1 < 32);
+
+ for (s = 0; s < (1) + 1; s++) {
+ if ((hdrSlotUsage[s] == slot) && (s != slot)) {
+ occupied = 1;
+ break;
+ }
+ }
+
+ if (occupied) {
+ occupied = 0;
+
+ for (s = 0; s < (1) + 1; s++) {
+ occupied |= 1 << hdrSlotUsage[s];
+ }
+ for (s = 0; s < (1) + 1; s++) {
+ if (!(occupied & 0x1)) {
+ slot = s;
+ break;
+ }
+ occupied >>= 1;
+ }
+ }
+
+ return slot;
+}
+
+static void copySbrHeader(HANDLE_SBR_HEADER_DATA hDst,
+ const HANDLE_SBR_HEADER_DATA hSrc) {
+ /* copy the whole header memory (including pointers) */
+ FDKmemcpy(hDst, hSrc, sizeof(SBR_HEADER_DATA));
+
+ /* update pointers */
+ hDst->freqBandData.freqBandTable[0] = hDst->freqBandData.freqBandTableLo;
+ 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_dflt, &hHdr2->bs_dflt, 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.
+
+ Reset should only be called if SBR has been sucessfully detected by
+ an appropriate checkForPayload() function.
+
+ \return Error code.
+*/
+static SBR_ERROR sbrDecoder_ResetElement(HANDLE_SBRDECODER self,
+ int sampleRateIn, int sampleRateOut,
+ int samplesPerFrame,
+ const MP4_ELEMENT_ID elementID,
+ const int elementIndex,
+ const int overlap) {
+ SBR_ERROR sbrError = SBRDEC_OK;
+ HANDLE_SBR_HEADER_DATA hSbrHeader;
+ UINT qmfFlags = 0;
+
+ int i, synDownsampleFac;
+
+ /* USAC: assuming theoretical case 8 kHz output sample rate with 4:1 SBR */
+ const int sbr_min_sample_rate_in = IS_USAC(self->coreCodec) ? 2000 : 6400;
+
+ /* Check in/out samplerates */
+ if (sampleRateIn < sbr_min_sample_rate_in || sampleRateIn > (96000)) {
+ sbrError = SBRDEC_UNSUPPORTED_CONFIG;
+ goto bail;
+ }
+
+ if (sampleRateOut > (96000)) {
+ sbrError = SBRDEC_UNSUPPORTED_CONFIG;
+ goto bail;
+ }
+
+ /* Set QMF mode flags */
+ if (self->flags & SBRDEC_LOW_POWER) qmfFlags |= QMF_FLAG_LP;
+
+ if (self->coreCodec == AOT_ER_AAC_ELD) {
+ if (self->flags & SBRDEC_LD_MPS_QMF) {
+ qmfFlags |= QMF_FLAG_MPSLDFB;
+ } else {
+ qmfFlags |= QMF_FLAG_CLDFB;
+ }
+ }
+
+ /* Set downsampling factor for synthesis filter bank */
+ if (sampleRateOut == 0) {
+ /* no single rate mode */
+ sampleRateOut =
+ sampleRateIn
+ << 1; /* In case of implicit signalling, assume dual rate SBR */
+ }
+
+ if (sampleRateIn == sampleRateOut) {
+ synDownsampleFac = 2;
+ self->flags |= SBRDEC_DOWNSAMPLE;
+ } else {
+ synDownsampleFac = 1;
+ self->flags &= ~SBRDEC_DOWNSAMPLE;
+ }
+
+ self->synDownsampleFac = synDownsampleFac;
+ self->sampleRateOut = sampleRateOut;
+
+ {
+ for (i = 0; i < (1) + 1; i++) {
+ int setDflt;
+ hSbrHeader = &(self->sbrHeader[elementIndex][i]);
+ setDflt = ((hSbrHeader->syncState == SBR_NOT_INITIALIZED) ||
+ (self->flags & SBRDEC_FORCE_RESET))
+ ? 1
+ : 0;
+
+ /* init a default header such that we can at least do upsampling later */
+ sbrError = initHeaderData(hSbrHeader, sampleRateIn, sampleRateOut,
+ self->downscaleFactor, samplesPerFrame,
+ self->flags, setDflt);
+
+ /* Set synchState to UPSAMPLING in case it already is initialized */
+ hSbrHeader->syncState = hSbrHeader->syncState > UPSAMPLING
+ ? UPSAMPLING
+ : hSbrHeader->syncState;
+ }
+ }
+
+ if (sbrError != SBRDEC_OK) {
+ goto bail;
+ }
+
+ if (!self->pQmfDomain->globalConf.qmfDomainExplicitConfig) {
+ self->pQmfDomain->globalConf.flags_requested |= qmfFlags;
+ self->pQmfDomain->globalConf.nBandsAnalysis_requested =
+ self->sbrHeader[elementIndex][0].numberOfAnalysisBands;
+ self->pQmfDomain->globalConf.nBandsSynthesis_requested =
+ (synDownsampleFac == 1) ? 64 : 32; /* may be overwritten by MPS */
+ self->pQmfDomain->globalConf.nBandsSynthesis_requested /=
+ self->downscaleFactor;
+ self->pQmfDomain->globalConf.nQmfTimeSlots_requested =
+ self->sbrHeader[elementIndex][0].numberTimeSlots *
+ self->sbrHeader[elementIndex][0].timeStep;
+ self->pQmfDomain->globalConf.nQmfOvTimeSlots_requested = overlap;
+ self->pQmfDomain->globalConf.nQmfProcBands_requested = 64; /* always 64 */
+ self->pQmfDomain->globalConf.nQmfProcChannels_requested =
+ 1; /* may be overwritten by MPS */
+ }
+
+ /* Init SBR channels going to be assigned to a SBR element */
+ {
+ int ch;
+ for (ch = 0; ch < self->pSbrElement[elementIndex]->nChannels; ch++) {
+ int headerIndex =
+ getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot,
+ self->pSbrElement[elementIndex]->useHeaderSlot);
+
+ /* and create sbrDec */
+ sbrError =
+ createSbrDec(self->pSbrElement[elementIndex]->pSbrChannel[ch],
+ &self->sbrHeader[elementIndex][headerIndex],
+ &self->pSbrElement[elementIndex]->transposerSettings,
+ synDownsampleFac, qmfFlags, self->flags, overlap, ch,
+ self->codecFrameSize);
+
+ if (sbrError != SBRDEC_OK) {
+ goto bail;
+ }
+ }
+ }
+
+ // FDKmemclear(sbr_OverlapBuffer, sizeof(sbr_OverlapBuffer));
+
+ if (self->numSbrElements == 1) {
+ switch (self->coreCodec) {
+ case AOT_AAC_LC:
+ case AOT_SBR:
+ case AOT_PS:
+ case AOT_ER_AAC_SCAL:
+ case AOT_DRM_AAC:
+ case AOT_DRM_SURROUND:
+ if (CreatePsDec(&self->hParametricStereoDec, samplesPerFrame)) {
+ sbrError = SBRDEC_CREATE_ERROR;
+ goto bail;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Init frame delay slot handling */
+ self->pSbrElement[elementIndex]->useFrameSlot = 0;
+ for (i = 0; i < ((1) + 1); i++) {
+ self->pSbrElement[elementIndex]->useHeaderSlot[i] = i;
+ }
+
+bail:
+
+ return sbrError;
+}
+
+/*!
+ \brief Assign QMF domain provided QMF channels to SBR channels.
+
+ \return void
+*/
+static void sbrDecoder_AssignQmfChannels2SbrChannels(HANDLE_SBRDECODER self) {
+ int ch, el, absCh_offset = 0;
+ for (el = 0; el < self->numSbrElements; el++) {
+ if (self->pSbrElement[el] != NULL) {
+ for (ch = 0; ch < self->pSbrElement[el]->nChannels; ch++) {
+ FDK_ASSERT(((absCh_offset + ch) < ((8) + (1))) &&
+ ((absCh_offset + ch) < ((8) + (1))));
+ self->pSbrElement[el]->pSbrChannel[ch]->SbrDec.qmfDomainInCh =
+ &self->pQmfDomain->QmfDomainIn[absCh_offset + ch];
+ self->pSbrElement[el]->pSbrChannel[ch]->SbrDec.qmfDomainOutCh =
+ &self->pQmfDomain->QmfDomainOut[absCh_offset + ch];
+ }
+ absCh_offset += self->pSbrElement[el]->nChannels;
+ }
+ }
+}
+
+SBR_ERROR sbrDecoder_Open(HANDLE_SBRDECODER *pSelf,
+ HANDLE_FDK_QMF_DOMAIN pQmfDomain) {
+ HANDLE_SBRDECODER self = NULL;
+ SBR_ERROR sbrError = SBRDEC_OK;
+ int elIdx;
+
+ if ((pSelf == NULL) || (pQmfDomain == NULL)) {
+ return SBRDEC_INVALID_ARGUMENT;
+ }
+
+ /* Get memory for this instance */
+ self = GetRam_SbrDecoder();
+ if (self == NULL) {
+ sbrError = SBRDEC_MEM_ALLOC_FAILED;
+ goto bail;
+ }
+
+ self->pQmfDomain = pQmfDomain;
+
+ /*
+ Already zero because of calloc
+ self->numSbrElements = 0;
+ self->numSbrChannels = 0;
+ self->codecFrameSize = 0;
+ */
+
+ self->numDelayFrames = (1); /* set to the max value by default */
+
+ /* Initialize header sync state */
+ for (elIdx = 0; elIdx < (8); elIdx += 1) {
+ int i;
+ for (i = 0; i < (1) + 1; i += 1) {
+ self->sbrHeader[elIdx][i].syncState = SBR_NOT_INITIALIZED;
+ }
+ }
+
+ *pSelf = self;
+
+bail:
+ return sbrError;
+}
+
+/**
+ * \brief determine if the given core codec AOT can be processed or not.
+ * \param coreCodec core codec audio object type.
+ * \return 1 if SBR can be processed, 0 if SBR cannot be processed/applied.
+ */
+static int sbrDecoder_isCoreCodecValid(AUDIO_OBJECT_TYPE coreCodec) {
+ switch (coreCodec) {
+ case AOT_AAC_LC:
+ case AOT_SBR:
+ case AOT_PS:
+ case AOT_ER_AAC_SCAL:
+ case AOT_ER_AAC_ELD:
+ case AOT_DRM_AAC:
+ case AOT_DRM_SURROUND:
+ case AOT_USAC:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static void sbrDecoder_DestroyElement(HANDLE_SBRDECODER self,
+ const int elementIndex) {
+ if (self->pSbrElement[elementIndex] != NULL) {
+ int ch;
+
+ for (ch = 0; ch < SBRDEC_MAX_CH_PER_ELEMENT; ch++) {
+ if (self->pSbrElement[elementIndex]->pSbrChannel[ch] != NULL) {
+ deleteSbrDec(self->pSbrElement[elementIndex]->pSbrChannel[ch]);
+ FreeRam_SbrDecChannel(
+ &self->pSbrElement[elementIndex]->pSbrChannel[ch]);
+ self->numSbrChannels -= 1;
+ }
+ }
+ FreeRam_SbrDecElement(&self->pSbrElement[elementIndex]);
+ self->numSbrElements -= 1;
+ }
+}
+
+SBR_ERROR sbrDecoder_InitElement(
+ HANDLE_SBRDECODER self, const int sampleRateIn, const int sampleRateOut,
+ const int samplesPerFrame, const AUDIO_OBJECT_TYPE coreCodec,
+ const MP4_ELEMENT_ID elementID, const int elementIndex,
+ const UCHAR harmonicSBR, const UCHAR stereoConfigIndex,
+ const UCHAR configMode, UCHAR *configChanged, const INT downscaleFactor) {
+ SBR_ERROR sbrError = SBRDEC_OK;
+ int chCnt = 0;
+ int nSbrElementsStart;
+ int nSbrChannelsStart;
+ if (self == NULL) {
+ return SBRDEC_INVALID_ARGUMENT;
+ }
+
+ nSbrElementsStart = self->numSbrElements;
+ nSbrChannelsStart = self->numSbrChannels;
+
+ /* Check core codec AOT */
+ if (!sbrDecoder_isCoreCodecValid(coreCodec) || elementIndex >= (8)) {
+ sbrError = SBRDEC_UNSUPPORTED_CONFIG;
+ goto bail;
+ }
+
+ if (elementID != ID_SCE && elementID != ID_CPE && elementID != ID_LFE) {
+ sbrError = SBRDEC_UNSUPPORTED_CONFIG;
+ goto bail;
+ }
+
+ if (self->sampleRateIn == sampleRateIn &&
+ self->codecFrameSize == samplesPerFrame && self->coreCodec == coreCodec &&
+ self->pSbrElement[elementIndex] != NULL &&
+ self->pSbrElement[elementIndex]->elementID == elementID &&
+ !(self->flags & SBRDEC_FORCE_RESET) &&
+ ((sampleRateOut == 0) ? 1 : (self->sampleRateOut == sampleRateOut)) &&
+ ((harmonicSBR == 2) ? 1
+ : (self->harmonicSBR ==
+ harmonicSBR)) /* The value 2 signalizes that
+ harmonicSBR shall be ignored in
+ the config change detection */
+ ) {
+ /* Nothing to do */
+ return SBRDEC_OK;
+ } else {
+ if (configMode & AC_CM_DET_CFG_CHANGE) {
+ *configChanged = 1;
+ }
+ }
+
+ /* reaching this point the SBR-decoder gets (re-)configured */
+
+ /* The flags field is used for all elements! */
+ self->flags &=
+ (SBRDEC_FORCE_RESET | SBRDEC_FLUSH); /* Keep the global flags. They will
+ be reset after decoding. */
+ self->flags |= (downscaleFactor > 1) ? SBRDEC_ELD_DOWNSCALE : 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;
+ self->flags |= (coreCodec == AOT_DRM_SURROUND)
+ ? SBRDEC_SYNTAX_SCAL | SBRDEC_SYNTAX_DRM
+ : 0;
+ self->flags |= (coreCodec == AOT_USAC) ? SBRDEC_SYNTAX_USAC : 0;
+ /* Robustness: Take integer division rounding into consideration. E.g. 22050
+ * Hz with 4:1 SBR => 5512 Hz core sampling rate. */
+ self->flags |= (sampleRateIn == sampleRateOut / 4) ? SBRDEC_QUAD_RATE : 0;
+ self->flags |= (harmonicSBR == 1) ? SBRDEC_USAC_HARMONICSBR : 0;
+
+ if (configMode & AC_CM_DET_CFG_CHANGE) {
+ return SBRDEC_OK;
+ }
+
+ self->sampleRateIn = sampleRateIn;
+ self->codecFrameSize = samplesPerFrame;
+ self->coreCodec = coreCodec;
+ self->harmonicSBR = harmonicSBR;
+ self->downscaleFactor = downscaleFactor;
+
+ /* Init SBR elements */
+ {
+ int elChannels, ch;
+
+ if (self->pSbrElement[elementIndex] == NULL) {
+ self->pSbrElement[elementIndex] = GetRam_SbrDecElement(elementIndex);
+ if (self->pSbrElement[elementIndex] == NULL) {
+ sbrError = SBRDEC_MEM_ALLOC_FAILED;
+ goto bail;
+ }
+ self->numSbrElements++;
+ } else {
+ self->numSbrChannels -= self->pSbrElement[elementIndex]->nChannels;
+ }
+
+ /* Save element ID for sanity checks and to have a fallback for concealment.
+ */
+ self->pSbrElement[elementIndex]->elementID = elementID;
+
+ /* Determine amount of channels for this element */
+ switch (elementID) {
+ case ID_NONE:
+ case ID_CPE:
+ elChannels = 2;
+ break;
+ case ID_LFE:
+ case ID_SCE:
+ elChannels = 1;
+ break;
+ default:
+ elChannels = 0;
+ break;
+ }
+
+ /* Handle case of Parametric Stereo */
+ if (elementIndex == 0 && elementID == ID_SCE) {
+ switch (coreCodec) {
+ case AOT_AAC_LC:
+ case AOT_SBR:
+ case AOT_PS:
+ case AOT_ER_AAC_SCAL:
+ case AOT_DRM_AAC:
+ case AOT_DRM_SURROUND:
+ elChannels = 2;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Sanity check to avoid memory leaks */
+ if (elChannels < self->pSbrElement[elementIndex]->nChannels) {
+ self->numSbrChannels += self->pSbrElement[elementIndex]->nChannels;
+ sbrError = SBRDEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ self->pSbrElement[elementIndex]->nChannels = elChannels;
+
+ for (ch = 0; ch < elChannels; ch++) {
+ if (self->pSbrElement[elementIndex]->pSbrChannel[ch] == NULL) {
+ self->pSbrElement[elementIndex]->pSbrChannel[ch] =
+ GetRam_SbrDecChannel(chCnt);
+ if (self->pSbrElement[elementIndex]->pSbrChannel[ch] == NULL) {
+ sbrError = SBRDEC_MEM_ALLOC_FAILED;
+ goto bail;
+ }
+ }
+ self->numSbrChannels++;
+
+ sbrDecoder_drcInitChannel(&self->pSbrElement[elementIndex]
+ ->pSbrChannel[ch]
+ ->SbrDec.sbrDrcChannel);
+
+ chCnt++;
+ }
+ }
+
+ if (!self->pQmfDomain->globalConf.qmfDomainExplicitConfig) {
+ self->pQmfDomain->globalConf.nInputChannels_requested =
+ self->numSbrChannels;
+ self->pQmfDomain->globalConf.nOutputChannels_requested =
+ fMax((INT)self->numSbrChannels,
+ (INT)self->pQmfDomain->globalConf.nOutputChannels_requested);
+ }
+
+ /* Make sure each SBR channel has one QMF channel assigned even if
+ * numSbrChannels or element set-up has changed. */
+ sbrDecoder_AssignQmfChannels2SbrChannels(self);
+
+ /* clear error flags for all delay slots */
+ FDKmemclear(self->pSbrElement[elementIndex]->frameErrorFlag,
+ ((1) + 1) * sizeof(UCHAR));
+
+ {
+ int overlap;
+
+ if (coreCodec == AOT_ER_AAC_ELD) {
+ overlap = 0;
+ } else if (self->flags & SBRDEC_QUAD_RATE) {
+ overlap = (3 * 4);
+ } else {
+ overlap = (3 * 2);
+ }
+ /* Initialize this instance */
+ sbrError = sbrDecoder_ResetElement(self, sampleRateIn, sampleRateOut,
+ samplesPerFrame, elementID, elementIndex,
+ overlap);
+ }
+
+bail:
+ if (sbrError != SBRDEC_OK) {
+ if ((nSbrElementsStart < self->numSbrElements) ||
+ (nSbrChannelsStart < self->numSbrChannels)) {
+ /* Free the memory allocated for this element */
+ sbrDecoder_DestroyElement(self, elementIndex);
+ } else if ((elementIndex < (8)) &&
+ (self->pSbrElement[elementIndex] !=
+ NULL)) { /* Set error flag to trigger concealment */
+ setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR);
+ }
+ }
+
+ return sbrError;
+}
+
+/**
+ * \brief Free config dependent SBR memory.
+ * \param self SBR decoder instance handle
+ */
+SBR_ERROR sbrDecoder_FreeMem(HANDLE_SBRDECODER *self) {
+ int i;
+ int elIdx;
+
+ if (self != NULL && *self != NULL) {
+ for (i = 0; i < (8); i++) {
+ sbrDecoder_DestroyElement(*self, i);
+ }
+
+ for (elIdx = 0; elIdx < (8); elIdx += 1) {
+ for (i = 0; i < (1) + 1; i += 1) {
+ (*self)->sbrHeader[elIdx][i].syncState = SBR_NOT_INITIALIZED;
+ }
+ }
+ }
+
+ return SBRDEC_OK;
+}
+
+/**
+ * \brief Apply decoded SBR header for one element.
+ * \param self SBR decoder instance handle
+ * \param hSbrHeader SBR header handle to be processed.
+ * \param hSbrChannel pointer array to the SBR element channels corresponding to
+ * the SBR header.
+ * \param headerStatus header status value returned from SBR header parser.
+ * \param numElementChannels amount of channels for the SBR element whos header
+ * is to be processed.
+ */
+static SBR_ERROR sbrDecoder_HeaderUpdate(HANDLE_SBRDECODER self,
+ HANDLE_SBR_HEADER_DATA hSbrHeader,
+ SBR_HEADER_STATUS headerStatus,
+ HANDLE_SBR_CHANNEL hSbrChannel[],
+ const int numElementChannels) {
+ SBR_ERROR errorStatus = SBRDEC_OK;
+
+ /*
+ change of control data, reset decoder
+ */
+ errorStatus = resetFreqBandTables(hSbrHeader, self->flags);
+
+ if (errorStatus == SBRDEC_OK) {
+ if (hSbrHeader->syncState == UPSAMPLING && headerStatus != HEADER_RESET) {
+#if (SBRDEC_MAX_HB_FADE_FRAMES > 0)
+ int ch;
+ for (ch = 0; ch < numElementChannels; ch += 1) {
+ hSbrChannel[ch]->SbrDec.highBandFadeCnt = SBRDEC_MAX_HB_FADE_FRAMES;
+ }
+
+#endif
+ /* As the default header would limit the frequency range,
+ lowSubband and highSubband must be patched. */
+ hSbrHeader->freqBandData.lowSubband = hSbrHeader->numberOfAnalysisBands;
+ hSbrHeader->freqBandData.highSubband = hSbrHeader->numberOfAnalysisBands;
+ }
+
+ /* Trigger a reset before processing this slot */
+ hSbrHeader->status |= SBRDEC_HDR_STAT_RESET;
+ }
+
+ return errorStatus;
+}
+
+INT sbrDecoder_Header(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
+ const INT sampleRateIn, const INT sampleRateOut,
+ const INT samplesPerFrame,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const MP4_ELEMENT_ID elementID, const INT elementIndex,
+ const UCHAR harmonicSBR, const UCHAR stereoConfigIndex,
+ const UCHAR configMode, UCHAR *configChanged,
+ const INT downscaleFactor) {
+ SBR_HEADER_STATUS headerStatus;
+ HANDLE_SBR_HEADER_DATA hSbrHeader;
+ SBR_ERROR sbrError = SBRDEC_OK;
+ int headerIndex;
+ UINT flagsSaved =
+ 0; /* flags should not be changed in AC_CM_DET_CFG_CHANGE - mode after
+ parsing */
+
+ if (self == NULL || elementIndex >= (8)) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ if (!sbrDecoder_isCoreCodecValid(coreCodec)) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ if (configMode & AC_CM_DET_CFG_CHANGE) {
+ flagsSaved = self->flags; /* store */
+ }
+
+ sbrError = sbrDecoder_InitElement(
+ self, sampleRateIn, sampleRateOut, samplesPerFrame, coreCodec, elementID,
+ elementIndex, harmonicSBR, stereoConfigIndex, configMode, configChanged,
+ downscaleFactor);
+
+ if ((sbrError != SBRDEC_OK) || (elementID == ID_LFE)) {
+ goto bail;
+ }
+
+ if (configMode & AC_CM_DET_CFG_CHANGE) {
+ hSbrHeader = NULL;
+ } else {
+ headerIndex = getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot,
+ self->pSbrElement[elementIndex]->useHeaderSlot);
+
+ hSbrHeader = &(self->sbrHeader[elementIndex][headerIndex]);
+ }
+
+ headerStatus = sbrGetHeaderData(hSbrHeader, hBs, self->flags, 0, configMode);
+
+ if (coreCodec == AOT_USAC) {
+ if (configMode & AC_CM_DET_CFG_CHANGE) {
+ self->flags = flagsSaved; /* restore */
+ }
+ return sbrError;
+ }
+
+ if (configMode & AC_CM_ALLOC_MEM) {
+ SBR_DECODER_ELEMENT *pSbrElement;
+
+ pSbrElement = self->pSbrElement[elementIndex];
+
+ /* Sanity check */
+ if (pSbrElement != NULL) {
+ if ((elementID == ID_CPE && pSbrElement->nChannels != 2) ||
+ (elementID != ID_CPE && pSbrElement->nChannels != 1)) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+ if (headerStatus == HEADER_RESET) {
+ sbrError = sbrDecoder_HeaderUpdate(self, hSbrHeader, headerStatus,
+ pSbrElement->pSbrChannel,
+ pSbrElement->nChannels);
+
+ if (sbrError == SBRDEC_OK) {
+ hSbrHeader->syncState = SBR_HEADER;
+ hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE;
+ }
+ /* else {
+ Since we already have overwritten the old SBR header the only way out
+ is UPSAMPLING! This will be prepared in the next step.
+ } */
+ }
+ }
+ }
+bail:
+ if (configMode & AC_CM_DET_CFG_CHANGE) {
+ self->flags = flagsSaved; /* restore */
+ }
+ return sbrError;
+}
+
+SBR_ERROR sbrDecoder_SetParam(HANDLE_SBRDECODER self, const SBRDEC_PARAM param,
+ const INT value) {
+ SBR_ERROR errorStatus = SBRDEC_OK;
+
+ /* configure the subsystems */
+ switch (param) {
+ case SBR_SYSTEM_BITSTREAM_DELAY:
+ if (value < 0 || value > (1)) {
+ errorStatus = SBRDEC_SET_PARAM_FAIL;
+ break;
+ }
+ if (self == NULL) {
+ errorStatus = SBRDEC_NOT_INITIALIZED;
+ } else {
+ self->numDelayFrames = (UCHAR)value;
+ }
+ break;
+ case SBR_QMF_MODE:
+ if (self == NULL) {
+ errorStatus = SBRDEC_NOT_INITIALIZED;
+ } else {
+ if (value == 1) {
+ self->flags |= SBRDEC_LOW_POWER;
+ } else {
+ self->flags &= ~SBRDEC_LOW_POWER;
+ }
+ }
+ break;
+ case SBR_LD_QMF_TIME_ALIGN:
+ if (self == NULL) {
+ errorStatus = SBRDEC_NOT_INITIALIZED;
+ } else {
+ if (value == 1) {
+ self->flags |= SBRDEC_LD_MPS_QMF;
+ } else {
+ self->flags &= ~SBRDEC_LD_MPS_QMF;
+ }
+ }
+ break;
+ case SBR_FLUSH_DATA:
+ if (value != 0) {
+ if (self == NULL) {
+ errorStatus = SBRDEC_NOT_INITIALIZED;
+ } else {
+ self->flags |= SBRDEC_FLUSH;
+ }
+ }
+ break;
+ case SBR_CLEAR_HISTORY:
+ if (value != 0) {
+ if (self == NULL) {
+ errorStatus = SBRDEC_NOT_INITIALIZED;
+ } else {
+ self->flags |= SBRDEC_FORCE_RESET;
+ }
+ }
+ break;
+ case SBR_BS_INTERRUPTION: {
+ int elementIndex;
+
+ if (self == NULL) {
+ errorStatus = SBRDEC_NOT_INITIALIZED;
+ break;
+ }
+
+ /* Loop over SBR elements */
+ for (elementIndex = 0; elementIndex < self->numSbrElements;
+ elementIndex++) {
+ if (self->pSbrElement[elementIndex] != NULL) {
+ HANDLE_SBR_HEADER_DATA hSbrHeader;
+ int headerIndex =
+ getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot,
+ self->pSbrElement[elementIndex]->useHeaderSlot);
+
+ hSbrHeader = &(self->sbrHeader[elementIndex][headerIndex]);
+
+ /* Set sync state UPSAMPLING for the corresponding slot.
+ This switches off bitstream parsing until a new header arrives. */
+ hSbrHeader->syncState = UPSAMPLING;
+ hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE;
+ }
+ }
+ } break;
+
+ case SBR_SKIP_QMF:
+ if (self == NULL) {
+ errorStatus = SBRDEC_NOT_INITIALIZED;
+ } else {
+ if (value == 1) {
+ self->flags |= SBRDEC_SKIP_QMF_ANA;
+ } else {
+ self->flags &= ~SBRDEC_SKIP_QMF_ANA;
+ }
+ if (value == 2) {
+ self->flags |= SBRDEC_SKIP_QMF_SYN;
+ } else {
+ self->flags &= ~SBRDEC_SKIP_QMF_SYN;
+ }
+ }
+ break;
+ default:
+ errorStatus = SBRDEC_SET_PARAM_FAIL;
+ break;
+ } /* switch(param) */
+
+ return (errorStatus);
+}
+
+static SBRDEC_DRC_CHANNEL *sbrDecoder_drcGetChannel(
+ const HANDLE_SBRDECODER self, const INT channel) {
+ SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;
+ int elementIndex, elChanIdx = 0, numCh = 0;
+
+ for (elementIndex = 0; (elementIndex < (8)) && (numCh <= channel);
+ elementIndex++) {
+ SBR_DECODER_ELEMENT *pSbrElement = self->pSbrElement[elementIndex];
+ int c, elChannels;
+
+ elChanIdx = 0;
+ if (pSbrElement == NULL) break;
+
+ /* Determine amount of channels for this element */
+ switch (pSbrElement->elementID) {
+ case ID_CPE:
+ elChannels = 2;
+ break;
+ case ID_LFE:
+ case ID_SCE:
+ elChannels = 1;
+ break;
+ case ID_NONE:
+ default:
+ elChannels = 0;
+ break;
+ }
+
+ /* Limit with actual allocated element channels */
+ elChannels = fMin(elChannels, pSbrElement->nChannels);
+
+ for (c = 0; (c < elChannels) && (numCh <= channel); c++) {
+ if (pSbrElement->pSbrChannel[elChanIdx] != NULL) {
+ numCh++;
+ elChanIdx++;
+ }
+ }
+ }
+ elementIndex -= 1;
+ elChanIdx -= 1;
+
+ if (elChanIdx < 0 || elementIndex < 0) {
+ return NULL;
+ }
+
+ if (self->pSbrElement[elementIndex] != NULL) {
+ if (self->pSbrElement[elementIndex]->pSbrChannel[elChanIdx] != NULL) {
+ pSbrDrcChannelData = &self->pSbrElement[elementIndex]
+ ->pSbrChannel[elChanIdx]
+ ->SbrDec.sbrDrcChannel;
+ }
+ }
+
+ return (pSbrDrcChannelData);
+}
+
+SBR_ERROR sbrDecoder_drcFeedChannel(HANDLE_SBRDECODER self, INT ch,
+ UINT numBands, FIXP_DBL *pNextFact_mag,
+ INT nextFact_exp,
+ SHORT drcInterpolationScheme,
+ UCHAR winSequence, USHORT *pBandTop) {
+ SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;
+ int band, isValidData = 0;
+
+ if (self == NULL) {
+ return SBRDEC_NOT_INITIALIZED;
+ }
+ if (ch > (8) || pNextFact_mag == NULL) {
+ return SBRDEC_SET_PARAM_FAIL;
+ }
+
+ /* Search for gain values different to 1.0f */
+ for (band = 0; band < (int)numBands; band += 1) {
+ if (!((pNextFact_mag[band] == FL2FXCONST_DBL(0.5)) &&
+ (nextFact_exp == 1)) &&
+ !((pNextFact_mag[band] == (FIXP_DBL)MAXVAL_DBL) &&
+ (nextFact_exp == 0))) {
+ isValidData = 1;
+ break;
+ }
+ }
+
+ /* Find the right SBR channel */
+ pSbrDrcChannelData = sbrDecoder_drcGetChannel(self, ch);
+
+ if (pSbrDrcChannelData != NULL) {
+ if (pSbrDrcChannelData->enable ||
+ isValidData) { /* Activate processing only with real and valid data */
+ int i;
+
+ pSbrDrcChannelData->enable = 1;
+ pSbrDrcChannelData->numBandsNext = numBands;
+
+ pSbrDrcChannelData->winSequenceNext = winSequence;
+ pSbrDrcChannelData->drcInterpolationSchemeNext = drcInterpolationScheme;
+ pSbrDrcChannelData->nextFact_exp = nextFact_exp;
+
+ for (i = 0; i < (int)numBands; i++) {
+ pSbrDrcChannelData->bandTopNext[i] = pBandTop[i];
+ pSbrDrcChannelData->nextFact_mag[i] = pNextFact_mag[i];
+ }
+ }
+ }
+
+ return SBRDEC_OK;
+}
+
+void sbrDecoder_drcDisable(HANDLE_SBRDECODER self, INT ch) {
+ SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;
+
+ if ((self == NULL) || (ch > (8)) || (self->numSbrElements == 0) ||
+ (self->numSbrChannels == 0)) {
+ return;
+ }
+
+ /* Find the right SBR channel */
+ pSbrDrcChannelData = sbrDecoder_drcGetChannel(self, ch);
+
+ if (pSbrDrcChannelData != NULL) {
+ sbrDecoder_drcInitChannel(pSbrDrcChannelData);
+ }
+}
+
+SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
+ UCHAR *pDrmBsBuffer, USHORT drmBsBufferSize,
+ int *count, int bsPayLen, int crcFlag,
+ MP4_ELEMENT_ID prevElement, int elementIndex,
+ UINT acFlags, UINT acElFlags[]) {
+ SBR_DECODER_ELEMENT *hSbrElement = NULL;
+ HANDLE_SBR_HEADER_DATA hSbrHeader = NULL;
+ HANDLE_SBR_CHANNEL *pSbrChannel;
+
+ SBR_FRAME_DATA *hFrameDataLeft = NULL;
+ SBR_FRAME_DATA *hFrameDataRight = NULL;
+ SBR_FRAME_DATA frameDataLeftCopy;
+ SBR_FRAME_DATA frameDataRightCopy;
+
+ SBR_ERROR errorStatus = SBRDEC_OK;
+ SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT;
+
+ INT startPos = FDKgetValidBits(hBs);
+ INT CRCLen = 0;
+ HANDLE_FDK_BITSTREAM hBsOriginal = hBs;
+ FDK_BITSTREAM bsBwd;
+
+ FDK_CRCINFO crcInfo;
+ INT crcReg = 0;
+ USHORT drmSbrCrc = 0;
+ const int fGlobalIndependencyFlag = acFlags & AC_INDEP;
+ const int bs_pvc = acElFlags[elementIndex] & AC_EL_USAC_PVC;
+ const int bs_interTes = acElFlags[elementIndex] & AC_EL_USAC_ITES;
+ int stereo;
+ int fDoDecodeSbrData = 1;
+
+ int lastSlot, lastHdrSlot = 0, thisHdrSlot = 0;
+
+ if (*count <= 0) {
+ setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR);
+ return SBRDEC_OK;
+ }
+
+ /* SBR sanity checks */
+ if (self == NULL) {
+ errorStatus = SBRDEC_NOT_INITIALIZED;
+ goto bail;
+ }
+
+ /* Reverse bits of DRM SBR payload */
+ if ((self->flags & SBRDEC_SYNTAX_DRM) && *count > 0) {
+ int dataBytes, dataBits;
+
+ FDK_ASSERT(drmBsBufferSize >= (512));
+ 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;
+ }
+ pDrmBsBuffer[j++] = buffer;
+ FDKpushBack(hBs, 16);
+ }
+
+ FDKinitBitStream(&bsBwd, pDrmBsBuffer, (512), dataBits, BS_READER);
+
+ /* Use reversed data */
+ hBs = &bsBwd;
+ bsPayLen = *count;
+ }
+
+ /* Remember start position of SBR element */
+ startPos = FDKgetValidBits(hBs);
+
+ /* SBR sanity checks */
+ if (self->pSbrElement[elementIndex] == NULL) {
+ errorStatus = SBRDEC_NOT_INITIALIZED;
+ goto bail;
+ }
+ hSbrElement = self->pSbrElement[elementIndex];
+
+ lastSlot = (hSbrElement->useFrameSlot > 0) ? hSbrElement->useFrameSlot - 1
+ : self->numDelayFrames;
+ lastHdrSlot = hSbrElement->useHeaderSlot[lastSlot];
+ thisHdrSlot = getHeaderSlot(
+ hSbrElement->useFrameSlot,
+ hSbrElement->useHeaderSlot); /* Get a free header slot not used by
+ frames not processed yet. */
+
+ /* Assign the free slot to store a new header if there is one. */
+ hSbrHeader = &self->sbrHeader[elementIndex][thisHdrSlot];
+
+ pSbrChannel = hSbrElement->pSbrChannel;
+ stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0;
+
+ hFrameDataLeft = &self->pSbrElement[elementIndex]
+ ->pSbrChannel[0]
+ ->frameData[hSbrElement->useFrameSlot];
+ if (stereo) {
+ hFrameDataRight = &self->pSbrElement[elementIndex]
+ ->pSbrChannel[1]
+ ->frameData[hSbrElement->useFrameSlot];
+ }
+
+ /* store frameData; new parsed frameData possibly corrupted */
+ FDKmemcpy(&frameDataLeftCopy, hFrameDataLeft, sizeof(SBR_FRAME_DATA));
+ if (stereo) {
+ FDKmemcpy(&frameDataRightCopy, hFrameDataRight, sizeof(SBR_FRAME_DATA));
+ }
+
+ /* reset PS flag; will be set after PS was found */
+ self->flags &= ~SBRDEC_PS_DECODED;
+
+ if (hSbrHeader->status & SBRDEC_HDR_STAT_UPDATE) {
+ /* Got a new header from extern (e.g. from an ASC) */
+ headerStatus = HEADER_OK;
+ hSbrHeader->status &= ~SBRDEC_HDR_STAT_UPDATE;
+ } else if (thisHdrSlot != lastHdrSlot) {
+ /* Copy the last header into this slot otherwise the
+ header compare will trigger more HEADER_RESETs than needed. */
+ copySbrHeader(hSbrHeader, &self->sbrHeader[elementIndex][lastHdrSlot]);
+ }
+
+ /*
+ Check if bit stream data is valid and matches the element context
+ */
+ if (((prevElement != ID_SCE) && (prevElement != ID_CPE)) ||
+ prevElement != hSbrElement->elementID) {
+ /* In case of LFE we also land here, since there is no LFE SBR element (do
+ * upsampling only) */
+ fDoDecodeSbrData = 0;
+ }
+
+ if (fDoDecodeSbrData) {
+ if ((INT)FDKgetValidBits(hBs) <= 0) {
+ fDoDecodeSbrData = 0;
+ }
+ }
+
+ /*
+ SBR CRC-check
+ */
+ if (fDoDecodeSbrData) {
+ if (crcFlag) {
+ switch (self->coreCodec) {
+ case AOT_ER_AAC_ELD:
+ FDKpushFor(hBs, 10);
+ /* check sbrcrc later: we don't know the payload length now */
+ break;
+ case AOT_DRM_AAC:
+ case AOT_DRM_SURROUND:
+ drmSbrCrc = (USHORT)FDKreadBits(hBs, 8);
+ /* Setup CRC decoder */
+ FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8);
+ /* Start CRC region */
+ crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
+ break;
+ default:
+ CRCLen = bsPayLen - 10; /* change: 0 => i */
+ if (CRCLen < 0) {
+ fDoDecodeSbrData = 0;
+ } else {
+ fDoDecodeSbrData = SbrCrcCheck(hBs, CRCLen);
+ }
+ break;
+ }
+ }
+ } /* if (fDoDecodeSbrData) */
+
+ /*
+ Read in the header data and issue a reset if change occured
+ */
+ if (fDoDecodeSbrData) {
+ int sbrHeaderPresent;
+
+ if (self->flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC)) {
+ SBR_HEADER_DATA_BS_INFO newSbrInfo;
+ int sbrInfoPresent;
+
+ if (bs_interTes) {
+ self->flags |= SBRDEC_USAC_ITES;
+ } else {
+ self->flags &= ~SBRDEC_USAC_ITES;
+ }
+
+ if (fGlobalIndependencyFlag) {
+ self->flags |= SBRDEC_USAC_INDEP;
+ sbrInfoPresent = 1;
+ sbrHeaderPresent = 1;
+ } else {
+ self->flags &= ~SBRDEC_USAC_INDEP;
+ sbrInfoPresent = FDKreadBit(hBs);
+ if (sbrInfoPresent) {
+ sbrHeaderPresent = FDKreadBit(hBs);
+ } else {
+ sbrHeaderPresent = 0;
+ }
+ }
+
+ if (sbrInfoPresent) {
+ newSbrInfo.ampResolution = FDKreadBit(hBs);
+ newSbrInfo.xover_band = FDKreadBits(hBs, 4);
+ newSbrInfo.sbr_preprocessing = FDKreadBit(hBs);
+ if (bs_pvc) {
+ newSbrInfo.pvc_mode = FDKreadBits(hBs, 2);
+ /* bs_pvc_mode: 0 -> no PVC, 1 -> PVC mode 1, 2 -> PVC mode 2, 3 ->
+ * reserved */
+ if (newSbrInfo.pvc_mode > 2) {
+ headerStatus = HEADER_ERROR;
+ }
+ if (stereo && newSbrInfo.pvc_mode > 0) {
+ /* bs_pvc is always transmitted but pvc_mode is set to zero in case
+ * of stereo SBR. The config might be wrong but we cannot tell for
+ * sure. */
+ newSbrInfo.pvc_mode = 0;
+ }
+ } else {
+ newSbrInfo.pvc_mode = 0;
+ }
+ if (headerStatus != HEADER_ERROR) {
+ if (FDKmemcmp(&hSbrHeader->bs_info, &newSbrInfo,
+ sizeof(SBR_HEADER_DATA_BS_INFO))) {
+ /* in case of ampResolution and preprocessing change no full reset
+ * required */
+ /* HEADER reset would trigger HBE transposer reset which breaks
+ * eSbr_3_Eaa.mp4 */
+ if ((hSbrHeader->bs_info.pvc_mode != newSbrInfo.pvc_mode) ||
+ (hSbrHeader->bs_info.xover_band != newSbrInfo.xover_band)) {
+ headerStatus = HEADER_RESET;
+ } else {
+ headerStatus = HEADER_OK;
+ }
+
+ hSbrHeader->bs_info = newSbrInfo;
+ } else {
+ headerStatus = HEADER_OK;
+ }
+ }
+ }
+ if (headerStatus == HEADER_ERROR) {
+ /* Corrupt SBR info data, do not decode and switch to UPSAMPLING */
+ hSbrHeader->syncState = UPSAMPLING;
+ fDoDecodeSbrData = 0;
+ sbrHeaderPresent = 0;
+ }
+
+ if (sbrHeaderPresent && fDoDecodeSbrData) {
+ int useDfltHeader;
+
+ useDfltHeader = FDKreadBit(hBs);
+
+ if (useDfltHeader) {
+ sbrHeaderPresent = 0;
+ if (FDKmemcmp(&hSbrHeader->bs_data, &hSbrHeader->bs_dflt,
+ sizeof(SBR_HEADER_DATA_BS)) ||
+ hSbrHeader->syncState != SBR_ACTIVE) {
+ hSbrHeader->bs_data = hSbrHeader->bs_dflt;
+ headerStatus = HEADER_RESET;
+ }
+ }
+ }
+ } else {
+ sbrHeaderPresent = FDKreadBit(hBs);
+ }
+
+ if (sbrHeaderPresent) {
+ headerStatus = sbrGetHeaderData(hSbrHeader, hBs, self->flags, 1, 0);
+ }
+
+ if (headerStatus == HEADER_RESET) {
+ errorStatus = sbrDecoder_HeaderUpdate(
+ self, hSbrHeader, headerStatus, pSbrChannel, hSbrElement->nChannels);
+
+ if (errorStatus == SBRDEC_OK) {
+ hSbrHeader->syncState = SBR_HEADER;
+ } else {
+ hSbrHeader->syncState = SBR_NOT_INITIALIZED;
+ headerStatus = HEADER_ERROR;
+ }
+ }
+
+ if (errorStatus != SBRDEC_OK) {
+ fDoDecodeSbrData = 0;
+ }
+ } /* if (fDoDecodeSbrData) */
+
+ /*
+ Print debugging output only if state has changed
+ */
+
+ /* read frame data */
+ if ((hSbrHeader->syncState >= SBR_HEADER) && fDoDecodeSbrData) {
+ int sbrFrameOk;
+ /* read the SBR element data */
+ if (!stereo && (self->hParametricStereoDec != NULL)) {
+ /* update slot index for PS bitstream parsing */
+ self->hParametricStereoDec->bsLastSlot =
+ self->hParametricStereoDec->bsReadSlot;
+ self->hParametricStereoDec->bsReadSlot = hSbrElement->useFrameSlot;
+ }
+ sbrFrameOk = sbrGetChannelElement(
+ hSbrHeader, hFrameDataLeft, (stereo) ? hFrameDataRight : NULL,
+ &pSbrChannel[0]->prevFrameData,
+ pSbrChannel[0]->SbrDec.PvcStaticData.pvc_mode_last, hBs,
+ (stereo) ? NULL : self->hParametricStereoDec, self->flags,
+ self->pSbrElement[elementIndex]->transposerSettings.overlap);
+
+ if (!sbrFrameOk) {
+ fDoDecodeSbrData = 0;
+ } else {
+ INT valBits;
+
+ if (bsPayLen > 0) {
+ valBits = bsPayLen - ((INT)startPos - (INT)FDKgetValidBits(hBs));
+ } else {
+ valBits = (INT)FDKgetValidBits(hBs);
+ }
+
+ if (crcFlag) {
+ switch (self->coreCodec) {
+ case AOT_ER_AAC_ELD: {
+ /* late crc check for eld */
+ INT payloadbits =
+ (INT)startPos - (INT)FDKgetValidBits(hBs) - startPos;
+ INT crcLen = payloadbits - 10;
+ FDKpushBack(hBs, payloadbits);
+ fDoDecodeSbrData = SbrCrcCheck(hBs, crcLen);
+ FDKpushFor(hBs, crcLen);
+ } break;
+ case AOT_DRM_AAC:
+ case AOT_DRM_SURROUND:
+ /* End CRC region */
+ FDKcrcEndReg(&crcInfo, hBs, crcReg);
+ /* Check CRC */
+ if ((FDKcrcGetCRC(&crcInfo) ^ 0xFF) != drmSbrCrc) {
+ fDoDecodeSbrData = 0;
+ if (headerStatus != HEADER_NOT_PRESENT) {
+ headerStatus = HEADER_ERROR;
+ hSbrHeader->syncState = SBR_NOT_INITIALIZED;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* sanity check of remaining bits */
+ if (valBits < 0) {
+ fDoDecodeSbrData = 0;
+ } else {
+ switch (self->coreCodec) {
+ case AOT_SBR:
+ case AOT_PS:
+ case AOT_AAC_LC: {
+ /* This sanity check is only meaningful with General Audio
+ * bitstreams */
+ int alignBits = valBits & 0x7;
+
+ if (valBits > alignBits) {
+ fDoDecodeSbrData = 0;
+ }
+ } break;
+ default:
+ /* No sanity check available */
+ break;
+ }
+ }
+ }
+ } else {
+ /* The returned bit count will not be the actual payload size since we did
+ not parse the frame data. Return an error so that the caller can react
+ respectively. */
+ errorStatus = SBRDEC_PARSE_ERROR;
+ }
+
+ if (!fDoDecodeSbrData) {
+ /* Set error flag for this slot to trigger concealment */
+ setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR);
+ /* restore old frameData for concealment */
+ FDKmemcpy(hFrameDataLeft, &frameDataLeftCopy, sizeof(SBR_FRAME_DATA));
+ if (stereo) {
+ FDKmemcpy(hFrameDataRight, &frameDataRightCopy, sizeof(SBR_FRAME_DATA));
+ }
+ errorStatus = SBRDEC_PARSE_ERROR;
+ } else {
+ /* Everything seems to be ok so clear the error flag */
+ setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_OK);
+ }
+
+ if (!stereo) {
+ /* Turn coupling off explicitely to avoid access to absent right frame data
+ that might occur with corrupt bitstreams. */
+ hFrameDataLeft->coupling = COUPLING_OFF;
+ }
+
+bail:
+
+ if (self != NULL) {
+ if (self->flags & SBRDEC_SYNTAX_DRM) {
+ hBs = hBsOriginal;
+ }
+
+ if (errorStatus != SBRDEC_NOT_INITIALIZED) {
+ int useOldHdr =
+ ((headerStatus == HEADER_NOT_PRESENT) ||
+ (headerStatus == HEADER_ERROR) ||
+ (headerStatus == HEADER_RESET && errorStatus == SBRDEC_PARSE_ERROR))
+ ? 1
+ : 0;
+
+ if (!useOldHdr && (thisHdrSlot != lastHdrSlot) && (hSbrHeader != NULL)) {
+ useOldHdr |=
+ (compareSbrHeader(hSbrHeader,
+ &self->sbrHeader[elementIndex][lastHdrSlot]) == 0)
+ ? 1
+ : 0;
+ }
+
+ if (hSbrElement != NULL) {
+ if (useOldHdr != 0) {
+ /* Use the old header for this frame */
+ hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot;
+ } else {
+ /* Use the new header for this frame */
+ hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = thisHdrSlot;
+ }
+
+ /* Move frame pointer to the next slot which is up to be decoded/applied
+ * next */
+ hSbrElement->useFrameSlot =
+ (hSbrElement->useFrameSlot + 1) % (self->numDelayFrames + 1);
+ }
+ }
+ }
+
+ *count -= startPos - (INT)FDKgetValidBits(hBs);
+
+ return errorStatus;
+}
+
+/**
+ * \brief Render one SBR element into time domain signal.
+ * \param self SBR decoder handle
+ * \param timeData pointer to output buffer
+ * \param channelMapping pointer to UCHAR array where next 2 channel offsets are
+ * stored.
+ * \param elementIndex enumerating index of the SBR element to render.
+ * \param numInChannels number of channels from core coder.
+ * \param numOutChannels pointer to a location to return number of output
+ * channels.
+ * \param psPossible flag indicating if PS is possible or not.
+ * \return SBRDEC_OK if successfull, else error code
+ */
+static SBR_ERROR sbrDecoder_DecodeElement(
+ HANDLE_SBRDECODER self, QDOM_PCM *input, INT_PCM *timeData,
+ const int timeDataSize, const FDK_channelMapDescr *const mapDescr,
+ const int mapIdx, int channelIndex, const int elementIndex,
+ const int numInChannels, int *numOutChannels, const int psPossible) {
+ SBR_DECODER_ELEMENT *hSbrElement = self->pSbrElement[elementIndex];
+ HANDLE_SBR_CHANNEL *pSbrChannel =
+ self->pSbrElement[elementIndex]->pSbrChannel;
+ HANDLE_SBR_HEADER_DATA hSbrHeader =
+ &self->sbrHeader[elementIndex]
+ [hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]];
+ HANDLE_PS_DEC h_ps_d = self->hParametricStereoDec;
+
+ /* get memory for frame data from scratch */
+ SBR_FRAME_DATA *hFrameDataLeft = NULL;
+ SBR_FRAME_DATA *hFrameDataRight = NULL;
+
+ SBR_ERROR errorStatus = SBRDEC_OK;
+
+ INT strideOut, offset0 = 255, offset0_block = 0, offset1 = 255,
+ offset1_block = 0;
+ INT codecFrameSize = self->codecFrameSize;
+
+ int stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0;
+ int numElementChannels =
+ hSbrElement
+ ->nChannels; /* Number of channels of the current SBR element */
+
+ hFrameDataLeft =
+ &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
+ if (stereo) {
+ hFrameDataRight =
+ &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
+ }
+
+ if (self->flags & SBRDEC_FLUSH) {
+ if (self->numFlushedFrames > self->numDelayFrames) {
+ int hdrIdx;
+ /* No valid SBR payload available, hence switch to upsampling (in all
+ * headers) */
+ for (hdrIdx = 0; hdrIdx < ((1) + 1); hdrIdx += 1) {
+ self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING;
+ }
+ } 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];
+ if (stereo) {
+ hFrameDataRight =
+ &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
+ }
+ }
+ }
+
+ /* Update the header error flag */
+ hSbrHeader->frameErrorFlag =
+ hSbrElement->frameErrorFlag[hSbrElement->useFrameSlot];
+
+ /*
+ Prepare filterbank for upsampling if no valid bit stream data is available.
+ */
+ if (hSbrHeader->syncState == SBR_NOT_INITIALIZED) {
+ errorStatus =
+ initHeaderData(hSbrHeader, self->sampleRateIn, self->sampleRateOut,
+ self->downscaleFactor, codecFrameSize, self->flags,
+ 1 /* SET_DEFAULT_HDR */
+ );
+
+ if (errorStatus != SBRDEC_OK) {
+ return errorStatus;
+ }
+
+ hSbrHeader->syncState = UPSAMPLING;
+
+ errorStatus = sbrDecoder_HeaderUpdate(self, hSbrHeader, HEADER_NOT_PRESENT,
+ pSbrChannel, hSbrElement->nChannels);
+
+ if (errorStatus != SBRDEC_OK) {
+ hSbrHeader->syncState = SBR_NOT_INITIALIZED;
+ return errorStatus;
+ }
+ }
+
+ /* reset */
+ if (hSbrHeader->status & SBRDEC_HDR_STAT_RESET) {
+ int ch;
+ int applySbrProc = (hSbrHeader->syncState == SBR_ACTIVE ||
+ (hSbrHeader->frameErrorFlag == 0 &&
+ hSbrHeader->syncState == SBR_HEADER));
+ for (ch = 0; ch < numElementChannels; ch++) {
+ SBR_ERROR errorStatusTmp = SBRDEC_OK;
+
+ errorStatusTmp = resetSbrDec(
+ &pSbrChannel[ch]->SbrDec, hSbrHeader, &pSbrChannel[ch]->prevFrameData,
+ self->synDownsampleFac, self->flags, pSbrChannel[ch]->frameData);
+
+ if (errorStatusTmp != SBRDEC_OK) {
+ hSbrHeader->syncState = UPSAMPLING;
+ }
+ }
+ if (applySbrProc) {
+ hSbrHeader->status &= ~SBRDEC_HDR_STAT_RESET;
+ }
+ }
+
+ /* decoding */
+ if ((hSbrHeader->syncState == SBR_ACTIVE) ||
+ ((hSbrHeader->syncState == SBR_HEADER) &&
+ (hSbrHeader->frameErrorFlag == 0))) {
+ errorStatus = SBRDEC_OK;
+
+ decodeSbrData(hSbrHeader, hFrameDataLeft, &pSbrChannel[0]->prevFrameData,
+ (stereo) ? hFrameDataRight : NULL,
+ (stereo) ? &pSbrChannel[1]->prevFrameData : NULL);
+
+ /* Now we have a full parameter set and can do parameter
+ based concealment instead of plain upsampling. */
+ hSbrHeader->syncState = SBR_ACTIVE;
+ }
+
+ if (timeDataSize <
+ hSbrHeader->numberTimeSlots * hSbrHeader->timeStep *
+ self->pQmfDomain->globalConf.nBandsSynthesis *
+ (psPossible ? fMax(2, numInChannels) : numInChannels)) {
+ return SBRDEC_OUTPUT_BUFFER_TOO_SMALL;
+ }
+
+ {
+ self->flags &= ~SBRDEC_PS_DECODED;
+ C_ALLOC_SCRATCH_START(pPsScratch, struct PS_DEC_COEFFICIENTS, 1)
+
+ /* decode PS data if available */
+ if (h_ps_d != NULL && psPossible && (hSbrHeader->syncState == SBR_ACTIVE)) {
+ int applyPs = 1;
+
+ /* define which frame delay line slot to process */
+ h_ps_d->processSlot = hSbrElement->useFrameSlot;
+
+ applyPs = DecodePs(h_ps_d, hSbrHeader->frameErrorFlag, pPsScratch);
+ self->flags |= (applyPs) ? SBRDEC_PS_DECODED : 0;
+ }
+
+ offset0 = FDK_chMapDescr_getMapValue(mapDescr, channelIndex, mapIdx);
+ offset0_block = offset0 * codecFrameSize;
+ if (stereo || psPossible) {
+ /* the value of offset1 only matters if the condition is true, however if
+ it is not true channelIndex+1 may exceed the channel map resutling in an
+ error, though the value of offset1 is actually meaningless. This is
+ prevented here. */
+ offset1 = FDK_chMapDescr_getMapValue(mapDescr, channelIndex + 1, mapIdx);
+ offset1_block = offset1 * codecFrameSize;
+ }
+ /* Set strides for reading and writing */
+ if (psPossible)
+ strideOut = (numInChannels < 2) ? 2 : numInChannels;
+ else
+ strideOut = numInChannels;
+
+ /* use same buffers for left and right channel and apply PS per timeslot */
+ /* Process left channel */
+ sbr_dec(&pSbrChannel[0]->SbrDec, input + offset0_block, timeData + offset0,
+ (self->flags & SBRDEC_PS_DECODED) ? &pSbrChannel[1]->SbrDec : NULL,
+ timeData + offset1, strideOut, hSbrHeader, hFrameDataLeft,
+ &pSbrChannel[0]->prevFrameData,
+ (hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, self->flags,
+ codecFrameSize);
+
+ if (stereo) {
+ /* Process right channel */
+ sbr_dec(&pSbrChannel[1]->SbrDec, input + offset1_block,
+ timeData + offset1, NULL, NULL, strideOut, hSbrHeader,
+ hFrameDataRight, &pSbrChannel[1]->prevFrameData,
+ (hSbrHeader->syncState == SBR_ACTIVE), NULL, self->flags,
+ codecFrameSize);
+ }
+
+ C_ALLOC_SCRATCH_END(pPsScratch, struct PS_DEC_COEFFICIENTS, 1)
+ }
+
+ if (h_ps_d != NULL) {
+ /* save PS status for next run */
+ h_ps_d->psDecodedPrv = (self->flags & SBRDEC_PS_DECODED) ? 1 : 0;
+ }
+
+ if (psPossible && !(self->flags & SBRDEC_SKIP_QMF_SYN)) {
+ FDK_ASSERT(strideOut > 1);
+ 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 available. */
+ /* So copy left channel to right channel. */
+ int copyFrameSize =
+ codecFrameSize * self->pQmfDomain->QmfDomainOut->fb.no_channels;
+ copyFrameSize /= self->pQmfDomain->QmfDomainIn->fb.no_channels;
+ INT_PCM *ptr;
+ INT i;
+ FDK_ASSERT(strideOut == 2);
+
+ ptr = timeData;
+ for (i = copyFrameSize >> 1; i--;) {
+ 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;
+ }
+ }
+ *numOutChannels = 2; /* Output minimum two channels when PS is enabled. */
+ }
+
+ return errorStatus;
+}
+
+SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
+ INT_PCM *timeData, const int timeDataSize,
+ int *numChannels, int *sampleRate,
+ const FDK_channelMapDescr *const mapDescr,
+ const int mapIdx, const int coreDecodedOk,
+ UCHAR *psDecoded) {
+ SBR_ERROR errorStatus = SBRDEC_OK;
+
+ int psPossible;
+ int sbrElementNum;
+ int numCoreChannels;
+ int numSbrChannels = 0;
+
+ if ((self == NULL) || (timeData == NULL) || (numChannels == NULL) ||
+ (sampleRate == NULL) || (psDecoded == NULL) ||
+ !FDK_chMapDescr_isValid(mapDescr)) {
+ return SBRDEC_INVALID_ARGUMENT;
+ }
+
+ psPossible = *psDecoded;
+ numCoreChannels = *numChannels;
+ if (numCoreChannels <= 0) {
+ return SBRDEC_INVALID_ARGUMENT;
+ }
+
+ if (self->numSbrElements < 1) {
+ /* exit immediately to avoid access violations */
+ return SBRDEC_NOT_INITIALIZED;
+ }
+
+ /* Sanity check of allocated SBR elements. */
+ for (sbrElementNum = 0; sbrElementNum < self->numSbrElements;
+ sbrElementNum++) {
+ if (self->pSbrElement[sbrElementNum] == NULL) {
+ return SBRDEC_NOT_INITIALIZED;
+ }
+ }
+
+ if (self->numSbrElements != 1 || self->pSbrElement[0]->elementID != ID_SCE) {
+ psPossible = 0;
+ }
+
+ /* Make sure that even if no SBR data was found/parsed *psDecoded is returned
+ * 1 if psPossible was 0. */
+ if (psPossible == 0) {
+ self->flags &= ~SBRDEC_PS_DECODED;
+ }
+
+ /* replaces channel based reset inside sbr_dec() */
+ if (((self->flags & SBRDEC_LOW_POWER) ? 1 : 0) !=
+ ((self->pQmfDomain->globalConf.flags & QMF_FLAG_LP) ? 1 : 0)) {
+ if (self->flags & SBRDEC_LOW_POWER) {
+ self->pQmfDomain->globalConf.flags |= QMF_FLAG_LP;
+ self->pQmfDomain->globalConf.flags_requested |= QMF_FLAG_LP;
+ } else {
+ self->pQmfDomain->globalConf.flags &= ~QMF_FLAG_LP;
+ self->pQmfDomain->globalConf.flags_requested &= ~QMF_FLAG_LP;
+ }
+ if (FDK_QmfDomain_InitFilterBank(self->pQmfDomain, QMF_FLAG_KEEP_STATES)) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+ }
+ if (self->numSbrChannels > self->pQmfDomain->globalConf.nInputChannels) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
+ 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 */
+ for (sbrElementNum = 0; sbrElementNum < self->numSbrElements;
+ sbrElementNum++) {
+ int numElementChan;
+
+ if (psPossible &&
+ self->pSbrElement[sbrElementNum]->pSbrChannel[1] == NULL) {
+ /* Disable PS and try decoding SBR mono. */
+ psPossible = 0;
+ }
+
+ numElementChan =
+ (self->pSbrElement[sbrElementNum]->elementID == ID_CPE) ? 2 : 1;
+
+ /* If core signal is bad then force upsampling */
+ if (!coreDecodedOk) {
+ setFrameErrorFlag(self->pSbrElement[sbrElementNum], FRAME_ERROR_ALLSLOTS);
+ }
+
+ errorStatus = sbrDecoder_DecodeElement(
+ self, input, timeData, timeDataSize, mapDescr, mapIdx, numSbrChannels,
+ sbrElementNum,
+ numCoreChannels, /* is correct even for USC SCI==2 case */
+ &numElementChan, psPossible);
+
+ if (errorStatus != SBRDEC_OK) {
+ goto bail;
+ }
+
+ numSbrChannels += numElementChan;
+
+ if (numSbrChannels >= numCoreChannels) {
+ break;
+ }
+ }
+
+ /* Update numChannels and samplerate */
+ /* Do not mess with output channels in case of USAC. numSbrChannels !=
+ * numChannels for stereoConfigIndex == 2 */
+ if (!(self->flags & SBRDEC_SYNTAX_USAC)) {
+ *numChannels = numSbrChannels;
+ }
+ *sampleRate = self->sampleRateOut;
+ *psDecoded = (self->flags & SBRDEC_PS_DECODED) ? 1 : 0;
+
+ /* Clear reset and flush flag because everything seems to be done
+ * successfully. */
+ self->flags &= ~SBRDEC_FORCE_RESET;
+ self->flags &= ~SBRDEC_FLUSH;
+
+bail:
+
+ return errorStatus;
+}
+
+SBR_ERROR sbrDecoder_Close(HANDLE_SBRDECODER *pSelf) {
+ HANDLE_SBRDECODER self = *pSelf;
+ int i;
+
+ if (self != NULL) {
+ if (self->hParametricStereoDec != NULL) {
+ DeletePsDec(&self->hParametricStereoDec);
+ }
+
+ for (i = 0; i < (8); i++) {
+ sbrDecoder_DestroyElement(self, i);
+ }
+
+ FreeRam_SbrDecoder(pSelf);
+ }
+
+ return SBRDEC_OK;
+}
+
+INT sbrDecoder_GetLibInfo(LIB_INFO *info) {
+ int i;
+
+ if (info == NULL) {
+ return -1;
+ }
+
+ /* search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) return -1;
+ info += i;
+
+ info->module_id = FDK_SBRDEC;
+ info->version =
+ LIB_VERSION(SBRDECODER_LIB_VL0, SBRDECODER_LIB_VL1, SBRDECODER_LIB_VL2);
+ LIB_VERSION_STRING(info);
+ info->build_date = SBRDECODER_LIB_BUILD_DATE;
+ info->build_time = SBRDECODER_LIB_BUILD_TIME;
+ info->title = SBRDECODER_LIB_TITLE;
+
+ /* Set flags */
+ info->flags = 0 | CAPF_SBR_HQ | CAPF_SBR_LP | CAPF_SBR_PS_MPEG |
+ CAPF_SBR_DRM_BS | CAPF_SBR_CONCEALMENT | CAPF_SBR_DRC |
+ CAPF_SBR_ELD_DOWNSCALE | CAPF_SBR_HBEHQ;
+ /* End of flags */
+
+ return 0;
+}
+
+UINT sbrDecoder_GetDelay(const HANDLE_SBRDECODER self) {
+ UINT outputDelay = 0;
+
+ if (self != NULL) {
+ UINT flags = self->flags;
+
+ /* See chapter 1.6.7.2 of ISO/IEC 14496-3 for the GA-SBR figures below. */
+
+ /* Are we initialized? */
+ if ((self->numSbrChannels > 0) && (self->numSbrElements > 0)) {
+ /* Add QMF synthesis delay */
+ if ((flags & SBRDEC_ELD_GRID) && IS_LOWDELAY(self->coreCodec)) {
+ /* Low delay SBR: */
+ if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
+ outputDelay +=
+ (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */
+ if (flags & SBRDEC_LD_MPS_QMF) {
+ outputDelay += 32;
+ }
+ }
+ } else if (!IS_USAC(self->coreCodec)) {
+ /* By the method of elimination this is the GA (AAC-LC, HE-AAC, ...)
+ * branch: */
+ outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 481 : 962;
+ if (flags & SBRDEC_SKIP_QMF_SYN) {
+ outputDelay -= 257; /* QMF synthesis */
+ }
+ }
+ }
+ }
+
+ return (outputDelay);
+}
diff --git a/fdk-aac/libSBRdec/src/transcendent.h b/fdk-aac/libSBRdec/src/transcendent.h
new file mode 100644
index 0000000..0e815c2
--- /dev/null
+++ b/fdk-aac/libSBRdec/src/transcendent.h
@@ -0,0 +1,372 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief FDK Fixed Point Arithmetic Library Interface
+*/
+
+#ifndef TRANSCENDENT_H
+#define TRANSCENDENT_H
+
+#include "sbrdecoder.h"
+#include "sbr_rom.h"
+
+/************************************************************************/
+/*!
+ \brief Get number of octaves between frequencies a and b
+
+ The Result is scaled with 1/8.
+ The valid range for a and b is 1 to LOG_DUALIS_TABLE_SIZE.
+
+ \return ld(a/b) / 8
+*/
+/************************************************************************/
+static inline FIXP_SGL FDK_getNumOctavesDiv8(INT a, /*!< lower band */
+ INT b) /*!< upper band */
+{
+ return ((SHORT)((LONG)(CalcLdInt(b) - CalcLdInt(a)) >> (FRACT_BITS - 3)));
+}
+
+/************************************************************************/
+/*!
+ \brief Add two values given by mantissa and exponent.
+
+ Mantissas are in fract format with values between 0 and 1. <br>
+ The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
+*/
+/************************************************************************/
+inline void FDK_add_MantExp(FIXP_SGL a_m, /*!< Mantissa of 1st operand a */
+ SCHAR a_e, /*!< Exponent of 1st operand a */
+ FIXP_SGL b_m, /*!< Mantissa of 2nd operand b */
+ SCHAR b_e, /*!< Exponent of 2nd operand b */
+ FIXP_SGL *ptrSum_m, /*!< Mantissa of result */
+ SCHAR *ptrSum_e) /*!< Exponent of result */
+{
+ FIXP_DBL accu;
+ int shift;
+ int shiftAbs;
+
+ FIXP_DBL shiftedMantissa;
+ FIXP_DBL otherMantissa;
+
+ /* Equalize exponents of the summands.
+ For the smaller summand, the exponent is adapted and
+ for compensation, the mantissa is shifted right. */
+
+ shift = (int)(a_e - b_e);
+
+ shiftAbs = (shift > 0) ? shift : -shift;
+ shiftAbs = (shiftAbs < DFRACT_BITS - 1) ? shiftAbs : DFRACT_BITS - 1;
+ shiftedMantissa = (shift > 0) ? (FX_SGL2FX_DBL(b_m) >> shiftAbs)
+ : (FX_SGL2FX_DBL(a_m) >> shiftAbs);
+ otherMantissa = (shift > 0) ? FX_SGL2FX_DBL(a_m) : FX_SGL2FX_DBL(b_m);
+ *ptrSum_e = (shift > 0) ? a_e : b_e;
+
+ accu = (shiftedMantissa >> 1) + (otherMantissa >> 1);
+ /* shift by 1 bit to avoid overflow */
+
+ if ((accu >= (FL2FXCONST_DBL(0.5f) - (FIXP_DBL)1)) ||
+ (accu <= FL2FXCONST_DBL(-0.5f)))
+ *ptrSum_e += 1;
+ else
+ accu = (shiftedMantissa + otherMantissa);
+
+ *ptrSum_m = FX_DBL2FX_SGL(accu);
+}
+
+inline void FDK_add_MantExp(FIXP_DBL a, /*!< Mantissa of 1st operand a */
+ SCHAR a_e, /*!< Exponent of 1st operand a */
+ FIXP_DBL b, /*!< Mantissa of 2nd operand b */
+ SCHAR b_e, /*!< Exponent of 2nd operand b */
+ FIXP_DBL *ptrSum, /*!< Mantissa of result */
+ SCHAR *ptrSum_e) /*!< Exponent of result */
+{
+ FIXP_DBL accu;
+ int shift;
+ int shiftAbs;
+
+ FIXP_DBL shiftedMantissa;
+ FIXP_DBL otherMantissa;
+
+ /* Equalize exponents of the summands.
+ For the smaller summand, the exponent is adapted and
+ for compensation, the mantissa is shifted right. */
+
+ shift = (int)(a_e - b_e);
+
+ shiftAbs = (shift > 0) ? shift : -shift;
+ shiftAbs = (shiftAbs < DFRACT_BITS - 1) ? shiftAbs : DFRACT_BITS - 1;
+ shiftedMantissa = (shift > 0) ? (b >> shiftAbs) : (a >> shiftAbs);
+ otherMantissa = (shift > 0) ? a : b;
+ *ptrSum_e = (shift > 0) ? a_e : b_e;
+
+ accu = (shiftedMantissa >> 1) + (otherMantissa >> 1);
+ /* shift by 1 bit to avoid overflow */
+
+ if ((accu >= (FL2FXCONST_DBL(0.5f) - (FIXP_DBL)1)) ||
+ (accu <= FL2FXCONST_DBL(-0.5f)))
+ *ptrSum_e += 1;
+ else
+ accu = (shiftedMantissa + otherMantissa);
+
+ *ptrSum = accu;
+}
+
+/************************************************************************/
+/*!
+ \brief Divide two values given by mantissa and exponent.
+
+ Mantissas are in fract format with values between 0 and 1. <br>
+ The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
+
+ For performance reasons, the division is based on a table lookup
+ which limits accuracy.
+*/
+/************************************************************************/
+static inline void FDK_divide_MantExp(
+ FIXP_SGL a_m, /*!< Mantissa of dividend a */
+ SCHAR a_e, /*!< Exponent of dividend a */
+ FIXP_SGL b_m, /*!< Mantissa of divisor b */
+ SCHAR b_e, /*!< Exponent of divisor b */
+ FIXP_SGL *ptrResult_m, /*!< Mantissa of quotient a/b */
+ SCHAR *ptrResult_e) /*!< Exponent of quotient a/b */
+
+{
+ int preShift, postShift, index, shift;
+ FIXP_DBL ratio_m;
+ FIXP_SGL bInv_m = FL2FXCONST_SGL(0.0f);
+
+ preShift = CntLeadingZeros(FX_SGL2FX_DBL(b_m));
+
+ /*
+ Shift b into the range from 0..INV_TABLE_SIZE-1,
+
+ E.g. 10 bits must be skipped for INV_TABLE_BITS 8:
+ - leave 8 bits as index for table
+ - skip sign bit,
+ - skip first bit of mantissa, because this is always the same (>0.5)
+
+ We are dealing with energies, so we need not care
+ about negative numbers
+ */
+
+ /*
+ The first interval has half width so the lowest bit of the index is
+ needed for a doubled resolution.
+ */
+ shift = (FRACT_BITS - 2 - INV_TABLE_BITS - preShift);
+
+ index = (shift < 0) ? (LONG)b_m << (-shift) : (LONG)b_m >> shift;
+
+ /* The index has INV_TABLE_BITS +1 valid bits here. Clear the other bits. */
+ index &= (1 << (INV_TABLE_BITS + 1)) - 1;
+
+ /* Remove offset of half an interval */
+ index--;
+
+ /* Now the lowest bit is shifted out */
+ index = index >> 1;
+
+ /* Fetch inversed mantissa from table: */
+ bInv_m = (index < 0) ? bInv_m : FDK_sbrDecoder_invTable[index];
+
+ /* Multiply a with the inverse of b: */
+ ratio_m = (index < 0) ? FX_SGL2FX_DBL(a_m >> 1) : fMultDiv2(bInv_m, a_m);
+
+ postShift = CntLeadingZeros(ratio_m) - 1;
+
+ *ptrResult_m = FX_DBL2FX_SGL(ratio_m << postShift);
+ *ptrResult_e = a_e - b_e + 1 + preShift - postShift;
+}
+
+static inline void FDK_divide_MantExp(
+ FIXP_DBL a_m, /*!< Mantissa of dividend a */
+ SCHAR a_e, /*!< Exponent of dividend a */
+ FIXP_DBL b_m, /*!< Mantissa of divisor b */
+ SCHAR b_e, /*!< Exponent of divisor b */
+ FIXP_DBL *ptrResult_m, /*!< Mantissa of quotient a/b */
+ SCHAR *ptrResult_e) /*!< Exponent of quotient a/b */
+
+{
+ int preShift, postShift, index, shift;
+ FIXP_DBL ratio_m;
+ FIXP_SGL bInv_m = FL2FXCONST_SGL(0.0f);
+
+ preShift = CntLeadingZeros(b_m);
+
+ /*
+ Shift b into the range from 0..INV_TABLE_SIZE-1,
+
+ E.g. 10 bits must be skipped for INV_TABLE_BITS 8:
+ - leave 8 bits as index for table
+ - skip sign bit,
+ - skip first bit of mantissa, because this is always the same (>0.5)
+
+ We are dealing with energies, so we need not care
+ about negative numbers
+ */
+
+ /*
+ The first interval has half width so the lowest bit of the index is
+ needed for a doubled resolution.
+ */
+ shift = (DFRACT_BITS - 2 - INV_TABLE_BITS - preShift);
+
+ index = (shift < 0) ? (LONG)b_m << (-shift) : (LONG)b_m >> shift;
+
+ /* The index has INV_TABLE_BITS +1 valid bits here. Clear the other bits. */
+ index &= (1 << (INV_TABLE_BITS + 1)) - 1;
+
+ /* Remove offset of half an interval */
+ index--;
+
+ /* Now the lowest bit is shifted out */
+ index = index >> 1;
+
+ /* Fetch inversed mantissa from table: */
+ bInv_m = (index < 0) ? bInv_m : FDK_sbrDecoder_invTable[index];
+
+ /* Multiply a with the inverse of b: */
+ ratio_m = (index < 0) ? (a_m >> 1) : fMultDiv2(bInv_m, a_m);
+
+ postShift = CntLeadingZeros(ratio_m) - 1;
+
+ *ptrResult_m = ratio_m << postShift;
+ *ptrResult_e = a_e - b_e + 1 + preShift - postShift;
+}
+
+/*!
+ \brief Calculate the squareroot of a number given by mantissa and exponent
+
+ Mantissa is in fract format with values between 0 and 1. <br>
+ The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
+ The operand is addressed via pointers and will be overwritten with the result.
+
+ For performance reasons, the square root is based on a table lookup
+ which limits accuracy.
+*/
+static inline void FDK_sqrt_MantExp(
+ FIXP_DBL *mantissa, /*!< Pointer to mantissa */
+ SCHAR *exponent, const SCHAR *destScale) {
+ FIXP_DBL input_m = *mantissa;
+ int input_e = (int)*exponent;
+ FIXP_DBL result = FL2FXCONST_DBL(0.0f);
+ int result_e = -FRACT_BITS;
+
+ /* Call lookup square root, which does internally normalization. */
+ result = sqrtFixp_lookup(input_m, &input_e);
+ result_e = input_e;
+
+ /* Write result */
+ if (exponent == destScale) {
+ *mantissa = result;
+ *exponent = result_e;
+ } else {
+ int shift = result_e - *destScale;
+ *mantissa = (shift >= 0) ? result << (INT)fixMin(DFRACT_BITS - 1, shift)
+ : result >> (INT)fixMin(DFRACT_BITS - 1, -shift);
+ *exponent = *destScale;
+ }
+}
+
+#endif
diff --git a/fdk-aac/libSBRenc/include/sbr_encoder.h b/fdk-aac/libSBRenc/include/sbr_encoder.h
new file mode 100644
index 0000000..d979ba6
--- /dev/null
+++ b/fdk-aac/libSBRenc/include/sbr_encoder.h
@@ -0,0 +1,483 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description: SBR encoder top level processing prototype
+
+*******************************************************************************/
+
+#ifndef SBR_ENCODER_H
+#define SBR_ENCODER_H
+
+#include "common_fix.h"
+#include "FDK_audio.h"
+
+#include "FDK_bitstream.h"
+
+/* core coder helpers */
+#define MAX_TRANS_FAC 8
+#define MAX_CODEC_FRAME_RATIO 2
+#define MAX_PAYLOAD_SIZE 256
+
+typedef enum codecType {
+ CODEC_AAC = 0,
+ CODEC_AACLD = 1,
+ CODEC_UNSPECIFIED = 99
+} CODEC_TYPE;
+
+typedef struct {
+ INT bitRate;
+ INT nChannels;
+ INT sampleFreq;
+ INT transFac;
+ INT standardBitrate;
+} CODEC_PARAM;
+
+typedef enum {
+ SBR_MONO,
+ SBR_LEFT_RIGHT,
+ SBR_COUPLING,
+ SBR_SWITCH_LRC
+} SBR_STEREO_MODE;
+
+/* bitstream syntax flags */
+enum {
+ SBR_SYNTAX_LOW_DELAY = 0x0001,
+ SBR_SYNTAX_SCALABLE = 0x0002,
+ SBR_SYNTAX_CRC = 0x0004,
+ SBR_SYNTAX_DRM_CRC = 0x0008,
+ SBR_SYNTAX_ELD_REDUCED_DELAY = 0x0010
+};
+
+typedef enum { FREQ_RES_LOW = 0, FREQ_RES_HIGH } FREQ_RES;
+
+typedef struct {
+ CODEC_TYPE coreCoder; /*!< LC or ELD */
+ UINT bitrateFrom; /*!< inclusive */
+ UINT bitrateTo; /*!< exclusive */
+
+ UINT sampleRate; /*!< */
+ UCHAR numChannels; /*!< */
+
+ UCHAR startFreq; /*!< bs_start_freq */
+ UCHAR startFreqSpeech; /*!< bs_start_freq for speech config flag */
+ UCHAR stopFreq; /*!< bs_stop_freq */
+ UCHAR stopFreqSpeech; /*!< bs_stop_freq for speech config flag */
+
+ UCHAR numNoiseBands; /*!< */
+ UCHAR noiseFloorOffset; /*!< */
+ SCHAR noiseMaxLevel; /*!< */
+ SBR_STEREO_MODE stereoMode; /*!< */
+ UCHAR freqScale; /*!< */
+} sbrTuningTable_t;
+
+typedef struct sbrConfiguration {
+ /*
+ core coder dependent configurations
+ */
+ CODEC_PARAM
+ codecSettings; /*!< Core coder settings. To be set from core coder. */
+ INT SendHeaderDataTime; /*!< SBR header send update frequency in ms. */
+ INT useWaveCoding; /*!< Flag: usage of wavecoding tool. */
+ INT crcSbr; /*!< Flag: usage of SBR-CRC. */
+ INT dynBwSupported; /*!< Flag: support for dynamic bandwidth in this
+ combination. */
+ INT parametricCoding; /*!< Flag: usage of parametric coding tool. */
+ INT downSampleFactor; /*!< Sampling rate relation between the SBR and the core
+ encoder. */
+ FREQ_RES freq_res_fixfix[2]; /*!< Frequency resolution of envelopes in frame
+ class FIXFIX, for non-split case and split
+ case */
+ UCHAR fResTransIsLow; /*!< Frequency resolution of envelopes in transient
+ frames: low (0) or variable (1) */
+
+ /*
+ core coder dependent tuning parameters
+ */
+ INT tran_thr; /*!< SBR transient detector threshold (* 100). */
+ INT noiseFloorOffset; /*!< Noise floor offset. */
+ UINT useSpeechConfig; /*!< Flag: adapt tuning parameters according to speech.
+ */
+
+ /*
+ core coder independent configurations
+ */
+ INT sbrFrameSize; /*!< SBR frame size in samples. Will be calculated from core
+ coder settings. */
+ INT sbr_data_extra; /*!< Flag usage of data extra. */
+ INT amp_res; /*!< Amplitude resolution. */
+ INT ana_max_level; /*!< Noise insertion maximum level. */
+ INT tran_fc; /*!< Transient detector start frequency. */
+ INT tran_det_mode; /*!< Transient detector mode. */
+ INT spread; /*!< Flag: usage of SBR spread. */
+ INT stat; /*!< Flag: usage of static framing. */
+ INT e; /*!< Number of envelopes when static framing is chosen. */
+ SBR_STEREO_MODE stereoMode; /*!< SBR stereo mode. */
+ INT deltaTAcrossFrames; /*!< Flag: allow time-delta coding. */
+ FIXP_DBL dF_edge_1stEnv; /*!< Extra fraction delta-F coding is allowed to be
+ more expensive. */
+ FIXP_DBL dF_edge_incr; /*!< Increment dF_edge_1stEnv this much if dT-coding
+ was used this frame. */
+ INT sbr_invf_mode; /*!< Inverse filtering mode. */
+ INT sbr_xpos_mode; /*!< Transposer mode. */
+ INT sbr_xpos_ctrl; /*!< Transposer control. */
+ INT sbr_xpos_level; /*!< Transposer 3rd order level. */
+ INT startFreq; /*!< The start frequency table index. */
+ INT stopFreq; /*!< The stop frequency table index. */
+ INT useSaPan; /*!< Flag: usage of SAPAN stereo. */
+ INT dynBwEnabled; /*!< Flag: usage of dynamic bandwidth. */
+ INT bParametricStereo; /*!< Flag: usage of parametric stereo coding tool. */
+
+ /*
+ header_extra1 configuration
+ */
+ UCHAR freqScale; /*!< Frequency grouping. */
+ INT alterScale; /*!< Scale resolution. */
+ INT sbr_noise_bands; /*!< Number of noise bands. */
+
+ /*
+ header_extra2 configuration
+ */
+ INT sbr_limiter_bands; /*!< Number of limiter bands. */
+ INT sbr_limiter_gains; /*!< Gain of limiter. */
+ INT sbr_interpol_freq; /*!< Flag: use interpolation in freq. direction. */
+ INT sbr_smoothing_length; /*!< Flag: choose length 4 or 0 (=on, off). */
+ UCHAR init_amp_res_FF;
+ FIXP_DBL threshold_AmpRes_FF_m;
+ SCHAR threshold_AmpRes_FF_e;
+} sbrConfiguration, *sbrConfigurationPtr;
+
+typedef struct SBR_CONFIG_DATA {
+ UINT sbrSyntaxFlags; /**< SBR syntax flags derived from AOT. */
+ INT nChannels; /**< Number of channels. */
+
+ INT nSfb[2]; /**< Number of SBR scalefactor bands for LO_RES and HI_RES (?) */
+ INT num_Master; /**< Number of elements in v_k_master. */
+ INT sampleFreq; /**< SBR sampling frequency. */
+ INT frameSize;
+ INT xOverFreq; /**< The SBR start frequency. */
+ INT dynXOverFreq; /**< Used crossover frequency when dynamic bandwidth is
+ enabled. */
+
+ INT noQmfBands; /**< Number of QMF frequency bands. */
+ INT noQmfSlots; /**< Number of QMF slots. */
+
+ 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. */
+
+ SBR_STEREO_MODE stereoMode;
+ INT noEnvChannels; /**< Number of envelope channels. */
+
+ INT useWaveCoding; /**< Flag indicates whether to use wave coding at all. */
+ INT useParametricCoding; /**< Flag indicates whether to use para coding at
+ all. */
+ INT xposCtrlSwitch; /**< Flag indicates whether to switch xpos ctrl on the
+ fly. */
+ INT switchTransposers; /**< Flag indicates whether to switch xpos on the fly .
+ */
+ UCHAR initAmpResFF;
+ FIXP_DBL thresholdAmpResFF_m;
+ SCHAR thresholdAmpResFF_e;
+} SBR_CONFIG_DATA, *HANDLE_SBR_CONFIG_DATA;
+
+typedef struct {
+ MP4_ELEMENT_ID elType;
+ INT bitRate;
+ int instanceTag;
+ UCHAR fParametricStereo;
+ UCHAR fDualMono; /**< This flags allows to disable coupling in sbr channel
+ pair element */
+ UCHAR nChannelsInEl;
+ UCHAR ChannelIndex[2];
+} SBR_ELEMENT_INFO;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SBR_ENCODER *HANDLE_SBR_ENCODER;
+
+/**
+ * \brief Get the max required input buffer size including delay balancing
+ * space for N audio channels.
+ * \param noChannels Number of audio channels.
+ * \return Max required input buffer size in bytes.
+ */
+INT sbrEncoder_GetInBufferSize(int noChannels);
+
+INT sbrEncoder_Open(HANDLE_SBR_ENCODER *phSbrEncoder, INT nElements,
+ INT nChannels, INT supportPS);
+
+/**
+ * \brief Get closest working bitrate to specified desired
+ * bitrate for a single SBR element.
+ * \param bitRate The desired target bit rate
+ * \param numChannels The amount of audio channels
+ * \param coreSampleRate The sample rate of the core coder
+ * \param aot The current Audio Object Type
+ * \return Closest working bit rate to bitRate value
+ */
+UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels,
+ UINT coreSampleRate, AUDIO_OBJECT_TYPE aot);
+
+/**
+ * \brief Check whether downsampled SBR single rate is possible
+ * with given audio object type.
+ * \param aot The Audio object type.
+ * \return 0 when downsampled SBR is not possible,
+ * 1 when downsampled SBR is possible.
+ */
+UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot);
+
+/**
+ * \brief Initialize SBR Encoder instance.
+ * \param phSbrEncoder Pointer to a SBR Encoder instance.
+ * \param elInfo Structure that describes the element/channel
+ * arrangement.
+ * \param noElements Amount of elements described in elInfo.
+ * \param inputBuffer Pointer to the encoder audio buffer
+ * \param inputBufferBufSize Buffer offset of one channel (frameSize + delay)
+ * \param bandwidth Returns the core audio encoder bandwidth (output)
+ * \param bufferOffset Returns the offset for the audio input data in order
+ * to do delay balancing.
+ * \param numChannels Input: Encoder input channels. output: core encoder
+ * channels.
+ * \param sampleRate Input: Encoder samplerate. output core encoder
+ * samplerate.
+ * \param downSampleFactor Input: Relation between SBR and core coder sampling
+ * rate;
+ * \param frameLength Input: Encoder frameLength. output core encoder
+ * frameLength.
+ * \param aot Input: AOT..
+ * \param delay Input: core encoder delay. Output: total delay
+ * because of SBR.
+ * \param transformFactor The core encoder transform factor (blockswitching).
+ * \param headerPeriod Repetition rate of the SBR header:
+ * - (-1) means intern configuration.
+ * - (1-10) corresponds to header repetition rate in
+ * frames.
+ * \return 0 on success, and non-zero if failed.
+ */
+INT sbrEncoder_Init(HANDLE_SBR_ENCODER hSbrEncoder,
+ SBR_ELEMENT_INFO elInfo[(8)], int noElements,
+ INT_PCM *inputBuffer, UINT inputBufferBufSize,
+ INT *coreBandwidth, INT *inputBufferOffset,
+ INT *numChannels, const UINT syntaxFlags, INT *sampleRate,
+ UINT *downSampleFactor, INT *frameLength,
+ AUDIO_OBJECT_TYPE aot, int *delay, int transformFactor,
+ const int headerPeriod, ULONG statesInitFlag);
+
+/**
+ * \brief Do delay line buffers housekeeping. To be called after
+ * each encoded audio frame.
+ * \param hEnvEnc SBR Encoder handle.
+ * \param timeBuffer Pointer to the encoder audio buffer.
+ * \param timeBufferBufSIze buffer size for one channel
+ * \return 0 on success, and non-zero if failed.
+ */
+INT sbrEncoder_UpdateBuffers(HANDLE_SBR_ENCODER hEnvEnc, INT_PCM *timeBuffer,
+ UINT timeBufferBufSIze);
+
+/**
+ * \brief Close SBR encoder instance.
+ * \param phEbrEncoder Handle of SBR encoder instance to be closed.
+ * \return void
+ */
+void sbrEncoder_Close(HANDLE_SBR_ENCODER *phEbrEncoder);
+
+/**
+ * \brief Encode SBR data of one complete audio frame.
+ * \param hEnvEncoder Handle of SBR encoder instance.
+ * \param samples Time samples, not interleaved.
+ * \param timeInStride Channel offset of samples buffer.
+ * \param sbrDataBits Size of SBR payload in bits.
+ * \param sbrData SBR payload.
+ * \return 0 on success, and non-zero if failed.
+ */
+INT sbrEncoder_EncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, INT_PCM *samples,
+ UINT samplesBufSize, UINT sbrDataBits[(8)],
+ UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE]);
+
+/**
+ * \brief Write SBR headers of one SBR element.
+ * \param sbrEncoder Handle of the SBR encoder instance.
+ * \param hBs Handle of bit stream handle to write SBR header to.
+ * \param element_index Index of the SBR element which header should be written.
+ * \param fSendHeaders Flag indicating that the SBR encoder should send more
+ * headers in the SBR payload or not.
+ * \return void
+ */
+void sbrEncoder_GetHeader(HANDLE_SBR_ENCODER sbrEncoder,
+ HANDLE_FDK_BITSTREAM hBs, INT element_index,
+ int fSendHeaders);
+
+/**
+ * \brief Request to write SBR header.
+ * \param hSbrEncoder SBR encoder handle.
+ * \return 0 on success, and non-zero if failed.
+ */
+INT sbrEncoder_SendHeader(HANDLE_SBR_ENCODER hSbrEncoder);
+
+/**
+ * \brief Request if last sbr payload contains an SBR header.
+ * \param hSbrEncoder SBR encoder handle.
+ * \return 1 contains sbr header, 0 without sbr header.
+ */
+INT sbrEncoder_ContainsHeader(HANDLE_SBR_ENCODER hSbrEncoder);
+
+/**
+ * \brief SBR header delay in frames.
+ * \param hSbrEncoder SBR encoder handle.
+ * \return Delay in frames, -1 on failure.
+ */
+INT sbrEncoder_GetHeaderDelay(HANDLE_SBR_ENCODER hSbrEncoder);
+
+/**
+ * \brief Bitstrem delay in SBR frames.
+ * \param hSbrEncoder SBR encoder handle.
+ * \return Delay in frames, -1 on failure.
+ */
+INT sbrEncoder_GetBsDelay(HANDLE_SBR_ENCODER hSbrEncoder);
+
+/**
+ * \brief Prepare SBR payload for SAP.
+ * \param hSbrEncoder SBR encoder handle.
+ * \return 0 on success, and non-zero if failed.
+ */
+INT sbrEncoder_SAPPrepare(HANDLE_SBR_ENCODER hSbrEncoder);
+
+/**
+ * \brief SBR encoder bitrate estimation.
+ * \param hSbrEncoder SBR encoder handle.
+ * \return Estimated bitrate.
+ */
+INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder);
+
+/**
+ * \brief Delay between input data and downsampled output data.
+ * \param hSbrEncoder SBR encoder handle.
+ * \return Delay.
+ */
+INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder);
+
+/**
+ * \brief Delay caused by the SBR decoder.
+ * \param hSbrEncoder SBR encoder handle.
+ * \return Delay.
+ */
+INT sbrEncoder_GetSbrDecDelay(HANDLE_SBR_ENCODER hSbrEncoder);
+
+/**
+ * \brief Get decoder library version info.
+ * \param info Pointer to an allocated LIB_INFO struct, where library info is
+ * written to.
+ * \return 0 on sucess.
+ */
+INT sbrEncoder_GetLibInfo(LIB_INFO *info);
+
+void sbrPrintRAM(void);
+
+void sbrPrintROM(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ifndef __SBR_MAIN_H */
diff --git a/fdk-aac/libSBRenc/src/bit_sbr.cpp b/fdk-aac/libSBRenc/src/bit_sbr.cpp
new file mode 100644
index 0000000..5a65e98
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/bit_sbr.cpp
@@ -0,0 +1,1049 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief SBR bit writing routines $Revision: 93300 $
+*/
+
+#include "bit_sbr.h"
+
+#include "code_env.h"
+#include "cmondata.h"
+#include "sbr.h"
+
+#include "ps_main.h"
+
+typedef enum { SBR_ID_SCE = 1, SBR_ID_CPE } SBR_ELEMENT_TYPE;
+
+static INT encodeSbrData(HANDLE_SBR_ENV_DATA sbrEnvDataLeft,
+ HANDLE_SBR_ENV_DATA sbrEnvDataRight,
+ HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_COMMON_DATA cmonData, SBR_ELEMENT_TYPE sbrElem,
+ INT coupling, UINT sbrSyntaxFlags);
+
+static INT encodeSbrHeader(HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData,
+ HANDLE_COMMON_DATA cmonData);
+
+static INT encodeSbrHeaderData(HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_FDK_BITSTREAM hBitStream);
+
+static INT encodeSbrSingleChannelElement(
+ HANDLE_SBR_ENV_DATA sbrEnvData, HANDLE_FDK_BITSTREAM hBitStream,
+ HANDLE_PARAMETRIC_STEREO hParametricStereo, const UINT sbrSyntaxFlags);
+
+static INT encodeSbrChannelPairElement(
+ HANDLE_SBR_ENV_DATA sbrEnvDataLeft, HANDLE_SBR_ENV_DATA sbrEnvDataRight,
+ HANDLE_PARAMETRIC_STEREO hParametricStereo, HANDLE_FDK_BITSTREAM hBitStream,
+ const INT coupling, const UINT sbrSyntaxFlags);
+
+static INT encodeSbrGrid(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream);
+
+static int encodeLowDelaySbrGrid(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ const int transmitFreqs,
+ const UINT sbrSyntaxFlags);
+
+static INT encodeSbrDtdf(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream);
+
+static INT writeNoiseLevelData(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream, INT coupling);
+
+static INT writeEnvelopeData(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream, INT coupling);
+
+static INT writeSyntheticCodingData(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream);
+
+static INT encodeExtendedData(HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_FDK_BITSTREAM hBitStream);
+
+static INT getSbrExtendedDataSize(HANDLE_PARAMETRIC_STEREO hParametricStereo);
+
+/*****************************************************************************
+
+ functionname: FDKsbrEnc_WriteEnvSingleChannelElement
+ description: writes pure SBR single channel data element
+ returns: number of bits written
+ input:
+ output:
+
+*****************************************************************************/
+INT FDKsbrEnc_WriteEnvSingleChannelElement(
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_COMMON_DATA cmonData, UINT sbrSyntaxFlags)
+
+{
+ INT payloadBits = 0;
+
+ cmonData->sbrHdrBits = 0;
+ cmonData->sbrDataBits = 0;
+
+ /* write pure sbr data */
+ if (sbrEnvData != NULL) {
+ /* write header */
+ payloadBits += encodeSbrHeader(sbrHeaderData, sbrBitstreamData, cmonData);
+
+ /* write data */
+ payloadBits += encodeSbrData(sbrEnvData, NULL, hParametricStereo, cmonData,
+ SBR_ID_SCE, 0, sbrSyntaxFlags);
+ }
+ return payloadBits;
+}
+
+/*****************************************************************************
+
+ functionname: FDKsbrEnc_WriteEnvChannelPairElement
+ description: writes pure SBR channel pair data element
+ returns: number of bits written
+ input:
+ output:
+
+*****************************************************************************/
+INT FDKsbrEnc_WriteEnvChannelPairElement(
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData,
+ HANDLE_SBR_ENV_DATA sbrEnvDataLeft, HANDLE_SBR_ENV_DATA sbrEnvDataRight,
+ HANDLE_COMMON_DATA cmonData, UINT sbrSyntaxFlags)
+
+{
+ INT payloadBits = 0;
+ cmonData->sbrHdrBits = 0;
+ cmonData->sbrDataBits = 0;
+
+ /* write pure sbr data */
+ if ((sbrEnvDataLeft != NULL) && (sbrEnvDataRight != NULL)) {
+ /* write header */
+ payloadBits += encodeSbrHeader(sbrHeaderData, sbrBitstreamData, cmonData);
+
+ /* write data */
+ payloadBits += encodeSbrData(sbrEnvDataLeft, sbrEnvDataRight,
+ hParametricStereo, cmonData, SBR_ID_CPE,
+ sbrHeaderData->coupling, sbrSyntaxFlags);
+ }
+ return payloadBits;
+}
+
+INT FDKsbrEnc_CountSbrChannelPairElement(
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData,
+ HANDLE_SBR_ENV_DATA sbrEnvDataLeft, HANDLE_SBR_ENV_DATA sbrEnvDataRight,
+ HANDLE_COMMON_DATA cmonData, UINT sbrSyntaxFlags) {
+ INT payloadBits;
+ INT bitPos = FDKgetValidBits(&cmonData->sbrBitbuf);
+
+ payloadBits = FDKsbrEnc_WriteEnvChannelPairElement(
+ sbrHeaderData, hParametricStereo, sbrBitstreamData, sbrEnvDataLeft,
+ sbrEnvDataRight, cmonData, sbrSyntaxFlags);
+
+ FDKpushBack(&cmonData->sbrBitbuf,
+ (FDKgetValidBits(&cmonData->sbrBitbuf) - bitPos));
+
+ return payloadBits;
+}
+
+void sbrEncoder_GetHeader(SBR_ENCODER *sbrEncoder, HANDLE_FDK_BITSTREAM hBs,
+ INT element_index, int fSendHeaders) {
+ encodeSbrHeaderData(&sbrEncoder->sbrElement[element_index]->sbrHeaderData,
+ hBs);
+
+ if (fSendHeaders == 0) {
+ /* Prevent header being embedded into the SBR payload. */
+ sbrEncoder->sbrElement[element_index]->sbrBitstreamData.NrSendHeaderData =
+ -1;
+ sbrEncoder->sbrElement[element_index]->sbrBitstreamData.HeaderActive = 0;
+ sbrEncoder->sbrElement[element_index]
+ ->sbrBitstreamData.CountSendHeaderData = -1;
+ }
+}
+
+/*****************************************************************************
+
+ functionname: encodeSbrHeader
+ description: encodes SBR Header information
+ returns: number of bits written
+ input:
+ output:
+
+*****************************************************************************/
+static INT encodeSbrHeader(HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData,
+ HANDLE_COMMON_DATA cmonData) {
+ INT payloadBits = 0;
+
+ if (sbrBitstreamData->HeaderActive) {
+ payloadBits += FDKwriteBits(&cmonData->sbrBitbuf, 1, 1);
+ payloadBits += encodeSbrHeaderData(sbrHeaderData, &cmonData->sbrBitbuf);
+ } else {
+ payloadBits += FDKwriteBits(&cmonData->sbrBitbuf, 0, 1);
+ }
+
+ cmonData->sbrHdrBits = payloadBits;
+
+ return payloadBits;
+}
+
+/*****************************************************************************
+
+ functionname: encodeSbrHeaderData
+ description: writes sbr_header()
+ bs_protocol_version through bs_header_extra_2
+ returns: number of bits written
+ input:
+ output:
+
+*****************************************************************************/
+static INT encodeSbrHeaderData(HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_FDK_BITSTREAM hBitStream)
+
+{
+ INT payloadBits = 0;
+ if (sbrHeaderData != NULL) {
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_amp_res,
+ SI_SBR_AMP_RES_BITS);
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_start_frequency,
+ SI_SBR_START_FREQ_BITS);
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_stop_frequency,
+ SI_SBR_STOP_FREQ_BITS);
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_xover_band,
+ SI_SBR_XOVER_BAND_BITS);
+
+ payloadBits += FDKwriteBits(hBitStream, 0, SI_SBR_RESERVED_BITS);
+
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->header_extra_1,
+ SI_SBR_HEADER_EXTRA_1_BITS);
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->header_extra_2,
+ SI_SBR_HEADER_EXTRA_2_BITS);
+
+ if (sbrHeaderData->header_extra_1) {
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->freqScale,
+ SI_SBR_FREQ_SCALE_BITS);
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->alterScale,
+ SI_SBR_ALTER_SCALE_BITS);
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_noise_bands,
+ SI_SBR_NOISE_BANDS_BITS);
+ } /* sbrHeaderData->header_extra_1 */
+
+ if (sbrHeaderData->header_extra_2) {
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_limiter_bands,
+ SI_SBR_LIMITER_BANDS_BITS);
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_limiter_gains,
+ SI_SBR_LIMITER_GAINS_BITS);
+ payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_interpol_freq,
+ SI_SBR_INTERPOL_FREQ_BITS);
+ payloadBits +=
+ FDKwriteBits(hBitStream, sbrHeaderData->sbr_smoothing_length,
+ SI_SBR_SMOOTHING_LENGTH_BITS);
+
+ } /* sbrHeaderData->header_extra_2 */
+ } /* sbrHeaderData != NULL */
+
+ return payloadBits;
+}
+
+/*****************************************************************************
+
+ functionname: encodeSbrData
+ description: encodes sbr Data information
+ returns: number of bits written
+ input:
+ output:
+
+*****************************************************************************/
+static INT encodeSbrData(HANDLE_SBR_ENV_DATA sbrEnvDataLeft,
+ HANDLE_SBR_ENV_DATA sbrEnvDataRight,
+ HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_COMMON_DATA cmonData, SBR_ELEMENT_TYPE sbrElem,
+ INT coupling, UINT sbrSyntaxFlags) {
+ INT payloadBits = 0;
+
+ switch (sbrElem) {
+ case SBR_ID_SCE:
+ payloadBits +=
+ encodeSbrSingleChannelElement(sbrEnvDataLeft, &cmonData->sbrBitbuf,
+ hParametricStereo, sbrSyntaxFlags);
+ break;
+ case SBR_ID_CPE:
+ payloadBits += encodeSbrChannelPairElement(
+ sbrEnvDataLeft, sbrEnvDataRight, hParametricStereo,
+ &cmonData->sbrBitbuf, coupling, sbrSyntaxFlags);
+ break;
+ default:
+ /* we never should apply SBR to any other element type */
+ FDK_ASSERT(0);
+ }
+
+ cmonData->sbrDataBits = payloadBits;
+
+ return payloadBits;
+}
+
+#define MODE_FREQ_TANS 1
+#define MODE_NO_FREQ_TRAN 0
+#define LD_TRANSMISSION MODE_FREQ_TANS
+static int encodeFreqs(int mode) { return ((mode & MODE_FREQ_TANS) ? 1 : 0); }
+
+/*****************************************************************************
+
+ functionname: encodeSbrSingleChannelElement
+ description: encodes sbr SCE information
+ returns: number of bits written
+ input:
+ output:
+
+*****************************************************************************/
+static INT encodeSbrSingleChannelElement(
+ HANDLE_SBR_ENV_DATA sbrEnvData, HANDLE_FDK_BITSTREAM hBitStream,
+ HANDLE_PARAMETRIC_STEREO hParametricStereo, const UINT sbrSyntaxFlags) {
+ INT i, payloadBits = 0;
+
+ payloadBits += FDKwriteBits(hBitStream, 0,
+ SI_SBR_DATA_EXTRA_BITS); /* no reserved bits */
+
+ if (sbrEnvData->ldGrid) {
+ if (sbrEnvData->hSbrBSGrid->frameClass != FIXFIXonly) {
+ /* encode normal SbrGrid */
+ payloadBits += encodeSbrGrid(sbrEnvData, hBitStream);
+ } else {
+ /* use FIXFIXonly frame Grid */
+ payloadBits += encodeLowDelaySbrGrid(
+ sbrEnvData, hBitStream, encodeFreqs(LD_TRANSMISSION), sbrSyntaxFlags);
+ }
+ } else {
+ if (sbrSyntaxFlags & SBR_SYNTAX_SCALABLE) {
+ payloadBits += FDKwriteBits(hBitStream, 1, SI_SBR_COUPLING_BITS);
+ }
+ payloadBits += encodeSbrGrid(sbrEnvData, hBitStream);
+ }
+
+ payloadBits += encodeSbrDtdf(sbrEnvData, hBitStream);
+
+ for (i = 0; i < sbrEnvData->noOfnoisebands; i++) {
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->sbr_invf_mode_vec[i],
+ SI_SBR_INVF_MODE_BITS);
+ }
+
+ payloadBits += writeEnvelopeData(sbrEnvData, hBitStream, 0);
+ payloadBits += writeNoiseLevelData(sbrEnvData, hBitStream, 0);
+
+ payloadBits += writeSyntheticCodingData(sbrEnvData, hBitStream);
+
+ payloadBits += encodeExtendedData(hParametricStereo, hBitStream);
+
+ return payloadBits;
+}
+
+/*****************************************************************************
+
+ functionname: encodeSbrChannelPairElement
+ description: encodes sbr CPE information
+ returns:
+ input:
+ output:
+
+*****************************************************************************/
+static INT encodeSbrChannelPairElement(
+ HANDLE_SBR_ENV_DATA sbrEnvDataLeft, HANDLE_SBR_ENV_DATA sbrEnvDataRight,
+ HANDLE_PARAMETRIC_STEREO hParametricStereo, HANDLE_FDK_BITSTREAM hBitStream,
+ const INT coupling, const UINT sbrSyntaxFlags) {
+ INT payloadBits = 0;
+ INT i = 0;
+
+ payloadBits += FDKwriteBits(hBitStream, 0,
+ SI_SBR_DATA_EXTRA_BITS); /* no reserved bits */
+
+ payloadBits += FDKwriteBits(hBitStream, coupling, SI_SBR_COUPLING_BITS);
+
+ if (coupling) {
+ if (sbrEnvDataLeft->ldGrid) {
+ if (sbrEnvDataLeft->hSbrBSGrid->frameClass != FIXFIXonly) {
+ /* normal SbrGrid */
+ payloadBits += encodeSbrGrid(sbrEnvDataLeft, hBitStream);
+
+ } else {
+ /* FIXFIXonly frame Grid */
+ payloadBits +=
+ encodeLowDelaySbrGrid(sbrEnvDataLeft, hBitStream,
+ encodeFreqs(LD_TRANSMISSION), sbrSyntaxFlags);
+ }
+ } else
+ payloadBits += encodeSbrGrid(sbrEnvDataLeft, hBitStream);
+
+ payloadBits += encodeSbrDtdf(sbrEnvDataLeft, hBitStream);
+ payloadBits += encodeSbrDtdf(sbrEnvDataRight, hBitStream);
+
+ for (i = 0; i < sbrEnvDataLeft->noOfnoisebands; i++) {
+ payloadBits +=
+ FDKwriteBits(hBitStream, sbrEnvDataLeft->sbr_invf_mode_vec[i],
+ SI_SBR_INVF_MODE_BITS);
+ }
+
+ payloadBits += writeEnvelopeData(sbrEnvDataLeft, hBitStream, 1);
+ payloadBits += writeNoiseLevelData(sbrEnvDataLeft, hBitStream, 1);
+ payloadBits += writeEnvelopeData(sbrEnvDataRight, hBitStream, 1);
+ payloadBits += writeNoiseLevelData(sbrEnvDataRight, hBitStream, 1);
+
+ payloadBits += writeSyntheticCodingData(sbrEnvDataLeft, hBitStream);
+ payloadBits += writeSyntheticCodingData(sbrEnvDataRight, hBitStream);
+
+ } else { /* no coupling */
+ FDK_ASSERT(sbrEnvDataLeft->ldGrid == sbrEnvDataRight->ldGrid);
+
+ if (sbrEnvDataLeft->ldGrid || sbrEnvDataRight->ldGrid) {
+ /* sbrEnvDataLeft (left channel) */
+ if (sbrEnvDataLeft->hSbrBSGrid->frameClass != FIXFIXonly) {
+ /* no FIXFIXonly Frame so we dont need encodeLowDelaySbrGrid */
+ /* normal SbrGrid */
+ payloadBits += encodeSbrGrid(sbrEnvDataLeft, hBitStream);
+
+ } else {
+ /* FIXFIXonly frame Grid */
+ payloadBits +=
+ encodeLowDelaySbrGrid(sbrEnvDataLeft, hBitStream,
+ encodeFreqs(LD_TRANSMISSION), sbrSyntaxFlags);
+ }
+
+ /* sbrEnvDataRight (right channel) */
+ if (sbrEnvDataRight->hSbrBSGrid->frameClass != FIXFIXonly) {
+ /* no FIXFIXonly Frame so we dont need encodeLowDelaySbrGrid */
+ /* normal SbrGrid */
+ payloadBits += encodeSbrGrid(sbrEnvDataRight, hBitStream);
+
+ } else {
+ /* FIXFIXonly frame Grid */
+ payloadBits +=
+ encodeLowDelaySbrGrid(sbrEnvDataRight, hBitStream,
+ encodeFreqs(LD_TRANSMISSION), sbrSyntaxFlags);
+ }
+ } else {
+ payloadBits += encodeSbrGrid(sbrEnvDataLeft, hBitStream);
+ payloadBits += encodeSbrGrid(sbrEnvDataRight, hBitStream);
+ }
+ payloadBits += encodeSbrDtdf(sbrEnvDataLeft, hBitStream);
+ payloadBits += encodeSbrDtdf(sbrEnvDataRight, hBitStream);
+
+ for (i = 0; i < sbrEnvDataLeft->noOfnoisebands; i++) {
+ payloadBits +=
+ FDKwriteBits(hBitStream, sbrEnvDataLeft->sbr_invf_mode_vec[i],
+ SI_SBR_INVF_MODE_BITS);
+ }
+ for (i = 0; i < sbrEnvDataRight->noOfnoisebands; i++) {
+ payloadBits +=
+ FDKwriteBits(hBitStream, sbrEnvDataRight->sbr_invf_mode_vec[i],
+ SI_SBR_INVF_MODE_BITS);
+ }
+
+ payloadBits += writeEnvelopeData(sbrEnvDataLeft, hBitStream, 0);
+ payloadBits += writeEnvelopeData(sbrEnvDataRight, hBitStream, 0);
+ payloadBits += writeNoiseLevelData(sbrEnvDataLeft, hBitStream, 0);
+ payloadBits += writeNoiseLevelData(sbrEnvDataRight, hBitStream, 0);
+
+ payloadBits += writeSyntheticCodingData(sbrEnvDataLeft, hBitStream);
+ payloadBits += writeSyntheticCodingData(sbrEnvDataRight, hBitStream);
+
+ } /* coupling */
+
+ payloadBits += encodeExtendedData(hParametricStereo, hBitStream);
+
+ return payloadBits;
+}
+
+static INT ceil_ln2(INT x) {
+ INT tmp = -1;
+ while ((1 << ++tmp) < x)
+ ;
+ return (tmp);
+}
+
+/*****************************************************************************
+
+ functionname: encodeSbrGrid
+ description: if hBitStream != NULL writes bits that describes the
+ time/frequency grouping of a frame; else counts them only
+ returns: number of bits written or counted
+ input:
+ output:
+
+*****************************************************************************/
+static INT encodeSbrGrid(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream) {
+ INT payloadBits = 0;
+ INT i, temp;
+ INT bufferFrameStart = sbrEnvData->hSbrBSGrid->bufferFrameStart;
+ INT numberTimeSlots = sbrEnvData->hSbrBSGrid->numberTimeSlots;
+
+ if (sbrEnvData->ldGrid)
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->frameClass,
+ SBR_CLA_BITS_LD);
+ else
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->frameClass,
+ SBR_CLA_BITS);
+
+ switch (sbrEnvData->hSbrBSGrid->frameClass) {
+ case FIXFIXonly:
+ FDK_ASSERT(0 /* Fatal error in encodeSbrGrid! */);
+ break;
+ case FIXFIX:
+ temp = ceil_ln2(sbrEnvData->hSbrBSGrid->bs_num_env);
+ payloadBits += FDKwriteBits(hBitStream, temp, SBR_ENV_BITS);
+ if ((sbrEnvData->ldGrid) && (sbrEnvData->hSbrBSGrid->bs_num_env == 1))
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->currentAmpResFF,
+ SI_SBR_AMP_RES_BITS);
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->v_f[0],
+ SBR_RES_BITS);
+
+ break;
+
+ case FIXVAR:
+ case VARFIX:
+ if (sbrEnvData->hSbrBSGrid->frameClass == FIXVAR)
+ temp = sbrEnvData->hSbrBSGrid->bs_abs_bord -
+ (bufferFrameStart + numberTimeSlots);
+ else
+ temp = sbrEnvData->hSbrBSGrid->bs_abs_bord - bufferFrameStart;
+
+ payloadBits += FDKwriteBits(hBitStream, temp, SBR_ABS_BITS);
+ payloadBits +=
+ FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->n, SBR_NUM_BITS);
+
+ for (i = 0; i < sbrEnvData->hSbrBSGrid->n; i++) {
+ temp = (sbrEnvData->hSbrBSGrid->bs_rel_bord[i] - 2) >> 1;
+ payloadBits += FDKwriteBits(hBitStream, temp, SBR_REL_BITS);
+ }
+
+ temp = ceil_ln2(sbrEnvData->hSbrBSGrid->n + 2);
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->p, temp);
+
+ for (i = 0; i < sbrEnvData->hSbrBSGrid->n + 1; i++) {
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->v_f[i],
+ SBR_RES_BITS);
+ }
+ break;
+
+ case VARVAR:
+ temp = sbrEnvData->hSbrBSGrid->bs_abs_bord_0 - bufferFrameStart;
+ payloadBits += FDKwriteBits(hBitStream, temp, SBR_ABS_BITS);
+ temp = sbrEnvData->hSbrBSGrid->bs_abs_bord_1 -
+ (bufferFrameStart + numberTimeSlots);
+ payloadBits += FDKwriteBits(hBitStream, temp, SBR_ABS_BITS);
+
+ payloadBits += FDKwriteBits(
+ hBitStream, sbrEnvData->hSbrBSGrid->bs_num_rel_0, SBR_NUM_BITS);
+ payloadBits += FDKwriteBits(
+ hBitStream, sbrEnvData->hSbrBSGrid->bs_num_rel_1, SBR_NUM_BITS);
+
+ for (i = 0; i < sbrEnvData->hSbrBSGrid->bs_num_rel_0; i++) {
+ temp = (sbrEnvData->hSbrBSGrid->bs_rel_bord_0[i] - 2) >> 1;
+ payloadBits += FDKwriteBits(hBitStream, temp, SBR_REL_BITS);
+ }
+
+ for (i = 0; i < sbrEnvData->hSbrBSGrid->bs_num_rel_1; i++) {
+ temp = (sbrEnvData->hSbrBSGrid->bs_rel_bord_1[i] - 2) >> 1;
+ payloadBits += FDKwriteBits(hBitStream, temp, SBR_REL_BITS);
+ }
+
+ temp = ceil_ln2(sbrEnvData->hSbrBSGrid->bs_num_rel_0 +
+ sbrEnvData->hSbrBSGrid->bs_num_rel_1 + 2);
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->p, temp);
+
+ temp = sbrEnvData->hSbrBSGrid->bs_num_rel_0 +
+ sbrEnvData->hSbrBSGrid->bs_num_rel_1 + 1;
+
+ for (i = 0; i < temp; i++) {
+ payloadBits += FDKwriteBits(
+ hBitStream, sbrEnvData->hSbrBSGrid->v_fLR[i], SBR_RES_BITS);
+ }
+ break;
+ }
+
+ return payloadBits;
+}
+
+#define SBR_CLA_BITS_LD 1
+/*****************************************************************************
+
+ functionname: encodeLowDelaySbrGrid
+ description: if hBitStream != NULL writes bits that describes the
+ time/frequency grouping of a frame;
+ else counts them only
+ (this function only write the FIXFIXonly Bitstream data)
+ returns: number of bits written or counted
+ input:
+ output:
+
+*****************************************************************************/
+static int encodeLowDelaySbrGrid(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ const int transmitFreqs,
+ const UINT sbrSyntaxFlags) {
+ int payloadBits = 0;
+ int i;
+
+ /* write FIXFIXonly Grid */
+ /* write frameClass [1 bit] for FIXFIXonly Grid */
+ payloadBits += FDKwriteBits(hBitStream, 1, SBR_CLA_BITS_LD);
+
+ /* absolute Borders are fix: 0,X,X,X,nTimeSlots; so we dont have to transmit
+ * them */
+ /* only transmit the transient position! */
+ /* with this info (b1) we can reconstruct the Frame on Decoder side : */
+ /* border[0] = 0; border[1] = b1; border[2]=b1+2; border[3] = nrTimeSlots */
+
+ /* use 3 or 4bits for transient border (border) */
+ if (sbrEnvData->hSbrBSGrid->numberTimeSlots == 8)
+ payloadBits +=
+ FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->bs_abs_bord, 3);
+ else
+ payloadBits +=
+ FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->bs_abs_bord, 4);
+
+ if (transmitFreqs) {
+ /* write FreqRes grid */
+ for (i = 0; i < sbrEnvData->hSbrBSGrid->bs_num_env; i++) {
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->v_f[i],
+ SBR_RES_BITS);
+ }
+ }
+
+ return payloadBits;
+}
+
+/*****************************************************************************
+
+ functionname: encodeSbrDtdf
+ description: writes bits that describes the direction of the envelopes of a
+frame returns: number of bits written input: output:
+
+*****************************************************************************/
+static INT encodeSbrDtdf(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream) {
+ INT i, payloadBits = 0, noOfNoiseEnvelopes;
+
+ noOfNoiseEnvelopes = sbrEnvData->noOfEnvelopes > 1 ? 2 : 1;
+
+ for (i = 0; i < sbrEnvData->noOfEnvelopes; ++i) {
+ payloadBits +=
+ FDKwriteBits(hBitStream, sbrEnvData->domain_vec[i], SBR_DIR_BITS);
+ }
+ for (i = 0; i < noOfNoiseEnvelopes; ++i) {
+ payloadBits +=
+ FDKwriteBits(hBitStream, sbrEnvData->domain_vec_noise[i], SBR_DIR_BITS);
+ }
+
+ return payloadBits;
+}
+
+/*****************************************************************************
+
+ functionname: writeNoiseLevelData
+ description: writes bits corresponding to the noise-floor-level
+ returns: number of bits written
+ input:
+ output:
+
+*****************************************************************************/
+static INT writeNoiseLevelData(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream, INT coupling) {
+ INT j, i, payloadBits = 0;
+ INT nNoiseEnvelopes = sbrEnvData->noOfEnvelopes > 1 ? 2 : 1;
+
+ for (i = 0; i < nNoiseEnvelopes; i++) {
+ switch (sbrEnvData->domain_vec_noise[i]) {
+ case FREQ:
+ if (coupling && sbrEnvData->balance) {
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData->sbr_noise_levels[i * sbrEnvData->noOfnoisebands],
+ sbrEnvData->si_sbr_start_noise_bits_balance);
+ } else {
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData->sbr_noise_levels[i * sbrEnvData->noOfnoisebands],
+ sbrEnvData->si_sbr_start_noise_bits);
+ }
+
+ for (j = 1 + i * sbrEnvData->noOfnoisebands;
+ j < (sbrEnvData->noOfnoisebands * (1 + i)); j++) {
+ if (coupling) {
+ if (sbrEnvData->balance) {
+ /* coupling && balance */
+ payloadBits += FDKwriteBits(hBitStream,
+ sbrEnvData->hufftableNoiseBalanceFreqC
+ [sbrEnvData->sbr_noise_levels[j] +
+ CODE_BOOK_SCF_LAV_BALANCE11],
+ sbrEnvData->hufftableNoiseBalanceFreqL
+ [sbrEnvData->sbr_noise_levels[j] +
+ CODE_BOOK_SCF_LAV_BALANCE11]);
+ } else {
+ /* coupling && !balance */
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData->hufftableNoiseLevelFreqC
+ [sbrEnvData->sbr_noise_levels[j] + CODE_BOOK_SCF_LAV11],
+ sbrEnvData->hufftableNoiseLevelFreqL
+ [sbrEnvData->sbr_noise_levels[j] + CODE_BOOK_SCF_LAV11]);
+ }
+ } else {
+ /* !coupling */
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData
+ ->hufftableNoiseFreqC[sbrEnvData->sbr_noise_levels[j] +
+ CODE_BOOK_SCF_LAV11],
+ sbrEnvData
+ ->hufftableNoiseFreqL[sbrEnvData->sbr_noise_levels[j] +
+ CODE_BOOK_SCF_LAV11]);
+ }
+ }
+ break;
+
+ case TIME:
+ for (j = i * sbrEnvData->noOfnoisebands;
+ j < (sbrEnvData->noOfnoisebands * (1 + i)); j++) {
+ if (coupling) {
+ if (sbrEnvData->balance) {
+ /* coupling && balance */
+ payloadBits += FDKwriteBits(hBitStream,
+ sbrEnvData->hufftableNoiseBalanceTimeC
+ [sbrEnvData->sbr_noise_levels[j] +
+ CODE_BOOK_SCF_LAV_BALANCE11],
+ sbrEnvData->hufftableNoiseBalanceTimeL
+ [sbrEnvData->sbr_noise_levels[j] +
+ CODE_BOOK_SCF_LAV_BALANCE11]);
+ } else {
+ /* coupling && !balance */
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData->hufftableNoiseLevelTimeC
+ [sbrEnvData->sbr_noise_levels[j] + CODE_BOOK_SCF_LAV11],
+ sbrEnvData->hufftableNoiseLevelTimeL
+ [sbrEnvData->sbr_noise_levels[j] + CODE_BOOK_SCF_LAV11]);
+ }
+ } else {
+ /* !coupling */
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData
+ ->hufftableNoiseLevelTimeC[sbrEnvData->sbr_noise_levels[j] +
+ CODE_BOOK_SCF_LAV11],
+ sbrEnvData
+ ->hufftableNoiseLevelTimeL[sbrEnvData->sbr_noise_levels[j] +
+ CODE_BOOK_SCF_LAV11]);
+ }
+ }
+ break;
+ }
+ }
+ return payloadBits;
+}
+
+/*****************************************************************************
+
+ functionname: writeEnvelopeData
+ description: writes bits corresponding to the envelope
+ returns: number of bits written
+ input:
+ output:
+
+*****************************************************************************/
+static INT writeEnvelopeData(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream, INT coupling) {
+ INT payloadBits = 0, j, i, delta;
+
+ for (j = 0; j < sbrEnvData->noOfEnvelopes;
+ j++) { /* loop over all envelopes */
+ if (sbrEnvData->domain_vec[j] == FREQ) {
+ if (coupling && sbrEnvData->balance) {
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->ienvelope[j][0],
+ sbrEnvData->si_sbr_start_env_bits_balance);
+ } else {
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->ienvelope[j][0],
+ sbrEnvData->si_sbr_start_env_bits);
+ }
+ }
+
+ for (i = 1 - sbrEnvData->domain_vec[j]; i < sbrEnvData->noScfBands[j];
+ i++) {
+ delta = sbrEnvData->ienvelope[j][i];
+ if (coupling && sbrEnvData->balance) {
+ FDK_ASSERT(fixp_abs(delta) <= sbrEnvData->codeBookScfLavBalance);
+ } else {
+ FDK_ASSERT(fixp_abs(delta) <= sbrEnvData->codeBookScfLav);
+ }
+ if (coupling) {
+ if (sbrEnvData->balance) {
+ if (sbrEnvData->domain_vec[j]) {
+ /* coupling && balance && TIME */
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData
+ ->hufftableBalanceTimeC[delta +
+ sbrEnvData->codeBookScfLavBalance],
+ sbrEnvData
+ ->hufftableBalanceTimeL[delta +
+ sbrEnvData->codeBookScfLavBalance]);
+ } else {
+ /* coupling && balance && FREQ */
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData
+ ->hufftableBalanceFreqC[delta +
+ sbrEnvData->codeBookScfLavBalance],
+ sbrEnvData
+ ->hufftableBalanceFreqL[delta +
+ sbrEnvData->codeBookScfLavBalance]);
+ }
+ } else {
+ if (sbrEnvData->domain_vec[j]) {
+ /* coupling && !balance && TIME */
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData
+ ->hufftableLevelTimeC[delta + sbrEnvData->codeBookScfLav],
+ sbrEnvData
+ ->hufftableLevelTimeL[delta + sbrEnvData->codeBookScfLav]);
+ } else {
+ /* coupling && !balance && FREQ */
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData
+ ->hufftableLevelFreqC[delta + sbrEnvData->codeBookScfLav],
+ sbrEnvData
+ ->hufftableLevelFreqL[delta + sbrEnvData->codeBookScfLav]);
+ }
+ }
+ } else {
+ if (sbrEnvData->domain_vec[j]) {
+ /* !coupling && TIME */
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData->hufftableTimeC[delta + sbrEnvData->codeBookScfLav],
+ sbrEnvData->hufftableTimeL[delta + sbrEnvData->codeBookScfLav]);
+ } else {
+ /* !coupling && FREQ */
+ payloadBits += FDKwriteBits(
+ hBitStream,
+ sbrEnvData->hufftableFreqC[delta + sbrEnvData->codeBookScfLav],
+ sbrEnvData->hufftableFreqL[delta + sbrEnvData->codeBookScfLav]);
+ }
+ }
+ }
+ }
+ return payloadBits;
+}
+
+/*****************************************************************************
+
+ functionname: encodeExtendedData
+ description: writes bits corresponding to the extended data
+ returns: number of bits written
+ input:
+ output:
+
+*****************************************************************************/
+static INT encodeExtendedData(HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_FDK_BITSTREAM hBitStream) {
+ INT extDataSize;
+ INT payloadBits = 0;
+
+ extDataSize = getSbrExtendedDataSize(hParametricStereo);
+
+ if (extDataSize != 0) {
+ INT maxExtSize = (1 << SI_SBR_EXTENSION_SIZE_BITS) - 1;
+ INT writtenNoBits = 0; /* needed to byte align the extended data */
+
+ payloadBits += FDKwriteBits(hBitStream, 1, SI_SBR_EXTENDED_DATA_BITS);
+ FDK_ASSERT(extDataSize <= SBR_EXTENDED_DATA_MAX_CNT);
+
+ if (extDataSize < maxExtSize) {
+ payloadBits +=
+ FDKwriteBits(hBitStream, extDataSize, SI_SBR_EXTENSION_SIZE_BITS);
+ } else {
+ payloadBits +=
+ FDKwriteBits(hBitStream, maxExtSize, SI_SBR_EXTENSION_SIZE_BITS);
+ payloadBits += FDKwriteBits(hBitStream, extDataSize - maxExtSize,
+ SI_SBR_EXTENSION_ESC_COUNT_BITS);
+ }
+
+ /* parametric coding signalled here? */
+ if (hParametricStereo) {
+ writtenNoBits += FDKwriteBits(hBitStream, EXTENSION_ID_PS_CODING,
+ SI_SBR_EXTENSION_ID_BITS);
+ writtenNoBits +=
+ FDKsbrEnc_PSEnc_WritePSData(hParametricStereo, hBitStream);
+ }
+
+ payloadBits += writtenNoBits;
+
+ /* byte alignment */
+ writtenNoBits = writtenNoBits % 8;
+ if (writtenNoBits)
+ payloadBits += FDKwriteBits(hBitStream, 0, (8 - writtenNoBits));
+ } else {
+ payloadBits += FDKwriteBits(hBitStream, 0, SI_SBR_EXTENDED_DATA_BITS);
+ }
+
+ return payloadBits;
+}
+
+/*****************************************************************************
+
+ functionname: writeSyntheticCodingData
+ description: writes bits corresponding to the "synthetic-coding"-extension
+ returns: number of bits written
+ input:
+ output:
+
+*****************************************************************************/
+static INT writeSyntheticCodingData(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_FDK_BITSTREAM hBitStream)
+
+{
+ INT i;
+ INT payloadBits = 0;
+
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->addHarmonicFlag, 1);
+
+ if (sbrEnvData->addHarmonicFlag) {
+ for (i = 0; i < sbrEnvData->noHarmonics; i++) {
+ payloadBits += FDKwriteBits(hBitStream, sbrEnvData->addHarmonic[i], 1);
+ }
+ }
+
+ return payloadBits;
+}
+
+/*****************************************************************************
+
+ functionname: getSbrExtendedDataSize
+ description: counts the number of bits needed for encoding the
+ extended data (including extension id)
+
+ returns: number of bits needed for the extended data
+ input:
+ output:
+
+*****************************************************************************/
+static INT getSbrExtendedDataSize(HANDLE_PARAMETRIC_STEREO hParametricStereo) {
+ INT extDataBits = 0;
+
+ /* add your new extended data counting methods here */
+
+ /*
+ no extended data
+ */
+
+ if (hParametricStereo) {
+ /* PS extended data */
+ extDataBits += SI_SBR_EXTENSION_ID_BITS;
+ extDataBits += FDKsbrEnc_PSEnc_WritePSData(hParametricStereo, NULL);
+ }
+
+ return (extDataBits + 7) >> 3;
+}
diff --git a/fdk-aac/libSBRenc/src/bit_sbr.h b/fdk-aac/libSBRenc/src/bit_sbr.h
new file mode 100644
index 0000000..e90f52c
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/bit_sbr.h
@@ -0,0 +1,267 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief SBR bit writing $Revision: 92790 $
+*/
+#ifndef BIT_SBR_H
+#define BIT_SBR_H
+
+#include "sbr_def.h"
+#include "cmondata.h"
+#include "fram_gen.h"
+
+struct SBR_ENV_DATA;
+
+struct SBR_BITSTREAM_DATA {
+ INT TotalBits;
+ INT PayloadBits;
+ INT FillBits;
+ INT HeaderActive;
+ INT HeaderActiveDelay; /**< sbr payload and its header is delayed depending on
+ encoder configuration*/
+ INT NrSendHeaderData; /**< input from commandline */
+ INT CountSendHeaderData; /**< modulo count. If < 0 then no counting is done
+ (no SBR headers) */
+ INT rightBorderFIX; /**< force VARFIX or FIXFIX frames */
+};
+
+typedef struct SBR_BITSTREAM_DATA *HANDLE_SBR_BITSTREAM_DATA;
+
+struct SBR_HEADER_DATA {
+ AMP_RES sbr_amp_res;
+ INT sbr_start_frequency;
+ INT sbr_stop_frequency;
+ INT sbr_xover_band;
+ INT sbr_noise_bands;
+ INT sbr_data_extra;
+ INT header_extra_1;
+ INT header_extra_2;
+ INT sbr_lc_stereo_mode;
+ INT sbr_limiter_bands;
+ INT sbr_limiter_gains;
+ INT sbr_interpol_freq;
+ INT sbr_smoothing_length;
+ INT alterScale;
+ INT freqScale;
+
+ /*
+ element of channelpairelement
+ */
+ INT coupling;
+ INT prev_coupling;
+
+ /*
+ element of singlechannelelement
+ */
+};
+typedef struct SBR_HEADER_DATA *HANDLE_SBR_HEADER_DATA;
+
+struct SBR_ENV_DATA {
+ INT sbr_xpos_ctrl;
+ FREQ_RES freq_res_fixfix[2];
+ UCHAR fResTransIsLow;
+
+ INVF_MODE sbr_invf_mode;
+ INVF_MODE sbr_invf_mode_vec[MAX_NUM_NOISE_VALUES];
+
+ XPOS_MODE sbr_xpos_mode;
+
+ INT ienvelope[MAX_ENVELOPES][MAX_FREQ_COEFFS];
+
+ INT codeBookScfLavBalance;
+ INT codeBookScfLav;
+ const INT *hufftableTimeC;
+ const INT *hufftableFreqC;
+ const UCHAR *hufftableTimeL;
+ const UCHAR *hufftableFreqL;
+
+ const INT *hufftableLevelTimeC;
+ const INT *hufftableBalanceTimeC;
+ const INT *hufftableLevelFreqC;
+ const INT *hufftableBalanceFreqC;
+ const UCHAR *hufftableLevelTimeL;
+ const UCHAR *hufftableBalanceTimeL;
+ const UCHAR *hufftableLevelFreqL;
+ const UCHAR *hufftableBalanceFreqL;
+
+ const UCHAR *hufftableNoiseTimeL;
+ const INT *hufftableNoiseTimeC;
+ const UCHAR *hufftableNoiseFreqL;
+ const INT *hufftableNoiseFreqC;
+
+ const UCHAR *hufftableNoiseLevelTimeL;
+ const INT *hufftableNoiseLevelTimeC;
+ const UCHAR *hufftableNoiseBalanceTimeL;
+ const INT *hufftableNoiseBalanceTimeC;
+ const UCHAR *hufftableNoiseLevelFreqL;
+ const INT *hufftableNoiseLevelFreqC;
+ const UCHAR *hufftableNoiseBalanceFreqL;
+ const INT *hufftableNoiseBalanceFreqC;
+
+ HANDLE_SBR_GRID hSbrBSGrid;
+
+ INT noHarmonics;
+ INT addHarmonicFlag;
+ UCHAR addHarmonic[MAX_FREQ_COEFFS];
+
+ /* calculated helper vars */
+ INT si_sbr_start_env_bits_balance;
+ INT si_sbr_start_env_bits;
+ INT si_sbr_start_noise_bits_balance;
+ INT si_sbr_start_noise_bits;
+
+ INT noOfEnvelopes;
+ INT noScfBands[MAX_ENVELOPES];
+ INT domain_vec[MAX_ENVELOPES];
+ INT domain_vec_noise[MAX_ENVELOPES];
+ SCHAR sbr_noise_levels[MAX_FREQ_COEFFS];
+ INT noOfnoisebands;
+
+ INT balance;
+ AMP_RES init_sbr_amp_res;
+ 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 */
+ INT extended_data;
+ INT extension_size;
+ INT extension_id;
+ UCHAR extended_data_buffer[SBR_EXTENDED_DATA_MAX_CNT];
+
+ UCHAR ldGrid;
+};
+typedef struct SBR_ENV_DATA *HANDLE_SBR_ENV_DATA;
+
+INT FDKsbrEnc_WriteEnvSingleChannelElement(
+ struct SBR_HEADER_DATA *sbrHeaderData,
+ struct T_PARAMETRIC_STEREO *hParametricStereo,
+ struct SBR_BITSTREAM_DATA *sbrBitstreamData,
+ struct SBR_ENV_DATA *sbrEnvData, struct COMMON_DATA *cmonData,
+ UINT sbrSyntaxFlags);
+
+INT FDKsbrEnc_WriteEnvChannelPairElement(
+ struct SBR_HEADER_DATA *sbrHeaderData,
+ struct T_PARAMETRIC_STEREO *hParametricStereo,
+ struct SBR_BITSTREAM_DATA *sbrBitstreamData,
+ struct SBR_ENV_DATA *sbrEnvDataLeft, struct SBR_ENV_DATA *sbrEnvDataRight,
+ struct COMMON_DATA *cmonData, UINT sbrSyntaxFlags);
+
+INT FDKsbrEnc_CountSbrChannelPairElement(
+ struct SBR_HEADER_DATA *sbrHeaderData,
+ struct T_PARAMETRIC_STEREO *hParametricStereo,
+ struct SBR_BITSTREAM_DATA *sbrBitstreamData,
+ struct SBR_ENV_DATA *sbrEnvDataLeft, struct SBR_ENV_DATA *sbrEnvDataRight,
+ struct COMMON_DATA *cmonData, UINT sbrSyntaxFlags);
+
+/* debugging and tuning functions */
+
+/*#define SBR_ENV_STATISTICS */
+
+/*#define SBR_PAYLOAD_MONITOR*/
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/cmondata.h b/fdk-aac/libSBRenc/src/cmondata.h
new file mode 100644
index 0000000..0779b4d
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/cmondata.h
@@ -0,0 +1,127 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Core Coder's and SBR's shared data structure definition $Revision:
+ 92790 $
+*/
+#ifndef CMONDATA_H
+#define CMONDATA_H
+
+#include "FDK_bitstream.h"
+
+struct COMMON_DATA {
+ INT sbrHdrBits; /**< number of SBR header bits */
+ INT sbrDataBits; /**< number of SBR data bits */
+ INT sbrFillBits; /**< number of SBR fill bits */
+ FDK_BITSTREAM sbrBitbuf; /**< the SBR data bitbuffer */
+ FDK_BITSTREAM tmpWriteBitbuf; /**< helper var for writing header*/
+ INT xOverFreq; /**< the SBR crossover frequency */
+ INT dynBwEnabled; /**< indicates if dynamic bandwidth is enabled */
+ INT sbrNumChannels; /**< number of channels (meaning mono or stereo) */
+ INT dynXOverFreqEnc; /**< encoder dynamic crossover frequency */
+};
+
+typedef struct COMMON_DATA *HANDLE_COMMON_DATA;
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/code_env.cpp b/fdk-aac/libSBRenc/src/code_env.cpp
new file mode 100644
index 0000000..fb0f6a4
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/code_env.cpp
@@ -0,0 +1,602 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "code_env.h"
+#include "sbrenc_rom.h"
+
+/*****************************************************************************
+
+ functionname: FDKsbrEnc_InitSbrHuffmanTables
+ description: initializes Huffman Tables dependent on chosen amp_res
+ returns: error handle
+ input:
+ output:
+
+*****************************************************************************/
+INT FDKsbrEnc_InitSbrHuffmanTables(HANDLE_SBR_ENV_DATA sbrEnvData,
+ HANDLE_SBR_CODE_ENVELOPE henv,
+ HANDLE_SBR_CODE_ENVELOPE hnoise,
+ AMP_RES amp_res) {
+ if ((!henv) || (!hnoise) || (!sbrEnvData)) return (1); /* not init. */
+
+ sbrEnvData->init_sbr_amp_res = amp_res;
+
+ switch (amp_res) {
+ case SBR_AMP_RES_3_0:
+ /*envelope data*/
+
+ /*Level/Pan - coding */
+ sbrEnvData->hufftableLevelTimeC = v_Huff_envelopeLevelC11T;
+ sbrEnvData->hufftableLevelTimeL = v_Huff_envelopeLevelL11T;
+ sbrEnvData->hufftableBalanceTimeC = bookSbrEnvBalanceC11T;
+ sbrEnvData->hufftableBalanceTimeL = bookSbrEnvBalanceL11T;
+
+ sbrEnvData->hufftableLevelFreqC = v_Huff_envelopeLevelC11F;
+ sbrEnvData->hufftableLevelFreqL = v_Huff_envelopeLevelL11F;
+ sbrEnvData->hufftableBalanceFreqC = bookSbrEnvBalanceC11F;
+ sbrEnvData->hufftableBalanceFreqL = bookSbrEnvBalanceL11F;
+
+ /*Right/Left - coding */
+ sbrEnvData->hufftableTimeC = v_Huff_envelopeLevelC11T;
+ sbrEnvData->hufftableTimeL = v_Huff_envelopeLevelL11T;
+ sbrEnvData->hufftableFreqC = v_Huff_envelopeLevelC11F;
+ sbrEnvData->hufftableFreqL = v_Huff_envelopeLevelL11F;
+
+ sbrEnvData->codeBookScfLavBalance = CODE_BOOK_SCF_LAV_BALANCE11;
+ sbrEnvData->codeBookScfLav = CODE_BOOK_SCF_LAV11;
+
+ sbrEnvData->si_sbr_start_env_bits = SI_SBR_START_ENV_BITS_AMP_RES_3_0;
+ sbrEnvData->si_sbr_start_env_bits_balance =
+ SI_SBR_START_ENV_BITS_BALANCE_AMP_RES_3_0;
+ break;
+
+ case SBR_AMP_RES_1_5:
+ /*envelope data*/
+
+ /*Level/Pan - coding */
+ sbrEnvData->hufftableLevelTimeC = v_Huff_envelopeLevelC10T;
+ sbrEnvData->hufftableLevelTimeL = v_Huff_envelopeLevelL10T;
+ sbrEnvData->hufftableBalanceTimeC = bookSbrEnvBalanceC10T;
+ sbrEnvData->hufftableBalanceTimeL = bookSbrEnvBalanceL10T;
+
+ sbrEnvData->hufftableLevelFreqC = v_Huff_envelopeLevelC10F;
+ sbrEnvData->hufftableLevelFreqL = v_Huff_envelopeLevelL10F;
+ sbrEnvData->hufftableBalanceFreqC = bookSbrEnvBalanceC10F;
+ sbrEnvData->hufftableBalanceFreqL = bookSbrEnvBalanceL10F;
+
+ /*Right/Left - coding */
+ sbrEnvData->hufftableTimeC = v_Huff_envelopeLevelC10T;
+ sbrEnvData->hufftableTimeL = v_Huff_envelopeLevelL10T;
+ sbrEnvData->hufftableFreqC = v_Huff_envelopeLevelC10F;
+ sbrEnvData->hufftableFreqL = v_Huff_envelopeLevelL10F;
+
+ sbrEnvData->codeBookScfLavBalance = CODE_BOOK_SCF_LAV_BALANCE10;
+ sbrEnvData->codeBookScfLav = CODE_BOOK_SCF_LAV10;
+
+ sbrEnvData->si_sbr_start_env_bits = SI_SBR_START_ENV_BITS_AMP_RES_1_5;
+ sbrEnvData->si_sbr_start_env_bits_balance =
+ SI_SBR_START_ENV_BITS_BALANCE_AMP_RES_1_5;
+ break;
+
+ default:
+ return (1); /* undefined amp_res mode */
+ }
+
+ /* these are common to both amp_res values */
+ /*Noise data*/
+
+ /*Level/Pan - coding */
+ sbrEnvData->hufftableNoiseLevelTimeC = v_Huff_NoiseLevelC11T;
+ sbrEnvData->hufftableNoiseLevelTimeL = v_Huff_NoiseLevelL11T;
+ sbrEnvData->hufftableNoiseBalanceTimeC = bookSbrNoiseBalanceC11T;
+ sbrEnvData->hufftableNoiseBalanceTimeL = bookSbrNoiseBalanceL11T;
+
+ sbrEnvData->hufftableNoiseLevelFreqC = v_Huff_envelopeLevelC11F;
+ sbrEnvData->hufftableNoiseLevelFreqL = v_Huff_envelopeLevelL11F;
+ sbrEnvData->hufftableNoiseBalanceFreqC = bookSbrEnvBalanceC11F;
+ sbrEnvData->hufftableNoiseBalanceFreqL = bookSbrEnvBalanceL11F;
+
+ /*Right/Left - coding */
+ sbrEnvData->hufftableNoiseTimeC = v_Huff_NoiseLevelC11T;
+ sbrEnvData->hufftableNoiseTimeL = v_Huff_NoiseLevelL11T;
+ sbrEnvData->hufftableNoiseFreqC = v_Huff_envelopeLevelC11F;
+ sbrEnvData->hufftableNoiseFreqL = v_Huff_envelopeLevelL11F;
+
+ sbrEnvData->si_sbr_start_noise_bits = SI_SBR_START_NOISE_BITS_AMP_RES_3_0;
+ sbrEnvData->si_sbr_start_noise_bits_balance =
+ SI_SBR_START_NOISE_BITS_BALANCE_AMP_RES_3_0;
+
+ /* init envelope tables and codebooks */
+ henv->codeBookScfLavBalanceTime = sbrEnvData->codeBookScfLavBalance;
+ henv->codeBookScfLavBalanceFreq = sbrEnvData->codeBookScfLavBalance;
+ henv->codeBookScfLavLevelTime = sbrEnvData->codeBookScfLav;
+ henv->codeBookScfLavLevelFreq = sbrEnvData->codeBookScfLav;
+ henv->codeBookScfLavTime = sbrEnvData->codeBookScfLav;
+ henv->codeBookScfLavFreq = sbrEnvData->codeBookScfLav;
+
+ henv->hufftableLevelTimeL = sbrEnvData->hufftableLevelTimeL;
+ henv->hufftableBalanceTimeL = sbrEnvData->hufftableBalanceTimeL;
+ henv->hufftableTimeL = sbrEnvData->hufftableTimeL;
+ henv->hufftableLevelFreqL = sbrEnvData->hufftableLevelFreqL;
+ henv->hufftableBalanceFreqL = sbrEnvData->hufftableBalanceFreqL;
+ henv->hufftableFreqL = sbrEnvData->hufftableFreqL;
+
+ henv->codeBookScfLavFreq = sbrEnvData->codeBookScfLav;
+ henv->codeBookScfLavTime = sbrEnvData->codeBookScfLav;
+
+ henv->start_bits = sbrEnvData->si_sbr_start_env_bits;
+ henv->start_bits_balance = sbrEnvData->si_sbr_start_env_bits_balance;
+
+ /* init noise tables and codebooks */
+
+ hnoise->codeBookScfLavBalanceTime = CODE_BOOK_SCF_LAV_BALANCE11;
+ hnoise->codeBookScfLavBalanceFreq = CODE_BOOK_SCF_LAV_BALANCE11;
+ hnoise->codeBookScfLavLevelTime = CODE_BOOK_SCF_LAV11;
+ hnoise->codeBookScfLavLevelFreq = CODE_BOOK_SCF_LAV11;
+ hnoise->codeBookScfLavTime = CODE_BOOK_SCF_LAV11;
+ hnoise->codeBookScfLavFreq = CODE_BOOK_SCF_LAV11;
+
+ hnoise->hufftableLevelTimeL = sbrEnvData->hufftableNoiseLevelTimeL;
+ hnoise->hufftableBalanceTimeL = sbrEnvData->hufftableNoiseBalanceTimeL;
+ hnoise->hufftableTimeL = sbrEnvData->hufftableNoiseTimeL;
+ hnoise->hufftableLevelFreqL = sbrEnvData->hufftableNoiseLevelFreqL;
+ hnoise->hufftableBalanceFreqL = sbrEnvData->hufftableNoiseBalanceFreqL;
+ hnoise->hufftableFreqL = sbrEnvData->hufftableNoiseFreqL;
+
+ hnoise->start_bits = sbrEnvData->si_sbr_start_noise_bits;
+ hnoise->start_bits_balance = sbrEnvData->si_sbr_start_noise_bits_balance;
+
+ /* No delta coding in time from the previous frame due to 1.5dB FIx-FIX rule
+ */
+ henv->upDate = 0;
+ hnoise->upDate = 0;
+ return (0);
+}
+
+/*******************************************************************************
+ Functionname: indexLow2High
+ *******************************************************************************
+
+ Description: Nice small patch-functions in order to cope with non-factor-2
+ ratios between high-res and low-res
+
+ Arguments: INT offset, INT index, FREQ_RES res
+
+ Return: INT
+
+*******************************************************************************/
+static INT indexLow2High(INT offset, INT index, FREQ_RES res) {
+ if (res == FREQ_RES_LOW) {
+ if (offset >= 0) {
+ if (index < offset)
+ return (index);
+ else
+ return (2 * index - offset);
+ } else {
+ offset = -offset;
+ if (index < offset)
+ return (2 * index + index);
+ else
+ return (2 * index + offset);
+ }
+ } else
+ return (index);
+}
+
+/*******************************************************************************
+ Functionname: mapLowResEnergyVal
+ *******************************************************************************
+
+ Description:
+
+ Arguments: INT currVal,INT* prevData, INT offset, INT index, FREQ_RES res
+
+ Return: none
+
+*******************************************************************************/
+static void mapLowResEnergyVal(SCHAR currVal, SCHAR *prevData, INT offset,
+ INT index, FREQ_RES res) {
+ if (res == FREQ_RES_LOW) {
+ if (offset >= 0) {
+ if (index < offset)
+ prevData[index] = currVal;
+ else {
+ prevData[2 * index - offset] = currVal;
+ prevData[2 * index + 1 - offset] = currVal;
+ }
+ } else {
+ offset = -offset;
+ if (index < offset) {
+ prevData[3 * index] = currVal;
+ prevData[3 * index + 1] = currVal;
+ prevData[3 * index + 2] = currVal;
+ } else {
+ prevData[2 * index + offset] = currVal;
+ prevData[2 * index + 1 + offset] = currVal;
+ }
+ }
+ } else
+ prevData[index] = currVal;
+}
+
+/*******************************************************************************
+ Functionname: computeBits
+ *******************************************************************************
+
+ Description:
+
+ Arguments: INT delta,
+ INT codeBookScfLavLevel,
+ INT codeBookScfLavBalance,
+ const UCHAR * hufftableLevel,
+ const UCHAR * hufftableBalance, INT coupling, INT channel)
+
+ Return: INT
+
+*******************************************************************************/
+static INT computeBits(SCHAR *delta, INT codeBookScfLavLevel,
+ INT codeBookScfLavBalance, const UCHAR *hufftableLevel,
+ const UCHAR *hufftableBalance, INT coupling,
+ INT channel) {
+ INT index;
+ INT delta_bits = 0;
+
+ if (coupling) {
+ if (channel == 1) {
+ if (*delta < 0)
+ index = fixMax(*delta, -codeBookScfLavBalance);
+ else
+ index = fixMin(*delta, codeBookScfLavBalance);
+
+ if (index != *delta) {
+ *delta = index;
+ return (10000);
+ }
+
+ delta_bits = hufftableBalance[index + codeBookScfLavBalance];
+ } else {
+ if (*delta < 0)
+ index = fixMax(*delta, -codeBookScfLavLevel);
+ else
+ index = fixMin(*delta, codeBookScfLavLevel);
+
+ if (index != *delta) {
+ *delta = index;
+ return (10000);
+ }
+ delta_bits = hufftableLevel[index + codeBookScfLavLevel];
+ }
+ } else {
+ if (*delta < 0)
+ index = fixMax(*delta, -codeBookScfLavLevel);
+ else
+ index = fixMin(*delta, codeBookScfLavLevel);
+
+ if (index != *delta) {
+ *delta = index;
+ return (10000);
+ }
+ delta_bits = hufftableLevel[index + codeBookScfLavLevel];
+ }
+
+ return (delta_bits);
+}
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_codeEnvelope
+ *******************************************************************************
+
+ Description:
+
+ Arguments: INT *sfb_nrg,
+ const FREQ_RES *freq_res,
+ SBR_CODE_ENVELOPE * h_sbrCodeEnvelope,
+ INT *directionVec, INT scalable, INT nEnvelopes, INT channel,
+ INT headerActive)
+
+ Return: none
+ h_sbrCodeEnvelope->sfb_nrg_prev is modified !
+ sfb_nrg is modified
+ h_sbrCodeEnvelope->update is modfied !
+ *directionVec is modified
+
+*******************************************************************************/
+void FDKsbrEnc_codeEnvelope(SCHAR *sfb_nrg, const FREQ_RES *freq_res,
+ SBR_CODE_ENVELOPE *h_sbrCodeEnvelope,
+ INT *directionVec, INT coupling, INT nEnvelopes,
+ INT channel, INT headerActive) {
+ INT i, no_of_bands, band;
+ FIXP_DBL tmp1, tmp2, tmp3, dF_edge_1stEnv;
+ SCHAR *ptr_nrg;
+
+ INT codeBookScfLavLevelTime;
+ INT codeBookScfLavLevelFreq;
+ INT codeBookScfLavBalanceTime;
+ INT codeBookScfLavBalanceFreq;
+ const UCHAR *hufftableLevelTimeL;
+ const UCHAR *hufftableBalanceTimeL;
+ const UCHAR *hufftableLevelFreqL;
+ const UCHAR *hufftableBalanceFreqL;
+
+ INT offset = h_sbrCodeEnvelope->offset;
+ INT envDataTableCompFactor;
+
+ INT delta_F_bits = 0, delta_T_bits = 0;
+ INT use_dT;
+
+ SCHAR delta_F[MAX_FREQ_COEFFS];
+ SCHAR delta_T[MAX_FREQ_COEFFS];
+ SCHAR last_nrg, curr_nrg;
+
+ tmp1 = FL2FXCONST_DBL(0.5f) >> (DFRACT_BITS - 16 - 1);
+ tmp2 = h_sbrCodeEnvelope->dF_edge_1stEnv >> (DFRACT_BITS - 16);
+ tmp3 = (FIXP_DBL)fMult(h_sbrCodeEnvelope->dF_edge_incr,
+ ((FIXP_DBL)h_sbrCodeEnvelope->dF_edge_incr_fac) << 15);
+
+ dF_edge_1stEnv = tmp1 + tmp2 + tmp3;
+
+ if (coupling) {
+ codeBookScfLavLevelTime = h_sbrCodeEnvelope->codeBookScfLavLevelTime;
+ codeBookScfLavLevelFreq = h_sbrCodeEnvelope->codeBookScfLavLevelFreq;
+ codeBookScfLavBalanceTime = h_sbrCodeEnvelope->codeBookScfLavBalanceTime;
+ codeBookScfLavBalanceFreq = h_sbrCodeEnvelope->codeBookScfLavBalanceFreq;
+ hufftableLevelTimeL = h_sbrCodeEnvelope->hufftableLevelTimeL;
+ hufftableBalanceTimeL = h_sbrCodeEnvelope->hufftableBalanceTimeL;
+ hufftableLevelFreqL = h_sbrCodeEnvelope->hufftableLevelFreqL;
+ hufftableBalanceFreqL = h_sbrCodeEnvelope->hufftableBalanceFreqL;
+ } else {
+ codeBookScfLavLevelTime = h_sbrCodeEnvelope->codeBookScfLavTime;
+ codeBookScfLavLevelFreq = h_sbrCodeEnvelope->codeBookScfLavFreq;
+ codeBookScfLavBalanceTime = h_sbrCodeEnvelope->codeBookScfLavTime;
+ codeBookScfLavBalanceFreq = h_sbrCodeEnvelope->codeBookScfLavFreq;
+ hufftableLevelTimeL = h_sbrCodeEnvelope->hufftableTimeL;
+ hufftableBalanceTimeL = h_sbrCodeEnvelope->hufftableTimeL;
+ hufftableLevelFreqL = h_sbrCodeEnvelope->hufftableFreqL;
+ hufftableBalanceFreqL = h_sbrCodeEnvelope->hufftableFreqL;
+ }
+
+ if (coupling == 1 && channel == 1)
+ envDataTableCompFactor =
+ 1; /*should be one when the new huffman-tables are ready*/
+ else
+ envDataTableCompFactor = 0;
+
+ if (h_sbrCodeEnvelope->deltaTAcrossFrames == 0) h_sbrCodeEnvelope->upDate = 0;
+
+ /* no delta coding in time in case of a header */
+ if (headerActive) h_sbrCodeEnvelope->upDate = 0;
+
+ for (i = 0; i < nEnvelopes; i++) {
+ if (freq_res[i] == FREQ_RES_HIGH)
+ no_of_bands = h_sbrCodeEnvelope->nSfb[FREQ_RES_HIGH];
+ else
+ no_of_bands = h_sbrCodeEnvelope->nSfb[FREQ_RES_LOW];
+
+ ptr_nrg = sfb_nrg;
+ curr_nrg = *ptr_nrg;
+
+ delta_F[0] = curr_nrg >> envDataTableCompFactor;
+
+ if (coupling && channel == 1)
+ delta_F_bits = h_sbrCodeEnvelope->start_bits_balance;
+ else
+ delta_F_bits = h_sbrCodeEnvelope->start_bits;
+
+ if (h_sbrCodeEnvelope->upDate != 0) {
+ delta_T[0] = (curr_nrg - h_sbrCodeEnvelope->sfb_nrg_prev[0]) >>
+ envDataTableCompFactor;
+
+ delta_T_bits = computeBits(&delta_T[0], codeBookScfLavLevelTime,
+ codeBookScfLavBalanceTime, hufftableLevelTimeL,
+ hufftableBalanceTimeL, coupling, channel);
+ }
+
+ mapLowResEnergyVal(curr_nrg, h_sbrCodeEnvelope->sfb_nrg_prev, offset, 0,
+ freq_res[i]);
+
+ /* ensure that nrg difference is not higher than codeBookScfLavXXXFreq */
+ if (coupling && channel == 1) {
+ for (band = no_of_bands - 1; band > 0; band--) {
+ if (ptr_nrg[band] - ptr_nrg[band - 1] > codeBookScfLavBalanceFreq) {
+ ptr_nrg[band - 1] = ptr_nrg[band] - codeBookScfLavBalanceFreq;
+ }
+ }
+ for (band = 1; band < no_of_bands; band++) {
+ if (ptr_nrg[band - 1] - ptr_nrg[band] > codeBookScfLavBalanceFreq) {
+ ptr_nrg[band] = ptr_nrg[band - 1] - codeBookScfLavBalanceFreq;
+ }
+ }
+ } else {
+ for (band = no_of_bands - 1; band > 0; band--) {
+ if (ptr_nrg[band] - ptr_nrg[band - 1] > codeBookScfLavLevelFreq) {
+ ptr_nrg[band - 1] = ptr_nrg[band] - codeBookScfLavLevelFreq;
+ }
+ }
+ for (band = 1; band < no_of_bands; band++) {
+ if (ptr_nrg[band - 1] - ptr_nrg[band] > codeBookScfLavLevelFreq) {
+ ptr_nrg[band] = ptr_nrg[band - 1] - codeBookScfLavLevelFreq;
+ }
+ }
+ }
+
+ /* Coding loop*/
+ for (band = 1; band < no_of_bands; band++) {
+ last_nrg = (*ptr_nrg);
+ ptr_nrg++;
+ curr_nrg = (*ptr_nrg);
+
+ delta_F[band] = (curr_nrg - last_nrg) >> envDataTableCompFactor;
+
+ delta_F_bits += computeBits(
+ &delta_F[band], codeBookScfLavLevelFreq, codeBookScfLavBalanceFreq,
+ hufftableLevelFreqL, hufftableBalanceFreqL, coupling, channel);
+
+ if (h_sbrCodeEnvelope->upDate != 0) {
+ delta_T[band] =
+ curr_nrg -
+ h_sbrCodeEnvelope
+ ->sfb_nrg_prev[indexLow2High(offset, band, freq_res[i])];
+ delta_T[band] = delta_T[band] >> envDataTableCompFactor;
+ }
+
+ mapLowResEnergyVal(curr_nrg, h_sbrCodeEnvelope->sfb_nrg_prev, offset,
+ band, freq_res[i]);
+
+ if (h_sbrCodeEnvelope->upDate != 0) {
+ delta_T_bits += computeBits(
+ &delta_T[band], codeBookScfLavLevelTime, codeBookScfLavBalanceTime,
+ hufftableLevelTimeL, hufftableBalanceTimeL, coupling, channel);
+ }
+ }
+
+ /* Replace sfb_nrg with deltacoded samples and set flag */
+ if (i == 0) {
+ INT tmp_bits;
+ tmp_bits = (((delta_T_bits * dF_edge_1stEnv) >> (DFRACT_BITS - 18)) +
+ (FIXP_DBL)1) >>
+ 1;
+ use_dT = (h_sbrCodeEnvelope->upDate != 0 && (delta_F_bits > tmp_bits));
+ } else
+ use_dT = (delta_T_bits < delta_F_bits && h_sbrCodeEnvelope->upDate != 0);
+
+ if (use_dT) {
+ directionVec[i] = TIME;
+ FDKmemcpy(sfb_nrg, delta_T, no_of_bands * sizeof(SCHAR));
+ } else {
+ h_sbrCodeEnvelope->upDate = 0;
+ directionVec[i] = FREQ;
+ FDKmemcpy(sfb_nrg, delta_F, no_of_bands * sizeof(SCHAR));
+ }
+ sfb_nrg += no_of_bands;
+ h_sbrCodeEnvelope->upDate = 1;
+ }
+}
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_InitSbrCodeEnvelope
+ *******************************************************************************
+
+ Description:
+
+ Arguments:
+
+ Return:
+
+*******************************************************************************/
+INT FDKsbrEnc_InitSbrCodeEnvelope(HANDLE_SBR_CODE_ENVELOPE h_sbrCodeEnvelope,
+ INT *nSfb, INT deltaTAcrossFrames,
+ FIXP_DBL dF_edge_1stEnv,
+ FIXP_DBL dF_edge_incr) {
+ FDKmemclear(h_sbrCodeEnvelope, sizeof(SBR_CODE_ENVELOPE));
+
+ h_sbrCodeEnvelope->deltaTAcrossFrames = deltaTAcrossFrames;
+ h_sbrCodeEnvelope->dF_edge_1stEnv = dF_edge_1stEnv;
+ h_sbrCodeEnvelope->dF_edge_incr = dF_edge_incr;
+ h_sbrCodeEnvelope->dF_edge_incr_fac = 0;
+ h_sbrCodeEnvelope->upDate = 0;
+ h_sbrCodeEnvelope->nSfb[FREQ_RES_LOW] = nSfb[FREQ_RES_LOW];
+ h_sbrCodeEnvelope->nSfb[FREQ_RES_HIGH] = nSfb[FREQ_RES_HIGH];
+ h_sbrCodeEnvelope->offset = 2 * h_sbrCodeEnvelope->nSfb[FREQ_RES_LOW] -
+ h_sbrCodeEnvelope->nSfb[FREQ_RES_HIGH];
+
+ return (0);
+}
diff --git a/fdk-aac/libSBRenc/src/code_env.h b/fdk-aac/libSBRenc/src/code_env.h
new file mode 100644
index 0000000..673a783
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/code_env.h
@@ -0,0 +1,161 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief DPCM Envelope coding $Revision: 92790 $
+*/
+
+#ifndef CODE_ENV_H
+#define CODE_ENV_H
+
+#include "sbr_def.h"
+#include "bit_sbr.h"
+#include "fram_gen.h"
+
+typedef struct {
+ INT offset;
+ INT upDate;
+ INT nSfb[2];
+ SCHAR sfb_nrg_prev[MAX_FREQ_COEFFS];
+ INT deltaTAcrossFrames;
+ FIXP_DBL dF_edge_1stEnv;
+ FIXP_DBL dF_edge_incr;
+ INT dF_edge_incr_fac;
+
+ INT codeBookScfLavTime;
+ INT codeBookScfLavFreq;
+
+ INT codeBookScfLavLevelTime;
+ INT codeBookScfLavLevelFreq;
+ INT codeBookScfLavBalanceTime;
+ INT codeBookScfLavBalanceFreq;
+
+ INT start_bits;
+ INT start_bits_balance;
+
+ const UCHAR *hufftableTimeL;
+ const UCHAR *hufftableFreqL;
+
+ const UCHAR *hufftableLevelTimeL;
+ const UCHAR *hufftableBalanceTimeL;
+ const UCHAR *hufftableLevelFreqL;
+ const UCHAR *hufftableBalanceFreqL;
+} SBR_CODE_ENVELOPE;
+typedef SBR_CODE_ENVELOPE *HANDLE_SBR_CODE_ENVELOPE;
+
+void FDKsbrEnc_codeEnvelope(SCHAR *sfb_nrg, const FREQ_RES *freq_res,
+ SBR_CODE_ENVELOPE *h_sbrCodeEnvelope,
+ INT *directionVec, INT coupling, INT nEnvelopes,
+ INT channel, INT headerActive);
+
+INT FDKsbrEnc_InitSbrCodeEnvelope(HANDLE_SBR_CODE_ENVELOPE h_sbrCodeEnvelope,
+ INT *nSfb, INT deltaTAcrossFrames,
+ FIXP_DBL dF_edge_1stEnv,
+ FIXP_DBL dF_edge_incr);
+
+INT FDKsbrEnc_InitSbrHuffmanTables(struct SBR_ENV_DATA *sbrEnvData,
+ HANDLE_SBR_CODE_ENVELOPE henv,
+ HANDLE_SBR_CODE_ENVELOPE hnoise,
+ AMP_RES amp_res);
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/env_bit.cpp b/fdk-aac/libSBRenc/src/env_bit.cpp
new file mode 100644
index 0000000..41812ac
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/env_bit.cpp
@@ -0,0 +1,257 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Remaining SBR Bit Writing Routines
+*/
+
+#include "env_bit.h"
+#include "cmondata.h"
+
+#ifndef min
+#define min(a, b) (a < b ? a : b)
+#endif
+
+#ifndef max
+#define max(a, b) (a > b ? a : b)
+#endif
+
+/* ***************************** crcAdvance **********************************/
+/**
+ * @fn
+ * @brief updates crc data register
+ * @return none
+ *
+ * This function updates the crc register
+ *
+ */
+static void crcAdvance(USHORT crcPoly, USHORT crcMask, USHORT *crc,
+ ULONG bValue, INT bBits) {
+ INT i;
+ USHORT flag;
+
+ for (i = bBits - 1; i >= 0; i--) {
+ flag = ((*crc) & crcMask) ? (1) : (0);
+ flag ^= (bValue & (1 << i)) ? (1) : (0);
+
+ (*crc) <<= 1;
+ if (flag) (*crc) ^= crcPoly;
+ }
+}
+
+/* ***************************** FDKsbrEnc_InitSbrBitstream
+ * **********************************/
+/**
+ * @fn
+ * @brief Inittialisation of sbr bitstream, write of dummy header and CRC
+ * @return none
+ *
+ *
+ *
+ */
+
+INT FDKsbrEnc_InitSbrBitstream(
+ HANDLE_COMMON_DATA hCmonData,
+ UCHAR *memoryBase, /*!< Pointer to bitstream buffer */
+ INT memorySize, /*!< Length of bitstream buffer in bytes */
+ HANDLE_FDK_CRCINFO hCrcInfo, UINT sbrSyntaxFlags) /*!< SBR syntax flags */
+{
+ INT crcRegion = 0;
+
+ /* reset bit buffer */
+ FDKresetBitbuffer(&hCmonData->sbrBitbuf, BS_WRITER);
+
+ FDKinitBitStream(&hCmonData->tmpWriteBitbuf, memoryBase, memorySize, 0,
+ BS_WRITER);
+
+ if (sbrSyntaxFlags & SBR_SYNTAX_CRC) {
+ if (sbrSyntaxFlags & SBR_SYNTAX_DRM_CRC) { /* Init and start CRC region */
+ FDKwriteBits(&hCmonData->sbrBitbuf, 0x0, SI_SBR_DRM_CRC_BITS);
+ FDKcrcInit(hCrcInfo, 0x001d, 0xFFFF, SI_SBR_DRM_CRC_BITS);
+ crcRegion = FDKcrcStartReg(hCrcInfo, &hCmonData->sbrBitbuf, 0);
+ } else {
+ FDKwriteBits(&hCmonData->sbrBitbuf, 0x0, SI_SBR_CRC_BITS);
+ }
+ }
+
+ return (crcRegion);
+}
+
+/* ************************** FDKsbrEnc_AssembleSbrBitstream
+ * *******************************/
+/**
+ * @fn
+ * @brief Formats the SBR payload
+ * @return nothing
+ *
+ * Also the CRC will be calculated here.
+ *
+ */
+
+void FDKsbrEnc_AssembleSbrBitstream(HANDLE_COMMON_DATA hCmonData,
+ HANDLE_FDK_CRCINFO hCrcInfo, INT crcRegion,
+ UINT sbrSyntaxFlags) {
+ USHORT crcReg = SBR_CRCINIT;
+ INT numCrcBits, i;
+
+ /* check if SBR is present */
+ if (hCmonData == NULL) return;
+
+ hCmonData->sbrFillBits = 0; /* Fill bits are written only for GA streams */
+
+ if (sbrSyntaxFlags & SBR_SYNTAX_DRM_CRC) {
+ /*
+ * Calculate and write DRM CRC
+ */
+ FDKcrcEndReg(hCrcInfo, &hCmonData->sbrBitbuf, crcRegion);
+ FDKwriteBits(&hCmonData->tmpWriteBitbuf, FDKcrcGetCRC(hCrcInfo) ^ 0xFF,
+ SI_SBR_DRM_CRC_BITS);
+ } else {
+ if (!(sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)) {
+ /* Do alignment here, because its defined as part of the
+ * sbr_extension_data */
+ int sbrLoad = hCmonData->sbrHdrBits + hCmonData->sbrDataBits;
+
+ if (sbrSyntaxFlags & SBR_SYNTAX_CRC) {
+ sbrLoad += SI_SBR_CRC_BITS;
+ }
+
+ sbrLoad += 4; /* Do byte Align with 4 bit offset. ISO/IEC 14496-3:2005(E)
+ page 39. */
+
+ hCmonData->sbrFillBits = (8 - (sbrLoad % 8)) % 8;
+
+ /*
+ append fill bits
+ */
+ FDKwriteBits(&hCmonData->sbrBitbuf, 0, hCmonData->sbrFillBits);
+
+ FDK_ASSERT(FDKgetValidBits(&hCmonData->sbrBitbuf) % 8 == 4);
+ }
+
+ /*
+ calculate crc
+ */
+ if (sbrSyntaxFlags & SBR_SYNTAX_CRC) {
+ FDK_BITSTREAM tmpCRCBuf = hCmonData->sbrBitbuf;
+ FDKresetBitbuffer(&tmpCRCBuf, BS_READER);
+
+ numCrcBits = hCmonData->sbrHdrBits + hCmonData->sbrDataBits +
+ hCmonData->sbrFillBits;
+
+ for (i = 0; i < numCrcBits; i++) {
+ INT bit;
+ bit = FDKreadBits(&tmpCRCBuf, 1);
+ crcAdvance(SBR_CRC_POLY, SBR_CRC_MASK, &crcReg, bit, 1);
+ }
+ crcReg &= (SBR_CRC_RANGE);
+
+ /*
+ * Write CRC data.
+ */
+ FDKwriteBits(&hCmonData->tmpWriteBitbuf, crcReg, SI_SBR_CRC_BITS);
+ }
+ }
+
+ FDKsyncCache(&hCmonData->tmpWriteBitbuf);
+}
diff --git a/fdk-aac/libSBRenc/src/env_bit.h b/fdk-aac/libSBRenc/src/env_bit.h
new file mode 100644
index 0000000..b91802c
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/env_bit.h
@@ -0,0 +1,135 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Remaining SBR Bit Writing Routines
+*/
+
+#ifndef ENV_BIT_H
+#define ENV_BIT_H
+
+#include "sbr_encoder.h"
+#include "FDK_crc.h"
+
+/* G(x) = x^10 + x^9 + x^5 + x^4 + x + 1 */
+#define SBR_CRC_POLY (0x0233)
+#define SBR_CRC_MASK (0x0200)
+#define SBR_CRC_RANGE (0x03FF)
+#define SBR_CRC_MAXREGS 1
+#define SBR_CRCINIT (0x0)
+
+#define SI_SBR_CRC_ENABLE_BITS 0
+#define SI_SBR_CRC_BITS 10
+#define SI_SBR_DRM_CRC_BITS 8
+
+struct COMMON_DATA;
+
+INT FDKsbrEnc_InitSbrBitstream(struct COMMON_DATA *hCmonData, UCHAR *memoryBase,
+ INT memorySize, HANDLE_FDK_CRCINFO hCrcInfo,
+ UINT sbrSyntaxFlags);
+
+void FDKsbrEnc_AssembleSbrBitstream(struct COMMON_DATA *hCmonData,
+ HANDLE_FDK_CRCINFO hCrcInfo, INT crcRegion,
+ UINT sbrSyntaxFlags);
+
+#endif /* #ifndef ENV_BIT_H */
diff --git a/fdk-aac/libSBRenc/src/env_est.cpp b/fdk-aac/libSBRenc/src/env_est.cpp
new file mode 100644
index 0000000..4af561b
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/env_est.cpp
@@ -0,0 +1,1986 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "env_est.h"
+#include "tran_det.h"
+
+#include "qmf.h"
+
+#include "fram_gen.h"
+#include "bit_sbr.h"
+#include "cmondata.h"
+#include "sbrenc_ram.h"
+
+#include "genericStds.h"
+
+#define QUANT_ERROR_THRES 200
+#define Y_NRG_SCALE 5 /* noCols = 32 -> shift(5) */
+#define MAX_NRG_SLOTS_LD 16
+
+static const UCHAR panTable[2][10] = {{0, 2, 4, 6, 8, 12, 16, 20, 24},
+ {0, 2, 4, 8, 12, 0, 0, 0, 0}};
+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[64];
+ 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;
+}
+
+/***************************************************************************/
+/*!
+
+ \brief Calculates energy form real and imaginary part of
+ the QMF subsamples
+
+ \return none
+
+****************************************************************************/
+LNK_SECTION_CODE_L1
+static void FDKsbrEnc_getEnergyFromCplxQmfData(
+ FIXP_DBL **RESTRICT energyValues, /*!< the result of the operation */
+ FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */
+ FIXP_DBL **RESTRICT
+ imagValues, /*!< the imaginary part of the QMF subsamples */
+ INT numberBands, /*!< number of QMF bands */
+ INT numberCols, /*!< number of QMF subsamples */
+ INT *qmfScale, /*!< sclefactor of QMF subsamples */
+ INT *energyScale) /*!< scalefactor of energies */
+{
+ int j, k;
+ int scale;
+ FIXP_DBL max_val = FL2FXCONST_DBL(0.0f);
+
+ /* Get Scratch buffer */
+ C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, 32 * 64 / 2)
+
+ /* Get max possible scaling of QMF data */
+ scale = DFRACT_BITS;
+ for (k = 0; k < numberCols; k++) {
+ scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands),
+ getScalefactor(imagValues[k], numberBands)));
+ }
+
+ /* Tweak scaling stability for zero signal to non-zero signal transitions */
+ if (scale >= DFRACT_BITS - 1) {
+ scale = (FRACT_BITS - 1 - *qmfScale);
+ }
+ /* prevent scaling of QMF values to -1.f */
+ scale = fixMax(0, scale - 1);
+
+ /* Update QMF scale */
+ *qmfScale += scale;
+
+ /*
+ Calculate energy of each time slot pair, max energy
+ and shift QMF values as far as possible to the left.
+ */
+ {
+ FIXP_DBL *nrgValues = tmpNrg;
+ for (k = 0; k < numberCols; k += 2) {
+ /* Load band vector addresses of 2 consecutive timeslots */
+ FIXP_DBL *RESTRICT r0 = realValues[k];
+ FIXP_DBL *RESTRICT i0 = imagValues[k];
+ FIXP_DBL *RESTRICT r1 = realValues[k + 1];
+ FIXP_DBL *RESTRICT i1 = imagValues[k + 1];
+ for (j = 0; j < numberBands; j++) {
+ FIXP_DBL energy;
+ FIXP_DBL tr0, tr1, ti0, ti1;
+
+ /* Read QMF values of 2 timeslots */
+ tr0 = r0[j];
+ tr1 = r1[j];
+ ti0 = i0[j];
+ ti1 = i1[j];
+
+ /* Scale QMF Values and Calc Energy average of both timeslots */
+ tr0 <<= scale;
+ ti0 <<= scale;
+ energy = fPow2AddDiv2(fPow2Div2(tr0), ti0) >> 1;
+
+ tr1 <<= scale;
+ ti1 <<= scale;
+ energy += fPow2AddDiv2(fPow2Div2(tr1), ti1) >> 1;
+
+ /* Write timeslot pair energy to scratch */
+ *nrgValues++ = energy;
+ max_val = fixMax(max_val, energy);
+
+ /* Write back scaled QMF values */
+ r0[j] = tr0;
+ r1[j] = tr1;
+ i0[j] = ti0;
+ i1[j] = ti1;
+ }
+ }
+ }
+ /* energyScale: scalefactor energies of current frame */
+ *energyScale =
+ 2 * (*qmfScale) -
+ 1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */
+
+ /* Scale timeslot pair energies and write to output buffer */
+ scale = CountLeadingBits(max_val);
+ {
+ FIXP_DBL *nrgValues = tmpNrg;
+ for (k = 0; k<numberCols>> 1; k++) {
+ scaleValues(energyValues[k], nrgValues, numberBands, scale);
+ nrgValues += numberBands;
+ }
+ *energyScale += scale;
+ }
+
+ /* Free Scratch buffer */
+ C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, 32 * 64 / 2)
+}
+
+LNK_SECTION_CODE_L1
+static void FDKsbrEnc_getEnergyFromCplxQmfDataFull(
+ FIXP_DBL **RESTRICT energyValues, /*!< the result of the operation */
+ FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */
+ FIXP_DBL **RESTRICT
+ imagValues, /*!< the imaginary part of the QMF subsamples */
+ int numberBands, /*!< number of QMF bands */
+ int numberCols, /*!< number of QMF subsamples */
+ int *qmfScale, /*!< scalefactor of QMF subsamples */
+ int *energyScale) /*!< scalefactor of energies */
+{
+ int j, k;
+ int scale;
+ FIXP_DBL max_val = FL2FXCONST_DBL(0.0f);
+
+ /* Get Scratch buffer */
+ C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64)
+
+ FDK_ASSERT(numberCols <= MAX_NRG_SLOTS_LD);
+ FDK_ASSERT(numberBands <= 64);
+
+ /* Get max possible scaling of QMF data */
+ scale = DFRACT_BITS;
+ for (k = 0; k < numberCols; k++) {
+ scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands),
+ getScalefactor(imagValues[k], numberBands)));
+ }
+
+ /* Tweak scaling stability for zero signal to non-zero signal transitions */
+ if (scale >= DFRACT_BITS - 1) {
+ scale = (FRACT_BITS - 1 - *qmfScale);
+ }
+ /* prevent scaling of QFM values to -1.f */
+ scale = fixMax(0, scale - 1);
+
+ /* Update QMF scale */
+ *qmfScale += scale;
+
+ /*
+ Calculate energy of each time slot pair, max energy
+ and shift QMF values as far as possible to the left.
+ */
+ {
+ FIXP_DBL *nrgValues = tmpNrg;
+ for (k = 0; k < numberCols; k++) {
+ /* Load band vector addresses of 1 timeslot */
+ FIXP_DBL *RESTRICT r0 = realValues[k];
+ FIXP_DBL *RESTRICT i0 = imagValues[k];
+ for (j = 0; j < numberBands; j++) {
+ FIXP_DBL energy;
+ FIXP_DBL tr0, ti0;
+
+ /* Read QMF values of 1 timeslot */
+ tr0 = r0[j];
+ ti0 = i0[j];
+
+ /* Scale QMF Values and Calc Energy */
+ tr0 <<= scale;
+ ti0 <<= scale;
+ energy = fPow2AddDiv2(fPow2Div2(tr0), ti0);
+ *nrgValues++ = energy;
+
+ max_val = fixMax(max_val, energy);
+
+ /* Write back scaled QMF values */
+ r0[j] = tr0;
+ i0[j] = ti0;
+ }
+ }
+ }
+ /* energyScale: scalefactor energies of current frame */
+ *energyScale =
+ 2 * (*qmfScale) -
+ 1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */
+
+ /* Scale timeslot pair energies and write to output buffer */
+ scale = CountLeadingBits(max_val);
+ {
+ FIXP_DBL *nrgValues = tmpNrg;
+ for (k = 0; k < numberCols; k++) {
+ scaleValues(energyValues[k], nrgValues, numberBands, scale);
+ nrgValues += numberBands;
+ }
+ *energyScale += scale;
+ }
+
+ /* Free Scratch buffer */
+ C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64)
+}
+
+/***************************************************************************/
+/*!
+
+ \brief Quantisation of the panorama value (balance)
+
+ \return the quantized pan value
+
+****************************************************************************/
+static INT mapPanorama(INT nrgVal, /*! integer value of the energy */
+ INT ampRes, /*! amplitude resolution [1.5/3dB] */
+ INT *quantError /*! quantization error of energy val*/
+) {
+ int i;
+ INT min_val, val;
+ UCHAR panIndex;
+ INT sign;
+
+ sign = nrgVal > 0 ? 1 : -1;
+
+ nrgVal *= sign;
+
+ min_val = FDK_INT_MAX;
+ panIndex = 0;
+ for (i = 0; i < maxIndex[ampRes]; i++) {
+ val = fixp_abs((nrgVal - (INT)panTable[ampRes][i]));
+
+ if (val < min_val) {
+ min_val = val;
+ panIndex = i;
+ }
+ }
+
+ *quantError = min_val;
+
+ return panTable[ampRes][maxIndex[ampRes] - 1] +
+ sign * panTable[ampRes][panIndex];
+}
+
+/***************************************************************************/
+/*!
+
+ \brief Quantisation of the noise floor levels
+
+ \return void
+
+****************************************************************************/
+static void sbrNoiseFloorLevelsQuantisation(
+ SCHAR *RESTRICT iNoiseLevels, /*! quantized noise levels */
+ FIXP_DBL *RESTRICT
+ NoiseLevels, /*! the noise levels. Exponent = LD_DATA_SHIFT */
+ INT coupling /*! the coupling flag */
+) {
+ INT i;
+ INT tmp, dummy;
+
+ /* Quantisation, similar to sfb quant... */
+ for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
+ /* tmp = NoiseLevels[i] > (PFLOAT)30.0f ? 30: (INT) (NoiseLevels[i] +
+ * (PFLOAT)0.5); */
+ /* 30>>LD_DATA_SHIFT = 0.46875 */
+ if ((FIXP_DBL)NoiseLevels[i] > FL2FXCONST_DBL(0.46875f)) {
+ tmp = 30;
+ } else {
+ /* tmp = (INT)((FIXP_DBL)NoiseLevels[i] + (FL2FXCONST_DBL(0.5f)>>(*/
+ /* FRACT_BITS+ */ /* 6-1)));*/
+ /* tmp = tmp >> (DFRACT_BITS-1-LD_DATA_SHIFT); */ /* conversion to integer
+ happens here */
+ /* rounding is done by shifting one bit less than necessary to the right,
+ * adding '1' and then shifting the final bit */
+ tmp = ((((INT)NoiseLevels[i]) >>
+ (DFRACT_BITS - 1 - LD_DATA_SHIFT))); /* conversion to integer */
+ if (tmp != 0) tmp += 1;
+ }
+
+ if (coupling) {
+ tmp = tmp < -30 ? -30 : tmp;
+ tmp = mapPanorama(tmp, 1, &dummy);
+ }
+ iNoiseLevels[i] = tmp;
+ }
+}
+
+/***************************************************************************/
+/*!
+
+ \brief Calculation of noise floor for coupling
+
+ \return void
+
+****************************************************************************/
+static void coupleNoiseFloor(
+ FIXP_DBL *RESTRICT noise_level_left, /*! noise level left (modified)*/
+ FIXP_DBL *RESTRICT noise_level_right /*! noise level right (modified)*/
+) {
+ FIXP_DBL cmpValLeft, cmpValRight;
+ INT i;
+ FIXP_DBL temp1, temp2;
+
+ for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
+ /* Calculation of the power function using ld64:
+ z = x^y;
+ z' = CalcLd64(z) = y*CalcLd64(x)/64;
+ z = CalcInvLd64(z');
+ */
+ cmpValLeft = NOISE_FLOOR_OFFSET_64 - noise_level_left[i];
+ cmpValRight = NOISE_FLOOR_OFFSET_64 - noise_level_right[i];
+
+ if (cmpValRight < FL2FXCONST_DBL(0.0f)) {
+ temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]);
+ } else {
+ temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]);
+ temp1 = temp1 << (DFRACT_BITS - 1 - LD_DATA_SHIFT -
+ 1); /* INT to fract conversion of result, if input of
+ CalcInvLdData is positiv */
+ }
+
+ if (cmpValLeft < FL2FXCONST_DBL(0.0f)) {
+ temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]);
+ } else {
+ temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]);
+ temp2 = temp2 << (DFRACT_BITS - 1 - LD_DATA_SHIFT -
+ 1); /* INT to fract conversion of result, if input of
+ CalcInvLdData is positiv */
+ }
+
+ if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) &&
+ (cmpValRight < FL2FXCONST_DBL(0.0f))) {
+ noise_level_left[i] =
+ NOISE_FLOOR_OFFSET_64 -
+ (CalcLdData(
+ ((temp1 >> 1) +
+ (temp2 >> 1)))); /* no scaling needed! both values are dfract */
+ noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1);
+ }
+
+ if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) &&
+ (cmpValRight >= FL2FXCONST_DBL(0.0f))) {
+ noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
+ (CalcLdData(((temp1 >> 1) + (temp2 >> 1))) +
+ FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
+ noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1);
+ }
+
+ if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) &&
+ (cmpValRight < FL2FXCONST_DBL(0.0f))) {
+ noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
+ (CalcLdData(((temp1 >> (7 + 1)) + (temp2 >> 1))) +
+ FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
+ noise_level_right[i] =
+ (CalcLdData(temp2) + FL2FXCONST_DBL(0.109375f)) - CalcLdData(temp1);
+ }
+
+ if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) &&
+ (cmpValRight >= FL2FXCONST_DBL(0.0f))) {
+ noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
+ (CalcLdData(((temp1 >> 1) + (temp2 >> (7 + 1)))) +
+ FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
+ noise_level_right[i] = CalcLdData(temp2) -
+ (CalcLdData(temp1) +
+ FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
+ }
+ }
+}
+
+/***************************************************************************/
+/*!
+
+ \brief Calculation of energy starting in lower band (li) up to upper band
+(ui) over slots (start_pos) to (stop_pos)
+
+ \return void
+
+****************************************************************************/
+
+static FIXP_DBL getEnvSfbEnergy(
+ INT li, /*! lower band */
+ INT ui, /*! upper band */
+ INT start_pos, /*! start slot */
+ INT stop_pos, /*! stop slot */
+ INT border_pos, /*! slots scaling border */
+ FIXP_DBL **YBuffer, /*! sfb energy buffer */
+ INT YBufferSzShift, /*! Energy buffer index scale */
+ INT scaleNrg0, /*! scaling of lower slots */
+ INT scaleNrg1) /*! scaling of upper slots */
+{
+ /* use dynamic scaling for outer energy loop;
+ energies are critical and every bit is important */
+ int sc0, sc1, k, l;
+
+ FIXP_DBL nrgSum, nrg1, nrg2, accu1, accu2;
+ INT dynScale, dynScale1, dynScale2;
+ if (ui - li == 0)
+ dynScale = DFRACT_BITS - 1;
+ else
+ dynScale = CalcLdInt(ui - li) >> (DFRACT_BITS - 1 - LD_DATA_SHIFT);
+
+ sc0 = fixMin(scaleNrg0, Y_NRG_SCALE);
+ sc1 = fixMin(scaleNrg1, Y_NRG_SCALE);
+ /* dynScale{1,2} is set such that the right shift below is positive */
+ dynScale1 = fixMin((scaleNrg0 - sc0), dynScale);
+ dynScale2 = fixMin((scaleNrg1 - sc1), dynScale);
+ nrgSum = accu1 = accu2 = (FIXP_DBL)0;
+
+ for (k = li; k < ui; k++) {
+ nrg1 = nrg2 = (FIXP_DBL)0;
+ for (l = start_pos; l < border_pos; l++) {
+ nrg1 += YBuffer[l >> YBufferSzShift][k] >> sc0;
+ }
+ for (; l < stop_pos; l++) {
+ nrg2 += YBuffer[l >> YBufferSzShift][k] >> sc1;
+ }
+ accu1 += (nrg1 >> dynScale1);
+ accu2 += (nrg2 >> dynScale2);
+ }
+ /* This shift factor is always positive. See comment above. */
+ nrgSum +=
+ (accu1 >> fixMin((scaleNrg0 - sc0 - dynScale1), (DFRACT_BITS - 1))) +
+ (accu2 >> fixMin((scaleNrg1 - sc1 - dynScale2), (DFRACT_BITS - 1)));
+
+ return nrgSum;
+}
+
+/***************************************************************************/
+/*!
+
+ \brief Energy compensation in missing harmonic mode
+
+ \return void
+
+****************************************************************************/
+static FIXP_DBL mhLoweringEnergy(FIXP_DBL nrg, INT M) {
+ /*
+ Compensating for the fact that we in the decoder map the "average energy to
+ every QMF band, and use this when we calculate the boost-factor. Since the
+ mapped energy isn't the average energy but the maximum energy in case of
+ missing harmonic creation, we will in the boost function calculate that too
+ much limiting has been applied and hence we will boost the signal although
+ it isn't called for. Hence we need to compensate for this by lowering the
+ transmitted energy values for the sines so they will get the correct level
+ after the boost is applied.
+ */
+ if (M > 2) {
+ INT tmpScale;
+ tmpScale = CountLeadingBits(nrg);
+ nrg <<= tmpScale;
+ nrg = fMult(nrg, FL2FXCONST_DBL(0.398107267f)); /* The maximum boost
+ is 1.584893, so the
+ maximum attenuation
+ should be
+ square(1/1.584893) =
+ 0.398107267 */
+ nrg >>= tmpScale;
+ } else {
+ if (M > 1) {
+ nrg >>= 1;
+ }
+ }
+
+ return nrg;
+}
+
+/***************************************************************************/
+/*!
+
+ \brief Energy compensation in none missing harmonic mode
+
+ \return void
+
+****************************************************************************/
+static FIXP_DBL nmhLoweringEnergy(FIXP_DBL nrg, const FIXP_DBL nrgSum,
+ const INT nrgSum_scale, const INT M) {
+ if (nrg > FL2FXCONST_DBL(0)) {
+ int sc = 0;
+ /* gain = nrgSum / (nrg*(M+1)) */
+ FIXP_DBL gain = fMult(fDivNorm(nrgSum, nrg, &sc), GetInvInt(M + 1));
+ sc += nrgSum_scale;
+
+ /* reduce nrg if gain smaller 1.f */
+ if (!((sc >= 0) && (gain > ((FIXP_DBL)MAXVAL_DBL >> sc)))) {
+ nrg = fMult(scaleValue(gain, sc), nrg);
+ }
+ }
+ return nrg;
+}
+
+/***************************************************************************/
+/*!
+
+ \brief calculates the envelope values from the energies, depending on
+ framing and stereo mode
+
+ \return void
+
+****************************************************************************/
+static void calculateSbrEnvelope(
+ FIXP_DBL **RESTRICT YBufferLeft, /*! energy buffer left */
+ FIXP_DBL **RESTRICT YBufferRight, /*! energy buffer right */
+ int *RESTRICT YBufferScaleLeft, /*! scale energy buffer left */
+ int *RESTRICT YBufferScaleRight, /*! scale energy buffer right */
+ const SBR_FRAME_INFO *frame_info, /*! frame info vector */
+ SCHAR *RESTRICT sfb_nrgLeft, /*! sfb energy buffer left */
+ SCHAR *RESTRICT sfb_nrgRight, /*! sfb energy buffer right */
+ HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */
+ HANDLE_ENV_CHANNEL h_sbr, /*! envelope channel handle */
+ SBR_STEREO_MODE stereoMode, /*! stereo coding mode */
+ INT *maxQuantError, /*! maximum quantization error, for panorama. */
+ int YBufferSzShift) /*! Energy buffer index scale */
+
+{
+ int env, j, m = 0;
+ INT no_of_bands, start_pos, stop_pos, li, ui;
+ FREQ_RES freq_res;
+
+ INT ca = 2 - h_sbr->encEnvData.init_sbr_amp_res;
+ INT oneBitLess = 0;
+ if (ca == 2)
+ oneBitLess =
+ 1; /* LD_DATA_SHIFT => ld64 scaling; one bit less for rounding */
+
+ INT quantError;
+ INT nEnvelopes = frame_info->nEnvelopes;
+ INT short_env = frame_info->shortEnv - 1;
+ INT timeStep = h_sbr->sbrExtractEnvelope.time_step;
+ INT commonScale, scaleLeft0, scaleLeft1;
+ INT scaleRight0 = 0, scaleRight1 = 0;
+
+ commonScale = fixMin(YBufferScaleLeft[0], YBufferScaleLeft[1]);
+
+ if (stereoMode == SBR_COUPLING) {
+ commonScale = fixMin(commonScale, YBufferScaleRight[0]);
+ commonScale = fixMin(commonScale, YBufferScaleRight[1]);
+ }
+
+ commonScale = commonScale - 7;
+
+ scaleLeft0 = YBufferScaleLeft[0] - commonScale;
+ scaleLeft1 = YBufferScaleLeft[1] - commonScale;
+ FDK_ASSERT((scaleLeft0 >= 0) && (scaleLeft1 >= 0));
+
+ if (stereoMode == SBR_COUPLING) {
+ scaleRight0 = YBufferScaleRight[0] - commonScale;
+ scaleRight1 = YBufferScaleRight[1] - commonScale;
+ FDK_ASSERT((scaleRight0 >= 0) && (scaleRight1 >= 0));
+ *maxQuantError = 0;
+ }
+
+ for (env = 0; env < nEnvelopes; env++) {
+ FIXP_DBL pNrgLeft[32];
+ FIXP_DBL pNrgRight[32];
+ int envNrg_scale;
+ FIXP_DBL envNrgLeft = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL envNrgRight = FL2FXCONST_DBL(0.0f);
+ int missingHarmonic[32];
+ int count[32];
+
+ start_pos = timeStep * frame_info->borders[env];
+ stop_pos = timeStep * frame_info->borders[env + 1];
+ freq_res = frame_info->freqRes[env];
+ no_of_bands = h_con->nSfb[freq_res];
+ envNrg_scale = DFRACT_BITS - fNormz((FIXP_DBL)no_of_bands);
+ if (env == short_env) {
+ j = fMax(2, timeStep); /* consider at least 2 QMF slots less for short
+ envelopes (envelopes just before transients) */
+ if ((stop_pos - start_pos - j) > 0) {
+ stop_pos = stop_pos - j;
+ }
+ }
+ for (j = 0; j < no_of_bands; j++) {
+ FIXP_DBL nrgLeft = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL nrgRight = FL2FXCONST_DBL(0.0f);
+
+ li = h_con->freqBandTable[freq_res][j];
+ ui = h_con->freqBandTable[freq_res][j + 1];
+
+ if (freq_res == FREQ_RES_HIGH) {
+ if (j == 0 && ui - li > 1) {
+ li++;
+ }
+ } else {
+ if (j == 0 && ui - li > 2) {
+ li++;
+ }
+ }
+
+ /*
+ Find out whether a sine will be missing in the scale-factor
+ band that we're currently processing.
+ */
+ missingHarmonic[j] = 0;
+
+ if (h_sbr->encEnvData.addHarmonicFlag) {
+ if (freq_res == FREQ_RES_HIGH) {
+ if (h_sbr->encEnvData
+ .addHarmonic[j]) { /*A missing sine in the current band*/
+ missingHarmonic[j] = 1;
+ }
+ } else {
+ INT i;
+ INT startBandHigh = 0;
+ INT stopBandHigh = 0;
+
+ while (h_con->freqBandTable[FREQ_RES_HIGH][startBandHigh] <
+ h_con->freqBandTable[FREQ_RES_LOW][j])
+ startBandHigh++;
+ while (h_con->freqBandTable[FREQ_RES_HIGH][stopBandHigh] <
+ h_con->freqBandTable[FREQ_RES_LOW][j + 1])
+ stopBandHigh++;
+
+ for (i = startBandHigh; i < stopBandHigh; i++) {
+ if (h_sbr->encEnvData.addHarmonic[i]) {
+ missingHarmonic[j] = 1;
+ }
+ }
+ }
+ }
+
+ /*
+ If a sine is missing in a scalefactorband, with more than one qmf
+ channel use the nrg from the channel with the largest nrg rather than
+ the mean. Compensate for the boost calculation in the decdoder.
+ */
+ int border_pos =
+ fixMin(stop_pos, h_sbr->sbrExtractEnvelope.YBufferWriteOffset
+ << YBufferSzShift);
+
+ if (missingHarmonic[j]) {
+ int k;
+ count[j] = stop_pos - start_pos;
+ nrgLeft = FL2FXCONST_DBL(0.0f);
+
+ for (k = li; k < ui; k++) {
+ FIXP_DBL tmpNrg;
+ tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos,
+ YBufferLeft, YBufferSzShift, scaleLeft0,
+ scaleLeft1);
+
+ nrgLeft = fixMax(nrgLeft, tmpNrg);
+ }
+
+ /* Energy lowering compensation */
+ nrgLeft = mhLoweringEnergy(nrgLeft, ui - li);
+
+ if (stereoMode == SBR_COUPLING) {
+ nrgRight = FL2FXCONST_DBL(0.0f);
+
+ for (k = li; k < ui; k++) {
+ FIXP_DBL tmpNrg;
+ tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos,
+ YBufferRight, YBufferSzShift, scaleRight0,
+ scaleRight1);
+
+ nrgRight = fixMax(nrgRight, tmpNrg);
+ }
+
+ /* Energy lowering compensation */
+ nrgRight = mhLoweringEnergy(nrgRight, ui - li);
+ }
+ } /* end missingHarmonic */
+ else {
+ count[j] = (stop_pos - start_pos) * (ui - li);
+
+ nrgLeft = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos,
+ YBufferLeft, YBufferSzShift, scaleLeft0,
+ scaleLeft1);
+
+ if (stereoMode == SBR_COUPLING) {
+ nrgRight = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos,
+ YBufferRight, YBufferSzShift, scaleRight0,
+ scaleRight1);
+ }
+ } /* !missingHarmonic */
+
+ /* save energies */
+ pNrgLeft[j] = nrgLeft;
+ pNrgRight[j] = nrgRight;
+ envNrgLeft += (nrgLeft >> envNrg_scale);
+ envNrgRight += (nrgRight >> envNrg_scale);
+ } /* j */
+
+ for (j = 0; j < no_of_bands; j++) {
+ FIXP_DBL nrgLeft2 = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL nrgLeft = pNrgLeft[j];
+ FIXP_DBL nrgRight = pNrgRight[j];
+
+ /* None missing harmonic Energy lowering compensation */
+ if (!missingHarmonic[j] && h_sbr->fLevelProtect) {
+ /* in case of missing energy in base band,
+ reduce reference energy to prevent overflows in decoder output */
+ nrgLeft =
+ nmhLoweringEnergy(nrgLeft, envNrgLeft, envNrg_scale, no_of_bands);
+ if (stereoMode == SBR_COUPLING) {
+ nrgRight = nmhLoweringEnergy(nrgRight, envNrgRight, envNrg_scale,
+ no_of_bands);
+ }
+ }
+
+ if (stereoMode == SBR_COUPLING) {
+ /* calc operation later with log */
+ nrgLeft2 = nrgLeft;
+ nrgLeft = (nrgRight + nrgLeft) >> 1;
+ }
+
+ /* nrgLeft = f20_log2(nrgLeft / (PFLOAT)(count * 64))+(PFLOAT)44; */
+ /* If nrgLeft == 0 then the Log calculations below do fail. */
+ if (nrgLeft > FL2FXCONST_DBL(0.0f)) {
+ FIXP_DBL tmp0, tmp1, tmp2, tmp3;
+ INT tmpScale;
+
+ tmpScale = CountLeadingBits(nrgLeft);
+ nrgLeft = nrgLeft << tmpScale;
+
+ tmp0 = CalcLdData(nrgLeft); /* scaled by 1/64 */
+ tmp1 = ((FIXP_DBL)(commonScale + tmpScale))
+ << (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1); /* scaled by 1/64 */
+ tmp2 = ((FIXP_DBL)(count[j] * 64)) << (DFRACT_BITS - 1 - 14 - 1);
+ tmp2 = CalcLdData(tmp2); /* scaled by 1/64 */
+ tmp3 = FL2FXCONST_DBL(0.6875f - 0.21875f - 0.015625f) >>
+ 1; /* scaled by 1/64 */
+
+ nrgLeft = ((tmp0 - tmp2) >> 1) + (tmp3 - tmp1);
+ } else {
+ nrgLeft = FL2FXCONST_DBL(-1.0f);
+ }
+
+ /* ld64 to integer conversion */
+ nrgLeft = fixMin(fixMax(nrgLeft, FL2FXCONST_DBL(0.0f)),
+ (FL2FXCONST_DBL(0.5f) >> oneBitLess));
+ nrgLeft = (FIXP_DBL)(LONG)nrgLeft >>
+ (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess - 1);
+ sfb_nrgLeft[m] = ((INT)nrgLeft + 1) >> 1; /* rounding */
+
+ if (stereoMode == SBR_COUPLING) {
+ FIXP_DBL scaleFract;
+ int sc0, sc1;
+
+ nrgLeft2 = fixMax((FIXP_DBL)0x1, nrgLeft2);
+ nrgRight = fixMax((FIXP_DBL)0x1, nrgRight);
+
+ sc0 = CountLeadingBits(nrgLeft2);
+ sc1 = CountLeadingBits(nrgRight);
+
+ scaleFract =
+ ((FIXP_DBL)(sc0 - sc1))
+ << (DFRACT_BITS - 1 -
+ LD_DATA_SHIFT); /* scale value in ld64 representation */
+ nrgRight = CalcLdData(nrgLeft2 << sc0) - CalcLdData(nrgRight << sc1) -
+ scaleFract;
+
+ /* ld64 to integer conversion */
+ nrgRight = (FIXP_DBL)(LONG)(nrgRight) >>
+ (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess);
+ nrgRight = (nrgRight + (FIXP_DBL)1) >> 1; /* rounding */
+
+ sfb_nrgRight[m] = mapPanorama(
+ nrgRight, h_sbr->encEnvData.init_sbr_amp_res, &quantError);
+
+ *maxQuantError = fixMax(quantError, *maxQuantError);
+ }
+
+ m++;
+ } /* j */
+
+ /* Do energy compensation for sines that are present in two
+ QMF-bands in the original, but will only occur in one band in
+ the decoder due to the synthetic sine coding.*/
+ if (h_con->useParametricCoding) {
+ m -= no_of_bands;
+ for (j = 0; j < no_of_bands; j++) {
+ if (freq_res == FREQ_RES_HIGH &&
+ h_sbr->sbrExtractEnvelope.envelopeCompensation[j]) {
+ sfb_nrgLeft[m] -=
+ (ca *
+ fixp_abs(
+ (INT)h_sbr->sbrExtractEnvelope.envelopeCompensation[j]));
+ }
+ sfb_nrgLeft[m] = fixMax(0, sfb_nrgLeft[m]);
+ m++;
+ }
+ } /* useParametricCoding */
+
+ } /* env loop */
+}
+
+/***************************************************************************/
+/*!
+
+ \brief calculates the noise floor and the envelope values from the
+ energies, depending on framing and stereo mode
+
+ FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the
+ envelope and the noise floor. The function includes the following processes:
+
+ -Analysis subband filtering.
+ -Encoding SA and pan parameters (if enabled).
+ -Transient detection.
+
+****************************************************************************/
+
+LNK_SECTION_CODE_L1
+void FDKsbrEnc_extractSbrEnvelope1(
+ HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_ENV_CHANNEL hEnvChan,
+ HANDLE_COMMON_DATA hCmonData, SBR_ENV_TEMP_DATA *eData,
+ SBR_FRAME_TEMP_DATA *fData) {
+ HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope;
+
+ if (sbrExtrEnv->YBufferSzShift == 0)
+ FDKsbrEnc_getEnergyFromCplxQmfDataFull(
+ &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset],
+ sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset,
+ sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands,
+ sbrExtrEnv->no_cols, &hEnvChan->qmfScale, &sbrExtrEnv->YBufferScale[1]);
+ else
+ FDKsbrEnc_getEnergyFromCplxQmfData(
+ &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset],
+ sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset,
+ sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands,
+ sbrExtrEnv->no_cols, &hEnvChan->qmfScale, &sbrExtrEnv->YBufferScale[1]);
+
+ /* Energie values =
+ * sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset][x].floatVal *
+ * (1<<2*7-sbrExtrEnv->YBufferScale[1]) */
+
+ /*
+ Precalculation of Tonality Quotas COEFF Transform OK
+ */
+ FDKsbrEnc_CalculateTonalityQuotas(
+ &hEnvChan->TonCorr, sbrExtrEnv->rBuffer, sbrExtrEnv->iBuffer,
+ h_con->freqBandTable[HI][h_con->nSfb[HI]], 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
+ */
+
+ 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, sbrExtrEnv->YBuffer,
+ sbrExtrEnv->YBufferScale, eData->transient_info,
+ sbrExtrEnv->YBufferWriteOffset, sbrExtrEnv->YBufferSzShift,
+ sbrExtrEnv->time_step, hEnvChan->SbrEnvFrame.frameMiddleSlot);
+ }
+
+ /*
+ Generate flags for 2 env in a FIXFIX-frame.
+ Remove this function to get always 1 env per FIXFIX-frame.
+ */
+
+ /*
+ frame Splitter COEFF Transform OK
+ */
+ FDKsbrEnc_frameSplitter(
+ sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale,
+ &hEnvChan->sbrTransientDetector, h_con->freqBandTable[1],
+ eData->transient_info, sbrExtrEnv->YBufferWriteOffset,
+ sbrExtrEnv->YBufferSzShift, h_con->nSfb[1], sbrExtrEnv->time_step,
+ sbrExtrEnv->no_cols, &hEnvChan->encEnvData.global_tonality);
+}
+
+/***************************************************************************/
+/*!
+
+ \brief calculates the noise floor and the envelope values from the
+ energies, depending on framing and stereo mode
+
+ FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the
+ envelope and the noise floor. The function includes the following processes:
+
+ -Determine time/frequency division of current granule.
+ -Sending transient info to bitstream.
+ -Set amp_res to 1.5 dB if the current frame contains only one envelope.
+ -Lock dynamic bandwidth frequency change if the next envelope not starts on a
+ frame boundary.
+ -MDCT transposer (needed to detect where harmonics will be missing).
+ -Spectrum Estimation (used for pulse train and missing harmonics detection).
+ -Pulse train detection.
+ -Inverse Filtering detection.
+ -Waveform Coding.
+ -Missing Harmonics detection.
+ -Extract envelope of current frame.
+ -Noise floor estimation.
+ -Noise floor quantisation and coding.
+ -Encode envelope of current frame.
+ -Send the encoded data to the bitstream.
+ -Write to bitstream.
+
+****************************************************************************/
+
+LNK_SECTION_CODE_L1
+void FDKsbrEnc_extractSbrEnvelope2(
+ HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_ENV_CHANNEL h_envChan0,
+ HANDLE_ENV_CHANNEL h_envChan1, HANDLE_COMMON_DATA hCmonData,
+ SBR_ENV_TEMP_DATA *eData, SBR_FRAME_TEMP_DATA *fData, int clearOutput) {
+ HANDLE_ENV_CHANNEL h_envChan[MAX_NUM_CHANNELS] = {h_envChan0, h_envChan1};
+ int ch, i, j, c, YSzShift = h_envChan[0]->sbrExtractEnvelope.YBufferSzShift;
+
+ SBR_STEREO_MODE stereoMode = h_con->stereoMode;
+ int nChannels = h_con->nChannels;
+ FDK_ASSERT(nChannels <= MAX_NUM_CHANNELS);
+ const int *v_tuning;
+ static const int v_tuningHEAAC[6] = {0, 2, 4, 0, 0, 0};
+
+ static const int v_tuningELD[6] = {0, 2, 3, 0, 0, 0};
+
+ if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
+ v_tuning = v_tuningELD;
+ else
+ v_tuning = v_tuningHEAAC;
+
+ /*
+ Select stereo mode.
+ */
+ if (stereoMode == SBR_COUPLING) {
+ if (eData[0].transient_info[1] && eData[1].transient_info[1]) {
+ eData[0].transient_info[0] =
+ fixMin(eData[1].transient_info[0], eData[0].transient_info[0]);
+ eData[1].transient_info[0] = eData[0].transient_info[0];
+ } else {
+ if (eData[0].transient_info[1] && !eData[1].transient_info[1]) {
+ eData[1].transient_info[0] = eData[0].transient_info[0];
+ } else {
+ if (!eData[0].transient_info[1] && eData[1].transient_info[1])
+ eData[0].transient_info[0] = eData[1].transient_info[0];
+ else {
+ eData[0].transient_info[0] =
+ fixMax(eData[1].transient_info[0], eData[0].transient_info[0]);
+ eData[1].transient_info[0] = eData[0].transient_info[0];
+ }
+ }
+ }
+ }
+
+ /*
+ Determine time/frequency division of current granule
+ */
+ eData[0].frame_info = FDKsbrEnc_frameInfoGenerator(
+ &h_envChan[0]->SbrEnvFrame, eData[0].transient_info,
+ sbrBitstreamData->rightBorderFIX,
+ h_envChan[0]->sbrExtractEnvelope.pre_transient_info,
+ h_envChan[0]->encEnvData.ldGrid, v_tuning);
+
+ h_envChan[0]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid;
+
+ /* AAC LD patch for transient prediction */
+ if (h_envChan[0]->encEnvData.ldGrid && eData[0].transient_info[2]) {
+ /* if next frame will start with transient, set shortEnv to
+ * numEnvelopes(shortend Envelope = shortEnv-1)*/
+ h_envChan[0]->SbrEnvFrame.SbrFrameInfo.shortEnv =
+ h_envChan[0]->SbrEnvFrame.SbrFrameInfo.nEnvelopes;
+ }
+
+ switch (stereoMode) {
+ case SBR_LEFT_RIGHT:
+ case SBR_SWITCH_LRC:
+ eData[1].frame_info = FDKsbrEnc_frameInfoGenerator(
+ &h_envChan[1]->SbrEnvFrame, eData[1].transient_info,
+ sbrBitstreamData->rightBorderFIX,
+ h_envChan[1]->sbrExtractEnvelope.pre_transient_info,
+ h_envChan[1]->encEnvData.ldGrid, v_tuning);
+
+ h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[1]->SbrEnvFrame.SbrGrid;
+
+ if (h_envChan[1]->encEnvData.ldGrid && eData[1].transient_info[2]) {
+ /* if next frame will start with transient, set shortEnv to
+ * numEnvelopes(shortend Envelope = shortEnv-1)*/
+ h_envChan[1]->SbrEnvFrame.SbrFrameInfo.shortEnv =
+ h_envChan[1]->SbrEnvFrame.SbrFrameInfo.nEnvelopes;
+ }
+
+ /* compare left and right frame_infos */
+ if (eData[0].frame_info->nEnvelopes != eData[1].frame_info->nEnvelopes) {
+ stereoMode = SBR_LEFT_RIGHT;
+ } else {
+ for (i = 0; i < eData[0].frame_info->nEnvelopes + 1; i++) {
+ if (eData[0].frame_info->borders[i] !=
+ eData[1].frame_info->borders[i]) {
+ stereoMode = SBR_LEFT_RIGHT;
+ break;
+ }
+ }
+ for (i = 0; i < eData[0].frame_info->nEnvelopes; i++) {
+ if (eData[0].frame_info->freqRes[i] !=
+ eData[1].frame_info->freqRes[i]) {
+ stereoMode = SBR_LEFT_RIGHT;
+ break;
+ }
+ }
+ if (eData[0].frame_info->shortEnv != eData[1].frame_info->shortEnv) {
+ stereoMode = SBR_LEFT_RIGHT;
+ }
+ }
+ break;
+ case SBR_COUPLING:
+ eData[1].frame_info = eData[0].frame_info;
+ h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid;
+ break;
+ case SBR_MONO:
+ /* nothing to do */
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+
+ for (ch = 0; ch < nChannels; ch++) {
+ HANDLE_ENV_CHANNEL hEnvChan = h_envChan[ch];
+ HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope;
+ SBR_ENV_TEMP_DATA *ed = &eData[ch];
+
+ /*
+ Send transient info to bitstream and store for next call
+ */
+ sbrExtrEnv->pre_transient_info[0] = ed->transient_info[0]; /* tran_pos */
+ sbrExtrEnv->pre_transient_info[1] = ed->transient_info[1]; /* tran_flag */
+ hEnvChan->encEnvData.noOfEnvelopes = ed->nEnvelopes =
+ ed->frame_info->nEnvelopes; /* number of envelopes of current frame */
+
+ /*
+ Check if the current frame is divided into one envelope only. If so, set
+ the amplitude resolution to 1.5 dB, otherwise may set back to chosen value
+ */
+ if ((hEnvChan->encEnvData.hSbrBSGrid->frameClass == FIXFIX) &&
+ (ed->nEnvelopes == 1)) {
+ if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
+ /* 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;
+
+ if (hEnvChan->encEnvData.currentAmpResFF !=
+ hEnvChan->encEnvData.init_sbr_amp_res) {
+ FDKsbrEnc_InitSbrHuffmanTables(
+ &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
+ &hEnvChan->sbrCodeNoiseFloor, hEnvChan->encEnvData.currentAmpResFF);
+ }
+ } else {
+ if (sbrHeaderData->sbr_amp_res != hEnvChan->encEnvData.init_sbr_amp_res) {
+ FDKsbrEnc_InitSbrHuffmanTables(
+ &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
+ &hEnvChan->sbrCodeNoiseFloor, sbrHeaderData->sbr_amp_res);
+ }
+ }
+
+ if (!clearOutput) {
+ /*
+ Tonality correction parameter extraction (inverse filtering level, noise
+ floor additional sines).
+ */
+ FDKsbrEnc_TonCorrParamExtr(
+ &hEnvChan->TonCorr, hEnvChan->encEnvData.sbr_invf_mode_vec,
+ ed->noiseFloor, &hEnvChan->encEnvData.addHarmonicFlag,
+ hEnvChan->encEnvData.addHarmonic, sbrExtrEnv->envelopeCompensation,
+ ed->frame_info, ed->transient_info, h_con->freqBandTable[HI],
+ h_con->nSfb[HI], hEnvChan->encEnvData.sbr_xpos_mode,
+ h_con->sbrSyntaxFlags);
+ }
+
+ /* Low energy in low band fix */
+ 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)) {
+ hEnvChan->fLevelProtect = 1;
+
+ for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
+ hEnvChan->encEnvData.sbr_invf_mode_vec[i] = INVF_HIGH_LEVEL;
+ } else {
+ hEnvChan->fLevelProtect = 0;
+ }
+
+ hEnvChan->encEnvData.sbr_invf_mode =
+ hEnvChan->encEnvData.sbr_invf_mode_vec[0];
+
+ hEnvChan->encEnvData.noOfnoisebands =
+ hEnvChan->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
+
+ } /* ch */
+
+ /*
+ Save number of scf bands per envelope
+ */
+ for (ch = 0; ch < nChannels; ch++) {
+ for (i = 0; i < eData[ch].nEnvelopes; i++) {
+ h_envChan[ch]->encEnvData.noScfBands[i] =
+ (eData[ch].frame_info->freqRes[i] == FREQ_RES_HIGH
+ ? h_con->nSfb[FREQ_RES_HIGH]
+ : h_con->nSfb[FREQ_RES_LOW]);
+ }
+ }
+
+ /*
+ Extract envelope of current frame.
+ */
+ switch (stereoMode) {
+ case SBR_MONO:
+ calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
+ h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
+ eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
+ h_envChan[0], SBR_MONO, NULL, YSzShift);
+ break;
+ case SBR_LEFT_RIGHT:
+ calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
+ h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
+ eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
+ h_envChan[0], SBR_MONO, NULL, YSzShift);
+ calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
+ h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
+ eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con,
+ h_envChan[1], SBR_MONO, NULL, YSzShift);
+ break;
+ case SBR_COUPLING:
+ calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer,
+ h_envChan[1]->sbrExtractEnvelope.YBuffer,
+ h_envChan[0]->sbrExtractEnvelope.YBufferScale,
+ h_envChan[1]->sbrExtractEnvelope.YBufferScale,
+ eData[0].frame_info, eData[0].sfb_nrg,
+ eData[1].sfb_nrg, h_con, h_envChan[0], SBR_COUPLING,
+ &fData->maxQuantError, YSzShift);
+ break;
+ case SBR_SWITCH_LRC:
+ calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
+ h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
+ eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
+ h_envChan[0], SBR_MONO, NULL, YSzShift);
+ calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
+ h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
+ eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con,
+ h_envChan[1], SBR_MONO, NULL, YSzShift);
+ calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer,
+ h_envChan[1]->sbrExtractEnvelope.YBuffer,
+ h_envChan[0]->sbrExtractEnvelope.YBufferScale,
+ h_envChan[1]->sbrExtractEnvelope.YBufferScale,
+ eData[0].frame_info, eData[0].sfb_nrg_coupling,
+ eData[1].sfb_nrg_coupling, h_con, h_envChan[0],
+ SBR_COUPLING, &fData->maxQuantError, YSzShift);
+ break;
+ }
+
+ /*
+ Noise floor quantisation and coding.
+ */
+
+ switch (stereoMode) {
+ case SBR_MONO:
+ sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
+ 0);
+
+ FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
+ &h_envChan[0]->sbrCodeNoiseFloor,
+ h_envChan[0]->encEnvData.domain_vec_noise, 0,
+ (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
+ sbrBitstreamData->HeaderActive);
+
+ break;
+ case SBR_LEFT_RIGHT:
+ sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
+ 0);
+
+ FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
+ &h_envChan[0]->sbrCodeNoiseFloor,
+ h_envChan[0]->encEnvData.domain_vec_noise, 0,
+ (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
+ sbrBitstreamData->HeaderActive);
+
+ sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
+ 0);
+
+ FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
+ &h_envChan[1]->sbrCodeNoiseFloor,
+ h_envChan[1]->encEnvData.domain_vec_noise, 0,
+ (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
+ sbrBitstreamData->HeaderActive);
+
+ break;
+
+ case SBR_COUPLING:
+ coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor);
+
+ sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
+ 0);
+
+ FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
+ &h_envChan[0]->sbrCodeNoiseFloor,
+ h_envChan[0]->encEnvData.domain_vec_noise, 1,
+ (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
+ sbrBitstreamData->HeaderActive);
+
+ sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
+ 1);
+
+ FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
+ &h_envChan[1]->sbrCodeNoiseFloor,
+ h_envChan[1]->encEnvData.domain_vec_noise, 1,
+ (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
+ sbrBitstreamData->HeaderActive);
+
+ break;
+ case SBR_SWITCH_LRC:
+ sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
+ 0);
+ sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
+ 0);
+ coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor);
+ sbrNoiseFloorLevelsQuantisation(eData[0].noise_level_coupling,
+ eData[0].noiseFloor, 0);
+ sbrNoiseFloorLevelsQuantisation(eData[1].noise_level_coupling,
+ eData[1].noiseFloor, 1);
+ break;
+ }
+
+ /*
+ Encode envelope of current frame.
+ */
+ switch (stereoMode) {
+ case SBR_MONO:
+ sbrHeaderData->coupling = 0;
+ h_envChan[0]->encEnvData.balance = 0;
+ FDKsbrEnc_codeEnvelope(
+ eData[0].sfb_nrg, eData[0].frame_info->freqRes,
+ &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
+ sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
+ sbrBitstreamData->HeaderActive);
+ break;
+ case SBR_LEFT_RIGHT:
+ sbrHeaderData->coupling = 0;
+
+ h_envChan[0]->encEnvData.balance = 0;
+ h_envChan[1]->encEnvData.balance = 0;
+
+ FDKsbrEnc_codeEnvelope(
+ eData[0].sfb_nrg, eData[0].frame_info->freqRes,
+ &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
+ sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
+ sbrBitstreamData->HeaderActive);
+ FDKsbrEnc_codeEnvelope(
+ eData[1].sfb_nrg, eData[1].frame_info->freqRes,
+ &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
+ sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 0,
+ sbrBitstreamData->HeaderActive);
+ break;
+ case SBR_COUPLING:
+ sbrHeaderData->coupling = 1;
+ h_envChan[0]->encEnvData.balance = 0;
+ h_envChan[1]->encEnvData.balance = 1;
+
+ FDKsbrEnc_codeEnvelope(
+ eData[0].sfb_nrg, eData[0].frame_info->freqRes,
+ &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
+ sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
+ sbrBitstreamData->HeaderActive);
+ FDKsbrEnc_codeEnvelope(
+ eData[1].sfb_nrg, eData[1].frame_info->freqRes,
+ &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
+ sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 1,
+ sbrBitstreamData->HeaderActive);
+ break;
+ case SBR_SWITCH_LRC: {
+ INT payloadbitsLR;
+ INT payloadbitsCOUPLING;
+
+ SCHAR sfbNrgPrevTemp[MAX_NUM_CHANNELS][MAX_FREQ_COEFFS];
+ SCHAR noisePrevTemp[MAX_NUM_CHANNELS][MAX_NUM_NOISE_COEFFS];
+ INT upDateNrgTemp[MAX_NUM_CHANNELS];
+ INT upDateNoiseTemp[MAX_NUM_CHANNELS];
+ INT domainVecTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
+ INT domainVecNoiseTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
+
+ INT tempFlagRight = 0;
+ INT tempFlagLeft = 0;
+
+ /*
+ Store previous values, in order to be able to "undo" what is being
+ done.
+ */
+
+ for (ch = 0; ch < nChannels; ch++) {
+ FDKmemcpy(sfbNrgPrevTemp[ch],
+ h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
+ MAX_FREQ_COEFFS * sizeof(SCHAR));
+
+ FDKmemcpy(noisePrevTemp[ch],
+ h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
+ MAX_NUM_NOISE_COEFFS * sizeof(SCHAR));
+
+ upDateNrgTemp[ch] = h_envChan[ch]->sbrCodeEnvelope.upDate;
+ upDateNoiseTemp[ch] = h_envChan[ch]->sbrCodeNoiseFloor.upDate;
+
+ /*
+ forbid time coding in the first envelope in case of a different
+ previous stereomode
+ */
+ if (sbrHeaderData->prev_coupling) {
+ h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
+ h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
+ }
+ } /* ch */
+
+ /*
+ Code ordinary Left/Right stereo
+ */
+ FDKsbrEnc_codeEnvelope(eData[0].sfb_nrg, eData[0].frame_info->freqRes,
+ &h_envChan[0]->sbrCodeEnvelope,
+ h_envChan[0]->encEnvData.domain_vec, 0,
+ eData[0].frame_info->nEnvelopes, 0,
+ sbrBitstreamData->HeaderActive);
+ FDKsbrEnc_codeEnvelope(eData[1].sfb_nrg, eData[1].frame_info->freqRes,
+ &h_envChan[1]->sbrCodeEnvelope,
+ h_envChan[1]->encEnvData.domain_vec, 0,
+ eData[1].frame_info->nEnvelopes, 0,
+ sbrBitstreamData->HeaderActive);
+
+ c = 0;
+ for (i = 0; i < eData[0].nEnvelopes; i++) {
+ for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) {
+ h_envChan[0]->encEnvData.ienvelope[i][j] = eData[0].sfb_nrg[c];
+ h_envChan[1]->encEnvData.ienvelope[i][j] = eData[1].sfb_nrg[c];
+ c++;
+ }
+ }
+
+ FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
+ &h_envChan[0]->sbrCodeNoiseFloor,
+ h_envChan[0]->encEnvData.domain_vec_noise, 0,
+ (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
+ sbrBitstreamData->HeaderActive);
+
+ for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
+ h_envChan[0]->encEnvData.sbr_noise_levels[i] = eData[0].noise_level[i];
+
+ FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
+ &h_envChan[1]->sbrCodeNoiseFloor,
+ h_envChan[1]->encEnvData.domain_vec_noise, 0,
+ (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
+ sbrBitstreamData->HeaderActive);
+
+ for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
+ h_envChan[1]->encEnvData.sbr_noise_levels[i] = eData[1].noise_level[i];
+
+ sbrHeaderData->coupling = 0;
+ h_envChan[0]->encEnvData.balance = 0;
+ h_envChan[1]->encEnvData.balance = 0;
+
+ payloadbitsLR = FDKsbrEnc_CountSbrChannelPairElement(
+ sbrHeaderData, hParametricStereo, sbrBitstreamData,
+ &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
+ h_con->sbrSyntaxFlags);
+
+ /*
+ swap saved stored with current values
+ */
+ for (ch = 0; ch < nChannels; ch++) {
+ INT itmp;
+ for (i = 0; i < MAX_FREQ_COEFFS; i++) {
+ /*
+ swap sfb energies
+ */
+ itmp = h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i];
+ h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i] =
+ sfbNrgPrevTemp[ch][i];
+ sfbNrgPrevTemp[ch][i] = itmp;
+ }
+ for (i = 0; i < MAX_NUM_NOISE_COEFFS; i++) {
+ /*
+ swap noise energies
+ */
+ itmp = h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i];
+ h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i] =
+ noisePrevTemp[ch][i];
+ noisePrevTemp[ch][i] = itmp;
+ }
+ /* swap update flags */
+ itmp = h_envChan[ch]->sbrCodeEnvelope.upDate;
+ h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch];
+ upDateNrgTemp[ch] = itmp;
+
+ itmp = h_envChan[ch]->sbrCodeNoiseFloor.upDate;
+ h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch];
+ upDateNoiseTemp[ch] = itmp;
+
+ /*
+ save domain vecs
+ */
+ FDKmemcpy(domainVecTemp[ch], h_envChan[ch]->encEnvData.domain_vec,
+ sizeof(INT) * MAX_ENVELOPES);
+ FDKmemcpy(domainVecNoiseTemp[ch],
+ h_envChan[ch]->encEnvData.domain_vec_noise,
+ sizeof(INT) * MAX_ENVELOPES);
+
+ /*
+ forbid time coding in the first envelope in case of a different
+ previous stereomode
+ */
+
+ if (!sbrHeaderData->prev_coupling) {
+ h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
+ h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
+ }
+ } /* ch */
+
+ /*
+ Coupling
+ */
+
+ FDKsbrEnc_codeEnvelope(
+ eData[0].sfb_nrg_coupling, eData[0].frame_info->freqRes,
+ &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
+ 1, eData[0].frame_info->nEnvelopes, 0,
+ sbrBitstreamData->HeaderActive);
+
+ FDKsbrEnc_codeEnvelope(
+ eData[1].sfb_nrg_coupling, eData[1].frame_info->freqRes,
+ &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
+ 1, eData[1].frame_info->nEnvelopes, 1,
+ sbrBitstreamData->HeaderActive);
+
+ c = 0;
+ for (i = 0; i < eData[0].nEnvelopes; i++) {
+ for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) {
+ h_envChan[0]->encEnvData.ienvelope[i][j] =
+ eData[0].sfb_nrg_coupling[c];
+ h_envChan[1]->encEnvData.ienvelope[i][j] =
+ eData[1].sfb_nrg_coupling[c];
+ c++;
+ }
+ }
+
+ FDKsbrEnc_codeEnvelope(eData[0].noise_level_coupling, fData->res,
+ &h_envChan[0]->sbrCodeNoiseFloor,
+ h_envChan[0]->encEnvData.domain_vec_noise, 1,
+ (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
+ sbrBitstreamData->HeaderActive);
+
+ for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
+ h_envChan[0]->encEnvData.sbr_noise_levels[i] =
+ eData[0].noise_level_coupling[i];
+
+ FDKsbrEnc_codeEnvelope(eData[1].noise_level_coupling, fData->res,
+ &h_envChan[1]->sbrCodeNoiseFloor,
+ h_envChan[1]->encEnvData.domain_vec_noise, 1,
+ (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
+ sbrBitstreamData->HeaderActive);
+
+ for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
+ h_envChan[1]->encEnvData.sbr_noise_levels[i] =
+ eData[1].noise_level_coupling[i];
+
+ sbrHeaderData->coupling = 1;
+
+ h_envChan[0]->encEnvData.balance = 0;
+ h_envChan[1]->encEnvData.balance = 1;
+
+ tempFlagLeft = h_envChan[0]->encEnvData.addHarmonicFlag;
+ tempFlagRight = h_envChan[1]->encEnvData.addHarmonicFlag;
+
+ payloadbitsCOUPLING = FDKsbrEnc_CountSbrChannelPairElement(
+ sbrHeaderData, hParametricStereo, sbrBitstreamData,
+ &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
+ h_con->sbrSyntaxFlags);
+
+ h_envChan[0]->encEnvData.addHarmonicFlag = tempFlagLeft;
+ h_envChan[1]->encEnvData.addHarmonicFlag = tempFlagRight;
+
+ if (payloadbitsCOUPLING < payloadbitsLR) {
+ /*
+ copy coded coupling envelope and noise data to l/r
+ */
+ for (ch = 0; ch < nChannels; ch++) {
+ SBR_ENV_TEMP_DATA *ed = &eData[ch];
+ FDKmemcpy(ed->sfb_nrg, ed->sfb_nrg_coupling,
+ MAX_NUM_ENVELOPE_VALUES * sizeof(SCHAR));
+ FDKmemcpy(ed->noise_level, ed->noise_level_coupling,
+ MAX_NUM_NOISE_VALUES * sizeof(SCHAR));
+ }
+
+ sbrHeaderData->coupling = 1;
+ h_envChan[0]->encEnvData.balance = 0;
+ h_envChan[1]->encEnvData.balance = 1;
+ } else {
+ /*
+ restore saved l/r items
+ */
+ for (ch = 0; ch < nChannels; ch++) {
+ FDKmemcpy(h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
+ sfbNrgPrevTemp[ch], MAX_FREQ_COEFFS * sizeof(SCHAR));
+
+ h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch];
+
+ FDKmemcpy(h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
+ noisePrevTemp[ch], MAX_NUM_NOISE_COEFFS * sizeof(SCHAR));
+
+ FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec, domainVecTemp[ch],
+ sizeof(INT) * MAX_ENVELOPES);
+ FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec_noise,
+ domainVecNoiseTemp[ch], sizeof(INT) * MAX_ENVELOPES);
+
+ h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch];
+ }
+
+ sbrHeaderData->coupling = 0;
+ h_envChan[0]->encEnvData.balance = 0;
+ h_envChan[1]->encEnvData.balance = 0;
+ }
+ } break;
+ } /* switch */
+
+ /* tell the envelope encoders how long it has been, since we last sent
+ a frame starting with a dF-coded envelope */
+ if (stereoMode == SBR_MONO) {
+ if (h_envChan[0]->encEnvData.domain_vec[0] == TIME)
+ h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
+ else
+ h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
+ } else {
+ if (h_envChan[0]->encEnvData.domain_vec[0] == TIME ||
+ h_envChan[1]->encEnvData.domain_vec[0] == TIME) {
+ h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
+ h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac++;
+ } else {
+ h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
+ h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
+ }
+ }
+
+ /*
+ Send the encoded data to the bitstream
+ */
+ for (ch = 0; ch < nChannels; ch++) {
+ SBR_ENV_TEMP_DATA *ed = &eData[ch];
+ c = 0;
+ for (i = 0; i < ed->nEnvelopes; i++) {
+ for (j = 0; j < h_envChan[ch]->encEnvData.noScfBands[i]; j++) {
+ h_envChan[ch]->encEnvData.ienvelope[i][j] = ed->sfb_nrg[c];
+
+ c++;
+ }
+ }
+ for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
+ h_envChan[ch]->encEnvData.sbr_noise_levels[i] = ed->noise_level[i];
+ }
+ } /* ch */
+
+ /*
+ Write bitstream
+ */
+ if (nChannels == 2) {
+ FDKsbrEnc_WriteEnvChannelPairElement(
+ sbrHeaderData, hParametricStereo, sbrBitstreamData,
+ &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
+ h_con->sbrSyntaxFlags);
+ } else {
+ FDKsbrEnc_WriteEnvSingleChannelElement(
+ sbrHeaderData, hParametricStereo, sbrBitstreamData,
+ &h_envChan[0]->encEnvData, hCmonData, h_con->sbrSyntaxFlags);
+ }
+
+ /*
+ * Update buffers.
+ */
+ for (ch = 0; ch < nChannels; ch++) {
+ int YBufferLength = h_envChan[ch]->sbrExtractEnvelope.no_cols >>
+ h_envChan[ch]->sbrExtractEnvelope.YBufferSzShift;
+ for (i = 0; i < h_envChan[ch]->sbrExtractEnvelope.YBufferWriteOffset; i++) {
+ FDKmemcpy(h_envChan[ch]->sbrExtractEnvelope.YBuffer[i],
+ h_envChan[ch]->sbrExtractEnvelope.YBuffer[i + YBufferLength],
+ sizeof(FIXP_DBL) * 64);
+ }
+ h_envChan[ch]->sbrExtractEnvelope.YBufferScale[0] =
+ h_envChan[ch]->sbrExtractEnvelope.YBufferScale[1];
+ }
+
+ sbrHeaderData->prev_coupling = sbrHeaderData->coupling;
+}
+
+/***************************************************************************/
+/*!
+
+ \brief creates an envelope extractor handle
+
+ \return error status
+
+****************************************************************************/
+INT FDKsbrEnc_CreateExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
+ INT channel, INT chInEl,
+ UCHAR *dynamic_RAM) {
+ INT i;
+ FIXP_DBL *rBuffer, *iBuffer;
+ INT n;
+ FIXP_DBL *YBufferDyn;
+
+ FDKmemclear(hSbrCut, sizeof(SBR_EXTRACT_ENVELOPE));
+
+ if (NULL == (hSbrCut->p_YBuffer = GetRam_Sbr_envYBuffer(channel))) {
+ goto bail;
+ }
+
+ for (i = 0; i < (32 >> 1); i++) {
+ hSbrCut->YBuffer[i] = hSbrCut->p_YBuffer + (i * 64);
+ }
+ YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
+ for (n = 0; i < 32; i++, n++) {
+ hSbrCut->YBuffer[i] = YBufferDyn + (n * 64);
+ }
+
+ rBuffer = GetRam_Sbr_envRBuffer(0, dynamic_RAM);
+ iBuffer = GetRam_Sbr_envIBuffer(0, dynamic_RAM);
+
+ for (i = 0; i < 32; i++) {
+ hSbrCut->rBuffer[i] = rBuffer + (i * 64);
+ hSbrCut->iBuffer[i] = iBuffer + (i * 64);
+ }
+
+ return 0;
+
+bail:
+ FDKsbrEnc_deleteExtractSbrEnvelope(hSbrCut);
+
+ return -1;
+}
+
+/***************************************************************************/
+/*!
+
+ \brief Initialize an envelope extractor instance.
+
+ \return error status
+
+****************************************************************************/
+INT FDKsbrEnc_InitExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
+ int no_cols, int no_rows, int start_index,
+ int time_slots, int time_step,
+ int tran_off, ULONG statesInitFlag,
+ int chInEl, UCHAR *dynamic_RAM,
+ UINT sbrSyntaxFlags) {
+ int YBufferLength, rBufferLength;
+ int i;
+
+ if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
+ int off = TRANSIENT_OFFSET_LD;
+ hSbrCut->YBufferWriteOffset = (no_cols >> 1) + off * time_step;
+ } else {
+ hSbrCut->YBufferWriteOffset = tran_off * time_step;
+ }
+ hSbrCut->rBufferReadOffset = 0;
+
+ YBufferLength = hSbrCut->YBufferWriteOffset + no_cols;
+ rBufferLength = no_cols;
+
+ hSbrCut->pre_transient_info[0] = 0;
+ hSbrCut->pre_transient_info[1] = 0;
+
+ hSbrCut->no_cols = no_cols;
+ hSbrCut->no_rows = no_rows;
+ hSbrCut->start_index = start_index;
+
+ hSbrCut->time_slots = time_slots;
+ hSbrCut->time_step = time_step;
+
+ FDK_ASSERT(no_rows <= 64);
+
+ /* Use half the Energy values if time step is 2 or greater */
+ if (time_step >= 2)
+ hSbrCut->YBufferSzShift = 1;
+ else
+ hSbrCut->YBufferSzShift = 0;
+
+ YBufferLength >>= hSbrCut->YBufferSzShift;
+ hSbrCut->YBufferWriteOffset >>= hSbrCut->YBufferSzShift;
+
+ FDK_ASSERT(YBufferLength <= 32);
+
+ FIXP_DBL *YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
+ INT n = 0;
+ for (i = (32 >> 1); i < 32; i++, n++) {
+ hSbrCut->YBuffer[i] = YBufferDyn + (n * 64);
+ }
+
+ if (statesInitFlag) {
+ for (i = 0; i < YBufferLength; i++) {
+ FDKmemclear(hSbrCut->YBuffer[i], 64 * sizeof(FIXP_DBL));
+ }
+ }
+
+ for (i = 0; i < rBufferLength; i++) {
+ FDKmemclear(hSbrCut->rBuffer[i], 64 * sizeof(FIXP_DBL));
+ FDKmemclear(hSbrCut->iBuffer[i], 64 * sizeof(FIXP_DBL));
+ }
+
+ FDKmemclear(hSbrCut->envelopeCompensation, sizeof(UCHAR) * MAX_FREQ_COEFFS);
+
+ if (statesInitFlag) {
+ hSbrCut->YBufferScale[0] = hSbrCut->YBufferScale[1] = FRACT_BITS - 1;
+ }
+
+ return (0);
+}
+
+/***************************************************************************/
+/*!
+
+ \brief deinitializes an envelope extractor handle
+
+ \return void
+
+****************************************************************************/
+
+void FDKsbrEnc_deleteExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut) {
+ if (hSbrCut) {
+ FreeRam_Sbr_envYBuffer(&hSbrCut->p_YBuffer);
+ }
+}
+
+INT FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr) {
+ return hSbr->no_rows *
+ ((hSbr->YBufferWriteOffset) *
+ 2 /* mult 2 because nrg's are grouped half */
+ - hSbr->rBufferReadOffset); /* in reference hold half spec and calc
+ nrg's on overlapped spec */
+}
diff --git a/fdk-aac/libSBRenc/src/env_est.h b/fdk-aac/libSBRenc/src/env_est.h
new file mode 100644
index 0000000..006f55b
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/env_est.h
@@ -0,0 +1,223 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Envelope estimation structs and prototypes $Revision: 92790 $
+*/
+#ifndef ENV_EST_H
+#define ENV_EST_H
+
+#include "sbr_def.h"
+#include "sbr_encoder.h" /* SBR econfig structs */
+#include "ps_main.h"
+#include "bit_sbr.h"
+#include "fram_gen.h"
+#include "tran_det.h"
+#include "code_env.h"
+#include "ton_corr.h"
+
+typedef struct {
+ FIXP_DBL *rBuffer[32];
+ FIXP_DBL *iBuffer[32];
+
+ FIXP_DBL *p_YBuffer;
+
+ FIXP_DBL *YBuffer[32];
+ int YBufferScale[2];
+
+ UCHAR envelopeCompensation[MAX_FREQ_COEFFS];
+ UCHAR pre_transient_info[2];
+
+ int YBufferWriteOffset;
+ int YBufferSzShift;
+ int rBufferReadOffset;
+
+ int no_cols;
+ int no_rows;
+ int start_index;
+
+ int time_slots;
+ int time_step;
+} SBR_EXTRACT_ENVELOPE;
+typedef SBR_EXTRACT_ENVELOPE *HANDLE_SBR_EXTRACT_ENVELOPE;
+
+struct ENV_CHANNEL {
+ FAST_TRAN_DETECTOR sbrFastTransientDetector;
+ SBR_TRANSIENT_DETECTOR sbrTransientDetector;
+ SBR_CODE_ENVELOPE sbrCodeEnvelope;
+ SBR_CODE_ENVELOPE sbrCodeNoiseFloor;
+ SBR_EXTRACT_ENVELOPE sbrExtractEnvelope;
+
+ SBR_ENVELOPE_FRAME SbrEnvFrame;
+ SBR_TON_CORR_EST TonCorr;
+
+ struct SBR_ENV_DATA encEnvData;
+
+ int qmfScale;
+ UCHAR fLevelProtect;
+};
+typedef struct ENV_CHANNEL *HANDLE_ENV_CHANNEL;
+
+/************ Function Declarations ***************/
+
+INT FDKsbrEnc_CreateExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
+ INT channel, INT chInEl,
+ UCHAR *dynamic_RAM);
+
+INT FDKsbrEnc_InitExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbr,
+ int no_cols, int no_rows, int start_index,
+ int time_slots, int time_step,
+ int tran_off, ULONG statesInitFlag,
+ int chInEl, UCHAR *dynamic_RAM,
+ UINT sbrSyntaxFlags);
+
+void FDKsbrEnc_deleteExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut);
+
+typedef struct {
+ FREQ_RES res[MAX_NUM_NOISE_VALUES];
+ int maxQuantError;
+
+} SBR_FRAME_TEMP_DATA;
+
+typedef struct {
+ const SBR_FRAME_INFO *frame_info;
+ FIXP_DBL noiseFloor[MAX_NUM_NOISE_VALUES];
+ SCHAR sfb_nrg_coupling
+ [MAX_NUM_ENVELOPE_VALUES]; /* only used if stereomode = SWITCH_L_R_C */
+ SCHAR sfb_nrg[MAX_NUM_ENVELOPE_VALUES];
+ SCHAR noise_level_coupling
+ [MAX_NUM_NOISE_VALUES]; /* only used if stereomode = SWITCH_L_R_C */
+ SCHAR noise_level[MAX_NUM_NOISE_VALUES];
+ UCHAR transient_info[3];
+ UCHAR nEnvelopes;
+} SBR_ENV_TEMP_DATA;
+
+/*
+ * Extract features from QMF data. Afterwards, the QMF data is not required
+ * anymore.
+ */
+void FDKsbrEnc_extractSbrEnvelope1(HANDLE_SBR_CONFIG_DATA h_con,
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData,
+ HANDLE_ENV_CHANNEL h_envChan,
+ HANDLE_COMMON_DATA cmonData,
+ SBR_ENV_TEMP_DATA *eData,
+ SBR_FRAME_TEMP_DATA *fData);
+
+/*
+ * Process the previously features extracted by FDKsbrEnc_extractSbrEnvelope1
+ * and create/encode SBR envelopes.
+ */
+void FDKsbrEnc_extractSbrEnvelope2(HANDLE_SBR_CONFIG_DATA h_con,
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData,
+ HANDLE_ENV_CHANNEL sbrEnvChannel0,
+ HANDLE_ENV_CHANNEL sbrEnvChannel1,
+ HANDLE_COMMON_DATA cmonData,
+ SBR_ENV_TEMP_DATA *eData,
+ SBR_FRAME_TEMP_DATA *fData, int clearOutput);
+
+INT FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr);
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/fram_gen.cpp b/fdk-aac/libSBRenc/src/fram_gen.cpp
new file mode 100644
index 0000000..7ed6e79
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/fram_gen.cpp
@@ -0,0 +1,1965 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "fram_gen.h"
+#include "sbr_misc.h"
+
+#include "genericStds.h"
+
+static const SBR_FRAME_INFO frameInfo1_2048 = {1, {0, 16}, {FREQ_RES_HIGH},
+ 0, 1, {0, 16}};
+
+static const SBR_FRAME_INFO frameInfo2_2048 = {
+ 2, {0, 8, 16}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 8, 16}};
+
+static const SBR_FRAME_INFO frameInfo4_2048 = {
+ 4,
+ {0, 4, 8, 12, 16},
+ {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH},
+ 0,
+ 2,
+ {0, 8, 16}};
+
+static const SBR_FRAME_INFO frameInfo1_2304 = {1, {0, 18}, {FREQ_RES_HIGH},
+ 0, 1, {0, 18}};
+
+static const SBR_FRAME_INFO frameInfo2_2304 = {
+ 2, {0, 9, 18}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 9, 18}};
+
+static const SBR_FRAME_INFO frameInfo4_2304 = {
+ 4,
+ {0, 5, 9, 14, 18},
+ {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH},
+ 0,
+ 2,
+ {0, 9, 18}};
+
+static const SBR_FRAME_INFO frameInfo1_1920 = {1, {0, 15}, {FREQ_RES_HIGH},
+ 0, 1, {0, 15}};
+
+static const SBR_FRAME_INFO frameInfo2_1920 = {
+ 2, {0, 8, 15}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 8, 15}};
+
+static const SBR_FRAME_INFO frameInfo4_1920 = {
+ 4,
+ {0, 4, 8, 12, 15},
+ {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH},
+ 0,
+ 2,
+ {0, 8, 15}};
+
+static const SBR_FRAME_INFO frameInfo1_1152 = {1, {0, 9}, {FREQ_RES_HIGH},
+ 0, 1, {0, 9}};
+
+static const SBR_FRAME_INFO frameInfo2_1152 = {
+ 2, {0, 5, 9}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 5, 9}};
+
+static const SBR_FRAME_INFO frameInfo4_1152 = {
+ 4,
+ {0, 2, 5, 7, 9},
+ {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH},
+ 0,
+ 2,
+ {0, 5, 9}};
+
+/* AACLD frame info */
+static const SBR_FRAME_INFO frameInfo1_512LD = {1, {0, 8}, {FREQ_RES_HIGH},
+ 0, 1, {0, 8}};
+
+static const SBR_FRAME_INFO frameInfo2_512LD = {
+ 2, {0, 4, 8}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 4, 8}};
+
+static const SBR_FRAME_INFO frameInfo4_512LD = {
+ 4,
+ {0, 2, 4, 6, 8},
+ {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH},
+ 0,
+ 2,
+ {0, 4, 8}};
+
+static int calcFillLengthMax(
+ int tranPos, /*!< input : transient position (ref: tran det) */
+ int numberTimeSlots /*!< input : number of timeslots */
+);
+
+static void fillFrameTran(
+ const int *v_tuningSegm, /*!< tuning: desired segment lengths */
+ const int *v_tuningFreq, /*!< tuning: desired frequency resolutions */
+ int tran, /*!< input : position of transient */
+ int *v_bord, /*!< memNew: borders */
+ int *length_v_bord, /*!< memNew: # borders */
+ int *v_freq, /*!< memNew: frequency resolutions */
+ int *length_v_freq, /*!< memNew: # frequency resolutions */
+ int *bmin, /*!< hlpNew: first mandatory border */
+ int *bmax /*!< hlpNew: last mandatory border */
+);
+
+static void fillFramePre(INT dmax, INT *v_bord, INT *length_v_bord, INT *v_freq,
+ INT *length_v_freq, INT bmin, INT rest);
+
+static void fillFramePost(INT *parts, INT *d, INT dmax, INT *v_bord,
+ INT *length_v_bord, INT *v_freq, INT *length_v_freq,
+ INT bmax, INT bufferFrameStart, INT numberTimeSlots,
+ INT fmax);
+
+static void fillFrameInter(INT *nL, const int *v_tuningSegm, INT *v_bord,
+ INT *length_v_bord, INT bmin, INT *v_freq,
+ INT *length_v_freq, INT *v_bordFollow,
+ INT *length_v_bordFollow, INT *v_freqFollow,
+ INT *length_v_freqFollow, INT i_fillFollow, INT dmin,
+ INT dmax, INT numberTimeSlots);
+
+static void calcFrameClass(FRAME_CLASS *frameClass, FRAME_CLASS *frameClassOld,
+ INT tranFlag, INT *spreadFlag);
+
+static void specialCase(INT *spreadFlag, INT allowSpread, INT *v_bord,
+ INT *length_v_bord, INT *v_freq, INT *length_v_freq,
+ INT *parts, INT d);
+
+static void calcCmonBorder(INT *i_cmon, INT *i_tran, INT *v_bord,
+ INT *length_v_bord, INT tran, INT bufferFrameStart,
+ INT numberTimeSlots);
+
+static void keepForFollowUp(INT *v_bordFollow, INT *length_v_bordFollow,
+ INT *v_freqFollow, INT *length_v_freqFollow,
+ INT *i_tranFollow, INT *i_fillFollow, INT *v_bord,
+ INT *length_v_bord, INT *v_freq, INT i_cmon,
+ INT i_tran, INT parts, INT numberTimeSlots);
+
+static void calcCtrlSignal(HANDLE_SBR_GRID hSbrGrid, FRAME_CLASS frameClass,
+ INT *v_bord, INT length_v_bord, INT *v_freq,
+ INT length_v_freq, INT i_cmon, INT i_tran,
+ INT spreadFlag, INT nL);
+
+static void ctrlSignal2FrameInfo(HANDLE_SBR_GRID hSbrGrid,
+ HANDLE_SBR_FRAME_INFO hFrameInfo,
+ FREQ_RES *freq_res_fixfix);
+
+/* table for 8 time slot index */
+static const int envelopeTable_8[8][5] = {
+ /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */
+ /* borders from left to right side; -1 = not in use */
+ /*[|T-|------]*/ {2, 0, 0, 1, -1},
+ /*[|-T-|-----]*/ {2, 0, 0, 2, -1},
+ /*[--|T-|----]*/ {3, 1, 1, 2, 4},
+ /*[---|T-|---]*/ {3, 1, 1, 3, 5},
+ /*[----|T-|--]*/ {3, 1, 1, 4, 6},
+ /*[-----|T--|]*/ {2, 1, 1, 5, -1},
+ /*[------|T-|]*/ {2, 1, 1, 6, -1},
+ /*[-------|T|]*/ {2, 1, 1, 7, -1},
+};
+
+/* table for 16 time slot index */
+static const int envelopeTable_16[16][6] = {
+ /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */
+ /* length from left to right side; -1 = not in use */
+ /*[|T---|------------|]*/ {2, 0, 0, 4, -1, -1},
+ /*[|-T---|-----------|]*/ {2, 0, 0, 5, -1, -1},
+ /*[|--|T---|----------]*/ {3, 1, 1, 2, 6, -1},
+ /*[|---|T---|---------]*/ {3, 1, 1, 3, 7, -1},
+ /*[|----|T---|--------]*/ {3, 1, 1, 4, 8, -1},
+ /*[|-----|T---|-------]*/ {3, 1, 1, 5, 9, -1},
+ /*[|------|T---|------]*/ {3, 1, 1, 6, 10, -1},
+ /*[|-------|T---|-----]*/ {3, 1, 1, 7, 11, -1},
+ /*[|--------|T---|----]*/ {3, 1, 1, 8, 12, -1},
+ /*[|---------|T---|---]*/ {3, 1, 1, 9, 13, -1},
+ /*[|----------|T---|--]*/ {3, 1, 1, 10, 14, -1},
+ /*[|-----------|T----|]*/ {2, 1, 1, 11, -1, -1},
+ /*[|------------|T---|]*/ {2, 1, 1, 12, -1, -1},
+ /*[|-------------|T--|]*/ {2, 1, 1, 13, -1, -1},
+ /*[|--------------|T-|]*/ {2, 1, 1, 14, -1, -1},
+ /*[|---------------|T|]*/ {2, 1, 1, 15, -1, -1},
+};
+
+/* table for 15 time slot index */
+static const int envelopeTable_15[15][6] = {
+ /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */
+ /* length from left to right side; -1 = not in use */
+ /*[|T---|------------]*/ {2, 0, 0, 4, -1, -1},
+ /*[|-T---|-----------]*/ {2, 0, 0, 5, -1, -1},
+ /*[|--|T---|---------]*/ {3, 1, 1, 2, 6, -1},
+ /*[|---|T---|--------]*/ {3, 1, 1, 3, 7, -1},
+ /*[|----|T---|-------]*/ {3, 1, 1, 4, 8, -1},
+ /*[|-----|T---|------]*/ {3, 1, 1, 5, 9, -1},
+ /*[|------|T---|-----]*/ {3, 1, 1, 6, 10, -1},
+ /*[|-------|T---|----]*/ {3, 1, 1, 7, 11, -1},
+ /*[|--------|T---|---]*/ {3, 1, 1, 8, 12, -1},
+ /*[|---------|T---|--]*/ {3, 1, 1, 9, 13, -1},
+ /*[|----------|T----|]*/ {2, 1, 1, 10, -1, -1},
+ /*[|-----------|T---|]*/ {2, 1, 1, 11, -1, -1},
+ /*[|------------|T--|]*/ {2, 1, 1, 12, -1, -1},
+ /*[|-------------|T-|]*/ {2, 1, 1, 13, -1, -1},
+ /*[|--------------|T|]*/ {2, 1, 1, 14, -1, -1},
+};
+
+static const int minFrameTranDistance = 4;
+
+static const FREQ_RES freqRes_table_8[] = {
+ FREQ_RES_LOW, FREQ_RES_LOW, FREQ_RES_LOW, FREQ_RES_LOW, FREQ_RES_LOW,
+ FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH};
+
+static const FREQ_RES freqRes_table_16[16] = {
+ /* size of envelope */
+ /* 0-4 */ FREQ_RES_LOW,
+ FREQ_RES_LOW,
+ FREQ_RES_LOW,
+ FREQ_RES_LOW,
+ FREQ_RES_LOW,
+ /* 5-9 */ FREQ_RES_LOW,
+ FREQ_RES_HIGH,
+ FREQ_RES_HIGH,
+ FREQ_RES_HIGH,
+ FREQ_RES_HIGH,
+ /* 10-16 */ FREQ_RES_HIGH,
+ FREQ_RES_HIGH,
+ FREQ_RES_HIGH,
+ FREQ_RES_HIGH,
+ FREQ_RES_HIGH,
+ FREQ_RES_HIGH};
+
+static void generateFixFixOnly(HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
+ HANDLE_SBR_GRID hSbrGrid, int tranPosInternal,
+ int numberTimeSlots, UCHAR fResTransIsLow);
+
+/*!
+ Functionname: FDKsbrEnc_frameInfoGenerator
+
+ Description: produces the FRAME_INFO struct for the current frame
+
+ Arguments: hSbrEnvFrame - pointer to sbr envelope handle
+ v_pre_transient_info - pointer to transient info vector
+ v_transient_info - pointer to previous transient info
+vector v_tuning - pointer to tuning vector
+
+ Return: frame_info - pointer to SBR_FRAME_INFO struct
+
+*******************************************************************************/
+HANDLE_SBR_FRAME_INFO
+FDKsbrEnc_frameInfoGenerator(HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
+ UCHAR *v_transient_info, const INT rightBorderFIX,
+ UCHAR *v_transient_info_pre, int ldGrid,
+ const int *v_tuning) {
+ INT numEnv, tranPosInternal = 0, bmin = 0, bmax = 0, parts, d, i_cmon = 0,
+ i_tran = 0, nL;
+ INT fmax = 0;
+
+ INT *v_bord = hSbrEnvFrame->v_bord;
+ INT *v_freq = hSbrEnvFrame->v_freq;
+ INT *v_bordFollow = hSbrEnvFrame->v_bordFollow;
+ INT *v_freqFollow = hSbrEnvFrame->v_freqFollow;
+
+ INT *length_v_bordFollow = &hSbrEnvFrame->length_v_bordFollow;
+ INT *length_v_freqFollow = &hSbrEnvFrame->length_v_freqFollow;
+ INT *length_v_bord = &hSbrEnvFrame->length_v_bord;
+ INT *length_v_freq = &hSbrEnvFrame->length_v_freq;
+ INT *spreadFlag = &hSbrEnvFrame->spreadFlag;
+ INT *i_tranFollow = &hSbrEnvFrame->i_tranFollow;
+ INT *i_fillFollow = &hSbrEnvFrame->i_fillFollow;
+ FRAME_CLASS *frameClassOld = &hSbrEnvFrame->frameClassOld;
+ FRAME_CLASS frameClass = FIXFIX;
+
+ INT allowSpread = hSbrEnvFrame->allowSpread;
+ INT numEnvStatic = hSbrEnvFrame->numEnvStatic;
+ INT staticFraming = hSbrEnvFrame->staticFraming;
+ INT dmin = hSbrEnvFrame->dmin;
+ INT dmax = hSbrEnvFrame->dmax;
+
+ INT bufferFrameStart = hSbrEnvFrame->SbrGrid.bufferFrameStart;
+ INT numberTimeSlots = hSbrEnvFrame->SbrGrid.numberTimeSlots;
+ INT frameMiddleSlot = hSbrEnvFrame->frameMiddleSlot;
+
+ INT tranPos = v_transient_info[0];
+ INT tranFlag = v_transient_info[1];
+
+ const int *v_tuningSegm = v_tuning;
+ const int *v_tuningFreq = v_tuning + 3;
+
+ hSbrEnvFrame->v_tuningSegm = v_tuningSegm;
+
+ if (ldGrid) {
+ /* in case there was a transient at the very end of the previous frame,
+ * start with a transient envelope */
+ if (!tranFlag && v_transient_info_pre[1] &&
+ (numberTimeSlots - v_transient_info_pre[0] < minFrameTranDistance)) {
+ tranFlag = 1;
+ tranPos = 0;
+ }
+ }
+
+ /*
+ * Synopsis:
+ *
+ * The frame generator creates the time-/frequency-grid for one SBR frame.
+ * Input signals are provided by the transient detector and the frame
+ * splitter (transientDetectNew() & FrameSplitter() in tran_det.c). The
+ * framing is controlled by adjusting tuning parameters stored in
+ * FRAME_GEN_TUNING. The parameter values are dependent on frame lengths
+ * and bitrates, and may in the future be signal dependent.
+ *
+ * The envelope borders are stored for frame generator internal use in
+ * aBorders. The contents of aBorders represent positions along the time
+ * axis given in the figures in fram_gen.h (the "frame-generator" rows).
+ * The unit is "time slot". The figures in fram_gen.h also define the
+ * detection ranges for the transient detector. For every border in
+ * aBorders, there is a corresponding entry in aFreqRes, which defines the
+ * frequency resolution of the envelope following (delimited by) the
+ * border.
+ *
+ * When no transients are present, FIXFIX class frames are used. The
+ * frame splitter decides whether to use one or two envelopes in the
+ * FIXFIX frame. "Sparse transients" (separated by a few frames without
+ * transients) are handeled by [FIXVAR, VARFIX] pairs or (depending on
+ * tuning and transient position relative the nominal frame boundaries)
+ * by [FIXVAR, VARVAR, VARFIX] triples. "Tight transients" (in
+ * consecutive frames) are handeled by [..., VARVAR, VARVAR, ...]
+ * sequences.
+ *
+ * The generator assumes that transients are "sparse", and designs
+ * borders for [FIXVAR, VARFIX] pairs right away, where the first frame
+ * corresponds to the present frame. At the next call of the generator
+ * it is known whether the transient actually is "sparse" or not. If
+ * 'yes', the already calculated VARFIX borders are used. If 'no', new
+ * borders, meeting the requirements of the "tight" transient, are
+ * calculated.
+ *
+ * The generator produces two outputs: A "clear-text bitstream" stored in
+ * SBR_GRID, and a straight-forward representation of the grid stored in
+ * SBR_FRAME_INFO. The former is subsequently converted to the actual
+ * bitstream sbr_grid() (encodeSbrGrid() in bit_sbr.c). The latter is
+ * used by other encoder functions, such as the envelope estimator
+ * (calculateSbrEnvelope() in env_est.c) and the noise floor and missing
+ * harmonics detector (TonCorrParamExtr() in nf_est.c).
+ */
+
+ if (staticFraming) {
+ /*--------------------------------------------------------------------------
+ Ignore transient detector
+ ---------------------------------------------------------------------------*/
+
+ frameClass = FIXFIX;
+ numEnv = numEnvStatic; /* {1,2,4,8} */
+ *frameClassOld = FIXFIX; /* for change to dyn */
+ hSbrEnvFrame->SbrGrid.bs_num_env = numEnv;
+ hSbrEnvFrame->SbrGrid.frameClass = frameClass;
+ } else {
+ /*--------------------------------------------------------------------------
+ Calculate frame class to use
+ ---------------------------------------------------------------------------*/
+ if (rightBorderFIX) {
+ tranFlag = 0;
+ *spreadFlag = 0;
+ }
+ calcFrameClass(&frameClass, frameClassOld, tranFlag, spreadFlag);
+
+ /* patch for new frame class FIXFIXonly for AAC LD */
+ if (tranFlag && ldGrid) {
+ frameClass = FIXFIXonly;
+ *frameClassOld = FIXFIX;
+ }
+
+ /*
+ * every transient is processed below by inserting
+ *
+ * - one border at the onset of the transient
+ * - one or more "decay borders" (after the onset of the transient)
+ * - optionally one "attack border" (before the onset of the transient)
+ *
+ * those borders are referred to as "mandatory borders" and are
+ * defined by the 'segmentLength' array in FRAME_GEN_TUNING
+ *
+ * the frequency resolutions of the corresponding envelopes are
+ * defined by the 'segmentRes' array in FRAME_GEN_TUNING
+ */
+
+ /*--------------------------------------------------------------------------
+ Design frame (or follow-up old design)
+ ---------------------------------------------------------------------------*/
+ if (tranFlag) {
+ /* Always for FixVar, often but not always for VarVar */
+
+ /*--------------------------------------------------------------------------
+ Design part of T/F-grid around the new transient
+ ---------------------------------------------------------------------------*/
+
+ tranPosInternal =
+ frameMiddleSlot + tranPos + bufferFrameStart; /* FH 00-06-26 */
+ /*
+ add mandatory borders around transient
+ */
+
+ fillFrameTran(v_tuningSegm, v_tuningFreq, tranPosInternal, v_bord,
+ length_v_bord, v_freq, length_v_freq, &bmin, &bmax);
+
+ /* make sure we stay within the maximum SBR frame overlap */
+ fmax = calcFillLengthMax(tranPos, numberTimeSlots);
+ }
+
+ switch (frameClass) {
+ case FIXFIXonly:
+ FDK_ASSERT(ldGrid);
+ tranPosInternal = tranPos;
+ generateFixFixOnly(&(hSbrEnvFrame->SbrFrameInfo),
+ &(hSbrEnvFrame->SbrGrid), tranPosInternal,
+ numberTimeSlots, hSbrEnvFrame->fResTransIsLow);
+
+ return &(hSbrEnvFrame->SbrFrameInfo);
+
+ case FIXVAR:
+
+ /*--------------------------------------------------------------------------
+ Design remaining parts of T/F-grid (assuming next frame is VarFix)
+ ---------------------------------------------------------------------------*/
+
+ /*--------------------------------------------------------------------------
+ Fill region before new transient:
+ ---------------------------------------------------------------------------*/
+ fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin,
+ bmin - bufferFrameStart); /* FH 00-06-26 */
+
+ /*--------------------------------------------------------------------------
+ Fill region after new transient:
+ ---------------------------------------------------------------------------*/
+ fillFramePost(&parts, &d, dmax, v_bord, length_v_bord, v_freq,
+ length_v_freq, bmax, bufferFrameStart, numberTimeSlots,
+ fmax);
+
+ /*--------------------------------------------------------------------------
+ Take care of special case:
+ ---------------------------------------------------------------------------*/
+ if (parts == 1 && d < dmin) /* no fill, short last envelope */
+ specialCase(spreadFlag, allowSpread, v_bord, length_v_bord, v_freq,
+ length_v_freq, &parts, d);
+
+ /*--------------------------------------------------------------------------
+ Calculate common border (split-point)
+ ---------------------------------------------------------------------------*/
+ calcCmonBorder(&i_cmon, &i_tran, v_bord, length_v_bord, tranPosInternal,
+ bufferFrameStart, numberTimeSlots); /* FH 00-06-26 */
+
+ /*--------------------------------------------------------------------------
+ Extract data for proper follow-up in next frame
+ ---------------------------------------------------------------------------*/
+ keepForFollowUp(v_bordFollow, length_v_bordFollow, v_freqFollow,
+ length_v_freqFollow, i_tranFollow, i_fillFollow, v_bord,
+ length_v_bord, v_freq, i_cmon, i_tran, parts,
+ numberTimeSlots); /* FH 00-06-26 */
+
+ /*--------------------------------------------------------------------------
+ Calculate control signal
+ ---------------------------------------------------------------------------*/
+ calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bord,
+ *length_v_bord, v_freq, *length_v_freq, i_cmon, i_tran,
+ *spreadFlag, DC);
+ break;
+ case VARFIX:
+ /*--------------------------------------------------------------------------
+ Follow-up old transient - calculate control signal
+ ---------------------------------------------------------------------------*/
+ calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bordFollow,
+ *length_v_bordFollow, v_freqFollow, *length_v_freqFollow,
+ DC, *i_tranFollow, *spreadFlag, DC);
+ break;
+ case VARVAR:
+ if (*spreadFlag) { /* spread across three frames */
+ /*--------------------------------------------------------------------------
+ Follow-up old transient - calculate control signal
+ ---------------------------------------------------------------------------*/
+ calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bordFollow,
+ *length_v_bordFollow, v_freqFollow,
+ *length_v_freqFollow, DC, *i_tranFollow, *spreadFlag,
+ DC);
+
+ *spreadFlag = 0;
+
+ /*--------------------------------------------------------------------------
+ Extract data for proper follow-up in next frame
+ ---------------------------------------------------------------------------*/
+ v_bordFollow[0] = hSbrEnvFrame->SbrGrid.bs_abs_bord_1 -
+ numberTimeSlots; /* FH 00-06-26 */
+ v_freqFollow[0] = 1;
+ *length_v_bordFollow = 1;
+ *length_v_freqFollow = 1;
+
+ *i_tranFollow = -DC;
+ *i_fillFollow = -DC;
+ } else {
+ /*--------------------------------------------------------------------------
+ Design remaining parts of T/F-grid (assuming next frame is VarFix)
+ adapt or fill region before new transient:
+ ---------------------------------------------------------------------------*/
+ fillFrameInter(&nL, v_tuningSegm, v_bord, length_v_bord, bmin, v_freq,
+ length_v_freq, v_bordFollow, length_v_bordFollow,
+ v_freqFollow, length_v_freqFollow, *i_fillFollow, dmin,
+ dmax, numberTimeSlots);
+
+ /*--------------------------------------------------------------------------
+ Fill after transient:
+ ---------------------------------------------------------------------------*/
+ fillFramePost(&parts, &d, dmax, v_bord, length_v_bord, v_freq,
+ length_v_freq, bmax, bufferFrameStart, numberTimeSlots,
+ fmax);
+
+ /*--------------------------------------------------------------------------
+ Take care of special case:
+ ---------------------------------------------------------------------------*/
+ if (parts == 1 && d < dmin) /*% no fill, short last envelope */
+ specialCase(spreadFlag, allowSpread, v_bord, length_v_bord, v_freq,
+ length_v_freq, &parts, d);
+
+ /*--------------------------------------------------------------------------
+ Calculate common border (split-point)
+ ---------------------------------------------------------------------------*/
+ calcCmonBorder(&i_cmon, &i_tran, v_bord, length_v_bord,
+ tranPosInternal, bufferFrameStart, numberTimeSlots);
+
+ /*--------------------------------------------------------------------------
+ Extract data for proper follow-up in next frame
+ ---------------------------------------------------------------------------*/
+ keepForFollowUp(v_bordFollow, length_v_bordFollow, v_freqFollow,
+ length_v_freqFollow, i_tranFollow, i_fillFollow,
+ v_bord, length_v_bord, v_freq, i_cmon, i_tran, parts,
+ numberTimeSlots);
+
+ /*--------------------------------------------------------------------------
+ Calculate control signal
+ ---------------------------------------------------------------------------*/
+ calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bord,
+ *length_v_bord, v_freq, *length_v_freq, i_cmon, i_tran,
+ 0, nL);
+ }
+ break;
+ case FIXFIX:
+ if (tranPos == 0)
+ numEnv = 1;
+ else
+ numEnv = 2;
+
+ hSbrEnvFrame->SbrGrid.bs_num_env = numEnv;
+ hSbrEnvFrame->SbrGrid.frameClass = frameClass;
+
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ Convert control signal to frame info struct
+ ---------------------------------------------------------------------------*/
+ ctrlSignal2FrameInfo(&hSbrEnvFrame->SbrGrid, &hSbrEnvFrame->SbrFrameInfo,
+ hSbrEnvFrame->freq_res_fixfix);
+
+ return &hSbrEnvFrame->SbrFrameInfo;
+}
+
+/***************************************************************************/
+/*!
+ \brief Gnerates frame info for FIXFIXonly frame class used for low delay
+ version
+
+ \return nothing
+ ****************************************************************************/
+static void generateFixFixOnly(HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
+ HANDLE_SBR_GRID hSbrGrid, int tranPosInternal,
+ int numberTimeSlots, UCHAR fResTransIsLow) {
+ int nEnv, i, k = 0, tranIdx;
+ const int *pTable = NULL;
+ const FREQ_RES *freqResTable = NULL;
+
+ switch (numberTimeSlots) {
+ case 8: {
+ pTable = envelopeTable_8[tranPosInternal];
+ }
+ freqResTable = freqRes_table_8;
+ break;
+ case 15:
+ pTable = envelopeTable_15[tranPosInternal];
+ freqResTable = freqRes_table_16;
+ break;
+ case 16:
+ pTable = envelopeTable_16[tranPosInternal];
+ freqResTable = freqRes_table_16;
+ break;
+ }
+
+ /* look number of envolpes in table */
+ nEnv = pTable[0];
+ /* look up envolpe distribution in table */
+ for (i = 1; i < nEnv; i++) hSbrFrameInfo->borders[i] = pTable[i + 2];
+
+ /* open and close frame border */
+ hSbrFrameInfo->borders[0] = 0;
+ hSbrFrameInfo->borders[nEnv] = numberTimeSlots;
+
+ /* adjust segment-frequency-resolution according to the segment-length */
+ for (i = 0; i < nEnv; i++) {
+ k = hSbrFrameInfo->borders[i + 1] - hSbrFrameInfo->borders[i];
+ if (!fResTransIsLow)
+ hSbrFrameInfo->freqRes[i] = freqResTable[k];
+ else
+ hSbrFrameInfo->freqRes[i] = FREQ_RES_LOW;
+
+ hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i];
+ }
+
+ hSbrFrameInfo->nEnvelopes = nEnv;
+ hSbrFrameInfo->shortEnv = pTable[2];
+ /* transient idx */
+ tranIdx = pTable[1];
+
+ /* add noise floors */
+ hSbrFrameInfo->bordersNoise[0] = 0;
+ hSbrFrameInfo->bordersNoise[1] =
+ hSbrFrameInfo->borders[tranIdx ? tranIdx : 1];
+ hSbrFrameInfo->bordersNoise[2] = numberTimeSlots;
+ hSbrFrameInfo->nNoiseEnvelopes = 2;
+
+ hSbrGrid->frameClass = FIXFIXonly;
+ hSbrGrid->bs_abs_bord = tranPosInternal;
+ hSbrGrid->bs_num_env = nEnv;
+}
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_initFrameInfoGenerator
+ *******************************************************************************
+
+ Description:
+
+ Arguments: hSbrEnvFrame - pointer to sbr envelope handle
+ allowSpread - commandline parameter
+ numEnvStatic - commandline parameter
+ staticFraming - commandline parameter
+
+ Return: none
+
+*******************************************************************************/
+void FDKsbrEnc_initFrameInfoGenerator(HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
+ INT allowSpread, INT numEnvStatic,
+ INT staticFraming, INT timeSlots,
+ const FREQ_RES *freq_res_fixfix,
+ UCHAR fResTransIsLow,
+ INT ldGrid) { /* FH 00-06-26 */
+
+ FDKmemclear(hSbrEnvFrame, sizeof(SBR_ENVELOPE_FRAME));
+
+ /* Initialisation */
+ hSbrEnvFrame->frameClassOld = FIXFIX;
+ hSbrEnvFrame->spreadFlag = 0;
+
+ hSbrEnvFrame->allowSpread = allowSpread;
+ hSbrEnvFrame->numEnvStatic = numEnvStatic;
+ hSbrEnvFrame->staticFraming = staticFraming;
+ 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_bordFollow = 0;
+
+ hSbrEnvFrame->length_v_freq = 0;
+ hSbrEnvFrame->length_v_freqFollow = 0;
+
+ hSbrEnvFrame->i_tranFollow = 0;
+ hSbrEnvFrame->i_fillFollow = 0;
+
+ hSbrEnvFrame->SbrGrid.numberTimeSlots = timeSlots;
+
+ if (ldGrid) {
+ /*case CODEC_AACLD:*/
+ hSbrEnvFrame->dmin = 2;
+ hSbrEnvFrame->dmax = 16;
+ hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_512LD;
+ hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
+ } else
+ switch (timeSlots) {
+ case NUMBER_TIME_SLOTS_1920:
+ hSbrEnvFrame->dmin = 4;
+ hSbrEnvFrame->dmax = 12;
+ hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
+ hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_1920;
+ break;
+ case NUMBER_TIME_SLOTS_2048:
+ hSbrEnvFrame->dmin = 4;
+ hSbrEnvFrame->dmax = 12;
+ hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
+ hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_2048;
+ break;
+ case NUMBER_TIME_SLOTS_1152:
+ hSbrEnvFrame->dmin = 2;
+ hSbrEnvFrame->dmax = 8;
+ hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
+ hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_1152;
+ break;
+ case NUMBER_TIME_SLOTS_2304:
+ hSbrEnvFrame->dmin = 4;
+ hSbrEnvFrame->dmax = 15;
+ hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
+ hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_2304;
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+}
+
+/*******************************************************************************
+ Functionname: fillFrameTran
+ *******************************************************************************
+
+ Description: Add mandatory borders, as described by the tuning vector
+ and the current transient position
+
+ Arguments:
+ modified:
+ v_bord - int pointer to v_bord vector
+ length_v_bord - length of v_bord vector
+ v_freq - int pointer to v_freq vector
+ length_v_freq - length of v_freq vector
+ bmin - int pointer to bmin (call by reference)
+ bmax - int pointer to bmax (call by reference)
+ not modified:
+ tran - position of transient
+ v_tuningSegm - int pointer to v_tuningSegm vector
+ v_tuningFreq - int pointer to v_tuningFreq vector
+
+ Return: none
+
+*******************************************************************************/
+static void fillFrameTran(
+ const int *v_tuningSegm, /*!< tuning: desired segment lengths */
+ const int *v_tuningFreq, /*!< tuning: desired frequency resolutions */
+ int tran, /*!< input : position of transient */
+ int *v_bord, /*!< memNew: borders */
+ int *length_v_bord, /*!< memNew: # borders */
+ int *v_freq, /*!< memNew: frequency resolutions */
+ int *length_v_freq, /*!< memNew: # frequency resolutions */
+ int *bmin, /*!< hlpNew: first mandatory border */
+ int *bmax /*!< hlpNew: last mandatory border */
+) {
+ int bord, i;
+
+ *length_v_bord = 0;
+ *length_v_freq = 0;
+
+ /* add attack env leading border (optional) */
+ if (v_tuningSegm[0]) {
+ /* v_bord = [(Ba)] start of attack env */
+ FDKsbrEnc_AddRight(v_bord, length_v_bord, (tran - v_tuningSegm[0]));
+
+ /* v_freq = [(Fa)] res of attack env */
+ FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[0]);
+ }
+
+ /* add attack env trailing border/first decay env leading border */
+ bord = tran;
+ FDKsbrEnc_AddRight(v_bord, length_v_bord, tran); /* v_bord = [(Ba),Bd1] */
+
+ /* add first decay env trailing border/2:nd decay env leading border */
+ if (v_tuningSegm[1]) {
+ bord += v_tuningSegm[1];
+
+ /* v_bord = [(Ba),Bd1,Bd2] */
+ FDKsbrEnc_AddRight(v_bord, length_v_bord, bord);
+
+ /* v_freq = [(Fa),Fd1] */
+ FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[1]);
+ }
+
+ /* add 2:nd decay env trailing border (optional) */
+ if (v_tuningSegm[2] != 0) {
+ bord += v_tuningSegm[2];
+
+ /* v_bord = [(Ba),Bd1, Bd2,(Bd3)] */
+ FDKsbrEnc_AddRight(v_bord, length_v_bord, bord);
+
+ /* v_freq = [(Fa),Fd1,(Fd2)] */
+ FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[2]);
+ }
+
+ /* v_freq = [(Fa),Fd1,(Fd2),1] */
+ FDKsbrEnc_AddRight(v_freq, length_v_freq, 1);
+
+ /* calc min and max values of mandatory borders */
+ *bmin = v_bord[0];
+ for (i = 0; i < *length_v_bord; i++)
+ if (v_bord[i] < *bmin) *bmin = v_bord[i];
+
+ *bmax = v_bord[0];
+ for (i = 0; i < *length_v_bord; i++)
+ if (v_bord[i] > *bmax) *bmax = v_bord[i];
+}
+
+/*******************************************************************************
+ Functionname: fillFramePre
+ *******************************************************************************
+
+ Description: Add borders before mandatory borders, if needed
+
+ Arguments:
+ modified:
+ v_bord - int pointer to v_bord vector
+ length_v_bord - length of v_bord vector
+ v_freq - int pointer to v_freq vector
+ length_v_freq - length of v_freq vector
+ not modified:
+ dmax - int value
+ bmin - int value
+ rest - int value
+
+ Return: none
+
+*******************************************************************************/
+static void fillFramePre(INT dmax, INT *v_bord, INT *length_v_bord, INT *v_freq,
+ INT *length_v_freq, INT bmin, INT rest) {
+ /*
+ input state:
+ v_bord = [(Ba),Bd1, Bd2 ,(Bd3)]
+ v_freq = [(Fa),Fd1,(Fd2),1 ]
+ */
+
+ INT parts, d, j, S, s = 0, segm, bord;
+
+ /*
+ start with one envelope
+ */
+
+ parts = 1;
+ d = rest;
+
+ /*
+ calc # of additional envelopes and corresponding lengths
+ */
+
+ while (d > dmax) {
+ parts++;
+
+ segm = rest / parts;
+ S = (segm - 2) >> 1;
+ s = fixMin(8, 2 * S + 2);
+ d = rest - (parts - 1) * s;
+ }
+
+ /*
+ add borders before mandatory borders
+ */
+
+ bord = bmin;
+
+ for (j = 0; j <= parts - 2; j++) {
+ bord = bord - s;
+
+ /* v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3)] */
+ FDKsbrEnc_AddLeft(v_bord, length_v_bord, bord);
+
+ /* v_freq = [...,(1 ),(Fa),Fd1,(Fd2), 1 ] */
+ FDKsbrEnc_AddLeft(v_freq, length_v_freq, 1);
+ }
+}
+
+/***************************************************************************/
+/*!
+ \brief Overlap control
+
+ Calculate max length of trailing fill segments, such that we always get a
+ border within the frame overlap region
+
+ \return void
+
+****************************************************************************/
+static int calcFillLengthMax(
+ int tranPos, /*!< input : transient position (ref: tran det) */
+ int numberTimeSlots /*!< input : number of timeslots */
+) {
+ int fmax;
+
+ /*
+ calculate transient position within envelope buffer
+ */
+ switch (numberTimeSlots) {
+ case NUMBER_TIME_SLOTS_2048:
+ if (tranPos < 4)
+ fmax = 6;
+ else if (tranPos == 4 || tranPos == 5)
+ fmax = 4;
+ else
+ fmax = 8;
+ break;
+
+ case NUMBER_TIME_SLOTS_1920:
+ if (tranPos < 4)
+ fmax = 5;
+ else if (tranPos == 4 || tranPos == 5)
+ fmax = 3;
+ else
+ fmax = 7;
+ break;
+
+ default:
+ fmax = 8;
+ break;
+ }
+
+ return fmax;
+}
+
+/*******************************************************************************
+ Functionname: fillFramePost
+ *******************************************************************************
+
+ Description: -Add borders after mandatory borders, if needed
+ Make a preliminary design of next frame,
+ assuming no transient is present there
+
+ Arguments:
+ modified:
+ parts - int pointer to parts (call by reference)
+ d - int pointer to d (call by reference)
+ v_bord - int pointer to v_bord vector
+ length_v_bord - length of v_bord vector
+ v_freq - int pointer to v_freq vector
+ length_v_freq - length of v_freq vector
+ not modified:
+ bmax - int value
+ dmax - int value
+
+ Return: none
+
+*******************************************************************************/
+static void fillFramePost(INT *parts, INT *d, INT dmax, INT *v_bord,
+ INT *length_v_bord, INT *v_freq, INT *length_v_freq,
+ INT bmax, INT bufferFrameStart, INT numberTimeSlots,
+ INT fmax) {
+ INT j, rest, segm, S, s = 0, bord;
+
+ /*
+ input state:
+ v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3)]
+ v_freq = [...,(1 ),(Fa),Fd1,(Fd2),1 ]
+ */
+
+ rest = bufferFrameStart + 2 * numberTimeSlots - bmax;
+ *d = rest;
+
+ if (*d > 0) {
+ *parts = 1; /* start with one envelope */
+
+ /* calc # of additional envelopes and corresponding lengths */
+
+ while (*d > dmax) {
+ *parts = *parts + 1;
+
+ segm = rest / (*parts);
+ S = (segm - 2) >> 1;
+ s = fixMin(fmax, 2 * S + 2);
+ *d = rest - (*parts - 1) * s;
+ }
+
+ /* add borders after mandatory borders */
+
+ bord = bmax;
+ for (j = 0; j <= *parts - 2; j++) {
+ bord += s;
+
+ /* v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3),(Bf)] */
+ FDKsbrEnc_AddRight(v_bord, length_v_bord, bord);
+
+ /* v_freq = [...,(1 ),(Fa),Fd1,(Fd2), 1 , 1! ,1] */
+ FDKsbrEnc_AddRight(v_freq, length_v_freq, 1);
+ }
+ } else {
+ *parts = 1;
+
+ /* remove last element from v_bord and v_freq */
+
+ *length_v_bord = *length_v_bord - 1;
+ *length_v_freq = *length_v_freq - 1;
+ }
+}
+
+/*******************************************************************************
+ Functionname: fillFrameInter
+ *******************************************************************************
+
+ Description:
+
+ Arguments: nL -
+ v_tuningSegm -
+ v_bord -
+ length_v_bord -
+ bmin -
+ v_freq -
+ length_v_freq -
+ v_bordFollow -
+ length_v_bordFollow -
+ v_freqFollow -
+ length_v_freqFollow -
+ i_fillFollow -
+ dmin -
+ dmax -
+
+ Return: none
+
+*******************************************************************************/
+static void fillFrameInter(INT *nL, const int *v_tuningSegm, INT *v_bord,
+ INT *length_v_bord, INT bmin, INT *v_freq,
+ INT *length_v_freq, INT *v_bordFollow,
+ INT *length_v_bordFollow, INT *v_freqFollow,
+ INT *length_v_freqFollow, INT i_fillFollow, INT dmin,
+ INT dmax, INT numberTimeSlots) {
+ INT middle, b_new, numBordFollow, bordMaxFollow, i;
+
+ if (numberTimeSlots != NUMBER_TIME_SLOTS_1152) {
+ /* % remove fill borders: */
+ if (i_fillFollow >= 1) {
+ *length_v_bordFollow = i_fillFollow;
+ *length_v_freqFollow = i_fillFollow;
+ }
+
+ numBordFollow = *length_v_bordFollow;
+ bordMaxFollow = v_bordFollow[numBordFollow - 1];
+
+ /* remove even more borders if needed */
+ middle = bmin - bordMaxFollow;
+ while (middle < 0) {
+ numBordFollow--;
+ bordMaxFollow = v_bordFollow[numBordFollow - 1];
+ middle = bmin - bordMaxFollow;
+ }
+
+ *length_v_bordFollow = numBordFollow;
+ *length_v_freqFollow = numBordFollow;
+ *nL = numBordFollow - 1;
+
+ b_new = *length_v_bord;
+
+ if (middle <= dmax) {
+ if (middle >= dmin) { /* concatenate */
+ FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
+ *length_v_bordFollow);
+ FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
+ *length_v_freqFollow);
+ }
+
+ else {
+ if (v_tuningSegm[0] != 0) { /* remove one new border and concatenate */
+ *length_v_bord = b_new - 1;
+ FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
+ *length_v_bordFollow);
+
+ *length_v_freq = b_new - 1;
+ FDKsbrEnc_AddVecLeft(v_freq + 1, length_v_freq, v_freqFollow,
+ *length_v_freqFollow);
+ } else {
+ if (*length_v_bordFollow >
+ 1) { /* remove one old border and concatenate */
+ FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
+ *length_v_bordFollow - 1);
+ FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
+ *length_v_bordFollow - 1);
+
+ *nL = *nL - 1;
+ } else { /* remove new "transient" border and concatenate */
+
+ for (i = 0; i < *length_v_bord - 1; i++) v_bord[i] = v_bord[i + 1];
+
+ for (i = 0; i < *length_v_freq - 1; i++) v_freq[i] = v_freq[i + 1];
+
+ *length_v_bord = b_new - 1;
+ *length_v_freq = b_new - 1;
+
+ FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
+ *length_v_bordFollow);
+ FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
+ *length_v_freqFollow);
+ }
+ }
+ }
+ } else { /* middle > dmax */
+
+ fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin,
+ middle);
+ FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
+ *length_v_bordFollow);
+ FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
+ *length_v_freqFollow);
+ }
+
+ } else { /* numberTimeSlots==NUMBER_TIME_SLOTS_1152 */
+
+ INT l, m;
+
+ /*------------------------------------------------------------------------
+ remove fill borders
+ ------------------------------------------------------------------------*/
+ if (i_fillFollow >= 1) {
+ *length_v_bordFollow = i_fillFollow;
+ *length_v_freqFollow = i_fillFollow;
+ }
+
+ numBordFollow = *length_v_bordFollow;
+ bordMaxFollow = v_bordFollow[numBordFollow - 1];
+
+ /*------------------------------------------------------------------------
+ remove more borders if necessary to eliminate overlap
+ ------------------------------------------------------------------------*/
+
+ /* check for overlap */
+ middle = bmin - bordMaxFollow;
+
+ /* intervals:
+ i) middle < 0 : overlap, must remove borders
+ ii) 0 <= middle < dmin : no overlap but too tight, must remove
+ borders iii) dmin <= middle <= dmax : ok, just concatenate iv) dmax
+ <= middle : too wide, must add borders
+ */
+
+ /* first remove old non-fill-borders... */
+ while (middle < 0) {
+ /* ...but don't remove all of them */
+ if (numBordFollow == 1) break;
+
+ numBordFollow--;
+ bordMaxFollow = v_bordFollow[numBordFollow - 1];
+ middle = bmin - bordMaxFollow;
+ }
+
+ /* if this isn't enough, remove new non-fill borders */
+ if (middle < 0) {
+ for (l = 0, m = 0; l < *length_v_bord; l++) {
+ if (v_bord[l] > bordMaxFollow) {
+ v_bord[m] = v_bord[l];
+ v_freq[m] = v_freq[l];
+ m++;
+ }
+ }
+
+ *length_v_bord = l;
+ *length_v_freq = l;
+
+ bmin = v_bord[0];
+ }
+
+ /*------------------------------------------------------------------------
+ update modified follow-up data
+ ------------------------------------------------------------------------*/
+
+ *length_v_bordFollow = numBordFollow;
+ *length_v_freqFollow = numBordFollow;
+
+ /* left relative borders correspond to follow-up */
+ *nL = numBordFollow - 1;
+
+ /*------------------------------------------------------------------------
+ take care of intervals ii through iv
+ ------------------------------------------------------------------------*/
+
+ /* now middle should be >= 0 */
+ middle = bmin - bordMaxFollow;
+
+ if (middle <= dmin) /* (ii) */
+ {
+ b_new = *length_v_bord;
+
+ if (v_tuningSegm[0] != 0) {
+ /* remove new "luxury" border and concatenate */
+ *length_v_bord = b_new - 1;
+ FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
+ *length_v_bordFollow);
+
+ *length_v_freq = b_new - 1;
+ FDKsbrEnc_AddVecLeft(v_freq + 1, length_v_freq, v_freqFollow,
+ *length_v_freqFollow);
+
+ } else if (*length_v_bordFollow > 1) {
+ /* remove old border and concatenate */
+ FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
+ *length_v_bordFollow - 1);
+ FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
+ *length_v_bordFollow - 1);
+
+ *nL = *nL - 1;
+ } else {
+ /* remove new border and concatenate */
+ for (i = 0; i < *length_v_bord - 1; i++) v_bord[i] = v_bord[i + 1];
+
+ for (i = 0; i < *length_v_freq - 1; i++) v_freq[i] = v_freq[i + 1];
+
+ *length_v_bord = b_new - 1;
+ *length_v_freq = b_new - 1;
+
+ FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
+ *length_v_bordFollow);
+ FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
+ *length_v_freqFollow);
+ }
+ } else if ((middle >= dmin) && (middle <= dmax)) /* (iii) */
+ {
+ /* concatenate */
+ FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
+ *length_v_bordFollow);
+ FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
+ *length_v_freqFollow);
+
+ } else /* (iv) */
+ {
+ fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin,
+ middle);
+ FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow,
+ *length_v_bordFollow);
+ FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow,
+ *length_v_freqFollow);
+ }
+ }
+}
+
+/*******************************************************************************
+ Functionname: calcFrameClass
+ *******************************************************************************
+
+ Description:
+
+ Arguments: INT* frameClass, INT* frameClassOld, INT tranFlag, INT* spreadFlag)
+
+ Return: none
+
+*******************************************************************************/
+static void calcFrameClass(FRAME_CLASS *frameClass, FRAME_CLASS *frameClassOld,
+ INT tranFlag, INT *spreadFlag) {
+ switch (*frameClassOld) {
+ case FIXFIXonly:
+ case FIXFIX:
+ if (tranFlag)
+ *frameClass = FIXVAR;
+ else
+ *frameClass = FIXFIX;
+ break;
+ case FIXVAR:
+ if (tranFlag) {
+ *frameClass = VARVAR;
+ *spreadFlag = 0;
+ } else {
+ if (*spreadFlag)
+ *frameClass = VARVAR;
+ else
+ *frameClass = VARFIX;
+ }
+ break;
+ case VARFIX:
+ if (tranFlag)
+ *frameClass = FIXVAR;
+ else
+ *frameClass = FIXFIX;
+ break;
+ case VARVAR:
+ if (tranFlag) {
+ *frameClass = VARVAR;
+ *spreadFlag = 0;
+ } else {
+ if (*spreadFlag)
+ *frameClass = VARVAR;
+ else
+ *frameClass = VARFIX;
+ }
+ break;
+ };
+
+ *frameClassOld = *frameClass;
+}
+
+/*******************************************************************************
+ Functionname: specialCase
+ *******************************************************************************
+
+ Description:
+
+ Arguments: spreadFlag
+ allowSpread
+ v_bord
+ length_v_bord
+ v_freq
+ length_v_freq
+ parts
+ d
+
+ Return: none
+
+*******************************************************************************/
+static void specialCase(INT *spreadFlag, INT allowSpread, INT *v_bord,
+ INT *length_v_bord, INT *v_freq, INT *length_v_freq,
+ INT *parts, INT d) {
+ INT L;
+
+ L = *length_v_bord;
+
+ if (allowSpread) { /* add one "step 8" */
+ *spreadFlag = 1;
+ FDKsbrEnc_AddRight(v_bord, length_v_bord, v_bord[L - 1] + 8);
+ FDKsbrEnc_AddRight(v_freq, length_v_freq, 1);
+ (*parts)++;
+ } else {
+ if (d == 1) { /* stretch one slot */
+ *length_v_bord = L - 1;
+ *length_v_freq = L - 1;
+ } else {
+ if ((v_bord[L - 1] - v_bord[L - 2]) > 2) { /* compress one quant step */
+ v_bord[L - 1] = v_bord[L - 1] - 2;
+ v_freq[*length_v_freq - 1] = 0; /* use low res for short segment */
+ }
+ }
+ }
+}
+
+/*******************************************************************************
+ Functionname: calcCmonBorder
+ *******************************************************************************
+
+ Description:
+
+ Arguments: i_cmon
+ i_tran
+ v_bord
+ length_v_bord
+ tran
+
+ Return: none
+
+*******************************************************************************/
+static void calcCmonBorder(INT *i_cmon, INT *i_tran, INT *v_bord,
+ INT *length_v_bord, INT tran, INT bufferFrameStart,
+ INT numberTimeSlots) { /* FH 00-06-26 */
+ INT i;
+
+ for (i = 0; i < *length_v_bord; i++)
+ if (v_bord[i] >= bufferFrameStart + numberTimeSlots) { /* FH 00-06-26 */
+ *i_cmon = i;
+ break;
+ }
+
+ /* keep track of transient: */
+ for (i = 0; i < *length_v_bord; i++)
+ if (v_bord[i] >= tran) {
+ *i_tran = i;
+ break;
+ } else
+ *i_tran = EMPTY;
+}
+
+/*******************************************************************************
+ Functionname: keepForFollowUp
+ *******************************************************************************
+
+ Description:
+
+ Arguments: v_bordFollow
+ length_v_bordFollow
+ v_freqFollow
+ length_v_freqFollow
+ i_tranFollow
+ i_fillFollow
+ v_bord
+ length_v_bord
+ v_freq
+ i_cmon
+ i_tran
+ parts)
+
+ Return: none
+
+*******************************************************************************/
+static void keepForFollowUp(INT *v_bordFollow, INT *length_v_bordFollow,
+ INT *v_freqFollow, INT *length_v_freqFollow,
+ INT *i_tranFollow, INT *i_fillFollow, INT *v_bord,
+ INT *length_v_bord, INT *v_freq, INT i_cmon,
+ INT i_tran, INT parts,
+ INT numberTimeSlots) { /* FH 00-06-26 */
+ INT L, i, j;
+
+ L = *length_v_bord;
+
+ (*length_v_bordFollow) = 0;
+ (*length_v_freqFollow) = 0;
+
+ for (j = 0, i = i_cmon; i < L; i++, j++) {
+ v_bordFollow[j] = v_bord[i] - numberTimeSlots; /* FH 00-06-26 */
+ v_freqFollow[j] = v_freq[i];
+ (*length_v_bordFollow)++;
+ (*length_v_freqFollow)++;
+ }
+ if (i_tran != EMPTY)
+ *i_tranFollow = i_tran - i_cmon;
+ else
+ *i_tranFollow = EMPTY;
+ *i_fillFollow = L - (parts - 1) - i_cmon;
+}
+
+/*******************************************************************************
+ Functionname: calcCtrlSignal
+ *******************************************************************************
+
+ Description:
+
+ Arguments: hSbrGrid
+ frameClass
+ v_bord
+ length_v_bord
+ v_freq
+ length_v_freq
+ i_cmon
+ i_tran
+ spreadFlag
+ nL
+
+ Return: none
+
+*******************************************************************************/
+static void calcCtrlSignal(HANDLE_SBR_GRID hSbrGrid, FRAME_CLASS frameClass,
+ INT *v_bord, INT length_v_bord, INT *v_freq,
+ INT length_v_freq, INT i_cmon, INT i_tran,
+ INT spreadFlag, INT nL) {
+ INT i, r, a, n, p, b, aL, aR, ntot, nmax, nR;
+
+ INT *v_f = hSbrGrid->v_f;
+ INT *v_fLR = hSbrGrid->v_fLR;
+ INT *v_r = hSbrGrid->bs_rel_bord;
+ INT *v_rL = hSbrGrid->bs_rel_bord_0;
+ INT *v_rR = hSbrGrid->bs_rel_bord_1;
+
+ INT length_v_r = 0;
+ INT length_v_rR = 0;
+ INT length_v_rL = 0;
+
+ switch (frameClass) {
+ case FIXVAR:
+ /* absolute border: */
+
+ a = v_bord[i_cmon];
+
+ /* relative borders: */
+ length_v_r = 0;
+ i = i_cmon;
+
+ while (i >= 1) {
+ r = v_bord[i] - v_bord[i - 1];
+ FDKsbrEnc_AddRight(v_r, &length_v_r, r);
+ i--;
+ }
+
+ /* number of relative borders: */
+ n = length_v_r;
+
+ /* freq res: */
+ for (i = 0; i < i_cmon; i++) v_f[i] = v_freq[i_cmon - 1 - i];
+ v_f[i_cmon] = 1;
+
+ /* pointer: */
+ p = (i_cmon >= i_tran && i_tran != EMPTY) ? (i_cmon - i_tran + 1) : (0);
+
+ hSbrGrid->frameClass = frameClass;
+ hSbrGrid->bs_abs_bord = a;
+ hSbrGrid->n = n;
+ hSbrGrid->p = p;
+
+ break;
+ case VARFIX:
+ /* absolute border: */
+ a = v_bord[0];
+
+ /* relative borders: */
+ length_v_r = 0;
+
+ for (i = 1; i < length_v_bord; i++) {
+ r = v_bord[i] - v_bord[i - 1];
+ FDKsbrEnc_AddRight(v_r, &length_v_r, r);
+ }
+
+ /* number of relative borders: */
+ n = length_v_r;
+
+ /* freq res: */
+ FDKmemcpy(v_f, v_freq, length_v_freq * sizeof(INT));
+
+ /* pointer: */
+ p = (i_tran >= 0 && i_tran != EMPTY) ? (i_tran + 1) : (0);
+
+ hSbrGrid->frameClass = frameClass;
+ hSbrGrid->bs_abs_bord = a;
+ hSbrGrid->n = n;
+ hSbrGrid->p = p;
+
+ break;
+ case VARVAR:
+ if (spreadFlag) {
+ /* absolute borders: */
+ b = length_v_bord;
+
+ aL = v_bord[0];
+ aR = v_bord[b - 1];
+
+ /* number of relative borders: */
+ ntot = b - 2;
+
+ nmax = 2; /* n: {0,1,2} */
+ if (ntot > nmax) {
+ nL = nmax;
+ nR = ntot - nmax;
+ } else {
+ nL = ntot;
+ nR = 0;
+ }
+
+ /* relative borders: */
+ length_v_rL = 0;
+ for (i = 1; i <= nL; i++) {
+ r = v_bord[i] - v_bord[i - 1];
+ FDKsbrEnc_AddRight(v_rL, &length_v_rL, r);
+ }
+
+ length_v_rR = 0;
+ i = b - 1;
+ while (i >= b - nR) {
+ r = v_bord[i] - v_bord[i - 1];
+ FDKsbrEnc_AddRight(v_rR, &length_v_rR, r);
+ i--;
+ }
+
+ /* pointer (only one due to constraint in frame info): */
+ p = (i_tran > 0 && i_tran != EMPTY) ? (b - i_tran) : (0);
+
+ /* freq res: */
+
+ for (i = 0; i < b - 1; i++) v_fLR[i] = v_freq[i];
+ } else {
+ length_v_bord = i_cmon + 1;
+
+ /* absolute borders: */
+ b = length_v_bord;
+
+ aL = v_bord[0];
+ aR = v_bord[b - 1];
+
+ /* number of relative borders: */
+ ntot = b - 2;
+ nR = ntot - nL;
+
+ /* relative borders: */
+ length_v_rL = 0;
+ for (i = 1; i <= nL; i++) {
+ r = v_bord[i] - v_bord[i - 1];
+ FDKsbrEnc_AddRight(v_rL, &length_v_rL, r);
+ }
+
+ length_v_rR = 0;
+ i = b - 1;
+ while (i >= b - nR) {
+ r = v_bord[i] - v_bord[i - 1];
+ FDKsbrEnc_AddRight(v_rR, &length_v_rR, r);
+ i--;
+ }
+
+ /* pointer (only one due to constraint in frame info): */
+ p = (i_cmon >= i_tran && i_tran != EMPTY) ? (i_cmon - i_tran + 1) : (0);
+
+ /* freq res: */
+ for (i = 0; i < b - 1; i++) v_fLR[i] = v_freq[i];
+ }
+
+ hSbrGrid->frameClass = frameClass;
+ hSbrGrid->bs_abs_bord_0 = aL;
+ hSbrGrid->bs_abs_bord_1 = aR;
+ hSbrGrid->bs_num_rel_0 = nL;
+ hSbrGrid->bs_num_rel_1 = nR;
+ hSbrGrid->p = p;
+
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+}
+
+/*******************************************************************************
+ Functionname: createDefFrameInfo
+ *******************************************************************************
+
+ Description: Copies the default (static) frameInfo structs to the frameInfo
+ passed by reference; only used for FIXFIX frames
+
+ Arguments: hFrameInfo - HANLDE_SBR_FRAME_INFO
+ nEnv - INT
+ nTimeSlots - INT
+
+ Return: none; hSbrFrameInfo contains a copy of the default frameInfo
+
+ Written: Andreas Schneider
+ Revised:
+*******************************************************************************/
+static void createDefFrameInfo(HANDLE_SBR_FRAME_INFO hSbrFrameInfo, INT nEnv,
+ INT nTimeSlots) {
+ switch (nEnv) {
+ case 1:
+ switch (nTimeSlots) {
+ case NUMBER_TIME_SLOTS_1920:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo1_1920, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_2048:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo1_2048, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_1152:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo1_1152, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_2304:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo1_2304, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_512LD:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo1_512LD, sizeof(SBR_FRAME_INFO));
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+ break;
+ case 2:
+ switch (nTimeSlots) {
+ case NUMBER_TIME_SLOTS_1920:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo2_1920, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_2048:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo2_2048, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_1152:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo2_1152, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_2304:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo2_2304, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_512LD:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo2_512LD, sizeof(SBR_FRAME_INFO));
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+ break;
+ case 4:
+ switch (nTimeSlots) {
+ case NUMBER_TIME_SLOTS_1920:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo4_1920, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_2048:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo4_2048, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_1152:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo4_1152, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_2304:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo4_2304, sizeof(SBR_FRAME_INFO));
+ break;
+ case NUMBER_TIME_SLOTS_512LD:
+ FDKmemcpy(hSbrFrameInfo, &frameInfo4_512LD, sizeof(SBR_FRAME_INFO));
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+}
+
+/*******************************************************************************
+ Functionname: ctrlSignal2FrameInfo
+ *******************************************************************************
+
+ 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
+ hSbrFrameInfo - destination
+ freq_res_fixfix - frequency resolution for FIXFIX frames
+
+ Return: void; hSbrFrameInfo contains the updated FRAME_INFO struct
+
+*******************************************************************************/
+static void ctrlSignal2FrameInfo(
+ HANDLE_SBR_GRID hSbrGrid, /* input : the grid handle */
+ 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 *v_r = hSbrGrid->bs_rel_bord;
+ INT *v_f = hSbrGrid->v_f;
+
+ FRAME_CLASS frameClass = hSbrGrid->frameClass;
+ INT bufferFrameStart = hSbrGrid->bufferFrameStart;
+ INT numberTimeSlots = hSbrGrid->numberTimeSlots;
+
+ switch (frameClass) {
+ case FIXFIX:
+ createDefFrameInfo(hSbrFrameInfo, hSbrGrid->bs_num_env, numberTimeSlots);
+
+ frameSplit = (hSbrFrameInfo->nEnvelopes > 1);
+ for (i = 0; i < hSbrFrameInfo->nEnvelopes; i++) {
+ hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i] =
+ freq_res_fixfix[frameSplit];
+ }
+ break;
+
+ case FIXVAR:
+ case VARFIX:
+ nEnv = hSbrGrid->n + 1; /* read n [SBR_NUM_BITS bits] */ /*? snd*/
+ FDK_ASSERT(nEnv <= MAX_ENVELOPES_FIXVAR_VARFIX);
+
+ hSbrFrameInfo->nEnvelopes = nEnv;
+
+ border = hSbrGrid->bs_abs_bord; /* read the absolute border */
+
+ if (nEnv == 1)
+ hSbrFrameInfo->nNoiseEnvelopes = 1;
+ else
+ hSbrFrameInfo->nNoiseEnvelopes = 2;
+
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ switch (frameClass) {
+ case FIXVAR:
+ hSbrFrameInfo->borders[0] =
+ bufferFrameStart; /* start-position of 1st envelope */
+
+ hSbrFrameInfo->borders[nEnv] = border;
+
+ for (k = 0, i = nEnv - 1; k < nEnv - 1; k++, i--) {
+ border -= v_r[k];
+ hSbrFrameInfo->borders[i] = border;
+ }
+
+ /* make either envelope nr. nEnv + 1 - p short; or don't shorten if p == 0
+ */
+ p = hSbrGrid->p;
+ if (p == 0) {
+ hSbrFrameInfo->shortEnv = 0;
+ } else {
+ hSbrFrameInfo->shortEnv = nEnv + 1 - p;
+ }
+
+ for (k = 0, i = nEnv - 1; k < nEnv; k++, i--) {
+ hSbrFrameInfo->freqRes[i] = (FREQ_RES)v_f[k];
+ }
+
+ /* if either there is no short envelope or the last envelope is short...
+ */
+ if (p == 0 || p == 1) {
+ hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
+ } else {
+ hSbrFrameInfo->bordersNoise[1] =
+ hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
+ }
+
+ break;
+
+ case VARFIX:
+ /* in this case 'border' indicates the start of the 1st envelope */
+ hSbrFrameInfo->borders[0] = border;
+
+ for (k = 0; k < nEnv - 1; k++) {
+ border += v_r[k];
+ hSbrFrameInfo->borders[k + 1] = border;
+ }
+
+ hSbrFrameInfo->borders[nEnv] = bufferFrameStart + numberTimeSlots;
+
+ p = hSbrGrid->p;
+ if (p == 0 || p == 1) {
+ hSbrFrameInfo->shortEnv = 0;
+ } else {
+ hSbrFrameInfo->shortEnv = p - 1;
+ }
+
+ for (k = 0; k < nEnv; k++) {
+ hSbrFrameInfo->freqRes[k] = (FREQ_RES)v_f[k];
+ }
+
+ switch (p) {
+ case 0:
+ hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[1];
+ break;
+ case 1:
+ hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
+ break;
+ default:
+ hSbrFrameInfo->bordersNoise[1] =
+ hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
+ break;
+ }
+ break;
+
+ case VARVAR:
+ nEnv = hSbrGrid->bs_num_rel_0 + hSbrGrid->bs_num_rel_1 + 1;
+ FDK_ASSERT(nEnv <= MAX_ENVELOPES_VARVAR); /* just to be sure */
+ hSbrFrameInfo->nEnvelopes = nEnv;
+
+ hSbrFrameInfo->borders[0] = border = hSbrGrid->bs_abs_bord_0;
+
+ for (k = 0, i = 1; k < hSbrGrid->bs_num_rel_0; k++, i++) {
+ border += hSbrGrid->bs_rel_bord_0[k];
+ hSbrFrameInfo->borders[i] = border;
+ }
+
+ border = hSbrGrid->bs_abs_bord_1;
+ hSbrFrameInfo->borders[nEnv] = border;
+
+ for (k = 0, i = nEnv - 1; k < hSbrGrid->bs_num_rel_1; k++, i--) {
+ border -= hSbrGrid->bs_rel_bord_1[k];
+ hSbrFrameInfo->borders[i] = border;
+ }
+
+ p = hSbrGrid->p;
+ if (p == 0) {
+ hSbrFrameInfo->shortEnv = 0;
+ } else {
+ hSbrFrameInfo->shortEnv = nEnv + 1 - p;
+ }
+
+ for (k = 0; k < nEnv; k++) {
+ hSbrFrameInfo->freqRes[k] = (FREQ_RES)hSbrGrid->v_fLR[k];
+ }
+
+ if (nEnv == 1) {
+ hSbrFrameInfo->nNoiseEnvelopes = 1;
+ hSbrFrameInfo->bordersNoise[0] = hSbrGrid->bs_abs_bord_0;
+ hSbrFrameInfo->bordersNoise[1] = hSbrGrid->bs_abs_bord_1;
+ } else {
+ hSbrFrameInfo->nNoiseEnvelopes = 2;
+ hSbrFrameInfo->bordersNoise[0] = hSbrGrid->bs_abs_bord_0;
+
+ if (p == 0 || p == 1) {
+ hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1];
+ } else {
+ hSbrFrameInfo->bordersNoise[1] =
+ hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv];
+ }
+ hSbrFrameInfo->bordersNoise[2] = hSbrGrid->bs_abs_bord_1;
+ }
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ if (frameClass == VARFIX || frameClass == FIXVAR) {
+ hSbrFrameInfo->bordersNoise[0] = hSbrFrameInfo->borders[0];
+ if (nEnv == 1) {
+ hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv];
+ } else {
+ hSbrFrameInfo->bordersNoise[2] = hSbrFrameInfo->borders[nEnv];
+ }
+ }
+}
diff --git a/fdk-aac/libSBRenc/src/fram_gen.h b/fdk-aac/libSBRenc/src/fram_gen.h
new file mode 100644
index 0000000..0c5edc3
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/fram_gen.h
@@ -0,0 +1,343 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Framing generator prototypes and structs $Revision: 92790 $
+*/
+#ifndef 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_encoder.h" /* for FREQ_RES */
+
+#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_NUM_REL \
+ 3 /*!< maximum number of relative borders in any VAR frame */
+
+/* SBR frame class definitions */
+typedef enum {
+ FIXFIX =
+ 0, /*!< bs_frame_class: leading and trailing frame borders are fixed */
+ FIXVAR, /*!< bs_frame_class: leading frame border is fixed, trailing frame
+ border is variable */
+ VARFIX, /*!< bs_frame_class: leading frame border is variable, trailing frame
+ border is fixed */
+ VARVAR /*!< bs_frame_class: leading and trailing frame borders are variable */
+ ,
+ FIXFIXonly /*!< bs_frame_class: leading border fixed (0), trailing border
+ fixed (nrTimeSlots) and encased borders are dynamically derived
+ from the tranPos */
+} FRAME_CLASS;
+
+/* helper constants */
+#define DC 4711 /*!< helper constant: don't care */
+#define EMPTY (-99) /*!< helper constant: empty */
+
+/* system constants: AAC+SBR, DRM Frame-Length */
+#define FRAME_MIDDLE_SLOT_1920 4
+#define NUMBER_TIME_SLOTS_1920 15
+
+#define LD_PRETRAN_OFF 3
+#define FRAME_MIDDLE_SLOT_512LD 4
+#define NUMBER_TIME_SLOTS_512LD 8
+#define TRANSIENT_OFFSET_LD 0
+
+/*
+system constants: AAC+SBR or aacPRO (hybrid format), Standard Frame-Length,
+Multi-Rate
+---------------------------------------------------------------------------
+Number of slots (numberTimeSlots): 16 (NUMBER_TIME_SLOTS_2048)
+Detector-offset (frameMiddleSlot): 4
+Overlap : 3
+Buffer-offset : 8 (BUFFER_FRAME_START_2048 = 0)
+
+
+ |<------------tranPos---------->|
+ |c|d|e|f|0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|
+ FixFix | |
+ FixVar | :<- ->:
+ VarFix :<- ->: |
+ VarVar :<- ->: :<- ->:
+ 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3
+................................................................................
+
+|-|-|-|-|-|-|-|-B-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-B-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
+
+frame-generator:0 16 24 32
+analysis-buffer:8 24 32 40
+*/
+#define FRAME_MIDDLE_SLOT_2048 4
+#define NUMBER_TIME_SLOTS_2048 16
+
+/*
+system constants: mp3PRO, Multi-Rate & Single-Rate
+--------------------------------------------------
+Number of slots (numberTimeSlots): 9 (NUMBER_TIME_SLOTS_1152)
+Detector-offset (frameMiddleSlot): 4 (FRAME_MIDDLE_SLOT_1152)
+Overlap : 3
+Buffer-offset : 4.5 (BUFFER_FRAME_START_1152 = 0)
+
+
+ |<----tranPos---->|
+ |5|6|7|8|0|1|2|3|4|5|6|7|8|
+ FixFix | |
+ FixVar | :<- ->:
+ VarFix :<- ->: |
+ VarVar :<- ->: :<- ->:
+ 0 1 2 3 4 5 6 7 8 0 1 2 3
+ .............................................
+
+ -|-|-|-|-B-|-|-|-|-|-|-|-|-B-|-|-|-|-|-|-|-|-|
+
+frame-generator: 0 9 13 18
+analysis-buffer: 4.5 13.5 22.5
+*/
+#define FRAME_MIDDLE_SLOT_1152 4
+#define NUMBER_TIME_SLOTS_1152 9
+
+/* system constants: Layer2+SBR */
+#define FRAME_MIDDLE_SLOT_2304 8
+#define NUMBER_TIME_SLOTS_2304 18
+
+/*!
+ \struct SBR_GRID
+ \brief sbr_grid() signals to be converted to bitstream elements
+
+ The variables hold the signals (e.g. lengths and numbers) in "clear text"
+*/
+
+typedef struct {
+ /* system constants */
+ INT bufferFrameStart; /*!< frame generator vs analysis buffer time alignment
+ (currently set to 0, offset added elsewhere) */
+ INT numberTimeSlots; /*!< number of SBR timeslots per frame */
+
+ /* will be adjusted for every frame */
+ FRAME_CLASS frameClass; /*!< SBR frame class */
+ INT bs_num_env; /*!< bs_num_env, number of envelopes for FIXFIX */
+ INT bs_abs_bord; /*!< bs_abs_bord, absolute border for VARFIX and FIXVAR */
+ INT n; /*!< number of relative borders for VARFIX and FIXVAR */
+ INT p; /*!< pointer-to-transient-border */
+ INT bs_rel_bord[MAX_NUM_REL]; /*!< bs_rel_bord, relative borders for all VAR
+ */
+ INT v_f[MAX_ENVELOPES_FIXVAR_VARFIX]; /*!< envelope frequency resolutions for
+ FIXVAR and VARFIX */
+
+ INT bs_abs_bord_0; /*!< bs_abs_bord_0, leading absolute border for VARVAR */
+ INT bs_abs_bord_1; /*!< bs_abs_bord_1, trailing absolute border for VARVAR */
+ INT bs_num_rel_0; /*!< bs_num_rel_0, number of relative borders associated
+ with leading absolute border for VARVAR */
+ INT bs_num_rel_1; /*!< bs_num_rel_1, number of relative borders associated
+ with trailing absolute border for VARVAR */
+ INT bs_rel_bord_0[MAX_NUM_REL]; /*!< bs_rel_bord_0, relative borders
+ associated with leading absolute border
+ for VARVAR */
+ INT bs_rel_bord_1[MAX_NUM_REL]; /*!< bs_rel_bord_1, relative borders
+ associated with trailing absolute border
+ for VARVAR */
+ INT v_fLR[MAX_ENVELOPES_VARVAR]; /*!< envelope frequency resolutions for
+ VARVAR */
+
+} SBR_GRID;
+typedef SBR_GRID *HANDLE_SBR_GRID;
+
+/*!
+ \struct SBR_FRAME_INFO
+ \brief time/frequency grid description for one frame
+*/
+typedef struct {
+ INT nEnvelopes; /*!< number of envelopes */
+ INT borders[MAX_ENVELOPES + 1]; /*!< envelope borders in SBR timeslots */
+ FREQ_RES freqRes[MAX_ENVELOPES]; /*!< frequency resolution of each envelope */
+ INT shortEnv; /*!< number of an envelope to be shortened (starting at 1) or 0
+ for no shortened envelope */
+ INT nNoiseEnvelopes; /*!< number of noise floors */
+ INT bordersNoise[MAX_NOISE_ENVELOPES +
+ 1]; /*!< noise floor borders in SBR timeslots */
+} SBR_FRAME_INFO;
+/* WARNING: When rearranging the elements of this struct keep in mind that the
+ * static initializations in the corresponding C-file have to be rearranged as
+ * well! snd 2002/01/23
+ */
+typedef SBR_FRAME_INFO *HANDLE_SBR_FRAME_INFO;
+
+/*!
+ \struct SBR_ENVELOPE_FRAME
+ \brief frame generator main struct
+
+ Contains tuning parameters, time/frequency grid description, sbr_grid()
+ bitstream elements, and generator internal signals
+*/
+typedef struct {
+ /* system constants */
+ INT frameMiddleSlot; /*!< transient detector offset in SBR timeslots */
+
+ /* basic tuning parameters */
+ 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 */
+ 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 */
+ const int *v_tuningSegm; /*!< segment lengths to use around transient */
+ const int *v_tuningFreq; /*!< frequency resolutions to use around transient */
+ INT dmin; /*!< minimum length of dependent segments */
+ INT dmax; /*!< maximum length of dependent segments */
+ INT allowSpread; /*!< 1: allow isolated transient to influence grid of 3
+ consecutive frames */
+
+ /* internally used signals */
+ FRAME_CLASS frameClassOld; /*!< frame class used for previous frame */
+ INT spreadFlag; /*!< 1: use VARVAR instead of VARFIX to follow up old
+ transient */
+
+ INT v_bord[2 * MAX_ENVELOPES_VARVAR + 1]; /*!< borders for current frame and
+ preliminary borders for next
+ frame (fixed borders excluded) */
+ INT length_v_bord; /*!< helper variable: length of v_bord */
+ INT v_freq[2 * MAX_ENVELOPES_VARVAR + 1]; /*!< frequency resolutions for
+ current frame and preliminary
+ resolutions for next frame */
+ INT length_v_freq; /*!< helper variable: length of v_freq */
+
+ INT v_bordFollow[MAX_ENVELOPES_VARVAR]; /*!< preliminary borders for current
+ frame (calculated during previous
+ frame) */
+ INT length_v_bordFollow; /*!< helper variable: length of v_bordFollow */
+ INT i_tranFollow; /*!< points to transient border in v_bordFollow (may be
+ negative, see keepForFollowUp()) */
+ INT i_fillFollow; /*!< points to first fill border in v_bordFollow */
+ INT v_freqFollow[MAX_ENVELOPES_VARVAR]; /*!< preliminary frequency resolutions
+ for current frame (calculated
+ during previous frame) */
+ INT length_v_freqFollow; /*!< helper variable: length of v_freqFollow */
+
+ /* externally needed signals */
+ SBR_GRID
+ SbrGrid; /*!< sbr_grid() signals to be converted to bitstream elements */
+ SBR_FRAME_INFO
+ SbrFrameInfo; /*!< time/frequency grid description for one frame */
+} SBR_ENVELOPE_FRAME;
+typedef SBR_ENVELOPE_FRAME *HANDLE_SBR_ENVELOPE_FRAME;
+
+void FDKsbrEnc_initFrameInfoGenerator(HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
+ INT allowSpread, INT numEnvStatic,
+ INT staticFraming, INT timeSlots,
+ const FREQ_RES *freq_res_fixfix,
+ UCHAR fResTransIsLow, INT ldGrid);
+
+HANDLE_SBR_FRAME_INFO
+FDKsbrEnc_frameInfoGenerator(HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
+ UCHAR *v_transient_info, const INT rightBorderFIX,
+ UCHAR *v_transient_info_pre, int ldGrid,
+ const int *v_tuning);
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/invf_est.cpp b/fdk-aac/libSBRenc/src/invf_est.cpp
new file mode 100644
index 0000000..53b47ac
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/invf_est.cpp
@@ -0,0 +1,610 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "invf_est.h"
+#include "sbr_misc.h"
+
+#include "genericStds.h"
+
+#define MAX_NUM_REGIONS 10
+#define SCALE_FAC_QUO 512.0f
+#define SCALE_FAC_NRG 256.0f
+
+#ifndef min
+#define min(a, b) (a < b ? a : b)
+#endif
+
+#ifndef max
+#define max(a, b) (a > b ? a : b)
+#endif
+
+static const FIXP_DBL quantStepsSbr[4] = {
+ 0x00400000, 0x02800000, 0x03800000,
+ 0x04c00000}; /* table scaled with SCALE_FAC_QUO */
+static const FIXP_DBL quantStepsOrig[4] = {
+ 0x00000000, 0x00c00000, 0x01c00000,
+ 0x02800000}; /* table scaled with SCALE_FAC_QUO */
+static const FIXP_DBL nrgBorders[4] = {
+ 0x0c800000, 0x0f000000, 0x11800000,
+ 0x14000000}; /* table scaled with SCALE_FAC_NRG */
+
+static const DETECTOR_PARAMETERS detectorParamsAAC = {
+ quantStepsSbr,
+ quantStepsOrig,
+ nrgBorders,
+ 4, /* Number of borders SBR. */
+ 4, /* Number of borders orig. */
+ 4, /* Number of borders Nrg. */
+ {
+ /* Region space. */
+ {INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF,
+ INVF_OFF}, /* regionSbr */
+ {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF,
+ INVF_OFF} /* | */
+ }, /*------------------------ regionOrig ---------------------------------*/
+ {
+ /* Region space transient. */
+ {INVF_LOW_LEVEL, INVF_LOW_LEVEL, INVF_LOW_LEVEL, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_LOW_LEVEL, INVF_LOW_LEVEL, INVF_LOW_LEVEL, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_OFF,
+ INVF_OFF}, /* regionSbr */
+ {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF,
+ INVF_OFF} /* | */
+ }, /*------------------------ regionOrig ---------------------------------*/
+ {-4, -3, -2, -1,
+ 0} /* Reduction factor of the inverse filtering for low energies.*/
+};
+
+static const FIXP_DBL hysteresis =
+ 0x00400000; /* Delta value for hysteresis. scaled with SCALE_FAC_QUO */
+
+/*
+ * AAC+SBR PARAMETERS for Speech
+ *********************************/
+static const DETECTOR_PARAMETERS detectorParamsAACSpeech = {
+ quantStepsSbr,
+ quantStepsOrig,
+ nrgBorders,
+ 4, /* Number of borders SBR. */
+ 4, /* Number of borders orig. */
+ 4, /* Number of borders Nrg. */
+ {
+ /* Region space. */
+ {INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_OFF,
+ INVF_OFF}, /* regionSbr */
+ {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF,
+ INVF_OFF} /* | */
+ }, /*------------------------ regionOrig ---------------------------------*/
+ {
+ /* Region space transient. */
+ {INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_OFF,
+ INVF_OFF}, /* regionSbr */
+ {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF,
+ INVF_OFF}, /* | */
+ {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF,
+ INVF_OFF} /* | */
+ }, /*------------------------ regionOrig ---------------------------------*/
+ {-4, -3, -2, -1,
+ 0} /* Reduction factor of the inverse filtering for low energies.*/
+};
+
+/*
+ * Smoothing filters.
+ ************************/
+typedef const FIXP_DBL FIR_FILTER[5];
+
+static const FIR_FILTER fir_0 = {0x7fffffff, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000};
+static const FIR_FILTER fir_1 = {0x2aaaaa80, 0x555554ff, 0x00000000, 0x00000000,
+ 0x00000000};
+static const FIR_FILTER fir_2 = {0x10000000, 0x30000000, 0x40000000, 0x00000000,
+ 0x00000000};
+static const FIR_FILTER fir_3 = {0x077f80e8, 0x199999a0, 0x2bb3b240, 0x33333340,
+ 0x00000000};
+static const FIR_FILTER fir_4 = {0x04130598, 0x0ebdb000, 0x1becfa60, 0x2697a4c0,
+ 0x2aaaaa80};
+
+static const FIR_FILTER *const fir_table[5] = {&fir_0, &fir_1, &fir_2, &fir_3,
+ &fir_4};
+
+/**************************************************************************/
+/*!
+ \brief Calculates the values used for the detector.
+
+
+ \return none
+
+*/
+/**************************************************************************/
+static void calculateDetectorValues(
+ FIXP_DBL **quotaMatrixOrig, /*!< Matrix holding the tonality values of the
+ original. */
+ SCHAR *indexVector, /*!< Index vector to obtain the patched data. */
+ FIXP_DBL *nrgVector, /*!< Energy vector. */
+ DETECTOR_VALUES *detectorValues, /*!< pointer to DETECTOR_VALUES struct. */
+ INT startChannel, /*!< Start channel. */
+ INT stopChannel, /*!< Stop channel. */
+ INT startIndex, /*!< Start index. */
+ INT stopIndex, /*!< Stop index. */
+ INT numberOfStrongest /*!< The number of sorted tonal components to be
+ considered. */
+) {
+ INT i, temp, j;
+
+ const FIXP_DBL *filter = *fir_table[INVF_SMOOTHING_LENGTH];
+ FIXP_DBL origQuotaMeanStrongest, sbrQuotaMeanStrongest;
+ FIXP_DBL origQuota, sbrQuota;
+ FIXP_DBL invIndex, invChannel, invTemp;
+ FIXP_DBL quotaVecOrig[64], quotaVecSbr[64];
+
+ FDKmemclear(quotaVecOrig, 64 * sizeof(FIXP_DBL));
+ FDKmemclear(quotaVecSbr, 64 * sizeof(FIXP_DBL));
+
+ invIndex = GetInvInt(stopIndex - startIndex);
+ invChannel = GetInvInt(stopChannel - startChannel);
+
+ /*
+ Calculate the mean value, over the current time segment, for the original,
+ the HFR and the difference, over all channels in the current frequency range.
+ NOTE: the averaging is done on the values quota/(1 - quota + RELAXATION).
+ */
+
+ /* The original, the sbr signal and the total energy */
+ detectorValues->avgNrg = FL2FXCONST_DBL(0.0f);
+ for (j = startIndex; j < stopIndex; j++) {
+ for (i = startChannel; i < stopChannel; i++) {
+ quotaVecOrig[i] += fMult(quotaMatrixOrig[j][i], invIndex);
+
+ if (indexVector[i] != -1)
+ quotaVecSbr[i] += fMult(quotaMatrixOrig[j][indexVector[i]], invIndex);
+ }
+ detectorValues->avgNrg += fMult(nrgVector[j], invIndex);
+ }
+
+ /*
+ Calculate the mean value, over the current frequency range, for the original,
+ the HFR and the difference. Also calculate the same mean values for the three
+ vectors, but only includeing the x strongest copmponents.
+ */
+
+ origQuota = FL2FXCONST_DBL(0.0f);
+ sbrQuota = FL2FXCONST_DBL(0.0f);
+ for (i = startChannel; i < stopChannel; i++) {
+ origQuota += fMultDiv2(quotaVecOrig[i], invChannel);
+ sbrQuota += fMultDiv2(quotaVecSbr[i], invChannel);
+ }
+
+ /*
+ Calculate the mean value for the x strongest components
+ */
+ FDKsbrEnc_Shellsort_fract(quotaVecOrig + startChannel,
+ stopChannel - startChannel);
+ FDKsbrEnc_Shellsort_fract(quotaVecSbr + startChannel,
+ stopChannel - startChannel);
+
+ origQuotaMeanStrongest = FL2FXCONST_DBL(0.0f);
+ sbrQuotaMeanStrongest = FL2FXCONST_DBL(0.0f);
+
+ temp = min(stopChannel - startChannel, numberOfStrongest);
+ invTemp = GetInvInt(temp);
+
+ for (i = 0; i < temp; i++) {
+ origQuotaMeanStrongest +=
+ fMultDiv2(quotaVecOrig[i + stopChannel - temp], invTemp);
+ sbrQuotaMeanStrongest +=
+ fMultDiv2(quotaVecSbr[i + stopChannel - temp], invTemp);
+ }
+
+ /*
+ The value for the strongest component
+ */
+ detectorValues->origQuotaMax = quotaVecOrig[stopChannel - 1];
+ detectorValues->sbrQuotaMax = quotaVecSbr[stopChannel - 1];
+
+ /*
+ Buffer values
+ */
+ FDKmemmove(detectorValues->origQuotaMean, detectorValues->origQuotaMean + 1,
+ INVF_SMOOTHING_LENGTH * sizeof(FIXP_DBL));
+ FDKmemmove(detectorValues->sbrQuotaMean, detectorValues->sbrQuotaMean + 1,
+ INVF_SMOOTHING_LENGTH * sizeof(FIXP_DBL));
+ FDKmemmove(detectorValues->origQuotaMeanStrongest,
+ detectorValues->origQuotaMeanStrongest + 1,
+ INVF_SMOOTHING_LENGTH * sizeof(FIXP_DBL));
+ FDKmemmove(detectorValues->sbrQuotaMeanStrongest,
+ detectorValues->sbrQuotaMeanStrongest + 1,
+ INVF_SMOOTHING_LENGTH * sizeof(FIXP_DBL));
+
+ detectorValues->origQuotaMean[INVF_SMOOTHING_LENGTH] = origQuota << 1;
+ detectorValues->sbrQuotaMean[INVF_SMOOTHING_LENGTH] = sbrQuota << 1;
+ detectorValues->origQuotaMeanStrongest[INVF_SMOOTHING_LENGTH] =
+ origQuotaMeanStrongest << 1;
+ detectorValues->sbrQuotaMeanStrongest[INVF_SMOOTHING_LENGTH] =
+ sbrQuotaMeanStrongest << 1;
+
+ /*
+ Filter values
+ */
+ detectorValues->origQuotaMeanFilt = FL2FXCONST_DBL(0.0f);
+ detectorValues->sbrQuotaMeanFilt = FL2FXCONST_DBL(0.0f);
+ detectorValues->origQuotaMeanStrongestFilt = FL2FXCONST_DBL(0.0f);
+ detectorValues->sbrQuotaMeanStrongestFilt = FL2FXCONST_DBL(0.0f);
+
+ for (i = 0; i < INVF_SMOOTHING_LENGTH + 1; i++) {
+ detectorValues->origQuotaMeanFilt +=
+ fMult(detectorValues->origQuotaMean[i], filter[i]);
+ detectorValues->sbrQuotaMeanFilt +=
+ fMult(detectorValues->sbrQuotaMean[i], filter[i]);
+ detectorValues->origQuotaMeanStrongestFilt +=
+ fMult(detectorValues->origQuotaMeanStrongest[i], filter[i]);
+ detectorValues->sbrQuotaMeanStrongestFilt +=
+ fMult(detectorValues->sbrQuotaMeanStrongest[i], filter[i]);
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief Returns the region in which the input value belongs.
+
+
+
+ \return region.
+
+*/
+/**************************************************************************/
+static INT findRegion(
+ FIXP_DBL currVal, /*!< The current value. */
+ const FIXP_DBL *borders, /*!< The border of the regions. */
+ const INT numBorders /*!< The number of borders. */
+) {
+ INT i;
+
+ if (currVal < borders[0]) {
+ return 0;
+ }
+
+ for (i = 1; i < numBorders; i++) {
+ if (currVal >= borders[i - 1] && currVal < borders[i]) {
+ return i;
+ }
+ }
+
+ if (currVal >= borders[numBorders - 1]) {
+ return numBorders;
+ }
+
+ return 0; /* We never get here, it's just to avoid compiler warnings.*/
+}
+
+/**************************************************************************/
+/*!
+ \brief Makes a clever decision based on the quota vector.
+
+
+ \return decision on which invf mode to use
+
+*/
+/**************************************************************************/
+static INVF_MODE decisionAlgorithm(
+ const DETECTOR_PARAMETERS
+ *detectorParams, /*!< Struct with the detector parameters. */
+ DETECTOR_VALUES *detectorValues, /*!< Struct with the detector values. */
+ INT transientFlag, /*!< Flag indicating if there is a transient present.*/
+ INT *prevRegionSbr, /*!< The previous region in which the Sbr value was. */
+ INT *prevRegionOrig /*!< The previous region in which the Orig value was. */
+) {
+ INT invFiltLevel, regionSbr, regionOrig, regionNrg;
+
+ /*
+ Current thresholds.
+ */
+ const INT numRegionsSbr = detectorParams->numRegionsSbr;
+ const INT numRegionsOrig = detectorParams->numRegionsOrig;
+ const INT numRegionsNrg = detectorParams->numRegionsNrg;
+
+ FIXP_DBL quantStepsSbrTmp[MAX_NUM_REGIONS];
+ FIXP_DBL quantStepsOrigTmp[MAX_NUM_REGIONS];
+
+ /*
+ Current detector values.
+ */
+ FIXP_DBL origQuotaMeanFilt;
+ FIXP_DBL sbrQuotaMeanFilt;
+ FIXP_DBL nrg;
+
+ /* 0.375 = 3.0 / 8.0; 0.31143075889 = log2(RELAXATION)/64.0; 0.625 =
+ * log(16)/64.0; 0.6875 = 44/64.0 */
+ origQuotaMeanFilt =
+ (fMultDiv2(FL2FXCONST_DBL(2.f * 0.375f),
+ (FIXP_DBL)(CalcLdData(max(detectorValues->origQuotaMeanFilt,
+ (FIXP_DBL)1)) +
+ FL2FXCONST_DBL(0.31143075889f))))
+ << 0; /* scaled by 1/2^9 */
+ sbrQuotaMeanFilt =
+ (fMultDiv2(FL2FXCONST_DBL(2.f * 0.375f),
+ (FIXP_DBL)(CalcLdData(max(detectorValues->sbrQuotaMeanFilt,
+ (FIXP_DBL)1)) +
+ FL2FXCONST_DBL(0.31143075889f))))
+ << 0; /* scaled by 1/2^9 */
+ /* If energy is zero then we will get different results for different word
+ * lengths. */
+ nrg =
+ (fMultDiv2(FL2FXCONST_DBL(2.f * 0.375f),
+ (FIXP_DBL)(CalcLdData(detectorValues->avgNrg + (FIXP_DBL)1) +
+ FL2FXCONST_DBL(0.0625f) + FL2FXCONST_DBL(0.6875f))))
+ << 0; /* scaled by 1/2^8; 2^44 -> qmf energy scale */
+
+ FDKmemcpy(quantStepsSbrTmp, detectorParams->quantStepsSbr,
+ numRegionsSbr * sizeof(FIXP_DBL));
+ FDKmemcpy(quantStepsOrigTmp, detectorParams->quantStepsOrig,
+ numRegionsOrig * sizeof(FIXP_DBL));
+
+ if (*prevRegionSbr < numRegionsSbr)
+ quantStepsSbrTmp[*prevRegionSbr] =
+ detectorParams->quantStepsSbr[*prevRegionSbr] + hysteresis;
+ if (*prevRegionSbr > 0)
+ quantStepsSbrTmp[*prevRegionSbr - 1] =
+ detectorParams->quantStepsSbr[*prevRegionSbr - 1] - hysteresis;
+
+ if (*prevRegionOrig < numRegionsOrig)
+ quantStepsOrigTmp[*prevRegionOrig] =
+ detectorParams->quantStepsOrig[*prevRegionOrig] + hysteresis;
+ if (*prevRegionOrig > 0)
+ quantStepsOrigTmp[*prevRegionOrig - 1] =
+ detectorParams->quantStepsOrig[*prevRegionOrig - 1] - hysteresis;
+
+ regionSbr = findRegion(sbrQuotaMeanFilt, quantStepsSbrTmp, numRegionsSbr);
+ regionOrig = findRegion(origQuotaMeanFilt, quantStepsOrigTmp, numRegionsOrig);
+ regionNrg = findRegion(nrg, detectorParams->nrgBorders, numRegionsNrg);
+
+ *prevRegionSbr = regionSbr;
+ *prevRegionOrig = regionOrig;
+
+ /* Use different settings if a transient is present*/
+ invFiltLevel =
+ (transientFlag == 1)
+ ? detectorParams->regionSpaceTransient[regionSbr][regionOrig]
+ : detectorParams->regionSpace[regionSbr][regionOrig];
+
+ /* Compensate for low energy.*/
+ invFiltLevel =
+ max(invFiltLevel + detectorParams->EnergyCompFactor[regionNrg], 0);
+
+ return (INVF_MODE)(invFiltLevel);
+}
+
+/**************************************************************************/
+/*!
+ \brief Estiamtion of the inverse filtering level required
+ in the decoder.
+
+ A second order LPC is calculated for every filterbank channel, using
+ the covariance method. THe ratio between the energy of the predicted
+ signal and the energy of the non-predictable signal is calcualted.
+
+ \return none.
+
+*/
+/**************************************************************************/
+void FDKsbrEnc_qmfInverseFilteringDetector(
+ HANDLE_SBR_INV_FILT_EST
+ hInvFilt, /*!< Handle to the SBR_INV_FILT_EST struct. */
+ FIXP_DBL **quotaMatrix, /*!< The matrix holding the tonality values of the
+ original. */
+ FIXP_DBL *nrgVector, /*!< The energy vector. */
+ SCHAR *indexVector, /*!< Index vector to obtain the patched data. */
+ INT startIndex, /*!< Start index. */
+ INT stopIndex, /*!< Stop index. */
+ INT transientFlag, /*!< Flag indicating if a transient is present or not.*/
+ INVF_MODE *infVec /*!< Vector holding the inverse filtering levels. */
+) {
+ INT band;
+
+ /*
+ * Do the inverse filtering level estimation.
+ *****************************************************/
+ for (band = 0; band < hInvFilt->noDetectorBands; band++) {
+ INT startChannel = hInvFilt->freqBandTableInvFilt[band];
+ INT stopChannel = hInvFilt->freqBandTableInvFilt[band + 1];
+
+ calculateDetectorValues(quotaMatrix, indexVector, nrgVector,
+ &hInvFilt->detectorValues[band], startChannel,
+ stopChannel, startIndex, stopIndex,
+ hInvFilt->numberOfStrongest);
+
+ infVec[band] = decisionAlgorithm(
+ hInvFilt->detectorParams, &hInvFilt->detectorValues[band],
+ transientFlag, &hInvFilt->prevRegionSbr[band],
+ &hInvFilt->prevRegionOrig[band]);
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief Initialize an instance of the inverse filtering level estimator.
+
+
+ \return errorCode, noError if successful.
+
+*/
+/**************************************************************************/
+INT FDKsbrEnc_initInvFiltDetector(
+ HANDLE_SBR_INV_FILT_EST
+ hInvFilt, /*!< Pointer to a handle to the SBR_INV_FILT_EST struct. */
+ INT *freqBandTableDetector, /*!< Frequency band table for the inverse
+ filtering. */
+ INT numDetectorBands, /*!< Number of inverse filtering bands. */
+ UINT
+ useSpeechConfig /*!< Flag: adapt tuning parameters according to speech*/
+) {
+ INT i;
+
+ FDKmemclear(hInvFilt, sizeof(SBR_INV_FILT_EST));
+
+ hInvFilt->detectorParams =
+ (useSpeechConfig) ? &detectorParamsAACSpeech : &detectorParamsAAC;
+
+ hInvFilt->noDetectorBandsMax = numDetectorBands;
+
+ /*
+ Memory initialisation
+ */
+ for (i = 0; i < hInvFilt->noDetectorBandsMax; i++) {
+ FDKmemclear(&hInvFilt->detectorValues[i], sizeof(DETECTOR_VALUES));
+ hInvFilt->prevInvfMode[i] = INVF_OFF;
+ hInvFilt->prevRegionOrig[i] = 0;
+ hInvFilt->prevRegionSbr[i] = 0;
+ }
+
+ /*
+ Reset the inverse fltering detector.
+ */
+ FDKsbrEnc_resetInvFiltDetector(hInvFilt, freqBandTableDetector,
+ hInvFilt->noDetectorBandsMax);
+
+ return (0);
+}
+
+/**************************************************************************/
+/*!
+ \brief resets sbr inverse filtering structure.
+
+
+
+ \return errorCode, noError if successful.
+
+*/
+/**************************************************************************/
+INT FDKsbrEnc_resetInvFiltDetector(
+ HANDLE_SBR_INV_FILT_EST
+ hInvFilt, /*!< Handle to the SBR_INV_FILT_EST struct. */
+ INT *freqBandTableDetector, /*!< Frequency band table for the inverse
+ filtering. */
+ INT numDetectorBands) /*!< Number of inverse filtering bands. */
+{
+ hInvFilt->numberOfStrongest = 1;
+ FDKmemcpy(hInvFilt->freqBandTableInvFilt, freqBandTableDetector,
+ (numDetectorBands + 1) * sizeof(INT));
+ hInvFilt->noDetectorBands = numDetectorBands;
+
+ return (0);
+}
diff --git a/fdk-aac/libSBRenc/src/invf_est.h b/fdk-aac/libSBRenc/src/invf_est.h
new file mode 100644
index 0000000..3ab6726
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/invf_est.h
@@ -0,0 +1,181 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Inverse Filtering detection prototypes $Revision: 92790 $
+*/
+#ifndef INVF_EST_H
+#define INVF_EST_H
+
+#include "sbr_encoder.h"
+#include "sbr_def.h"
+
+#define INVF_SMOOTHING_LENGTH 2
+
+typedef struct {
+ const FIXP_DBL *quantStepsSbr;
+ const FIXP_DBL *quantStepsOrig;
+ const FIXP_DBL *nrgBorders;
+ INT numRegionsSbr;
+ INT numRegionsOrig;
+ INT numRegionsNrg;
+ INVF_MODE regionSpace[5][5];
+ INVF_MODE regionSpaceTransient[5][5];
+ INT EnergyCompFactor[5];
+
+} DETECTOR_PARAMETERS;
+
+typedef struct {
+ FIXP_DBL origQuotaMean[INVF_SMOOTHING_LENGTH + 1];
+ FIXP_DBL sbrQuotaMean[INVF_SMOOTHING_LENGTH + 1];
+ FIXP_DBL origQuotaMeanStrongest[INVF_SMOOTHING_LENGTH + 1];
+ FIXP_DBL sbrQuotaMeanStrongest[INVF_SMOOTHING_LENGTH + 1];
+
+ FIXP_DBL origQuotaMeanFilt;
+ FIXP_DBL sbrQuotaMeanFilt;
+ FIXP_DBL origQuotaMeanStrongestFilt;
+ FIXP_DBL sbrQuotaMeanStrongestFilt;
+
+ FIXP_DBL origQuotaMax;
+ FIXP_DBL sbrQuotaMax;
+
+ FIXP_DBL avgNrg;
+} DETECTOR_VALUES;
+
+typedef struct {
+ INT numberOfStrongest;
+
+ INT prevRegionSbr[MAX_NUM_NOISE_VALUES];
+ INT prevRegionOrig[MAX_NUM_NOISE_VALUES];
+
+ INT freqBandTableInvFilt[MAX_NUM_NOISE_VALUES];
+ INT noDetectorBands;
+ INT noDetectorBandsMax;
+
+ const DETECTOR_PARAMETERS *detectorParams;
+
+ INVF_MODE prevInvfMode[MAX_NUM_NOISE_VALUES];
+ DETECTOR_VALUES detectorValues[MAX_NUM_NOISE_VALUES];
+
+ FIXP_DBL nrgAvg;
+ FIXP_DBL wmQmf[MAX_NUM_NOISE_VALUES];
+} SBR_INV_FILT_EST;
+
+typedef SBR_INV_FILT_EST *HANDLE_SBR_INV_FILT_EST;
+
+void FDKsbrEnc_qmfInverseFilteringDetector(HANDLE_SBR_INV_FILT_EST hInvFilt,
+ FIXP_DBL **quotaMatrix,
+ FIXP_DBL *nrgVector,
+ SCHAR *indexVector, INT startIndex,
+ INT stopIndex, INT transientFlag,
+ INVF_MODE *infVec);
+
+INT FDKsbrEnc_initInvFiltDetector(HANDLE_SBR_INV_FILT_EST hInvFilt,
+ INT *freqBandTableDetector,
+ INT numDetectorBands, UINT useSpeechConfig);
+
+INT FDKsbrEnc_resetInvFiltDetector(HANDLE_SBR_INV_FILT_EST hInvFilt,
+ INT *freqBandTableDetector,
+ INT numDetectorBands);
+
+#endif /* _QMF_INV_FILT_H */
diff --git a/fdk-aac/libSBRenc/src/mh_det.cpp b/fdk-aac/libSBRenc/src/mh_det.cpp
new file mode 100644
index 0000000..2f3b386
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/mh_det.cpp
@@ -0,0 +1,1396 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "mh_det.h"
+
+#include "sbrenc_ram.h"
+#include "sbr_misc.h"
+
+#include "genericStds.h"
+
+#define SFM_SHIFT 2 /* Attention: SFM_SCALE depends on SFM_SHIFT */
+#define SFM_SCALE (MAXVAL_DBL >> SFM_SHIFT) /* 1.0 >> SFM_SHIFT */
+
+/*!< Detector Parameters for AAC core codec. */
+static const DETECTOR_PARAMETERS_MH paramsAac = {
+ 9, /*!< deltaTime */
+ {
+ FL2FXCONST_DBL(20.0f * RELAXATION_FLOAT), /*!< thresHoldDiff */
+ FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< thresHoldDiffGuide */
+ FL2FXCONST_DBL(15.0f * RELAXATION_FLOAT), /*!< thresHoldTone */
+ FL2FXCONST_DBL((1.0f / 15.0f) *
+ RELAXATION_FLOAT), /*!< invThresHoldTone */
+ FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< thresHoldToneGuide */
+ FL2FXCONST_DBL(0.3f) >> SFM_SHIFT, /*!< sfmThresSbr */
+ FL2FXCONST_DBL(0.1f) >> SFM_SHIFT, /*!< sfmThresOrig */
+ FL2FXCONST_DBL(0.3f), /*!< decayGuideOrig */
+ FL2FXCONST_DBL(0.5f), /*!< decayGuideDiff */
+ FL2FXCONST_DBL(-0.000112993269),
+ /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresMaxLD64 */
+ FL2FXCONST_DBL(-0.000112993269),
+ /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresBelowLD64 */
+ FL2FXCONST_DBL(
+ -0.005030126483f) /* LD64(FL2FXCONST_DBL(0.8f)) */ /*!<
+ derivThresAboveLD64
+ */
+ },
+ 50 /*!< maxComp */
+};
+
+/*!< Detector Parameters for AAC LD core codec. */
+static const DETECTOR_PARAMETERS_MH paramsAacLd = {
+ 16, /*!< Delta time. */
+ {
+ FL2FXCONST_DBL(25.0f * RELAXATION_FLOAT), /*!< thresHoldDiff */
+ FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< tresHoldDiffGuide */
+ FL2FXCONST_DBL(15.0f * RELAXATION_FLOAT), /*!< thresHoldTone */
+ FL2FXCONST_DBL((1.0f / 15.0f) *
+ RELAXATION_FLOAT), /*!< invThresHoldTone */
+ FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< thresHoldToneGuide */
+ FL2FXCONST_DBL(0.3f) >> SFM_SHIFT, /*!< sfmThresSbr */
+ FL2FXCONST_DBL(0.1f) >> SFM_SHIFT, /*!< sfmThresOrig */
+ FL2FXCONST_DBL(0.3f), /*!< decayGuideOrig */
+ FL2FXCONST_DBL(0.2f), /*!< decayGuideDiff */
+ FL2FXCONST_DBL(-0.000112993269),
+ /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresMaxLD64 */
+ FL2FXCONST_DBL(-0.000112993269),
+ /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresBelowLD64 */
+ FL2FXCONST_DBL(
+ -0.005030126483f) /* LD64(FL2FXCONST_DBL(0.8f)) */ /*!<
+ derivThresAboveLD64
+ */
+ },
+ 50 /*!< maxComp */
+};
+
+/**************************************************************************/
+/*!
+ \brief Calculates the difference in tonality between original and SBR
+ for a given time and frequency region.
+
+ The values for pDiffMapped2Scfb are scaled by RELAXATION
+
+ \return none.
+
+*/
+/**************************************************************************/
+static void diff(FIXP_DBL *RESTRICT pTonalityOrig, FIXP_DBL *pDiffMapped2Scfb,
+ const UCHAR *RESTRICT pFreqBandTable, INT nScfb,
+ SCHAR *indexVector) {
+ UCHAR i, ll, lu, k;
+ FIXP_DBL maxValOrig, maxValSbr, tmp;
+ INT scale;
+
+ for (i = 0; i < nScfb; i++) {
+ ll = pFreqBandTable[i];
+ lu = pFreqBandTable[i + 1];
+
+ maxValOrig = FL2FXCONST_DBL(0.0f);
+ maxValSbr = FL2FXCONST_DBL(0.0f);
+
+ for (k = ll; k < lu; k++) {
+ maxValOrig = fixMax(maxValOrig, pTonalityOrig[k]);
+ maxValSbr = fixMax(maxValSbr, pTonalityOrig[indexVector[k]]);
+ }
+
+ if ((maxValSbr >= RELAXATION)) {
+ tmp = fDivNorm(maxValOrig, maxValSbr, &scale);
+ pDiffMapped2Scfb[i] =
+ scaleValue(fMult(tmp, RELAXATION_FRACT),
+ fixMax(-(DFRACT_BITS - 1), (scale - RELAXATION_SHIFT)));
+ } else {
+ pDiffMapped2Scfb[i] = maxValOrig;
+ }
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief Calculates a flatness measure of the tonality measures.
+
+ Calculation of the power function and using scalefactor for basis:
+ Using log2:
+ z = (2^k * x)^y;
+ z' = CalcLd(z) = y*CalcLd(x) + y*k;
+ z = CalcInvLd(z');
+
+ Using ld64:
+ z = (2^k * x)^y;
+ z' = CalcLd64(z) = y*CalcLd64(x)/64 + y*k/64;
+ z = CalcInvLd64(z');
+
+ The values pSfmOrigVec and pSfmSbrVec are scaled by the factor 1/4.0
+
+ \return none.
+
+*/
+/**************************************************************************/
+static void calculateFlatnessMeasure(FIXP_DBL *pQuotaBuffer, SCHAR *indexVector,
+ FIXP_DBL *pSfmOrigVec,
+ FIXP_DBL *pSfmSbrVec,
+ const UCHAR *pFreqBandTable, INT nSfb) {
+ INT i, j;
+ FIXP_DBL invBands, tmp1, tmp2;
+ INT shiftFac0, shiftFacSum0;
+ INT shiftFac1, shiftFacSum1;
+ FIXP_DBL accu;
+
+ for (i = 0; i < nSfb; i++) {
+ INT ll = pFreqBandTable[i];
+ INT lu = pFreqBandTable[i + 1];
+ pSfmOrigVec[i] = (FIXP_DBL)(MAXVAL_DBL >> 2);
+ pSfmSbrVec[i] = (FIXP_DBL)(MAXVAL_DBL >> 2);
+
+ if (lu - ll > 1) {
+ FIXP_DBL amOrig, amTransp, gmOrig, gmTransp, sfmOrig, sfmTransp;
+ invBands = GetInvInt(lu - ll);
+ shiftFacSum0 = 0;
+ shiftFacSum1 = 0;
+ amOrig = amTransp = FL2FXCONST_DBL(0.0f);
+ gmOrig = gmTransp = (FIXP_DBL)MAXVAL_DBL;
+
+ for (j = ll; j < lu; j++) {
+ sfmOrig = pQuotaBuffer[j];
+ sfmTransp = pQuotaBuffer[indexVector[j]];
+
+ amOrig += fMult(sfmOrig, invBands);
+ amTransp += fMult(sfmTransp, invBands);
+
+ shiftFac0 = CountLeadingBits(sfmOrig);
+ shiftFac1 = CountLeadingBits(sfmTransp);
+
+ gmOrig = fMult(gmOrig, sfmOrig << shiftFac0);
+ gmTransp = fMult(gmTransp, sfmTransp << shiftFac1);
+
+ shiftFacSum0 += shiftFac0;
+ shiftFacSum1 += shiftFac1;
+ }
+
+ if (gmOrig > FL2FXCONST_DBL(0.0f)) {
+ tmp1 = CalcLdData(gmOrig); /* CalcLd64(x)/64 */
+ tmp1 = fMult(invBands, tmp1); /* y*CalcLd64(x)/64 */
+
+ /* y*k/64 */
+ accu = (FIXP_DBL)-shiftFacSum0 << (DFRACT_BITS - 1 - 8);
+ tmp2 = fMultDiv2(invBands, accu) << (2 + 1);
+
+ tmp2 = tmp1 + tmp2; /* y*CalcLd64(x)/64 + y*k/64 */
+ gmOrig = CalcInvLdData(tmp2); /* CalcInvLd64(z'); */
+ } else {
+ gmOrig = FL2FXCONST_DBL(0.0f);
+ }
+
+ if (gmTransp > FL2FXCONST_DBL(0.0f)) {
+ tmp1 = CalcLdData(gmTransp); /* CalcLd64(x)/64 */
+ tmp1 = fMult(invBands, tmp1); /* y*CalcLd64(x)/64 */
+
+ /* y*k/64 */
+ accu = (FIXP_DBL)-shiftFacSum1 << (DFRACT_BITS - 1 - 8);
+ tmp2 = fMultDiv2(invBands, accu) << (2 + 1);
+
+ tmp2 = tmp1 + tmp2; /* y*CalcLd64(x)/64 + y*k/64 */
+ gmTransp = CalcInvLdData(tmp2); /* CalcInvLd64(z'); */
+ } else {
+ gmTransp = FL2FXCONST_DBL(0.0f);
+ }
+ if (amOrig != FL2FXCONST_DBL(0.0f))
+ pSfmOrigVec[i] =
+ FDKsbrEnc_LSI_divide_scale_fract(gmOrig, amOrig, SFM_SCALE);
+
+ if (amTransp != FL2FXCONST_DBL(0.0f))
+ pSfmSbrVec[i] =
+ FDKsbrEnc_LSI_divide_scale_fract(gmTransp, amTransp, SFM_SCALE);
+ }
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief Calculates the input to the missing harmonics detection.
+
+
+ \return none.
+
+*/
+/**************************************************************************/
+static void calculateDetectorInput(
+ FIXP_DBL **RESTRICT pQuotaBuffer, /*!< Pointer to tonality matrix. */
+ SCHAR *RESTRICT indexVector, FIXP_DBL **RESTRICT tonalityDiff,
+ FIXP_DBL **RESTRICT pSfmOrig, FIXP_DBL **RESTRICT pSfmSbr,
+ const UCHAR *freqBandTable, INT nSfb, INT noEstPerFrame, INT move) {
+ INT est;
+
+ /*
+ New estimate.
+ */
+ for (est = 0; est < noEstPerFrame; est++) {
+ diff(pQuotaBuffer[est + move], tonalityDiff[est + move], freqBandTable,
+ nSfb, indexVector);
+
+ calculateFlatnessMeasure(pQuotaBuffer[est + move], indexVector,
+ pSfmOrig[est + move], pSfmSbr[est + move],
+ freqBandTable, nSfb);
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief Checks that the detection is not due to a LP filter
+
+ This function determines if a newly detected missing harmonics is not
+ in fact just a low-pass filtere input signal. If so, the detection is
+ removed.
+
+ \return none.
+
+*/
+/**************************************************************************/
+static void removeLowPassDetection(UCHAR *RESTRICT pAddHarmSfb,
+ UCHAR **RESTRICT pDetectionVectors,
+ INT start, INT stop, INT nSfb,
+ const UCHAR *RESTRICT pFreqBandTable,
+ FIXP_DBL *RESTRICT pNrgVector,
+ THRES_HOLDS mhThresh)
+
+{
+ INT i, est;
+ INT maxDerivPos = pFreqBandTable[nSfb];
+ INT numBands = pFreqBandTable[nSfb];
+ FIXP_DBL nrgLow, nrgHigh;
+ FIXP_DBL nrgLD64, nrgLowLD64, nrgHighLD64, nrgDiffLD64;
+ FIXP_DBL valLD64, maxValLD64, maxValAboveLD64;
+ INT bLPsignal = 0;
+
+ maxValLD64 = FL2FXCONST_DBL(-1.0f);
+ for (i = numBands - 1 - 2; i > pFreqBandTable[0]; i--) {
+ nrgLow = pNrgVector[i];
+ nrgHigh = pNrgVector[i + 2];
+
+ if (nrgLow != FL2FXCONST_DBL(0.0f) && nrgLow > nrgHigh) {
+ nrgLowLD64 = CalcLdData(nrgLow >> 1);
+ nrgDiffLD64 = CalcLdData((nrgLow >> 1) - (nrgHigh >> 1));
+ valLD64 = nrgDiffLD64 - nrgLowLD64;
+ if (valLD64 > maxValLD64) {
+ maxDerivPos = i;
+ maxValLD64 = valLD64;
+ }
+ if (maxValLD64 > mhThresh.derivThresMaxLD64) {
+ break;
+ }
+ }
+ }
+
+ /* Find the largest "gradient" above. (should be relatively flat, hence we
+ expect a low value if the signal is LP.*/
+ maxValAboveLD64 = FL2FXCONST_DBL(-1.0f);
+ for (i = numBands - 1 - 2; i > maxDerivPos + 2; i--) {
+ nrgLow = pNrgVector[i];
+ nrgHigh = pNrgVector[i + 2];
+
+ if (nrgLow != FL2FXCONST_DBL(0.0f) && nrgLow > nrgHigh) {
+ nrgLowLD64 = CalcLdData(nrgLow >> 1);
+ nrgDiffLD64 = CalcLdData((nrgLow >> 1) - (nrgHigh >> 1));
+ valLD64 = nrgDiffLD64 - nrgLowLD64;
+ if (valLD64 > maxValAboveLD64) {
+ maxValAboveLD64 = valLD64;
+ }
+ } else {
+ if (nrgHigh != FL2FXCONST_DBL(0.0f) && nrgHigh > nrgLow) {
+ nrgHighLD64 = CalcLdData(nrgHigh >> 1);
+ nrgDiffLD64 = CalcLdData((nrgHigh >> 1) - (nrgLow >> 1));
+ valLD64 = nrgDiffLD64 - nrgHighLD64;
+ if (valLD64 > maxValAboveLD64) {
+ maxValAboveLD64 = valLD64;
+ }
+ }
+ }
+ }
+
+ if (maxValLD64 > mhThresh.derivThresMaxLD64 &&
+ maxValAboveLD64 < mhThresh.derivThresAboveLD64) {
+ bLPsignal = 1;
+
+ for (i = maxDerivPos - 1; i > maxDerivPos - 5 && i >= 0; i--) {
+ if (pNrgVector[i] != FL2FXCONST_DBL(0.0f) &&
+ pNrgVector[i] > pNrgVector[maxDerivPos + 2]) {
+ nrgDiffLD64 = CalcLdData((pNrgVector[i] >> 1) -
+ (pNrgVector[maxDerivPos + 2] >> 1));
+ nrgLD64 = CalcLdData(pNrgVector[i] >> 1);
+ valLD64 = nrgDiffLD64 - nrgLD64;
+ if (valLD64 < mhThresh.derivThresBelowLD64) {
+ bLPsignal = 0;
+ break;
+ }
+ } else {
+ bLPsignal = 0;
+ break;
+ }
+ }
+ }
+
+ if (bLPsignal) {
+ for (i = 0; i < nSfb; i++) {
+ if (maxDerivPos >= pFreqBandTable[i] &&
+ maxDerivPos < pFreqBandTable[i + 1])
+ break;
+ }
+
+ if (pAddHarmSfb[i]) {
+ pAddHarmSfb[i] = 0;
+ for (est = start; est < stop; est++) {
+ pDetectionVectors[est][i] = 0;
+ }
+ }
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief Checks if it is allowed to detect a missing tone, that wasn't
+ detected previously.
+
+
+ \return newDetectionAllowed flag.
+
+*/
+/**************************************************************************/
+static INT isDetectionOfNewToneAllowed(
+ const SBR_FRAME_INFO *pFrameInfo, INT *pDetectionStartPos,
+ INT noEstPerFrame, INT prevTransientFrame, INT prevTransientPos,
+ INT prevTransientFlag, INT transientPosOffset, INT transientFlag,
+ INT transientPos, INT deltaTime,
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMissingHarmonicsDetector) {
+ INT transientFrame, newDetectionAllowed;
+
+ /* Determine if this is a frame where a transient starts...
+ * If the transient flag was set the previous frame but not the
+ * transient frame flag, the transient frame flag is set in the current frame.
+ *****************************************************************************/
+ transientFrame = 0;
+ if (transientFlag) {
+ if (transientPos + transientPosOffset <
+ pFrameInfo->borders[pFrameInfo->nEnvelopes]) {
+ transientFrame = 1;
+ if (noEstPerFrame > 1) {
+ if (transientPos + transientPosOffset >
+ h_sbrMissingHarmonicsDetector->timeSlots >> 1) {
+ *pDetectionStartPos = noEstPerFrame;
+ } else {
+ *pDetectionStartPos = noEstPerFrame >> 1;
+ }
+
+ } else {
+ *pDetectionStartPos = noEstPerFrame;
+ }
+ }
+ } else {
+ if (prevTransientFlag && !prevTransientFrame) {
+ transientFrame = 1;
+ *pDetectionStartPos = 0;
+ }
+ }
+
+ /*
+ * Determine if detection of new missing harmonics are allowed.
+ * If the frame contains a transient it's ok. If the previous
+ * frame contained a transient it needs to be sufficiently close
+ * to the start of the current frame.
+ ****************************************************************/
+ newDetectionAllowed = 0;
+ if (transientFrame) {
+ newDetectionAllowed = 1;
+ } else {
+ if (prevTransientFrame &&
+ fixp_abs(pFrameInfo->borders[0] -
+ (prevTransientPos + transientPosOffset -
+ h_sbrMissingHarmonicsDetector->timeSlots)) < deltaTime) {
+ newDetectionAllowed = 1;
+ *pDetectionStartPos = 0;
+ }
+ }
+
+ h_sbrMissingHarmonicsDetector->previousTransientFlag = transientFlag;
+ h_sbrMissingHarmonicsDetector->previousTransientFrame = transientFrame;
+ h_sbrMissingHarmonicsDetector->previousTransientPos = transientPos;
+
+ return (newDetectionAllowed);
+}
+
+/**************************************************************************/
+/*!
+ \brief Cleans up the detection after a transient.
+
+
+ \return none.
+
+*/
+/**************************************************************************/
+static void transientCleanUp(FIXP_DBL **quotaBuffer, INT nSfb,
+ UCHAR **detectionVectors, UCHAR *pAddHarmSfb,
+ UCHAR *pPrevAddHarmSfb, INT **signBuffer,
+ const UCHAR *pFreqBandTable, INT start, INT stop,
+ INT newDetectionAllowed, FIXP_DBL *pNrgVector,
+ THRES_HOLDS mhThresh) {
+ INT i, j, est;
+
+ for (est = start; est < stop; est++) {
+ for (i = 0; i < nSfb; i++) {
+ pAddHarmSfb[i] = pAddHarmSfb[i] || detectionVectors[est][i];
+ }
+ }
+
+ if (newDetectionAllowed == 1) {
+ /*
+ * Check for duplication of sines located
+ * on the border of two scf-bands.
+ *************************************************/
+ for (i = 0; i < nSfb - 1; i++) {
+ /* detection in adjacent channels.*/
+ if (pAddHarmSfb[i] && pAddHarmSfb[i + 1]) {
+ FIXP_DBL maxVal1, maxVal2;
+ INT maxPos1, maxPos2, maxPosTime1, maxPosTime2;
+
+ INT li = pFreqBandTable[i];
+ INT ui = pFreqBandTable[i + 1];
+
+ /* Find maximum tonality in the the two scf bands.*/
+ maxPosTime1 = start;
+ maxPos1 = li;
+ maxVal1 = quotaBuffer[start][li];
+ for (est = start; est < stop; est++) {
+ for (j = li; j < ui; j++) {
+ if (quotaBuffer[est][j] > maxVal1) {
+ maxVal1 = quotaBuffer[est][j];
+ maxPos1 = j;
+ maxPosTime1 = est;
+ }
+ }
+ }
+
+ li = pFreqBandTable[i + 1];
+ ui = pFreqBandTable[i + 2];
+
+ /* Find maximum tonality in the the two scf bands.*/
+ maxPosTime2 = start;
+ maxPos2 = li;
+ maxVal2 = quotaBuffer[start][li];
+ for (est = start; est < stop; est++) {
+ for (j = li; j < ui; j++) {
+ if (quotaBuffer[est][j] > maxVal2) {
+ maxVal2 = quotaBuffer[est][j];
+ maxPos2 = j;
+ maxPosTime2 = est;
+ }
+ }
+ }
+
+ /* If the maximum values are in adjacent QMF-channels, we need to remove
+ the lowest of the two.*/
+ if (maxPos2 - maxPos1 < 2) {
+ if (pPrevAddHarmSfb[i] == 1 && pPrevAddHarmSfb[i + 1] == 0) {
+ /* Keep the lower, remove the upper.*/
+ pAddHarmSfb[i + 1] = 0;
+ for (est = start; est < stop; est++) {
+ detectionVectors[est][i + 1] = 0;
+ }
+ } else {
+ if (pPrevAddHarmSfb[i] == 0 && pPrevAddHarmSfb[i + 1] == 1) {
+ /* Keep the upper, remove the lower.*/
+ pAddHarmSfb[i] = 0;
+ for (est = start; est < stop; est++) {
+ detectionVectors[est][i] = 0;
+ }
+ } else {
+ /* If the maximum values are in adjacent QMF-channels, and if the
+ signs indicate that it is the same sine, we need to remove the
+ lowest of the two.*/
+ if (maxVal1 > maxVal2) {
+ if (signBuffer[maxPosTime1][maxPos2] < 0 &&
+ signBuffer[maxPosTime1][maxPos1] > 0) {
+ /* Keep the lower, remove the upper.*/
+ pAddHarmSfb[i + 1] = 0;
+ for (est = start; est < stop; est++) {
+ detectionVectors[est][i + 1] = 0;
+ }
+ }
+ } else {
+ if (signBuffer[maxPosTime2][maxPos2] < 0 &&
+ signBuffer[maxPosTime2][maxPos1] > 0) {
+ /* Keep the upper, remove the lower.*/
+ pAddHarmSfb[i] = 0;
+ for (est = start; est < stop; est++) {
+ detectionVectors[est][i] = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Make sure that the detection is not the cut-off of a low pass filter. */
+ removeLowPassDetection(pAddHarmSfb, detectionVectors, start, stop, nSfb,
+ pFreqBandTable, pNrgVector, mhThresh);
+ } else {
+ /*
+ * If a missing harmonic wasn't missing the previous frame
+ * the transient-flag needs to be set in order to be allowed to detect it.
+ *************************************************************************/
+ for (i = 0; i < nSfb; i++) {
+ if (pAddHarmSfb[i] - pPrevAddHarmSfb[i] > 0) pAddHarmSfb[i] = 0;
+ }
+ }
+}
+
+/*****************************************************************************/
+/*!
+ \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.
+
+*/
+/**************************************************************************/
+static void detection(FIXP_DBL *quotaBuffer, FIXP_DBL *pDiffVecScfb, INT nSfb,
+ UCHAR *pHarmVec, const UCHAR *pFreqBandTable,
+ FIXP_DBL *sfmOrig, FIXP_DBL *sfmSbr,
+ GUIDE_VECTORS guideVectors, GUIDE_VECTORS newGuideVectors,
+ THRES_HOLDS mhThresh) {
+ INT i, j, ll, lu;
+ FIXP_DBL thresTemp, thresOrig;
+
+ /*
+ * Do detection on the difference vector, i.e. the difference between
+ * the original and the transposed.
+ *********************************************************************/
+ for (i = 0; i < nSfb; i++) {
+ thresTemp = (guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f))
+ ? fMax(fMult(mhThresh.decayGuideDiff,
+ guideVectors.guideVectorDiff[i]),
+ mhThresh.thresHoldDiffGuide)
+ : mhThresh.thresHoldDiff;
+
+ thresTemp = fMin(thresTemp, mhThresh.thresHoldDiff);
+
+ if (pDiffVecScfb[i] > thresTemp) {
+ pHarmVec[i] = 1;
+ newGuideVectors.guideVectorDiff[i] = pDiffVecScfb[i];
+ } else {
+ /* If the guide wasn't zero, but the current level is to low,
+ start tracking the decay on the tone in the original rather
+ than the difference.*/
+ if (guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f)) {
+ guideVectors.guideVectorOrig[i] = mhThresh.thresHoldToneGuide;
+ }
+ }
+ }
+
+ /*
+ * Trace tones in the original signal that at one point
+ * have been detected because they will be replaced by
+ * multiple tones in the sbr signal.
+ ****************************************************/
+
+ for (i = 0; i < nSfb; i++) {
+ ll = pFreqBandTable[i];
+ lu = pFreqBandTable[i + 1];
+
+ thresOrig =
+ fixMax(fMult(guideVectors.guideVectorOrig[i], mhThresh.decayGuideOrig),
+ mhThresh.thresHoldToneGuide);
+ thresOrig = fixMin(thresOrig, mhThresh.thresHoldTone);
+
+ if (guideVectors.guideVectorOrig[i] != FL2FXCONST_DBL(0.0f)) {
+ for (j = ll; j < lu; j++) {
+ if (quotaBuffer[j] > thresOrig) {
+ pHarmVec[i] = 1;
+ newGuideVectors.guideVectorOrig[i] = quotaBuffer[j];
+ }
+ }
+ }
+ }
+
+ /*
+ * Check for multiple sines in the transposed signal,
+ * where there is only one in the original.
+ ****************************************************/
+ thresOrig = mhThresh.thresHoldTone;
+
+ for (i = 0; i < nSfb; i++) {
+ ll = pFreqBandTable[i];
+ lu = pFreqBandTable[i + 1];
+
+ if (pHarmVec[i] == 0) {
+ if (lu - ll > 1) {
+ for (j = ll; j < lu; j++) {
+ if (quotaBuffer[j] > thresOrig &&
+ (sfmSbr[i] > mhThresh.sfmThresSbr &&
+ sfmOrig[i] < mhThresh.sfmThresOrig)) {
+ pHarmVec[i] = 1;
+ newGuideVectors.guideVectorOrig[i] = quotaBuffer[j];
+ }
+ }
+ } else {
+ if (i < nSfb - 1) {
+ ll = pFreqBandTable[i];
+
+ if (i > 0) {
+ if (quotaBuffer[ll] > mhThresh.thresHoldTone &&
+ (pDiffVecScfb[i + 1] < mhThresh.invThresHoldTone ||
+ pDiffVecScfb[i - 1] < mhThresh.invThresHoldTone)) {
+ pHarmVec[i] = 1;
+ newGuideVectors.guideVectorOrig[i] = quotaBuffer[ll];
+ }
+ } else {
+ if (quotaBuffer[ll] > mhThresh.thresHoldTone &&
+ pDiffVecScfb[i + 1] < mhThresh.invThresHoldTone) {
+ pHarmVec[i] = 1;
+ newGuideVectors.guideVectorOrig[i] = quotaBuffer[ll];
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief Do detection for every tonality estimate, using forward prediction.
+
+
+ \return none.
+
+*/
+/**************************************************************************/
+static void detectionWithPrediction(
+ FIXP_DBL **quotaBuffer, FIXP_DBL **pDiffVecScfb, INT **signBuffer, INT nSfb,
+ const UCHAR *pFreqBandTable, FIXP_DBL **sfmOrig, FIXP_DBL **sfmSbr,
+ UCHAR **detectionVectors, UCHAR *pPrevAddHarmSfb,
+ GUIDE_VECTORS *guideVectors, INT noEstPerFrame, INT detectionStart,
+ INT totNoEst, INT newDetectionAllowed, INT *pAddHarmFlag,
+ UCHAR *pAddHarmSfb, FIXP_DBL *pNrgVector,
+ const DETECTOR_PARAMETERS_MH *mhParams) {
+ INT est = 0, i;
+ INT start;
+
+ FDKmemclear(pAddHarmSfb, nSfb * sizeof(UCHAR));
+
+ 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) {
+ start = detectionStart + 1;
+
+ if (start != 0) {
+ FDKmemcpy(guideVectors[start].guideVectorDiff,
+ guideVectors[0].guideVectorDiff, nSfb * sizeof(FIXP_DBL));
+ FDKmemcpy(guideVectors[start].guideVectorOrig,
+ guideVectors[0].guideVectorOrig, nSfb * sizeof(FIXP_DBL));
+ FDKmemclear(guideVectors[start - 1].guideVectorDetected,
+ nSfb * sizeof(UCHAR));
+ }
+ } else {
+ start = 0;
+ }
+ } else {
+ start = 0;
+ }
+
+ for (est = start; est < totNoEst; est++) {
+ /*
+ * Do detection on the current frame using
+ * guide-info from the previous.
+ *******************************************/
+ if (est > 0) {
+ FDKmemcpy(guideVectors[est].guideVectorDetected,
+ detectionVectors[est - 1], nSfb * sizeof(UCHAR));
+ }
+
+ FDKmemclear(detectionVectors[est], nSfb * sizeof(UCHAR));
+
+ if (est < totNoEst - 1) {
+ FDKmemclear(guideVectors[est + 1].guideVectorDiff,
+ nSfb * sizeof(FIXP_DBL));
+ FDKmemclear(guideVectors[est + 1].guideVectorOrig,
+ nSfb * sizeof(FIXP_DBL));
+ FDKmemclear(guideVectors[est + 1].guideVectorDetected,
+ nSfb * sizeof(UCHAR));
+
+ detection(quotaBuffer[est], pDiffVecScfb[est], nSfb,
+ detectionVectors[est], pFreqBandTable, sfmOrig[est],
+ sfmSbr[est], guideVectors[est], guideVectors[est + 1],
+ mhParams->thresHolds);
+ } else {
+ FDKmemclear(guideVectors[est].guideVectorDiff, nSfb * sizeof(FIXP_DBL));
+ FDKmemclear(guideVectors[est].guideVectorOrig, nSfb * sizeof(FIXP_DBL));
+ FDKmemclear(guideVectors[est].guideVectorDetected, nSfb * sizeof(UCHAR));
+
+ detection(quotaBuffer[est], pDiffVecScfb[est], nSfb,
+ detectionVectors[est], pFreqBandTable, sfmOrig[est],
+ sfmSbr[est], guideVectors[est], guideVectors[est],
+ mhParams->thresHolds);
+ }
+ }
+
+ /* Clean up the detection.*/
+ transientCleanUp(quotaBuffer, nSfb, detectionVectors, pAddHarmSfb,
+ pPrevAddHarmSfb, signBuffer, pFreqBandTable, start, totNoEst,
+ newDetectionAllowed, pNrgVector, mhParams->thresHolds);
+
+ /* Set flag... */
+ *pAddHarmFlag = 0;
+ for (i = 0; i < nSfb; i++) {
+ if (pAddHarmSfb[i]) {
+ *pAddHarmFlag = 1;
+ break;
+ }
+ }
+
+ FDKmemcpy(pPrevAddHarmSfb, pAddHarmSfb, nSfb * sizeof(UCHAR));
+ FDKmemcpy(guideVectors[0].guideVectorDetected, pAddHarmSfb,
+ nSfb * sizeof(INT));
+
+ for (i = 0; i < nSfb; i++) {
+ guideVectors[0].guideVectorDiff[i] = FL2FXCONST_DBL(0.0f);
+ guideVectors[0].guideVectorOrig[i] = FL2FXCONST_DBL(0.0f);
+
+ if (pAddHarmSfb[i] == 1) {
+ /* If we had a detection use the guide-value in the next frame from the
+ last estimate were the detection was done.*/
+ for (est = start; est < totNoEst; est++) {
+ if (guideVectors[est].guideVectorDiff[i] != FL2FXCONST_DBL(0.0f)) {
+ guideVectors[0].guideVectorDiff[i] =
+ guideVectors[est].guideVectorDiff[i];
+ }
+ if (guideVectors[est].guideVectorOrig[i] != FL2FXCONST_DBL(0.0f)) {
+ guideVectors[0].guideVectorOrig[i] =
+ guideVectors[est].guideVectorOrig[i];
+ }
+ }
+ }
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief Calculates a compensation vector for the energy data.
+
+ This function calculates a compensation vector for the energy data (i.e.
+ envelope data) that is calculated elsewhere. This is since, one sine on
+ the border of two scalefactor bands, will be replace by one sine in the
+ middle of either scalefactor band. However, since the sine that is replaced
+ will influence the energy estimate in both scalefactor bands (in the envelops
+ calculation function) a compensation value is required in order to avoid
+ noise substitution in the decoder next to the synthetic sine.
+
+ \return none.
+
+*/
+/**************************************************************************/
+static void calculateCompVector(UCHAR *pAddHarmSfb, FIXP_DBL **pTonalityMatrix,
+ INT **pSignMatrix, UCHAR *pEnvComp, INT nSfb,
+ const UCHAR *freqBandTable, INT totNoEst,
+ INT maxComp, UCHAR *pPrevEnvComp,
+ INT newDetectionAllowed) {
+ INT scfBand, est, l, ll, lu, maxPosF, maxPosT;
+ FIXP_DBL maxVal;
+ INT compValue;
+ FIXP_DBL tmp;
+
+ FDKmemclear(pEnvComp, nSfb * sizeof(UCHAR));
+
+ for (scfBand = 0; scfBand < nSfb; scfBand++) {
+ if (pAddHarmSfb[scfBand]) { /* A missing sine was detected */
+ ll = freqBandTable[scfBand];
+ lu = freqBandTable[scfBand + 1];
+
+ maxPosF = 0; /* First find the maximum*/
+ maxPosT = 0;
+ maxVal = FL2FXCONST_DBL(0.0f);
+
+ for (est = 0; est < totNoEst; est++) {
+ for (l = ll; l < lu; l++) {
+ if (pTonalityMatrix[est][l] > maxVal) {
+ maxVal = pTonalityMatrix[est][l];
+ maxPosF = l;
+ maxPosT = est;
+ }
+ }
+ }
+
+ /*
+ * If the maximum tonality is at the lower border of the
+ * scalefactor band, we check the sign of the adjacent channels
+ * to see if this sine is shared by the lower channel. If so, the
+ * energy of the single sine will be present in two scalefactor bands
+ * in the SBR data, which will cause problems in the decoder, when we
+ * add a sine to just one of the channels.
+ *********************************************************************/
+ if (maxPosF == ll && scfBand) {
+ if (!pAddHarmSfb[scfBand - 1]) { /* No detection below*/
+ if (pSignMatrix[maxPosT][maxPosF - 1] > 0 &&
+ pSignMatrix[maxPosT][maxPosF] < 0) {
+ /* The comp value is calulated as the tonallity value, i.e we want
+ to reduce the envelope data for this channel with as much as the
+ tonality that is spread from the channel above. (ld64(RELAXATION)
+ = 0.31143075889) */
+ tmp = fixp_abs(
+ (FIXP_DBL)CalcLdData(pTonalityMatrix[maxPosT][maxPosF - 1]) +
+ RELAXATION_LD64);
+ tmp = (tmp >> (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1)) +
+ (FIXP_DBL)1; /* shift one bit less for rounding */
+ compValue = ((INT)(LONG)tmp) >> 1;
+
+ /* limit the comp-value*/
+ if (compValue > maxComp) compValue = maxComp;
+
+ pEnvComp[scfBand - 1] = compValue;
+ }
+ }
+ }
+
+ /*
+ * Same as above, but for the upper end of the scalefactor-band.
+ ***************************************************************/
+ if (maxPosF == lu - 1 && scfBand + 1 < nSfb) { /* Upper border*/
+ if (!pAddHarmSfb[scfBand + 1]) {
+ if (pSignMatrix[maxPosT][maxPosF] > 0 &&
+ pSignMatrix[maxPosT][maxPosF + 1] < 0) {
+ tmp = fixp_abs(
+ (FIXP_DBL)CalcLdData(pTonalityMatrix[maxPosT][maxPosF + 1]) +
+ RELAXATION_LD64);
+ tmp = (tmp >> (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1)) +
+ (FIXP_DBL)1; /* shift one bit less for rounding */
+ compValue = ((INT)(LONG)tmp) >> 1;
+
+ if (compValue > maxComp) compValue = maxComp;
+
+ pEnvComp[scfBand + 1] = compValue;
+ }
+ }
+ }
+ }
+ }
+
+ if (newDetectionAllowed == 0) {
+ for (scfBand = 0; scfBand < nSfb; scfBand++) {
+ if (pEnvComp[scfBand] != 0 && pPrevEnvComp[scfBand] == 0)
+ pEnvComp[scfBand] = 0;
+ }
+ }
+
+ /* remember the value for the next frame.*/
+ FDKmemcpy(pPrevEnvComp, pEnvComp, nSfb * sizeof(UCHAR));
+}
+
+/**************************************************************************/
+/*!
+ \brief Detects where strong tonal components will be missing after
+ HFR in the decoder.
+
+
+ \return none.
+
+*/
+/**************************************************************************/
+void FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMHDet, FIXP_DBL **pQuotaBuffer,
+ INT **pSignBuffer, SCHAR *indexVector, const SBR_FRAME_INFO *pFrameInfo,
+ const UCHAR *pTranInfo, INT *pAddHarmonicsFlag,
+ UCHAR *pAddHarmonicsScaleFactorBands, const UCHAR *freqBandTable, INT nSfb,
+ UCHAR *envelopeCompensation, FIXP_DBL *pNrgVector) {
+ INT transientFlag = pTranInfo[1];
+ INT transientPos = pTranInfo[0];
+ INT newDetectionAllowed;
+ INT transientDetStart = 0;
+
+ UCHAR **detectionVectors = h_sbrMHDet->detectionVectors;
+ INT move = h_sbrMHDet->move;
+ INT noEstPerFrame = h_sbrMHDet->noEstPerFrame;
+ INT totNoEst = h_sbrMHDet->totNoEst;
+ INT prevTransientFlag = h_sbrMHDet->previousTransientFlag;
+ INT prevTransientFrame = h_sbrMHDet->previousTransientFrame;
+ INT transientPosOffset = h_sbrMHDet->transientPosOffset;
+ INT prevTransientPos = h_sbrMHDet->previousTransientPos;
+ GUIDE_VECTORS *guideVectors = h_sbrMHDet->guideVectors;
+ INT deltaTime = h_sbrMHDet->mhParams->deltaTime;
+ INT maxComp = h_sbrMHDet->mhParams->maxComp;
+
+ int est;
+
+ /*
+ Buffer values.
+ */
+ FDK_ASSERT(move <= (MAX_NO_OF_ESTIMATES >> 1));
+ FDK_ASSERT(noEstPerFrame <= (MAX_NO_OF_ESTIMATES >> 1));
+
+ FIXP_DBL *sfmSbr[MAX_NO_OF_ESTIMATES];
+ FIXP_DBL *sfmOrig[MAX_NO_OF_ESTIMATES];
+ FIXP_DBL *tonalityDiff[MAX_NO_OF_ESTIMATES];
+
+ for (est = 0; est < MAX_NO_OF_ESTIMATES / 2; est++) {
+ sfmSbr[est] = h_sbrMHDet->sfmSbr[est];
+ sfmOrig[est] = h_sbrMHDet->sfmOrig[est];
+ tonalityDiff[est] = h_sbrMHDet->tonalityDiff[est];
+ }
+
+ C_ALLOC_SCRATCH_START(_scratch, FIXP_DBL,
+ 3 * MAX_NO_OF_ESTIMATES / 2 * MAX_FREQ_COEFFS)
+ FIXP_DBL *scratch = _scratch;
+ for (; est < MAX_NO_OF_ESTIMATES; est++) {
+ sfmSbr[est] = scratch;
+ scratch += MAX_FREQ_COEFFS;
+ sfmOrig[est] = scratch;
+ scratch += MAX_FREQ_COEFFS;
+ tonalityDiff[est] = scratch;
+ scratch += MAX_FREQ_COEFFS;
+ }
+
+ /* Determine if we're allowed to detect "missing harmonics" that wasn't
+ detected before. In order to be allowed to do new detection, there must be
+ a transient in the current frame, or a transient in the previous frame
+ sufficiently close to the current frame. */
+ newDetectionAllowed = isDetectionOfNewToneAllowed(
+ pFrameInfo, &transientDetStart, noEstPerFrame, prevTransientFrame,
+ prevTransientPos, prevTransientFlag, transientPosOffset, transientFlag,
+ transientPos, deltaTime, h_sbrMHDet);
+
+ /* Calulate the variables that will be used subsequently for the actual
+ * detection */
+ calculateDetectorInput(pQuotaBuffer, indexVector, tonalityDiff, sfmOrig,
+ sfmSbr, freqBandTable, nSfb, noEstPerFrame, move);
+
+ /* Do the actual detection using information from previous detections */
+ detectionWithPrediction(pQuotaBuffer, tonalityDiff, pSignBuffer, nSfb,
+ freqBandTable, sfmOrig, sfmSbr, detectionVectors,
+ h_sbrMHDet->guideScfb, guideVectors, noEstPerFrame,
+ transientDetStart, totNoEst, newDetectionAllowed,
+ pAddHarmonicsFlag, pAddHarmonicsScaleFactorBands,
+ pNrgVector, h_sbrMHDet->mhParams);
+
+ /* Calculate the comp vector, so that the energy can be
+ compensated for a sine between two QMF-bands. */
+ calculateCompVector(pAddHarmonicsScaleFactorBands, pQuotaBuffer, pSignBuffer,
+ envelopeCompensation, nSfb, freqBandTable, totNoEst,
+ maxComp, h_sbrMHDet->prevEnvelopeCompensation,
+ newDetectionAllowed);
+
+ for (est = 0; est < move; est++) {
+ FDKmemcpy(tonalityDiff[est], tonalityDiff[est + noEstPerFrame],
+ sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
+ FDKmemcpy(sfmOrig[est], sfmOrig[est + noEstPerFrame],
+ sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
+ FDKmemcpy(sfmSbr[est], sfmSbr[est + noEstPerFrame],
+ sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
+ }
+ C_ALLOC_SCRATCH_END(_scratch, FIXP_DBL,
+ 3 * MAX_NO_OF_ESTIMATES / 2 * MAX_FREQ_COEFFS)
+}
+
+/**************************************************************************/
+/*!
+ \brief Initialize an instance of the missing harmonics detector.
+
+
+ \return errorCode, noError if OK.
+
+*/
+/**************************************************************************/
+INT FDKsbrEnc_CreateSbrMissingHarmonicsDetector(
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet, INT chan) {
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet;
+ INT i;
+
+ UCHAR *detectionVectors = GetRam_Sbr_detectionVectors(chan);
+ UCHAR *guideVectorDetected = GetRam_Sbr_guideVectorDetected(chan);
+ FIXP_DBL *guideVectorDiff = GetRam_Sbr_guideVectorDiff(chan);
+ FIXP_DBL *guideVectorOrig = GetRam_Sbr_guideVectorOrig(chan);
+
+ FDKmemclear(hs, sizeof(SBR_MISSING_HARMONICS_DETECTOR));
+
+ hs->prevEnvelopeCompensation = GetRam_Sbr_prevEnvelopeCompensation(chan);
+ hs->guideScfb = GetRam_Sbr_guideScfb(chan);
+
+ if ((NULL == detectionVectors) || (NULL == guideVectorDetected) ||
+ (NULL == guideVectorDiff) || (NULL == guideVectorOrig) ||
+ (NULL == hs->prevEnvelopeCompensation) || (NULL == hs->guideScfb)) {
+ goto bail;
+ }
+
+ for (i = 0; i < MAX_NO_OF_ESTIMATES; i++) {
+ hs->guideVectors[i].guideVectorDiff =
+ guideVectorDiff + (i * MAX_FREQ_COEFFS);
+ hs->guideVectors[i].guideVectorOrig =
+ guideVectorOrig + (i * MAX_FREQ_COEFFS);
+ hs->detectionVectors[i] = detectionVectors + (i * MAX_FREQ_COEFFS);
+ hs->guideVectors[i].guideVectorDetected =
+ guideVectorDetected + (i * MAX_FREQ_COEFFS);
+ }
+
+ return 0;
+
+bail:
+ hs->guideVectors[0].guideVectorDiff = guideVectorDiff;
+ hs->guideVectors[0].guideVectorOrig = guideVectorOrig;
+ hs->detectionVectors[0] = detectionVectors;
+ hs->guideVectors[0].guideVectorDetected = guideVectorDetected;
+
+ FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(hs);
+ return -1;
+}
+
+/**************************************************************************/
+/*!
+ \brief Initialize an instance of the missing harmonics detector.
+
+
+ \return errorCode, noError if OK.
+
+*/
+/**************************************************************************/
+INT FDKsbrEnc_InitSbrMissingHarmonicsDetector(
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet, INT sampleFreq,
+ INT frameSize, INT nSfb, INT qmfNoChannels, INT totNoEst, INT move,
+ INT noEstPerFrame, UINT sbrSyntaxFlags) {
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet;
+ int i;
+
+ FDK_ASSERT(totNoEst <= MAX_NO_OF_ESTIMATES);
+
+ if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
+ switch (frameSize) {
+ case 1024:
+ case 512:
+ hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
+ hs->timeSlots = 16;
+ break;
+ case 960:
+ case 480:
+ hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
+ hs->timeSlots = 15;
+ break;
+ default:
+ return -1;
+ }
+ } else {
+ switch (frameSize) {
+ case 2048:
+ case 1024:
+ hs->transientPosOffset = FRAME_MIDDLE_SLOT_2048;
+ hs->timeSlots = NUMBER_TIME_SLOTS_2048;
+ break;
+ case 1920:
+ case 960:
+ hs->transientPosOffset = FRAME_MIDDLE_SLOT_1920;
+ hs->timeSlots = NUMBER_TIME_SLOTS_1920;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
+ hs->mhParams = &paramsAacLd;
+ } else
+ hs->mhParams = &paramsAac;
+
+ hs->qmfNoChannels = qmfNoChannels;
+ hs->sampleFreq = sampleFreq;
+ hs->nSfb = nSfb;
+
+ hs->totNoEst = totNoEst;
+ hs->move = move;
+ hs->noEstPerFrame = noEstPerFrame;
+
+ for (i = 0; i < totNoEst; i++) {
+ FDKmemclear(hs->guideVectors[i].guideVectorDiff,
+ sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
+ FDKmemclear(hs->guideVectors[i].guideVectorOrig,
+ sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
+ FDKmemclear(hs->detectionVectors[i], sizeof(UCHAR) * MAX_FREQ_COEFFS);
+ FDKmemclear(hs->guideVectors[i].guideVectorDetected,
+ sizeof(UCHAR) * MAX_FREQ_COEFFS);
+ }
+
+ // for(i=0; i<totNoEst/2; i++) {
+ for (i = 0; i < MAX_NO_OF_ESTIMATES / 2; i++) {
+ FDKmemclear(hs->tonalityDiff[i], sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
+ FDKmemclear(hs->sfmOrig[i], sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
+ FDKmemclear(hs->sfmSbr[i], sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
+ }
+
+ FDKmemclear(hs->prevEnvelopeCompensation, sizeof(UCHAR) * MAX_FREQ_COEFFS);
+ FDKmemclear(hs->guideScfb, sizeof(UCHAR) * MAX_FREQ_COEFFS);
+
+ hs->previousTransientFlag = 0;
+ hs->previousTransientFrame = 0;
+ hs->previousTransientPos = 0;
+
+ return (0);
+}
+
+/**************************************************************************/
+/*!
+ \brief Deletes an instance of the missing harmonics detector.
+
+
+ \return none.
+
+*/
+/**************************************************************************/
+void FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet) {
+ if (hSbrMHDet) {
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet;
+
+ FreeRam_Sbr_detectionVectors(&hs->detectionVectors[0]);
+ FreeRam_Sbr_guideVectorDetected(&hs->guideVectors[0].guideVectorDetected);
+ FreeRam_Sbr_guideVectorDiff(&hs->guideVectors[0].guideVectorDiff);
+ FreeRam_Sbr_guideVectorOrig(&hs->guideVectors[0].guideVectorOrig);
+ FreeRam_Sbr_prevEnvelopeCompensation(&hs->prevEnvelopeCompensation);
+ FreeRam_Sbr_guideScfb(&hs->guideScfb);
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief Resets an instance of the missing harmonics detector.
+
+
+ \return error code, noError if OK.
+
+*/
+/**************************************************************************/
+INT FDKsbrEnc_ResetSbrMissingHarmonicsDetector(
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMissingHarmonicsDetector,
+ INT nSfb) {
+ int i;
+ FIXP_DBL tempGuide[MAX_FREQ_COEFFS];
+ UCHAR tempGuideInt[MAX_FREQ_COEFFS];
+ INT nSfbPrev;
+
+ nSfbPrev = hSbrMissingHarmonicsDetector->nSfb;
+ hSbrMissingHarmonicsDetector->nSfb = nSfb;
+
+ FDKmemcpy(tempGuideInt, hSbrMissingHarmonicsDetector->guideScfb,
+ nSfbPrev * sizeof(UCHAR));
+
+ if (nSfb > nSfbPrev) {
+ for (i = 0; i < (nSfb - nSfbPrev); i++) {
+ hSbrMissingHarmonicsDetector->guideScfb[i] = 0;
+ }
+
+ for (i = 0; i < nSfbPrev; i++) {
+ hSbrMissingHarmonicsDetector->guideScfb[i + (nSfb - nSfbPrev)] =
+ tempGuideInt[i];
+ }
+ } else {
+ for (i = 0; i < nSfb; i++) {
+ hSbrMissingHarmonicsDetector->guideScfb[i] =
+ tempGuideInt[i + (nSfbPrev - nSfb)];
+ }
+ }
+
+ FDKmemcpy(tempGuide,
+ hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff,
+ nSfbPrev * sizeof(FIXP_DBL));
+
+ if (nSfb > nSfbPrev) {
+ for (i = 0; i < (nSfb - nSfbPrev); i++) {
+ hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i] =
+ FL2FXCONST_DBL(0.0f);
+ }
+
+ for (i = 0; i < nSfbPrev; i++) {
+ hSbrMissingHarmonicsDetector->guideVectors[0]
+ .guideVectorDiff[i + (nSfb - nSfbPrev)] = tempGuide[i];
+ }
+ } else {
+ for (i = 0; i < nSfb; i++) {
+ hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i] =
+ tempGuide[i + (nSfbPrev - nSfb)];
+ }
+ }
+
+ FDKmemcpy(tempGuide,
+ hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig,
+ nSfbPrev * sizeof(FIXP_DBL));
+
+ if (nSfb > nSfbPrev) {
+ for (i = 0; i < (nSfb - nSfbPrev); i++) {
+ hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i] =
+ FL2FXCONST_DBL(0.0f);
+ }
+
+ for (i = 0; i < nSfbPrev; i++) {
+ hSbrMissingHarmonicsDetector->guideVectors[0]
+ .guideVectorOrig[i + (nSfb - nSfbPrev)] = tempGuide[i];
+ }
+ } else {
+ for (i = 0; i < nSfb; i++) {
+ hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i] =
+ tempGuide[i + (nSfbPrev - nSfb)];
+ }
+ }
+
+ FDKmemcpy(tempGuideInt,
+ hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected,
+ nSfbPrev * sizeof(UCHAR));
+
+ if (nSfb > nSfbPrev) {
+ for (i = 0; i < (nSfb - nSfbPrev); i++) {
+ hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i] = 0;
+ }
+
+ for (i = 0; i < nSfbPrev; i++) {
+ hSbrMissingHarmonicsDetector->guideVectors[0]
+ .guideVectorDetected[i + (nSfb - nSfbPrev)] = tempGuideInt[i];
+ }
+ } else {
+ for (i = 0; i < nSfb; i++) {
+ hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i] =
+ tempGuideInt[i + (nSfbPrev - nSfb)];
+ }
+ }
+
+ FDKmemcpy(tempGuideInt,
+ hSbrMissingHarmonicsDetector->prevEnvelopeCompensation,
+ nSfbPrev * sizeof(UCHAR));
+
+ if (nSfb > nSfbPrev) {
+ for (i = 0; i < (nSfb - nSfbPrev); i++) {
+ hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i] = 0;
+ }
+
+ for (i = 0; i < nSfbPrev; i++) {
+ hSbrMissingHarmonicsDetector
+ ->prevEnvelopeCompensation[i + (nSfb - nSfbPrev)] = tempGuideInt[i];
+ }
+ } else {
+ for (i = 0; i < nSfb; i++) {
+ hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i] =
+ tempGuideInt[i + (nSfbPrev - nSfb)];
+ }
+ }
+
+ return 0;
+}
diff --git a/fdk-aac/libSBRenc/src/mh_det.h b/fdk-aac/libSBRenc/src/mh_det.h
new file mode 100644
index 0000000..89d81b5
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/mh_det.h
@@ -0,0 +1,204 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief missing harmonics detection header file $Revision: 92790 $
+*/
+
+#ifndef MH_DET_H
+#define MH_DET_H
+
+#include "sbr_encoder.h"
+#include "fram_gen.h"
+
+typedef struct {
+ FIXP_DBL thresHoldDiff; /*!< threshold for tonality difference */
+ FIXP_DBL thresHoldDiffGuide; /*!< threshold for tonality difference for the
+ guide */
+ FIXP_DBL thresHoldTone; /*!< threshold for tonality for a sine */
+ FIXP_DBL invThresHoldTone;
+ FIXP_DBL thresHoldToneGuide; /*!< threshold for tonality for a sine for the
+ guide */
+ FIXP_DBL sfmThresSbr; /*!< tonality flatness measure threshold for the SBR
+ signal.*/
+ FIXP_DBL sfmThresOrig; /*!< tonality flatness measure threshold for the
+ original signal.*/
+ FIXP_DBL decayGuideOrig; /*!< decay value of the tonality value of the guide
+ for the tone. */
+ FIXP_DBL decayGuideDiff; /*!< decay value of the tonality value of the guide
+ for the tonality difference. */
+ FIXP_DBL derivThresMaxLD64; /*!< threshold for detecting LP character in a
+ signal. */
+ FIXP_DBL derivThresBelowLD64; /*!< threshold for detecting LP character in a
+ signal. */
+ FIXP_DBL derivThresAboveLD64; /*!< threshold for detecting LP character in a
+ signal. */
+} THRES_HOLDS;
+
+typedef struct {
+ INT deltaTime; /*!< maximum allowed transient distance (from frame border in
+ number of qmf subband sample) for a frame to be considered a
+ transient frame.*/
+ THRES_HOLDS thresHolds; /*!< the thresholds used for detection. */
+ INT maxComp; /*!< maximum alllowed compensation factor for the envelope data.
+ */
+} DETECTOR_PARAMETERS_MH;
+
+typedef struct {
+ FIXP_DBL *guideVectorDiff;
+ FIXP_DBL *guideVectorOrig;
+ UCHAR *guideVectorDetected;
+} GUIDE_VECTORS;
+
+typedef struct {
+ INT qmfNoChannels;
+ INT nSfb;
+ INT sampleFreq;
+ INT previousTransientFlag;
+ INT previousTransientFrame;
+ INT previousTransientPos;
+
+ INT noVecPerFrame;
+ INT transientPosOffset;
+
+ INT move;
+ INT totNoEst;
+ INT noEstPerFrame;
+ INT timeSlots;
+
+ UCHAR *guideScfb;
+ UCHAR *prevEnvelopeCompensation;
+ UCHAR *detectionVectors[MAX_NO_OF_ESTIMATES];
+ FIXP_DBL tonalityDiff[MAX_NO_OF_ESTIMATES / 2][MAX_FREQ_COEFFS];
+ FIXP_DBL sfmOrig[MAX_NO_OF_ESTIMATES / 2][MAX_FREQ_COEFFS];
+ FIXP_DBL sfmSbr[MAX_NO_OF_ESTIMATES / 2][MAX_FREQ_COEFFS];
+ const DETECTOR_PARAMETERS_MH *mhParams;
+ GUIDE_VECTORS guideVectors[MAX_NO_OF_ESTIMATES];
+} SBR_MISSING_HARMONICS_DETECTOR;
+
+typedef SBR_MISSING_HARMONICS_DETECTOR *HANDLE_SBR_MISSING_HARMONICS_DETECTOR;
+
+void FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMissingHarmonicsDetector,
+ FIXP_DBL **pQuotaBuffer, INT **pSignBuffer, SCHAR *indexVector,
+ const SBR_FRAME_INFO *pFrameInfo, const UCHAR *pTranInfo,
+ INT *pAddHarmonicsFlag, UCHAR *pAddHarmonicsScaleFactorBands,
+ const UCHAR *freqBandTable, INT nSfb, UCHAR *envelopeCompensation,
+ FIXP_DBL *pNrgVector);
+
+INT FDKsbrEnc_CreateSbrMissingHarmonicsDetector(
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet, INT chan);
+
+INT FDKsbrEnc_InitSbrMissingHarmonicsDetector(
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMissingHarmonicsDetector,
+ INT sampleFreq, INT frameSize, INT nSfb, INT qmfNoChannels, INT totNoEst,
+ INT move, INT noEstPerFrame, UINT sbrSyntaxFlags);
+
+void FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMissingHarmonicsDetector);
+
+INT FDKsbrEnc_ResetSbrMissingHarmonicsDetector(
+ HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMissingHarmonicsDetector,
+ INT nSfb);
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/nf_est.cpp b/fdk-aac/libSBRenc/src/nf_est.cpp
new file mode 100644
index 0000000..290ec35
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/nf_est.cpp
@@ -0,0 +1,612 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "nf_est.h"
+
+#include "sbr_misc.h"
+
+#include "genericStds.h"
+
+/* smoothFilter[4] = {0.05857864376269f, 0.2f, 0.34142135623731f, 0.4f}; */
+static const FIXP_DBL smoothFilter[4] = {0x077f813d, 0x19999995, 0x2bb3b1f5,
+ 0x33333335};
+
+/* static const INT smoothFilterLength = 4; */
+
+static const FIXP_DBL QuantOffset = (INT)0xfc000000; /* ld64(0.25) */
+
+#ifndef min
+#define min(a, b) (a < b ? a : b)
+#endif
+
+#ifndef max
+#define max(a, b) (a > b ? a : b)
+#endif
+
+#define NOISE_FLOOR_OFFSET_SCALING (4)
+
+/**************************************************************************/
+/*!
+ \brief The function applies smoothing to the noise levels.
+
+
+
+ \return none
+
+*/
+/**************************************************************************/
+static void smoothingOfNoiseLevels(
+ FIXP_DBL *NoiseLevels, /*!< pointer to noise-floor levels.*/
+ INT nEnvelopes, /*!< Number of noise floor envelopes.*/
+ INT noNoiseBands, /*!< Number of noise bands for every noise floor envelope.
+ */
+ FIXP_DBL prevNoiseLevels[NF_SMOOTHING_LENGTH]
+ [MAX_NUM_NOISE_VALUES], /*!< Previous noise floor
+ envelopes. */
+ const FIXP_DBL *
+ pSmoothFilter, /*!< filter used for smoothing the noise floor levels. */
+ INT transientFlag) /*!< flag indicating if a transient is present*/
+
+{
+ INT i, band, env;
+ FIXP_DBL accu;
+
+ for (env = 0; env < nEnvelopes; env++) {
+ if (transientFlag) {
+ for (i = 0; i < NF_SMOOTHING_LENGTH; i++) {
+ FDKmemcpy(prevNoiseLevels[i], NoiseLevels + env * noNoiseBands,
+ noNoiseBands * sizeof(FIXP_DBL));
+ }
+ } else {
+ for (i = 1; i < NF_SMOOTHING_LENGTH; i++) {
+ FDKmemcpy(prevNoiseLevels[i - 1], prevNoiseLevels[i],
+ noNoiseBands * sizeof(FIXP_DBL));
+ }
+ FDKmemcpy(prevNoiseLevels[NF_SMOOTHING_LENGTH - 1],
+ NoiseLevels + env * noNoiseBands,
+ noNoiseBands * sizeof(FIXP_DBL));
+ }
+
+ for (band = 0; band < noNoiseBands; band++) {
+ accu = FL2FXCONST_DBL(0.0f);
+ for (i = 0; i < NF_SMOOTHING_LENGTH; i++) {
+ accu += fMultDiv2(pSmoothFilter[i], prevNoiseLevels[i][band]);
+ }
+ FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES);
+ NoiseLevels[band + env * noNoiseBands] = accu << 1;
+ }
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief Does the noise floor level estiamtion.
+
+ The noiseLevel samples are scaled by the factor 0.25
+
+ \return none
+
+*/
+/**************************************************************************/
+static void qmfBasedNoiseFloorDetection(
+ FIXP_DBL *noiseLevel, /*!< Pointer to vector to
+ store the noise levels
+ in.*/
+ FIXP_DBL **quotaMatrixOrig, /*!< Matrix holding the quota
+ values of the original. */
+ SCHAR *indexVector, /*!< Index vector to obtain the
+ patched data. */
+ INT startIndex, /*!< Start index. */
+ INT stopIndex, /*!< Stop index. */
+ INT startChannel, /*!< Start channel of the current
+ noise floor band.*/
+ INT stopChannel, /*!< Stop channel of the current
+ noise floor band. */
+ FIXP_DBL ana_max_level, /*!< Maximum level of the
+ adaptive noise.*/
+ FIXP_DBL noiseFloorOffset, /*!< Noise floor offset. */
+ INT missingHarmonicFlag, /*!< Flag indicating if a
+ strong tonal component
+ is missing.*/
+ FIXP_DBL weightFac, /*!< Weightening factor for the
+ difference between orig and sbr.
+ */
+ INVF_MODE diffThres, /*!< Threshold value to control the
+ inverse filtering decision.*/
+ INVF_MODE inverseFilteringLevel) /*!< Inverse filtering
+ level of the current
+ band.*/
+{
+ INT scale, l, k;
+ FIXP_DBL meanOrig = FL2FXCONST_DBL(0.0f), meanSbr = FL2FXCONST_DBL(0.0f),
+ diff;
+ FIXP_DBL invIndex = GetInvInt(stopIndex - startIndex);
+ FIXP_DBL invChannel = GetInvInt(stopChannel - startChannel);
+ FIXP_DBL accu;
+
+ /*
+ Calculate the mean value, over the current time segment, for the original, the
+ HFR and the difference, over all channels in the current frequency range.
+ */
+
+ if (missingHarmonicFlag == 1) {
+ for (l = startChannel; l < stopChannel; l++) {
+ /* tonalityOrig */
+ accu = FL2FXCONST_DBL(0.0f);
+ for (k = startIndex; k < stopIndex; k++) {
+ accu += fMultDiv2(quotaMatrixOrig[k][l], invIndex);
+ }
+ meanOrig = fixMax(meanOrig, (accu << 1));
+
+ /* tonalitySbr */
+ accu = FL2FXCONST_DBL(0.0f);
+ for (k = startIndex; k < stopIndex; k++) {
+ accu += fMultDiv2(quotaMatrixOrig[k][indexVector[l]], invIndex);
+ }
+ meanSbr = fixMax(meanSbr, (accu << 1));
+ }
+ } else {
+ for (l = startChannel; l < stopChannel; l++) {
+ /* tonalityOrig */
+ accu = FL2FXCONST_DBL(0.0f);
+ for (k = startIndex; k < stopIndex; k++) {
+ accu += fMultDiv2(quotaMatrixOrig[k][l], invIndex);
+ }
+ meanOrig += fMult((accu << 1), invChannel);
+
+ /* tonalitySbr */
+ accu = FL2FXCONST_DBL(0.0f);
+ for (k = startIndex; k < stopIndex; k++) {
+ accu += fMultDiv2(quotaMatrixOrig[k][indexVector[l]], invIndex);
+ }
+ meanSbr += fMult((accu << 1), invChannel);
+ }
+ }
+
+ /* Small fix to avoid noise during silent passages.*/
+ if (meanOrig <= FL2FXCONST_DBL(0.000976562f * RELAXATION_FLOAT) &&
+ meanSbr <= FL2FXCONST_DBL(0.000976562f * RELAXATION_FLOAT)) {
+ meanOrig = FL2FXCONST_DBL(101.5936673f * RELAXATION_FLOAT);
+ meanSbr = FL2FXCONST_DBL(101.5936673f * RELAXATION_FLOAT);
+ }
+
+ meanOrig = fixMax(meanOrig, RELAXATION);
+ meanSbr = fixMax(meanSbr, RELAXATION);
+
+ if (missingHarmonicFlag == 1 || inverseFilteringLevel == INVF_MID_LEVEL ||
+ inverseFilteringLevel == INVF_LOW_LEVEL ||
+ inverseFilteringLevel == INVF_OFF || inverseFilteringLevel <= diffThres) {
+ diff = RELAXATION;
+ } else {
+ accu = fDivNorm(meanSbr, meanOrig, &scale);
+
+ diff = fixMax(RELAXATION, fMult(RELAXATION_FRACT, fMult(weightFac, accu)) >>
+ (RELAXATION_SHIFT - scale));
+ }
+
+ /*
+ * noise Level is now a positive value, i.e.
+ * the more harmonic the signal is the higher noise level,
+ * this makes no sense so we change the sign.
+ *********************************************************/
+ accu = fDivNorm(diff, meanOrig, &scale);
+ scale -= 2;
+
+ if ((scale > 0) && (accu > ((FIXP_DBL)MAXVAL_DBL) >> scale)) {
+ *noiseLevel = (FIXP_DBL)MAXVAL_DBL;
+ } else {
+ *noiseLevel = scaleValue(accu, scale);
+ }
+
+ /*
+ * Add a noise floor offset to compensate for bias in the detector
+ *****************************************************************/
+ if (!missingHarmonicFlag) {
+ *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
+ **************************************************************/
+ *noiseLevel =
+ fixMin(*noiseLevel,
+ ana_max_level); /* ana_max_level is scaled with factor 0.25 */
+}
+
+/**************************************************************************/
+/*!
+ \brief Does the noise floor level estiamtion.
+ The function calls the Noisefloor estimation function
+ for the time segments decided based upon the transient
+ information. The block is always divided into one or two segments.
+
+
+ \return none
+
+*/
+/**************************************************************************/
+void FDKsbrEnc_sbrNoiseFloorEstimateQmf(
+ HANDLE_SBR_NOISE_FLOOR_ESTIMATE
+ h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
+ */
+ const SBR_FRAME_INFO
+ *frame_info, /*!< Time frequency grid of the current frame. */
+ FIXP_DBL
+ *noiseLevels, /*!< Pointer to vector to store the noise levels in.*/
+ FIXP_DBL **quotaMatrixOrig, /*!< Matrix holding the quota values of the
+ original. */
+ SCHAR *indexVector, /*!< Index vector to obtain the patched data. */
+ INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component
+ will be missing. */
+ INT startIndex, /*!< Start index. */
+ UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per
+ frame. */
+ int transientFrame, /*!< A flag indicating if a transient is present. */
+ INVF_MODE *pInvFiltLevels, /*!< Pointer to the vector holding the inverse
+ filtering levels. */
+ UINT sbrSyntaxFlags)
+
+{
+ INT nNoiseEnvelopes, startPos[2], stopPos[2], env, band;
+
+ INT noNoiseBands = h_sbrNoiseFloorEstimate->noNoiseBands;
+ INT *freqBandTable = h_sbrNoiseFloorEstimate->freqBandTableQmf;
+
+ nNoiseEnvelopes = frame_info->nNoiseEnvelopes;
+
+ startPos[0] = startIndex;
+
+ if (nNoiseEnvelopes == 1) {
+ stopPos[0] = startIndex + min(numberOfEstimatesPerFrame, 2);
+ } else {
+ stopPos[0] = startIndex + 1;
+ startPos[1] = startIndex + 1;
+ stopPos[1] = startIndex + min(numberOfEstimatesPerFrame, 2);
+ }
+
+ /*
+ * Estimate the noise floor.
+ **************************************/
+ for (env = 0; env < nNoiseEnvelopes; env++) {
+ for (band = 0; band < noNoiseBands; band++) {
+ FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES);
+ qmfBasedNoiseFloorDetection(
+ &noiseLevels[band + env * noNoiseBands], quotaMatrixOrig, indexVector,
+ startPos[env], stopPos[env], freqBandTable[band],
+ freqBandTable[band + 1], h_sbrNoiseFloorEstimate->ana_max_level,
+ h_sbrNoiseFloorEstimate->noiseFloorOffset[band], missingHarmonicsFlag,
+ h_sbrNoiseFloorEstimate->weightFac,
+ h_sbrNoiseFloorEstimate->diffThres, pInvFiltLevels[band]);
+ }
+ }
+
+ /*
+ * Smoothing of the values.
+ **************************/
+ smoothingOfNoiseLevels(noiseLevels, nNoiseEnvelopes,
+ h_sbrNoiseFloorEstimate->noNoiseBands,
+ h_sbrNoiseFloorEstimate->prevNoiseLevels,
+ h_sbrNoiseFloorEstimate->smoothFilter, transientFrame);
+
+ /* quantisation*/
+ for (env = 0; env < nNoiseEnvelopes; env++) {
+ for (band = 0; band < noNoiseBands; band++) {
+ FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES);
+ noiseLevels[band + env * noNoiseBands] =
+ (FIXP_DBL)NOISE_FLOOR_OFFSET_64 -
+ (FIXP_DBL)CalcLdData(noiseLevels[band + env * noNoiseBands] +
+ (FIXP_DBL)1) +
+ QuantOffset;
+ }
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief
+
+
+ \return errorCode, noError if successful
+
+*/
+/**************************************************************************/
+static INT downSampleLoRes(INT *v_result, /*!< */
+ INT num_result, /*!< */
+ const UCHAR *freqBandTableRef, /*!< */
+ INT num_Ref) /*!< */
+{
+ INT step;
+ INT i, j;
+ INT org_length, result_length;
+ INT v_index[MAX_FREQ_COEFFS / 2];
+
+ /* init */
+ org_length = num_Ref;
+ result_length = num_result;
+
+ v_index[0] = 0; /* Always use left border */
+ i = 0;
+ while (org_length > 0) /* Create downsample vector */
+ {
+ i++;
+ step = org_length / result_length; /* floor; */
+ org_length = org_length - step;
+ result_length--;
+ v_index[i] = v_index[i - 1] + step;
+ }
+
+ if (i != num_result) /* Should never happen */
+ return (1); /* error downsampling */
+
+ for (j = 0; j <= i;
+ j++) /* Use downsample vector to index LoResolution vector. */
+ {
+ v_result[j] = freqBandTableRef[v_index[j]];
+ }
+
+ return (0);
+}
+
+/**************************************************************************/
+/*!
+ \brief Initialize an instance of the noise floor level estimation module.
+
+
+ \return errorCode, noError if successful
+
+*/
+/**************************************************************************/
+INT FDKsbrEnc_InitSbrNoiseFloorEstimate(
+ HANDLE_SBR_NOISE_FLOOR_ESTIMATE
+ h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
+ */
+ INT ana_max_level, /*!< Maximum level of the adaptive noise. */
+ const UCHAR *freqBandTable, /*!< Frequency band table. */
+ INT nSfb, /*!< Number of frequency bands. */
+ INT noiseBands, /*!< Number of noise bands per octave. */
+ INT noiseFloorOffset, /*!< Noise floor offset. */
+ INT timeSlots, /*!< Number of time slots in a frame. */
+ UINT useSpeechConfig /*!< Flag: adapt tuning parameters according to speech
+ */
+) {
+ INT i, qexp, qtmp;
+ FIXP_DBL tmp, exp;
+
+ FDKmemclear(h_sbrNoiseFloorEstimate, sizeof(SBR_NOISE_FLOOR_ESTIMATE));
+
+ h_sbrNoiseFloorEstimate->smoothFilter = smoothFilter;
+ if (useSpeechConfig) {
+ h_sbrNoiseFloorEstimate->weightFac = (FIXP_DBL)MAXVAL_DBL;
+ h_sbrNoiseFloorEstimate->diffThres = INVF_LOW_LEVEL;
+ } else {
+ h_sbrNoiseFloorEstimate->weightFac = FL2FXCONST_DBL(0.25f);
+ h_sbrNoiseFloorEstimate->diffThres = INVF_MID_LEVEL;
+ }
+
+ h_sbrNoiseFloorEstimate->timeSlots = timeSlots;
+ h_sbrNoiseFloorEstimate->noiseBands = noiseBands;
+
+ /* h_sbrNoiseFloorEstimate->ana_max_level is scaled by 0.25 */
+ switch (ana_max_level) {
+ case 6:
+ h_sbrNoiseFloorEstimate->ana_max_level = (FIXP_DBL)MAXVAL_DBL;
+ break;
+ case 3:
+ h_sbrNoiseFloorEstimate->ana_max_level = FL2FXCONST_DBL(0.5);
+ break;
+ case -3:
+ h_sbrNoiseFloorEstimate->ana_max_level = FL2FXCONST_DBL(0.125);
+ break;
+ default:
+ /* Should not enter here */
+ h_sbrNoiseFloorEstimate->ana_max_level = (FIXP_DBL)MAXVAL_DBL;
+ break;
+ }
+
+ /*
+ calculate number of noise bands and allocate
+ */
+ if (FDKsbrEnc_resetSbrNoiseFloorEstimate(h_sbrNoiseFloorEstimate,
+ freqBandTable, nSfb))
+ return (1);
+
+ if (noiseFloorOffset == 0) {
+ tmp = ((FIXP_DBL)MAXVAL_DBL) >> NOISE_FLOOR_OFFSET_SCALING;
+ } else {
+ /* noiseFloorOffset has to be smaller than 12, because
+ the result of the calculation below must be smaller than 1:
+ (2^(noiseFloorOffset/3))*2^4<1 */
+ FDK_ASSERT(noiseFloorOffset < 12);
+
+ /* Assumes the noise floor offset in tuning table are in q31 */
+ /* Change the qformat here when non-zero values would be filled */
+ exp = fDivNorm((FIXP_DBL)noiseFloorOffset, 3, &qexp);
+ tmp = fPow(2, DFRACT_BITS - 1, exp, qexp, &qtmp);
+ tmp = scaleValue(tmp, qtmp - NOISE_FLOOR_OFFSET_SCALING);
+ }
+
+ for (i = 0; i < h_sbrNoiseFloorEstimate->noNoiseBands; i++) {
+ h_sbrNoiseFloorEstimate->noiseFloorOffset[i] = tmp;
+ }
+
+ return (0);
+}
+
+/**************************************************************************/
+/*!
+ \brief Resets the current instance of the noise floor estiamtion
+ module.
+
+
+ \return errorCode, noError if successful
+
+*/
+/**************************************************************************/
+INT FDKsbrEnc_resetSbrNoiseFloorEstimate(
+ HANDLE_SBR_NOISE_FLOOR_ESTIMATE
+ h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
+ */
+ const UCHAR *freqBandTable, /*!< Frequency band table. */
+ INT nSfb /*!< Number of bands in the frequency band table. */
+) {
+ INT k2, kx;
+
+ /*
+ * Calculate number of noise bands
+ ***********************************/
+ k2 = freqBandTable[nSfb];
+ kx = freqBandTable[0];
+ if (h_sbrNoiseFloorEstimate->noiseBands == 0) {
+ h_sbrNoiseFloorEstimate->noNoiseBands = 1;
+ } else {
+ /*
+ * Calculate number of noise bands 1,2 or 3 bands/octave
+ ********************************************************/
+ FIXP_DBL tmp, ratio, lg2;
+ INT ratio_e, qlg2, nNoiseBands;
+
+ ratio = fDivNorm(k2, kx, &ratio_e);
+ lg2 = fLog2(ratio, ratio_e, &qlg2);
+ tmp = fMult((FIXP_DBL)(h_sbrNoiseFloorEstimate->noiseBands << 24), lg2);
+ tmp = scaleValue(tmp, qlg2 - 23);
+
+ nNoiseBands = (INT)((tmp + (FIXP_DBL)1) >> 1);
+
+ if (nNoiseBands > MAX_NUM_NOISE_COEFFS) {
+ nNoiseBands = MAX_NUM_NOISE_COEFFS;
+ }
+
+ if (nNoiseBands == 0) {
+ nNoiseBands = 1;
+ }
+
+ h_sbrNoiseFloorEstimate->noNoiseBands = nNoiseBands;
+ }
+
+ return (downSampleLoRes(h_sbrNoiseFloorEstimate->freqBandTableQmf,
+ h_sbrNoiseFloorEstimate->noNoiseBands, freqBandTable,
+ nSfb));
+}
+
+/**************************************************************************/
+/*!
+ \brief Deletes the current instancce of the noise floor level
+ estimation module.
+
+
+ \return none
+
+*/
+/**************************************************************************/
+void FDKsbrEnc_deleteSbrNoiseFloorEstimate(
+ HANDLE_SBR_NOISE_FLOOR_ESTIMATE
+ h_sbrNoiseFloorEstimate) /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
+ */
+{
+ if (h_sbrNoiseFloorEstimate) {
+ /*
+ nothing to do
+ */
+ }
+}
diff --git a/fdk-aac/libSBRenc/src/nf_est.h b/fdk-aac/libSBRenc/src/nf_est.h
new file mode 100644
index 0000000..c2f16e9
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/nf_est.h
@@ -0,0 +1,185 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Noise floor estimation structs and prototypes $Revision: 92790 $
+*/
+
+#ifndef NF_EST_H
+#define NF_EST_H
+
+#include "sbr_encoder.h"
+#include "fram_gen.h"
+
+#define NF_SMOOTHING_LENGTH 4 /*!< Smoothing length of the noise floors. */
+
+typedef struct {
+ FIXP_DBL
+ prevNoiseLevels[NF_SMOOTHING_LENGTH]
+ [MAX_NUM_NOISE_VALUES]; /*!< The previous noise levels. */
+ FIXP_DBL noiseFloorOffset
+ [MAX_NUM_NOISE_VALUES]; /*!< Noise floor offset, scaled with
+ NOISE_FLOOR_OFFSET_SCALING */
+ const FIXP_DBL *smoothFilter; /*!< Smoothing filter to use. */
+ FIXP_DBL ana_max_level; /*!< Max level allowed. */
+ FIXP_DBL weightFac; /*!< Weightening factor for the difference between orig
+ and sbr. */
+ INT freqBandTableQmf[MAX_NUM_NOISE_VALUES +
+ 1]; /*!< Frequncy band table for the noise floor bands.*/
+ INT noNoiseBands; /*!< Number of noisebands. */
+ INT noiseBands; /*!< NoiseBands switch 4 bit.*/
+ INT timeSlots; /*!< Number of timeslots in a frame. */
+ INVF_MODE diffThres; /*!< Threshold value to control the inverse filtering
+ decision */
+} SBR_NOISE_FLOOR_ESTIMATE;
+
+typedef SBR_NOISE_FLOOR_ESTIMATE *HANDLE_SBR_NOISE_FLOOR_ESTIMATE;
+
+void FDKsbrEnc_sbrNoiseFloorEstimateQmf(
+ HANDLE_SBR_NOISE_FLOOR_ESTIMATE
+ h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
+ */
+ const SBR_FRAME_INFO
+ *frame_info, /*!< Time frequency grid of the current frame. */
+ FIXP_DBL
+ *noiseLevels, /*!< Pointer to vector to store the noise levels in.*/
+ FIXP_DBL **quotaMatrixOrig, /*!< Matrix holding the quota values of the
+ original. */
+ SCHAR *indexVector, /*!< Index vector to obtain the patched data. */
+ INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component
+ will be missing. */
+ INT startIndex, /*!< Start index. */
+ UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per
+ frame. */
+ INT transientFrame, /*!< A flag indicating if a transient is present. */
+ INVF_MODE *pInvFiltLevels, /*!< Pointer to the vector holding the inverse
+ filtering levels. */
+ UINT sbrSyntaxFlags);
+
+INT FDKsbrEnc_InitSbrNoiseFloorEstimate(
+ HANDLE_SBR_NOISE_FLOOR_ESTIMATE
+ h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
+ */
+ INT ana_max_level, /*!< Maximum level of the adaptive noise. */
+ const UCHAR *freqBandTable, /*!< Frequany band table. */
+ INT nSfb, /*!< Number of frequency bands. */
+ INT noiseBands, /*!< Number of noise bands per octave. */
+ INT noiseFloorOffset, /*!< Noise floor offset. */
+ INT timeSlots, /*!< Number of time slots in a frame. */
+ UINT useSpeechConfig /*!< Flag: adapt tuning parameters according to speech
+ */
+);
+
+INT FDKsbrEnc_resetSbrNoiseFloorEstimate(
+ HANDLE_SBR_NOISE_FLOOR_ESTIMATE
+ h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
+ */
+ const UCHAR *freqBandTable, /*!< Frequany band table. */
+ INT nSfb); /*!< Number of bands in the frequency band table. */
+
+void FDKsbrEnc_deleteSbrNoiseFloorEstimate(
+ HANDLE_SBR_NOISE_FLOOR_ESTIMATE
+ h_sbrNoiseFloorEstimate); /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
+ */
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/ps_bitenc.cpp b/fdk-aac/libSBRenc/src/ps_bitenc.cpp
new file mode 100644
index 0000000..e30af2a
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/ps_bitenc.cpp
@@ -0,0 +1,624 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s): N. Rettelbach
+
+ Description: Parametric Stereo bitstream encoder
+
+*******************************************************************************/
+
+#include "ps_bitenc.h"
+
+#include "ps_main.h"
+
+static inline UCHAR FDKsbrEnc_WriteBits_ps(HANDLE_FDK_BITSTREAM hBitStream,
+ UINT value,
+ const UINT numberOfBits) {
+ /* hBitStream == NULL happens here intentionally */
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, value, numberOfBits);
+ }
+ return numberOfBits;
+}
+
+#define SI_SBR_EXTENSION_SIZE_BITS 4
+#define SI_SBR_EXTENSION_ESC_COUNT_BITS 8
+#define SI_SBR_EXTENSION_ID_BITS 2
+#define EXTENSION_ID_PS_CODING 2
+#define PS_EXT_ID_V0 0
+
+static const INT iidDeltaCoarse_Offset = 14;
+static const INT iidDeltaCoarse_MaxVal = 28;
+static const INT iidDeltaFine_Offset = 30;
+static const INT iidDeltaFine_MaxVal = 60;
+
+/* PS Stereo Huffmantable: iidDeltaFreqCoarse */
+static const UINT iidDeltaFreqCoarse_Length[] = {
+ 17, 17, 17, 17, 16, 15, 13, 10, 9, 7, 6, 5, 4, 3, 1,
+ 3, 4, 5, 6, 6, 8, 11, 13, 14, 14, 15, 17, 18, 18};
+static const UINT iidDeltaFreqCoarse_Code[] = {
+ 0x0001fffb, 0x0001fffc, 0x0001fffd, 0x0001fffa, 0x0000fffc, 0x00007ffc,
+ 0x00001ffd, 0x000003fe, 0x000001fe, 0x0000007e, 0x0000003c, 0x0000001d,
+ 0x0000000d, 0x00000005, 0000000000, 0x00000004, 0x0000000c, 0x0000001c,
+ 0x0000003d, 0x0000003e, 0x000000fe, 0x000007fe, 0x00001ffc, 0x00003ffc,
+ 0x00003ffd, 0x00007ffd, 0x0001fffe, 0x0003fffe, 0x0003ffff};
+
+/* PS Stereo Huffmantable: iidDeltaFreqFine */
+static const UINT iidDeltaFreqFine_Length[] = {
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 17, 17, 16, 16, 15,
+ 14, 14, 13, 12, 12, 11, 10, 10, 8, 7, 6, 5, 4, 3, 1, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 16,
+ 17, 17, 18, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18};
+static const UINT iidDeltaFreqFine_Code[] = {
+ 0x0001feb4, 0x0001feb5, 0x0001fd76, 0x0001fd77, 0x0001fd74, 0x0001fd75,
+ 0x0001fe8a, 0x0001fe8b, 0x0001fe88, 0x0000fe80, 0x0001feb6, 0x0000fe82,
+ 0x0000feb8, 0x00007f42, 0x00007fae, 0x00003faf, 0x00001fd1, 0x00001fe9,
+ 0x00000fe9, 0x000007ea, 0x000007fb, 0x000003fb, 0x000001fb, 0x000001ff,
+ 0x0000007c, 0x0000003c, 0x0000001c, 0x0000000c, 0000000000, 0x00000001,
+ 0x00000001, 0x00000002, 0x00000001, 0x0000000d, 0x0000001d, 0x0000003d,
+ 0x0000007d, 0x000000fc, 0x000001fc, 0x000003fc, 0x000003f4, 0x000007eb,
+ 0x00000fea, 0x00001fea, 0x00001fd6, 0x00003fd0, 0x00007faf, 0x00007f43,
+ 0x0000feb9, 0x0000fe83, 0x0001feb7, 0x0000fe81, 0x0001fe89, 0x0001fe8e,
+ 0x0001fe8f, 0x0001fe8c, 0x0001fe8d, 0x0001feb2, 0x0001feb3, 0x0001feb0,
+ 0x0001feb1};
+
+/* PS Stereo Huffmantable: iidDeltaTimeCoarse */
+static const UINT iidDeltaTimeCoarse_Length[] = {
+ 19, 19, 19, 20, 20, 20, 17, 15, 12, 10, 8, 6, 4, 2, 1,
+ 3, 5, 7, 9, 11, 13, 14, 17, 19, 20, 20, 20, 20, 20};
+static const UINT iidDeltaTimeCoarse_Code[] = {
+ 0x0007fff9, 0x0007fffa, 0x0007fffb, 0x000ffff8, 0x000ffff9, 0x000ffffa,
+ 0x0001fffd, 0x00007ffe, 0x00000ffe, 0x000003fe, 0x000000fe, 0x0000003e,
+ 0x0000000e, 0x00000002, 0000000000, 0x00000006, 0x0000001e, 0x0000007e,
+ 0x000001fe, 0x000007fe, 0x00001ffe, 0x00003ffe, 0x0001fffc, 0x0007fff8,
+ 0x000ffffb, 0x000ffffc, 0x000ffffd, 0x000ffffe, 0x000fffff};
+
+/* PS Stereo Huffmantable: iidDeltaTimeFine */
+static const UINT iidDeltaTimeFine_Length[] = {
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14,
+ 14, 13, 13, 13, 12, 12, 11, 10, 9, 9, 7, 6, 5, 3, 1, 2,
+ 5, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15,
+ 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
+static const UINT iidDeltaTimeFine_Code[] = {
+ 0x00004ed4, 0x00004ed5, 0x00004ece, 0x00004ecf, 0x00004ecc, 0x00004ed6,
+ 0x00004ed8, 0x00004f46, 0x00004f60, 0x00002718, 0x00002719, 0x00002764,
+ 0x00002765, 0x0000276d, 0x000027b1, 0x000013b7, 0x000013d6, 0x000009c7,
+ 0x000009e9, 0x000009ed, 0x000004ee, 0x000004f7, 0x00000278, 0x00000139,
+ 0x0000009a, 0x0000009f, 0x00000020, 0x00000011, 0x0000000a, 0x00000003,
+ 0x00000001, 0000000000, 0x0000000b, 0x00000012, 0x00000021, 0x0000004c,
+ 0x0000009b, 0x0000013a, 0x00000279, 0x00000270, 0x000004ef, 0x000004e2,
+ 0x000009ea, 0x000009d8, 0x000013d7, 0x000013d0, 0x000027b2, 0x000027a2,
+ 0x0000271a, 0x0000271b, 0x00004f66, 0x00004f67, 0x00004f61, 0x00004f47,
+ 0x00004ed9, 0x00004ed7, 0x00004ecd, 0x00004ed2, 0x00004ed3, 0x00004ed0,
+ 0x00004ed1};
+
+static const INT iccDelta_Offset = 7;
+static const INT iccDelta_MaxVal = 14;
+/* PS Stereo Huffmantable: iccDeltaFreq */
+static const UINT iccDeltaFreq_Length[] = {14, 14, 12, 10, 7, 5, 3, 1,
+ 2, 4, 6, 8, 9, 11, 13};
+static const UINT iccDeltaFreq_Code[] = {
+ 0x00003fff, 0x00003ffe, 0x00000ffe, 0x000003fe, 0x0000007e,
+ 0x0000001e, 0x00000006, 0000000000, 0x00000002, 0x0000000e,
+ 0x0000003e, 0x000000fe, 0x000001fe, 0x000007fe, 0x00001ffe};
+
+/* PS Stereo Huffmantable: iccDeltaTime */
+static const UINT iccDeltaTime_Length[] = {14, 13, 11, 9, 7, 5, 3, 1,
+ 2, 4, 6, 8, 10, 12, 14};
+static const UINT iccDeltaTime_Code[] = {
+ 0x00003ffe, 0x00001ffe, 0x000007fe, 0x000001fe, 0x0000007e,
+ 0x0000001e, 0x00000006, 0000000000, 0x00000002, 0x0000000e,
+ 0x0000003e, 0x000000fe, 0x000003fe, 0x00000ffe, 0x00003fff};
+
+static const INT ipdDelta_Offset = 0;
+static const INT ipdDelta_MaxVal = 7;
+/* PS Stereo Huffmantable: ipdDeltaFreq */
+static const UINT ipdDeltaFreq_Length[] = {1, 3, 4, 4, 4, 4, 4, 4};
+static const UINT ipdDeltaFreq_Code[] = {0x00000001, 0000000000, 0x00000006,
+ 0x00000004, 0x00000002, 0x00000003,
+ 0x00000005, 0x00000007};
+
+/* PS Stereo Huffmantable: ipdDeltaTime */
+static const UINT ipdDeltaTime_Length[] = {1, 3, 4, 5, 5, 4, 4, 3};
+static const UINT ipdDeltaTime_Code[] = {0x00000001, 0x00000002, 0x00000002,
+ 0x00000003, 0x00000002, 0000000000,
+ 0x00000003, 0x00000003};
+
+static const INT opdDelta_Offset = 0;
+static const INT opdDelta_MaxVal = 7;
+/* PS Stereo Huffmantable: opdDeltaFreq */
+static const UINT opdDeltaFreq_Length[] = {1, 3, 4, 4, 5, 5, 4, 3};
+static const UINT opdDeltaFreq_Code[] = {
+ 0x00000001, 0x00000001, 0x00000006, 0x00000004,
+ 0x0000000f, 0x0000000e, 0x00000005, 0000000000,
+};
+
+/* PS Stereo Huffmantable: opdDeltaTime */
+static const UINT opdDeltaTime_Length[] = {1, 3, 4, 5, 5, 4, 4, 3};
+static const UINT opdDeltaTime_Code[] = {0x00000001, 0x00000002, 0x00000001,
+ 0x00000007, 0x00000006, 0000000000,
+ 0x00000002, 0x00000003};
+
+static INT getNoBands(const INT mode) {
+ INT noBands = 0;
+
+ switch (mode) {
+ case 0:
+ case 3: /* coarse */
+ noBands = PS_BANDS_COARSE;
+ 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;
+ }
+
+ return noBands;
+}
+
+static INT getIIDRes(INT iidMode) {
+ if (iidMode < 3)
+ return PS_IID_RES_COARSE;
+ else
+ return PS_IID_RES_FINE;
+}
+
+static INT encodeDeltaFreq(HANDLE_FDK_BITSTREAM hBitBuf, const INT *val,
+ const INT nBands, const UINT *codeTable,
+ const UINT *lengthTable, const INT tableOffset,
+ const INT maxVal, INT *error) {
+ INT bitCnt = 0;
+ INT lastVal = 0;
+ INT band;
+
+ for (band = 0; band < nBands; band++) {
+ INT delta = (val[band] - lastVal) + tableOffset;
+ lastVal = val[band];
+ if ((delta > maxVal) || (delta < 0)) {
+ *error = 1;
+ delta = delta > 0 ? maxVal : 0;
+ }
+ bitCnt +=
+ FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]);
+ }
+
+ return bitCnt;
+}
+
+static INT encodeDeltaTime(HANDLE_FDK_BITSTREAM hBitBuf, const INT *val,
+ const INT *valLast, const INT nBands,
+ const UINT *codeTable, const UINT *lengthTable,
+ const INT tableOffset, const INT maxVal,
+ INT *error) {
+ INT bitCnt = 0;
+ INT band;
+
+ for (band = 0; band < nBands; band++) {
+ INT delta = (val[band] - valLast[band]) + tableOffset;
+ if ((delta > maxVal) || (delta < 0)) {
+ *error = 1;
+ delta = delta > 0 ? maxVal : 0;
+ }
+ bitCnt +=
+ FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]);
+ }
+
+ return bitCnt;
+}
+
+INT FDKsbrEnc_EncodeIid(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iidVal,
+ const INT *iidValLast, const INT nBands,
+ const PS_IID_RESOLUTION res, const PS_DELTA mode,
+ INT *error) {
+ const UINT *codeTable;
+ const UINT *lengthTable;
+ INT bitCnt = 0;
+
+ bitCnt = 0;
+
+ switch (mode) {
+ case PS_DELTA_FREQ:
+ switch (res) {
+ case PS_IID_RES_COARSE:
+ codeTable = iidDeltaFreqCoarse_Code;
+ lengthTable = iidDeltaFreqCoarse_Length;
+ bitCnt += encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable,
+ lengthTable, iidDeltaCoarse_Offset,
+ iidDeltaCoarse_MaxVal, error);
+ break;
+ case PS_IID_RES_FINE:
+ codeTable = iidDeltaFreqFine_Code;
+ lengthTable = iidDeltaFreqFine_Length;
+ bitCnt +=
+ encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable, lengthTable,
+ iidDeltaFine_Offset, iidDeltaFine_MaxVal, error);
+ break;
+ default:
+ *error = 1;
+ }
+ break;
+
+ case PS_DELTA_TIME:
+ switch (res) {
+ case PS_IID_RES_COARSE:
+ codeTable = iidDeltaTimeCoarse_Code;
+ lengthTable = iidDeltaTimeCoarse_Length;
+ bitCnt += encodeDeltaTime(
+ hBitBuf, iidVal, iidValLast, nBands, codeTable, lengthTable,
+ iidDeltaCoarse_Offset, iidDeltaCoarse_MaxVal, error);
+ break;
+ case PS_IID_RES_FINE:
+ codeTable = iidDeltaTimeFine_Code;
+ lengthTable = iidDeltaTimeFine_Length;
+ bitCnt += encodeDeltaTime(hBitBuf, iidVal, iidValLast, nBands,
+ codeTable, lengthTable, iidDeltaFine_Offset,
+ iidDeltaFine_MaxVal, error);
+ break;
+ default:
+ *error = 1;
+ }
+ break;
+
+ default:
+ *error = 1;
+ }
+
+ return bitCnt;
+}
+
+INT FDKsbrEnc_EncodeIcc(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iccVal,
+ const INT *iccValLast, const INT nBands,
+ const PS_DELTA mode, INT *error) {
+ const UINT *codeTable;
+ const UINT *lengthTable;
+ INT bitCnt = 0;
+
+ switch (mode) {
+ case PS_DELTA_FREQ:
+ codeTable = iccDeltaFreq_Code;
+ lengthTable = iccDeltaFreq_Length;
+ bitCnt += encodeDeltaFreq(hBitBuf, iccVal, nBands, codeTable, lengthTable,
+ iccDelta_Offset, iccDelta_MaxVal, error);
+ break;
+
+ case PS_DELTA_TIME:
+ codeTable = iccDeltaTime_Code;
+ lengthTable = iccDeltaTime_Length;
+
+ bitCnt +=
+ encodeDeltaTime(hBitBuf, iccVal, iccValLast, nBands, codeTable,
+ lengthTable, iccDelta_Offset, iccDelta_MaxVal, error);
+ break;
+
+ default:
+ *error = 1;
+ }
+
+ return bitCnt;
+}
+
+INT FDKsbrEnc_EncodeIpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *ipdVal,
+ const INT *ipdValLast, const INT nBands,
+ const PS_DELTA mode, INT *error) {
+ const UINT *codeTable;
+ const UINT *lengthTable;
+ INT bitCnt = 0;
+
+ switch (mode) {
+ case PS_DELTA_FREQ:
+ codeTable = ipdDeltaFreq_Code;
+ lengthTable = ipdDeltaFreq_Length;
+ bitCnt += encodeDeltaFreq(hBitBuf, ipdVal, nBands, codeTable, lengthTable,
+ ipdDelta_Offset, ipdDelta_MaxVal, error);
+ break;
+
+ case PS_DELTA_TIME:
+ codeTable = ipdDeltaTime_Code;
+ lengthTable = ipdDeltaTime_Length;
+
+ bitCnt +=
+ encodeDeltaTime(hBitBuf, ipdVal, ipdValLast, nBands, codeTable,
+ lengthTable, ipdDelta_Offset, ipdDelta_MaxVal, error);
+ break;
+
+ default:
+ *error = 1;
+ }
+
+ return bitCnt;
+}
+
+INT FDKsbrEnc_EncodeOpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *opdVal,
+ const INT *opdValLast, const INT nBands,
+ const PS_DELTA mode, INT *error) {
+ const UINT *codeTable;
+ const UINT *lengthTable;
+ INT bitCnt = 0;
+
+ switch (mode) {
+ case PS_DELTA_FREQ:
+ codeTable = opdDeltaFreq_Code;
+ lengthTable = opdDeltaFreq_Length;
+ bitCnt += encodeDeltaFreq(hBitBuf, opdVal, nBands, codeTable, lengthTable,
+ opdDelta_Offset, opdDelta_MaxVal, error);
+ break;
+
+ case PS_DELTA_TIME:
+ codeTable = opdDeltaTime_Code;
+ lengthTable = opdDeltaTime_Length;
+
+ bitCnt +=
+ encodeDeltaTime(hBitBuf, opdVal, opdValLast, nBands, codeTable,
+ lengthTable, opdDelta_Offset, opdDelta_MaxVal, error);
+ break;
+
+ default:
+ *error = 1;
+ }
+
+ return bitCnt;
+}
+
+static INT encodeIpdOpd(HANDLE_PS_OUT psOut, HANDLE_FDK_BITSTREAM hBitBuf) {
+ INT bitCnt = 0;
+ INT error = 0;
+ INT env;
+
+ FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIpdOpd, 1);
+
+ if (psOut->enableIpdOpd == 1) {
+ INT *ipdLast = psOut->ipdLast;
+ INT *opdLast = psOut->opdLast;
+
+ for (env = 0; env < psOut->nEnvelopes; env++) {
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaIPD[env], 1);
+ bitCnt += FDKsbrEnc_EncodeIpd(hBitBuf, psOut->ipd[env], ipdLast,
+ getNoBands(psOut->iidMode),
+ psOut->deltaIPD[env], &error);
+
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaOPD[env], 1);
+ bitCnt += FDKsbrEnc_EncodeOpd(hBitBuf, psOut->opd[env], opdLast,
+ getNoBands(psOut->iidMode),
+ psOut->deltaOPD[env], &error);
+ }
+ /* reserved bit */
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, 1);
+ }
+
+ return bitCnt;
+}
+
+static INT getEnvIdx(const INT nEnvelopes, const INT frameClass) {
+ INT envIdx = 0;
+
+ switch (nEnvelopes) {
+ case 0:
+ envIdx = 0;
+ break;
+
+ case 1:
+ if (frameClass == 0)
+ envIdx = 1;
+ else
+ envIdx = 0;
+ break;
+
+ case 2:
+ if (frameClass == 0)
+ envIdx = 2;
+ else
+ envIdx = 1;
+ break;
+
+ case 3:
+ envIdx = 2;
+ break;
+
+ case 4:
+ envIdx = 3;
+ break;
+
+ default:
+ /* unsupported number of envelopes */
+ envIdx = 0;
+ }
+
+ return envIdx;
+}
+
+static INT encodePSExtension(const HANDLE_PS_OUT psOut,
+ HANDLE_FDK_BITSTREAM hBitBuf) {
+ INT bitCnt = 0;
+
+ if (psOut->enableIpdOpd == 1) {
+ INT ipdOpdBits = 0;
+ INT extSize = (2 + encodeIpdOpd(psOut, NULL) + 7) >> 3;
+
+ if (extSize < 15) {
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, extSize, 4);
+ } else {
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, 15, 4);
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, (extSize - 15), 8);
+ }
+
+ /* write ipd opd data */
+ ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, PS_EXT_ID_V0, 2);
+ ipdOpdBits += encodeIpdOpd(psOut, hBitBuf);
+
+ /* byte align the ipd opd data */
+ if (ipdOpdBits % 8)
+ ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, (8 - (ipdOpdBits % 8)));
+
+ bitCnt += ipdOpdBits;
+ }
+
+ return (bitCnt);
+}
+
+INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut,
+ HANDLE_FDK_BITSTREAM hBitBuf) {
+ INT psExtEnable = 0;
+ INT bitCnt = 0;
+ INT error = 0;
+ INT env;
+
+ if (psOut != NULL) {
+ /* PS HEADER */
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enablePSHeader, 1);
+
+ if (psOut->enablePSHeader) {
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIID, 1);
+ if (psOut->enableIID) {
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->iidMode, 3);
+ }
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableICC, 1);
+ if (psOut->enableICC) {
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->iccMode, 3);
+ }
+ if (psOut->enableIpdOpd) {
+ psExtEnable = 1;
+ }
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psExtEnable, 1);
+ }
+
+ /* Frame class, number of envelopes */
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->frameClass, 1);
+ bitCnt += FDKsbrEnc_WriteBits_ps(
+ hBitBuf, getEnvIdx(psOut->nEnvelopes, psOut->frameClass), 2);
+
+ if (psOut->frameClass == 1) {
+ for (env = 0; env < psOut->nEnvelopes; env++) {
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->frameBorder[env], 5);
+ }
+ }
+
+ if (psOut->enableIID == 1) {
+ INT *iidLast = psOut->iidLast;
+ for (env = 0; env < psOut->nEnvelopes; env++) {
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaIID[env], 1);
+ bitCnt += FDKsbrEnc_EncodeIid(
+ hBitBuf, psOut->iid[env], iidLast, getNoBands(psOut->iidMode),
+ (PS_IID_RESOLUTION)getIIDRes(psOut->iidMode), psOut->deltaIID[env],
+ &error);
+
+ iidLast = psOut->iid[env];
+ }
+ }
+
+ if (psOut->enableICC == 1) {
+ INT *iccLast = psOut->iccLast;
+ for (env = 0; env < psOut->nEnvelopes; env++) {
+ bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaICC[env], 1);
+ bitCnt += FDKsbrEnc_EncodeIcc(hBitBuf, psOut->icc[env], iccLast,
+ getNoBands(psOut->iccMode),
+ psOut->deltaICC[env], &error);
+
+ iccLast = psOut->icc[env];
+ }
+ }
+
+ if (psExtEnable != 0) {
+ bitCnt += encodePSExtension(psOut, hBitBuf);
+ }
+
+ } /* if(psOut != NULL) */
+
+ return bitCnt;
+}
diff --git a/fdk-aac/libSBRenc/src/ps_bitenc.h b/fdk-aac/libSBRenc/src/ps_bitenc.h
new file mode 100644
index 0000000..1d383e3
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/ps_bitenc.h
@@ -0,0 +1,173 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s): N. Rettelbach
+
+ Description: Parametric Stereo bitstream encoder
+
+*******************************************************************************/
+
+#include "ps_main.h"
+#include "ps_const.h"
+#include "FDK_bitstream.h"
+
+#ifndef PS_BITENC_H
+#define PS_BITENC_H
+
+typedef struct T_PS_OUT {
+ INT enablePSHeader;
+ INT enableIID;
+ INT iidMode;
+ INT enableICC;
+ INT iccMode;
+ INT enableIpdOpd;
+
+ INT frameClass;
+ INT nEnvelopes;
+ /* ENV data */
+ INT frameBorder[PS_MAX_ENVELOPES];
+
+ /* iid data */
+ PS_DELTA deltaIID[PS_MAX_ENVELOPES];
+ INT iid[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ INT iidLast[PS_MAX_BANDS];
+
+ /* icc data */
+ PS_DELTA deltaICC[PS_MAX_ENVELOPES];
+ INT icc[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ INT iccLast[PS_MAX_BANDS];
+
+ /* ipd data */
+ PS_DELTA deltaIPD[PS_MAX_ENVELOPES];
+ INT ipd[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ INT ipdLast[PS_MAX_BANDS];
+
+ /* opd data */
+ PS_DELTA deltaOPD[PS_MAX_ENVELOPES];
+ INT opd[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ INT opdLast[PS_MAX_BANDS];
+
+} PS_OUT, *HANDLE_PS_OUT;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+INT FDKsbrEnc_EncodeIid(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iidVal,
+ const INT *iidValLast, const INT nBands,
+ const PS_IID_RESOLUTION res, const PS_DELTA mode,
+ INT *error);
+
+INT FDKsbrEnc_EncodeIcc(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iccVal,
+ const INT *iccValLast, const INT nBands,
+ const PS_DELTA mode, INT *error);
+
+INT FDKsbrEnc_EncodeIpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *ipdVal,
+ const INT *ipdValLast, const INT nBands,
+ const PS_DELTA mode, INT *error);
+
+INT FDKsbrEnc_EncodeOpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *opdVal,
+ const INT *opdValLast, const INT nBands,
+ const PS_DELTA mode, INT *error);
+
+INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut,
+ HANDLE_FDK_BITSTREAM hBitBuf);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* defined(PSENC_ENABLE) */
diff --git a/fdk-aac/libSBRenc/src/ps_const.h b/fdk-aac/libSBRenc/src/ps_const.h
new file mode 100644
index 0000000..b9a33f9
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/ps_const.h
@@ -0,0 +1,150 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s): N. Rettelbach
+
+ Description: Parametric Stereo constants
+
+*******************************************************************************/
+
+#ifndef PS_CONST_H
+#define PS_CONST_H
+
+#define MAX_PS_CHANNELS (2)
+#define HYBRID_MAX_QMF_BANDS (3)
+#define HYBRID_FILTER_LENGTH (13)
+#define HYBRID_FILTER_DELAY ((HYBRID_FILTER_LENGTH - 1) / 2)
+
+#define HYBRID_FRAMESIZE (32)
+#define HYBRID_READ_OFFSET (10)
+
+#define MAX_HYBRID_BANDS ((64 - HYBRID_MAX_QMF_BANDS + 10))
+
+typedef enum {
+ PS_RES_COARSE = 0,
+ PS_RES_MID = 1,
+ PS_RES_FINE = 2
+} PS_RESOLUTION;
+
+typedef enum {
+ PS_BANDS_COARSE = 10,
+ PS_BANDS_MID = 20,
+ PS_MAX_BANDS = PS_BANDS_MID
+} PS_BANDS;
+
+typedef enum { PS_IID_RES_COARSE = 0, PS_IID_RES_FINE } PS_IID_RESOLUTION;
+
+typedef enum { PS_ICC_ROT_A = 0, PS_ICC_ROT_B } PS_ICC_ROTATION_MODE;
+
+typedef enum { PS_DELTA_FREQ, PS_DELTA_TIME } PS_DELTA;
+
+typedef enum {
+ PS_MAX_ENVELOPES = 4
+
+} PS_CONSTS;
+
+typedef enum {
+ PSENC_OK = 0x0000, /*!< No error happened. All fine. */
+ PSENC_INVALID_HANDLE =
+ 0x0020, /*!< Handle passed to function call was invalid. */
+ PSENC_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */
+ PSENC_INIT_ERROR = 0x0040, /*!< General initialization error. */
+ PSENC_ENCODE_ERROR = 0x0060 /*!< The encoding process was interrupted by an
+ unexpected error. */
+
+} FDK_PSENC_ERROR;
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/ps_encode.cpp b/fdk-aac/libSBRenc/src/ps_encode.cpp
new file mode 100644
index 0000000..88d3131
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/ps_encode.cpp
@@ -0,0 +1,1031 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s): M. Neuendorf, N. Rettelbach, M. Multrus
+
+ Description: PS parameter extraction, encoding
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief PS parameter extraction, encoding functions $Revision: 96441 $
+*/
+
+#include "ps_main.h"
+#include "ps_encode.h"
+#include "qmf.h"
+#include "sbr_misc.h"
+#include "sbrenc_ram.h"
+
+#include "genericStds.h"
+
+inline void FDKsbrEnc_addFIXP_DBL(const FIXP_DBL *X, const FIXP_DBL *Y,
+ FIXP_DBL *Z, INT n) {
+ for (INT i = 0; i < n; i++) Z[i] = (X[i] >> 1) + (Y[i] >> 1);
+}
+
+#define LOG10_2_10 3.01029995664f /* 10.0f*log10(2.f) */
+
+static const INT
+ iidGroupBordersLoRes[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES + 1] = {
+ 0, 1, 2, 3, 4, 5, /* 6 subqmf subbands - 0th qmf subband */
+ 6, 7, /* 2 subqmf subbands - 1st qmf subband */
+ 8, 9, /* 2 subqmf subbands - 2nd qmf subband */
+ 10, 11, 12, 13, 14, 15, 16, 18, 21, 25, 30, 42, 71};
+
+static const UCHAR
+ iidGroupWidthLdLoRes[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 4, 5};
+
+static const INT subband2parameter20[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES] =
+ {1, 0, 0, 1, 2, 3, /* 6 subqmf subbands - 0th qmf subband */
+ 4, 5, /* 2 subqmf subbands - 1st qmf subband */
+ 6, 7, /* 2 subqmf subbands - 2nd qmf subband */
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
+
+typedef enum {
+ MAX_TIME_DIFF_FRAMES = 20,
+ MAX_PS_NOHEADER_CNT = 10,
+ MAX_NOENV_CNT = 10,
+ DO_NOT_USE_THIS_MODE = 0x7FFFFF
+} __PS_CONSTANTS;
+
+static const FIXP_DBL iidQuant_fx[15] = {
+ (FIXP_DBL)0xce000000, (FIXP_DBL)0xdc000000, (FIXP_DBL)0xe4000000,
+ (FIXP_DBL)0xec000000, (FIXP_DBL)0xf2000000, (FIXP_DBL)0xf8000000,
+ (FIXP_DBL)0xfc000000, (FIXP_DBL)0x00000000, (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] = {
+ (FIXP_DBL)0x9c000001, (FIXP_DBL)0xa6000001, (FIXP_DBL)0xb0000001,
+ (FIXP_DBL)0xba000001, (FIXP_DBL)0xc4000000, (FIXP_DBL)0xce000000,
+ (FIXP_DBL)0xd4000000, (FIXP_DBL)0xda000000, (FIXP_DBL)0xe0000000,
+ (FIXP_DBL)0xe6000000, (FIXP_DBL)0xec000000, (FIXP_DBL)0xf0000000,
+ (FIXP_DBL)0xf4000000, (FIXP_DBL)0xf8000000, (FIXP_DBL)0xfc000000,
+ (FIXP_DBL)0x00000000, (FIXP_DBL)0x04000000, (FIXP_DBL)0x08000000,
+ (FIXP_DBL)0x0c000000, (FIXP_DBL)0x10000000, (FIXP_DBL)0x14000000,
+ (FIXP_DBL)0x1a000000, (FIXP_DBL)0x20000000, (FIXP_DBL)0x26000000,
+ (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] = {
+ (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(HANDLE_PS_DATA hPsData) {
+ FDK_PSENC_ERROR error = PSENC_OK;
+
+ if (hPsData == NULL) {
+ error = PSENC_INVALID_HANDLE;
+ } else {
+ int i, env;
+ FDKmemclear(hPsData, sizeof(PS_DATA));
+
+ for (i = 0; i < PS_MAX_BANDS; i++) {
+ hPsData->iidIdxLast[i] = 0;
+ hPsData->iccIdxLast[i] = 0;
+ }
+
+ hPsData->iidEnable = hPsData->iidEnableLast = 0;
+ hPsData->iccEnable = hPsData->iccEnableLast = 0;
+ hPsData->iidQuantMode = hPsData->iidQuantModeLast = PS_IID_RES_COARSE;
+ hPsData->iccQuantMode = hPsData->iccQuantModeLast = PS_ICC_ROT_A;
+
+ for (env = 0; env < PS_MAX_ENVELOPES; env++) {
+ hPsData->iccDiffMode[env] = PS_DELTA_FREQ;
+ hPsData->iccDiffMode[env] = PS_DELTA_FREQ;
+
+ for (i = 0; i < PS_MAX_BANDS; i++) {
+ hPsData->iidIdx[env][i] = 0;
+ hPsData->iccIdx[env][i] = 0;
+ }
+ }
+
+ hPsData->nEnvelopesLast = 0;
+
+ hPsData->headerCnt = MAX_PS_NOHEADER_CNT;
+ hPsData->iidTimeCnt = MAX_TIME_DIFF_FRAMES;
+ hPsData->iccTimeCnt = MAX_TIME_DIFF_FRAMES;
+ hPsData->noEnvCnt = MAX_NOENV_CNT;
+ }
+
+ return error;
+}
+
+static FIXP_DBL quantizeCoef(const FIXP_DBL *RESTRICT input, const INT nBands,
+ const FIXP_DBL *RESTRICT quantTable,
+ const INT idxOffset, const INT nQuantSteps,
+ INT *RESTRICT quantOut) {
+ INT idx, band;
+ FIXP_DBL quantErr = FL2FXCONST_DBL(0.f);
+
+ for (band = 0; band < nBands; band++) {
+ for (idx = 0; idx < nQuantSteps - 1; idx++) {
+ if (fixp_abs((input[band] >> 1) - (quantTable[idx + 1] >> 1)) >
+ fixp_abs((input[band] >> 1) - (quantTable[idx] >> 1))) {
+ break;
+ }
+ }
+ quantErr += (fixp_abs(input[band] - quantTable[idx]) >>
+ PS_QUANT_SCALE); /* don't scale before subtraction; diff
+ smaller (64-25)/64 */
+ quantOut[band] = idx - idxOffset;
+ }
+
+ return quantErr;
+}
+
+static INT getICCMode(const INT nBands, const INT rotType) {
+ INT mode = 0;
+
+ switch (nBands) {
+ case PS_BANDS_COARSE:
+ mode = PS_RES_COARSE;
+ break;
+ case PS_BANDS_MID:
+ mode = PS_RES_MID;
+ break;
+ default:
+ mode = 0;
+ }
+ if (rotType == PS_ICC_ROT_B) {
+ mode += 3;
+ }
+
+ return mode;
+}
+
+static INT getIIDMode(const INT nBands, const INT iidRes) {
+ INT mode = 0;
+
+ switch (nBands) {
+ case PS_BANDS_COARSE:
+ mode = PS_RES_COARSE;
+ break;
+ case PS_BANDS_MID:
+ mode = PS_RES_MID;
+ break;
+ default:
+ mode = 0;
+ break;
+ }
+
+ if (iidRes == PS_IID_RES_FINE) {
+ mode += 3;
+ }
+
+ return mode;
+}
+
+static INT envelopeReducible(FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],
+ FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS],
+ INT psBands, INT nEnvelopes) {
+#define THRESH_SCALE 7
+
+ INT reducible = 1; /* true */
+ INT e = 0, b = 0;
+ FIXP_DBL dIid = FL2FXCONST_DBL(0.f);
+ FIXP_DBL dIcc = FL2FXCONST_DBL(0.f);
+
+ FIXP_DBL iidErrThreshold, iccErrThreshold;
+ FIXP_DBL iidMeanError, iccMeanError;
+
+ /* square values to prevent sqrt,
+ multiply bands to prevent division; bands shifted DFRACT_BITS instead
+ (DFRACT_BITS-1) because fMultDiv2 used*/
+ iidErrThreshold =
+ fMultDiv2(FL2FXCONST_DBL(6.5f * 6.5f / (IID_SCALE_FT * IID_SCALE_FT)),
+ (FIXP_DBL)(psBands << ((DFRACT_BITS)-THRESH_SCALE)));
+ iccErrThreshold =
+ fMultDiv2(FL2FXCONST_DBL(0.75f * 0.75f),
+ (FIXP_DBL)(psBands << ((DFRACT_BITS)-THRESH_SCALE)));
+
+ if (nEnvelopes <= 1) {
+ reducible = 0;
+ } else {
+ /* mean error criterion */
+ for (e = 0; (e < nEnvelopes / 2) && (reducible != 0); e++) {
+ iidMeanError = iccMeanError = FL2FXCONST_DBL(0.f);
+ for (b = 0; b < psBands; b++) {
+ dIid = (iid[2 * e][b] >> 1) -
+ (iid[2 * e + 1][b] >> 1); /* scale 1 bit; squared -> 2 bit */
+ dIcc = (icc[2 * e][b] >> 1) - (icc[2 * e + 1][b] >> 1);
+ iidMeanError += fPow2Div2(dIid) >> (5 - 1); /* + (bands=20) scale = 5 */
+ iccMeanError += fPow2Div2(dIcc) >> (5 - 1);
+ } /* --> scaling = 7 bit = THRESH_SCALE !! */
+
+ /* instead sqrt values are squared!
+ instead of division, multiply threshold with psBands
+ scaling necessary!! */
+
+ /* quit as soon as threshold is reached */
+ if ((iidMeanError > (iidErrThreshold)) ||
+ (iccMeanError > (iccErrThreshold))) {
+ reducible = 0;
+ }
+ }
+ } /* nEnvelopes != 1 */
+
+ return reducible;
+}
+
+static void processIidData(PS_DATA *psData,
+ FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],
+ const INT psBands, const INT nEnvelopes,
+ const FIXP_DBL quantErrorThreshold) {
+ INT iidIdxFine[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ INT iidIdxCoarse[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+
+ FIXP_DBL errIID = FL2FXCONST_DBL(0.f);
+ FIXP_DBL errIIDFine = FL2FXCONST_DBL(0.f);
+ INT bitsIidFreq = 0;
+ INT bitsIidTime = 0;
+ INT bitsFineTot = 0;
+ INT bitsCoarseTot = 0;
+ INT error = 0;
+ INT env, band;
+ INT diffMode[PS_MAX_ENVELOPES], diffModeFine[PS_MAX_ENVELOPES];
+ INT loudnDiff = 0;
+ INT iidTransmit = 0;
+
+ /* Quantize IID coefficients */
+ for (env = 0; env < nEnvelopes; env++) {
+ errIID +=
+ quantizeCoef(iid[env], psBands, iidQuant_fx, 7, 15, iidIdxCoarse[env]);
+ errIIDFine += quantizeCoef(iid[env], psBands, iidQuantFine_fx, 15, 31,
+ iidIdxFine[env]);
+ }
+
+ /* normalize error to number of envelopes, ps bands
+ errIID /= psBands*nEnvelopes;
+ errIIDFine /= psBands*nEnvelopes; */
+
+ /* Check if IID coefficients should be used in this frame */
+ psData->iidEnable = 0;
+ for (env = 0; env < nEnvelopes; env++) {
+ for (band = 0; band < psBands; band++) {
+ loudnDiff += fixp_abs(iidIdxCoarse[env][band]);
+ iidTransmit++;
+ }
+ }
+
+ if (loudnDiff >
+ fMultI(FL2FXCONST_DBL(0.7f), iidTransmit)) { /* 0.7f empiric value */
+ psData->iidEnable = 1;
+ }
+
+ /* if iid not active -> RESET data */
+ if (psData->iidEnable == 0) {
+ psData->iidTimeCnt = MAX_TIME_DIFF_FRAMES;
+ for (env = 0; env < nEnvelopes; env++) {
+ psData->iidDiffMode[env] = PS_DELTA_FREQ;
+ FDKmemclear(psData->iidIdx[env], sizeof(INT) * psBands);
+ }
+ return;
+ }
+
+ /* count COARSE quantization bits for first envelope*/
+ bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[0], NULL, psBands,
+ PS_IID_RES_COARSE, PS_DELTA_FREQ, &error);
+
+ if ((psData->iidTimeCnt >= MAX_TIME_DIFF_FRAMES) ||
+ (psData->iidQuantModeLast == PS_IID_RES_FINE)) {
+ bitsIidTime = DO_NOT_USE_THIS_MODE;
+ } else {
+ bitsIidTime =
+ FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[0], psData->iidIdxLast, psBands,
+ PS_IID_RES_COARSE, PS_DELTA_TIME, &error);
+ }
+
+ /* decision DELTA_FREQ vs DELTA_TIME */
+ if (bitsIidTime > bitsIidFreq) {
+ diffMode[0] = PS_DELTA_FREQ;
+ bitsCoarseTot = bitsIidFreq;
+ } else {
+ diffMode[0] = PS_DELTA_TIME;
+ bitsCoarseTot = bitsIidTime;
+ }
+
+ /* count COARSE quantization bits for following envelopes*/
+ for (env = 1; env < nEnvelopes; env++) {
+ bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[env], NULL, psBands,
+ PS_IID_RES_COARSE, PS_DELTA_FREQ, &error);
+ bitsIidTime =
+ FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[env], iidIdxCoarse[env - 1],
+ psBands, PS_IID_RES_COARSE, PS_DELTA_TIME, &error);
+
+ /* decision DELTA_FREQ vs DELTA_TIME */
+ if (bitsIidTime > bitsIidFreq) {
+ diffMode[env] = PS_DELTA_FREQ;
+ bitsCoarseTot += bitsIidFreq;
+ } else {
+ diffMode[env] = PS_DELTA_TIME;
+ bitsCoarseTot += bitsIidTime;
+ }
+ }
+
+ /* count FINE quantization bits for first envelope*/
+ bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[0], NULL, psBands,
+ PS_IID_RES_FINE, PS_DELTA_FREQ, &error);
+
+ if ((psData->iidTimeCnt >= MAX_TIME_DIFF_FRAMES) ||
+ (psData->iidQuantModeLast == PS_IID_RES_COARSE)) {
+ bitsIidTime = DO_NOT_USE_THIS_MODE;
+ } else {
+ bitsIidTime =
+ FDKsbrEnc_EncodeIid(NULL, iidIdxFine[0], psData->iidIdxLast, psBands,
+ PS_IID_RES_FINE, PS_DELTA_TIME, &error);
+ }
+
+ /* decision DELTA_FREQ vs DELTA_TIME */
+ if (bitsIidTime > bitsIidFreq) {
+ diffModeFine[0] = PS_DELTA_FREQ;
+ bitsFineTot = bitsIidFreq;
+ } else {
+ diffModeFine[0] = PS_DELTA_TIME;
+ bitsFineTot = bitsIidTime;
+ }
+
+ /* count FINE quantization bits for following envelopes*/
+ for (env = 1; env < nEnvelopes; env++) {
+ bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[env], NULL, psBands,
+ PS_IID_RES_FINE, PS_DELTA_FREQ, &error);
+ bitsIidTime =
+ FDKsbrEnc_EncodeIid(NULL, iidIdxFine[env], iidIdxFine[env - 1], psBands,
+ PS_IID_RES_FINE, PS_DELTA_TIME, &error);
+
+ /* decision DELTA_FREQ vs DELTA_TIME */
+ if (bitsIidTime > bitsIidFreq) {
+ diffModeFine[env] = PS_DELTA_FREQ;
+ bitsFineTot += bitsIidFreq;
+ } else {
+ diffModeFine[env] = PS_DELTA_TIME;
+ bitsFineTot += bitsIidTime;
+ }
+ }
+
+ if (bitsFineTot == bitsCoarseTot) {
+ /* if same number of bits is needed, use the quantization with lower error
+ */
+ if (errIIDFine < errIID) {
+ bitsCoarseTot = DO_NOT_USE_THIS_MODE;
+ } else {
+ bitsFineTot = DO_NOT_USE_THIS_MODE;
+ }
+ } else {
+ /* const FIXP_DBL minThreshold =
+ * FL2FXCONST_DBL(0.2f/(IID_SCALE_FT*PS_QUANT_SCALE_FT)*(psBands*nEnvelopes));
+ */
+ const FIXP_DBL minThreshold =
+ (FIXP_DBL)((LONG)0x00019999 * (psBands * nEnvelopes));
+
+ /* decision RES_FINE vs RES_COARSE */
+ /* test if errIIDFine*quantErrorThreshold < errIID */
+ /* shiftVal 2 comes from scaling of quantErrorThreshold */
+ if (fixMax(((errIIDFine >> 1) + (minThreshold >> 1)) >> 1,
+ fMult(quantErrorThreshold, errIIDFine)) < (errIID >> 2)) {
+ bitsCoarseTot = DO_NOT_USE_THIS_MODE;
+ } else if (fixMax(((errIID >> 1) + (minThreshold >> 1)) >> 1,
+ fMult(quantErrorThreshold, errIID)) < (errIIDFine >> 2)) {
+ bitsFineTot = DO_NOT_USE_THIS_MODE;
+ }
+ }
+
+ /* decision RES_FINE vs RES_COARSE */
+ if (bitsFineTot < bitsCoarseTot) {
+ psData->iidQuantMode = PS_IID_RES_FINE;
+ for (env = 0; env < nEnvelopes; env++) {
+ psData->iidDiffMode[env] = diffModeFine[env];
+ FDKmemcpy(psData->iidIdx[env], iidIdxFine[env], psBands * sizeof(INT));
+ }
+ } else {
+ psData->iidQuantMode = PS_IID_RES_COARSE;
+ for (env = 0; env < nEnvelopes; env++) {
+ psData->iidDiffMode[env] = diffMode[env];
+ FDKmemcpy(psData->iidIdx[env], iidIdxCoarse[env], psBands * sizeof(INT));
+ }
+ }
+
+ /* Count DELTA_TIME encoding streaks */
+ for (env = 0; env < nEnvelopes; env++) {
+ if (psData->iidDiffMode[env] == PS_DELTA_TIME)
+ psData->iidTimeCnt++;
+ else
+ psData->iidTimeCnt = 0;
+ }
+}
+
+static INT similarIid(PS_DATA *psData, const INT psBands,
+ const INT nEnvelopes) {
+ const INT diffThr = (psData->iidQuantMode == PS_IID_RES_COARSE) ? 2 : 3;
+ const INT sumDiffThr = diffThr * psBands / 4;
+ INT similar = 0;
+ INT diff = 0;
+ INT sumDiff = 0;
+ INT env = 0;
+ INT b = 0;
+ if ((nEnvelopes == psData->nEnvelopesLast) && (nEnvelopes == 1)) {
+ similar = 1;
+ for (env = 0; env < nEnvelopes; env++) {
+ sumDiff = 0;
+ b = 0;
+ do {
+ diff = fixp_abs(psData->iidIdx[env][b] - psData->iidIdxLast[b]);
+ sumDiff += diff;
+ if ((diff > diffThr) /* more than x quantization steps in any band */
+ || (sumDiff > sumDiffThr)) { /* more than x quantisations steps
+ overall difference */
+ similar = 0;
+ }
+ b++;
+ } while ((b < psBands) && (similar > 0));
+ }
+ } /* nEnvelopes==1 */
+
+ return similar;
+}
+
+static INT similarIcc(PS_DATA *psData, const INT psBands,
+ const INT nEnvelopes) {
+ const INT diffThr = 2;
+ const INT sumDiffThr = diffThr * psBands / 4;
+ INT similar = 0;
+ INT diff = 0;
+ INT sumDiff = 0;
+ INT env = 0;
+ INT b = 0;
+ if ((nEnvelopes == psData->nEnvelopesLast) && (nEnvelopes == 1)) {
+ similar = 1;
+ for (env = 0; env < nEnvelopes; env++) {
+ sumDiff = 0;
+ b = 0;
+ do {
+ diff = fixp_abs(psData->iccIdx[env][b] - psData->iccIdxLast[b]);
+ sumDiff += diff;
+ if ((diff > diffThr) /* more than x quantisation step in any band */
+ || (sumDiff > sumDiffThr)) { /* more than x quantisations steps
+ overall difference */
+ similar = 0;
+ }
+ b++;
+ } while ((b < psBands) && (similar > 0));
+ }
+ } /* nEnvelopes==1 */
+
+ return similar;
+}
+
+static void processIccData(
+ PS_DATA *psData,
+ FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS], /* const input values:
+ unable to declare as
+ const, since it does
+ not poINT to const
+ memory */
+ const INT psBands, const INT nEnvelopes) {
+ FIXP_DBL errICC = FL2FXCONST_DBL(0.f);
+ INT env, band;
+ INT bitsIccFreq, bitsIccTime;
+ INT error = 0;
+ INT inCoherence = 0, iccTransmit = 0;
+ INT *iccIdxLast;
+
+ iccIdxLast = psData->iccIdxLast;
+
+ /* Quantize ICC coefficients */
+ for (env = 0; env < nEnvelopes; env++) {
+ errICC +=
+ quantizeCoef(icc[env], psBands, iccQuant, 0, 8, psData->iccIdx[env]);
+ }
+
+ /* Check if ICC coefficients should be used */
+ psData->iccEnable = 0;
+ for (env = 0; env < nEnvelopes; env++) {
+ for (band = 0; band < psBands; band++) {
+ inCoherence += psData->iccIdx[env][band];
+ iccTransmit++;
+ }
+ }
+ if (inCoherence >
+ fMultI(FL2FXCONST_DBL(0.5f), iccTransmit)) { /* 0.5f empiric value */
+ psData->iccEnable = 1;
+ }
+
+ if (psData->iccEnable == 0) {
+ psData->iccTimeCnt = MAX_TIME_DIFF_FRAMES;
+ for (env = 0; env < nEnvelopes; env++) {
+ psData->iccDiffMode[env] = PS_DELTA_FREQ;
+ FDKmemclear(psData->iccIdx[env], sizeof(INT) * psBands);
+ }
+ return;
+ }
+
+ for (env = 0; env < nEnvelopes; env++) {
+ bitsIccFreq = FDKsbrEnc_EncodeIcc(NULL, psData->iccIdx[env], NULL, psBands,
+ PS_DELTA_FREQ, &error);
+
+ if (psData->iccTimeCnt < MAX_TIME_DIFF_FRAMES) {
+ bitsIccTime = FDKsbrEnc_EncodeIcc(NULL, psData->iccIdx[env], iccIdxLast,
+ psBands, PS_DELTA_TIME, &error);
+ } else {
+ bitsIccTime = DO_NOT_USE_THIS_MODE;
+ }
+
+ if (bitsIccFreq > bitsIccTime) {
+ psData->iccDiffMode[env] = PS_DELTA_TIME;
+ psData->iccTimeCnt++;
+ } else {
+ psData->iccDiffMode[env] = PS_DELTA_FREQ;
+ psData->iccTimeCnt = 0;
+ }
+ iccIdxLast = psData->iccIdx[env];
+ }
+}
+
+static void calculateIID(FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS],
+ FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS],
+ FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS],
+ INT nEnvelopes, INT psBands) {
+ INT i = 0;
+ INT env = 0;
+ for (env = 0; env < nEnvelopes; env++) {
+ for (i = 0; i < psBands; i++) {
+ /* iid[env][i] = 10.0f*(float)log10(pwrL[env][i]/pwrR[env][i]);
+ */
+ FIXP_DBL IID = fMultDiv2(FL2FXCONST_DBL(LOG10_2_10 / IID_SCALE_FT),
+ (ldPwrL[env][i] - ldPwrR[env][i]));
+
+ IID = fixMin(IID, (FIXP_DBL)(MAXVAL_DBL >> (LD_DATA_SHIFT + 1)));
+ IID = fixMax(IID, (FIXP_DBL)(MINVAL_DBL >> (LD_DATA_SHIFT + 1)));
+ iid[env][i] = IID << (LD_DATA_SHIFT + 1);
+ }
+ }
+}
+
+static void calculateICC(FIXP_DBL pwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS],
+ FIXP_DBL pwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS],
+ FIXP_DBL pwrCr[PS_MAX_ENVELOPES][PS_MAX_BANDS],
+ FIXP_DBL pwrCi[PS_MAX_ENVELOPES][PS_MAX_BANDS],
+ FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS],
+ INT nEnvelopes, INT psBands) {
+ INT i = 0;
+ INT env = 0;
+ INT border = psBands;
+
+ switch (psBands) {
+ case PS_BANDS_COARSE:
+ border = 5;
+ break;
+ case PS_BANDS_MID:
+ border = 11;
+ break;
+ default:
+ break;
+ }
+
+ for (env = 0; env < nEnvelopes; env++) {
+ for (i = 0; i < border; i++) {
+ /* icc[env][i] = min( pwrCr[env][i] / (float) sqrt(pwrL[env][i] *
+ * pwrR[env][i]) , 1.f);
+ */
+ int scale;
+ FIXP_DBL invNrg = invSqrtNorm2(
+ fMax(fMult(pwrL[env][i], pwrR[env][i]), (FIXP_DBL)1), &scale);
+ icc[env][i] =
+ SATURATE_LEFT_SHIFT(fMult(pwrCr[env][i], invNrg), scale, DFRACT_BITS);
+ }
+
+ for (; i < psBands; i++) {
+ int denom_e;
+ FIXP_DBL denom_m = fMultNorm(pwrL[env][i], pwrR[env][i], &denom_e);
+
+ if (denom_m == (FIXP_DBL)0) {
+ icc[env][i] = (FIXP_DBL)MAXVAL_DBL;
+ } else {
+ int num_e, result_e;
+ FIXP_DBL num_m, result_m;
+
+ num_e = CountLeadingBits(
+ fixMax(fixp_abs(pwrCr[env][i]), fixp_abs(pwrCi[env][i])));
+ num_m = fPow2Div2((pwrCr[env][i] << num_e)) +
+ fPow2Div2((pwrCi[env][i] << num_e));
+
+ result_m = fDivNorm(num_m, denom_m, &result_e);
+ result_e += (-2 * num_e + 1) - denom_e;
+ icc[env][i] = scaleValueSaturate(sqrtFixp(result_m >> (result_e & 1)),
+ (result_e + (result_e & 1)) >> 1);
+ }
+ }
+ }
+}
+
+void FDKsbrEnc_initPsBandNrgScale(HANDLE_PS_ENCODE hPsEncode) {
+ INT group, bin;
+ INT nIidGroups = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups;
+
+ FDKmemclear(hPsEncode->psBandNrgScale, PS_MAX_BANDS * sizeof(SCHAR));
+
+ for (group = 0; group < nIidGroups; group++) {
+ /* Translate group to bin */
+ bin = hPsEncode->subband2parameterIndex[group];
+
+ /* Translate from 20 bins to 10 bins */
+ if (hPsEncode->psEncMode == PS_BANDS_COARSE) {
+ bin = bin >> 1;
+ }
+
+ hPsEncode->psBandNrgScale[bin] =
+ (hPsEncode->psBandNrgScale[bin] == 0)
+ ? (hPsEncode->iidGroupWidthLd[group] + 5)
+ : (fixMax(hPsEncode->iidGroupWidthLd[group],
+ hPsEncode->psBandNrgScale[bin]) +
+ 1);
+ }
+}
+
+FDK_PSENC_ERROR FDKsbrEnc_CreatePSEncode(HANDLE_PS_ENCODE *phPsEncode) {
+ FDK_PSENC_ERROR error = PSENC_OK;
+
+ if (phPsEncode == NULL) {
+ error = PSENC_INVALID_HANDLE;
+ } else {
+ HANDLE_PS_ENCODE hPsEncode = NULL;
+ if (NULL == (hPsEncode = GetRam_PsEncode())) {
+ error = PSENC_MEMORY_ERROR;
+ goto bail;
+ }
+ FDKmemclear(hPsEncode, sizeof(PS_ENCODE));
+ *phPsEncode = hPsEncode; /* return allocated handle */
+ }
+bail:
+ return error;
+}
+
+FDK_PSENC_ERROR FDKsbrEnc_InitPSEncode(HANDLE_PS_ENCODE hPsEncode,
+ const PS_BANDS psEncMode,
+ const FIXP_DBL iidQuantErrorThreshold) {
+ FDK_PSENC_ERROR error = PSENC_OK;
+
+ if (NULL == hPsEncode) {
+ error = PSENC_INVALID_HANDLE;
+ } else {
+ if (PSENC_OK != (InitPSData(&hPsEncode->psData))) {
+ goto bail;
+ }
+
+ switch (psEncMode) {
+ case PS_BANDS_COARSE:
+ case PS_BANDS_MID:
+ hPsEncode->nQmfIidGroups = QMF_GROUPS_LO_RES;
+ hPsEncode->nSubQmfIidGroups = SUBQMF_GROUPS_LO_RES;
+ FDKmemcpy(hPsEncode->iidGroupBorders, iidGroupBordersLoRes,
+ (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups + 1) *
+ sizeof(INT));
+ FDKmemcpy(hPsEncode->subband2parameterIndex, subband2parameter20,
+ (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups) *
+ sizeof(INT));
+ FDKmemcpy(hPsEncode->iidGroupWidthLd, iidGroupWidthLdLoRes,
+ (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups) *
+ sizeof(UCHAR));
+ break;
+ default:
+ error = PSENC_INIT_ERROR;
+ goto bail;
+ }
+
+ hPsEncode->psEncMode = psEncMode;
+ hPsEncode->iidQuantErrorThreshold = iidQuantErrorThreshold;
+ FDKsbrEnc_initPsBandNrgScale(hPsEncode);
+ }
+bail:
+ return error;
+}
+
+FDK_PSENC_ERROR FDKsbrEnc_DestroyPSEncode(HANDLE_PS_ENCODE *phPsEncode) {
+ FDK_PSENC_ERROR error = PSENC_OK;
+
+ if (NULL != phPsEncode) {
+ FreeRam_PsEncode(phPsEncode);
+ }
+
+ return error;
+}
+
+typedef struct {
+ FIXP_DBL pwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ FIXP_DBL pwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ FIXP_DBL pwrCr[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ FIXP_DBL pwrCi[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+
+} PS_PWR_DATA;
+
+FDK_PSENC_ERROR FDKsbrEnc_PSEncode(
+ HANDLE_PS_ENCODE hPsEncode, HANDLE_PS_OUT hPsOut, UCHAR *dynBandScale,
+ UINT maxEnvelopes,
+ FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2],
+ const INT frameSize, const INT sendHeader) {
+ FDK_PSENC_ERROR error = PSENC_OK;
+
+ HANDLE_PS_DATA hPsData = &hPsEncode->psData;
+ FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ int envBorder[PS_MAX_ENVELOPES + 1];
+
+ int group, bin, col, subband, band;
+ int i = 0;
+
+ int env = 0;
+ int psBands = (int)hPsEncode->psEncMode;
+ int nIidGroups = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups;
+ int nEnvelopes = fixMin(maxEnvelopes, (UINT)PS_MAX_ENVELOPES);
+
+ C_ALLOC_SCRATCH_START(pwrData, PS_PWR_DATA, 1)
+
+ for (env = 0; env < nEnvelopes + 1; env++) {
+ envBorder[env] = fMultI(GetInvInt(nEnvelopes), frameSize * env);
+ }
+
+ for (env = 0; env < nEnvelopes; env++) {
+ /* clear energy array */
+ for (band = 0; band < psBands; band++) {
+ pwrData->pwrL[env][band] = pwrData->pwrR[env][band] =
+ pwrData->pwrCr[env][band] = pwrData->pwrCi[env][band] = FIXP_DBL(1);
+ }
+
+ /**** calculate energies and correlation ****/
+
+ /* start with hybrid data */
+ for (group = 0; group < nIidGroups; group++) {
+ /* Translate group to bin */
+ bin = hPsEncode->subband2parameterIndex[group];
+
+ /* Translate from 20 bins to 10 bins */
+ if (hPsEncode->psEncMode == PS_BANDS_COARSE) {
+ bin >>= 1;
+ }
+
+ /* determine group border */
+ int bScale = hPsEncode->psBandNrgScale[bin];
+
+ FIXP_DBL pwrL_env_bin = pwrData->pwrL[env][bin];
+ FIXP_DBL pwrR_env_bin = pwrData->pwrR[env][bin];
+ FIXP_DBL pwrCr_env_bin = pwrData->pwrCr[env][bin];
+ FIXP_DBL pwrCi_env_bin = pwrData->pwrCi[env][bin];
+
+ int scale = (int)dynBandScale[bin];
+ for (col = envBorder[env]; col < envBorder[env + 1]; col++) {
+ for (subband = hPsEncode->iidGroupBorders[group];
+ subband < hPsEncode->iidGroupBorders[group + 1]; subband++) {
+ FIXP_DBL l_real = (hybridData[col][0][0][subband]) << scale;
+ FIXP_DBL l_imag = (hybridData[col][0][1][subband]) << scale;
+ FIXP_DBL r_real = (hybridData[col][1][0][subband]) << scale;
+ FIXP_DBL r_imag = (hybridData[col][1][1][subband]) << scale;
+
+ pwrL_env_bin += (fPow2Div2(l_real) + fPow2Div2(l_imag)) >> bScale;
+ pwrR_env_bin += (fPow2Div2(r_real) + fPow2Div2(r_imag)) >> bScale;
+ pwrCr_env_bin +=
+ (fMultDiv2(l_real, r_real) + fMultDiv2(l_imag, r_imag)) >> bScale;
+ pwrCi_env_bin +=
+ (fMultDiv2(r_real, l_imag) - fMultDiv2(l_real, r_imag)) >> bScale;
+ }
+ }
+ /* assure, nrg's of left and right channel are not negative; necessary on
+ * 16 bit multiply units */
+ pwrData->pwrL[env][bin] = fixMax((FIXP_DBL)0, pwrL_env_bin);
+ pwrData->pwrR[env][bin] = fixMax((FIXP_DBL)0, pwrR_env_bin);
+
+ pwrData->pwrCr[env][bin] = pwrCr_env_bin;
+ pwrData->pwrCi[env][bin] = pwrCi_env_bin;
+
+ } /* nIidGroups */
+
+ /* calc logarithmic energy */
+ LdDataVector(pwrData->pwrL[env], pwrData->ldPwrL[env], psBands);
+ LdDataVector(pwrData->pwrR[env], pwrData->ldPwrR[env], psBands);
+
+ } /* nEnvelopes */
+
+ /* calculate iid and icc */
+ calculateIID(pwrData->ldPwrL, pwrData->ldPwrR, iid, nEnvelopes, psBands);
+ calculateICC(pwrData->pwrL, pwrData->pwrR, pwrData->pwrCr, pwrData->pwrCi,
+ icc, nEnvelopes, psBands);
+
+ /*** Envelope Reduction ***/
+ while (envelopeReducible(iid, icc, psBands, nEnvelopes)) {
+ int e = 0;
+ /* sum energies of two neighboring envelopes */
+ nEnvelopes >>= 1;
+ for (e = 0; e < nEnvelopes; e++) {
+ FDKsbrEnc_addFIXP_DBL(pwrData->pwrL[2 * e], pwrData->pwrL[2 * e + 1],
+ pwrData->pwrL[e], psBands);
+ FDKsbrEnc_addFIXP_DBL(pwrData->pwrR[2 * e], pwrData->pwrR[2 * e + 1],
+ pwrData->pwrR[e], psBands);
+ FDKsbrEnc_addFIXP_DBL(pwrData->pwrCr[2 * e], pwrData->pwrCr[2 * e + 1],
+ pwrData->pwrCr[e], psBands);
+ FDKsbrEnc_addFIXP_DBL(pwrData->pwrCi[2 * e], pwrData->pwrCi[2 * e + 1],
+ pwrData->pwrCi[e], psBands);
+
+ /* calc logarithmic energy */
+ LdDataVector(pwrData->pwrL[e], pwrData->ldPwrL[e], psBands);
+ LdDataVector(pwrData->pwrR[e], pwrData->ldPwrR[e], psBands);
+
+ /* reduce number of envelopes and adjust borders */
+ envBorder[e] = envBorder[2 * e];
+ }
+ envBorder[nEnvelopes] = envBorder[2 * nEnvelopes];
+
+ /* re-calculate iid and icc */
+ calculateIID(pwrData->ldPwrL, pwrData->ldPwrR, iid, nEnvelopes, psBands);
+ calculateICC(pwrData->pwrL, pwrData->pwrR, pwrData->pwrCr, pwrData->pwrCi,
+ icc, nEnvelopes, psBands);
+ }
+
+ /* */
+ if (sendHeader) {
+ hPsData->headerCnt = MAX_PS_NOHEADER_CNT;
+ hPsData->iidTimeCnt = MAX_TIME_DIFF_FRAMES;
+ hPsData->iccTimeCnt = MAX_TIME_DIFF_FRAMES;
+ hPsData->noEnvCnt = MAX_NOENV_CNT;
+ }
+
+ /*** Parameter processing, quantisation etc ***/
+ processIidData(hPsData, iid, psBands, nEnvelopes,
+ hPsEncode->iidQuantErrorThreshold);
+ processIccData(hPsData, icc, psBands, nEnvelopes);
+
+ /*** Initialize output struct ***/
+
+ /* PS Header on/off ? */
+ if ((hPsData->headerCnt < MAX_PS_NOHEADER_CNT) &&
+ ((hPsData->iidQuantMode == hPsData->iidQuantModeLast) &&
+ (hPsData->iccQuantMode == hPsData->iccQuantModeLast)) &&
+ ((hPsData->iidEnable == hPsData->iidEnableLast) &&
+ (hPsData->iccEnable == hPsData->iccEnableLast))) {
+ hPsOut->enablePSHeader = 0;
+ } else {
+ hPsOut->enablePSHeader = 1;
+ hPsData->headerCnt = 0;
+ }
+
+ /* nEnvelopes = 0 ? */
+ if ((hPsData->noEnvCnt < MAX_NOENV_CNT) &&
+ (similarIid(hPsData, psBands, nEnvelopes)) &&
+ (similarIcc(hPsData, psBands, nEnvelopes))) {
+ hPsOut->nEnvelopes = nEnvelopes = 0;
+ hPsData->noEnvCnt++;
+ } else {
+ hPsData->noEnvCnt = 0;
+ }
+
+ if (nEnvelopes > 0) {
+ hPsOut->enableIID = hPsData->iidEnable;
+ hPsOut->iidMode = getIIDMode(psBands, hPsData->iidQuantMode);
+
+ hPsOut->enableICC = hPsData->iccEnable;
+ hPsOut->iccMode = getICCMode(psBands, hPsData->iccQuantMode);
+
+ hPsOut->enableIpdOpd = 0;
+ hPsOut->frameClass = 0;
+ hPsOut->nEnvelopes = nEnvelopes;
+
+ for (env = 0; env < nEnvelopes; env++) {
+ hPsOut->frameBorder[env] = envBorder[env + 1];
+ hPsOut->deltaIID[env] = (PS_DELTA)hPsData->iidDiffMode[env];
+ hPsOut->deltaICC[env] = (PS_DELTA)hPsData->iccDiffMode[env];
+ for (band = 0; band < psBands; band++) {
+ hPsOut->iid[env][band] = hPsData->iidIdx[env][band];
+ hPsOut->icc[env][band] = hPsData->iccIdx[env][band];
+ }
+ }
+
+ /* IPD OPD not supported right now */
+ FDKmemclear(hPsOut->ipd,
+ PS_MAX_ENVELOPES * PS_MAX_BANDS * sizeof(PS_DELTA));
+ for (env = 0; env < PS_MAX_ENVELOPES; env++) {
+ hPsOut->deltaIPD[env] = PS_DELTA_FREQ;
+ hPsOut->deltaOPD[env] = PS_DELTA_FREQ;
+ }
+
+ FDKmemclear(hPsOut->ipdLast, PS_MAX_BANDS * sizeof(INT));
+ FDKmemclear(hPsOut->opdLast, PS_MAX_BANDS * sizeof(INT));
+
+ for (band = 0; band < PS_MAX_BANDS; band++) {
+ hPsOut->iidLast[band] = hPsData->iidIdxLast[band];
+ hPsOut->iccLast[band] = hPsData->iccIdxLast[band];
+ }
+
+ /* save iids and iccs for differential time coding in the next frame */
+ hPsData->nEnvelopesLast = nEnvelopes;
+ hPsData->iidEnableLast = hPsData->iidEnable;
+ hPsData->iccEnableLast = hPsData->iccEnable;
+ hPsData->iidQuantModeLast = hPsData->iidQuantMode;
+ hPsData->iccQuantModeLast = hPsData->iccQuantMode;
+ for (i = 0; i < psBands; i++) {
+ hPsData->iidIdxLast[i] = hPsData->iidIdx[nEnvelopes - 1][i];
+ hPsData->iccIdxLast[i] = hPsData->iccIdx[nEnvelopes - 1][i];
+ }
+ } /* Envelope > 0 */
+
+ C_ALLOC_SCRATCH_END(pwrData, PS_PWR_DATA, 1)
+
+ return error;
+}
diff --git a/fdk-aac/libSBRenc/src/ps_encode.h b/fdk-aac/libSBRenc/src/ps_encode.h
new file mode 100644
index 0000000..4237a00
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/ps_encode.h
@@ -0,0 +1,185 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s): M. Neuendorf, N. Rettelbach, M. Multrus
+
+ Description: PS Parameter extraction, encoding
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief PS parameter extraction, encoding functions $Revision: 92790 $
+*/
+
+#ifndef PS_ENCODE_H
+#define PS_ENCODE_H
+
+#include "ps_const.h"
+#include "ps_bitenc.h"
+
+#define IID_SCALE_FT (64.f) /* maxVal in Quant tab is +/- 50 */
+#define IID_SCALE 6 /* maxVal in Quant tab is +/- 50 */
+#define IID_MAXVAL (1 << IID_SCALE)
+
+#define PS_QUANT_SCALE_FT \
+ (64.f) /* error smaller (64-25)/64 * 20 bands * 4 env -> QuantScale 64 */
+#define PS_QUANT_SCALE \
+ 6 /* error smaller (64-25)/64 * 20 bands * 4 env -> QuantScale 6 bit */
+
+#define QMF_GROUPS_LO_RES 12
+#define SUBQMF_GROUPS_LO_RES 10
+#define QMF_GROUPS_HI_RES 18
+#define SUBQMF_GROUPS_HI_RES 30
+
+typedef struct T_PS_DATA {
+ INT iidEnable;
+ INT iidEnableLast;
+ INT iidQuantMode;
+ INT iidQuantModeLast;
+ INT iidDiffMode[PS_MAX_ENVELOPES];
+ INT iidIdx[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ INT iidIdxLast[PS_MAX_BANDS];
+
+ INT iccEnable;
+ INT iccEnableLast;
+ INT iccQuantMode;
+ INT iccQuantModeLast;
+ INT iccDiffMode[PS_MAX_ENVELOPES];
+ INT iccIdx[PS_MAX_ENVELOPES][PS_MAX_BANDS];
+ INT iccIdxLast[PS_MAX_BANDS];
+
+ INT nEnvelopesLast;
+
+ INT headerCnt;
+ INT iidTimeCnt;
+ INT iccTimeCnt;
+ INT noEnvCnt;
+
+} PS_DATA, *HANDLE_PS_DATA;
+
+typedef struct T_PS_ENCODE {
+ PS_DATA psData;
+
+ PS_BANDS psEncMode;
+ INT nQmfIidGroups;
+ INT nSubQmfIidGroups;
+ INT iidGroupBorders[QMF_GROUPS_HI_RES + SUBQMF_GROUPS_HI_RES + 1];
+ INT subband2parameterIndex[QMF_GROUPS_HI_RES + SUBQMF_GROUPS_HI_RES];
+ UCHAR iidGroupWidthLd[QMF_GROUPS_HI_RES + SUBQMF_GROUPS_HI_RES];
+ FIXP_DBL iidQuantErrorThreshold;
+
+ UCHAR psBandNrgScale[PS_MAX_BANDS];
+
+} PS_ENCODE;
+
+typedef struct T_PS_ENCODE *HANDLE_PS_ENCODE;
+
+FDK_PSENC_ERROR FDKsbrEnc_CreatePSEncode(HANDLE_PS_ENCODE *phPsEncode);
+
+FDK_PSENC_ERROR FDKsbrEnc_InitPSEncode(HANDLE_PS_ENCODE hPsEncode,
+ const PS_BANDS psEncMode,
+ const FIXP_DBL iidQuantErrorThreshold);
+
+FDK_PSENC_ERROR FDKsbrEnc_DestroyPSEncode(HANDLE_PS_ENCODE *phPsEncode);
+
+FDK_PSENC_ERROR FDKsbrEnc_PSEncode(
+ HANDLE_PS_ENCODE hPsEncode, HANDLE_PS_OUT hPsOut, UCHAR *dynBandScale,
+ UINT maxEnvelopes,
+ FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2],
+ const INT frameSize, const INT sendHeader);
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/ps_main.cpp b/fdk-aac/libSBRenc/src/ps_main.cpp
new file mode 100644
index 0000000..4d7a7a5
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/ps_main.cpp
@@ -0,0 +1,606 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s): M. Multrus
+
+ Description: PS Wrapper, Downmix
+
+*******************************************************************************/
+
+#include "ps_main.h"
+
+/* Includes ******************************************************************/
+#include "ps_bitenc.h"
+#include "sbrenc_ram.h"
+
+/*--------------- function declarations --------------------*/
+static void psFindBestScaling(
+ HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2],
+ UCHAR *dynBandScale, FIXP_DBL *maxBandValue, SCHAR *dmxScale);
+
+/*------------- function definitions ----------------*/
+FDK_PSENC_ERROR PSEnc_Create(HANDLE_PARAMETRIC_STEREO *phParametricStereo) {
+ FDK_PSENC_ERROR error = PSENC_OK;
+ HANDLE_PARAMETRIC_STEREO hParametricStereo = NULL;
+
+ if (phParametricStereo == NULL) {
+ error = PSENC_INVALID_HANDLE;
+ } else {
+ int i;
+
+ if (NULL == (hParametricStereo = GetRam_ParamStereo())) {
+ error = PSENC_MEMORY_ERROR;
+ goto bail;
+ }
+ FDKmemclear(hParametricStereo, sizeof(PARAMETRIC_STEREO));
+
+ if (PSENC_OK !=
+ (error = FDKsbrEnc_CreatePSEncode(&hParametricStereo->hPsEncode))) {
+ error = PSENC_MEMORY_ERROR;
+ goto bail;
+ }
+
+ for (i = 0; i < MAX_PS_CHANNELS; i++) {
+ if (FDKhybridAnalysisOpen(
+ &hParametricStereo->fdkHybAnaFilter[i],
+ hParametricStereo->__staticHybAnaStatesLF[i],
+ sizeof(hParametricStereo->__staticHybAnaStatesLF[i]),
+ hParametricStereo->__staticHybAnaStatesHF[i],
+ sizeof(hParametricStereo->__staticHybAnaStatesHF[i])) != 0) {
+ error = PSENC_MEMORY_ERROR;
+ goto bail;
+ }
+ }
+ }
+
+bail:
+ if (phParametricStereo != NULL) {
+ *phParametricStereo = hParametricStereo; /* return allocated handle */
+ }
+
+ if (error != PSENC_OK) {
+ PSEnc_Destroy(phParametricStereo);
+ }
+ return error;
+}
+
+FDK_PSENC_ERROR PSEnc_Init(HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ const HANDLE_PSENC_CONFIG hPsEncConfig,
+ INT noQmfSlots, INT noQmfBands, UCHAR *dynamic_RAM) {
+ FDK_PSENC_ERROR error = PSENC_OK;
+
+ if ((NULL == hParametricStereo) || (NULL == hPsEncConfig)) {
+ error = PSENC_INVALID_HANDLE;
+ } else {
+ int ch, i;
+
+ hParametricStereo->initPS = 1;
+ hParametricStereo->noQmfSlots = noQmfSlots;
+ hParametricStereo->noQmfBands = noQmfBands;
+
+ /* clear delay lines */
+ FDKmemclear(hParametricStereo->qmfDelayLines,
+ sizeof(hParametricStereo->qmfDelayLines));
+
+ hParametricStereo->qmfDelayScale = FRACT_BITS - 1;
+
+ /* create configuration for hybrid filter bank */
+ for (ch = 0; ch < MAX_PS_CHANNELS; ch++) {
+ FDKhybridAnalysisInit(&hParametricStereo->fdkHybAnaFilter[ch],
+ THREE_TO_TEN, 64, 64, 1);
+ } /* ch */
+
+ FDKhybridSynthesisInit(&hParametricStereo->fdkHybSynFilter, THREE_TO_TEN,
+ 64, 64);
+
+ /* determine average delay */
+ hParametricStereo->psDelay =
+ (HYBRID_FILTER_DELAY * hParametricStereo->noQmfBands);
+
+ if ((hPsEncConfig->maxEnvelopes < PSENC_NENV_1) ||
+ (hPsEncConfig->maxEnvelopes > PSENC_NENV_MAX)) {
+ hPsEncConfig->maxEnvelopes = PSENC_NENV_DEFAULT;
+ }
+ hParametricStereo->maxEnvelopes = hPsEncConfig->maxEnvelopes;
+
+ if (PSENC_OK !=
+ (error = FDKsbrEnc_InitPSEncode(
+ hParametricStereo->hPsEncode, (PS_BANDS)hPsEncConfig->nStereoBands,
+ hPsEncConfig->iidQuantErrorThreshold))) {
+ goto bail;
+ }
+
+ for (ch = 0; ch < MAX_PS_CHANNELS; ch++) {
+ FIXP_DBL *pDynReal = GetRam_Sbr_envRBuffer(ch, dynamic_RAM);
+ FIXP_DBL *pDynImag = GetRam_Sbr_envIBuffer(ch, dynamic_RAM);
+
+ for (i = 0; i < HYBRID_FRAMESIZE; i++) {
+ hParametricStereo->pHybridData[i + HYBRID_READ_OFFSET][ch][0] =
+ &pDynReal[i * MAX_HYBRID_BANDS];
+ hParametricStereo->pHybridData[i + HYBRID_READ_OFFSET][ch][1] =
+ &pDynImag[i * MAX_HYBRID_BANDS];
+ ;
+ }
+
+ for (i = 0; i < HYBRID_READ_OFFSET; i++) {
+ hParametricStereo->pHybridData[i][ch][0] =
+ hParametricStereo->__staticHybridData[i][ch][0];
+ hParametricStereo->pHybridData[i][ch][1] =
+ hParametricStereo->__staticHybridData[i][ch][1];
+ }
+ } /* ch */
+
+ /* clear static hybrid buffer */
+ FDKmemclear(hParametricStereo->__staticHybridData,
+ sizeof(hParametricStereo->__staticHybridData));
+
+ /* clear bs buffer */
+ FDKmemclear(hParametricStereo->psOut, sizeof(hParametricStereo->psOut));
+
+ hParametricStereo->psOut[0].enablePSHeader =
+ 1; /* write ps header in first frame */
+
+ /* clear scaling buffer */
+ FDKmemclear(hParametricStereo->dynBandScale, sizeof(UCHAR) * PS_MAX_BANDS);
+ FDKmemclear(hParametricStereo->maxBandValue,
+ sizeof(FIXP_DBL) * PS_MAX_BANDS);
+
+ } /* valid handle */
+bail:
+ return error;
+}
+
+FDK_PSENC_ERROR PSEnc_Destroy(HANDLE_PARAMETRIC_STEREO *phParametricStereo) {
+ FDK_PSENC_ERROR error = PSENC_OK;
+
+ if (NULL != phParametricStereo) {
+ HANDLE_PARAMETRIC_STEREO hParametricStereo = *phParametricStereo;
+ if (hParametricStereo != NULL) {
+ FDKsbrEnc_DestroyPSEncode(&hParametricStereo->hPsEncode);
+ FreeRam_ParamStereo(phParametricStereo);
+ }
+ }
+
+ return error;
+}
+
+static FDK_PSENC_ERROR ExtractPSParameters(
+ HANDLE_PARAMETRIC_STEREO hParametricStereo, const int sendHeader,
+ FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2]) {
+ FDK_PSENC_ERROR error = PSENC_OK;
+
+ if (hParametricStereo == NULL) {
+ error = PSENC_INVALID_HANDLE;
+ } else {
+ /* call ps encode function */
+ if (hParametricStereo->initPS) {
+ hParametricStereo->psOut[1] = hParametricStereo->psOut[0];
+ }
+ hParametricStereo->psOut[0] = hParametricStereo->psOut[1];
+
+ if (PSENC_OK !=
+ (error = FDKsbrEnc_PSEncode(
+ hParametricStereo->hPsEncode, &hParametricStereo->psOut[1],
+ hParametricStereo->dynBandScale, hParametricStereo->maxEnvelopes,
+ hybridData, hParametricStereo->noQmfSlots, sendHeader))) {
+ goto bail;
+ }
+
+ if (hParametricStereo->initPS) {
+ hParametricStereo->psOut[0] = hParametricStereo->psOut[1];
+ hParametricStereo->initPS = 0;
+ }
+ }
+bail:
+ return error;
+}
+
+static FDK_PSENC_ERROR DownmixPSQmfData(
+ HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_QMF_FILTER_BANK sbrSynthQmf, FIXP_DBL **RESTRICT mixRealQmfData,
+ FIXP_DBL **RESTRICT mixImagQmfData, INT_PCM *downsampledOutSignal,
+ const UINT downsampledOutSignalBufSize,
+ FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2],
+ const INT noQmfSlots, const INT psQmfScale[MAX_PS_CHANNELS],
+ SCHAR *qmfScale) {
+ FDK_PSENC_ERROR error = PSENC_OK;
+
+ if (hParametricStereo == NULL) {
+ error = PSENC_INVALID_HANDLE;
+ } else {
+ int n, k;
+ C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, 2 * 64)
+
+ /* define scalings */
+ int dynQmfScale = fixMax(
+ 0, hParametricStereo->dmxScale -
+ 1); /* scale one bit more for addition of left and right */
+ int downmixScale = psQmfScale[0] - dynQmfScale;
+ const FIXP_DBL maxStereoScaleFactor = MAXVAL_DBL; /* 2.f/2.f */
+
+ for (n = 0; n < noQmfSlots; n++) {
+ FIXP_DBL tmpHybrid[2][MAX_HYBRID_BANDS];
+
+ for (k = 0; k < 71; k++) {
+ int dynScale, sc; /* scaling */
+ FIXP_DBL tmpLeftReal, tmpRightReal, tmpLeftImag, tmpRightImag;
+ FIXP_DBL tmpScaleFactor, stereoScaleFactor;
+
+ tmpLeftReal = hybridData[n][0][0][k];
+ tmpLeftImag = hybridData[n][0][1][k];
+ tmpRightReal = hybridData[n][1][0][k];
+ tmpRightImag = hybridData[n][1][1][k];
+
+ sc = fixMax(
+ 0, CntLeadingZeros(fixMax(
+ fixMax(fixp_abs(tmpLeftReal), fixp_abs(tmpLeftImag)),
+ fixMax(fixp_abs(tmpRightReal), fixp_abs(tmpRightImag)))) -
+ 2);
+
+ tmpLeftReal <<= sc;
+ tmpLeftImag <<= sc;
+ tmpRightReal <<= sc;
+ tmpRightImag <<= sc;
+ dynScale = fixMin(sc - dynQmfScale, DFRACT_BITS - 1);
+
+ /* calc stereo scale factor to avoid loss of energy in bands */
+ /* stereo scale factor = min(2.0f, sqrt( (abs(l(k, n)^2 + abs(r(k, n)^2
+ * )))/(0.5f*abs(l(k, n) + r(k, n))) )) */
+ stereoScaleFactor = fPow2Div2(tmpLeftReal) + fPow2Div2(tmpLeftImag) +
+ fPow2Div2(tmpRightReal) + fPow2Div2(tmpRightImag);
+
+ /* might be that tmpScaleFactor becomes negative, so fabs(.) */
+ tmpScaleFactor =
+ fixp_abs(stereoScaleFactor + fMult(tmpLeftReal, tmpRightReal) +
+ fMult(tmpLeftImag, tmpRightImag));
+
+ /* min(2.0f, sqrt(stereoScaleFactor/(0.5f*tmpScaleFactor))) */
+ if ((stereoScaleFactor >> 1) <
+ fMult(maxStereoScaleFactor, tmpScaleFactor)) {
+ int sc_num = CountLeadingBits(stereoScaleFactor);
+ int sc_denum = CountLeadingBits(tmpScaleFactor);
+ sc = -(sc_num - sc_denum);
+
+ tmpScaleFactor = schur_div((stereoScaleFactor << (sc_num)) >> 1,
+ tmpScaleFactor << sc_denum, 16);
+
+ /* prevent odd scaling for next sqrt calculation */
+ if (sc & 0x1) {
+ sc++;
+ tmpScaleFactor >>= 1;
+ }
+ stereoScaleFactor = sqrtFixp(tmpScaleFactor);
+ stereoScaleFactor <<= (sc >> 1);
+ } else {
+ stereoScaleFactor = maxStereoScaleFactor;
+ }
+
+ /* write data to hybrid output */
+ tmpHybrid[0][k] = fMultDiv2(stereoScaleFactor,
+ (FIXP_DBL)(tmpLeftReal + tmpRightReal)) >>
+ dynScale;
+ tmpHybrid[1][k] = fMultDiv2(stereoScaleFactor,
+ (FIXP_DBL)(tmpLeftImag + tmpRightImag)) >>
+ dynScale;
+
+ } /* hybrid bands - k */
+
+ FDKhybridSynthesisApply(&hParametricStereo->fdkHybSynFilter, tmpHybrid[0],
+ tmpHybrid[1], mixRealQmfData[n],
+ mixImagQmfData[n]);
+
+ qmfSynthesisFilteringSlot(
+ sbrSynthQmf, mixRealQmfData[n], mixImagQmfData[n], downmixScale - 7,
+ downmixScale - 7,
+ downsampledOutSignal + (n * sbrSynthQmf->no_channels), 1,
+ pWorkBuffer);
+
+ } /* slots */
+
+ *qmfScale = -downmixScale + 7;
+
+ C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, 2 * 64)
+
+ {
+ const INT noQmfSlots2 = hParametricStereo->noQmfSlots >> 1;
+ const int noQmfBands = hParametricStereo->noQmfBands;
+
+ INT scale, i, j, slotOffset;
+
+ FIXP_DBL tmp[2][64];
+
+ for (i = 0; i < noQmfSlots2; i++) {
+ FDKmemcpy(tmp[0], hParametricStereo->qmfDelayLines[0][i],
+ noQmfBands * sizeof(FIXP_DBL));
+ FDKmemcpy(tmp[1], hParametricStereo->qmfDelayLines[1][i],
+ noQmfBands * sizeof(FIXP_DBL));
+
+ FDKmemcpy(hParametricStereo->qmfDelayLines[0][i],
+ mixRealQmfData[i + noQmfSlots2],
+ noQmfBands * sizeof(FIXP_DBL));
+ FDKmemcpy(hParametricStereo->qmfDelayLines[1][i],
+ mixImagQmfData[i + noQmfSlots2],
+ noQmfBands * sizeof(FIXP_DBL));
+
+ FDKmemcpy(mixRealQmfData[i + noQmfSlots2], mixRealQmfData[i],
+ noQmfBands * sizeof(FIXP_DBL));
+ FDKmemcpy(mixImagQmfData[i + noQmfSlots2], mixImagQmfData[i],
+ noQmfBands * sizeof(FIXP_DBL));
+
+ FDKmemcpy(mixRealQmfData[i], tmp[0], noQmfBands * sizeof(FIXP_DBL));
+ FDKmemcpy(mixImagQmfData[i], tmp[1], noQmfBands * sizeof(FIXP_DBL));
+ }
+
+ if (hParametricStereo->qmfDelayScale > *qmfScale) {
+ scale = hParametricStereo->qmfDelayScale - *qmfScale;
+ slotOffset = 0;
+ } else {
+ scale = *qmfScale - hParametricStereo->qmfDelayScale;
+ slotOffset = noQmfSlots2;
+ }
+
+ for (i = 0; i < noQmfSlots2; i++) {
+ for (j = 0; j < noQmfBands; j++) {
+ mixRealQmfData[i + slotOffset][j] >>= scale;
+ mixImagQmfData[i + slotOffset][j] >>= scale;
+ }
+ }
+
+ scale = *qmfScale;
+ *qmfScale = fMin(*qmfScale, hParametricStereo->qmfDelayScale);
+ hParametricStereo->qmfDelayScale = scale;
+ }
+
+ } /* valid handle */
+
+ return error;
+}
+
+INT FDKsbrEnc_PSEnc_WritePSData(HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_FDK_BITSTREAM hBitstream) {
+ return (
+ (hParametricStereo != NULL)
+ ? FDKsbrEnc_WritePSBitstream(&hParametricStereo->psOut[0], hBitstream)
+ : 0);
+}
+
+FDK_PSENC_ERROR FDKsbrEnc_PSEnc_ParametricStereoProcessing(
+ HANDLE_PARAMETRIC_STEREO hParametricStereo, INT_PCM *samples[2],
+ UINT samplesBufSize, QMF_FILTER_BANK **hQmfAnalysis,
+ FIXP_DBL **RESTRICT downmixedRealQmfData,
+ FIXP_DBL **RESTRICT downmixedImagQmfData, INT_PCM *downsampledOutSignal,
+ HANDLE_QMF_FILTER_BANK sbrSynthQmf, SCHAR *qmfScale, const int sendHeader) {
+ FDK_PSENC_ERROR error = PSENC_OK;
+ INT psQmfScale[MAX_PS_CHANNELS] = {0};
+ int psCh, i;
+ C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, 4 * 64)
+
+ for (psCh = 0; psCh < MAX_PS_CHANNELS; psCh++) {
+ for (i = 0; i < hQmfAnalysis[psCh]->no_col; i++) {
+ qmfAnalysisFilteringSlot(
+ hQmfAnalysis[psCh], &pWorkBuffer[2 * 64], /* qmfReal[64] */
+ &pWorkBuffer[3 * 64], /* qmfImag[64] */
+ samples[psCh] + i * hQmfAnalysis[psCh]->no_channels, 1,
+ &pWorkBuffer[0 * 64] /* qmf workbuffer 2*64 */
+ );
+
+ FDKhybridAnalysisApply(
+ &hParametricStereo->fdkHybAnaFilter[psCh],
+ &pWorkBuffer[2 * 64], /* qmfReal[64] */
+ &pWorkBuffer[3 * 64], /* qmfImag[64] */
+ hParametricStereo->pHybridData[i + HYBRID_READ_OFFSET][psCh][0],
+ hParametricStereo->pHybridData[i + HYBRID_READ_OFFSET][psCh][1]);
+
+ } /* no_col loop i */
+
+ psQmfScale[psCh] = hQmfAnalysis[psCh]->outScalefactor;
+
+ } /* for psCh */
+
+ C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, 4 * 64)
+
+ /* find best scaling in new QMF and Hybrid data */
+ psFindBestScaling(
+ hParametricStereo, &hParametricStereo->pHybridData[HYBRID_READ_OFFSET],
+ hParametricStereo->dynBandScale, hParametricStereo->maxBandValue,
+ &hParametricStereo->dmxScale);
+
+ /* extract the ps parameters */
+ if (PSENC_OK !=
+ (error = ExtractPSParameters(hParametricStereo, sendHeader,
+ &hParametricStereo->pHybridData[0]))) {
+ goto bail;
+ }
+
+ /* save hybrid date for next frame */
+ for (i = 0; i < HYBRID_READ_OFFSET; i++) {
+ FDKmemcpy(
+ hParametricStereo->pHybridData[i][0][0],
+ hParametricStereo->pHybridData[hParametricStereo->noQmfSlots + i][0][0],
+ MAX_HYBRID_BANDS * sizeof(FIXP_DBL)); /* left, real */
+ FDKmemcpy(
+ hParametricStereo->pHybridData[i][0][1],
+ hParametricStereo->pHybridData[hParametricStereo->noQmfSlots + i][0][1],
+ MAX_HYBRID_BANDS * sizeof(FIXP_DBL)); /* left, imag */
+ FDKmemcpy(
+ hParametricStereo->pHybridData[i][1][0],
+ hParametricStereo->pHybridData[hParametricStereo->noQmfSlots + i][1][0],
+ MAX_HYBRID_BANDS * sizeof(FIXP_DBL)); /* right, real */
+ FDKmemcpy(
+ hParametricStereo->pHybridData[i][1][1],
+ hParametricStereo->pHybridData[hParametricStereo->noQmfSlots + i][1][1],
+ MAX_HYBRID_BANDS * sizeof(FIXP_DBL)); /* right, imag */
+ }
+
+ /* downmix and hybrid synthesis */
+ if (PSENC_OK !=
+ (error = DownmixPSQmfData(
+ hParametricStereo, sbrSynthQmf, downmixedRealQmfData,
+ downmixedImagQmfData, downsampledOutSignal, samplesBufSize,
+ &hParametricStereo->pHybridData[HYBRID_READ_OFFSET],
+ hParametricStereo->noQmfSlots, psQmfScale, qmfScale))) {
+ goto bail;
+ }
+
+bail:
+
+ return error;
+}
+
+static void psFindBestScaling(
+ HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2],
+ UCHAR *dynBandScale, FIXP_DBL *maxBandValue, SCHAR *dmxScale) {
+ HANDLE_PS_ENCODE hPsEncode = hParametricStereo->hPsEncode;
+
+ INT group, bin, col, band;
+ const INT frameSize = hParametricStereo->noQmfSlots;
+ const INT psBands = (INT)hPsEncode->psEncMode;
+ const INT nIidGroups = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups;
+
+ /* group wise scaling */
+ FIXP_DBL maxVal[2][PS_MAX_BANDS];
+ FIXP_DBL maxValue = FL2FXCONST_DBL(0.f);
+
+ FDKmemclear(maxVal, sizeof(maxVal));
+
+ /* start with hybrid data */
+ for (group = 0; group < nIidGroups; group++) {
+ /* Translate group to bin */
+ bin = hPsEncode->subband2parameterIndex[group];
+
+ /* Translate from 20 bins to 10 bins */
+ if (hPsEncode->psEncMode == PS_BANDS_COARSE) {
+ bin >>= 1;
+ }
+
+ /* QMF downmix scaling */
+ for (col = 0; col < frameSize; col++) {
+ int i, section = (col < frameSize - HYBRID_READ_OFFSET) ? 0 : 1;
+ FIXP_DBL tmp = maxVal[section][bin];
+ for (i = hPsEncode->iidGroupBorders[group];
+ i < hPsEncode->iidGroupBorders[group + 1]; i++) {
+ tmp = fixMax(tmp, (FIXP_DBL)fixp_abs(hybridData[col][0][0][i]));
+ tmp = fixMax(tmp, (FIXP_DBL)fixp_abs(hybridData[col][0][1][i]));
+ tmp = fixMax(tmp, (FIXP_DBL)fixp_abs(hybridData[col][1][0][i]));
+ tmp = fixMax(tmp, (FIXP_DBL)fixp_abs(hybridData[col][1][1][i]));
+ }
+ maxVal[section][bin] = tmp;
+ }
+ } /* nIidGroups */
+
+ /* convert maxSpec to maxScaling, find scaling space */
+ for (band = 0; band < psBands; band++) {
+#ifndef MULT_16x16
+ dynBandScale[band] =
+ CountLeadingBits(fixMax(maxVal[0][band], maxBandValue[band]));
+#else
+ dynBandScale[band] = fixMax(
+ 0, CountLeadingBits(fixMax(maxVal[0][band], maxBandValue[band])) -
+ FRACT_BITS);
+#endif
+ maxValue = fixMax(maxValue, fixMax(maxVal[0][band], maxVal[1][band]));
+ maxBandValue[band] = fixMax(maxVal[0][band], maxVal[1][band]);
+ }
+
+ /* calculate maximal scaling for QMF downmix */
+#ifndef MULT_16x16
+ *dmxScale = fixMin(DFRACT_BITS, CountLeadingBits(maxValue));
+#else
+ *dmxScale = fixMax(0, fixMin(FRACT_BITS, CountLeadingBits((maxValue))));
+#endif
+}
diff --git a/fdk-aac/libSBRenc/src/ps_main.h b/fdk-aac/libSBRenc/src/ps_main.h
new file mode 100644
index 0000000..88b2993
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/ps_main.h
@@ -0,0 +1,270 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s): Markus Multrus
+
+ Description: PS Wrapper, Downmix header file
+
+*******************************************************************************/
+
+#ifndef PS_MAIN_H
+#define PS_MAIN_H
+
+/* Includes ******************************************************************/
+
+#include "sbr_def.h"
+#include "qmf.h"
+#include "ps_encode.h"
+#include "FDK_bitstream.h"
+#include "FDK_hybrid.h"
+
+/* Data Types ****************************************************************/
+typedef enum {
+ PSENC_STEREO_BANDS_INVALID = 0,
+ PSENC_STEREO_BANDS_10 = 10,
+ PSENC_STEREO_BANDS_20 = 20
+
+} PSENC_STEREO_BANDS_CONFIG;
+
+typedef enum {
+ PSENC_NENV_1 = 1,
+ PSENC_NENV_2 = 2,
+ PSENC_NENV_4 = 4,
+ PSENC_NENV_DEFAULT = PSENC_NENV_2,
+ PSENC_NENV_MAX = PSENC_NENV_4
+
+} PSENC_NENV_CONFIG;
+
+typedef struct {
+ UINT bitrateFrom; /* inclusive */
+ UINT bitrateTo; /* exclusive */
+ PSENC_STEREO_BANDS_CONFIG nStereoBands;
+ PSENC_NENV_CONFIG nEnvelopes;
+ LONG iidQuantErrorThreshold; /* quantization threshold to switch between
+ coarse and fine iid quantization */
+
+} psTuningTable_t;
+
+/* Function / Class Declarations *********************************************/
+
+typedef struct T_PARAMETRIC_STEREO {
+ HANDLE_PS_ENCODE hPsEncode;
+ PS_OUT psOut[2];
+
+ FIXP_DBL __staticHybridData[HYBRID_READ_OFFSET][MAX_PS_CHANNELS][2]
+ [MAX_HYBRID_BANDS];
+ FIXP_DBL
+ *pHybridData[HYBRID_READ_OFFSET + HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2];
+
+ FIXP_DBL qmfDelayLines[2][32 >> 1][64];
+ int qmfDelayScale;
+
+ INT psDelay;
+ UINT maxEnvelopes;
+ UCHAR dynBandScale[PS_MAX_BANDS];
+ FIXP_DBL maxBandValue[PS_MAX_BANDS];
+ SCHAR dmxScale;
+ INT initPS;
+ INT noQmfSlots;
+ INT noQmfBands;
+
+ FIXP_DBL __staticHybAnaStatesLF[MAX_PS_CHANNELS][2 * HYBRID_FILTER_LENGTH *
+ HYBRID_MAX_QMF_BANDS];
+ FIXP_DBL __staticHybAnaStatesHF[MAX_PS_CHANNELS][2 * HYBRID_FILTER_DELAY *
+ (64 - HYBRID_MAX_QMF_BANDS)];
+ FDK_ANA_HYB_FILTER fdkHybAnaFilter[MAX_PS_CHANNELS];
+ FDK_SYN_HYB_FILTER fdkHybSynFilter;
+
+} PARAMETRIC_STEREO;
+
+typedef struct T_PSENC_CONFIG {
+ INT frameSize;
+ INT qmfFilterMode;
+ INT sbrPsDelay;
+ PSENC_STEREO_BANDS_CONFIG nStereoBands;
+ PSENC_NENV_CONFIG maxEnvelopes;
+ FIXP_DBL iidQuantErrorThreshold;
+
+} PSENC_CONFIG, *HANDLE_PSENC_CONFIG;
+
+typedef struct T_PARAMETRIC_STEREO *HANDLE_PARAMETRIC_STEREO;
+
+/**
+ * \brief Create a parametric stereo encoder instance.
+ *
+ * \param phParametricStereo A pointer to a parametric stereo handle to be
+ * allocated. Initialized on return.
+ *
+ * \return
+ * - PSENC_OK, on succes.
+ * - PSENC_INVALID_HANDLE, PSENC_MEMORY_ERROR, on failure.
+ */
+FDK_PSENC_ERROR PSEnc_Create(HANDLE_PARAMETRIC_STEREO *phParametricStereo);
+
+/**
+ * \brief Initialize a parametric stereo encoder instance.
+ *
+ * \param hParametricStereo Meta Data handle.
+ * \param hPsEncConfig Filled parametric stereo configuration
+ * structure.
+ * \param noQmfSlots Number of slots within one audio frame.
+ * \param noQmfBands Number of QMF bands.
+ * \param dynamic_RAM Pointer to preallocated workbuffer.
+ *
+ * \return
+ * - PSENC_OK, on succes.
+ * - PSENC_INVALID_HANDLE, PSENC_INIT_ERROR, on failure.
+ */
+FDK_PSENC_ERROR PSEnc_Init(HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ const HANDLE_PSENC_CONFIG hPsEncConfig,
+ INT noQmfSlots, INT noQmfBands, UCHAR *dynamic_RAM);
+
+/**
+ * \brief Destroy parametric stereo encoder instance.
+ *
+ * Deallocate instance and free whole memory.
+ *
+ * \param phParametricStereo Pointer to the parametric stereo handle to be
+ * deallocated.
+ *
+ * \return
+ * - PSENC_OK, on succes.
+ * - PSENC_INVALID_HANDLE, on failure.
+ */
+FDK_PSENC_ERROR PSEnc_Destroy(HANDLE_PARAMETRIC_STEREO *phParametricStereo);
+
+/**
+ * \brief Apply parametric stereo processing.
+ *
+ * \param hParametricStereo Meta Data handle.
+ * \param samples Pointer to 2 channel audio input signal.
+ * \param timeInStride, Stride factor of input buffer.
+ * \param hQmfAnalysis, Pointer to QMF analysis filterbanks.
+ * \param downmixedRealQmfData Pointer to real QMF buffer to be written to.
+ * \param downmixedImagQmfData Pointer to imag QMF buffer to be written to.
+ * \param downsampledOutSignal Pointer to buffer where to write downmixed
+ * timesignal.
+ * \param sbrSynthQmf Pointer to QMF synthesis filterbank.
+ * \param qmfScale Return scaling factor of the qmf data.
+ * \param sendHeader Signal whether to write header data.
+ *
+ * \return
+ * - PSENC_OK, on succes.
+ * - PSENC_INVALID_HANDLE, PSENC_ENCODE_ERROR, on failure.
+ */
+FDK_PSENC_ERROR FDKsbrEnc_PSEnc_ParametricStereoProcessing(
+ HANDLE_PARAMETRIC_STEREO hParametricStereo, INT_PCM *samples[2],
+ UINT timeInStride, QMF_FILTER_BANK **hQmfAnalysis,
+ FIXP_DBL **RESTRICT downmixedRealQmfData,
+ FIXP_DBL **RESTRICT downmixedImagQmfData, INT_PCM *downsampledOutSignal,
+ HANDLE_QMF_FILTER_BANK sbrSynthQmf, SCHAR *qmfScale, const int sendHeader);
+
+/**
+ * \brief Write parametric stereo bitstream.
+ *
+ * Write ps_data() element to bitstream and return number of written bits.
+ * Returns number of written bits only, if hBitstream == NULL.
+ *
+ * \param hParametricStereo Meta Data handle.
+ * \param hBitstream Bitstream buffer handle.
+ *
+ * \return
+ * - number of written bits.
+ */
+INT FDKsbrEnc_PSEnc_WritePSData(HANDLE_PARAMETRIC_STEREO hParametricStereo,
+ HANDLE_FDK_BITSTREAM hBitstream);
+
+#endif /* PS_MAIN_H */
diff --git a/fdk-aac/libSBRenc/src/resampler.cpp b/fdk-aac/libSBRenc/src/resampler.cpp
new file mode 100644
index 0000000..b1781a7
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/resampler.cpp
@@ -0,0 +1,444 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief FDK resampler tool box:$Revision: 91655 $
+ \author M. Werner
+*/
+
+#include "resampler.h"
+
+#include "genericStds.h"
+
+/**************************************************************************/
+/* BIQUAD Filter Specifications */
+/**************************************************************************/
+
+#define B1 0
+#define B2 1
+#define A1 2
+#define A2 3
+
+#define BQC(x) FL2FXCONST_SGL(x / 2)
+
+struct FILTER_PARAM {
+ const FIXP_SGL *coeffa; /*! SOS matrix One row/section. Scaled using BQC().
+ Order of coefficients: B1,B2,A1,A2. B0=A0=1.0 */
+ FIXP_DBL g; /*! overall gain */
+ int Wc; /*! normalized passband bandwidth at input samplerate * 1000 */
+ int noCoeffs; /*! number of filter coeffs */
+ int delay; /*! delay in samples at input samplerate */
+};
+
+#define BIQUAD_COEFSTEP 4
+
+/**
+ *\brief Low Pass
+ Wc = 0,5, order 30, Stop Band -96dB. Wc criteria is "almost 0dB passband", not
+ the usual -3db gain point. [b,a]=cheby2(30,96,0.505) [sos,g]=tf2sos(b,a)
+ bandwidth 0.48
+ */
+static const FIXP_SGL sos48[] = {
+ BQC(1.98941075681938), BQC(0.999999996890811),
+ BQC(0.863264527201963), BQC(0.189553799960663),
+ BQC(1.90733804822445), BQC(1.00000001736189),
+ BQC(0.836321575841691), BQC(0.203505809266564),
+ BQC(1.75616665495325), BQC(0.999999946079721),
+ BQC(0.784699225121588), BQC(0.230471265506986),
+ BQC(1.55727745512726), BQC(1.00000011737815),
+ BQC(0.712515423588351), BQC(0.268752723900498),
+ BQC(1.33407591943643), BQC(0.999999795953228),
+ BQC(0.625059117330989), BQC(0.316194685288965),
+ BQC(1.10689898412458), BQC(1.00000035057114),
+ BQC(0.52803514366398), BQC(0.370517843224669),
+ BQC(0.89060371078454), BQC(0.999999343962822),
+ BQC(0.426920462165257), BQC(0.429608200207746),
+ BQC(0.694438261209433), BQC(1.0000008629792),
+ BQC(0.326530699561716), BQC(0.491714450654174),
+ BQC(0.523237800935322), BQC(1.00000101349782),
+ BQC(0.230829556274851), BQC(0.555559034843281),
+ BQC(0.378631165929563), BQC(0.99998986482665),
+ BQC(0.142906422036095), BQC(0.620338874442411),
+ BQC(0.260786911308437), BQC(1.00003261460178),
+ BQC(0.0651008576256505), BQC(0.685759923926262),
+ BQC(0.168409429188098), BQC(0.999933049695828),
+ BQC(-0.000790067789975562), BQC(0.751905896602325),
+ BQC(0.100724533818628), BQC(1.00009472669872),
+ BQC(-0.0533772830257041), BQC(0.81930744384525),
+ BQC(0.0561434357867363), BQC(0.999911636304276),
+ BQC(-0.0913550299236405), BQC(0.88883625875915),
+ BQC(0.0341680678662057), BQC(1.00003667508676),
+ BQC(-0.113405185536697), BQC(0.961756638268446)};
+
+static const FIXP_DBL g48 =
+ FL2FXCONST_DBL(0.002712866530047) - (FIXP_DBL)0x8000;
+
+static const struct FILTER_PARAM param_set48 = {
+ sos48, g48, 480, 15, 4 /* LF 2 */
+};
+
+/**
+ *\brief Low Pass
+ Wc = 0,5, order 24, Stop Band -96dB. Wc criteria is "almost 0dB passband", not
+ the usual -3db gain point. [b,a]=cheby2(24,96,0.5) [sos,g]=tf2sos(b,a)
+ bandwidth 0.45
+ */
+static const FIXP_SGL sos45[] = {
+ BQC(1.982962601444), BQC(1.00000000007504), BQC(0.646113303737836),
+ BQC(0.10851149979981), BQC(1.85334094281111), BQC(0.999999999677192),
+ BQC(0.612073220102006), BQC(0.130022141698044), BQC(1.62541051415425),
+ BQC(1.00000000080398), BQC(0.547879702855959), BQC(0.171165825133192),
+ BQC(1.34554656923247), BQC(0.9999999980169), BQC(0.460373914508491),
+ BQC(0.228677463376354), BQC(1.05656568503116), BQC(1.00000000569363),
+ BQC(0.357891894038287), BQC(0.298676843912185), BQC(0.787967587877312),
+ BQC(0.999999984415017), BQC(0.248826893211877), BQC(0.377441803512978),
+ BQC(0.555480971120497), BQC(1.00000003583307), BQC(0.140614263345315),
+ BQC(0.461979302213679), BQC(0.364986207070964), BQC(0.999999932084303),
+ BQC(0.0392669446074516), BQC(0.55033451180825), BQC(0.216827267631558),
+ BQC(1.00000010534682), BQC(-0.0506232228865103), BQC(0.641691581560946),
+ BQC(0.108951672277119), BQC(0.999999871167516), BQC(-0.125584840183225),
+ BQC(0.736367748771803), BQC(0.0387988607229035), BQC(1.00000011205574),
+ BQC(-0.182814849097974), BQC(0.835802108714964), BQC(0.0042866175809225),
+ BQC(0.999999954830813), BQC(-0.21965740617151), BQC(0.942623047782363)};
+
+static const FIXP_DBL g45 =
+ FL2FXCONST_DBL(0.00242743980909524) - (FIXP_DBL)0x8000;
+
+static const struct FILTER_PARAM param_set45 = {
+ sos45, g45, 450, 12, 4 /* LF 2 */
+};
+
+/*
+ Created by Octave 2.1.73, Mon Oct 13 17:31:32 2008 CEST
+ Wc = 0,5, order 16, Stop Band -96dB damping.
+ [b,a]=cheby2(16,96,0.5)
+ [sos,g]=tf2sos(b,a)
+ bandwidth = 0.41
+ */
+
+static const FIXP_SGL sos41[] = {
+ BQC(1.96193625292), BQC(0.999999999999964), BQC(0.169266178786789),
+ BQC(0.0128823300475907), BQC(1.68913437662092), BQC(1.00000000000053),
+ BQC(0.124751503206552), BQC(0.0537472273950989), BQC(1.27274692366017),
+ BQC(0.999999999995674), BQC(0.0433108625178357), BQC(0.131015753236317),
+ BQC(0.85214175088395), BQC(1.00000000001813), BQC(-0.0625658152550408),
+ BQC(0.237763778993806), BQC(0.503841579939009), BQC(0.999999999953223),
+ BQC(-0.179176128722865), BQC(0.367475236424474), BQC(0.249990711986162),
+ BQC(1.00000000007952), BQC(-0.294425165824676), BQC(0.516594857170212),
+ BQC(0.087971668680286), BQC(0.999999999915528), BQC(-0.398956566777928),
+ BQC(0.686417767801123), BQC(0.00965373325350294), BQC(1.00000000003744),
+ BQC(-0.48579173764817), BQC(0.884931534239068)};
+
+static const FIXP_DBL g41 = FL2FXCONST_DBL(0.00155956951169248);
+
+static const struct FILTER_PARAM param_set41 = {
+ sos41, g41, 410, 8, 5 /* LF 3 */
+};
+
+/*
+ # Created by Octave 2.1.73, Mon Oct 13 17:55:33 2008 CEST
+ Wc = 0,5, order 12, Stop Band -96dB damping.
+ [b,a]=cheby2(12,96,0.5);
+ [sos,g]=tf2sos(b,a)
+*/
+static const FIXP_SGL sos35[] = {
+ BQC(1.93299325235762), BQC(0.999999999999985), BQC(-0.140733187246596),
+ BQC(0.0124139497836062), BQC(1.4890416764109), BQC(1.00000000000011),
+ BQC(-0.198215402588504), BQC(0.0746730616584138), BQC(0.918450161309795),
+ BQC(0.999999999999619), BQC(-0.30133912791941), BQC(0.192276468839529),
+ BQC(0.454877024246818), BQC(1.00000000000086), BQC(-0.432337328809815),
+ BQC(0.356852933642815), BQC(0.158017147118507), BQC(0.999999999998876),
+ BQC(-0.574817494249777), BQC(0.566380436970833), BQC(0.0171834649478749),
+ BQC(1.00000000000055), BQC(-0.718581178041165), BQC(0.83367484487889)};
+
+static const FIXP_DBL g35 = FL2FXCONST_DBL(0.00162580994125131);
+
+static const struct FILTER_PARAM param_set35 = {sos35, g35, 350, 6, 4};
+
+/*
+ # Created by Octave 2.1.73, Mon Oct 13 18:15:38 2008 CEST
+ Wc = 0,5, order 8, Stop Band -96dB damping.
+ [b,a]=cheby2(8,96,0.5);
+ [sos,g]=tf2sos(b,a)
+*/
+static const FIXP_SGL sos25[] = {
+ BQC(1.85334094301225), BQC(1.0),
+ BQC(-0.702127214212663), BQC(0.132452403998767),
+ BQC(1.056565682167), BQC(0.999999999999997),
+ BQC(-0.789503667880785), BQC(0.236328693569128),
+ BQC(0.364986307455489), BQC(0.999999999999996),
+ BQC(-0.955191189843375), BQC(0.442966457936379),
+ BQC(0.0387985751642125), BQC(1.0),
+ BQC(-1.19817786088084), BQC(0.770493895456328)};
+
+static const FIXP_DBL g25 = FL2FXCONST_DBL(0.000945182835294559);
+
+static const struct FILTER_PARAM param_set25 = {sos25, g25, 250, 4, 5};
+
+/* Must be sorted in descending order */
+static const struct FILTER_PARAM *const filter_paramSet[] = {
+ &param_set48, &param_set45, &param_set41, &param_set35, &param_set25};
+
+/**************************************************************************/
+/* Resampler Functions */
+/**************************************************************************/
+
+/*!
+ \brief Reset downsampler instance and clear delay lines
+
+ \return success of operation
+*/
+
+INT FDKaacEnc_InitDownsampler(
+ DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */
+ int Wc, /*!< normalized cutoff freq * 1000* */
+ int ratio) /*!< downsampler ratio */
+
+{
+ UINT i;
+ const struct FILTER_PARAM *currentSet = NULL;
+
+ FDKmemclear(DownSampler->downFilter.states,
+ sizeof(DownSampler->downFilter.states));
+ DownSampler->downFilter.ptr = 0;
+
+ /*
+ find applicable parameter set
+ */
+ currentSet = filter_paramSet[0];
+ for (i = 1; i < sizeof(filter_paramSet) / sizeof(struct FILTER_PARAM *);
+ i++) {
+ if (filter_paramSet[i]->Wc <= Wc) {
+ break;
+ }
+ currentSet = filter_paramSet[i];
+ }
+
+ DownSampler->downFilter.coeffa = currentSet->coeffa;
+
+ DownSampler->downFilter.gain = currentSet->g;
+ FDK_ASSERT(currentSet->noCoeffs <= MAXNR_SECTIONS * 2);
+
+ DownSampler->downFilter.noCoeffs = currentSet->noCoeffs;
+ DownSampler->delay = currentSet->delay;
+ DownSampler->downFilter.Wc = currentSet->Wc;
+
+ DownSampler->ratio = ratio;
+ DownSampler->pending = ratio - 1;
+ return (1);
+}
+
+/*!
+ \brief faster simple folding operation
+ Filter:
+ H(z) = A(z)/B(z)
+ with
+ A(z) = a[0]*z^0 + a[1]*z^1 + a[2]*z^2 ... a[n]*z^n
+
+ \return filtered value
+*/
+
+static inline INT_PCM AdvanceFilter(
+ LP_FILTER *downFilter, /*!< pointer to iir filter instance */
+ INT_PCM *pInput, /*!< input of filter */
+ int downRatio) {
+ INT_PCM output;
+ int i, n;
+
+#define BIQUAD_SCALE 12
+
+ FIXP_DBL y = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL input;
+
+ for (n = 0; n < downRatio; n++) {
+ FIXP_BQS(*states)[2] = downFilter->states;
+ const FIXP_SGL *coeff = downFilter->coeffa;
+ int s1, s2;
+
+ s1 = downFilter->ptr;
+ s2 = s1 ^ 1;
+
+#if (SAMPLE_BITS == 16)
+ input = ((FIXP_DBL)pInput[n]) << (DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE);
+#elif (SAMPLE_BITS == 32)
+ input = pInput[n] >> BIQUAD_SCALE;
+#else
+#error NOT IMPLEMENTED
+#endif
+
+ FIXP_BQS state1, state2, state1b, state2b;
+
+ state1 = states[0][s1];
+ state2 = states[0][s2];
+
+ /* Loop over sections */
+ for (i = 0; i < downFilter->noCoeffs; i++) {
+ FIXP_DBL state0;
+
+ /* Load merged states (from next section) */
+ state1b = states[i + 1][s1];
+ state2b = states[i + 1][s2];
+
+ state0 = input + fMult(state1, coeff[B1]) + fMult(state2, coeff[B2]);
+ y = state0 - fMult(state1b, coeff[A1]) - fMult(state2b, coeff[A2]);
+
+ /* Store new feed forward merge state */
+ states[i + 1][s2] = y << 1;
+ /* Store new feed backward state */
+ states[i][s2] = input << 1;
+
+ /* Feedback output to next section. */
+ input = y;
+
+ /* Transfer merged states */
+ state1 = state1b;
+ state2 = state2b;
+
+ /* Step to next coef set */
+ coeff += BIQUAD_COEFSTEP;
+ }
+ downFilter->ptr ^= 1;
+ }
+ /* Apply global gain */
+ y = fMult(y, downFilter->gain);
+
+ /* Apply final gain/scaling to output */
+#if (SAMPLE_BITS == 16)
+ output = (INT_PCM)SATURATE_RIGHT_SHIFT(
+ y + (FIXP_DBL)(1 << (DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE - 1)),
+ DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE, SAMPLE_BITS);
+ // output = (INT_PCM) SATURATE_RIGHT_SHIFT(y,
+ // DFRACT_BITS-SAMPLE_BITS-BIQUAD_SCALE, SAMPLE_BITS);
+#else
+ output = SATURATE_LEFT_SHIFT(y, BIQUAD_SCALE, SAMPLE_BITS);
+#endif
+
+ return output;
+}
+
+/*!
+ \brief FDKaacEnc_Downsample numInSamples of type INT_PCM
+ Returns number of output samples in numOutSamples
+
+ \return success of operation
+*/
+
+INT FDKaacEnc_Downsample(
+ DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */
+ INT_PCM *inSamples, /*!< pointer to input samples */
+ INT numInSamples, /*!< number of input samples */
+ INT_PCM *outSamples, /*!< pointer to output samples */
+ INT *numOutSamples /*!< pointer tp number of output samples */
+) {
+ INT i;
+ *numOutSamples = 0;
+
+ for (i = 0; i < numInSamples; i += DownSampler->ratio) {
+ *outSamples = AdvanceFilter(&(DownSampler->downFilter), &inSamples[i],
+ DownSampler->ratio);
+ outSamples++;
+ }
+ *numOutSamples = numInSamples / DownSampler->ratio;
+
+ return 0;
+}
diff --git a/fdk-aac/libSBRenc/src/resampler.h b/fdk-aac/libSBRenc/src/resampler.h
new file mode 100644
index 0000000..7aa1cae
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/resampler.h
@@ -0,0 +1,159 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef RESAMPLER_H
+#define RESAMPLER_H
+/*!
+ \file
+ \brief Fixed Point Resampler Tool Box $Revision: 92790 $
+*/
+
+#include "common_fix.h"
+
+/**************************************************************************/
+/* BIQUAD Filter Structure */
+/**************************************************************************/
+
+#define MAXNR_SECTIONS (15)
+
+typedef FIXP_DBL FIXP_BQS;
+
+typedef struct {
+ FIXP_BQS states[MAXNR_SECTIONS + 1][2]; /*! state buffer */
+ const FIXP_SGL *coeffa; /*! pointer to filter coeffs */
+ FIXP_DBL gain; /*! overall gain factor */
+ int Wc; /*! normalized cutoff freq * 1000 */
+ int noCoeffs; /*! number of filter coeffs sets */
+ int ptr; /*! index to rinbuffers */
+} LP_FILTER;
+
+/**************************************************************************/
+/* Downsampler Structure */
+/**************************************************************************/
+
+typedef struct {
+ LP_FILTER downFilter; /*! filter instance */
+ int ratio; /*! downsampling ration */
+ int delay; /*! downsampling delay (source fs) */
+ int pending; /*! number of pending output samples */
+} DOWNSAMPLER;
+
+/**
+ * \brief Initialized a given downsampler structure.
+ */
+INT FDKaacEnc_InitDownsampler(
+ DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */
+ INT Wc, /*!< normalized cutoff freq * 1000 */
+ INT ratio); /*!< downsampler ratio */
+
+/**
+ * \brief Downsample a set of audio samples. numInSamples must be at least equal
+ * to the downsampler ratio.
+ */
+INT FDKaacEnc_Downsample(
+ DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */
+ INT_PCM *inSamples, /*!< pointer to input samples */
+ INT numInSamples, /*!< number of input samples */
+ INT_PCM *outSamples, /*!< pointer to output samples */
+ INT *numOutSamples); /*!< pointer tp number of output samples */
+
+#endif /* RESAMPLER_H */
diff --git a/fdk-aac/libSBRenc/src/sbr.h b/fdk-aac/libSBRenc/src/sbr.h
new file mode 100644
index 0000000..341dcab
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/sbr.h
@@ -0,0 +1,194 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Main SBR structs definitions $Revision: 92790 $
+*/
+
+#ifndef SBR_H
+#define SBR_H
+
+#include "fram_gen.h"
+#include "bit_sbr.h"
+#include "tran_det.h"
+#include "code_env.h"
+#include "env_est.h"
+#include "cmondata.h"
+
+#include "qmf.h"
+#include "resampler.h"
+
+#include "ton_corr.h"
+
+/* SBR bitstream delay */
+#define MAX_DELAY_FRAMES 2
+
+/* sbr encoder downsampling type */
+typedef enum { SBRENC_DS_NONE, SBRENC_DS_TIME, SBRENC_DS_QMF } SBRENC_DS_TYPE;
+
+typedef struct SBR_CHANNEL {
+ struct ENV_CHANNEL hEnvChannel;
+ // INT_PCM *pDSOutBuffer; /**< Pointer to
+ // downsampled audio output of SBR encoder */
+ DOWNSAMPLER downSampler;
+
+} SBR_CHANNEL;
+typedef SBR_CHANNEL* HANDLE_SBR_CHANNEL;
+
+typedef struct SBR_ELEMENT {
+ HANDLE_SBR_CHANNEL sbrChannel[2];
+ QMF_FILTER_BANK* hQmfAnalysis[2];
+ SBR_CONFIG_DATA sbrConfigData;
+ SBR_HEADER_DATA sbrHeaderData;
+ SBR_BITSTREAM_DATA sbrBitstreamData;
+ COMMON_DATA CmonData;
+ INT dynXOverFreqDelay[5]; /**< to delay a frame (I don't like it that much
+ that way - hrc) */
+ SBR_ELEMENT_INFO elInfo;
+
+ UCHAR payloadDelayLine[1 + MAX_DELAY_FRAMES][MAX_PAYLOAD_SIZE];
+ UINT payloadDelayLineSize[1 + MAX_DELAY_FRAMES]; /* Sizes in bits */
+
+} SBR_ELEMENT, *HANDLE_SBR_ELEMENT;
+
+typedef struct SBR_ENCODER {
+ HANDLE_SBR_ELEMENT sbrElement[(8)];
+ HANDLE_SBR_CHANNEL pSbrChannel[(8)];
+ QMF_FILTER_BANK QmfAnalysis[(8)];
+ DOWNSAMPLER lfeDownSampler;
+ int lfeChIdx; /* -1 default for no lfe, else assign channel index. */
+ int noElements; /* Number of elements. */
+ int nChannels; /* Total channel count across all elements. */
+ int frameSize; /* SBR framelength. */
+ int bufferOffset; /* Offset for SBR parameter extraction in time domain input
+ buffer. */
+ int downsampledOffset; /* Offset of downsampled/mixed output for core encoder.
+ */
+ int downmixSize; /* Size in samples of downsampled/mixed output for core
+ encoder. */
+ INT downSampleFactor; /* Sampling rate relation between the SBR and the core
+ encoder. */
+ SBRENC_DS_TYPE
+ downsamplingMethod; /* Method of downsmapling, time-domain, QMF or none.
+ */
+ int nBitstrDelay; /* Amount of SBR frames to be delayed in bitstream domain.
+ */
+ int sbrDecDelay; /* SBR decoder delay in samples */
+ INT estimateBitrate; /* Estimate bitrate of SBR encoder. */
+ INT inputDataDelay; /* Delay caused by downsampler, in/out buffer at
+ sbrEncoder_EncodeFrame. */
+
+ UCHAR* dynamicRam;
+ UCHAR* pSBRdynamic_RAM;
+
+ HANDLE_PARAMETRIC_STEREO hParametricStereo;
+ QMF_FILTER_BANK qmfSynthesisPS;
+
+ /* parameters describing allocation volume of present instance */
+ INT maxElements;
+ INT maxChannels;
+ INT supportPS;
+
+} SBR_ENCODER;
+
+#endif /* SBR_H */
diff --git a/fdk-aac/libSBRenc/src/sbr_def.h b/fdk-aac/libSBRenc/src/sbr_def.h
new file mode 100644
index 0000000..53eba71
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/sbr_def.h
@@ -0,0 +1,276 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief SBR main definitions $Revision: 92790 $
+*/
+#ifndef SBR_DEF_H
+#define SBR_DEF_H
+
+#include "common_fix.h"
+
+#define noError 0
+#define HANDLE_ERROR_INFO INT
+#define ERROR(a, b) 1
+
+/* #define SBR_ENV_STATISTICS_BITRATE */
+#undef SBR_ENV_STATISTICS_BITRATE
+
+/* #define SBR_ENV_STATISTICS */
+#undef SBR_ENV_STATISTICS
+
+/* #define SBR_PAYLOAD_MONITOR */
+#undef SBR_PAYLOAD_MONITOR
+
+#define SWAP(a, b) tempr = a, a = b, b = tempr
+#define TRUE 1
+#define FALSE 0
+
+/* Constants */
+#define EPS 1e-12
+#define LOG2 0.69314718056f /* natural logarithm of 2 */
+#define ILOG2 1.442695041f /* 1/LOG2 */
+#define RELAXATION_FLOAT (1e-6f)
+#define RELAXATION (FL2FXCONST_DBL(RELAXATION_FLOAT))
+#define RELAXATION_FRACT \
+ (FL2FXCONST_DBL(0.524288f)) /* 0.524288f is fractional part of RELAXATION */
+#define RELAXATION_SHIFT (19)
+#define RELAXATION_LD64 \
+ (FL2FXCONST_DBL(0.31143075889f)) /* (ld64(RELAXATION) \
+ */
+
+/************ Definitions ***************/
+#define SBR_COMP_MODE_DELTA 0
+#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_NOISE_ENVELOPES 2
+#define MAX_NUM_NOISE_COEFFS 5
+#define MAX_NUM_NOISE_VALUES (MAX_NUM_NOISE_COEFFS * MAX_NOISE_ENVELOPES)
+
+#define MAX_NUM_ENVELOPE_VALUES (MAX_ENVELOPES * MAX_FREQ_COEFFS)
+#define MAX_ENVELOPES 5
+#define MAX_FREQ_COEFFS 48
+
+#define MAX_FREQ_COEFFS_FS44100 35
+#define MAX_FREQ_COEFFS_FS48000 32
+
+#define NO_OF_ESTIMATES_LC 4
+#define NO_OF_ESTIMATES_LD 3
+#define MAX_NO_OF_ESTIMATES 4
+
+#define NOISE_FLOOR_OFFSET 6
+#define NOISE_FLOOR_OFFSET_64 (FL2FXCONST_DBL(0.09375f))
+
+#define LOW_RES 0
+#define HIGH_RES 1
+
+#define LO 0
+#define HI 1
+
+#define LENGTH_SBR_FRAME_INFO 35 /* 19 */
+
+#define SBR_NSFB_LOW_RES 9 /* 8 */
+#define SBR_NSFB_HIGH_RES 18 /* 16 */
+
+#define SBR_XPOS_CTRL_DEFAULT 2
+
+#define SBR_FREQ_SCALE_DEFAULT 2
+#define SBR_ALTER_SCALE_DEFAULT 1
+#define SBR_NOISE_BANDS_DEFAULT 2
+
+#define SBR_LIMITER_BANDS_DEFAULT 2
+#define SBR_LIMITER_GAINS_DEFAULT 2
+#define SBR_LIMITER_GAINS_INFINITE 3
+#define SBR_INTERPOL_FREQ_DEFAULT 1
+#define SBR_SMOOTHING_LENGTH_DEFAULT 0
+
+/* sbr_header */
+#define SI_SBR_AMP_RES_BITS 1
+#define SI_SBR_COUPLING_BITS 1
+#define SI_SBR_START_FREQ_BITS 4
+#define SI_SBR_STOP_FREQ_BITS 4
+#define SI_SBR_XOVER_BAND_BITS 3
+#define SI_SBR_RESERVED_BITS 2
+#define SI_SBR_DATA_EXTRA_BITS 1
+#define SI_SBR_HEADER_EXTRA_1_BITS 1
+#define SI_SBR_HEADER_EXTRA_2_BITS 1
+
+/* sbr_header extra 1 */
+#define SI_SBR_FREQ_SCALE_BITS 2
+#define SI_SBR_ALTER_SCALE_BITS 1
+#define SI_SBR_NOISE_BANDS_BITS 2
+
+/* sbr_header extra 2 */
+#define SI_SBR_LIMITER_BANDS_BITS 2
+#define SI_SBR_LIMITER_GAINS_BITS 2
+#define SI_SBR_INTERPOL_FREQ_BITS 1
+#define SI_SBR_SMOOTHING_LENGTH_BITS 1
+
+/* sbr_grid */
+#define SBR_CLA_BITS 2 /*!< size of bs_frame_class */
+#define SBR_CLA_BITS_LD 1 /*!< size of bs_frame_class */
+#define SBR_ENV_BITS 2 /*!< size of bs_num_env_raw */
+#define SBR_ABS_BITS 2 /*!< size of bs_abs_bord_raw for HE-AAC */
+#define SBR_NUM_BITS 2 /*!< size of bs_num_rel */
+#define SBR_REL_BITS 2 /*!< size of bs_rel_bord_raw */
+#define SBR_RES_BITS 1 /*!< size of bs_freq_res_flag */
+#define SBR_DIR_BITS 1 /*!< size of bs_df_flag */
+
+/* sbr_data */
+#define SI_SBR_INVF_MODE_BITS 2
+
+#define SI_SBR_START_ENV_BITS_AMP_RES_3_0 6
+#define SI_SBR_START_ENV_BITS_BALANCE_AMP_RES_3_0 5
+#define SI_SBR_START_NOISE_BITS_AMP_RES_3_0 5
+#define SI_SBR_START_NOISE_BITS_BALANCE_AMP_RES_3_0 5
+
+#define SI_SBR_START_ENV_BITS_AMP_RES_1_5 7
+#define SI_SBR_START_ENV_BITS_BALANCE_AMP_RES_1_5 6
+
+#define SI_SBR_EXTENDED_DATA_BITS 1
+#define SI_SBR_EXTENSION_SIZE_BITS 4
+#define SI_SBR_EXTENSION_ESC_COUNT_BITS 8
+#define SI_SBR_EXTENSION_ID_BITS 2
+
+#define SBR_EXTENDED_DATA_MAX_CNT (15 + 255)
+
+#define EXTENSION_ID_PS_CODING 2
+
+/* Envelope coding constants */
+#define FREQ 0
+#define TIME 1
+
+/* qmf data scaling */
+#define QMF_SCALE_OFFSET 7
+
+/* huffman tables */
+#define CODE_BOOK_SCF_LAV00 60
+#define CODE_BOOK_SCF_LAV01 31
+#define CODE_BOOK_SCF_LAV10 60
+#define CODE_BOOK_SCF_LAV11 31
+#define CODE_BOOK_SCF_LAV_BALANCE11 12
+#define CODE_BOOK_SCF_LAV_BALANCE10 24
+
+typedef enum { SBR_AMP_RES_1_5 = 0, SBR_AMP_RES_3_0 } AMP_RES;
+
+typedef enum {
+ XPOS_MDCT,
+ XPOS_MDCT_CROSS,
+ XPOS_LC,
+ XPOS_RESERVED,
+ XPOS_SWITCHED /* not a real choice but used here to control behaviour */
+} XPOS_MODE;
+
+typedef enum {
+ INVF_OFF = 0,
+ INVF_LOW_LEVEL,
+ INVF_MID_LEVEL,
+ INVF_HIGH_LEVEL,
+ INVF_SWITCHED /* not a real choice but used here to control behaviour */
+} INVF_MODE;
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/sbr_encoder.cpp b/fdk-aac/libSBRenc/src/sbr_encoder.cpp
new file mode 100644
index 0000000..26257a1
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/sbr_encoder.cpp
@@ -0,0 +1,2577 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s): Andreas Ehret, Tobias Chalupka
+
+ Description: SBR encoder top level processing.
+
+*******************************************************************************/
+
+#include "sbr_encoder.h"
+
+#include "sbrenc_ram.h"
+#include "sbrenc_rom.h"
+#include "sbrenc_freq_sca.h"
+#include "env_bit.h"
+#include "cmondata.h"
+#include "sbr_misc.h"
+#include "sbr.h"
+#include "qmf.h"
+
+#include "ps_main.h"
+
+#define SBRENCODER_LIB_VL0 4
+#define SBRENCODER_LIB_VL1 0
+#define SBRENCODER_LIB_VL2 0
+
+/***************************************************************************/
+/*
+ * SBR Delay balancing definitions.
+ */
+
+/*
+ input buffer (1ch)
+
+ |------------ 1537 -------------|-----|---------- 2048 -------------|
+ (core2sbr delay ) ds (read, core and ds area)
+*/
+
+#define SFB(dwnsmp) \
+ (32 << (dwnsmp - \
+ 1)) /* SBR Frequency bands: 64 for dual-rate, 32 for single-rate */
+#define STS(fl) \
+ (((fl) == 1024) ? 32 \
+ : 30) /* SBR Time Slots: 32 for core frame length 1024, 30 \
+ for core frame length 960 */
+
+#define DELAY_QMF_ANA(dwnsmp) \
+ ((320 << ((dwnsmp)-1)) - (32 << ((dwnsmp)-1))) /* Full bandwidth */
+#define DELAY_HYB_ANA (10 * 64) /* + 0.5 */ /* */
+#define DELAY_HYB_SYN (6 * 64 - 32) /* */
+#define DELAY_QMF_POSTPROC(dwnsmp) \
+ (32 * (dwnsmp)) /* QMF postprocessing delay */
+#define DELAY_DEC_QMF(dwnsmp) (6 * SFB(dwnsmp)) /* Decoder QMF overlap */
+#define DELAY_QMF_SYN(dwnsmp) \
+ (1 << (dwnsmp - \
+ 1)) /* QMF_NO_POLY/2=2.5, rounded down to 2, half for single-rate */
+#define DELAY_QMF_DS (32) /* QMF synthesis for downsampled time signal */
+
+/* Delay in QMF paths */
+#define DELAY_SBR(fl, dwnsmp) \
+ (DELAY_QMF_ANA(dwnsmp) + (SFB(dwnsmp) * STS(fl) - 1) + DELAY_QMF_SYN(dwnsmp))
+#define DELAY_PS(fl, dwnsmp) \
+ (DELAY_QMF_ANA(dwnsmp) + DELAY_HYB_ANA + DELAY_DEC_QMF(dwnsmp) + \
+ (SFB(dwnsmp) * STS(fl) - 1) + DELAY_HYB_SYN + DELAY_QMF_SYN(dwnsmp))
+#define DELAY_ELDSBR(fl, dwnsmp) \
+ ((((fl) / 2) * (dwnsmp)) - 1 + DELAY_QMF_POSTPROC(dwnsmp))
+#define DELAY_ELDv2SBR(fl, dwnsmp) \
+ ((((fl) / 2) * (dwnsmp)) - 1 + 80 * (dwnsmp)) /* 80 is the delay caused \
+ by the sum of the CLD \
+ analysis and the MPSLD \
+ synthesis filterbank */
+
+/* Delay in core path (core and downsampler not taken into account) */
+#define DELAY_COREPATH_SBR(fl, dwnsmp) \
+ ((DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_QMF_SYN(dwnsmp)))
+#define DELAY_COREPATH_ELDSBR(fl, dwnsmp) ((DELAY_QMF_POSTPROC(dwnsmp)))
+#define DELAY_COREPATH_ELDv2SBR(fl, dwnsmp) (128 * (dwnsmp)) /* 4 slots */
+#define DELAY_COREPATH_PS(fl, dwnsmp) \
+ ((DELAY_QMF_ANA(dwnsmp) + DELAY_QMF_DS + \
+ /*(DELAY_AAC(fl)*2) + */ DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + \
+ DELAY_HYB_SYN + DELAY_QMF_SYN(dwnsmp))) /* 2048 - 463*2 */
+
+/* Delay differences between SBR- and downsampled path for SBR and SBR+PS */
+#define DELAY_AAC2SBR(fl, dwnsmp) \
+ ((DELAY_COREPATH_SBR(fl, dwnsmp)) - DELAY_SBR((fl), (dwnsmp)))
+#define DELAY_ELD2SBR(fl, dwnsmp) \
+ ((DELAY_COREPATH_ELDSBR(fl, dwnsmp)) - DELAY_ELDSBR(fl, dwnsmp))
+#define DELAY_AAC2PS(fl, dwnsmp) \
+ ((DELAY_COREPATH_PS(fl, dwnsmp)) - DELAY_PS(fl, dwnsmp)) /* 2048 - 463*2 */
+
+/* Assumption: The sample delay resulting of of DELAY_AAC2PS is always smaller
+ * than the sample delay implied by DELAY_AAC2SBR */
+#define MAX_DS_FILTER_DELAY \
+ (5) /* the additional max downsampler filter delay (source fs) */
+#define MAX_SAMPLE_DELAY \
+ (DELAY_AAC2SBR(1024, 2) + MAX_DS_FILTER_DELAY) /* maximum delay: frame \
+ length of 1024 and \
+ dual-rate sbr */
+
+/***************************************************************************/
+
+/*************** Delay parameters for sbrEncoder_Init_delay() **************/
+typedef struct {
+ int dsDelay; /* the delay of the (time-domain) downsampler itself */
+ int delay; /* overall delay / samples */
+ int sbrDecDelay; /* SBR decoder's delay */
+ int corePathOffset; /* core path offset / samples; added by
+ sbrEncoder_Init_delay() */
+ int sbrPathOffset; /* SBR path offset / samples; added by
+ sbrEncoder_Init_delay() */
+ int bitstrDelay; /* bitstream delay / frames; added by sbrEncoder_Init_delay()
+ */
+ int delayInput2Core; /* delay of the input to the core / samples */
+} DELAY_PARAM;
+/***************************************************************************/
+
+#define INVALID_TABLE_IDX -1
+
+/***************************************************************************/
+/*!
+
+ \brief Selects the SBR tuning settings to use dependent on number of
+ channels, bitrate, sample rate and core coder
+
+ \return Index to the appropriate table
+
+****************************************************************************/
+#define DISTANCE_CEIL_VALUE 5000000
+static INT getSbrTuningTableIndex(
+ UINT bitrate, /*! the total bitrate in bits/sec */
+ UINT numChannels, /*! the number of channels for the core coder */
+ UINT sampleRate, /*! the sampling rate of the core coder */
+ AUDIO_OBJECT_TYPE core, UINT *pBitRateClosest) {
+ int i, bitRateClosestLowerIndex = -1, bitRateClosestUpperIndex = -1,
+ found = 0;
+ UINT bitRateClosestUpper = 0, bitRateClosestLower = DISTANCE_CEIL_VALUE;
+
+#define isForThisCore(i) \
+ ((sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD) || \
+ (sbrTuningTable[i].coreCoder == CODEC_AAC && core != AOT_ER_AAC_ELD))
+
+ for (i = 0; i < sbrTuningTableSize; i++) {
+ if (isForThisCore(i)) /* tuning table is for this core codec */
+ {
+ if (numChannels == sbrTuningTable[i].numChannels &&
+ sampleRate == sbrTuningTable[i].sampleRate) {
+ found = 1;
+ if ((bitrate >= sbrTuningTable[i].bitrateFrom) &&
+ (bitrate < sbrTuningTable[i].bitrateTo)) {
+ return i;
+ } else {
+ if (sbrTuningTable[i].bitrateFrom > bitrate) {
+ if (sbrTuningTable[i].bitrateFrom < bitRateClosestLower) {
+ bitRateClosestLower = sbrTuningTable[i].bitrateFrom;
+ bitRateClosestLowerIndex = i;
+ }
+ }
+ if (sbrTuningTable[i].bitrateTo <= bitrate) {
+ if (sbrTuningTable[i].bitrateTo > bitRateClosestUpper) {
+ bitRateClosestUpper = sbrTuningTable[i].bitrateTo - 1;
+ bitRateClosestUpperIndex = i;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (bitRateClosestUpperIndex >= 0) {
+ return bitRateClosestUpperIndex;
+ }
+
+ if (pBitRateClosest != NULL) {
+ /* If there was at least one matching tuning entry pick the least distance
+ * bit rate */
+ if (found) {
+ int distanceUpper = DISTANCE_CEIL_VALUE,
+ distanceLower = DISTANCE_CEIL_VALUE;
+ if (bitRateClosestLowerIndex >= 0) {
+ distanceLower =
+ sbrTuningTable[bitRateClosestLowerIndex].bitrateFrom - bitrate;
+ }
+ if (bitRateClosestUpperIndex >= 0) {
+ distanceUpper =
+ bitrate - sbrTuningTable[bitRateClosestUpperIndex].bitrateTo;
+ }
+ if (distanceUpper < distanceLower) {
+ *pBitRateClosest = bitRateClosestUpper;
+ } else {
+ *pBitRateClosest = bitRateClosestLower;
+ }
+ } else {
+ *pBitRateClosest = 0;
+ }
+ }
+
+ return INVALID_TABLE_IDX;
+}
+
+/***************************************************************************/
+/*!
+
+ \brief Selects the PS tuning settings to use dependent on bitrate
+ and core coder
+
+ \return Index to the appropriate table
+
+****************************************************************************/
+static INT getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest) {
+ INT i, paramSets = sizeof(psTuningTable) / sizeof(psTuningTable[0]);
+ int bitRateClosestLowerIndex = -1, bitRateClosestUpperIndex = -1;
+ UINT bitRateClosestUpper = 0, bitRateClosestLower = DISTANCE_CEIL_VALUE;
+
+ for (i = 0; i < paramSets; i++) {
+ if ((bitrate >= psTuningTable[i].bitrateFrom) &&
+ (bitrate < psTuningTable[i].bitrateTo)) {
+ return i;
+ } else {
+ if (psTuningTable[i].bitrateFrom > bitrate) {
+ if (psTuningTable[i].bitrateFrom < bitRateClosestLower) {
+ bitRateClosestLower = psTuningTable[i].bitrateFrom;
+ bitRateClosestLowerIndex = i;
+ }
+ }
+ if (psTuningTable[i].bitrateTo <= bitrate) {
+ if (psTuningTable[i].bitrateTo > bitRateClosestUpper) {
+ bitRateClosestUpper = psTuningTable[i].bitrateTo - 1;
+ bitRateClosestUpperIndex = i;
+ }
+ }
+ }
+ }
+
+ if (bitRateClosestUpperIndex >= 0) {
+ return bitRateClosestUpperIndex;
+ }
+
+ if (pBitRateClosest != NULL) {
+ int distanceUpper = DISTANCE_CEIL_VALUE,
+ distanceLower = DISTANCE_CEIL_VALUE;
+ if (bitRateClosestLowerIndex >= 0) {
+ distanceLower =
+ sbrTuningTable[bitRateClosestLowerIndex].bitrateFrom - bitrate;
+ }
+ if (bitRateClosestUpperIndex >= 0) {
+ distanceUpper =
+ bitrate - sbrTuningTable[bitRateClosestUpperIndex].bitrateTo;
+ }
+ if (distanceUpper < distanceLower) {
+ *pBitRateClosest = bitRateClosestUpper;
+ } else {
+ *pBitRateClosest = bitRateClosestLower;
+ }
+ }
+
+ return INVALID_TABLE_IDX;
+}
+
+/***************************************************************************/
+/*!
+
+ \brief In case of downsampled SBR we may need to lower the stop freq
+ of a tuning setting to fit into the lower half of the
+ spectrum ( which is sampleRate/4 )
+
+ \return the adapted stop frequency index (-1 -> error)
+
+ \ingroup SbrEncCfg
+
+****************************************************************************/
+static INT FDKsbrEnc_GetDownsampledStopFreq(const INT sampleRateCore,
+ const INT startFreq, INT stopFreq,
+ const INT downSampleFactor) {
+ INT maxStopFreqRaw = sampleRateCore / 2;
+ INT startBand, stopBand;
+ HANDLE_ERROR_INFO err;
+
+ while (stopFreq > 0 && FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) >
+ maxStopFreqRaw) {
+ stopFreq--;
+ }
+
+ if (FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > maxStopFreqRaw)
+ return -1;
+
+ err = FDKsbrEnc_FindStartAndStopBand(
+ sampleRateCore << (downSampleFactor - 1), sampleRateCore,
+ 32 << (downSampleFactor - 1), startFreq, stopFreq, &startBand, &stopBand);
+ if (err) return -1;
+
+ return stopFreq;
+}
+
+/***************************************************************************/
+/*!
+
+ \brief tells us, if for the given coreCoder, bitrate, number of channels
+ and input sampling rate an SBR setting is available. If yes, it
+ tells us also the core sampling rate we would need to run with
+
+ \return a flag indicating success: yes (1) or no (0)
+
+****************************************************************************/
+static UINT FDKsbrEnc_IsSbrSettingAvail(
+ UINT bitrate, /*! the total bitrate in bits/sec */
+ UINT vbrMode, /*! the vbr paramter, 0 means constant bitrate */
+ UINT numOutputChannels, /*! the number of channels for the core coder */
+ UINT sampleRateInput, /*! the input sample rate [in Hz] */
+ UINT sampleRateCore, /*! the core's sampling rate */
+ AUDIO_OBJECT_TYPE core) {
+ INT idx = INVALID_TABLE_IDX;
+
+ if (sampleRateInput < 16000) return 0;
+
+ if (bitrate == 0) {
+ /* map vbr quality to bitrate */
+ if (vbrMode < 30)
+ bitrate = 24000;
+ else if (vbrMode < 40)
+ bitrate = 28000;
+ else if (vbrMode < 60)
+ bitrate = 32000;
+ else if (vbrMode < 75)
+ bitrate = 40000;
+ else
+ bitrate = 48000;
+ bitrate *= numOutputChannels;
+ }
+
+ idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core,
+ NULL);
+
+ return (idx == INVALID_TABLE_IDX ? 0 : 1);
+}
+
+/***************************************************************************/
+/*!
+
+ \brief Adjusts the SBR settings according to the chosen core coder
+ settings which are accessible via config->codecSettings
+
+ \return A flag indicating success: yes (1) or no (0)
+
+****************************************************************************/
+static UINT FDKsbrEnc_AdjustSbrSettings(
+ const sbrConfigurationPtr config, /*! output, modified */
+ UINT bitRate, /*! the total bitrate in bits/sec */
+ UINT numChannels, /*! the core coder number of channels */
+ UINT sampleRateCore, /*! the core coder sampling rate in Hz */
+ UINT sampleRateSbr, /*! the sbr coder sampling rate in Hz */
+ UINT transFac, /*! the short block to long block ratio */
+ UINT standardBitrate, /*! the standard bitrate per channel in bits/sec */
+ UINT vbrMode, /*! the vbr paramter, 0 poor quality .. 100 high quality*/
+ UINT useSpeechConfig, /*!< adapt tuning parameters for speech ? */
+ UINT lcsMode, /*! the low complexity stereo mode */
+ UINT bParametricStereo, /*!< use parametric stereo */
+ AUDIO_OBJECT_TYPE core) /* Core audio codec object type */
+{
+ INT idx = INVALID_TABLE_IDX;
+ /* set the core codec settings */
+ config->codecSettings.bitRate = bitRate;
+ config->codecSettings.nChannels = numChannels;
+ config->codecSettings.sampleFreq = sampleRateCore;
+ config->codecSettings.transFac = transFac;
+ 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) {
+ /* map vbr quality to bitrate */
+ if (vbrMode < 30)
+ bitRate = 24000;
+ else if (vbrMode < 40)
+ bitRate = 28000;
+ else if (vbrMode < 60)
+ bitRate = 32000;
+ else if (vbrMode < 75)
+ bitRate = 40000;
+ else
+ bitRate = 48000;
+ bitRate *= numChannels;
+ /* fix to enable mono vbrMode<40 @ 44.1 of 48kHz */
+ if (numChannels == 1) {
+ if (sampleRateSbr == 44100 || sampleRateSbr == 48000) {
+ if (vbrMode < 40) bitRate = 32000;
+ }
+ }
+ }
+
+ idx =
+ getSbrTuningTableIndex(bitRate, numChannels, sampleRateCore, core, NULL);
+
+ if (idx != INVALID_TABLE_IDX) {
+ config->startFreq = sbrTuningTable[idx].startFreq;
+ config->stopFreq = sbrTuningTable[idx].stopFreq;
+ if (useSpeechConfig) {
+ config->startFreq = sbrTuningTable[idx].startFreqSpeech;
+ config->stopFreq = sbrTuningTable[idx].stopFreqSpeech;
+ }
+
+ /* Adapt stop frequency in case of downsampled SBR - only 32 bands then */
+ if (1 == config->downSampleFactor) {
+ INT dsStopFreq = FDKsbrEnc_GetDownsampledStopFreq(
+ sampleRateCore, config->startFreq, config->stopFreq,
+ config->downSampleFactor);
+ if (dsStopFreq < 0) {
+ return 0;
+ }
+
+ config->stopFreq = dsStopFreq;
+ }
+
+ config->sbr_noise_bands = sbrTuningTable[idx].numNoiseBands;
+ if (core == AOT_ER_AAC_ELD) config->init_amp_res_FF = SBR_AMP_RES_1_5;
+ config->noiseFloorOffset = sbrTuningTable[idx].noiseFloorOffset;
+
+ config->ana_max_level = sbrTuningTable[idx].noiseMaxLevel;
+ config->stereoMode = sbrTuningTable[idx].stereoMode;
+ 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 */
+ if (useSpeechConfig) config->parametricCoding = 0;
+
+ if (core == AOT_ER_AAC_ELD) {
+ if (bitRate < 28000) config->init_amp_res_FF = SBR_AMP_RES_3_0;
+ config->SendHeaderDataTime = -1;
+ }
+
+ if (numChannels == 1) {
+ if (bitRate < 16000) {
+ config->parametricCoding = 0;
+ }
+ } else {
+ if (bitRate < 20000) {
+ config->parametricCoding = 0;
+ }
+ }
+
+ config->useSpeechConfig = useSpeechConfig;
+
+ /* PS settings */
+ config->bParametricStereo = bParametricStereo;
+
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/*****************************************************************************
+
+ functionname: FDKsbrEnc_InitializeSbrDefaults
+ description: initializes the SBR configuration
+ returns: error status
+ input: - core codec type,
+ - factor of SBR to core frame length,
+ - core frame length
+ output: initialized SBR configuration
+
+*****************************************************************************/
+static UINT FDKsbrEnc_InitializeSbrDefaults(sbrConfigurationPtr config,
+ INT downSampleFactor,
+ UINT codecGranuleLen,
+ const INT isLowDelay) {
+ if ((downSampleFactor < 1 || downSampleFactor > 2) ||
+ (codecGranuleLen * downSampleFactor > 64 * 32))
+ return (0); /* error */
+
+ config->SendHeaderDataTime = 1000;
+ config->useWaveCoding = 0;
+ config->crcSbr = 0;
+ config->dynBwSupported = 1;
+ if (isLowDelay)
+ config->tran_thr = 6000;
+ else
+ config->tran_thr = 13000;
+
+ config->parametricCoding = 1;
+
+ config->sbrFrameSize = codecGranuleLen * downSampleFactor;
+ config->downSampleFactor = downSampleFactor;
+
+ /* sbr default parameters */
+ config->sbr_data_extra = 0;
+ config->amp_res = SBR_AMP_RES_3_0;
+ config->tran_fc = 0;
+ config->tran_det_mode = 1;
+ config->spread = 1;
+ config->stat = 0;
+ config->e = 1;
+ config->deltaTAcrossFrames = 1;
+ config->dF_edge_1stEnv = FL2FXCONST_DBL(0.3f);
+ config->dF_edge_incr = FL2FXCONST_DBL(0.3f);
+
+ config->sbr_invf_mode = INVF_SWITCHED;
+ config->sbr_xpos_mode = XPOS_LC;
+ config->sbr_xpos_ctrl = SBR_XPOS_CTRL_DEFAULT;
+ config->sbr_xpos_level = 0;
+ config->useSaPan = 0;
+ config->dynBwEnabled = 0;
+
+ /* the following parameters are overwritten by the
+ FDKsbrEnc_AdjustSbrSettings() function since they are included in the
+ tuning table */
+ config->stereoMode = SBR_SWITCH_LRC;
+ config->ana_max_level = 6;
+ config->noiseFloorOffset = 0;
+ 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->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 */
+ config->freqScale = SBR_FREQ_SCALE_DEFAULT;
+ config->alterScale = SBR_ALTER_SCALE_DEFAULT;
+ config->sbr_noise_bands = SBR_NOISE_BANDS_DEFAULT;
+
+ /* header_extra_2 */
+ config->sbr_limiter_bands = SBR_LIMITER_BANDS_DEFAULT;
+ config->sbr_limiter_gains = SBR_LIMITER_GAINS_DEFAULT;
+ config->sbr_interpol_freq = SBR_INTERPOL_FREQ_DEFAULT;
+ config->sbr_smoothing_length = SBR_SMOOTHING_LENGTH_DEFAULT;
+
+ return 1;
+}
+
+/*****************************************************************************
+
+ functionname: DeleteEnvChannel
+ description: frees memory of one SBR channel
+ returns: -
+ input: handle of channel
+ output: released handle
+
+*****************************************************************************/
+static void deleteEnvChannel(HANDLE_ENV_CHANNEL hEnvCut) {
+ if (hEnvCut) {
+ FDKsbrEnc_DeleteTonCorrParamExtr(&hEnvCut->TonCorr);
+
+ FDKsbrEnc_deleteExtractSbrEnvelope(&hEnvCut->sbrExtractEnvelope);
+ }
+}
+
+/*****************************************************************************
+
+ functionname: sbrEncoder_ChannelClose
+ description: close the channel coding handle
+ returns:
+ input: phSbrChannel
+ output:
+
+*****************************************************************************/
+static void sbrEncoder_ChannelClose(HANDLE_SBR_CHANNEL hSbrChannel) {
+ if (hSbrChannel != NULL) {
+ deleteEnvChannel(&hSbrChannel->hEnvChannel);
+ }
+}
+
+/*****************************************************************************
+
+ functionname: sbrEncoder_ElementClose
+ description: close the channel coding handle
+ returns:
+ input: phSbrChannel
+ output:
+
+*****************************************************************************/
+static void sbrEncoder_ElementClose(HANDLE_SBR_ELEMENT *phSbrElement) {
+ HANDLE_SBR_ELEMENT hSbrElement = *phSbrElement;
+
+ if (hSbrElement != NULL) {
+ if (hSbrElement->sbrConfigData.v_k_master)
+ FreeRam_Sbr_v_k_master(&hSbrElement->sbrConfigData.v_k_master);
+ if (hSbrElement->sbrConfigData.freqBandTable[LO])
+ FreeRam_Sbr_freqBandTableLO(
+ &hSbrElement->sbrConfigData.freqBandTable[LO]);
+ if (hSbrElement->sbrConfigData.freqBandTable[HI])
+ FreeRam_Sbr_freqBandTableHI(
+ &hSbrElement->sbrConfigData.freqBandTable[HI]);
+
+ FreeRam_SbrElement(phSbrElement);
+ }
+ return;
+}
+
+void sbrEncoder_Close(HANDLE_SBR_ENCODER *phSbrEncoder) {
+ HANDLE_SBR_ENCODER hSbrEncoder = *phSbrEncoder;
+
+ if (hSbrEncoder != NULL) {
+ int el, ch;
+
+ for (el = 0; el < (8); el++) {
+ if (hSbrEncoder->sbrElement[el] != NULL) {
+ sbrEncoder_ElementClose(&hSbrEncoder->sbrElement[el]);
+ }
+ }
+
+ /* Close sbr Channels */
+ for (ch = 0; ch < (8); ch++) {
+ if (hSbrEncoder->pSbrChannel[ch]) {
+ sbrEncoder_ChannelClose(hSbrEncoder->pSbrChannel[ch]);
+ FreeRam_SbrChannel(&hSbrEncoder->pSbrChannel[ch]);
+ }
+
+ if (hSbrEncoder->QmfAnalysis[ch].FilterStates)
+ FreeRam_Sbr_QmfStatesAnalysis(
+ (FIXP_QAS **)&hSbrEncoder->QmfAnalysis[ch].FilterStates);
+ }
+
+ if (hSbrEncoder->hParametricStereo)
+ PSEnc_Destroy(&hSbrEncoder->hParametricStereo);
+ if (hSbrEncoder->qmfSynthesisPS.FilterStates)
+ FreeRam_PsQmfStatesSynthesis(
+ (FIXP_DBL **)&hSbrEncoder->qmfSynthesisPS.FilterStates);
+
+ /* Release Overlay */
+ if (hSbrEncoder->pSBRdynamic_RAM)
+ FreeRam_SbrDynamic_RAM((FIXP_DBL **)&hSbrEncoder->pSBRdynamic_RAM);
+
+ FreeRam_SbrEncoder(phSbrEncoder);
+ }
+}
+
+/*****************************************************************************
+
+ functionname: updateFreqBandTable
+ description: updates vk_master
+ returns: -
+ input: config handle
+ output: error info
+
+*****************************************************************************/
+static INT updateFreqBandTable(HANDLE_SBR_CONFIG_DATA sbrConfigData,
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ const INT downSampleFactor) {
+ INT k0, k2;
+
+ if (FDKsbrEnc_FindStartAndStopBand(
+ sbrConfigData->sampleFreq,
+ sbrConfigData->sampleFreq >> (downSampleFactor - 1),
+ sbrConfigData->noQmfBands, sbrHeaderData->sbr_start_frequency,
+ sbrHeaderData->sbr_stop_frequency, &k0, &k2))
+ return (1);
+
+ if (FDKsbrEnc_UpdateFreqScale(
+ sbrConfigData->v_k_master, &sbrConfigData->num_Master, k0, k2,
+ sbrHeaderData->freqScale, sbrHeaderData->alterScale))
+ return (1);
+
+ sbrHeaderData->sbr_xover_band = 0;
+
+ if (FDKsbrEnc_UpdateHiRes(sbrConfigData->freqBandTable[HI],
+ &sbrConfigData->nSfb[HI], sbrConfigData->v_k_master,
+ sbrConfigData->num_Master,
+ &sbrHeaderData->sbr_xover_band))
+ return (1);
+
+ FDKsbrEnc_UpdateLoRes(
+ sbrConfigData->freqBandTable[LO], &sbrConfigData->nSfb[LO],
+ sbrConfigData->freqBandTable[HI], sbrConfigData->nSfb[HI]);
+
+ sbrConfigData->xOverFreq =
+ (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq /
+ sbrConfigData->noQmfBands +
+ 1) >>
+ 1;
+
+ return (0);
+}
+
+/*****************************************************************************
+
+ functionname: resetEnvChannel
+ description: resets parameters and allocates memory
+ returns: error status
+ input:
+ output: hEnv
+
+*****************************************************************************/
+static INT resetEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData,
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_ENV_CHANNEL hEnv) {
+ /* note !!! hEnv->encEnvData.noOfnoisebands will be updated later in function
+ * FDKsbrEnc_extractSbrEnvelope !!!*/
+ hEnv->TonCorr.sbrNoiseFloorEstimate.noiseBands =
+ sbrHeaderData->sbr_noise_bands;
+
+ if (FDKsbrEnc_ResetTonCorrParamExtr(
+ &hEnv->TonCorr, sbrConfigData->xposCtrlSwitch,
+ sbrConfigData->freqBandTable[HI][0], sbrConfigData->v_k_master,
+ sbrConfigData->num_Master, sbrConfigData->sampleFreq,
+ sbrConfigData->freqBandTable, sbrConfigData->nSfb,
+ sbrConfigData->noQmfBands))
+ return (1);
+
+ hEnv->sbrCodeNoiseFloor.nSfb[LO] =
+ hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
+ hEnv->sbrCodeNoiseFloor.nSfb[HI] =
+ hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
+
+ hEnv->sbrCodeEnvelope.nSfb[LO] = sbrConfigData->nSfb[LO];
+ hEnv->sbrCodeEnvelope.nSfb[HI] = sbrConfigData->nSfb[HI];
+
+ hEnv->encEnvData.noHarmonics = sbrConfigData->nSfb[HI];
+
+ hEnv->sbrCodeEnvelope.upDate = 0;
+ hEnv->sbrCodeNoiseFloor.upDate = 0;
+
+ return (0);
+}
+
+/* ****************************** FDKsbrEnc_SbrGetXOverFreq
+ * ******************************/
+/**
+ * @fn
+ * @brief calculates the closest possible crossover frequency
+ * @return the crossover frequency SBR accepts
+ *
+ */
+static INT FDKsbrEnc_SbrGetXOverFreq(
+ HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR encoder instance */
+ INT xoverFreq) /*!< from core coder suggested crossover frequency */
+{
+ INT band;
+ INT lastDiff, newDiff;
+ INT cutoffSb;
+
+ UCHAR *RESTRICT pVKMaster = hEnv->sbrConfigData.v_k_master;
+
+ /* Check if there is a matching cutoff frequency in the master table */
+ cutoffSb = (4 * xoverFreq * hEnv->sbrConfigData.noQmfBands /
+ hEnv->sbrConfigData.sampleFreq +
+ 1) >>
+ 1;
+ lastDiff = cutoffSb;
+ for (band = 0; band < hEnv->sbrConfigData.num_Master; band++) {
+ newDiff = fixp_abs((INT)pVKMaster[band] - cutoffSb);
+
+ if (newDiff >= lastDiff) {
+ band--;
+ break;
+ }
+
+ lastDiff = newDiff;
+ }
+
+ return ((pVKMaster[band] * hEnv->sbrConfigData.sampleFreq /
+ hEnv->sbrConfigData.noQmfBands +
+ 1) >>
+ 1);
+}
+
+/*****************************************************************************
+
+ functionname: FDKsbrEnc_EnvEncodeFrame
+ description: performs the sbr envelope calculation for one element
+ returns:
+ input:
+ output:
+
+*****************************************************************************/
+INT FDKsbrEnc_EnvEncodeFrame(
+ HANDLE_SBR_ENCODER hEnvEncoder, int iElement,
+ INT_PCM *samples, /*!< time samples, always deinterleaved */
+ UINT samplesBufSize, /*!< time buffer channel stride */
+ UINT *sbrDataBits, /*!< Size of SBR payload */
+ UCHAR *sbrData, /*!< SBR payload */
+ int clearOutput /*!< Do not consider any input signal */
+) {
+ HANDLE_SBR_ELEMENT hSbrElement = NULL;
+ FDK_CRCINFO crcInfo;
+ INT crcReg;
+ INT ch;
+ INT band;
+ INT cutoffSb;
+ INT newXOver;
+
+ if (hEnvEncoder == NULL) return -1;
+
+ hSbrElement = hEnvEncoder->sbrElement[iElement];
+
+ if (hSbrElement == NULL) return -1;
+
+ /* header bitstream handling */
+ HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData = &hSbrElement->sbrBitstreamData;
+
+ INT psHeaderActive = 0;
+ sbrBitstreamData->HeaderActive = 0;
+
+ /* Anticipate PS header because of internal PS bitstream delay in order to be
+ * in sync with SBR header. */
+ if (sbrBitstreamData->CountSendHeaderData ==
+ (sbrBitstreamData->NrSendHeaderData - 1)) {
+ psHeaderActive = 1;
+ }
+
+ /* Signal SBR header to be written into bitstream */
+ if (sbrBitstreamData->CountSendHeaderData == 0) {
+ sbrBitstreamData->HeaderActive = 1;
+ }
+
+ /* Increment header interval counter */
+ if (sbrBitstreamData->NrSendHeaderData == 0) {
+ sbrBitstreamData->CountSendHeaderData = 1;
+ } else {
+ if (sbrBitstreamData->CountSendHeaderData >= 0) {
+ sbrBitstreamData->CountSendHeaderData++;
+ sbrBitstreamData->CountSendHeaderData %=
+ sbrBitstreamData->NrSendHeaderData;
+ }
+ }
+
+ if (hSbrElement->CmonData.dynBwEnabled) {
+ INT i;
+ for (i = 4; i > 0; i--)
+ hSbrElement->dynXOverFreqDelay[i] = hSbrElement->dynXOverFreqDelay[i - 1];
+
+ hSbrElement->dynXOverFreqDelay[0] = hSbrElement->CmonData.dynXOverFreqEnc;
+ if (hSbrElement->dynXOverFreqDelay[1] > hSbrElement->dynXOverFreqDelay[2])
+ newXOver = hSbrElement->dynXOverFreqDelay[2];
+ else
+ newXOver = hSbrElement->dynXOverFreqDelay[1];
+
+ /* has the crossover frequency changed? */
+ if (hSbrElement->sbrConfigData.dynXOverFreq != newXOver) {
+ /* get corresponding master band */
+ cutoffSb = ((4 * newXOver * hSbrElement->sbrConfigData.noQmfBands /
+ hSbrElement->sbrConfigData.sampleFreq) +
+ 1) >>
+ 1;
+
+ for (band = 0; band < hSbrElement->sbrConfigData.num_Master; band++) {
+ if (cutoffSb == hSbrElement->sbrConfigData.v_k_master[band]) break;
+ }
+ FDK_ASSERT(band < hSbrElement->sbrConfigData.num_Master);
+
+ hSbrElement->sbrConfigData.dynXOverFreq = newXOver;
+ hSbrElement->sbrHeaderData.sbr_xover_band = band;
+ hSbrElement->sbrBitstreamData.HeaderActive = 1;
+ psHeaderActive = 1; /* ps header is one frame delayed */
+
+ /*
+ update vk_master table
+ */
+ if (updateFreqBandTable(&hSbrElement->sbrConfigData,
+ &hSbrElement->sbrHeaderData,
+ hEnvEncoder->downSampleFactor))
+ return (1);
+
+ /* reset SBR channels */
+ INT nEnvCh = hSbrElement->sbrConfigData.nChannels;
+ for (ch = 0; ch < nEnvCh; ch++) {
+ if (resetEnvChannel(&hSbrElement->sbrConfigData,
+ &hSbrElement->sbrHeaderData,
+ &hSbrElement->sbrChannel[ch]->hEnvChannel))
+ return (1);
+ }
+ }
+ }
+
+ /*
+ allocate space for dummy header and crc
+ */
+ crcReg = FDKsbrEnc_InitSbrBitstream(
+ &hSbrElement->CmonData,
+ hSbrElement->payloadDelayLine[hEnvEncoder->nBitstrDelay],
+ MAX_PAYLOAD_SIZE * sizeof(UCHAR), &crcInfo,
+ hSbrElement->sbrConfigData.sbrSyntaxFlags);
+
+ /* Temporal Envelope Data */
+ SBR_FRAME_TEMP_DATA _fData;
+ SBR_FRAME_TEMP_DATA *fData = &_fData;
+ SBR_ENV_TEMP_DATA eData[MAX_NUM_CHANNELS];
+
+ /* Init Temporal Envelope Data */
+ {
+ int i;
+
+ FDKmemclear(&eData[0], sizeof(SBR_ENV_TEMP_DATA));
+ FDKmemclear(&eData[1], sizeof(SBR_ENV_TEMP_DATA));
+ FDKmemclear(fData, sizeof(SBR_FRAME_TEMP_DATA));
+
+ for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) fData->res[i] = FREQ_RES_HIGH;
+ }
+
+ if (!clearOutput) {
+ /*
+ * Transform audio data into QMF domain
+ */
+ for (ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) {
+ HANDLE_ENV_CHANNEL h_envChan = &hSbrElement->sbrChannel[ch]->hEnvChannel;
+ HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &h_envChan->sbrExtractEnvelope;
+
+ if (hSbrElement->elInfo.fParametricStereo == 0) {
+ QMF_SCALE_FACTOR tmpScale;
+ FIXP_DBL **pQmfReal, **pQmfImag;
+ C_AALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, 64 * 2)
+
+ /* Obtain pointers to QMF buffers. */
+ pQmfReal = sbrExtrEnv->rBuffer;
+ pQmfImag = sbrExtrEnv->iBuffer;
+
+ qmfAnalysisFiltering(
+ hSbrElement->hQmfAnalysis[ch], pQmfReal, pQmfImag, &tmpScale,
+ samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize, 0,
+ 1, qmfWorkBuffer);
+
+ h_envChan->qmfScale = tmpScale.lb_scale + 7;
+
+ C_AALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, 64 * 2)
+
+ } /* fParametricStereo == 0 */
+
+ /*
+ Parametric Stereo processing
+ */
+ if (hSbrElement->elInfo.fParametricStereo) {
+ INT error = noError;
+
+ /* Limit Parametric Stereo to one instance */
+ FDK_ASSERT(ch == 0);
+
+ if (error == noError) {
+ /* parametric stereo processing:
+ - input:
+ o left and right time domain samples
+ - processing:
+ o stereo qmf analysis
+ o stereo hybrid analysis
+ o ps parameter extraction
+ o downmix + hybrid synthesis
+ - output:
+ o downmixed qmf data is written to sbrExtrEnv->rBuffer and
+ sbrExtrEnv->iBuffer
+ */
+ SCHAR qmfScale;
+ INT_PCM *pSamples[2] = {
+ samples + hSbrElement->elInfo.ChannelIndex[0] * samplesBufSize,
+ samples + hSbrElement->elInfo.ChannelIndex[1] * samplesBufSize};
+ error = FDKsbrEnc_PSEnc_ParametricStereoProcessing(
+ hEnvEncoder->hParametricStereo, pSamples, samplesBufSize,
+ hSbrElement->hQmfAnalysis, sbrExtrEnv->rBuffer,
+ sbrExtrEnv->iBuffer,
+ samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize,
+ &hEnvEncoder->qmfSynthesisPS, &qmfScale, psHeaderActive);
+ h_envChan->qmfScale = (int)qmfScale;
+ }
+
+ } /* if (hEnvEncoder->hParametricStereo) */
+
+ /*
+
+ Extract Envelope relevant things from QMF data
+
+ */
+ FDKsbrEnc_extractSbrEnvelope1(&hSbrElement->sbrConfigData,
+ &hSbrElement->sbrHeaderData,
+ &hSbrElement->sbrBitstreamData, h_envChan,
+ &hSbrElement->CmonData, &eData[ch], fData);
+
+ } /* hEnvEncoder->sbrConfigData.nChannels */
+ }
+
+ /*
+ Process Envelope relevant things and calculate envelope data and write
+ payload
+ */
+ FDKsbrEnc_extractSbrEnvelope2(
+ &hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData,
+ (hSbrElement->elInfo.fParametricStereo) ? hEnvEncoder->hParametricStereo
+ : NULL,
+ &hSbrElement->sbrBitstreamData, &hSbrElement->sbrChannel[0]->hEnvChannel,
+ (hSbrElement->sbrConfigData.stereoMode != SBR_MONO)
+ ? &hSbrElement->sbrChannel[1]->hEnvChannel
+ : NULL,
+ &hSbrElement->CmonData, eData, fData, clearOutput);
+
+ hSbrElement->sbrBitstreamData.rightBorderFIX = 0;
+
+ /*
+ format payload, calculate crc
+ */
+ FDKsbrEnc_AssembleSbrBitstream(&hSbrElement->CmonData, &crcInfo, crcReg,
+ hSbrElement->sbrConfigData.sbrSyntaxFlags);
+
+ /*
+ save new payload, set to zero length if greater than MAX_PAYLOAD_SIZE
+ */
+ hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] =
+ FDKgetValidBits(&hSbrElement->CmonData.sbrBitbuf);
+
+ if (hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] >
+ (MAX_PAYLOAD_SIZE << 3))
+ hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = 0;
+
+ /* While filling the Delay lines, sbrData is NULL */
+ if (sbrData) {
+ *sbrDataBits = hSbrElement->payloadDelayLineSize[0];
+ FDKmemcpy(sbrData, hSbrElement->payloadDelayLine[0],
+ (hSbrElement->payloadDelayLineSize[0] + 7) >> 3);
+ }
+
+ /* delay header active flag */
+ if (hSbrElement->sbrBitstreamData.HeaderActive == 1) {
+ hSbrElement->sbrBitstreamData.HeaderActiveDelay =
+ 1 + hEnvEncoder->nBitstrDelay;
+ } else {
+ if (hSbrElement->sbrBitstreamData.HeaderActiveDelay > 0) {
+ hSbrElement->sbrBitstreamData.HeaderActiveDelay--;
+ }
+ }
+
+ return (0);
+}
+
+/*****************************************************************************
+
+ functionname: FDKsbrEnc_Downsample
+ description: performs downsampling and delay compensation of the core path
+ returns:
+ input:
+ output:
+
+*****************************************************************************/
+INT FDKsbrEnc_Downsample(
+ HANDLE_SBR_ENCODER hSbrEncoder,
+ INT_PCM *samples, /*!< time samples, always deinterleaved */
+ UINT samplesBufSize, /*!< time buffer size per channel */
+ UINT numChannels, /*!< number of channels */
+ UINT *sbrDataBits, /*!< Size of SBR payload */
+ UCHAR *sbrData, /*!< SBR payload */
+ int clearOutput /*!< Do not consider any input signal */
+) {
+ HANDLE_SBR_ELEMENT hSbrElement = NULL;
+ INT nOutSamples;
+ int el;
+ if (hSbrEncoder->downSampleFactor > 1) {
+ /* Do downsampling */
+
+ /* Loop over elements (LFE is handled later) */
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ hSbrElement = hSbrEncoder->sbrElement[el];
+ if (hSbrEncoder->sbrElement[el] != NULL) {
+ if (hSbrEncoder->downsamplingMethod == SBRENC_DS_TIME) {
+ int ch;
+ int nChannels = hSbrElement->sbrConfigData.nChannels;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ FDKaacEnc_Downsample(
+ &hSbrElement->sbrChannel[ch]->downSampler,
+ samples +
+ hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize +
+ hSbrEncoder->bufferOffset / numChannels,
+ hSbrElement->sbrConfigData.frameSize,
+ samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize,
+ &nOutSamples);
+ }
+ }
+ }
+ }
+
+ /* Handle LFE (if existing) */
+ if (hSbrEncoder->lfeChIdx != -1) { /* lfe downsampler */
+ FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler,
+ samples + hSbrEncoder->lfeChIdx * samplesBufSize +
+ hSbrEncoder->bufferOffset / numChannels,
+ hSbrEncoder->frameSize,
+ samples + hSbrEncoder->lfeChIdx * samplesBufSize,
+ &nOutSamples);
+ }
+ } else {
+ /* No downsampling. Still, some buffer shifting for correct delay */
+ int samples2Copy = hSbrEncoder->frameSize;
+ if (hSbrEncoder->bufferOffset / (int)numChannels < samples2Copy) {
+ for (int c = 0; c < (int)numChannels; c++) {
+ /* Do memmove while taking care of overlapping memory areas. (memcpy
+ does not necessarily take care) Distinguish between oeverlapping and
+ non overlapping version due to reasons of complexity. */
+ FDKmemmove(samples + c * samplesBufSize,
+ samples + c * samplesBufSize +
+ hSbrEncoder->bufferOffset / numChannels,
+ samples2Copy * sizeof(INT_PCM));
+ }
+ } else {
+ for (int c = 0; c < (int)numChannels; c++) {
+ /* Simple memcpy since the memory areas are not overlapping */
+ FDKmemcpy(samples + c * samplesBufSize,
+ samples + c * samplesBufSize +
+ hSbrEncoder->bufferOffset / numChannels,
+ samples2Copy * sizeof(INT_PCM));
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+
+ functionname: createEnvChannel
+ description: initializes parameters and allocates memory
+ returns: error status
+ input:
+ output: hEnv
+
+*****************************************************************************/
+
+static INT createEnvChannel(HANDLE_ENV_CHANNEL hEnv, INT channel,
+ UCHAR *dynamic_RAM) {
+ FDKmemclear(hEnv, sizeof(struct ENV_CHANNEL));
+
+ if (FDKsbrEnc_CreateTonCorrParamExtr(&hEnv->TonCorr, channel)) {
+ return (1);
+ }
+
+ if (FDKsbrEnc_CreateExtractSbrEnvelope(&hEnv->sbrExtractEnvelope, channel,
+ /*chan*/ 0, dynamic_RAM)) {
+ return (1);
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+
+ functionname: initEnvChannel
+ description: initializes parameters
+ returns: error status
+ input:
+ output:
+
+*****************************************************************************/
+static INT initEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData,
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_ENV_CHANNEL hEnv, sbrConfigurationPtr params,
+ ULONG statesInitFlag, INT chanInEl,
+ UCHAR *dynamic_RAM) {
+ int frameShift, tran_off = 0;
+ INT e;
+ INT tran_fc;
+ INT timeSlots, timeStep, startIndex;
+ INT noiseBands[2] = {3, 3};
+
+ e = 1 << params->e;
+
+ FDK_ASSERT(params->e >= 0);
+
+ 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->encEnvData.ldGrid =
+ (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0;
+
+ hEnv->encEnvData.sbr_xpos_mode = (XPOS_MODE)params->sbr_xpos_mode;
+
+ if (hEnv->encEnvData.sbr_xpos_mode == XPOS_SWITCHED) {
+ /*
+ no other type than XPOS_MDCT or XPOS_SPEECH allowed,
+ but enable switching
+ */
+ sbrConfigData->switchTransposers = TRUE;
+ hEnv->encEnvData.sbr_xpos_mode = XPOS_MDCT;
+ } else {
+ sbrConfigData->switchTransposers = FALSE;
+ }
+
+ hEnv->encEnvData.sbr_xpos_ctrl = params->sbr_xpos_ctrl;
+
+ /* extended data */
+ if (params->parametricCoding) {
+ hEnv->encEnvData.extended_data = 1;
+ } else {
+ hEnv->encEnvData.extended_data = 0;
+ }
+
+ hEnv->encEnvData.extension_size = 0;
+
+ startIndex = QMF_FILTER_PROTOTYPE_SIZE - sbrConfigData->noQmfBands;
+
+ switch (params->sbrFrameSize) {
+ case 2304:
+ timeSlots = 18;
+ break;
+ case 2048:
+ case 1024:
+ case 512:
+ timeSlots = 16;
+ break;
+ case 1920:
+ case 960:
+ case 480:
+ timeSlots = 15;
+ break;
+ case 1152:
+ timeSlots = 9;
+ break;
+ default:
+ return (1); /* Illegal frame size */
+ }
+
+ timeStep = sbrConfigData->noQmfSlots / timeSlots;
+
+ if (FDKsbrEnc_InitTonCorrParamExtr(
+ params->sbrFrameSize, &hEnv->TonCorr, sbrConfigData, timeSlots,
+ params->sbr_xpos_ctrl, params->ana_max_level,
+ sbrHeaderData->sbr_noise_bands, params->noiseFloorOffset,
+ params->useSpeechConfig))
+ return (1);
+
+ hEnv->encEnvData.noOfnoisebands =
+ hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
+
+ noiseBands[0] = hEnv->encEnvData.noOfnoisebands;
+ noiseBands[1] = hEnv->encEnvData.noOfnoisebands;
+
+ hEnv->encEnvData.sbr_invf_mode = (INVF_MODE)params->sbr_invf_mode;
+
+ if (hEnv->encEnvData.sbr_invf_mode == INVF_SWITCHED) {
+ hEnv->encEnvData.sbr_invf_mode = INVF_MID_LEVEL;
+ hEnv->TonCorr.switchInverseFilt = TRUE;
+ } else {
+ hEnv->TonCorr.switchInverseFilt = FALSE;
+ }
+
+ tran_fc = params->tran_fc;
+
+ if (tran_fc == 0) {
+ tran_fc = fixMin(
+ 5000, FDKsbrEnc_getSbrStartFreqRAW(sbrHeaderData->sbr_start_frequency,
+ params->codecSettings.sampleFreq));
+ }
+
+ tran_fc =
+ (tran_fc * 4 * sbrConfigData->noQmfBands / sbrConfigData->sampleFreq +
+ 1) >>
+ 1;
+
+ if (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
+ frameShift = LD_PRETRAN_OFF;
+ tran_off = LD_PRETRAN_OFF + FRAME_MIDDLE_SLOT_512LD * timeStep;
+ } else {
+ frameShift = 0;
+ switch (timeSlots) {
+ /* The factor of 2 is by definition. */
+ case NUMBER_TIME_SLOTS_2048:
+ tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep;
+ break;
+ case NUMBER_TIME_SLOTS_1920:
+ tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep;
+ break;
+ default:
+ return 1;
+ }
+ }
+ if (FDKsbrEnc_InitExtractSbrEnvelope(
+ &hEnv->sbrExtractEnvelope, sbrConfigData->noQmfSlots,
+ sbrConfigData->noQmfBands, startIndex, timeSlots, timeStep, tran_off,
+ statesInitFlag, chanInEl, dynamic_RAM, sbrConfigData->sbrSyntaxFlags))
+ return (1);
+
+ if (FDKsbrEnc_InitSbrCodeEnvelope(&hEnv->sbrCodeEnvelope, sbrConfigData->nSfb,
+ params->deltaTAcrossFrames,
+ params->dF_edge_1stEnv,
+ params->dF_edge_incr))
+ return (1);
+
+ if (FDKsbrEnc_InitSbrCodeEnvelope(&hEnv->sbrCodeNoiseFloor, noiseBands,
+ params->deltaTAcrossFrames, 0, 0))
+ return (1);
+
+ sbrConfigData->initAmpResFF = params->init_amp_res_FF;
+
+ if (FDKsbrEnc_InitSbrHuffmanTables(&hEnv->encEnvData, &hEnv->sbrCodeEnvelope,
+ &hEnv->sbrCodeNoiseFloor,
+ sbrHeaderData->sbr_amp_res))
+ return (1);
+
+ FDKsbrEnc_initFrameInfoGenerator(
+ &hEnv->SbrEnvFrame, params->spread, e, params->stat, timeSlots,
+ hEnv->encEnvData.freq_res_fixfix, 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, sbrConfigData->sbrSyntaxFlags,
+ sbrConfigData->frameSize, sbrConfigData->sampleFreq, params, tran_fc,
+ sbrConfigData->noQmfSlots, sbrConfigData->noQmfBands,
+ hEnv->sbrExtractEnvelope.YBufferWriteOffset,
+ hEnv->sbrExtractEnvelope.YBufferSzShift, frameShift, tran_off))
+ return (1);
+
+ sbrConfigData->xposCtrlSwitch = params->sbr_xpos_ctrl;
+
+ hEnv->encEnvData.noHarmonics = sbrConfigData->nSfb[HI];
+ hEnv->encEnvData.addHarmonicFlag = 0;
+
+ return (0);
+}
+
+INT sbrEncoder_Open(HANDLE_SBR_ENCODER *phSbrEncoder, INT nElements,
+ INT nChannels, INT supportPS) {
+ INT i;
+ INT errorStatus = 1;
+ HANDLE_SBR_ENCODER hSbrEncoder = NULL;
+
+ if (phSbrEncoder == NULL) {
+ goto bail;
+ }
+
+ hSbrEncoder = GetRam_SbrEncoder();
+ if (hSbrEncoder == NULL) {
+ goto bail;
+ }
+ FDKmemclear(hSbrEncoder, sizeof(SBR_ENCODER));
+
+ if (NULL ==
+ (hSbrEncoder->pSBRdynamic_RAM = (UCHAR *)GetRam_SbrDynamic_RAM())) {
+ goto bail;
+ }
+ hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM;
+
+ /* Create SBR elements */
+ for (i = 0; i < nElements; i++) {
+ hSbrEncoder->sbrElement[i] = GetRam_SbrElement(i);
+ if (hSbrEncoder->sbrElement[i] == NULL) {
+ goto bail;
+ }
+ FDKmemclear(hSbrEncoder->sbrElement[i], sizeof(SBR_ELEMENT));
+ hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] =
+ GetRam_Sbr_freqBandTableLO(i);
+ hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] =
+ GetRam_Sbr_freqBandTableHI(i);
+ hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master =
+ GetRam_Sbr_v_k_master(i);
+ if ((hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] == NULL) ||
+ (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] == NULL) ||
+ (hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master == NULL)) {
+ goto bail;
+ }
+ }
+
+ /* Create SBR channels */
+ for (i = 0; i < nChannels; i++) {
+ hSbrEncoder->pSbrChannel[i] = GetRam_SbrChannel(i);
+ if (hSbrEncoder->pSbrChannel[i] == NULL) {
+ goto bail;
+ }
+
+ if (createEnvChannel(&hSbrEncoder->pSbrChannel[i]->hEnvChannel, i,
+ hSbrEncoder->dynamicRam)) {
+ goto bail;
+ }
+ }
+
+ /* Create QMF States */
+ for (i = 0; i < fixMax(nChannels, (supportPS) ? 2 : 0); i++) {
+ hSbrEncoder->QmfAnalysis[i].FilterStates = GetRam_Sbr_QmfStatesAnalysis(i);
+ if (hSbrEncoder->QmfAnalysis[i].FilterStates == NULL) {
+ goto bail;
+ }
+ }
+
+ /* Create Parametric Stereo handle */
+ if (supportPS) {
+ if (PSEnc_Create(&hSbrEncoder->hParametricStereo)) {
+ goto bail;
+ }
+
+ hSbrEncoder->qmfSynthesisPS.FilterStates = GetRam_PsQmfStatesSynthesis();
+ if (hSbrEncoder->qmfSynthesisPS.FilterStates == NULL) {
+ goto bail;
+ }
+ } /* supportPS */
+
+ *phSbrEncoder = hSbrEncoder;
+
+ errorStatus = 0;
+ return errorStatus;
+
+bail:
+ /* Close SBR encoder instance */
+ sbrEncoder_Close(&hSbrEncoder);
+ return errorStatus;
+}
+
+static INT FDKsbrEnc_Reallocate(HANDLE_SBR_ENCODER hSbrEncoder,
+ SBR_ELEMENT_INFO elInfo[(8)],
+ const INT noElements) {
+ INT totalCh = 0;
+ INT totalQmf = 0;
+ INT coreEl;
+ INT el = -1;
+
+ hSbrEncoder->lfeChIdx = -1; /* default value, until lfe found */
+
+ for (coreEl = 0; coreEl < noElements; coreEl++) {
+ /* SBR only handles SCE and CPE's */
+ if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) {
+ el++;
+ } else {
+ if (elInfo[coreEl].elType == ID_LFE) {
+ hSbrEncoder->lfeChIdx = elInfo[coreEl].ChannelIndex[0];
+ }
+ continue;
+ }
+
+ SBR_ELEMENT_INFO *pelInfo = &elInfo[coreEl];
+ HANDLE_SBR_ELEMENT hSbrElement = hSbrEncoder->sbrElement[el];
+
+ int ch;
+ for (ch = 0; ch < pelInfo->nChannelsInEl; ch++) {
+ hSbrElement->sbrChannel[ch] = hSbrEncoder->pSbrChannel[totalCh];
+ totalCh++;
+ }
+ /* analysis QMF */
+ for (ch = 0;
+ ch < ((pelInfo->fParametricStereo) ? 2 : pelInfo->nChannelsInEl);
+ ch++) {
+ hSbrElement->elInfo.ChannelIndex[ch] = pelInfo->ChannelIndex[ch];
+ hSbrElement->hQmfAnalysis[ch] = &hSbrEncoder->QmfAnalysis[totalQmf++];
+ }
+
+ /* Copy Element info */
+ hSbrElement->elInfo.elType = pelInfo->elType;
+ hSbrElement->elInfo.instanceTag = pelInfo->instanceTag;
+ hSbrElement->elInfo.nChannelsInEl = pelInfo->nChannelsInEl;
+ hSbrElement->elInfo.fParametricStereo = pelInfo->fParametricStereo;
+ hSbrElement->elInfo.fDualMono = pelInfo->fDualMono;
+ } /* coreEl */
+
+ return 0;
+}
+
+/*****************************************************************************
+
+ functionname: FDKsbrEnc_bsBufInit
+ description: initializes bitstream buffer
+ returns: initialized bitstream buffer in env encoder
+ input:
+ output: hEnv
+
+*****************************************************************************/
+static INT FDKsbrEnc_bsBufInit(HANDLE_SBR_ELEMENT hSbrElement,
+ int nBitstrDelay) {
+ UCHAR *bitstreamBuffer;
+
+ /* initialize the bitstream buffer */
+ bitstreamBuffer = hSbrElement->payloadDelayLine[nBitstrDelay];
+ FDKinitBitStream(&hSbrElement->CmonData.sbrBitbuf, bitstreamBuffer,
+ MAX_PAYLOAD_SIZE * sizeof(UCHAR), 0, BS_WRITER);
+
+ return (0);
+}
+
+/*****************************************************************************
+
+ functionname: FDKsbrEnc_EnvInit
+ description: initializes parameters
+ returns: error status
+ input:
+ output: hEnv
+
+*****************************************************************************/
+static INT FDKsbrEnc_EnvInit(HANDLE_SBR_ELEMENT hSbrElement,
+ sbrConfigurationPtr params, INT *coreBandWith,
+ AUDIO_OBJECT_TYPE aot, int nElement,
+ const int headerPeriod, ULONG statesInitFlag,
+ const SBRENC_DS_TYPE downsamplingMethod,
+ UCHAR *dynamic_RAM) {
+ int ch, i;
+
+ if ((params->codecSettings.nChannels < 1) ||
+ (params->codecSettings.nChannels > MAX_NUM_CHANNELS)) {
+ return (1);
+ }
+
+ /* init and set syntax flags */
+ hSbrElement->sbrConfigData.sbrSyntaxFlags = 0;
+
+ switch (aot) {
+ case AOT_ER_AAC_ELD:
+ hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY;
+ break;
+ default:
+ break;
+ }
+ if (params->crcSbr) {
+ hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC;
+ }
+
+ hSbrElement->sbrConfigData.noQmfBands = 64 >> (2 - params->downSampleFactor);
+ switch (hSbrElement->sbrConfigData.noQmfBands) {
+ case 64:
+ hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 6;
+ break;
+ case 32:
+ hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 5;
+ break;
+ default:
+ hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 6;
+ return (2);
+ }
+
+ /*
+ now initialize sbrConfigData, sbrHeaderData and sbrBitstreamData,
+ */
+ hSbrElement->sbrConfigData.nChannels = params->codecSettings.nChannels;
+
+ if (params->codecSettings.nChannels == 2) {
+ if ((hSbrElement->elInfo.elType == ID_CPE) &&
+ ((hSbrElement->elInfo.fDualMono == 1))) {
+ hSbrElement->sbrConfigData.stereoMode = SBR_LEFT_RIGHT;
+ } else {
+ hSbrElement->sbrConfigData.stereoMode = params->stereoMode;
+ }
+ } else {
+ hSbrElement->sbrConfigData.stereoMode = SBR_MONO;
+ }
+
+ hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize;
+
+ hSbrElement->sbrConfigData.sampleFreq =
+ params->downSampleFactor * params->codecSettings.sampleFreq;
+
+ hSbrElement->sbrBitstreamData.CountSendHeaderData = 0;
+ if (params->SendHeaderDataTime > 0) {
+ if (headerPeriod == -1) {
+ hSbrElement->sbrBitstreamData.NrSendHeaderData = (INT)(
+ params->SendHeaderDataTime * hSbrElement->sbrConfigData.sampleFreq /
+ (1000 * hSbrElement->sbrConfigData.frameSize));
+ hSbrElement->sbrBitstreamData.NrSendHeaderData =
+ fixMax(hSbrElement->sbrBitstreamData.NrSendHeaderData, 1);
+ } else {
+ /* assure header period at least once per second */
+ hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMin(
+ fixMax(headerPeriod, 1), (hSbrElement->sbrConfigData.sampleFreq /
+ hSbrElement->sbrConfigData.frameSize));
+ }
+ } else {
+ hSbrElement->sbrBitstreamData.NrSendHeaderData = 0;
+ }
+
+ hSbrElement->sbrHeaderData.sbr_data_extra = params->sbr_data_extra;
+ hSbrElement->sbrBitstreamData.HeaderActive = 0;
+ hSbrElement->sbrBitstreamData.rightBorderFIX = 0;
+ hSbrElement->sbrHeaderData.sbr_start_frequency = params->startFreq;
+ hSbrElement->sbrHeaderData.sbr_stop_frequency = params->stopFreq;
+ hSbrElement->sbrHeaderData.sbr_xover_band = 0;
+ hSbrElement->sbrHeaderData.sbr_lc_stereo_mode = 0;
+
+ /* data_extra */
+ if (params->sbr_xpos_ctrl != SBR_XPOS_CTRL_DEFAULT)
+ hSbrElement->sbrHeaderData.sbr_data_extra = 1;
+
+ hSbrElement->sbrHeaderData.sbr_amp_res = (AMP_RES)params->amp_res;
+
+ /* header_extra_1 */
+ hSbrElement->sbrHeaderData.freqScale = params->freqScale;
+ hSbrElement->sbrHeaderData.alterScale = params->alterScale;
+ hSbrElement->sbrHeaderData.sbr_noise_bands = params->sbr_noise_bands;
+ hSbrElement->sbrHeaderData.header_extra_1 = 0;
+
+ if ((params->freqScale != SBR_FREQ_SCALE_DEFAULT) ||
+ (params->alterScale != SBR_ALTER_SCALE_DEFAULT) ||
+ (params->sbr_noise_bands != SBR_NOISE_BANDS_DEFAULT)) {
+ hSbrElement->sbrHeaderData.header_extra_1 = 1;
+ }
+
+ /* header_extra_2 */
+ hSbrElement->sbrHeaderData.sbr_limiter_bands = params->sbr_limiter_bands;
+ hSbrElement->sbrHeaderData.sbr_limiter_gains = params->sbr_limiter_gains;
+
+ if ((hSbrElement->sbrConfigData.sampleFreq > 48000) &&
+ (hSbrElement->sbrHeaderData.sbr_start_frequency >= 9)) {
+ hSbrElement->sbrHeaderData.sbr_limiter_gains = SBR_LIMITER_GAINS_INFINITE;
+ }
+
+ hSbrElement->sbrHeaderData.sbr_interpol_freq = params->sbr_interpol_freq;
+ hSbrElement->sbrHeaderData.sbr_smoothing_length =
+ params->sbr_smoothing_length;
+ hSbrElement->sbrHeaderData.header_extra_2 = 0;
+
+ if ((params->sbr_limiter_bands != SBR_LIMITER_BANDS_DEFAULT) ||
+ (params->sbr_limiter_gains != SBR_LIMITER_GAINS_DEFAULT) ||
+ (params->sbr_interpol_freq != SBR_INTERPOL_FREQ_DEFAULT) ||
+ (params->sbr_smoothing_length != SBR_SMOOTHING_LENGTH_DEFAULT)) {
+ hSbrElement->sbrHeaderData.header_extra_2 = 1;
+ }
+
+ /* other switches */
+ hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding;
+ 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 */
+ if (updateFreqBandTable(&hSbrElement->sbrConfigData,
+ &hSbrElement->sbrHeaderData,
+ params->downSampleFactor)) {
+ return (1);
+ }
+
+ /* now create envelope ext and QMF for each available channel */
+ for (ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) {
+ if (initEnvChannel(&hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData,
+ &hSbrElement->sbrChannel[ch]->hEnvChannel, params,
+ statesInitFlag, ch, dynamic_RAM)) {
+ return (1);
+ }
+
+ } /* nChannels */
+
+ /* reset and intialize analysis qmf */
+ for (ch = 0; ch < ((hSbrElement->elInfo.fParametricStereo)
+ ? 2
+ : hSbrElement->sbrConfigData.nChannels);
+ ch++) {
+ int err;
+ UINT qmfFlags =
+ (hSbrElement->sbrConfigData.sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
+ ? QMF_FLAG_CLDFB
+ : 0;
+ if (statesInitFlag)
+ qmfFlags &= ~QMF_FLAG_KEEP_STATES;
+ else
+ qmfFlags |= QMF_FLAG_KEEP_STATES;
+
+ err = qmfInitAnalysisFilterBank(
+ hSbrElement->hQmfAnalysis[ch],
+ (FIXP_QAS *)hSbrElement->hQmfAnalysis[ch]->FilterStates,
+ hSbrElement->sbrConfigData.noQmfSlots,
+ hSbrElement->sbrConfigData.noQmfBands,
+ hSbrElement->sbrConfigData.noQmfBands,
+ hSbrElement->sbrConfigData.noQmfBands, qmfFlags);
+ if (0 != err) {
+ return err;
+ }
+ }
+
+ /* */
+ hSbrElement->CmonData.xOverFreq = hSbrElement->sbrConfigData.xOverFreq;
+ hSbrElement->CmonData.dynBwEnabled =
+ (params->dynBwSupported && params->dynBwEnabled);
+ hSbrElement->CmonData.dynXOverFreqEnc =
+ FDKsbrEnc_SbrGetXOverFreq(hSbrElement, hSbrElement->CmonData.xOverFreq);
+ for (i = 0; i < 5; i++)
+ hSbrElement->dynXOverFreqDelay[i] = hSbrElement->CmonData.dynXOverFreqEnc;
+ hSbrElement->CmonData.sbrNumChannels = hSbrElement->sbrConfigData.nChannels;
+ hSbrElement->sbrConfigData.dynXOverFreq = hSbrElement->CmonData.xOverFreq;
+
+ /* Update Bandwith to be passed to the core encoder */
+ *coreBandWith = hSbrElement->CmonData.xOverFreq;
+
+ return (0);
+}
+
+INT sbrEncoder_GetInBufferSize(int noChannels) {
+ INT temp;
+
+ temp = (2048);
+ temp += 1024 + MAX_SAMPLE_DELAY;
+ temp *= noChannels;
+ temp *= sizeof(INT_PCM);
+ return temp;
+}
+
+/*
+ * Encode Dummy SBR payload frames to fill the delay lines.
+ */
+static INT FDKsbrEnc_DelayCompensation(HANDLE_SBR_ENCODER hEnvEnc,
+ INT_PCM *timeBuffer,
+ UINT timeBufferBufSize) {
+ int n, el;
+
+ for (n = hEnvEnc->nBitstrDelay; n > 0; n--) {
+ for (el = 0; el < hEnvEnc->noElements; el++) {
+ if (FDKsbrEnc_EnvEncodeFrame(
+ hEnvEnc, el,
+ timeBuffer + hEnvEnc->downsampledOffset / hEnvEnc->nChannels,
+ timeBufferBufSize, NULL, NULL, 1))
+ return -1;
+ }
+ sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer, timeBufferBufSize);
+ }
+ return 0;
+}
+
+UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels,
+ UINT coreSampleRate, AUDIO_OBJECT_TYPE aot) {
+ UINT newBitRate = bitRate;
+ INT index;
+
+ FDK_ASSERT(numChannels > 0 && numChannels <= 2);
+ if (aot == AOT_PS) {
+ if (numChannels == 1) {
+ index = getPsTuningTableIndex(bitRate, &newBitRate);
+ if (index == INVALID_TABLE_IDX) {
+ bitRate = newBitRate;
+ }
+ } else {
+ return 0;
+ }
+ }
+ index = getSbrTuningTableIndex(bitRate, numChannels, coreSampleRate, aot,
+ &newBitRate);
+ if (index != INVALID_TABLE_IDX) {
+ newBitRate = bitRate;
+ }
+
+ return newBitRate;
+}
+
+UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot) {
+ UINT isPossible = (AOT_PS == aot) ? 0 : 1;
+ return isPossible;
+}
+
+/*****************************************************************************/
+/* */
+/*functionname: sbrEncoder_Init_delay */
+/*description: Determine Delay balancing and new encoder delay */
+/* */
+/*returns: - error status */
+/*input: - frame length of the core (i.e. e.g. AAC) */
+/* - number of channels */
+/* - downsample factor (1 for downsampled, 2 for dual-rate SBR) */
+/* - low delay presence */
+/* - ps presence */
+/* - downsampling method: QMF-, time domain or no downsampling */
+/* - various delay values (see DELAY_PARAM struct description) */
+/* */
+/*Example: Delay balancing for a HE-AACv1 encoder (time-domain downsampling) */
+/*========================================================================== */
+/* */
+/* +--------+ +--------+ +--------+ +--------+ +--------+ */
+/* |core | |ds 2:1 | |AAC | |QMF | |QMF | */
+/* +-+path +------------+ +-+core +-+analysis+-+overlap +-+ */
+/* | |offset | | | | | |32 bands| | | | */
+/* | +--------+ +--------+ +--------+ +--------+ +--------+ | */
+/* | core path +-------++ */
+/* | |QMF | */
+/*->+ +synth. +-> */
+/* | |64 bands| */
+/* | +-------++ */
+/* | +--------+ +--------+ +--------+ +--------+ | */
+/* | |SBR path| |QMF | |subband | |bs delay| | */
+/* +-+offset +-+analysis+-+sample +-+(full +-----------------------+ */
+/* | | |64 bands| |buffer | | frames)| */
+/* +--------+ +--------+ +--------+ +--------+ */
+/* SBR path */
+/* */
+/*****************************************************************************/
+static INT sbrEncoder_Init_delay(
+ const int coreFrameLength, /* input */
+ const int numChannels, /* input */
+ const int downSampleFactor, /* input */
+ const int lowDelay, /* input */
+ const int usePs, /* input */
+ const int is212, /* input */
+ const SBRENC_DS_TYPE downsamplingMethod, /* input */
+ DELAY_PARAM *hDelayParam /* input/output */
+) {
+ int delayCorePath = 0; /* delay in core path */
+ int delaySbrPath = 0; /* delay difference in QMF aka SBR path */
+ int delayInput2Core = 0; /* delay from the input to the core */
+ int delaySbrDec = 0; /* delay of the decoder's SBR module */
+
+ int delayCore = hDelayParam->delay; /* delay of the core */
+
+ /* Added delay by the SBR delay initialization */
+ int corePathOffset = 0; /* core path */
+ int sbrPathOffset = 0; /* sbr path */
+ int bitstreamDelay = 0; /* sbr path, framewise */
+
+ int flCore = coreFrameLength; /* core frame length */
+
+ int returnValue = 0; /* return value - 0 means: no error */
+
+ /* 1) Calculate actual delay for core and SBR path */
+ if (is212) {
+ delayCorePath = DELAY_COREPATH_ELDv2SBR(flCore, downSampleFactor);
+ delaySbrPath = DELAY_ELDv2SBR(flCore, downSampleFactor);
+ delaySbrDec = ((flCore) / 2) * (downSampleFactor);
+ } else if (lowDelay) {
+ delayCorePath = DELAY_COREPATH_ELDSBR(flCore, downSampleFactor);
+ delaySbrPath = DELAY_ELDSBR(flCore, downSampleFactor);
+ delaySbrDec = DELAY_QMF_POSTPROC(downSampleFactor);
+ } else if (usePs) {
+ delayCorePath = DELAY_COREPATH_PS(flCore, downSampleFactor);
+ delaySbrPath = DELAY_PS(flCore, downSampleFactor);
+ delaySbrDec = DELAY_COREPATH_SBR(flCore, downSampleFactor);
+ } else {
+ delayCorePath = DELAY_COREPATH_SBR(flCore, downSampleFactor);
+ delaySbrPath = DELAY_SBR(flCore, downSampleFactor);
+ delaySbrDec = DELAY_COREPATH_SBR(flCore, downSampleFactor);
+ }
+ delayCorePath += delayCore * downSampleFactor;
+ delayCorePath +=
+ (downsamplingMethod == SBRENC_DS_TIME) ? hDelayParam->dsDelay : 0;
+
+ /* 2) Manage coupling of paths */
+ if (downsamplingMethod == SBRENC_DS_QMF && delayCorePath > delaySbrPath) {
+ /* In case of QMF downsampling, both paths are coupled, i.e. the SBR path
+ offset would be added to both the SBR path and to the core path
+ as well, thus making it impossible to achieve delay balancing.
+ To overcome that problem, a framewise delay is added to the SBR path
+ first, until the overall delay of the core path is shorter than
+ the delay of the SBR path. When this is achieved, the missing delay
+ difference can be added as downsampled offset to the core path.
+ */
+ while (delayCorePath > delaySbrPath) {
+ /* Add one frame delay to SBR path */
+ delaySbrPath += flCore * downSampleFactor;
+ bitstreamDelay += 1;
+ }
+ }
+
+ /* 3) Calculate necessary additional delay to balance the paths */
+ if (delayCorePath > delaySbrPath) {
+ /* Delay QMF input */
+ while (delayCorePath > delaySbrPath + (int)flCore * (int)downSampleFactor) {
+ /* Do bitstream frame-wise delay balancing if there are
+ more than SBR framelength samples delay difference */
+ delaySbrPath += flCore * downSampleFactor;
+ bitstreamDelay += 1;
+ }
+ /* Multiply input offset by input channels */
+ corePathOffset = 0;
+ sbrPathOffset = (delayCorePath - delaySbrPath) * numChannels;
+ } else {
+ /* Delay AAC data */
+ /* Multiply downsampled offset by AAC core channels. Divide by 2 because of
+ half samplerate of downsampled data. */
+ corePathOffset = ((delaySbrPath - delayCorePath) * numChannels) >>
+ (downSampleFactor - 1);
+ sbrPathOffset = 0;
+ }
+
+ /* 4) Calculate delay from input to core */
+ if (usePs) {
+ delayInput2Core =
+ (DELAY_QMF_ANA(downSampleFactor) + DELAY_QMF_DS + DELAY_HYB_SYN) +
+ (downSampleFactor * corePathOffset) + 1;
+ } else if (downsamplingMethod == SBRENC_DS_TIME) {
+ delayInput2Core = corePathOffset + hDelayParam->dsDelay;
+ } else {
+ delayInput2Core = corePathOffset;
+ }
+
+ /* 6) Set output parameters */
+ hDelayParam->delay = FDKmax(delayCorePath, delaySbrPath); /* overall delay */
+ hDelayParam->sbrDecDelay = delaySbrDec; /* SBR decoder delay */
+ hDelayParam->delayInput2Core = delayInput2Core; /* delay input - core */
+ hDelayParam->bitstrDelay = bitstreamDelay; /* bitstream delay, in frames */
+ hDelayParam->corePathOffset = corePathOffset; /* offset added to core path */
+ hDelayParam->sbrPathOffset = sbrPathOffset; /* offset added to SBR path */
+
+ return returnValue;
+}
+
+/*****************************************************************************
+
+ functionname: sbrEncoder_Init
+ description: initializes the SBR encoder
+ returns: error status
+
+*****************************************************************************/
+INT sbrEncoder_Init(HANDLE_SBR_ENCODER hSbrEncoder,
+ SBR_ELEMENT_INFO elInfo[(8)], int noElements,
+ INT_PCM *inputBuffer, UINT inputBufferBufSize,
+ INT *coreBandwidth, INT *inputBufferOffset,
+ INT *numChannels, const UINT syntaxFlags,
+ INT *coreSampleRate, UINT *downSampleFactor,
+ INT *frameLength, AUDIO_OBJECT_TYPE aot, int *delay,
+ int transformFactor, const int headerPeriod,
+ ULONG statesInitFlag) {
+ HANDLE_ERROR_INFO errorInfo = noError;
+ sbrConfiguration sbrConfig[(8)];
+ INT error = 0;
+ INT lowestBandwidth;
+ /* Save input parameters */
+ INT inputSampleRate = *coreSampleRate;
+ int coreFrameLength = *frameLength;
+ int inputBandWidth = *coreBandwidth;
+ int inputChannels = *numChannels;
+
+ SBRENC_DS_TYPE downsamplingMethod = SBRENC_DS_NONE;
+ int highestSbrStartFreq, highestSbrStopFreq;
+ int lowDelay = 0;
+ int usePs = 0;
+ int is212 = 0;
+
+ DELAY_PARAM delayParam;
+
+ /* check whether SBR setting is available for the current encoder
+ * configuration (bitrate, samplerate) */
+ if (!sbrEncoder_IsSingleRatePossible(aot)) {
+ *downSampleFactor = 2;
+ }
+
+ if (aot == AOT_PS || aot == AOT_DABPLUS_PS) {
+ usePs = 1;
+ }
+ if (aot == AOT_ER_AAC_ELD) {
+ lowDelay = 1;
+ } else if (aot == AOT_ER_AAC_LD) {
+ error = 1;
+ goto bail;
+ }
+
+ /* Parametric Stereo */
+ if (usePs) {
+ if (*numChannels == 2 && noElements == 1) {
+ /* Override Element type in case of Parametric stereo */
+ elInfo[0].elType = ID_SCE;
+ elInfo[0].fParametricStereo = 1;
+ elInfo[0].nChannelsInEl = 1;
+ /* core encoder gets downmixed mono signal */
+ *numChannels = 1;
+ } else {
+ error = 1;
+ goto bail;
+ }
+ } /* usePs */
+
+ /* set the core's sample rate */
+ switch (*downSampleFactor) {
+ case 1:
+ *coreSampleRate = inputSampleRate;
+ downsamplingMethod = SBRENC_DS_NONE;
+ break;
+ case 2:
+ *coreSampleRate = inputSampleRate >> 1;
+ downsamplingMethod = usePs ? SBRENC_DS_QMF : SBRENC_DS_TIME;
+ break;
+ default:
+ *coreSampleRate = inputSampleRate >> 1;
+ return 0; /* return error */
+ }
+
+ /* check whether SBR setting is available for the current encoder
+ * configuration (bitrate, coreSampleRate) */
+ {
+ int el, coreEl;
+
+ /* Check if every element config is feasible */
+ for (coreEl = 0; coreEl < noElements; coreEl++) {
+ /* SBR only handles SCE and CPE's */
+ if (elInfo[coreEl].elType != ID_SCE && elInfo[coreEl].elType != ID_CPE) {
+ continue;
+ }
+ /* check if desired configuration is available */
+ if (!FDKsbrEnc_IsSbrSettingAvail(elInfo[coreEl].bitRate, 0,
+ elInfo[coreEl].nChannelsInEl,
+ inputSampleRate, *coreSampleRate, aot)) {
+ error = 1;
+ goto bail;
+ }
+ }
+
+ hSbrEncoder->nChannels = *numChannels;
+ hSbrEncoder->frameSize = coreFrameLength * *downSampleFactor;
+ hSbrEncoder->downsamplingMethod = downsamplingMethod;
+ hSbrEncoder->downSampleFactor = *downSampleFactor;
+ hSbrEncoder->estimateBitrate = 0;
+ hSbrEncoder->inputDataDelay = 0;
+ is212 = ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS)) ? 1 : 0;
+
+ /* Open SBR elements */
+ el = -1;
+ highestSbrStartFreq = highestSbrStopFreq = 0;
+ lowestBandwidth = 99999;
+
+ /* Loop through each core encoder element and get a matching SBR element
+ * config */
+ for (coreEl = 0; coreEl < noElements; coreEl++) {
+ /* SBR only handles SCE and CPE's */
+ if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) {
+ el++;
+ } else {
+ continue;
+ }
+
+ /* Set parametric Stereo Flag. */
+ if (usePs) {
+ elInfo[coreEl].fParametricStereo = 1;
+ } else {
+ elInfo[coreEl].fParametricStereo = 0;
+ }
+
+ /*
+ * Init sbrConfig structure
+ */
+ if (!FDKsbrEnc_InitializeSbrDefaults(&sbrConfig[el], *downSampleFactor,
+ coreFrameLength, IS_LOWDELAY(aot))) {
+ error = 1;
+ goto bail;
+ }
+
+ /*
+ * Modify sbrConfig structure according to Element parameters
+ */
+ if (!FDKsbrEnc_AdjustSbrSettings(
+ &sbrConfig[el], elInfo[coreEl].bitRate,
+ elInfo[coreEl].nChannelsInEl, *coreSampleRate, inputSampleRate,
+ transformFactor, 24000, 0, 0, /* useSpeechConfig */
+ 0, /* lcsMode */
+ usePs, /* bParametricStereo */
+ aot)) {
+ error = 1;
+ goto bail;
+ }
+
+ /* Find common frequency border for all SBR elements */
+ highestSbrStartFreq =
+ fixMax(highestSbrStartFreq, sbrConfig[el].startFreq);
+ highestSbrStopFreq = fixMax(highestSbrStopFreq, sbrConfig[el].stopFreq);
+
+ } /* first element loop */
+
+ /* Set element count (can be less than core encoder element count) */
+ hSbrEncoder->noElements = el + 1;
+
+ FDKsbrEnc_Reallocate(hSbrEncoder, elInfo, noElements);
+
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ int bandwidth = *coreBandwidth;
+
+ /* Use lowest common bandwidth */
+ sbrConfig[el].startFreq = highestSbrStartFreq;
+ sbrConfig[el].stopFreq = highestSbrStopFreq;
+
+ /* initialize SBR element, and get core bandwidth */
+ error = FDKsbrEnc_EnvInit(hSbrEncoder->sbrElement[el], &sbrConfig[el],
+ &bandwidth, aot, el, headerPeriod,
+ statesInitFlag, hSbrEncoder->downsamplingMethod,
+ hSbrEncoder->dynamicRam);
+
+ if (error != 0) {
+ error = 2;
+ goto bail;
+ }
+
+ /* Get lowest core encoder bandwidth to be returned later. */
+ lowestBandwidth = fixMin(lowestBandwidth, bandwidth);
+
+ } /* second element loop */
+
+ /* Initialize a downsampler for each channel in each SBR element */
+ if (hSbrEncoder->downsamplingMethod == SBRENC_DS_TIME) {
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ HANDLE_SBR_ELEMENT hSbrEl = hSbrEncoder->sbrElement[el];
+ INT Wc, ch;
+
+ Wc = 500; /* Cutoff frequency with full bandwidth */
+
+ for (ch = 0; ch < hSbrEl->elInfo.nChannelsInEl; ch++) {
+ FDKaacEnc_InitDownsampler(&hSbrEl->sbrChannel[ch]->downSampler, Wc,
+ *downSampleFactor);
+ FDK_ASSERT(hSbrEl->sbrChannel[ch]->downSampler.delay <=
+ MAX_DS_FILTER_DELAY);
+ }
+ } /* third element loop */
+
+ /* lfe */
+ FDKaacEnc_InitDownsampler(&hSbrEncoder->lfeDownSampler, 0,
+ *downSampleFactor);
+ }
+
+ /* Get delay information */
+ delayParam.dsDelay =
+ hSbrEncoder->sbrElement[0]->sbrChannel[0]->downSampler.delay;
+ delayParam.delay = *delay;
+
+ error = sbrEncoder_Init_delay(coreFrameLength, *numChannels,
+ *downSampleFactor, lowDelay, usePs, is212,
+ downsamplingMethod, &delayParam);
+
+ if (error != 0) {
+ error = 3;
+ goto bail;
+ }
+
+ hSbrEncoder->nBitstrDelay = delayParam.bitstrDelay;
+ hSbrEncoder->sbrDecDelay = delayParam.sbrDecDelay;
+ hSbrEncoder->inputDataDelay = delayParam.delayInput2Core;
+
+ /* Assign core encoder Bandwidth */
+ *coreBandwidth = lowestBandwidth;
+
+ /* Estimate sbr bitrate, 2.5 kBit/s per sbr channel */
+ hSbrEncoder->estimateBitrate += 2500 * (*numChannels);
+
+ /* Initialize bitstream buffer for each element */
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ FDKsbrEnc_bsBufInit(hSbrEncoder->sbrElement[el], delayParam.bitstrDelay);
+ }
+
+ /* initialize parametric stereo */
+ if (usePs) {
+ PSENC_CONFIG psEncConfig;
+ FDK_ASSERT(hSbrEncoder->noElements == 1);
+ INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL);
+
+ psEncConfig.frameSize = coreFrameLength; // sbrConfig.sbrFrameSize;
+ psEncConfig.qmfFilterMode = 0;
+ psEncConfig.sbrPsDelay = 0;
+
+ /* tuning parameters */
+ if (psTuningTableIdx != INVALID_TABLE_IDX) {
+ psEncConfig.nStereoBands = psTuningTable[psTuningTableIdx].nStereoBands;
+ psEncConfig.maxEnvelopes = psTuningTable[psTuningTableIdx].nEnvelopes;
+ psEncConfig.iidQuantErrorThreshold =
+ (FIXP_DBL)psTuningTable[psTuningTableIdx].iidQuantErrorThreshold;
+
+ /* calculation is not quite linear, increased number of envelopes causes
+ * more bits */
+ /* assume avg. 50 bits per frame for 10 stereo bands / 1 envelope
+ * configuration */
+ hSbrEncoder->estimateBitrate +=
+ ((((*coreSampleRate) * 5 * psEncConfig.nStereoBands *
+ psEncConfig.maxEnvelopes) /
+ hSbrEncoder->frameSize));
+
+ } else {
+ error = ERROR(CDI, "Invalid ps tuning table index.");
+ goto bail;
+ }
+
+ qmfInitSynthesisFilterBank(
+ &hSbrEncoder->qmfSynthesisPS,
+ (FIXP_DBL *)hSbrEncoder->qmfSynthesisPS.FilterStates,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1,
+ (statesInitFlag) ? 0 : QMF_FLAG_KEEP_STATES);
+
+ if (errorInfo == noError) {
+ /* update delay */
+ psEncConfig.sbrPsDelay =
+ FDKsbrEnc_GetEnvEstDelay(&hSbrEncoder->sbrElement[0]
+ ->sbrChannel[0]
+ ->hEnvChannel.sbrExtractEnvelope);
+
+ errorInfo =
+ PSEnc_Init(hSbrEncoder->hParametricStereo, &psEncConfig,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands,
+ hSbrEncoder->dynamicRam);
+ }
+ }
+
+ hSbrEncoder->downsampledOffset = delayParam.corePathOffset;
+ hSbrEncoder->bufferOffset = delayParam.sbrPathOffset;
+ *delay = delayParam.delay;
+
+ { hSbrEncoder->downmixSize = coreFrameLength * (*numChannels); }
+
+ /* Delay Compensation: fill bitstream delay buffer with zero input signal */
+ if (hSbrEncoder->nBitstrDelay > 0) {
+ error = FDKsbrEnc_DelayCompensation(hSbrEncoder, inputBuffer,
+ inputBufferBufSize);
+ if (error != 0) goto bail;
+ }
+
+ /* Set Output frame length */
+ *frameLength = coreFrameLength * *downSampleFactor;
+ /* Input buffer offset */
+ *inputBufferOffset =
+ fixMax(delayParam.sbrPathOffset, delayParam.corePathOffset);
+ }
+
+ return error;
+
+bail:
+ /* Restore input settings */
+ *coreSampleRate = inputSampleRate;
+ *frameLength = coreFrameLength;
+ *numChannels = inputChannels;
+ *coreBandwidth = inputBandWidth;
+
+ return error;
+}
+
+INT sbrEncoder_EncodeFrame(HANDLE_SBR_ENCODER hSbrEncoder, INT_PCM *samples,
+ UINT samplesBufSize, UINT sbrDataBits[(8)],
+ UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE]) {
+ INT error;
+ int el;
+
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ if (hSbrEncoder->sbrElement[el] != NULL) {
+ error = FDKsbrEnc_EnvEncodeFrame(
+ hSbrEncoder, el,
+ samples + hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels,
+ samplesBufSize, &sbrDataBits[el], sbrData[el], 0);
+ if (error) return error;
+ }
+ }
+
+ error = FDKsbrEnc_Downsample(
+ hSbrEncoder,
+ samples + hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels,
+ samplesBufSize, hSbrEncoder->nChannels, &sbrDataBits[el], sbrData[el], 0);
+ if (error) return error;
+
+ return 0;
+}
+
+INT sbrEncoder_UpdateBuffers(HANDLE_SBR_ENCODER hSbrEncoder,
+ INT_PCM *timeBuffer, UINT timeBufferBufSize) {
+ if (hSbrEncoder->downsampledOffset > 0) {
+ int c;
+ int nd = hSbrEncoder->downmixSize / hSbrEncoder->nChannels;
+
+ for (c = 0; c < hSbrEncoder->nChannels; c++) {
+ /* Move delayed downsampled data */
+ FDKmemcpy(timeBuffer + timeBufferBufSize * c,
+ timeBuffer + timeBufferBufSize * c + nd,
+ sizeof(INT_PCM) *
+ (hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels));
+ }
+ } else {
+ int c;
+
+ for (c = 0; c < hSbrEncoder->nChannels; c++) {
+ /* Move delayed input data */
+ FDKmemcpy(
+ timeBuffer + timeBufferBufSize * c,
+ timeBuffer + timeBufferBufSize * c + hSbrEncoder->frameSize,
+ sizeof(INT_PCM) * hSbrEncoder->bufferOffset / hSbrEncoder->nChannels);
+ }
+ }
+ if (hSbrEncoder->nBitstrDelay > 0) {
+ int el;
+
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ FDKmemmove(
+ hSbrEncoder->sbrElement[el]->payloadDelayLine[0],
+ hSbrEncoder->sbrElement[el]->payloadDelayLine[1],
+ sizeof(UCHAR) * (hSbrEncoder->nBitstrDelay * MAX_PAYLOAD_SIZE));
+
+ FDKmemmove(&hSbrEncoder->sbrElement[el]->payloadDelayLineSize[0],
+ &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[1],
+ sizeof(UINT) * (hSbrEncoder->nBitstrDelay));
+ }
+ }
+ return 0;
+}
+
+INT sbrEncoder_SendHeader(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT error = -1;
+ if (hSbrEncoder) {
+ int el;
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ if ((hSbrEncoder->noElements == 1) &&
+ (hSbrEncoder->sbrElement[0]->elInfo.fParametricStereo == 1)) {
+ hSbrEncoder->sbrElement[el]->sbrBitstreamData.CountSendHeaderData =
+ hSbrEncoder->sbrElement[el]->sbrBitstreamData.NrSendHeaderData - 1;
+ } else {
+ hSbrEncoder->sbrElement[el]->sbrBitstreamData.CountSendHeaderData = 0;
+ }
+ }
+ error = 0;
+ }
+ return error;
+}
+
+INT sbrEncoder_ContainsHeader(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT sbrHeader = 1;
+ if (hSbrEncoder) {
+ int el;
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ sbrHeader &=
+ (hSbrEncoder->sbrElement[el]->sbrBitstreamData.HeaderActiveDelay == 1)
+ ? 1
+ : 0;
+ }
+ }
+ return sbrHeader;
+}
+
+INT sbrEncoder_GetHeaderDelay(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT delay = -1;
+
+ if (hSbrEncoder) {
+ if ((hSbrEncoder->noElements == 1) &&
+ (hSbrEncoder->sbrElement[0]->elInfo.fParametricStereo == 1)) {
+ delay = hSbrEncoder->nBitstrDelay + 1;
+ } else {
+ delay = hSbrEncoder->nBitstrDelay;
+ }
+ }
+ return delay;
+}
+INT sbrEncoder_GetBsDelay(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT delay = -1;
+
+ if (hSbrEncoder) {
+ delay = hSbrEncoder->nBitstrDelay;
+ }
+ return delay;
+}
+
+INT sbrEncoder_SAPPrepare(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT error = -1;
+ if (hSbrEncoder) {
+ int el;
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ hSbrEncoder->sbrElement[el]->sbrBitstreamData.rightBorderFIX = 1;
+ }
+ error = 0;
+ }
+ return error;
+}
+
+INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT estimateBitrate = 0;
+
+ if (hSbrEncoder) {
+ estimateBitrate += hSbrEncoder->estimateBitrate;
+ }
+
+ return estimateBitrate;
+}
+
+INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT delay = -1;
+
+ if (hSbrEncoder) {
+ delay = hSbrEncoder->inputDataDelay;
+ }
+ return delay;
+}
+
+INT sbrEncoder_GetSbrDecDelay(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT delay = -1;
+
+ if (hSbrEncoder) {
+ delay = hSbrEncoder->sbrDecDelay;
+ }
+ return delay;
+}
+
+INT sbrEncoder_GetLibInfo(LIB_INFO *info) {
+ int i;
+
+ if (info == NULL) {
+ return -1;
+ }
+ /* search for next free tab */
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) {
+ return -1;
+ }
+ info += i;
+
+ info->module_id = FDK_SBRENC;
+ info->version =
+ LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2);
+ LIB_VERSION_STRING(info);
+#ifdef __ANDROID__
+ info->build_date = "";
+ info->build_time = "";
+#else
+ info->build_date = __DATE__;
+ info->build_time = __TIME__;
+#endif
+ info->title = "SBR Encoder";
+
+ /* Set flags */
+ info->flags = 0 | CAPF_SBR_HQ | CAPF_SBR_PS_MPEG;
+ /* End of flags */
+
+ return 0;
+}
diff --git a/fdk-aac/libSBRenc/src/sbr_misc.cpp b/fdk-aac/libSBRenc/src/sbr_misc.cpp
new file mode 100644
index 0000000..83d7e36
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/sbr_misc.cpp
@@ -0,0 +1,265 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Sbr miscellaneous helper functions $Revision: 36750 $
+*/
+#include "sbr_misc.h"
+
+void FDKsbrEnc_Shellsort_fract(FIXP_DBL *in, INT n) {
+ FIXP_DBL v;
+ INT i, j;
+ INT inc = 1;
+
+ do
+ inc = 3 * inc + 1;
+ while (inc <= n);
+
+ do {
+ inc = inc / 3;
+ for (i = inc + 1; i <= n; i++) {
+ v = in[i - 1];
+ j = i;
+ while (in[j - inc - 1] > v) {
+ in[j - 1] = in[j - inc - 1];
+ j -= inc;
+ if (j <= inc) break;
+ }
+ in[j - 1] = v;
+ }
+ } while (inc > 1);
+}
+
+/* Sorting routine */
+void FDKsbrEnc_Shellsort_int(INT *in, INT n) {
+ INT i, j, v;
+ INT inc = 1;
+
+ do
+ inc = 3 * inc + 1;
+ while (inc <= n);
+
+ do {
+ inc = inc / 3;
+ for (i = inc + 1; i <= n; i++) {
+ v = in[i - 1];
+ j = i;
+ while (in[j - inc - 1] > v) {
+ in[j - 1] = in[j - inc - 1];
+ j -= inc;
+ if (j <= inc) break;
+ }
+ in[j - 1] = v;
+ }
+ } while (inc > 1);
+}
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_AddVecLeft
+ *******************************************************************************
+
+ Description:
+
+ Arguments: INT* dst, INT* length_dst, INT* src, INT length_src
+
+ Return: none
+
+*******************************************************************************/
+void FDKsbrEnc_AddVecLeft(INT *dst, INT *length_dst, INT *src, INT length_src) {
+ INT i;
+
+ for (i = length_src - 1; i >= 0; i--)
+ FDKsbrEnc_AddLeft(dst, length_dst, src[i]);
+}
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_AddLeft
+ *******************************************************************************
+
+ Description:
+
+ Arguments: INT* vector, INT* length_vector, INT value
+
+ Return: none
+
+*******************************************************************************/
+void FDKsbrEnc_AddLeft(INT *vector, INT *length_vector, INT value) {
+ INT i;
+
+ for (i = *length_vector; i > 0; i--) vector[i] = vector[i - 1];
+ vector[0] = value;
+ (*length_vector)++;
+}
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_AddRight
+ *******************************************************************************
+
+ Description:
+
+ Arguments: INT* vector, INT* length_vector, INT value
+
+ Return: none
+
+*******************************************************************************/
+void FDKsbrEnc_AddRight(INT *vector, INT *length_vector, INT value) {
+ vector[*length_vector] = value;
+ (*length_vector)++;
+}
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_AddVecRight
+ *******************************************************************************
+
+ Description:
+
+ Arguments: INT* dst, INT* length_dst, INT* src, INT length_src)
+
+ Return: none
+
+*******************************************************************************/
+void FDKsbrEnc_AddVecRight(INT *dst, INT *length_dst, INT *src,
+ INT length_src) {
+ INT i;
+ for (i = 0; i < length_src; i++) FDKsbrEnc_AddRight(dst, length_dst, src[i]);
+}
+
+/*****************************************************************************
+
+ functionname: FDKsbrEnc_LSI_divide_scale_fract
+
+ description: Calculates division with best precision and scales the result.
+
+ return: num*scale/denom
+
+*****************************************************************************/
+FIXP_DBL FDKsbrEnc_LSI_divide_scale_fract(FIXP_DBL num, FIXP_DBL denom,
+ FIXP_DBL scale) {
+ FIXP_DBL tmp = FL2FXCONST_DBL(0.0f);
+ if (num != FL2FXCONST_DBL(0.0f)) {
+ INT shiftCommon;
+ INT shiftNum = CountLeadingBits(num);
+ INT shiftDenom = CountLeadingBits(denom);
+ INT shiftScale = CountLeadingBits(scale);
+
+ num = num << shiftNum;
+ scale = scale << shiftScale;
+
+ tmp = fMultDiv2(num, scale);
+
+ if (denom > (tmp >> fixMin(shiftNum + shiftScale - 1, (DFRACT_BITS - 1)))) {
+ denom = denom << shiftDenom;
+ tmp = schur_div(tmp, denom, 15);
+ shiftCommon =
+ fixMin((shiftNum - shiftDenom + shiftScale - 1), (DFRACT_BITS - 1));
+ if (shiftCommon < 0)
+ tmp <<= -shiftCommon;
+ else
+ tmp >>= shiftCommon;
+ } else {
+ tmp = /*FL2FXCONST_DBL(1.0)*/ (FIXP_DBL)MAXVAL_DBL;
+ }
+ }
+
+ return (tmp);
+}
diff --git a/fdk-aac/libSBRenc/src/sbr_misc.h b/fdk-aac/libSBRenc/src/sbr_misc.h
new file mode 100644
index 0000000..fad853f
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/sbr_misc.h
@@ -0,0 +1,127 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Sbr miscellaneous helper functions prototypes $Revision: 92790 $
+ \author
+*/
+
+#ifndef SBR_MISC_H
+#define SBR_MISC_H
+
+#include "sbr_encoder.h"
+
+/* Sorting routines */
+void FDKsbrEnc_Shellsort_fract(FIXP_DBL *in, INT n);
+void FDKsbrEnc_Shellsort_int(INT *in, INT n);
+
+void FDKsbrEnc_AddLeft(INT *vector, INT *length_vector, INT value);
+void FDKsbrEnc_AddRight(INT *vector, INT *length_vector, INT value);
+void FDKsbrEnc_AddVecLeft(INT *dst, INT *length_dst, INT *src, INT length_src);
+void FDKsbrEnc_AddVecRight(INT *dst, INT *length_vector_dst, INT *src,
+ INT length_src);
+
+FIXP_DBL FDKsbrEnc_LSI_divide_scale_fract(FIXP_DBL num, FIXP_DBL denom,
+ FIXP_DBL scale);
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/sbrenc_freq_sca.cpp b/fdk-aac/libSBRenc/src/sbrenc_freq_sca.cpp
new file mode 100644
index 0000000..c86e047
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/sbrenc_freq_sca.cpp
@@ -0,0 +1,674 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief frequency scale $Revision: 95225 $
+*/
+
+#include "sbrenc_freq_sca.h"
+#include "sbr_misc.h"
+
+#include "genericStds.h"
+
+/* StartFreq */
+static INT getStartFreq(INT fsCore, const INT start_freq);
+
+/* StopFreq */
+static INT getStopFreq(INT fsCore, const INT stop_freq);
+
+static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor);
+static void CalcBands(INT *diff, INT start, INT stop, INT num_bands);
+static INT modifyBands(INT max_band, INT *diff, INT length);
+static void cumSum(INT start_value, INT *diff, INT length, UCHAR *start_adress);
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_getSbrStartFreqRAW
+ *******************************************************************************
+ Description:
+
+ Arguments:
+
+ Return:
+ *******************************************************************************/
+
+INT FDKsbrEnc_getSbrStartFreqRAW(INT startFreq, INT fsCore) {
+ INT result;
+
+ if (startFreq < 0 || startFreq > 15) {
+ return -1;
+ }
+ /* Update startFreq struct */
+ result = getStartFreq(fsCore, startFreq);
+
+ result =
+ (result * (fsCore >> 5) + 1) >> 1; /* (result*fsSBR/QMFbands+1)>>1; */
+
+ return (result);
+
+} /* End FDKsbrEnc_getSbrStartFreqRAW */
+
+/*******************************************************************************
+ Functionname: getSbrStopFreq
+ *******************************************************************************
+ Description:
+
+ Arguments:
+
+ Return:
+ *******************************************************************************/
+INT FDKsbrEnc_getSbrStopFreqRAW(INT stopFreq, INT fsCore) {
+ INT result;
+
+ if (stopFreq < 0 || stopFreq > 13) return -1;
+
+ /* Uppdate stopFreq struct */
+ result = getStopFreq(fsCore, stopFreq);
+ result =
+ (result * (fsCore >> 5) + 1) >> 1; /* (result*fsSBR/QMFbands+1)>>1; */
+
+ return (result);
+} /* End getSbrStopFreq */
+
+/*******************************************************************************
+ Functionname: getStartFreq
+ *******************************************************************************
+ Description:
+
+ Arguments: fsCore - core sampling rate
+
+
+ Return:
+ *******************************************************************************/
+static INT getStartFreq(INT fsCore, const INT start_freq) {
+ INT k0_min;
+
+ switch (fsCore) {
+ case 8000:
+ k0_min = 24; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
+ break;
+ case 11025:
+ k0_min = 17; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
+ break;
+ case 12000:
+ k0_min = 16; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
+ break;
+ case 16000:
+ k0_min = 16; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
+ break;
+ case 22050:
+ k0_min = 12; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
+ break;
+ case 24000:
+ k0_min = 11; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
+ break;
+ case 32000:
+ k0_min = 10; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
+ break;
+ case 44100:
+ k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
+ break;
+ case 48000:
+ k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
+ break;
+ case 96000:
+ k0_min = 3; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
+ break;
+ default:
+ k0_min = 11; /* illegal fs */
+ }
+
+ switch (fsCore) {
+ case 8000: {
+ INT v_offset[] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
+ return (k0_min + v_offset[start_freq]);
+ }
+ case 11025: {
+ INT v_offset[] = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13};
+ return (k0_min + v_offset[start_freq]);
+ }
+ case 12000: {
+ INT v_offset[] = {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16};
+ return (k0_min + v_offset[start_freq]);
+ }
+ case 16000: {
+ INT v_offset[] = {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16};
+ return (k0_min + v_offset[start_freq]);
+ }
+ case 22050:
+ case 24000:
+ case 32000: {
+ INT v_offset[] = {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20};
+ return (k0_min + v_offset[start_freq]);
+ }
+ case 44100:
+ case 48000:
+ case 96000: {
+ INT v_offset[] = {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24};
+ return (k0_min + v_offset[start_freq]);
+ }
+ default: {
+ INT v_offset[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24, 28, 33};
+ return (k0_min + v_offset[start_freq]);
+ }
+ }
+} /* End getStartFreq */
+
+/*******************************************************************************
+ Functionname: getStopFreq
+ *******************************************************************************
+ Description:
+
+ Arguments:
+
+ Return:
+ *******************************************************************************/
+static INT getStopFreq(INT fsCore, const INT stop_freq) {
+ INT result, i;
+ INT k1_min;
+ INT v_dstop[13];
+
+ INT *v_stop_freq = NULL;
+ INT v_stop_freq_16[14] = {48, 49, 50, 51, 52, 54, 55,
+ 56, 57, 59, 60, 61, 63, 64};
+ INT v_stop_freq_22[14] = {35, 37, 38, 40, 42, 44, 46,
+ 48, 51, 53, 56, 58, 61, 64};
+ INT v_stop_freq_24[14] = {32, 34, 36, 38, 40, 42, 44,
+ 46, 49, 52, 55, 58, 61, 64};
+ INT v_stop_freq_32[14] = {32, 34, 36, 38, 40, 42, 44,
+ 46, 49, 52, 55, 58, 61, 64};
+ INT v_stop_freq_44[14] = {23, 25, 27, 29, 32, 34, 37,
+ 40, 43, 47, 51, 55, 59, 64};
+ INT v_stop_freq_48[14] = {21, 23, 25, 27, 30, 32, 35,
+ 38, 42, 45, 49, 54, 59, 64};
+ INT v_stop_freq_64[14] = {20, 22, 24, 26, 29, 31, 34,
+ 37, 41, 45, 49, 54, 59, 64};
+ INT v_stop_freq_88[14] = {15, 17, 19, 21, 23, 26, 29,
+ 33, 37, 41, 46, 51, 57, 64};
+ INT v_stop_freq_96[14] = {13, 15, 17, 19, 21, 24, 27,
+ 31, 35, 39, 44, 50, 57, 64};
+ INT v_stop_freq_192[14] = {7, 8, 10, 12, 14, 16, 19,
+ 23, 27, 32, 38, 46, 54, 64};
+
+ switch (fsCore) {
+ case 8000:
+ k1_min = 48;
+ v_stop_freq = v_stop_freq_16;
+ break;
+ case 11025:
+ k1_min = 35;
+ v_stop_freq = v_stop_freq_22;
+ break;
+ case 12000:
+ k1_min = 32;
+ v_stop_freq = v_stop_freq_24;
+ break;
+ case 16000:
+ k1_min = 32;
+ v_stop_freq = v_stop_freq_32;
+ break;
+ case 22050:
+ k1_min = 23;
+ v_stop_freq = v_stop_freq_44;
+ break;
+ case 24000:
+ k1_min = 21;
+ v_stop_freq = v_stop_freq_48;
+ break;
+ case 32000:
+ k1_min = 20;
+ v_stop_freq = v_stop_freq_64;
+ break;
+ case 44100:
+ k1_min = 15;
+ v_stop_freq = v_stop_freq_88;
+ break;
+ case 48000:
+ k1_min = 13;
+ v_stop_freq = v_stop_freq_96;
+ break;
+ case 96000:
+ k1_min = 7;
+ v_stop_freq = v_stop_freq_192;
+ break;
+ default:
+ k1_min = 21; /* illegal fs */
+ }
+
+ /* Ensure increasing bandwidth */
+ for (i = 0; i <= 12; i++) {
+ v_dstop[i] = v_stop_freq[i + 1] - v_stop_freq[i];
+ }
+
+ FDKsbrEnc_Shellsort_int(v_dstop, 13); /* Sort bandwidth changes */
+
+ result = k1_min;
+ for (i = 0; i < stop_freq; i++) {
+ result = result + v_dstop[i];
+ }
+
+ return (result);
+
+} /* End getStopFreq */
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_FindStartAndStopBand
+ *******************************************************************************
+ Description:
+
+ Arguments: srSbr SBR sampling freqency
+ srCore AAC core sampling freqency
+ noChannels Number of QMF channels
+ startFreq SBR start frequency in QMF bands
+ stopFreq SBR start frequency in QMF bands
+
+ *k0 Output parameter
+ *k2 Output parameter
+
+ Return: Error code (0 is OK)
+ *******************************************************************************/
+INT FDKsbrEnc_FindStartAndStopBand(const INT srSbr, const INT srCore,
+ const INT noChannels, const INT startFreq,
+ const INT stopFreq, INT *k0, INT *k2) {
+ /* Update startFreq struct */
+ *k0 = getStartFreq(srCore, startFreq);
+
+ /* Test if start freq is outside corecoder range */
+ if (srSbr * noChannels < *k0 * srCore) {
+ return (
+ 1); /* raise the cross-over frequency and/or lower the number
+ of target bands per octave (or lower the sampling frequency) */
+ }
+
+ /*Update stopFreq struct */
+ if (stopFreq < 14) {
+ *k2 = getStopFreq(srCore, stopFreq);
+ } else if (stopFreq == 14) {
+ *k2 = 2 * *k0;
+ } else {
+ *k2 = 3 * *k0;
+ }
+
+ /* limit to Nyqvist */
+ if (*k2 > noChannels) {
+ *k2 = noChannels;
+ }
+
+ /* Test for invalid k0 k2 combinations */
+ if ((srCore == 22050) && ((*k2 - *k0) > MAX_FREQ_COEFFS_FS44100))
+ return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for
+ fs=44.1kHz */
+
+ if ((srCore >= 24000) && ((*k2 - *k0) > MAX_FREQ_COEFFS_FS48000))
+ return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for
+ fs>=48kHz */
+
+ if ((*k2 - *k0) > MAX_FREQ_COEFFS)
+ return (1); /*Number of bands exceeds valid range of MAX_FREQ_COEFFS */
+
+ if ((*k2 - *k0) < 0) return (1); /* Number of bands is negative */
+
+ return (0);
+}
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_UpdateFreqScale
+ *******************************************************************************
+ Description:
+
+ Arguments:
+
+ Return:
+ *******************************************************************************/
+INT FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, const INT k0,
+ const INT k2, const INT freqScale,
+ const INT alterScale)
+
+{
+ INT b_p_o = 0; /* bands_per_octave */
+ FIXP_DBL warp = FL2FXCONST_DBL(0.0f);
+ INT dk = 0;
+
+ /* Internal variables */
+ INT k1 = 0, i;
+ INT num_bands0;
+ INT num_bands1;
+ INT diff_tot[MAX_OCTAVE + MAX_SECOND_REGION];
+ INT *diff0 = diff_tot;
+ INT *diff1 = diff_tot + MAX_OCTAVE;
+ INT k2_achived;
+ INT k2_diff;
+ INT incr = 0;
+
+ /* Init */
+ if (freqScale == 1) b_p_o = 12;
+ if (freqScale == 2) b_p_o = 10;
+ if (freqScale == 3) b_p_o = 8;
+
+ if (freqScale > 0) /*Bark*/
+ {
+ if (alterScale == 0)
+ warp = FL2FXCONST_DBL(0.5f); /* 1.0/(1.0*2.0) */
+ else
+ warp = FL2FXCONST_DBL(1.0f / 2.6f); /* 1.0/(1.3*2.0); */
+
+ if (4 * k2 >= 9 * k0) /*two or more regions (how many times the basis band
+ is copied)*/
+ {
+ k1 = 2 * k0;
+
+ num_bands0 = numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f));
+ num_bands1 = numberOfBands(b_p_o, k1, k2, warp);
+
+ CalcBands(diff0, k0, k1, num_bands0); /*CalcBands1 => diff0 */
+ FDKsbrEnc_Shellsort_int(diff0, num_bands0); /*SortBands sort diff0 */
+
+ if (diff0[0] == 0) /* too wide FB bands for target tuning */
+ {
+ return (1); /* raise the cross-over frequency and/or lower the number
+ of target bands per octave (or lower the sampling
+ frequency */
+ }
+
+ cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */
+
+ CalcBands(diff1, k1, k2, num_bands1); /* CalcBands2 => diff1 */
+ FDKsbrEnc_Shellsort_int(diff1, num_bands1); /* SortBands sort diff1 */
+ if (diff0[num_bands0 - 1] > diff1[0]) /* max(1) > min(2) */
+ {
+ if (modifyBands(diff0[num_bands0 - 1], diff1, num_bands1)) return (1);
+ }
+
+ /* Add 2'nd region */
+ cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]);
+ *h_num_bands = num_bands0 + num_bands1; /* Output nr of bands */
+
+ } else /* one region */
+ {
+ k1 = k2;
+
+ num_bands0 = numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f));
+ CalcBands(diff0, k0, k1, num_bands0); /* CalcBands1 => diff0 */
+ FDKsbrEnc_Shellsort_int(diff0, num_bands0); /* SortBands sort diff0 */
+
+ if (diff0[0] == 0) /* too wide FB bands for target tuning */
+ {
+ return (1); /* raise the cross-over frequency and/or lower the number
+ of target bands per octave (or lower the sampling
+ frequency */
+ }
+
+ cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */
+ *h_num_bands = num_bands0; /* Output nr of bands */
+ }
+ } else /* Linear mode */
+ {
+ if (alterScale == 0) {
+ dk = 1;
+ num_bands0 = 2 * ((k2 - k0) / 2); /* FLOOR to get to few number of bands*/
+ } else {
+ dk = 2;
+ num_bands0 =
+ 2 * (((k2 - k0) / dk + 1) / 2); /* ROUND to get closest fit */
+ }
+
+ k2_achived = k0 + num_bands0 * dk;
+ k2_diff = k2 - k2_achived;
+
+ for (i = 0; i < num_bands0; i++) diff_tot[i] = dk;
+
+ /* If linear scale wasn't achived */
+ /* and we got wide SBR are */
+ if (k2_diff < 0) {
+ incr = 1;
+ i = 0;
+ }
+
+ /* If linear scale wasn't achived */
+ /* and we got small SBR are */
+ if (k2_diff > 0) {
+ incr = -1;
+ i = num_bands0 - 1;
+ }
+
+ /* Adjust diff vector to get sepc. SBR range */
+ while (k2_diff != 0) {
+ diff_tot[i] = diff_tot[i] - incr;
+ i = i + incr;
+ k2_diff = k2_diff + incr;
+ }
+
+ cumSum(k0, diff_tot, num_bands0, v_k_master); /* cumsum */
+ *h_num_bands = num_bands0; /* Output nr of bands */
+ }
+
+ if (*h_num_bands < 1) return (1); /*To small sbr area */
+
+ return (0);
+} /* End FDKsbrEnc_UpdateFreqScale */
+
+static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor) {
+ INT result = 0;
+ /* result = 2* (INT) ( (double)b_p_o *
+ * (double)(FDKlog((double)stop/(double)start)/FDKlog((double)2)) *
+ * (double)FX_DBL2FL(warp_factor) + 0.5); */
+ result = ((b_p_o * fMult((CalcLdInt(stop) - CalcLdInt(start)), warp_factor) +
+ (FL2FX_DBL(0.5f) >> LD_DATA_SHIFT)) >>
+ ((DFRACT_BITS - 1) - LD_DATA_SHIFT))
+ << 1; /* do not optimize anymore (rounding!!) */
+
+ return (result);
+}
+
+static void CalcBands(INT *diff, INT start, INT stop, INT num_bands) {
+ INT i, qb, qe, qtmp;
+ INT previous;
+ INT current;
+ FIXP_DBL base, exp, tmp;
+
+ previous = start;
+ for (i = 1; i <= num_bands; i++) {
+ base = fDivNorm((FIXP_DBL)stop, (FIXP_DBL)start, &qb);
+ exp = fDivNorm((FIXP_DBL)i, (FIXP_DBL)num_bands, &qe);
+ tmp = fPow(base, qb, exp, qe, &qtmp);
+ tmp = fMult(tmp, (FIXP_DBL)(start << 24));
+ current = (INT)scaleValue(tmp, qtmp - 23);
+ current = (current + 1) >> 1; /* rounding*/
+ diff[i - 1] = current - previous;
+ previous = current;
+ }
+
+} /* End CalcBands */
+
+static void cumSum(INT start_value, INT *diff, INT length,
+ UCHAR *start_adress) {
+ INT i;
+ start_adress[0] = start_value;
+ for (i = 1; i <= length; i++)
+ start_adress[i] = start_adress[i - 1] + diff[i - 1];
+} /* End cumSum */
+
+static INT modifyBands(INT max_band_previous, INT *diff, INT length) {
+ INT change = max_band_previous - diff[0];
+
+ /* Limit the change so that the last band cannot get narrower than the first
+ * one */
+ if (change > (diff[length - 1] - diff[0]) / 2)
+ change = (diff[length - 1] - diff[0]) / 2;
+
+ diff[0] += change;
+ diff[length - 1] -= change;
+ FDKsbrEnc_Shellsort_int(diff, length);
+
+ return (0);
+} /* End modifyBands */
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_UpdateHiRes
+ *******************************************************************************
+ Description:
+
+
+ Arguments:
+
+ Return:
+ *******************************************************************************/
+INT FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, INT *num_hires, UCHAR *v_k_master,
+ INT num_master, INT *xover_band) {
+ INT i;
+ INT max1, max2;
+
+ if ((v_k_master[*xover_band] >
+ 32) || /* v_k_master[*xover_band] > noQMFChannels(dualRate)/divider */
+ (*xover_band > num_master)) {
+ /* xover_band error, too big for this startFreq. Will be clipped */
+
+ /* Calculate maximum value for xover_band */
+ max1 = 0;
+ max2 = num_master;
+ while ((v_k_master[max1 + 1] < 32) && /* noQMFChannels(dualRate)/divider */
+ ((max1 + 1) < max2)) {
+ max1++;
+ }
+
+ *xover_band = max1;
+ }
+
+ *num_hires = num_master - *xover_band;
+ for (i = *xover_band; i <= num_master; i++) {
+ h_hires[i - *xover_band] = v_k_master[i];
+ }
+
+ return (0);
+} /* End FDKsbrEnc_UpdateHiRes */
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_UpdateLoRes
+ *******************************************************************************
+ Description:
+
+ Arguments:
+
+ Return:
+ *******************************************************************************/
+void FDKsbrEnc_UpdateLoRes(UCHAR *h_lores, INT *num_lores, UCHAR *h_hires,
+ INT num_hires) {
+ INT i;
+
+ if (num_hires % 2 == 0) /* if even number of hires bands */
+ {
+ *num_lores = num_hires / 2;
+ /* Use every second lores=hires[0,2,4...] */
+ for (i = 0; i <= *num_lores; i++) h_lores[i] = h_hires[i * 2];
+
+ } else /* odd number of hires which means xover is odd */
+ {
+ *num_lores = (num_hires + 1) / 2;
+
+ /* Use lores=hires[0,1,3,5 ...] */
+ h_lores[0] = h_hires[0];
+ for (i = 1; i <= *num_lores; i++) {
+ h_lores[i] = h_hires[i * 2 - 1];
+ }
+ }
+
+} /* End FDKsbrEnc_UpdateLoRes */
diff --git a/fdk-aac/libSBRenc/src/sbrenc_freq_sca.h b/fdk-aac/libSBRenc/src/sbrenc_freq_sca.h
new file mode 100644
index 0000000..9b8d360
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/sbrenc_freq_sca.h
@@ -0,0 +1,132 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief frequency scale prototypes $Revision: 92790 $
+*/
+#ifndef SBRENC_FREQ_SCA_H
+#define SBRENC_FREQ_SCA_H
+
+#include "sbr_encoder.h"
+#include "sbr_def.h"
+
+#define MAX_OCTAVE 29
+#define MAX_SECOND_REGION 50
+
+INT FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, const INT k0,
+ const INT k2, const INT freq_scale,
+ const INT alter_scale);
+
+INT FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, INT *num_hires, UCHAR *v_k_master,
+ INT num_master, INT *xover_band);
+
+void FDKsbrEnc_UpdateLoRes(UCHAR *v_lores, INT *num_lores, UCHAR *v_hires,
+ INT num_hires);
+
+INT FDKsbrEnc_FindStartAndStopBand(const INT srSbr, const INT srCore,
+ const INT noChannels, const INT startFreq,
+ const INT stop_freq, INT *k0, INT *k2);
+
+INT FDKsbrEnc_getSbrStartFreqRAW(INT startFreq, INT fsCore);
+INT FDKsbrEnc_getSbrStopFreqRAW(INT stopFreq, INT fsCore);
+#endif
diff --git a/fdk-aac/libSBRenc/src/sbrenc_ram.cpp b/fdk-aac/libSBRenc/src/sbrenc_ram.cpp
new file mode 100644
index 0000000..fb30fa2
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/sbrenc_ram.cpp
@@ -0,0 +1,249 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Memory layout
+ $Revision: 92864 $
+
+ This module declares all static and dynamic memory spaces
+*/
+#include "sbrenc_ram.h"
+
+#include "sbr.h"
+#include "genericStds.h"
+
+C_AALLOC_MEM(Ram_SbrDynamic_RAM, FIXP_DBL,
+ ((SBR_ENC_DYN_RAM_SIZE) / sizeof(FIXP_DBL)))
+
+/*!
+ \name StaticSbrData
+
+ Static memory areas, must not be overwritten in other sections of the encoder
+*/
+/* @{ */
+
+/*! static sbr encoder instance for one encoder (2 channels)
+ all major static and dynamic memory areas are located
+ in module sbr_ram and sbr rom
+*/
+C_ALLOC_MEM(Ram_SbrEncoder, SBR_ENCODER, 1)
+C_ALLOC_MEM2(Ram_SbrChannel, SBR_CHANNEL, 1, (8))
+C_ALLOC_MEM2(Ram_SbrElement, SBR_ELEMENT, 1, (8))
+
+/*! Filter states for QMF-analysis. <br>
+ Dimension: #MAXNRSBRCHANNELS * #SBR_QMF_FILTER_LENGTH
+*/
+C_AALLOC_MEM2_L(Ram_Sbr_QmfStatesAnalysis, FIXP_QAS, 640, (8), SECT_DATA_L1)
+
+/*! Matrix holding the quota values for all estimates, all channels
+ Dimension #MAXNRSBRCHANNELS * +#SBR_QMF_CHANNELS* #MAX_NO_OF_ESTIMATES
+*/
+C_ALLOC_MEM2_L(Ram_Sbr_quotaMatrix, FIXP_DBL, (MAX_NO_OF_ESTIMATES * 64), (8),
+ SECT_DATA_L1)
+
+/*! Matrix holding the sign values for all estimates, all channels
+ Dimension #MAXNRSBRCHANNELS * +#SBR_QMF_CHANNELS* #MAX_NO_OF_ESTIMATES
+*/
+C_ALLOC_MEM2(Ram_Sbr_signMatrix, INT, (MAX_NO_OF_ESTIMATES * 64), (8))
+
+/*! Frequency band table (low res) <br>
+ Dimension #MAX_FREQ_COEFFS/2+1
+*/
+C_ALLOC_MEM2(Ram_Sbr_freqBandTableLO, UCHAR, (MAX_FREQ_COEFFS / 2 + 1), (8))
+
+/*! Frequency band table (high res) <br>
+ Dimension #MAX_FREQ_COEFFS +1
+*/
+C_ALLOC_MEM2(Ram_Sbr_freqBandTableHI, UCHAR, (MAX_FREQ_COEFFS + 1), (8))
+
+/*! vk matser table <br>
+ Dimension #MAX_FREQ_COEFFS +1
+*/
+C_ALLOC_MEM2(Ram_Sbr_v_k_master, UCHAR, (MAX_FREQ_COEFFS + 1), (8))
+
+/*
+ Missing harmonics detection
+*/
+
+/*! sbr_detectionVectors <br>
+ Dimension #MAX_NUM_CHANNELS*#MAX_NO_OF_ESTIMATES*#MAX_FREQ_COEFFS]
+*/
+C_ALLOC_MEM2(Ram_Sbr_detectionVectors, UCHAR,
+ (MAX_NO_OF_ESTIMATES * MAX_FREQ_COEFFS), (8))
+
+/*! sbr_prevCompVec[ <br>
+ Dimension #MAX_NUM_CHANNELS*#MAX_FREQ_COEFFS]
+*/
+C_ALLOC_MEM2(Ram_Sbr_prevEnvelopeCompensation, UCHAR, MAX_FREQ_COEFFS, (8))
+/*! sbr_guideScfb[ <br>
+ Dimension #MAX_NUM_CHANNELS*#MAX_FREQ_COEFFS]
+*/
+C_ALLOC_MEM2(Ram_Sbr_guideScfb, UCHAR, MAX_FREQ_COEFFS, (8))
+
+/*! sbr_guideVectorDetected <br>
+ Dimension #MAX_NUM_CHANNELS*#MAX_NO_OF_ESTIMATES*#MAX_FREQ_COEFFS]
+*/
+C_ALLOC_MEM2(Ram_Sbr_guideVectorDetected, UCHAR,
+ (MAX_NO_OF_ESTIMATES * MAX_FREQ_COEFFS), (8))
+C_ALLOC_MEM2(Ram_Sbr_guideVectorDiff, FIXP_DBL,
+ (MAX_NO_OF_ESTIMATES * MAX_FREQ_COEFFS), (8))
+C_ALLOC_MEM2(Ram_Sbr_guideVectorOrig, FIXP_DBL,
+ (MAX_NO_OF_ESTIMATES * MAX_FREQ_COEFFS), (8))
+
+/*
+ Static Parametric Stereo memory
+*/
+C_AALLOC_MEM_L(Ram_PsQmfStatesSynthesis, FIXP_DBL, 640 / 2, SECT_DATA_L1)
+
+C_ALLOC_MEM_L(Ram_PsEncode, PS_ENCODE, 1, SECT_DATA_L1)
+C_ALLOC_MEM(Ram_ParamStereo, PARAMETRIC_STEREO, 1)
+
+/* @} */
+
+/*!
+ \name DynamicSbrData
+
+ Dynamic memory areas, might be reused in other algorithm sections,
+ e.g. the core encoder.
+*/
+/* @{ */
+
+/*! Energy buffer for envelope extraction <br>
+ Dimension #MAXNRSBRCHANNELS * +#SBR_QMF_SLOTS * #SBR_QMF_CHANNELS
+*/
+C_ALLOC_MEM2(Ram_Sbr_envYBuffer, FIXP_DBL, (32 / 2 * 64), (8))
+
+FIXP_DBL* GetRam_Sbr_envYBuffer(int n, UCHAR* dynamic_RAM) {
+ FDK_ASSERT(dynamic_RAM != 0);
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * (dynamic_RAM + OFFSET_NRG + (n*Y_2_BUF_BYTE)) is sufficiently aligned, so
+ * the cast is safe */
+ return reinterpret_cast<FIXP_DBL*>(
+ reinterpret_cast<void*>(dynamic_RAM + OFFSET_NRG + (n * Y_2_BUF_BYTE)));
+}
+
+/*
+ * QMF data
+ */
+/* The SBR encoder uses a single channel overlapping buffer set (always n=0),
+ * but PS does not. */
+FIXP_DBL* GetRam_Sbr_envRBuffer(int n, UCHAR* dynamic_RAM) {
+ FDK_ASSERT(dynamic_RAM != 0);
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * (dynamic_RAM + OFFSET_QMF + (n*(ENV_R_BUFF_BYTE+ENV_I_BUFF_BYTE))) is
+ * sufficiently aligned, so the cast is safe */
+ return reinterpret_cast<FIXP_DBL*>(reinterpret_cast<void*>(
+ dynamic_RAM + OFFSET_QMF + (n * (ENV_R_BUFF_BYTE + ENV_I_BUFF_BYTE))));
+}
+FIXP_DBL* GetRam_Sbr_envIBuffer(int n, UCHAR* dynamic_RAM) {
+ FDK_ASSERT(dynamic_RAM != 0);
+ /* The reinterpret_cast is used to suppress a compiler warning. We know that
+ * (dynamic_RAM + OFFSET_QMF + (ENV_R_BUFF_BYTE) +
+ * (n*(ENV_R_BUFF_BYTE+ENV_I_BUFF_BYTE))) is sufficiently aligned, so the cast
+ * is safe */
+ return reinterpret_cast<FIXP_DBL*>(
+ reinterpret_cast<void*>(dynamic_RAM + OFFSET_QMF + (ENV_R_BUFF_BYTE) +
+ (n * (ENV_R_BUFF_BYTE + ENV_I_BUFF_BYTE))));
+}
+
+/* @} */
diff --git a/fdk-aac/libSBRenc/src/sbrenc_ram.h b/fdk-aac/libSBRenc/src/sbrenc_ram.h
new file mode 100644
index 0000000..cf23378
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/sbrenc_ram.h
@@ -0,0 +1,199 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+\file
+\brief Memory layout
+$Revision: 92790 $
+*/
+#ifndef SBRENC_RAM_H
+#define SBRENC_RAM_H
+
+#include "sbr_def.h"
+#include "env_est.h"
+#include "sbr_encoder.h"
+#include "sbr.h"
+
+#include "ps_main.h"
+#include "ps_encode.h"
+
+#define ENV_TRANSIENTS_BYTE ((sizeof(FIXP_DBL) * (MAX_NUM_CHANNELS * 3 * 32)))
+
+#define ENV_R_BUFF_BYTE ((sizeof(FIXP_DBL) * ((32) * MAX_HYBRID_BANDS)))
+#define ENV_I_BUFF_BYTE ((sizeof(FIXP_DBL) * ((32) * MAX_HYBRID_BANDS)))
+#define Y_BUF_CH_BYTE \
+ ((2 * sizeof(FIXP_DBL) * (((32) - (32 / 2)) * MAX_HYBRID_BANDS)))
+
+#define ENV_R_BUF_PS_BYTE ((sizeof(FIXP_DBL) * 32 * 64 / 2))
+#define ENV_I_BUF_PS_BYTE ((sizeof(FIXP_DBL) * 32 * 64 / 2))
+
+#define TON_BUF_CH_BYTE \
+ ((sizeof(FIXP_DBL) * (MAX_NO_OF_ESTIMATES * MAX_FREQ_COEFFS)))
+
+#define Y_2_BUF_BYTE (Y_BUF_CH_BYTE)
+
+/* Workbuffer RAM - Allocation */
+/*
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ | OFFSET_QMF | OFFSET_NRG |
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ ------------------------- -------------------------
+ | | 0.5 * |
+ | sbr_envRBuffer | sbr_envYBuffer_size |
+ | sbr_envIBuffer | |
+ ------------------------- -------------------------
+
+*/
+#define BUF_NRG_SIZE ((MAX_NUM_CHANNELS * Y_2_BUF_BYTE))
+#define BUF_QMF_SIZE (ENV_R_BUFF_BYTE + ENV_I_BUFF_BYTE)
+
+/* Size of the shareable memory region than can be reused */
+#define SBR_ENC_DYN_RAM_SIZE (BUF_QMF_SIZE + BUF_NRG_SIZE)
+
+#define OFFSET_QMF (0)
+#define OFFSET_NRG (OFFSET_QMF + BUF_QMF_SIZE)
+
+/*
+ *****************************************************************************************************
+ */
+
+H_ALLOC_MEM(Ram_SbrDynamic_RAM, FIXP_DBL)
+
+H_ALLOC_MEM(Ram_SbrEncoder, SBR_ENCODER)
+H_ALLOC_MEM(Ram_SbrChannel, SBR_CHANNEL)
+H_ALLOC_MEM(Ram_SbrElement, SBR_ELEMENT)
+
+H_ALLOC_MEM(Ram_Sbr_quotaMatrix, FIXP_DBL)
+H_ALLOC_MEM(Ram_Sbr_signMatrix, INT)
+
+H_ALLOC_MEM(Ram_Sbr_QmfStatesAnalysis, FIXP_QAS)
+
+H_ALLOC_MEM(Ram_Sbr_freqBandTableLO, UCHAR)
+H_ALLOC_MEM(Ram_Sbr_freqBandTableHI, UCHAR)
+H_ALLOC_MEM(Ram_Sbr_v_k_master, UCHAR)
+
+H_ALLOC_MEM(Ram_Sbr_detectionVectors, UCHAR)
+H_ALLOC_MEM(Ram_Sbr_prevEnvelopeCompensation, UCHAR)
+H_ALLOC_MEM(Ram_Sbr_guideScfb, UCHAR)
+H_ALLOC_MEM(Ram_Sbr_guideVectorDetected, UCHAR)
+
+/* Dynamic Memory Allocation */
+
+H_ALLOC_MEM(Ram_Sbr_envYBuffer, FIXP_DBL)
+FIXP_DBL* GetRam_Sbr_envYBuffer(int n, UCHAR* dynamic_RAM);
+FIXP_DBL* GetRam_Sbr_envRBuffer(int n, UCHAR* dynamic_RAM);
+FIXP_DBL* GetRam_Sbr_envIBuffer(int n, UCHAR* dynamic_RAM);
+
+H_ALLOC_MEM(Ram_Sbr_guideVectorDiff, FIXP_DBL)
+H_ALLOC_MEM(Ram_Sbr_guideVectorOrig, FIXP_DBL)
+
+H_ALLOC_MEM(Ram_PsQmfStatesSynthesis, FIXP_DBL)
+
+H_ALLOC_MEM(Ram_PsEncode, PS_ENCODE)
+
+FIXP_DBL* FDKsbrEnc_SliceRam_PsRqmf(FIXP_DBL* rQmfData, UCHAR* dynamic_RAM,
+ int n, int i, int qmfSlots);
+FIXP_DBL* FDKsbrEnc_SliceRam_PsIqmf(FIXP_DBL* iQmfData, UCHAR* dynamic_RAM,
+ int n, int i, int qmfSlots);
+
+H_ALLOC_MEM(Ram_ParamStereo, PARAMETRIC_STEREO)
+#endif
diff --git a/fdk-aac/libSBRenc/src/sbrenc_rom.cpp b/fdk-aac/libSBRenc/src/sbrenc_rom.cpp
new file mode 100644
index 0000000..737afaf
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/sbrenc_rom.cpp
@@ -0,0 +1,910 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s): Tobias Chalupka
+
+ Description: Definition of constant tables
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Definition of constant tables
+ $Revision: 95404 $
+
+ This module contains most of the constant data that can be stored in ROM.
+*/
+
+#include "sbrenc_rom.h"
+#include "genericStds.h"
+
+//@{
+/*******************************************************************************
+
+ Table Overview:
+
+ o envelope level, 1.5 dB:
+ 1a) v_Huff_envelopeLevelC10T[121]
+ 1b) v_Huff_envelopeLevelL10T[121]
+ 2a) v_Huff_envelopeLevelC10F[121]
+ 2b) v_Huff_envelopeLevelL10F[121]
+
+ o envelope balance, 1.5 dB:
+ 3a) bookSbrEnvBalanceC10T[49]
+ 3b) bookSbrEnvBalanceL10T[49]
+ 4a) bookSbrEnvBalanceC10F[49]
+ 4b) bookSbrEnvBalanceL10F[49]
+
+ o envelope level, 3.0 dB:
+ 5a) v_Huff_envelopeLevelC11T[63]
+ 5b) v_Huff_envelopeLevelL11T[63]
+ 6a) v_Huff_envelopeLevelC11F[63]
+ 6b) v_Huff_envelopeLevelC11F[63]
+
+ o envelope balance, 3.0 dB:
+ 7a) bookSbrEnvBalanceC11T[25]
+ 7b) bookSbrEnvBalanceL11T[25]
+ 8a) bookSbrEnvBalanceC11F[25]
+ 8b) bookSbrEnvBalanceL11F[25]
+
+ o noise level, 3.0 dB:
+ 9a) v_Huff_NoiseLevelC11T[63]
+ 9b) v_Huff_NoiseLevelL11T[63]
+ - ) (v_Huff_envelopeLevelC11F[63] is used for freq dir)
+ - ) (v_Huff_envelopeLevelL11F[63] is used for freq dir)
+
+ o noise balance, 3.0 dB:
+ 10a) bookSbrNoiseBalanceC11T[25]
+ 10b) bookSbrNoiseBalanceL11T[25]
+ - ) (bookSbrEnvBalanceC11F[25] is used for freq dir)
+ - ) (bookSbrEnvBalanceL11F[25] is used for freq dir)
+
+
+ (1.5 dB is never used for noise)
+
+********************************************************************************/
+
+/*******************************************************************************/
+/* table : envelope level, 1.5 dB */
+/* theor range : [-58,58], CODE_BOOK_SCF_LAV = 58 */
+/* implem range: [-60,60], CODE_BOOK_SCF_LAV10 = 60 */
+/* raw stats : envelopeLevel_00 (yes, wrong suffix in name) KK 01-03-09 */
+/*******************************************************************************/
+
+/* direction: time
+ contents : codewords
+ raw table: HuffCode3C2FIX.m/envelopeLevel_00T_cF.mat/v_nChex_cF
+ built by : FH 01-07-05 */
+
+const INT v_Huff_envelopeLevelC10T[121] = {
+ 0x0003FFD6, 0x0003FFD7, 0x0003FFD8, 0x0003FFD9, 0x0003FFDA, 0x0003FFDB,
+ 0x0007FFB8, 0x0007FFB9, 0x0007FFBA, 0x0007FFBB, 0x0007FFBC, 0x0007FFBD,
+ 0x0007FFBE, 0x0007FFBF, 0x0007FFC0, 0x0007FFC1, 0x0007FFC2, 0x0007FFC3,
+ 0x0007FFC4, 0x0007FFC5, 0x0007FFC6, 0x0007FFC7, 0x0007FFC8, 0x0007FFC9,
+ 0x0007FFCA, 0x0007FFCB, 0x0007FFCC, 0x0007FFCD, 0x0007FFCE, 0x0007FFCF,
+ 0x0007FFD0, 0x0007FFD1, 0x0007FFD2, 0x0007FFD3, 0x0001FFE6, 0x0003FFD4,
+ 0x0000FFF0, 0x0001FFE9, 0x0003FFD5, 0x0001FFE7, 0x0000FFF1, 0x0000FFEC,
+ 0x0000FFED, 0x0000FFEE, 0x00007FF4, 0x00003FF9, 0x00003FF7, 0x00001FFA,
+ 0x00001FF9, 0x00000FFB, 0x000007FC, 0x000003FC, 0x000001FD, 0x000000FD,
+ 0x0000007D, 0x0000003D, 0x0000001D, 0x0000000D, 0x00000005, 0x00000001,
+ 0x00000000, 0x00000004, 0x0000000C, 0x0000001C, 0x0000003C, 0x0000007C,
+ 0x000000FC, 0x000001FC, 0x000003FD, 0x00000FFA, 0x00001FF8, 0x00003FF6,
+ 0x00003FF8, 0x00007FF5, 0x0000FFEF, 0x0001FFE8, 0x0000FFF2, 0x0007FFD4,
+ 0x0007FFD5, 0x0007FFD6, 0x0007FFD7, 0x0007FFD8, 0x0007FFD9, 0x0007FFDA,
+ 0x0007FFDB, 0x0007FFDC, 0x0007FFDD, 0x0007FFDE, 0x0007FFDF, 0x0007FFE0,
+ 0x0007FFE1, 0x0007FFE2, 0x0007FFE3, 0x0007FFE4, 0x0007FFE5, 0x0007FFE6,
+ 0x0007FFE7, 0x0007FFE8, 0x0007FFE9, 0x0007FFEA, 0x0007FFEB, 0x0007FFEC,
+ 0x0007FFED, 0x0007FFEE, 0x0007FFEF, 0x0007FFF0, 0x0007FFF1, 0x0007FFF2,
+ 0x0007FFF3, 0x0007FFF4, 0x0007FFF5, 0x0007FFF6, 0x0007FFF7, 0x0007FFF8,
+ 0x0007FFF9, 0x0007FFFA, 0x0007FFFB, 0x0007FFFC, 0x0007FFFD, 0x0007FFFE,
+ 0x0007FFFF};
+
+/* direction: time
+ contents : codeword lengths
+ raw table: HuffCode3C2FIX.m/envelopeLevel_00T_cF.mat/v_nLhex_cF
+ built by : FH 01-07-05 */
+
+const UCHAR v_Huff_envelopeLevelL10T[121] = {
+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x11, 0x12, 0x10, 0x11, 0x12, 0x11, 0x10, 0x10, 0x10, 0x10,
+ 0x0F, 0x0E, 0x0E, 0x0D, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07,
+ 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0E, 0x0F, 0x10, 0x11, 0x10,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13};
+
+/* direction: freq
+ contents : codewords
+ raw table: HuffCode3C2FIX.m/envelopeLevel_00F_cF.mat/v_nChex_cF
+ built by : FH 01-07-05 */
+
+const INT v_Huff_envelopeLevelC10F[121] = {
+ 0x0007FFE7, 0x0007FFE8, 0x000FFFD2, 0x000FFFD3, 0x000FFFD4, 0x000FFFD5,
+ 0x000FFFD6, 0x000FFFD7, 0x000FFFD8, 0x0007FFDA, 0x000FFFD9, 0x000FFFDA,
+ 0x000FFFDB, 0x000FFFDC, 0x0007FFDB, 0x000FFFDD, 0x0007FFDC, 0x0007FFDD,
+ 0x000FFFDE, 0x0003FFE4, 0x000FFFDF, 0x000FFFE0, 0x000FFFE1, 0x0007FFDE,
+ 0x000FFFE2, 0x000FFFE3, 0x000FFFE4, 0x0007FFDF, 0x000FFFE5, 0x0007FFE0,
+ 0x0003FFE8, 0x0007FFE1, 0x0003FFE0, 0x0003FFE9, 0x0001FFEF, 0x0003FFE5,
+ 0x0001FFEC, 0x0001FFED, 0x0001FFEE, 0x0000FFF4, 0x0000FFF3, 0x0000FFF0,
+ 0x00007FF7, 0x00007FF6, 0x00003FFA, 0x00001FFA, 0x00001FF9, 0x00000FFA,
+ 0x00000FF8, 0x000007F9, 0x000003FB, 0x000001FC, 0x000001FA, 0x000000FB,
+ 0x0000007C, 0x0000003C, 0x0000001C, 0x0000000C, 0x00000005, 0x00000001,
+ 0x00000000, 0x00000004, 0x0000000D, 0x0000001D, 0x0000003D, 0x000000FA,
+ 0x000000FC, 0x000001FB, 0x000003FA, 0x000007F8, 0x000007FA, 0x000007FB,
+ 0x00000FF9, 0x00000FFB, 0x00001FF8, 0x00001FFB, 0x00003FF8, 0x00003FF9,
+ 0x0000FFF1, 0x0000FFF2, 0x0001FFEA, 0x0001FFEB, 0x0003FFE1, 0x0003FFE2,
+ 0x0003FFEA, 0x0003FFE3, 0x0003FFE6, 0x0003FFE7, 0x0003FFEB, 0x000FFFE6,
+ 0x0007FFE2, 0x000FFFE7, 0x000FFFE8, 0x000FFFE9, 0x000FFFEA, 0x000FFFEB,
+ 0x000FFFEC, 0x0007FFE3, 0x000FFFED, 0x000FFFEE, 0x000FFFEF, 0x000FFFF0,
+ 0x0007FFE4, 0x000FFFF1, 0x0003FFEC, 0x000FFFF2, 0x000FFFF3, 0x0007FFE5,
+ 0x0007FFE6, 0x000FFFF4, 0x000FFFF5, 0x000FFFF6, 0x000FFFF7, 0x000FFFF8,
+ 0x000FFFF9, 0x000FFFFA, 0x000FFFFB, 0x000FFFFC, 0x000FFFFD, 0x000FFFFE,
+ 0x000FFFFF};
+
+/* direction: freq
+ contents : codeword lengths
+ raw table: HuffCode3C2FIX.m/envelopeLevel_00F_cF.mat/v_nLhex_cF
+ built by : FH 01-07-05 */
+
+const UCHAR v_Huff_envelopeLevelL10F[121] = {
+ 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x13, 0x14,
+ 0x14, 0x14, 0x14, 0x13, 0x14, 0x13, 0x13, 0x14, 0x12, 0x14, 0x14,
+ 0x14, 0x13, 0x14, 0x14, 0x14, 0x13, 0x14, 0x13, 0x12, 0x13, 0x12,
+ 0x12, 0x11, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x10, 0x0F, 0x0F,
+ 0x0E, 0x0D, 0x0D, 0x0C, 0x0C, 0x0B, 0x0A, 0x09, 0x09, 0x08, 0x07,
+ 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0D, 0x0D, 0x0E,
+ 0x0E, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
+ 0x12, 0x14, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x13, 0x14,
+ 0x14, 0x14, 0x14, 0x13, 0x14, 0x12, 0x14, 0x14, 0x13, 0x13, 0x14,
+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14};
+
+/*******************************************************************************/
+/* table : envelope balance, 1.5 dB */
+/* theor range : [-48,48], CODE_BOOK_SCF_LAV = 48 */
+/* implem range: same but mapped to [-24,24], CODE_BOOK_SCF_LAV_BALANCE10 = 24
+ */
+/* raw stats : envelopePan_00 (yes, wrong suffix in name) KK 01-03-09 */
+/*******************************************************************************/
+
+/* direction: time
+ contents : codewords
+ raw table: HuffCode3C.m/envelopePan_00T.mat/v_nBhex
+ built by : FH 01-05-15 */
+
+const INT bookSbrEnvBalanceC10T[49] = {
+ 0x0000FFE4, 0x0000FFE5, 0x0000FFE6, 0x0000FFE7, 0x0000FFE8, 0x0000FFE9,
+ 0x0000FFEA, 0x0000FFEB, 0x0000FFEC, 0x0000FFED, 0x0000FFEE, 0x0000FFEF,
+ 0x0000FFF0, 0x0000FFF1, 0x0000FFF2, 0x0000FFF3, 0x0000FFF4, 0x0000FFE2,
+ 0x00000FFC, 0x000007FC, 0x000001FE, 0x0000007E, 0x0000001E, 0x00000006,
+ 0x00000000, 0x00000002, 0x0000000E, 0x0000003E, 0x000000FE, 0x000007FD,
+ 0x00000FFD, 0x00007FF0, 0x0000FFE3, 0x0000FFF5, 0x0000FFF6, 0x0000FFF7,
+ 0x0000FFF8, 0x0000FFF9, 0x0000FFFA, 0x0001FFF6, 0x0001FFF7, 0x0001FFF8,
+ 0x0001FFF9, 0x0001FFFA, 0x0001FFFB, 0x0001FFFC, 0x0001FFFD, 0x0001FFFE,
+ 0x0001FFFF};
+
+/* direction: time
+ contents : codeword lengths
+ raw table: HuffCode3C.m/envelopePan_00T.mat/v_nLhex
+ built by : FH 01-05-15 */
+
+const UCHAR bookSbrEnvBalanceL10T[49] = {
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x0B,
+ 0x09, 0x07, 0x05, 0x03, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0B,
+ 0x0C, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11,
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
+
+/* direction: freq
+ contents : codewords
+ raw table: HuffCode3C.m/envelopePan_00F.mat/v_nBhex
+ built by : FH 01-05-15 */
+
+const INT bookSbrEnvBalanceC10F[49] = {
+ 0x0003FFE2, 0x0003FFE3, 0x0003FFE4, 0x0003FFE5, 0x0003FFE6, 0x0003FFE7,
+ 0x0003FFE8, 0x0003FFE9, 0x0003FFEA, 0x0003FFEB, 0x0003FFEC, 0x0003FFED,
+ 0x0003FFEE, 0x0003FFEF, 0x0003FFF0, 0x0000FFF7, 0x0001FFF0, 0x00003FFC,
+ 0x000007FE, 0x000007FC, 0x000000FE, 0x0000007E, 0x0000000E, 0x00000002,
+ 0x00000000, 0x00000006, 0x0000001E, 0x0000003E, 0x000001FE, 0x000007FD,
+ 0x00000FFE, 0x00007FFA, 0x0000FFF6, 0x0003FFF1, 0x0003FFF2, 0x0003FFF3,
+ 0x0003FFF4, 0x0003FFF5, 0x0003FFF6, 0x0003FFF7, 0x0003FFF8, 0x0003FFF9,
+ 0x0003FFFA, 0x0003FFFB, 0x0003FFFC, 0x0003FFFD, 0x0003FFFE, 0x0007FFFE,
+ 0x0007FFFF};
+
+/* direction: freq
+ contents : codeword lengths
+ raw table: HuffCode3C.m/envelopePan_00F.mat/v_nLhex
+ built by : FH 01-05-15 */
+
+const UCHAR bookSbrEnvBalanceL10F[49] = {
+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x10, 0x11, 0x0E, 0x0B, 0x0B,
+ 0x08, 0x07, 0x04, 0x02, 0x01, 0x03, 0x05, 0x06, 0x09, 0x0B,
+ 0x0C, 0x0F, 0x10, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13};
+
+/*******************************************************************************/
+/* table : envelope level, 3.0 dB */
+/* theor range : [-29,29], CODE_BOOK_SCF_LAV = 29 */
+/* implem range: [-31,31], CODE_BOOK_SCF_LAV11 = 31 */
+/* raw stats : envelopeLevel_11 KK 00-02-03 */
+/*******************************************************************************/
+
+/* direction: time
+ contents : codewords
+ raw table: HuffCode2.m
+ built by : FH 00-02-04 */
+
+const INT v_Huff_envelopeLevelC11T[63] = {
+ 0x0003FFED, 0x0003FFEE, 0x0007FFDE, 0x0007FFDF, 0x0007FFE0, 0x0007FFE1,
+ 0x0007FFE2, 0x0007FFE3, 0x0007FFE4, 0x0007FFE5, 0x0007FFE6, 0x0007FFE7,
+ 0x0007FFE8, 0x0007FFE9, 0x0007FFEA, 0x0007FFEB, 0x0007FFEC, 0x0001FFF4,
+ 0x0000FFF7, 0x0000FFF9, 0x0000FFF8, 0x00003FFB, 0x00003FFA, 0x00003FF8,
+ 0x00001FFA, 0x00000FFC, 0x000007FC, 0x000000FE, 0x0000003E, 0x0000000E,
+ 0x00000002, 0x00000000, 0x00000006, 0x0000001E, 0x0000007E, 0x000001FE,
+ 0x000007FD, 0x00001FFB, 0x00003FF9, 0x00003FFC, 0x00007FFA, 0x0000FFF6,
+ 0x0001FFF5, 0x0003FFEC, 0x0007FFED, 0x0007FFEE, 0x0007FFEF, 0x0007FFF0,
+ 0x0007FFF1, 0x0007FFF2, 0x0007FFF3, 0x0007FFF4, 0x0007FFF5, 0x0007FFF6,
+ 0x0007FFF7, 0x0007FFF8, 0x0007FFF9, 0x0007FFFA, 0x0007FFFB, 0x0007FFFC,
+ 0x0007FFFD, 0x0007FFFE, 0x0007FFFF};
+
+/* direction: time
+ contents : codeword lengths
+ raw table: HuffCode2.m
+ built by : FH 00-02-04 */
+
+const UCHAR v_Huff_envelopeLevelL11T[63] = {
+ 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x11, 0x10, 0x10, 0x10, 0x0E,
+ 0x0E, 0x0E, 0x0D, 0x0C, 0x0B, 0x08, 0x06, 0x04, 0x02, 0x01, 0x03,
+ 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0E, 0x0E, 0x0F, 0x10, 0x11, 0x12,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13};
+
+/* direction: freq
+ contents : codewords
+ raw table: HuffCode2.m
+ built by : FH 00-02-04 */
+
+const INT v_Huff_envelopeLevelC11F[63] = {
+ 0x000FFFF0, 0x000FFFF1, 0x000FFFF2, 0x000FFFF3, 0x000FFFF4, 0x000FFFF5,
+ 0x000FFFF6, 0x0003FFF3, 0x0007FFF5, 0x0007FFEE, 0x0007FFEF, 0x0007FFF6,
+ 0x0003FFF4, 0x0003FFF2, 0x000FFFF7, 0x0007FFF0, 0x0001FFF5, 0x0003FFF0,
+ 0x0001FFF4, 0x0000FFF7, 0x0000FFF6, 0x00007FF8, 0x00003FFB, 0x00000FFD,
+ 0x000007FD, 0x000003FD, 0x000001FD, 0x000000FD, 0x0000003E, 0x0000000E,
+ 0x00000002, 0x00000000, 0x00000006, 0x0000001E, 0x000000FC, 0x000001FC,
+ 0x000003FC, 0x000007FC, 0x00000FFC, 0x00001FFC, 0x00003FFA, 0x00007FF9,
+ 0x00007FFA, 0x0000FFF8, 0x0000FFF9, 0x0001FFF6, 0x0001FFF7, 0x0003FFF5,
+ 0x0003FFF6, 0x0003FFF1, 0x000FFFF8, 0x0007FFF1, 0x0007FFF2, 0x0007FFF3,
+ 0x000FFFF9, 0x0007FFF7, 0x0007FFF4, 0x000FFFFA, 0x000FFFFB, 0x000FFFFC,
+ 0x000FFFFD, 0x000FFFFE, 0x000FFFFF};
+
+/* direction: freq
+ contents : codeword lengths
+ raw table: HuffCode2.m
+ built by : FH 00-02-04 */
+
+const UCHAR v_Huff_envelopeLevelL11F[63] = {
+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x12, 0x13, 0x13, 0x13,
+ 0x13, 0x12, 0x12, 0x14, 0x13, 0x11, 0x12, 0x11, 0x10, 0x10, 0x0F,
+ 0x0E, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01, 0x03,
+ 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x0F, 0x10,
+ 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x14, 0x13, 0x13, 0x13, 0x14,
+ 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14};
+
+/*******************************************************************************/
+/* table : envelope balance, 3.0 dB */
+/* theor range : [-24,24], CODE_BOOK_SCF_LAV = 24 */
+/* implem range: same but mapped to [-12,12], CODE_BOOK_SCF_LAV_BALANCE11 = 12
+ */
+/* raw stats : envelopeBalance_11 KK 00-02-03 */
+/*******************************************************************************/
+
+/* direction: time
+ contents : codewords
+ raw table: HuffCode3C.m/envelopeBalance_11T.mat/v_nBhex
+ built by : FH 01-05-15 */
+
+const INT bookSbrEnvBalanceC11T[25] = {
+ 0x00001FF2, 0x00001FF3, 0x00001FF4, 0x00001FF5, 0x00001FF6,
+ 0x00001FF7, 0x00001FF8, 0x00000FF8, 0x000000FE, 0x0000007E,
+ 0x0000000E, 0x00000006, 0x00000000, 0x00000002, 0x0000001E,
+ 0x0000003E, 0x000001FE, 0x00001FF9, 0x00001FFA, 0x00001FFB,
+ 0x00001FFC, 0x00001FFD, 0x00001FFE, 0x00003FFE, 0x00003FFF};
+
+/* direction: time
+ contents : codeword lengths
+ raw table: HuffCode3C.m/envelopeBalance_11T.mat/v_nLhex
+ built by : FH 01-05-15 */
+
+const UCHAR bookSbrEnvBalanceL11T[25] = {
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x08,
+ 0x07, 0x04, 0x03, 0x01, 0x02, 0x05, 0x06, 0x09, 0x0D,
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E};
+
+/* direction: freq
+ contents : codewords
+ raw table: HuffCode3C.m/envelopeBalance_11F.mat/v_nBhex
+ built by : FH 01-05-15 */
+
+const INT bookSbrEnvBalanceC11F[25] = {
+ 0x00001FF7, 0x00001FF8, 0x00001FF9, 0x00001FFA, 0x00001FFB,
+ 0x00003FF8, 0x00003FF9, 0x000007FC, 0x000000FE, 0x0000007E,
+ 0x0000000E, 0x00000002, 0x00000000, 0x00000006, 0x0000001E,
+ 0x0000003E, 0x000001FE, 0x00000FFA, 0x00001FF6, 0x00003FFA,
+ 0x00003FFB, 0x00003FFC, 0x00003FFD, 0x00003FFE, 0x00003FFF};
+
+/* direction: freq
+ contents : codeword lengths
+ raw table: HuffCode3C.m/envelopeBalance_11F.mat/v_nLhex
+ built by : FH 01-05-15 */
+
+const UCHAR bookSbrEnvBalanceL11F[25] = {
+ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E, 0x0B, 0x08,
+ 0x07, 0x04, 0x02, 0x01, 0x03, 0x05, 0x06, 0x09, 0x0C,
+ 0x0D, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E};
+
+/*******************************************************************************/
+/* table : noise level, 3.0 dB */
+/* theor range : [-29,29], CODE_BOOK_SCF_LAV = 29 */
+/* implem range: [-31,31], CODE_BOOK_SCF_LAV11 = 31 */
+/* raw stats : noiseLevel_11 KK 00-02-03 */
+/*******************************************************************************/
+
+/* direction: time
+ contents : codewords
+ raw table: HuffCode2.m
+ built by : FH 00-02-04 */
+
+const INT v_Huff_NoiseLevelC11T[63] = {
+ 0x00001FCE, 0x00001FCF, 0x00001FD0, 0x00001FD1, 0x00001FD2, 0x00001FD3,
+ 0x00001FD4, 0x00001FD5, 0x00001FD6, 0x00001FD7, 0x00001FD8, 0x00001FD9,
+ 0x00001FDA, 0x00001FDB, 0x00001FDC, 0x00001FDD, 0x00001FDE, 0x00001FDF,
+ 0x00001FE0, 0x00001FE1, 0x00001FE2, 0x00001FE3, 0x00001FE4, 0x00001FE5,
+ 0x00001FE6, 0x00001FE7, 0x000007F2, 0x000000FD, 0x0000003E, 0x0000000E,
+ 0x00000006, 0x00000000, 0x00000002, 0x0000001E, 0x000000FC, 0x000003F8,
+ 0x00001FCC, 0x00001FE8, 0x00001FE9, 0x00001FEA, 0x00001FEB, 0x00001FEC,
+ 0x00001FCD, 0x00001FED, 0x00001FEE, 0x00001FEF, 0x00001FF0, 0x00001FF1,
+ 0x00001FF2, 0x00001FF3, 0x00001FF4, 0x00001FF5, 0x00001FF6, 0x00001FF7,
+ 0x00001FF8, 0x00001FF9, 0x00001FFA, 0x00001FFB, 0x00001FFC, 0x00001FFD,
+ 0x00001FFE, 0x00003FFE, 0x00003FFF};
+
+/* direction: time
+ contents : codeword lengths
+ raw table: HuffCode2.m
+ built by : FH 00-02-04 */
+
+const UCHAR v_Huff_NoiseLevelL11T[63] = {
+ 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
+ 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
+ 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
+ 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
+ 0x0000000D, 0x0000000D, 0x0000000B, 0x00000008, 0x00000006, 0x00000004,
+ 0x00000003, 0x00000001, 0x00000002, 0x00000005, 0x00000008, 0x0000000A,
+ 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
+ 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
+ 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
+ 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D,
+ 0x0000000D, 0x0000000E, 0x0000000E};
+
+/*******************************************************************************/
+/* table : noise balance, 3.0 dB */
+/* theor range : [-24,24], CODE_BOOK_SCF_LAV = 24 */
+/* implem range: same but mapped to [-12,12], CODE_BOOK_SCF_LAV_BALANCE11 = 12
+ */
+/* raw stats : noiseBalance_11 KK 00-02-03 */
+/*******************************************************************************/
+
+/* direction: time
+ contents : codewords
+ raw table: HuffCode3C.m/noiseBalance_11.mat/v_nBhex
+ built by : FH 01-05-15 */
+
+const INT bookSbrNoiseBalanceC11T[25] = {
+ 0x000000EC, 0x000000ED, 0x000000EE, 0x000000EF, 0x000000F0,
+ 0x000000F1, 0x000000F2, 0x000000F3, 0x000000F4, 0x000000F5,
+ 0x0000001C, 0x00000002, 0x00000000, 0x00000006, 0x0000003A,
+ 0x000000F6, 0x000000F7, 0x000000F8, 0x000000F9, 0x000000FA,
+ 0x000000FB, 0x000000FC, 0x000000FD, 0x000000FE, 0x000000FF};
+
+/* direction: time
+ contents : codeword lengths
+ raw table: HuffCode3C.m/noiseBalance_11.mat/v_nLhex
+ built by : FH 01-05-15 */
+
+const UCHAR bookSbrNoiseBalanceL11T[25] = {
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x05, 0x02, 0x01, 0x03, 0x06, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
+
+/*
+ tuningTable
+*/
+const sbrTuningTable_t sbrTuningTable[] = {
+ /* Some of the low bitrates are commented out here, this is because the
+ encoder could lose frames at those bitrates and throw an error
+ because it has insufficient bits to encode for some test items.
+ */
+
+ /*** HE-AAC section ***/
+ /* sf,sfsp,sf,sfsp,nnb,nfo,saml,SM,FS*/
+
+ /*** mono ***/
+
+ /* 8/16 kHz dual rate */
+ {CODEC_AAC, 8000, 10000, 8000, 1, 7, 6, 11, 10, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 10000, 12000, 8000, 1, 11, 7, 13, 12, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 12000, 16001, 8000, 1, 14, 10, 13, 13, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 16000, 24000, 8000, 1, 14, 10, 14, 14, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 24000, 32000, 8000, 1, 14, 10, 14, 14, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 32000, 48001, 8000, 1, 14, 11, 15, 15, 2, 0, 3, SBR_MONO, 2},
+
+ /* 11/22 kHz dual rate */
+ {CODEC_AAC, 8000, 10000, 11025, 1, 5, 4, 6, 6, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 10000, 12000, 11025, 1, 8, 5, 12, 9, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 12000, 16000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 16000, 20000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 20000, 24001, 11025, 1, 13, 9, 13, 8, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 24000, 32000, 11025, 1, 14, 10, 14, 9, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 32000, 48000, 11025, 1, 15, 11, 15, 10, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 48000, 64001, 11025, 1, 15, 11, 15, 10, 2, 0, 3, SBR_MONO, 1},
+
+ /* 12/24 kHz dual rate */
+ {CODEC_AAC, 8000, 10000, 12000, 1, 4, 3, 6, 6, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 10000, 12000, 12000, 1, 7, 4, 11, 8, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 12000, 16000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 16000, 20000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 20000, 24001, 12000, 1, 12, 8, 12, 8, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 24000, 32000, 12000, 1, 13, 9, 13, 9, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 32000, 48000, 12000, 1, 14, 10, 14, 10, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 48000, 64001, 12000, 1, 14, 11, 15, 11, 2, 0, 3, SBR_MONO, 1},
+
+ /* 16/32 kHz dual rate */
+ {CODEC_AAC, 8000, 10000, 16000, 1, 1, 1, 0, 0, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 10000, 12000, 16000, 1, 2, 1, 6, 0, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 12000, 16000, 16000, 1, 4, 2, 6, 0, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 16000, 18000, 16000, 1, 4, 2, 8, 3, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 18000, 22000, 16000, 1, 6, 5, 11, 7, 2, 0, 6, SBR_MONO, 2},
+ {CODEC_AAC, 22000, 28000, 16000, 1, 10, 9, 12, 8, 2, 0, 6, SBR_MONO, 2},
+ {CODEC_AAC, 28000, 36000, 16000, 1, 12, 12, 13, 13, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 36000, 44000, 16000, 1, 14, 14, 13, 13, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AAC, 44000, 64001, 16000, 1, 14, 14, 13, 13, 2, 0, 3, SBR_MONO, 1},
+
+ /* 22.05/44.1 kHz dual rate */
+ /* { CODEC_AAC, 8000, 11369, 22050, 1, 1, 1, 1, 1, 1, 0, 6,
+ SBR_MONO, 3 }, */
+ {CODEC_AAC, 11369, 16000, 22050, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 16000, 18000, 22050, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 18000, 22000, 22050, 1, 4, 4, 8, 5, 2, 0, 6, SBR_MONO, 2},
+ {CODEC_AAC, 22000, 28000, 22050, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2},
+ {CODEC_AAC, 28000, 36000, 22050, 1, 10, 10, 9, 9, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 36000, 44000, 22050, 1, 11, 11, 10, 10, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AAC, 44000, 64001, 22050, 1, 13, 13, 12, 12, 2, 0, 3, SBR_MONO, 1},
+
+ /* 24/48 kHz dual rate */
+ /* { CODEC_AAC, 8000, 12000, 24000, 1, 1, 1, 1, 1, 1, 0, 6,
+ SBR_MONO, 3 }, */
+ {CODEC_AAC, 12000, 16000, 24000, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 16000, 18000, 24000, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AAC, 18000, 22000, 24000, 1, 4, 3, 8, 5, 2, 0, 6, SBR_MONO, 2},
+ {CODEC_AAC, 22000, 28000, 24000, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2},
+ {CODEC_AAC, 28000, 36000, 24000, 1, 10, 10, 9, 9, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 36000, 44000, 24000, 1, 11, 11, 10, 10, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AAC, 44000, 64001, 24000, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO, 1},
+
+ /* 32/64 kHz dual rate */
+ {CODEC_AAC, 24000, 36000, 32000, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3},
+ {CODEC_AAC, 36000, 60000, 32000, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 60000, 72000, 32000, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AAC, 72000, 100000, 32000, 1, 11, 11, 10, 10, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AAC, 100000, 160001, 32000, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO, 1},
+
+ /* 44.1/88.2 kHz dual rate */
+ {CODEC_AAC, 24000, 36000, 44100, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3},
+ {CODEC_AAC, 36000, 60000, 44100, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 60000, 72000, 44100, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AAC, 72000, 100000, 44100, 1, 11, 11, 10, 10, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AAC, 100000, 160001, 44100, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO, 1},
+
+ /* 48/96 kHz dual rate */
+ {CODEC_AAC, 32000, 36000, 48000, 1, 4, 4, 9, 9, 2, 0, 3, SBR_MONO, 3},
+ {CODEC_AAC, 36000, 60000, 48000, 1, 7, 7, 10, 10, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AAC, 60000, 72000, 48000, 1, 9, 9, 10, 10, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AAC, 72000, 100000, 48000, 1, 11, 11, 11, 11, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AAC, 100000, 160001, 48000, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO, 1},
+
+ /*** stereo ***/
+ /* 08/16 kHz dual rate */
+ {CODEC_AAC, 16000, 24000, 8000, 2, 6, 6, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, 3},
+ {CODEC_AAC, 24000, 28000, 8000, 2, 9, 9, 11, 9, 1, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 28000, 36000, 8000, 2, 11, 9, 11, 9, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 36000, 44000, 8000, 2, 13, 11, 13, 11, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 44000, 52000, 8000, 2, 14, 12, 13, 12, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 52000, 60000, 8000, 2, 14, 14, 13, 13, 3, 0, -3, SBR_SWITCH_LRC,
+ 1},
+ {CODEC_AAC, 60000, 76000, 8000, 2, 14, 14, 13, 13, 3, 0, -3, SBR_LEFT_RIGHT,
+ 1},
+ {CODEC_AAC, 76000, 128001, 8000, 2, 14, 14, 13, 13, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 11/22 kHz dual rate */
+ {CODEC_AAC, 16000, 24000, 11025, 2, 7, 5, 9, 7, 1, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 24000, 28000, 11025, 2, 10, 8, 10, 8, 1, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 28000, 36000, 11025, 2, 12, 8, 12, 8, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 36000, 44000, 11025, 2, 13, 9, 13, 9, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 44000, 52000, 11025, 2, 14, 11, 13, 11, 2, 0, -3,
+ SBR_SWITCH_LRC, 2},
+ {CODEC_AAC, 52000, 60000, 11025, 2, 15, 15, 13, 13, 3, 0, -3,
+ SBR_SWITCH_LRC, 1},
+ {CODEC_AAC, 60000, 76000, 11025, 2, 15, 15, 13, 13, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AAC, 76000, 128001, 11025, 2, 15, 15, 13, 13, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 12/24 kHz dual rate */
+ {CODEC_AAC, 16000, 24000, 12000, 2, 6, 4, 9, 7, 1, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 24000, 28000, 12000, 2, 9, 7, 10, 8, 1, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 28000, 36000, 12000, 2, 11, 7, 12, 8, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 36000, 44000, 12000, 2, 12, 9, 12, 9, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 44000, 52000, 12000, 2, 13, 12, 13, 12, 2, 0, -3,
+ SBR_SWITCH_LRC, 2},
+ {CODEC_AAC, 52000, 60000, 12000, 2, 14, 14, 13, 13, 3, 0, -3,
+ SBR_SWITCH_LRC, 1},
+ {CODEC_AAC, 60000, 76000, 12000, 2, 14, 14, 13, 13, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AAC, 76000, 128001, 12000, 2, 14, 14, 13, 13, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 16/32 kHz dual rate */
+ {CODEC_AAC, 16000, 24000, 16000, 2, 4, 2, 1, 0, 1, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 24000, 28000, 16000, 2, 8, 7, 10, 8, 1, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 28000, 36000, 16000, 2, 10, 9, 12, 11, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 36000, 44000, 16000, 2, 13, 13, 13, 13, 2, 0, -3,
+ SBR_SWITCH_LRC, 2},
+ {CODEC_AAC, 44000, 52000, 16000, 2, 14, 14, 13, 13, 2, 0, -3,
+ SBR_SWITCH_LRC, 2},
+ {CODEC_AAC, 52000, 60000, 16000, 2, 14, 14, 13, 13, 3, 0, -3,
+ SBR_SWITCH_LRC, 1},
+ {CODEC_AAC, 60000, 76000, 16000, 2, 14, 14, 13, 13, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AAC, 76000, 128001, 16000, 2, 14, 14, 13, 13, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 22.05/44.1 kHz dual rate */
+ {CODEC_AAC, 16000, 24000, 22050, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 24000, 28000, 22050, 2, 5, 4, 6, 5, 1, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 28000, 32000, 22050, 2, 5, 4, 8, 7, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 32000, 36000, 22050, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 36000, 44000, 22050, 2, 10, 10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 44000, 52000, 22050, 2, 12, 12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 52000, 60000, 22050, 2, 13, 13, 10, 10, 3, 0, -3,
+ SBR_SWITCH_LRC, 1},
+ {CODEC_AAC, 60000, 76000, 22050, 2, 14, 14, 12, 12, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AAC, 76000, 128001, 22050, 2, 14, 14, 12, 12, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 24/48 kHz dual rate */
+ {CODEC_AAC, 16000, 24000, 24000, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 24000, 28000, 24000, 2, 5, 5, 6, 6, 1, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 28000, 36000, 24000, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 36000, 44000, 24000, 2, 10, 10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 44000, 52000, 24000, 2, 12, 12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 52000, 60000, 24000, 2, 13, 13, 10, 10, 3, 0, -3,
+ SBR_SWITCH_LRC, 1},
+ {CODEC_AAC, 60000, 76000, 24000, 2, 14, 14, 12, 12, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AAC, 76000, 128001, 24000, 2, 14, 14, 12, 12, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 32/64 kHz dual rate */
+ {CODEC_AAC, 32000, 60000, 32000, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 60000, 80000, 32000, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 80000, 112000, 32000, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT,
+ 1},
+ {CODEC_AAC, 112000, 144000, 32000, 2, 11, 11, 10, 10, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AAC, 144000, 256001, 32000, 2, 13, 13, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 44.1/88.2 kHz dual rate */
+ {CODEC_AAC, 32000, 60000, 44100, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 60000, 80000, 44100, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 80000, 112000, 44100, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT,
+ 1},
+ {CODEC_AAC, 112000, 144000, 44100, 2, 11, 11, 10, 10, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AAC, 144000, 256001, 44100, 2, 13, 13, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 48/96 kHz dual rate */
+ {CODEC_AAC, 36000, 60000, 48000, 2, 4, 4, 9, 9, 2, 0, -3, SBR_SWITCH_LRC,
+ 3},
+ {CODEC_AAC, 60000, 80000, 48000, 2, 7, 7, 9, 9, 3, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AAC, 80000, 112000, 48000, 2, 9, 9, 10, 10, 3, 0, -3, SBR_LEFT_RIGHT,
+ 1},
+ {CODEC_AAC, 112000, 144000, 48000, 2, 11, 11, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AAC, 144000, 256001, 48000, 2, 13, 13, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /** 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},
+
+ /*** mono ***/
+ /* 16/32 kHz dual rate */
+ {CODEC_AACLD, 16000, 18000, 16000, 1, 4, 5, 9, 7, 1, 0, 6, SBR_MONO, 3},
+ {CODEC_AACLD, 18000, 22000, 16000, 1, 7, 7, 12, 12, 1, 6, 9, SBR_MONO, 3},
+ {CODEC_AACLD, 22000, 28000, 16000, 1, 6, 6, 9, 9, 2, 3, 6, SBR_MONO, 3},
+ {CODEC_AACLD, 28000, 36000, 16000, 1, 8, 8, 12, 7, 2, 9, 12, SBR_MONO, 3},
+ {CODEC_AACLD, 36000, 44000, 16000, 1, 10, 14, 12, 13, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AACLD, 44000, 64001, 16000, 1, 11, 14, 13, 13, 2, 0, 3, SBR_MONO, 1},
+
+ /* 22.05/44.1 kHz dual rate */
+ {CODEC_AACLD, 18000, 22000, 22050, 1, 4, 4, 5, 5, 2, 0, 6, SBR_MONO, 3},
+ {CODEC_AACLD, 22000, 28000, 22050, 1, 5, 5, 6, 6, 2, 0, 6, SBR_MONO, 2},
+ {CODEC_AACLD, 28000, 36000, 22050, 1, 7, 8, 8, 8, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AACLD, 36000, 44000, 22050, 1, 9, 9, 9, 9, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AACLD, 44000, 52000, 22050, 1, 12, 11, 11, 11, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AACLD, 52000, 64001, 22050, 1, 13, 11, 11, 10, 2, 0, 3, SBR_MONO, 1},
+
+ /* 24/48 kHz dual rate */
+ {CODEC_AACLD, 20000, 22000, 24000, 1, 3, 4, 8, 8, 2, 0, 6, SBR_MONO, 2},
+ {CODEC_AACLD, 22000, 28000, 24000, 1, 3, 8, 8, 7, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AACLD, 28000, 36000, 24000, 1, 4, 8, 8, 7, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AACLD, 36000, 56000, 24000, 1, 8, 9, 9, 8, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AACLD, 56000, 64001, 24000, 1, 13, 11, 11, 10, 2, 0, 3, SBR_MONO, 1},
+
+ /* 32/64 kHz dual rate */
+ {CODEC_AACLD, 24000, 36000, 32000, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3},
+ {CODEC_AACLD, 36000, 60000, 32000, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AACLD, 60000, 72000, 32000, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AACLD, 72000, 100000, 32000, 1, 11, 11, 10, 10, 2, 0, 3, SBR_MONO,
+ 1},
+ {CODEC_AACLD, 100000, 160001, 32000, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO,
+ 1},
+
+ /* 44/88 kHz dual rate */
+ {CODEC_AACLD, 36000, 60000, 44100, 1, 8, 7, 6, 9, 2, 0, 3, SBR_MONO, 2},
+ {CODEC_AACLD, 60000, 72000, 44100, 1, 9, 9, 10, 10, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AACLD, 72000, 100000, 44100, 1, 11, 11, 11, 11, 2, 0, 3, SBR_MONO,
+ 1},
+ {CODEC_AACLD, 100000, 160001, 44100, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO,
+ 1},
+
+ /* 48/96 kHz dual rate */ /* 32 and 40kbps line tuned for dual-rate SBR
+ */
+ {CODEC_AACLD, 36000, 60000, 48000, 1, 4, 7, 4, 4, 2, 0, 3, SBR_MONO, 3},
+ {CODEC_AACLD, 60000, 72000, 48000, 1, 9, 9, 10, 10, 2, 0, 3, SBR_MONO, 1},
+ {CODEC_AACLD, 72000, 100000, 48000, 1, 11, 11, 11, 11, 2, 0, 3, SBR_MONO,
+ 1},
+ {CODEC_AACLD, 100000, 160001, 48000, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO,
+ 1},
+
+ /*** stereo ***/
+ /* 16/32 kHz dual rate */
+ {CODEC_AACLD, 32000, 36000, 16000, 2, 10, 9, 12, 11, 2, 0, -3,
+ SBR_SWITCH_LRC, 2},
+ {CODEC_AACLD, 36000, 44000, 16000, 2, 13, 13, 13, 13, 2, 0, -3,
+ SBR_SWITCH_LRC, 2},
+ {CODEC_AACLD, 44000, 52000, 16000, 2, 10, 9, 11, 9, 2, 0, -3,
+ SBR_SWITCH_LRC, 2},
+ {CODEC_AACLD, 52000, 60000, 16000, 2, 14, 14, 13, 13, 3, 0, -3,
+ SBR_SWITCH_LRC, 1},
+ {CODEC_AACLD, 60000, 76000, 16000, 2, 14, 14, 13, 13, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AACLD, 76000, 128001, 16000, 2, 14, 14, 13, 13, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 22.05/44.1 kHz dual rate */
+ {CODEC_AACLD, 32000, 36000, 22050, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AACLD, 36000, 44000, 22050, 2, 5, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AACLD, 44000, 52000, 22050, 2, 7, 10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AACLD, 52000, 60000, 22050, 2, 9, 11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC,
+ 1},
+ {CODEC_AACLD, 60000, 76000, 22050, 2, 10, 12, 10, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AACLD, 76000, 82000, 22050, 2, 12, 12, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AACLD, 82000, 128001, 22050, 2, 13, 12, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 24/48 kHz dual rate */
+ {CODEC_AACLD, 32000, 36000, 24000, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AACLD, 36000, 44000, 24000, 2, 4, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AACLD, 44000, 52000, 24000, 2, 6, 10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AACLD, 52000, 60000, 24000, 2, 9, 11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC,
+ 1},
+ {CODEC_AACLD, 60000, 76000, 24000, 2, 11, 12, 10, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AACLD, 76000, 88000, 24000, 2, 12, 13, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AACLD, 88000, 128001, 24000, 2, 13, 13, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 32/64 kHz dual rate */
+ {CODEC_AACLD, 60000, 80000, 32000, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AACLD, 80000, 112000, 32000, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT,
+ 1},
+ {CODEC_AACLD, 112000, 144000, 32000, 2, 11, 11, 10, 10, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AACLD, 144000, 256001, 32000, 2, 13, 13, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 44.1/88.2 kHz dual rate */
+ {CODEC_AACLD, 60000, 80000, 44100, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC,
+ 2},
+ {CODEC_AACLD, 80000, 112000, 44100, 2, 10, 10, 8, 8, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AACLD, 112000, 144000, 44100, 2, 12, 12, 10, 10, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AACLD, 144000, 256001, 44100, 2, 13, 13, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+ /* 48/96 kHz dual rate */
+ {CODEC_AACLD, 60000, 80000, 48000, 2, 7, 7, 10, 10, 2, 0, -3,
+ SBR_SWITCH_LRC, 2},
+ {CODEC_AACLD, 80000, 112000, 48000, 2, 9, 9, 10, 10, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AACLD, 112000, 144000, 48000, 2, 11, 11, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AACLD, 144000, 176000, 48000, 2, 12, 12, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+ {CODEC_AACLD, 176000, 256001, 48000, 2, 13, 13, 11, 11, 3, 0, -3,
+ SBR_LEFT_RIGHT, 1},
+
+};
+
+const int sbrTuningTableSize =
+ sizeof(sbrTuningTable) / sizeof(sbrTuningTable[0]);
+
+const psTuningTable_t psTuningTable[4] = {
+ {8000, 22000, PSENC_STEREO_BANDS_10, PSENC_NENV_1,
+ FL2FXCONST_DBL(3.0f / 4.0f)},
+ {22000, 28000, PSENC_STEREO_BANDS_20, PSENC_NENV_1,
+ FL2FXCONST_DBL(2.0f / 4.0f)},
+ {28000, 36000, PSENC_STEREO_BANDS_20, PSENC_NENV_2,
+ FL2FXCONST_DBL(1.5f / 4.0f)},
+ {36000, 160001, PSENC_STEREO_BANDS_20, PSENC_NENV_4,
+ FL2FXCONST_DBL(1.1f / 4.0f)},
+};
+
+//@}
diff --git a/fdk-aac/libSBRenc/src/sbrenc_rom.h b/fdk-aac/libSBRenc/src/sbrenc_rom.h
new file mode 100644
index 0000000..18c1fb9
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/sbrenc_rom.h
@@ -0,0 +1,145 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+\file
+\brief Declaration of constant tables
+$Revision: 92790 $
+*/
+#ifndef SBRENC_ROM_H
+#define SBRENC_ROM_H
+
+#include "sbr_def.h"
+#include "sbr_encoder.h"
+
+#include "ps_main.h"
+
+/*
+ huffman tables
+*/
+extern const INT v_Huff_envelopeLevelC10T[121];
+extern const UCHAR v_Huff_envelopeLevelL10T[121];
+extern const INT v_Huff_envelopeLevelC10F[121];
+extern const UCHAR v_Huff_envelopeLevelL10F[121];
+extern const INT bookSbrEnvBalanceC10T[49];
+extern const UCHAR bookSbrEnvBalanceL10T[49];
+extern const INT bookSbrEnvBalanceC10F[49];
+extern const UCHAR bookSbrEnvBalanceL10F[49];
+extern const INT v_Huff_envelopeLevelC11T[63];
+extern const UCHAR v_Huff_envelopeLevelL11T[63];
+extern const INT v_Huff_envelopeLevelC11F[63];
+extern const UCHAR v_Huff_envelopeLevelL11F[63];
+extern const INT bookSbrEnvBalanceC11T[25];
+extern const UCHAR bookSbrEnvBalanceL11T[25];
+extern const INT bookSbrEnvBalanceC11F[25];
+extern const UCHAR bookSbrEnvBalanceL11F[25];
+extern const INT v_Huff_NoiseLevelC11T[63];
+extern const UCHAR v_Huff_NoiseLevelL11T[63];
+extern const INT bookSbrNoiseBalanceC11T[25];
+extern const UCHAR bookSbrNoiseBalanceL11T[25];
+
+extern const sbrTuningTable_t sbrTuningTable[];
+extern const int sbrTuningTableSize;
+
+extern const psTuningTable_t psTuningTable[4];
+
+#endif
diff --git a/fdk-aac/libSBRenc/src/ton_corr.cpp b/fdk-aac/libSBRenc/src/ton_corr.cpp
new file mode 100644
index 0000000..1c050e2
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/ton_corr.cpp
@@ -0,0 +1,891 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#include "ton_corr.h"
+
+#include "sbrenc_ram.h"
+#include "sbr_misc.h"
+#include "genericStds.h"
+#include "autocorr2nd.h"
+
+#define BAND_V_SIZE 32
+#define NUM_V_COMBINE \
+ 8 /* Must be a divisor of 64 and fulfill the ASSERTs below */
+
+/**************************************************************************/
+/*!
+ \brief Calculates the tonal to noise ration for different frequency bands
+ and time segments.
+
+ The ratio between the predicted energy (tonal energy A) and the total
+ energy (A + B) is calculated. This is converted to the ratio between
+ the predicted energy (tonal energy A) and the non-predictable energy
+ (noise energy B). Hence the quota-matrix contains A/B = q/(1-q).
+
+ The samples in nrgVector are scaled by 1.0/16.0
+ The samples in pNrgVectorFreq are scaled by 1.0/2.0
+ The samples in quotaMatrix are scaled by RELAXATION
+
+ \return none.
+
+*/
+/**************************************************************************/
+
+void FDKsbrEnc_CalculateTonalityQuotas(
+ HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
+ FIXP_DBL **RESTRICT
+ sourceBufferReal, /*!< The real part of the QMF-matrix. */
+ FIXP_DBL **RESTRICT
+ sourceBufferImag, /*!< The imaginary part of the QMF-matrix. */
+ INT usb, /*!< upper side band, highest + 1 QMF band in the SBR range. */
+ INT qmfScale /*!< sclefactor of QMF subsamples */
+) {
+ INT i, k, r, r2, timeIndex, autoCorrScaling;
+
+ INT startIndexMatrix = hTonCorr->startIndexMatrix;
+ INT totNoEst = hTonCorr->numberOfEstimates;
+ INT noEstPerFrame = hTonCorr->numberOfEstimatesPerFrame;
+ INT move = hTonCorr->move;
+ INT noQmfChannels = hTonCorr->noQmfChannels; /* Number of Bands */
+ INT buffLen = hTonCorr->bufferLength; /* Number of Slots */
+ INT stepSize = hTonCorr->stepSize;
+ INT *pBlockLength = hTonCorr->lpcLength;
+ INT **RESTRICT signMatrix = hTonCorr->signMatrix;
+ FIXP_DBL *RESTRICT nrgVector = hTonCorr->nrgVector;
+ FIXP_DBL **RESTRICT quotaMatrix = hTonCorr->quotaMatrix;
+ FIXP_DBL *RESTRICT pNrgVectorFreq = hTonCorr->nrgVectorFreq;
+
+ FIXP_DBL *realBuf;
+ FIXP_DBL *imagBuf;
+
+ FIXP_DBL alphar[2], alphai[2], fac;
+
+ C_ALLOC_SCRATCH_START(ac, ACORR_COEFS, 1)
+ C_ALLOC_SCRATCH_START(realBufRef, FIXP_DBL, 2 * BAND_V_SIZE * NUM_V_COMBINE)
+ realBuf = realBufRef;
+ imagBuf = realBuf + BAND_V_SIZE * NUM_V_COMBINE;
+
+ FDK_ASSERT(buffLen <= BAND_V_SIZE);
+ FDK_ASSERT(sizeof(FIXP_DBL) * NUM_V_COMBINE * BAND_V_SIZE * 2 <
+ (1024 * sizeof(FIXP_DBL) - sizeof(ACORR_COEFS)));
+
+ /*
+ * Buffering of the quotaMatrix and the quotaMatrixTransp.
+ *********************************************************/
+ for (i = 0; i < move; i++) {
+ FDKmemcpy(quotaMatrix[i], quotaMatrix[i + noEstPerFrame],
+ noQmfChannels * sizeof(FIXP_DBL));
+ FDKmemcpy(signMatrix[i], signMatrix[i + noEstPerFrame],
+ noQmfChannels * sizeof(INT));
+ }
+
+ FDKmemmove(nrgVector, nrgVector + noEstPerFrame, move * sizeof(FIXP_DBL));
+ FDKmemclear(nrgVector + startIndexMatrix,
+ (totNoEst - startIndexMatrix) * sizeof(FIXP_DBL));
+ FDKmemclear(pNrgVectorFreq, noQmfChannels * sizeof(FIXP_DBL));
+
+ /*
+ * Calculate the quotas for the current time steps.
+ **************************************************/
+
+ for (r = 0; r < usb; r++) {
+ int blockLength;
+
+ k = hTonCorr->nextSample; /* startSample */
+ timeIndex = startIndexMatrix;
+ /* Copy as many as possible Band across all Slots at once */
+ if (realBuf != realBufRef) {
+ realBuf -= BAND_V_SIZE;
+ imagBuf -= BAND_V_SIZE;
+ } else {
+ realBuf += BAND_V_SIZE * (NUM_V_COMBINE - 1);
+ imagBuf += BAND_V_SIZE * (NUM_V_COMBINE - 1);
+
+ for (i = 0; i < buffLen; i++) {
+ int v;
+ FIXP_DBL *ptr;
+ ptr = realBuf + i;
+ for (v = 0; v < NUM_V_COMBINE; v++) {
+ ptr[0] = sourceBufferReal[i][r + v];
+ ptr[0 + BAND_V_SIZE * NUM_V_COMBINE] = sourceBufferImag[i][r + v];
+ ptr -= BAND_V_SIZE;
+ }
+ }
+ }
+
+ blockLength = pBlockLength[0];
+
+ while (k <= buffLen - blockLength) {
+ autoCorrScaling = fixMin(
+ getScalefactor(&realBuf[k - LPC_ORDER], LPC_ORDER + blockLength),
+ getScalefactor(&imagBuf[k - LPC_ORDER], LPC_ORDER + blockLength));
+ autoCorrScaling = fixMax(0, autoCorrScaling - 1);
+
+ scaleValues(&realBuf[k - LPC_ORDER], LPC_ORDER + blockLength,
+ autoCorrScaling);
+ scaleValues(&imagBuf[k - LPC_ORDER], LPC_ORDER + blockLength,
+ autoCorrScaling);
+
+ autoCorrScaling <<= 1; /* consider qmf buffer scaling twice */
+ autoCorrScaling +=
+ autoCorr2nd_cplx(ac, realBuf + k, imagBuf + k, blockLength);
+
+ if (ac->det == FL2FXCONST_DBL(0.0f)) {
+ alphar[1] = alphai[1] = FL2FXCONST_DBL(0.0f);
+
+ alphar[0] = (ac->r01r) >> 2;
+ alphai[0] = (ac->r01i) >> 2;
+
+ fac = fMultDiv2(ac->r00r, ac->r11r) >> 1;
+ } else {
+ alphar[1] = (fMultDiv2(ac->r01r, ac->r12r) >> 1) -
+ (fMultDiv2(ac->r01i, ac->r12i) >> 1) -
+ (fMultDiv2(ac->r02r, ac->r11r) >> 1);
+ alphai[1] = (fMultDiv2(ac->r01i, ac->r12r) >> 1) +
+ (fMultDiv2(ac->r01r, ac->r12i) >> 1) -
+ (fMultDiv2(ac->r02i, ac->r11r) >> 1);
+
+ alphar[0] = (fMultDiv2(ac->r01r, ac->det) >> (ac->det_scale + 1)) +
+ fMult(alphar[1], ac->r12r) + fMult(alphai[1], ac->r12i);
+ alphai[0] = (fMultDiv2(ac->r01i, ac->det) >> (ac->det_scale + 1)) +
+ fMult(alphai[1], ac->r12r) - fMult(alphar[1], ac->r12i);
+
+ fac = fMultDiv2(ac->r00r, fMult(ac->det, ac->r11r)) >>
+ (ac->det_scale + 1);
+ }
+
+ if (fac == FL2FXCONST_DBL(0.0f)) {
+ quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f);
+ signMatrix[timeIndex][r] = 0;
+ } else {
+ /* quotaMatrix is scaled with the factor RELAXATION
+ parse RELAXATION in fractional part and shift factor: 1/(1/0.524288 *
+ 2^RELAXATION_SHIFT) */
+ FIXP_DBL tmp, num, denom;
+ INT numShift, denomShift, commonShift;
+ INT sign;
+
+ num = fMultDiv2(alphar[0], ac->r01r) + fMultDiv2(alphai[0], ac->r01i) -
+ fMultDiv2(alphar[1], fMult(ac->r02r, ac->r11r)) -
+ fMultDiv2(alphai[1], fMult(ac->r02i, ac->r11r));
+ num = fixp_abs(num);
+
+ denom = (fac >> 1) +
+ (fMultDiv2(fac, RELAXATION_FRACT) >> RELAXATION_SHIFT) - num;
+ denom = fixp_abs(denom);
+
+ num = fMult(num, RELAXATION_FRACT);
+
+ numShift = CountLeadingBits(num) - 2;
+ num = scaleValue(num, numShift);
+
+ denomShift = CountLeadingBits(denom);
+ denom = (FIXP_DBL)denom << denomShift;
+
+ if ((num > FL2FXCONST_DBL(0.0f)) && (denom != FL2FXCONST_DBL(0.0f))) {
+ commonShift =
+ fixMin(numShift - denomShift + RELAXATION_SHIFT, DFRACT_BITS - 1);
+ if (commonShift < 0) {
+ commonShift = -commonShift;
+ tmp = schur_div(num, denom, 16);
+ commonShift = fixMin(commonShift, CountLeadingBits(tmp));
+ quotaMatrix[timeIndex][r] = tmp << commonShift;
+ } else {
+ quotaMatrix[timeIndex][r] =
+ schur_div(num, denom, 16) >> commonShift;
+ }
+ } else {
+ quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f);
+ }
+
+ if (ac->r11r != FL2FXCONST_DBL(0.0f)) {
+ if (((ac->r01r >= FL2FXCONST_DBL(0.0f)) &&
+ (ac->r11r >= FL2FXCONST_DBL(0.0f))) ||
+ ((ac->r01r < FL2FXCONST_DBL(0.0f)) &&
+ (ac->r11r < FL2FXCONST_DBL(0.0f)))) {
+ sign = 1;
+ } else {
+ sign = -1;
+ }
+ } else {
+ sign = 1;
+ }
+
+ if (sign < 0) {
+ r2 = r; /* (INT) pow(-1, band); */
+ } else {
+ r2 = r + 1; /* (INT) pow(-1, band+1); */
+ }
+ signMatrix[timeIndex][r] = 1 - 2 * (r2 & 0x1);
+ }
+
+ nrgVector[timeIndex] +=
+ ((ac->r00r) >>
+ fixMin(DFRACT_BITS - 1,
+ (2 * qmfScale + autoCorrScaling + SCALE_NRGVEC)));
+ /* pNrgVectorFreq[r] finally has to be divided by noEstPerFrame, replaced
+ * division by shifting with one */
+ pNrgVectorFreq[r] =
+ pNrgVectorFreq[r] +
+ ((ac->r00r) >>
+ fixMin(DFRACT_BITS - 1,
+ (2 * qmfScale + autoCorrScaling + SCALE_NRGVEC)));
+
+ blockLength = pBlockLength[1];
+ k += stepSize;
+ timeIndex++;
+ }
+ }
+
+ C_ALLOC_SCRATCH_END(realBufRef, FIXP_DBL, 2 * BAND_V_SIZE * NUM_V_COMBINE)
+ C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1)
+}
+
+/**************************************************************************/
+/*!
+ \brief Extracts the parameters required in the decoder to obtain the
+ correct tonal to noise ratio after SBR.
+
+ Estimates the tonal to noise ratio of the original signal (using LPC).
+ Predicts the tonal to noise ration of the SBR signal (in the decoder) by
+ patching the tonal to noise ratio values similar to the patching of the
+ lowband in the decoder. Given the tonal to noise ratio of the original
+ and the SBR signal, it estimates the required amount of inverse filtering,
+ additional noise as well as any additional sines.
+
+ \return none.
+
+*/
+/**************************************************************************/
+void FDKsbrEnc_TonCorrParamExtr(
+ HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
+ INVF_MODE *infVec, /*!< Vector where the inverse filtering levels will be
+ stored. */
+ FIXP_DBL *noiseLevels, /*!< Vector where the noise levels will be stored. */
+ INT *missingHarmonicFlag, /*!< Flag set to one or zero, dependent on if any
+ strong sines are missing.*/
+ UCHAR *missingHarmonicsIndex, /*!< Vector indicating where sines are
+ missing. */
+ UCHAR *envelopeCompensation, /*!< Vector to store compensation values for
+ the energies in. */
+ const SBR_FRAME_INFO *frameInfo, /*!< Frame info struct, contains the time
+ and frequency grid of the current
+ frame.*/
+ UCHAR *transientInfo, /*!< Transient info.*/
+ UCHAR *freqBandTable, /*!< Frequency band tables for high-res.*/
+ INT nSfb, /*!< Number of scalefactor bands for high-res. */
+ XPOS_MODE xposType, /*!< Type of transposer used in the decoder.*/
+ UINT sbrSyntaxFlags) {
+ INT band;
+ INT transientFlag = transientInfo[1]; /*!< Flag indicating if a transient is
+ present in the current frame. */
+ INT transientPos = transientInfo[0]; /*!< Position of the transient.*/
+ INT transientFrame, transientFrameInvfEst;
+ INVF_MODE *infVecPtr;
+
+ /* Determine if this is a frame where a transient starts...
+
+ The detection of noise-floor, missing harmonics and invf_est, is not in sync
+ for the non-buf-opt decoder such as AAC. Hence we need to keep track on the
+ transient in the present frame as well as in the next.
+ */
+ transientFrame = 0;
+ if (hTonCorr->transientNextFrame) { /* The transient was detected in the
+ previous frame, but is actually */
+ transientFrame = 1;
+ hTonCorr->transientNextFrame = 0;
+
+ if (transientFlag) {
+ if (transientPos + hTonCorr->transientPosOffset >=
+ frameInfo->borders[frameInfo->nEnvelopes]) {
+ hTonCorr->transientNextFrame = 1;
+ }
+ }
+ } else {
+ if (transientFlag) {
+ if (transientPos + hTonCorr->transientPosOffset <
+ frameInfo->borders[frameInfo->nEnvelopes]) {
+ transientFrame = 1;
+ hTonCorr->transientNextFrame = 0;
+ } else {
+ hTonCorr->transientNextFrame = 1;
+ }
+ }
+ }
+ transientFrameInvfEst = transientFrame;
+
+ /*
+ Estimate the required invese filtereing level.
+ */
+ if (hTonCorr->switchInverseFilt)
+ FDKsbrEnc_qmfInverseFilteringDetector(
+ &hTonCorr->sbrInvFilt, hTonCorr->quotaMatrix, hTonCorr->nrgVector,
+ hTonCorr->indexVector, hTonCorr->frameStartIndexInvfEst,
+ hTonCorr->numberOfEstimatesPerFrame + hTonCorr->frameStartIndexInvfEst,
+ transientFrameInvfEst, infVec);
+
+ /*
+ Detect what tones will be missing.
+ */
+ if (xposType == XPOS_LC) {
+ FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(
+ &hTonCorr->sbrMissingHarmonicsDetector, hTonCorr->quotaMatrix,
+ hTonCorr->signMatrix, hTonCorr->indexVector, frameInfo, transientInfo,
+ missingHarmonicFlag, missingHarmonicsIndex, freqBandTable, nSfb,
+ envelopeCompensation, hTonCorr->nrgVectorFreq);
+ } else {
+ *missingHarmonicFlag = 0;
+ FDKmemclear(missingHarmonicsIndex, nSfb * sizeof(UCHAR));
+ }
+
+ /*
+ Noise floor estimation
+ */
+
+ infVecPtr = hTonCorr->sbrInvFilt.prevInvfMode;
+
+ FDKsbrEnc_sbrNoiseFloorEstimateQmf(
+ &hTonCorr->sbrNoiseFloorEstimate, frameInfo, noiseLevels,
+ hTonCorr->quotaMatrix, hTonCorr->indexVector, *missingHarmonicFlag,
+ hTonCorr->frameStartIndex, hTonCorr->numberOfEstimatesPerFrame,
+ transientFrame, infVecPtr, sbrSyntaxFlags);
+
+ /* Store the invfVec data for the next frame...*/
+ for (band = 0; band < hTonCorr->sbrInvFilt.noDetectorBands; band++) {
+ hTonCorr->sbrInvFilt.prevInvfMode[band] = infVec[band];
+ }
+}
+
+/**************************************************************************/
+/*!
+ \brief Searches for the closest match in the frequency master table.
+
+
+
+ \return closest entry.
+
+*/
+/**************************************************************************/
+static INT findClosestEntry(INT goalSb, UCHAR *v_k_master, INT numMaster,
+ INT direction) {
+ INT index;
+
+ if (goalSb <= v_k_master[0]) return v_k_master[0];
+
+ if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster];
+
+ if (direction) {
+ index = 0;
+ while (v_k_master[index] < goalSb) {
+ index++;
+ }
+ } else {
+ index = numMaster;
+ while (v_k_master[index] > goalSb) {
+ index--;
+ }
+ }
+
+ return v_k_master[index];
+}
+
+/**************************************************************************/
+/*!
+ \brief resets the patch
+
+
+
+ \return errorCode, noError if successful.
+
+*/
+/**************************************************************************/
+static INT resetPatch(
+ HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
+ INT xposctrl, /*!< Different patch modes. */
+ INT highBandStartSb, /*!< Start band of the SBR range. */
+ UCHAR *v_k_master, /*!< Master frequency table from which all other table
+ are derived.*/
+ INT numMaster, /*!< Number of elements in the master table. */
+ INT fs, /*!< Sampling frequency. */
+ INT noChannels) /*!< Number of QMF-channels. */
+{
+ INT patch, k, i;
+ INT targetStopBand;
+
+ PATCH_PARAM *patchParam = hTonCorr->patchParam;
+
+ INT sbGuard = hTonCorr->guard;
+ INT sourceStartBand;
+ INT patchDistance;
+ INT numBandsInPatch;
+
+ INT lsb =
+ v_k_master[0]; /* Lowest subband related to the synthesis filterbank */
+ INT usb = v_k_master[numMaster]; /* Stop subband related to the synthesis
+ filterbank */
+ INT xoverOffset =
+ highBandStartSb -
+ v_k_master[0]; /* Calculate distance in subbands between k0 and kx */
+
+ INT goalSb;
+
+ /*
+ * Initialize the patching parameter
+ */
+
+ if (xposctrl == 1) {
+ lsb += xoverOffset;
+ xoverOffset = 0;
+ }
+
+ goalSb = (INT)((2 * noChannels * 16000 + (fs >> 1)) / fs); /* 16 kHz band */
+ goalSb = findClosestEntry(goalSb, v_k_master, numMaster,
+ 1); /* Adapt region to master-table */
+
+ /* First patch */
+ sourceStartBand = hTonCorr->shiftStartSb + xoverOffset;
+ targetStopBand = lsb + xoverOffset;
+
+ /* even (odd) numbered channel must be patched to even (odd) numbered channel
+ */
+ patch = 0;
+ while (targetStopBand < usb) {
+ /* To many patches */
+ if (patch >= MAX_NUM_PATCHES) return (1); /*Number of patches to high */
+
+ patchParam[patch].guardStartBand = targetStopBand;
+ targetStopBand += sbGuard;
+ patchParam[patch].targetStartBand = targetStopBand;
+
+ numBandsInPatch =
+ goalSb - targetStopBand; /* get the desired range of the patch */
+
+ if (numBandsInPatch >= lsb - sourceStartBand) {
+ /* desired number bands are not available -> patch whole source range */
+ patchDistance =
+ targetStopBand - sourceStartBand; /* get the targetOffset */
+ patchDistance =
+ patchDistance & ~1; /* rounding off odd numbers and make all even */
+ numBandsInPatch = lsb - (targetStopBand - patchDistance);
+ numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch,
+ v_k_master, numMaster, 0) -
+ targetStopBand; /* Adapt region to master-table */
+ }
+
+ /* desired number bands are available -> get the minimal even patching
+ * distance */
+ patchDistance =
+ numBandsInPatch + targetStopBand - lsb; /* get minimal distance */
+ patchDistance = (patchDistance + 1) &
+ ~1; /* rounding up odd numbers and make all even */
+
+ if (numBandsInPatch <= 0) {
+ patch--;
+ } else {
+ patchParam[patch].sourceStartBand = targetStopBand - patchDistance;
+ patchParam[patch].targetBandOffs = patchDistance;
+ patchParam[patch].numBandsInPatch = numBandsInPatch;
+ patchParam[patch].sourceStopBand =
+ patchParam[patch].sourceStartBand + numBandsInPatch;
+
+ targetStopBand += patchParam[patch].numBandsInPatch;
+ }
+
+ /* All patches but first */
+ sourceStartBand = hTonCorr->shiftStartSb;
+
+ /* Check if we are close to goalSb */
+ if (fixp_abs(targetStopBand - goalSb) < 3) {
+ goalSb = usb;
+ }
+
+ patch++;
+ }
+
+ patch--;
+
+ /* if highest patch contains less than three subband: skip it */
+ if (patchParam[patch].numBandsInPatch < 3 && patch > 0) {
+ patch--;
+ }
+
+ hTonCorr->noOfPatches = patch + 1;
+
+ /* Assign the index-vector, so we know where to look for the high-band.
+ -1 represents a guard-band. */
+ for (k = 0; k < hTonCorr->patchParam[0].guardStartBand; k++)
+ hTonCorr->indexVector[k] = k;
+
+ for (i = 0; i < hTonCorr->noOfPatches; i++) {
+ INT sourceStart = hTonCorr->patchParam[i].sourceStartBand;
+ INT targetStart = hTonCorr->patchParam[i].targetStartBand;
+ INT numberOfBands = hTonCorr->patchParam[i].numBandsInPatch;
+ INT startGuardBand = hTonCorr->patchParam[i].guardStartBand;
+
+ for (k = 0; k < (targetStart - startGuardBand); k++)
+ hTonCorr->indexVector[startGuardBand + k] = -1;
+
+ for (k = 0; k < numberOfBands; k++)
+ hTonCorr->indexVector[targetStart + k] = sourceStart + k;
+ }
+
+ return (0);
+}
+
+/**************************************************************************/
+/*!
+ \brief Creates an instance of the tonality correction parameter module.
+
+ The module includes modules for inverse filtering level estimation,
+ missing harmonics detection and noise floor level estimation.
+
+ \return errorCode, noError if successful.
+*/
+/**************************************************************************/
+INT FDKsbrEnc_CreateTonCorrParamExtr(
+ HANDLE_SBR_TON_CORR_EST
+ hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
+ INT chan) /*!< Channel index, needed for mem allocation */
+{
+ INT i;
+ FIXP_DBL *quotaMatrix = GetRam_Sbr_quotaMatrix(chan);
+ INT *signMatrix = GetRam_Sbr_signMatrix(chan);
+
+ if ((NULL == quotaMatrix) || (NULL == signMatrix)) {
+ goto bail;
+ }
+
+ FDKmemclear(hTonCorr, sizeof(SBR_TON_CORR_EST));
+
+ for (i = 0; i < MAX_NO_OF_ESTIMATES; i++) {
+ hTonCorr->quotaMatrix[i] = quotaMatrix + (i * 64);
+ hTonCorr->signMatrix[i] = signMatrix + (i * 64);
+ }
+
+ if (0 != FDKsbrEnc_CreateSbrMissingHarmonicsDetector(
+ &hTonCorr->sbrMissingHarmonicsDetector, chan)) {
+ goto bail;
+ }
+
+ return 0;
+
+bail:
+ hTonCorr->quotaMatrix[0] = quotaMatrix;
+ hTonCorr->signMatrix[0] = signMatrix;
+
+ FDKsbrEnc_DeleteTonCorrParamExtr(hTonCorr);
+
+ return -1;
+}
+
+/**************************************************************************/
+/*!
+ \brief Initialize an instance of the tonality correction parameter module.
+
+ The module includes modules for inverse filtering level estimation,
+ missing harmonics detection and noise floor level estimation.
+
+ \return errorCode, noError if successful.
+*/
+/**************************************************************************/
+INT FDKsbrEnc_InitTonCorrParamExtr(
+ INT frameSize, /*!< Current SBR frame size. */
+ HANDLE_SBR_TON_CORR_EST
+ hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
+ HANDLE_SBR_CONFIG_DATA
+ sbrCfg, /*!< Pointer to SBR configuration parameters. */
+ INT timeSlots, /*!< Number of time-slots per frame */
+ INT xposCtrl, /*!< Different patch modes. */
+ INT ana_max_level, /*!< Maximum level of the adaptive noise. */
+ INT noiseBands, /*!< Number of noise bands per octave. */
+ INT noiseFloorOffset, /*!< Noise floor offset. */
+ UINT useSpeechConfig) /*!< Speech or music tuning. */
+{
+ INT nCols = sbrCfg->noQmfSlots;
+ INT fs = sbrCfg->sampleFreq;
+ INT noQmfChannels = sbrCfg->noQmfBands;
+
+ INT highBandStartSb = sbrCfg->freqBandTable[LOW_RES][0];
+ UCHAR *v_k_master = sbrCfg->v_k_master;
+ INT numMaster = sbrCfg->num_Master;
+
+ UCHAR **freqBandTable = sbrCfg->freqBandTable;
+ INT *nSfb = sbrCfg->nSfb;
+
+ INT i;
+
+ /*
+ Reset the patching and allocate memory for the quota matrix.
+ Assuming parameters for the LPC analysis.
+ */
+ if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
+ switch (timeSlots) {
+ case NUMBER_TIME_SLOTS_1920:
+ hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
+ hTonCorr->lpcLength[1] = 7 - LPC_ORDER;
+ hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
+ hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 7 */
+ hTonCorr->frameStartIndexInvfEst = 0;
+ hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
+ break;
+ case NUMBER_TIME_SLOTS_2048:
+ hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
+ hTonCorr->lpcLength[1] = 8 - LPC_ORDER;
+ hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
+ hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 8 */
+ hTonCorr->frameStartIndexInvfEst = 0;
+ hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
+ break;
+ }
+ } else
+ switch (timeSlots) {
+ case NUMBER_TIME_SLOTS_2048:
+ hTonCorr->lpcLength[0] = 16 - LPC_ORDER; /* blockLength[0] */
+ hTonCorr->lpcLength[1] = 16 - LPC_ORDER; /* blockLength[0] */
+ hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC;
+ hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 16;
+ hTonCorr->frameStartIndexInvfEst = 0;
+ hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_2048;
+ break;
+ case NUMBER_TIME_SLOTS_1920:
+ hTonCorr->lpcLength[0] = 15 - LPC_ORDER; /* blockLength[0] */
+ hTonCorr->lpcLength[1] = 15 - LPC_ORDER; /* blockLength[0] */
+ hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC;
+ hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 15;
+ hTonCorr->frameStartIndexInvfEst = 0;
+ hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_1920;
+ break;
+ default:
+ return -1;
+ }
+
+ hTonCorr->bufferLength = nCols;
+ hTonCorr->stepSize =
+ hTonCorr->lpcLength[0] + LPC_ORDER; /* stepSize[0] implicitly 0. */
+
+ hTonCorr->nextSample = LPC_ORDER; /* firstSample */
+ hTonCorr->move = hTonCorr->numberOfEstimates -
+ hTonCorr->numberOfEstimatesPerFrame; /* Number of estimates
+ to move when
+ buffering.*/
+ if (hTonCorr->move < 0) {
+ return -1;
+ }
+ hTonCorr->startIndexMatrix =
+ hTonCorr->numberOfEstimates -
+ hTonCorr->numberOfEstimatesPerFrame; /* Where to store the latest
+ estimations in the tonality
+ Matrix.*/
+ hTonCorr->frameStartIndex = 0; /* Where in the tonality matrix the current
+ frame (to be sent to the decoder) starts. */
+ hTonCorr->prevTransientFlag = 0;
+ hTonCorr->transientNextFrame = 0;
+
+ hTonCorr->noQmfChannels = noQmfChannels;
+
+ for (i = 0; i < hTonCorr->numberOfEstimates; i++) {
+ FDKmemclear(hTonCorr->quotaMatrix[i], sizeof(FIXP_DBL) * noQmfChannels);
+ FDKmemclear(hTonCorr->signMatrix[i], sizeof(INT) * noQmfChannels);
+ }
+
+ /* Reset the patch.*/
+ hTonCorr->guard = 0;
+ hTonCorr->shiftStartSb = 1;
+
+ if (resetPatch(hTonCorr, xposCtrl, highBandStartSb, v_k_master, numMaster, fs,
+ noQmfChannels))
+ return (1);
+
+ if (FDKsbrEnc_InitSbrNoiseFloorEstimate(
+ &hTonCorr->sbrNoiseFloorEstimate, ana_max_level, freqBandTable[LO],
+ nSfb[LO], noiseBands, noiseFloorOffset, timeSlots, useSpeechConfig))
+ return (1);
+
+ if (FDKsbrEnc_initInvFiltDetector(
+ &hTonCorr->sbrInvFilt,
+ hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
+ hTonCorr->sbrNoiseFloorEstimate.noNoiseBands, useSpeechConfig))
+ return (1);
+
+ if (FDKsbrEnc_InitSbrMissingHarmonicsDetector(
+ &hTonCorr->sbrMissingHarmonicsDetector, fs, frameSize, nSfb[HI],
+ noQmfChannels, hTonCorr->numberOfEstimates, hTonCorr->move,
+ hTonCorr->numberOfEstimatesPerFrame, sbrCfg->sbrSyntaxFlags))
+ return (1);
+
+ return (0);
+}
+
+/**************************************************************************/
+/*!
+ \brief resets tonality correction parameter module.
+
+
+
+ \return errorCode, noError if successful.
+
+*/
+/**************************************************************************/
+INT FDKsbrEnc_ResetTonCorrParamExtr(
+ HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
+ INT xposctrl, /*!< Different patch modes. */
+ INT highBandStartSb, /*!< Start band of the SBR range. */
+ UCHAR *v_k_master, /*!< Master frequency table from which all other table
+ are derived.*/
+ INT numMaster, /*!< Number of elements in the master table. */
+ INT fs, /*!< Sampling frequency (of the SBR part). */
+ UCHAR *
+ *freqBandTable, /*!< Frequency band table for low-res and high-res. */
+ INT *nSfb, /*!< Number of frequency bands (hig-res and low-res). */
+ INT noQmfChannels /*!< Number of QMF channels. */
+) {
+ /* Reset the patch.*/
+ hTonCorr->guard = 0;
+ hTonCorr->shiftStartSb = 1;
+
+ if (resetPatch(hTonCorr, xposctrl, highBandStartSb, v_k_master, numMaster, fs,
+ noQmfChannels))
+ return (1);
+
+ /* Reset the noise floor estimate.*/
+ if (FDKsbrEnc_resetSbrNoiseFloorEstimate(&hTonCorr->sbrNoiseFloorEstimate,
+ freqBandTable[LO], nSfb[LO]))
+ return (1);
+
+ /*
+ Reset the inveerse filtereing detector.
+ */
+ if (FDKsbrEnc_resetInvFiltDetector(
+ &hTonCorr->sbrInvFilt,
+ hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf,
+ hTonCorr->sbrNoiseFloorEstimate.noNoiseBands))
+ return (1);
+ /* Reset the missing harmonics detector. */
+ if (FDKsbrEnc_ResetSbrMissingHarmonicsDetector(
+ &hTonCorr->sbrMissingHarmonicsDetector, nSfb[HI]))
+ return (1);
+
+ return (0);
+}
+
+/**************************************************************************/
+/*!
+ \brief Deletes the tonality correction paramtere module.
+
+
+
+ \return none
+
+*/
+/**************************************************************************/
+void FDKsbrEnc_DeleteTonCorrParamExtr(
+ HANDLE_SBR_TON_CORR_EST hTonCorr) /*!< Handle to SBR_TON_CORR struct. */
+{
+ if (hTonCorr) {
+ FreeRam_Sbr_quotaMatrix(hTonCorr->quotaMatrix);
+
+ FreeRam_Sbr_signMatrix(hTonCorr->signMatrix);
+
+ FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(
+ &hTonCorr->sbrMissingHarmonicsDetector);
+ }
+}
diff --git a/fdk-aac/libSBRenc/src/ton_corr.h b/fdk-aac/libSBRenc/src/ton_corr.h
new file mode 100644
index 0000000..91aa278
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/ton_corr.h
@@ -0,0 +1,258 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief General tonality correction detector module.
+*/
+#ifndef TON_CORR_H
+#define TON_CORR_H
+
+#include "sbr_encoder.h"
+#include "mh_det.h"
+#include "nf_est.h"
+#include "invf_est.h"
+
+#define MAX_NUM_PATCHES 6
+#define SCALE_NRGVEC 4
+
+/** parameter set for one single patch */
+typedef struct {
+ INT sourceStartBand; /*!< first band in lowbands where to take the samples
+ from */
+ INT sourceStopBand; /*!< first band in lowbands which is not included in the
+ patch anymore */
+ INT guardStartBand; /*!< first band in highbands to be filled with zeros in
+ order to reduce interferences between patches */
+ INT targetStartBand; /*!< first band in highbands to be filled with whitened
+ lowband signal */
+ INT targetBandOffs; /*!< difference between 'startTargetBand' and
+ 'startSourceBand' */
+ INT numBandsInPatch; /*!< number of consecutive bands in this one patch */
+} PATCH_PARAM;
+
+typedef struct {
+ INT switchInverseFilt; /*!< Flag to enable dynamic adaption of invf. detection
+ */
+ INT noQmfChannels;
+ INT bufferLength; /*!< Length of the r and i buffers. */
+ INT stepSize; /*!< Stride for the lpc estimate. */
+ INT numberOfEstimates; /*!< The total number of estiamtes, 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 nextSample; /*!< Where to start the LPC analysis of the current frame.*/
+ INT move; /*!< How many estimates to move in the quotaMatrix, when buffering.
+ */
+ INT frameStartIndex; /*!< The start index for the current frame in the r and i
+ buffers. */
+ INT startIndexMatrix; /*!< The start index for the current frame in the
+ quotaMatrix. */
+ INT frameStartIndexInvfEst; /*!< The start index of the inverse filtering, not
+ the same as the others, dependent on what
+ decoder is used (buffer opt, or no buffer opt).
+ */
+ INT prevTransientFlag; /*!< The transisent flag (from the transient detector)
+ for the previous frame. */
+ INT transientNextFrame; /*!< Flag to indicate that the transient will show up
+ in the next frame. */
+ INT transientPosOffset; /*!< An offset value to match the transient pos as
+ calculated by the transient detector with the
+ actual position in the frame.*/
+
+ INT* signMatrix[MAX_NO_OF_ESTIMATES]; /*!< Matrix holding the sign of each
+ channe, i.e. indicating in what part
+ of a QMF channel a possible sine is.
+ */
+
+ FIXP_DBL* quotaMatrix[MAX_NO_OF_ESTIMATES]; /*!< Matrix holding the quota
+ values for all estimates, all
+ channels. */
+
+ FIXP_DBL nrgVector[MAX_NO_OF_ESTIMATES]; /*!< Vector holding the averaged
+ energies for every QMF band. */
+ FIXP_DBL nrgVectorFreq[64]; /*!< Vector holding the averaged energies for
+ every QMF channel */
+
+ SCHAR indexVector[64]; /*!< Index vector poINTing to the correct lowband
+ channel, when indexing a highband channel, -1
+ represents a guard band */
+ PATCH_PARAM
+ patchParam[MAX_NUM_PATCHES]; /*!< new parameter set for patching */
+ INT guard; /*!< number of guardbands between every patch */
+ INT shiftStartSb; /*!< lowest subband of source range to be included in the
+ patches */
+ INT noOfPatches; /*!< number of patches */
+
+ SBR_MISSING_HARMONICS_DETECTOR
+ sbrMissingHarmonicsDetector; /*!< SBR_MISSING_HARMONICS_DETECTOR struct.
+ */
+ SBR_NOISE_FLOOR_ESTIMATE
+ sbrNoiseFloorEstimate; /*!< SBR_NOISE_FLOOR_ESTIMATE struct. */
+ SBR_INV_FILT_EST sbrInvFilt; /*!< SBR_INV_FILT_EST struct. */
+} SBR_TON_CORR_EST;
+
+typedef SBR_TON_CORR_EST* HANDLE_SBR_TON_CORR_EST;
+
+void FDKsbrEnc_TonCorrParamExtr(
+ HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
+ INVF_MODE* infVec, /*!< Vector where the inverse filtering levels will be
+ stored. */
+ FIXP_DBL* noiseLevels, /*!< Vector where the noise levels will be stored. */
+ INT* missingHarmonicFlag, /*!< Flag set to one or zero, dependent on if any
+ strong sines are missing.*/
+ UCHAR* missingHarmonicsIndex, /*!< Vector indicating where sines are
+ missing. */
+ UCHAR* envelopeCompensation, /*!< Vector to store compensation values for
+ the energies in. */
+ const SBR_FRAME_INFO* frameInfo, /*!< Frame info struct, contains the time
+ and frequency grid of the current
+ frame.*/
+ UCHAR* transientInfo, /*!< Transient info.*/
+ UCHAR* freqBandTable, /*!< Frequency band tables for high-res.*/
+ INT nSfb, /*!< Number of scalefactor bands for high-res. */
+ XPOS_MODE xposType, /*!< Type of transposer used in the decoder.*/
+ UINT sbrSyntaxFlags);
+
+INT FDKsbrEnc_CreateTonCorrParamExtr(
+ HANDLE_SBR_TON_CORR_EST
+ hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
+ INT chan); /*!< Channel index, needed for mem allocation */
+
+INT FDKsbrEnc_InitTonCorrParamExtr(
+ INT frameSize, /*!< Current SBR frame size. */
+ HANDLE_SBR_TON_CORR_EST
+ hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */
+ HANDLE_SBR_CONFIG_DATA
+ sbrCfg, /*!< Pointer to SBR configuration parameters. */
+ INT timeSlots, /*!< Number of time-slots per frame */
+ INT xposCtrl, /*!< Different patch modes. */
+ INT ana_max_level, /*!< Maximum level of the adaptive noise. */
+ INT noiseBands, /*!< Number of noise bands per octave. */
+ INT noiseFloorOffset, /*!< Noise floor offset. */
+ UINT useSpeechConfig /*!< Speech or music tuning. */
+);
+
+void FDKsbrEnc_DeleteTonCorrParamExtr(
+ HANDLE_SBR_TON_CORR_EST hTonCorr); /*!< Handle to SBR_TON_CORR struct. */
+
+void FDKsbrEnc_CalculateTonalityQuotas(
+ HANDLE_SBR_TON_CORR_EST hTonCorr, FIXP_DBL** sourceBufferReal,
+ FIXP_DBL** sourceBufferImag, INT usb,
+ INT qmfScale /*!< sclefactor of QMF subsamples */
+);
+
+INT FDKsbrEnc_ResetTonCorrParamExtr(
+ HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */
+ INT xposctrl, /*!< Different patch modes. */
+ INT highBandStartSb, /*!< Start band of the SBR range. */
+ UCHAR* v_k_master, /*!< Master frequency table from which all other table
+ are derived.*/
+ INT numMaster, /*!< Number of elements in the master table. */
+ INT fs, /*!< Sampling frequency (of the SBR part). */
+ UCHAR**
+ freqBandTable, /*!< Frequency band table for low-res and high-res. */
+ INT* nSfb, /*!< Number of frequency bands (hig-res and low-res). */
+ INT noQmfChannels /*!< Number of QMF channels. */
+);
+#endif
diff --git a/fdk-aac/libSBRenc/src/tran_det.cpp b/fdk-aac/libSBRenc/src/tran_det.cpp
new file mode 100644
index 0000000..3b6765a
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/tran_det.cpp
@@ -0,0 +1,1092 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s): Tobias Chalupka
+
+ Description: SBR encoder transient detector
+
+*******************************************************************************/
+
+#include "tran_det.h"
+
+#include "fram_gen.h"
+#include "sbrenc_ram.h"
+#include "sbr_misc.h"
+
+#include "genericStds.h"
+
+#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 */
+#define ABS_THRES ((FIXP_DBL)16)
+
+/*******************************************************************************
+ Functionname: spectralChange
+ *******************************************************************************
+ \brief Calculates a measure for the spectral change within the frame
+
+ The function says how good it would be to split the frame at the given border
+ position into 2 envelopes.
+
+ The return value delta_sum is scaled with the factor 1/64
+
+ \return calculated value
+*******************************************************************************/
+#define NRG_SHIFT 3 /* for energy summation */
+
+static FIXP_DBL spectralChange(
+ FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS],
+ INT *scaleEnergies, FIXP_DBL EnergyTotal, INT nSfb, INT start, INT border,
+ INT YBufferWriteOffset, INT stop, INT *result_e) {
+ INT i, j;
+ INT len1, len2;
+ SCHAR energies_e_diff[NUMBER_TIME_SLOTS_2304], energies_e, energyTotal_e = 19,
+ energies_e_add;
+ SCHAR prevEnergies_e_diff, newEnergies_e_diff;
+ FIXP_DBL tmp0, tmp1;
+ FIXP_DBL delta, delta_sum;
+ INT accu_e, tmp_e;
+
+ delta_sum = FL2FXCONST_DBL(0.0f);
+ *result_e = 0;
+
+ len1 = border - start;
+ len2 = stop - border;
+
+ /* prefer borders near the middle of the frame */
+ FIXP_DBL pos_weight;
+ 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);
+
+ /*** Calc scaling for energies ***/
+ FDK_ASSERT(scaleEnergies[0] >= 0);
+ FDK_ASSERT(scaleEnergies[1] >= 0);
+
+ energies_e = 19 - fMin(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] -
+ fMin(scaleEnergies[0], scaleEnergies[1]) +
+ energies_e_add + NRG_SHIFT;
+ newEnergies_e_diff = scaleEnergies[1] -
+ fMin(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 */
+ FDK_ASSERT(len1 <= 8); /* otherwise an overflow is possible */
+ FDK_ASSERT(len2 <= 8); /* otherwise an overflow is possible */
+
+ for (j = 0; j < nSfb; j++) {
+ FIXP_DBL accu1 = FL2FXCONST_DBL(0.f);
+ FIXP_DBL accu2 = FL2FXCONST_DBL(0.f);
+ accu_e = energies_e + 3;
+
+ /* Sum up energies in first half */
+ for (i = start; i < border; i++) {
+ accu1 += scaleValue(Energies[i][j], -energies_e_diff[i]);
+ }
+
+ /* Sum up energies in second half */
+ for (i = border; i < stop; i++) {
+ accu2 += scaleValue(Energies[i][j], -energies_e_diff[i]);
+ }
+
+ /* Ensure certain energy to prevent division by zero and to prevent
+ * splitting for very low levels */
+ accu1 = fMax(accu1, (FIXP_DBL)len1);
+ accu2 = fMax(accu2, (FIXP_DBL)len2);
+
+/* Energy change in current band */
+#define LN2 FL2FXCONST_DBL(0.6931471806f) /* ln(2) */
+ tmp0 = fLog2(accu2, accu_e) - fLog2(accu1, accu_e);
+ tmp1 = fLog2((FIXP_DBL)len1, 31) - fLog2((FIXP_DBL)len2, 31);
+ delta = fMult(LN2, (tmp0 + tmp1));
+ delta = (FIXP_DBL)fAbs(delta);
+
+ /* Weighting with amplitude ratio of this band */
+ accu_e++; /* scale at least one bit due to (accu1+accu2) */
+ accu1 >>= 1;
+ accu2 >>= 1;
+
+ if (accu_e & 1) {
+ accu_e++; /* for a defined square result exponent, the exponent has to be
+ even */
+ accu1 >>= 1;
+ accu2 >>= 1;
+ }
+
+ delta_sum += fMult(sqrtFixp(accu1 + accu2), delta);
+ *result_e = ((accu_e >> 1) + LD_DATA_SHIFT);
+ }
+
+ if (energyTotal_e & 1) {
+ 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);
+}
+
+/*******************************************************************************
+ Functionname: addLowbandEnergies
+ *******************************************************************************
+ \brief Calculates total lowband energy
+
+ 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, scaled by the factor 2^19
+*******************************************************************************/
+static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies, int *scaleEnergies,
+ int YBufferWriteOffset, int nrgSzShift,
+ int tran_off, UCHAR *freqBandTable,
+ int slots) {
+ INT nrgTotal_e;
+ FIXP_DBL nrgTotal_m;
+ FIXP_DBL accu1 = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL accu2 = FL2FXCONST_DBL(0.0f);
+ int tran_offdiv2 = tran_off >> nrgSzShift;
+ const int sc1 =
+ DFRACT_BITS -
+ fNormz((FIXP_DBL)fMax(
+ 1, (freqBandTable[0] * (YBufferWriteOffset - tran_offdiv2) - 1)));
+ const int sc2 =
+ DFRACT_BITS -
+ fNormz((FIXP_DBL)fMax(
+ 1, (freqBandTable[0] *
+ (tran_offdiv2 + (slots >> nrgSzShift) - YBufferWriteOffset) -
+ 1)));
+ int ts, k;
+
+ /* 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 (k = 0; k < freqBandTable[0]; k++) {
+ accu1 += Energies[ts][k] >> sc1;
+ }
+ }
+ for (; ts < tran_offdiv2 + (slots >> nrgSzShift); ts++) {
+ for (k = 0; k < freqBandTable[0]; k++) {
+ accu2 += Energies[ts][k] >> sc2;
+ }
+ }
+
+ nrgTotal_m = fAddNorm(accu1, (sc1 - 5) - scaleEnergies[0], accu2,
+ (sc2 - 5) - scaleEnergies[1], &nrgTotal_e);
+ nrgTotal_m = scaleValueSaturate(nrgTotal_m, nrgTotal_e);
+
+ return (nrgTotal_m);
+}
+
+/*******************************************************************************
+ Functionname: addHighbandEnergies
+ *******************************************************************************
+ \brief Add highband energies
+
+ Highband energies are mapped to an array with smaller dimension:
+ Its time resolution is only 1 SBR-timeslot and its frequency resolution
+ is 1 SBR-band. Therefore the data to be fed into the spectralChange
+ function is reduced.
+
+ The values EnergiesM are scaled by the factor (2^19-scaleEnergies[0]) for
+ slots<YBufferWriteOffset and by the factor (2^19-scaleEnergies[1]) for
+ slots>=YBufferWriteOffset.
+
+ \return total energy in the highband, scaled by factor 2^19
+*******************************************************************************/
+
+static FIXP_DBL addHighbandEnergies(
+ FIXP_DBL **RESTRICT Energies, /*!< input */
+ INT *scaleEnergies, INT YBufferWriteOffset,
+ FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304]
+ [MAX_FREQ_COEFFS], /*!< Combined output */
+ UCHAR *RESTRICT freqBandTable, INT nSfb, INT sbrSlots, INT timeStep) {
+ INT i, j, k, slotIn, slotOut, scale[2];
+ INT li, ui;
+ FIXP_DBL nrgTotal;
+ FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
+
+ /* Combine QMF-timeslots to SBR-timeslots,
+ combine QMF-bands to SBR-bands,
+ combine Left and Right channel */
+ for (slotOut = 0; slotOut < sbrSlots; slotOut++) {
+ /* Note: Below slotIn = slotOut and not slotIn = timeStep*slotOut
+ because the Energies[] time resolution is always the SBR slot resolution
+ regardless of the timeStep. */
+ slotIn = slotOut;
+
+ for (j = 0; j < nSfb; j++) {
+ accu = FL2FXCONST_DBL(0.0f);
+
+ li = freqBandTable[j];
+ ui = freqBandTable[j + 1];
+
+ for (k = li; k < ui; k++) {
+ for (i = 0; i < timeStep; i++) {
+ accu += Energies[slotIn][k] >> 5;
+ }
+ }
+ EnergiesM[slotOut][j] = accu;
+ }
+ }
+
+ /* scale energies down before add up */
+ scale[0] = fixMin(8, scaleEnergies[0]);
+ scale[1] = fixMin(8, scaleEnergies[1]);
+
+ if ((scaleEnergies[0] - scale[0]) > (DFRACT_BITS - 1) ||
+ (scaleEnergies[1] - scale[1]) > (DFRACT_BITS - 1))
+ nrgTotal = FL2FXCONST_DBL(0.0f);
+ else {
+ /* Now add all energies */
+ accu = FL2FXCONST_DBL(0.0f);
+
+ for (slotOut = 0; slotOut < YBufferWriteOffset; slotOut++) {
+ for (j = 0; j < nSfb; j++) {
+ accu += (EnergiesM[slotOut][j] >> scale[0]);
+ }
+ }
+ 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 = fAddSaturate(nrgTotal, accu >> (scaleEnergies[1] - scale[1]));
+ }
+
+ return (nrgTotal);
+}
+
+/*******************************************************************************
+ Functionname: FDKsbrEnc_frameSplitter
+ *******************************************************************************
+ \brief Decides if a FIXFIX-frame shall be splitted into 2 envelopes
+
+ If no transient has been detected before, the frame can still be splitted
+ into 2 envelopes.
+*******************************************************************************/
+void FDKsbrEnc_frameSplitter(
+ FIXP_DBL **Energies, INT *scaleEnergies,
+ HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, UCHAR *freqBandTable,
+ UCHAR *tran_vector, int YBufferWriteOffset, int YBufferSzShift, int nSfb,
+ int timeStep, int no_cols, FIXP_DBL *tonality) {
+ if (tran_vector[1] == 0) /* no transient was detected */
+ {
+ FIXP_DBL delta;
+ INT delta_e;
+ FIXP_DBL(*EnergiesM)[MAX_FREQ_COEFFS];
+ FIXP_DBL EnergyTotal, newLowbandEnergy, newHighbandEnergy;
+ INT border;
+ 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);
+
+ EnergiesM = (FIXP_DBL(*)[MAX_FREQ_COEFFS])_EnergiesM;
+
+ /*
+ Get Lowband-energy over a range of 2 frames (Look half a frame back and
+ ahead).
+ */
+ newLowbandEnergy = addLowbandEnergies(
+ Energies, scaleEnergies, YBufferWriteOffset, YBufferSzShift,
+ h_sbrTransientDetector->tran_off, freqBandTable, no_cols);
+
+ newHighbandEnergy =
+ addHighbandEnergies(Energies, scaleEnergies, YBufferWriteOffset,
+ EnergiesM, freqBandTable, nSfb, sbrSlots, timeStep);
+
+ {
+ /* 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 */
+ EnergyTotal = (newLowbandEnergy >> 1) +
+ (h_sbrTransientDetector->prevLowBandEnergy >>
+ 1); /* mean of new and prev LB NRG */
+ EnergyTotal =
+ fAddSaturate(EnergyTotal, newHighbandEnergy); /* Add HB NRG */
+ /* The below border should specify the same position as the middle border
+ of a FIXFIX-frame with 2 envelopes. */
+ border = (sbrSlots + 1) >> 1;
+
+ if ((INT)EnergyTotal & 0xffffffe0 &&
+ (scaleEnergies[0] < 32 || scaleEnergies[1] < 32)) /* i.e. > 31 */ {
+ delta = spectralChange(EnergiesM, scaleEnergies, EnergyTotal, nSfb, 0,
+ border, YBufferWriteOffset, sbrSlots, &delta_e);
+ } else {
+ delta = FL2FXCONST_DBL(0.0f);
+ delta_e = 0;
+
+ /* 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 */
+ } else {
+ tran_vector[0] = 0;
+ }
+ }
+
+ /* Update prevLowBandEnergy */
+ h_sbrTransientDetector->prevLowBandEnergy = newLowbandEnergy;
+ h_sbrTransientDetector->prevHighBandEnergy = newHighbandEnergy;
+ C_ALLOC_SCRATCH_END(_EnergiesM, FIXP_DBL,
+ NUMBER_TIME_SLOTS_2304 * MAX_FREQ_COEFFS)
+ }
+}
+
+/*
+ * Calculate transient energy threshold for each QMF band
+ */
+static void calculateThresholds(FIXP_DBL **RESTRICT Energies,
+ INT *RESTRICT scaleEnergies,
+ FIXP_DBL *RESTRICT thresholds,
+ int YBufferWriteOffset, int YBufferSzShift,
+ int noCols, int noRows, int tran_off) {
+ FIXP_DBL mean_val, std_val, temp;
+ FIXP_DBL i_noCols;
+ FIXP_DBL i_noCols1;
+ FIXP_DBL accu, accu0, accu1;
+ int scaleFactor0, scaleFactor1, commonScale;
+ int i, j;
+
+ i_noCols = GetInvInt(noCols + tran_off) << YBufferSzShift;
+ i_noCols1 = GetInvInt(noCols + tran_off - 1) << YBufferSzShift;
+
+ /* calc minimum scale of energies of previous and current frame */
+ commonScale = fixMin(scaleEnergies[0], scaleEnergies[1]);
+
+ /* calc scalefactors to adapt energies to common scale */
+ scaleFactor0 = fixMin((scaleEnergies[0] - commonScale), (DFRACT_BITS - 1));
+ scaleFactor1 = fixMin((scaleEnergies[1] - commonScale), (DFRACT_BITS - 1));
+
+ FDK_ASSERT((scaleFactor0 >= 0) && (scaleFactor1 >= 0));
+
+ /* calculate standard deviation in every subband */
+ for (i = 0; i < noRows; i++) {
+ int startEnergy = (tran_off >> YBufferSzShift);
+ int endEnergy = ((noCols >> YBufferSzShift) + tran_off);
+ int shift;
+
+ /* calculate mean value over decimated energy values (downsampled by 2). */
+ accu0 = accu1 = FL2FXCONST_DBL(0.0f);
+
+ for (j = startEnergy; j < YBufferWriteOffset; j++)
+ accu0 = fMultAddDiv2(accu0, Energies[j][i], i_noCols);
+ for (; j < endEnergy; j++)
+ accu1 = fMultAddDiv2(accu1, Energies[j][i], i_noCols);
+
+ mean_val = ((accu0 << 1) >> scaleFactor0) +
+ ((accu1 << 1) >> scaleFactor1); /* average */
+ shift = fixMax(
+ 0, CountLeadingBits(mean_val) -
+ 6); /* -6 to keep room for accumulating upto N = 24 values */
+
+ /* calculate standard deviation */
+ accu = FL2FXCONST_DBL(0.0f);
+
+ /* summe { ((mean_val-nrg)^2) * i_noCols1 } */
+ for (j = startEnergy; j < YBufferWriteOffset; j++) {
+ temp = ((FIXP_DBL)mean_val - ((FIXP_DBL)Energies[j][i] >> scaleFactor0))
+ << shift;
+ temp = fPow2Div2(temp);
+ accu = fMultAddDiv2(accu, temp, i_noCols1);
+ }
+ for (; j < endEnergy; j++) {
+ temp = ((FIXP_DBL)mean_val - ((FIXP_DBL)Energies[j][i] >> scaleFactor1))
+ << shift;
+ temp = fPow2Div2(temp);
+ accu = fMultAddDiv2(accu, temp, i_noCols1);
+ }
+ accu <<= 2;
+ std_val = sqrtFixp(accu) >> shift; /* standard deviation */
+
+ /*
+ Take new threshold as average of calculated standard deviation ratio
+ and old threshold if greater than absolute threshold
+ */
+ temp = (commonScale <= (DFRACT_BITS - 1))
+ ? fMult(FL2FXCONST_DBL(0.66f), thresholds[i]) +
+ (fMult(FL2FXCONST_DBL(0.34f), std_val) >> commonScale)
+ : (FIXP_DBL)0;
+
+ thresholds[i] = fixMax(ABS_THRES, temp);
+
+ FDK_ASSERT(commonScale >= 0);
+ }
+}
+
+/*
+ * Calculate transient levels for each QMF time slot.
+ */
+static void extractTransientCandidates(
+ FIXP_DBL **RESTRICT Energies, INT *RESTRICT scaleEnergies,
+ FIXP_DBL *RESTRICT thresholds, FIXP_DBL *RESTRICT transients,
+ int YBufferWriteOffset, int YBufferSzShift, int noCols, int start_band,
+ int stop_band, int tran_off, int addPrevSamples) {
+ FIXP_DBL i_thres;
+ C_ALLOC_SCRATCH_START(EnergiesTemp, FIXP_DBL, 2 * 32)
+ int tmpScaleEnergies0, tmpScaleEnergies1;
+ int endCond;
+ int startEnerg, endEnerg;
+ int i, j, jIndex, jpBM;
+
+ tmpScaleEnergies0 = scaleEnergies[0];
+ tmpScaleEnergies1 = scaleEnergies[1];
+
+ /* Scale value for first energies, upto YBufferWriteOffset */
+ tmpScaleEnergies0 = fixMin(tmpScaleEnergies0, MAX_SHIFT_DBL);
+ /* Scale value for first energies, from YBufferWriteOffset upwards */
+ tmpScaleEnergies1 = fixMin(tmpScaleEnergies1, MAX_SHIFT_DBL);
+
+ FDK_ASSERT((tmpScaleEnergies0 >= 0) && (tmpScaleEnergies1 >= 0));
+
+ /* Keep addPrevSamples extra previous transient candidates. */
+ FDKmemmove(transients, transients + noCols - addPrevSamples,
+ (tran_off + addPrevSamples) * sizeof(FIXP_DBL));
+ FDKmemclear(transients + tran_off + addPrevSamples,
+ noCols * sizeof(FIXP_DBL));
+
+ endCond = noCols; /* Amount of new transient values to be calculated. */
+ startEnerg = (tran_off - 3) >> YBufferSzShift; /* >>YBufferSzShift because of
+ amount of energy values. -3
+ because of neighbors being
+ watched. */
+ endEnerg =
+ ((noCols + (YBufferWriteOffset << YBufferSzShift)) - 1) >>
+ YBufferSzShift; /* YBufferSzShift shifts because of half energy values. */
+
+ /* Compute differential values with two different weightings in every subband
+ */
+ for (i = start_band; i < stop_band; i++) {
+ FIXP_DBL thres = thresholds[i];
+
+ if ((LONG)thresholds[i] >= 256)
+ i_thres = (LONG)((LONG)MAXVAL_DBL / ((((LONG)thresholds[i])) + 1))
+ << (32 - 24);
+ else
+ i_thres = (LONG)MAXVAL_DBL;
+
+ /* Copy one timeslot and de-scale and de-squish */
+ if (YBufferSzShift == 1) {
+ for (j = startEnerg; j < YBufferWriteOffset; j++) {
+ FIXP_DBL tmp = Energies[j][i];
+ EnergiesTemp[(j << 1) + 1] = EnergiesTemp[j << 1] =
+ tmp >> tmpScaleEnergies0;
+ }
+ for (; j <= endEnerg; j++) {
+ FIXP_DBL tmp = Energies[j][i];
+ EnergiesTemp[(j << 1) + 1] = EnergiesTemp[j << 1] =
+ tmp >> tmpScaleEnergies1;
+ }
+ } else {
+ for (j = startEnerg; j < YBufferWriteOffset; j++) {
+ FIXP_DBL tmp = Energies[j][i];
+ EnergiesTemp[j] = tmp >> tmpScaleEnergies0;
+ }
+ for (; j <= endEnerg; j++) {
+ FIXP_DBL tmp = Energies[j][i];
+ EnergiesTemp[j] = tmp >> tmpScaleEnergies1;
+ }
+ }
+
+ /* Detect peaks in energy values. */
+
+ jIndex = tran_off;
+ jpBM = jIndex + addPrevSamples;
+
+ for (j = endCond; j--; jIndex++, jpBM++) {
+ FIXP_DBL delta, tran;
+ int d;
+
+ delta = (FIXP_DBL)0;
+ tran = (FIXP_DBL)0;
+
+ for (d = 1; d < 4; d++) {
+ delta += EnergiesTemp[jIndex + d]; /* R */
+ delta -= EnergiesTemp[jIndex - d]; /* L */
+ delta -= thres;
+
+ if (delta > (FIXP_DBL)0) {
+ tran = fMultAddDiv2(tran, i_thres, delta);
+ }
+ }
+ transients[jpBM] += (tran << 1);
+ }
+ }
+ C_ALLOC_SCRATCH_END(EnergiesTemp, FIXP_DBL, 2 * 32)
+}
+
+void FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTran,
+ FIXP_DBL **Energies, INT *scaleEnergies,
+ UCHAR *transient_info, int YBufferWriteOffset,
+ int YBufferSzShift, int timeStep,
+ int frameMiddleBorder) {
+ int no_cols = h_sbrTran->no_cols;
+ int qmfStartSample;
+ int addPrevSamples;
+ int timeStepShift = 0;
+ int i, cond;
+
+ /* Where to start looking for transients in the transient candidate buffer */
+ qmfStartSample = timeStep * frameMiddleBorder;
+ /* We need to look one value backwards in the transients, so we might need one
+ * more previous value. */
+ addPrevSamples = (qmfStartSample > 0) ? 0 : 1;
+
+ switch (timeStep) {
+ case 1:
+ timeStepShift = 0;
+ break;
+ case 2:
+ timeStepShift = 1;
+ break;
+ case 4:
+ timeStepShift = 2;
+ break;
+ }
+
+ calculateThresholds(Energies, scaleEnergies, h_sbrTran->thresholds,
+ YBufferWriteOffset, YBufferSzShift, h_sbrTran->no_cols,
+ h_sbrTran->no_rows, h_sbrTran->tran_off);
+
+ extractTransientCandidates(
+ Energies, scaleEnergies, h_sbrTran->thresholds, h_sbrTran->transients,
+ YBufferWriteOffset, YBufferSzShift, h_sbrTran->no_cols, 0,
+ h_sbrTran->no_rows, h_sbrTran->tran_off, addPrevSamples);
+
+ transient_info[0] = 0;
+ transient_info[1] = 0;
+ transient_info[2] = 0;
+
+ /* Offset by the amount of additional previous transient candidates being
+ * kept. */
+ qmfStartSample += addPrevSamples;
+
+ /* Check for transients in second granule (pick the last value of subsequent
+ * values) */
+ for (i = qmfStartSample; i < qmfStartSample + no_cols; i++) {
+ cond = (h_sbrTran->transients[i] <
+ fMult(FL2FXCONST_DBL(0.9f), h_sbrTran->transients[i - 1])) &&
+ (h_sbrTran->transients[i - 1] > h_sbrTran->tran_thr);
+
+ if (cond) {
+ transient_info[0] = (i - qmfStartSample) >> timeStepShift;
+ transient_info[1] = 1;
+ break;
+ }
+ }
+
+ if (h_sbrTran->frameShift != 0) {
+ /* transient prediction for LDSBR */
+ /* Check for transients in first <frameShift> qmf-slots of second frame */
+ for (i = qmfStartSample + no_cols;
+ i < qmfStartSample + no_cols + h_sbrTran->frameShift; i++) {
+ cond = (h_sbrTran->transients[i] <
+ fMult(FL2FXCONST_DBL(0.9f), h_sbrTran->transients[i - 1])) &&
+ (h_sbrTran->transients[i - 1] > h_sbrTran->tran_thr);
+
+ if (cond) {
+ int pos = (int)((i - qmfStartSample - no_cols) >> timeStepShift);
+ if ((pos < 3) && (transient_info[1] == 0)) {
+ transient_info[2] = 1;
+ }
+ break;
+ }
+ }
+ }
+}
+
+int FDKsbrEnc_InitSbrTransientDetector(
+ HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
+ UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */
+ INT frameSize, INT sampleFreq, sbrConfigurationPtr params, int tran_fc,
+ int no_cols, int no_rows, int YBufferWriteOffset, int YBufferSzShift,
+ int frameShift, int tran_off) {
+ INT totalBitrate =
+ params->codecSettings.standardBitrate * params->codecSettings.nChannels;
+ INT codecBitrate = params->codecSettings.bitRate;
+ FIXP_DBL bitrateFactor_m, framedur_fix;
+ INT bitrateFactor_e, tmp_e;
+
+ FDKmemclear(h_sbrTransientDetector, sizeof(SBR_TRANSIENT_DETECTOR));
+
+ h_sbrTransientDetector->frameShift = frameShift;
+ h_sbrTransientDetector->tran_off = tran_off;
+
+ if (codecBitrate) {
+ bitrateFactor_m = fDivNorm((FIXP_DBL)totalBitrate,
+ (FIXP_DBL)(codecBitrate << 2), &bitrateFactor_e);
+ bitrateFactor_e += 2;
+ } else {
+ bitrateFactor_m = FL2FXCONST_DBL(1.0 / 4.0);
+ bitrateFactor_e = 2;
+ }
+
+ framedur_fix = fDivNorm(frameSize, sampleFreq);
+
+ /* The longer the frames, the more often should the FIXFIX-
+ case transmit 2 envelopes instead of 1.
+ Frame durations below 10 ms produce the highest threshold
+ so that practically always only 1 env is transmitted. */
+ FIXP_DBL tmp = framedur_fix - FL2FXCONST_DBL(0.010);
+
+ tmp = fixMax(tmp, FL2FXCONST_DBL(0.0001));
+ tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &tmp_e);
+
+ bitrateFactor_e = (tmp_e + bitrateFactor_e);
+
+ if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
+ bitrateFactor_e--; /* divide by 2 */
+ }
+
+ FDK_ASSERT(no_cols <= 32);
+ FDK_ASSERT(no_rows <= 64);
+
+ h_sbrTransientDetector->no_cols = no_cols;
+ h_sbrTransientDetector->tran_thr =
+ (FIXP_DBL)((params->tran_thr << (32 - 24 - 1)) / no_rows);
+ h_sbrTransientDetector->tran_fc = tran_fc;
+ h_sbrTransientDetector->split_thr_m = fMult(tmp, bitrateFactor_m);
+ h_sbrTransientDetector->split_thr_e = bitrateFactor_e;
+ h_sbrTransientDetector->no_rows = no_rows;
+ h_sbrTransientDetector->mode = params->tran_det_mode;
+ h_sbrTransientDetector->prevLowBandEnergy = FL2FXCONST_DBL(0.0f);
+
+ 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;
+ 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 /* 64 (=64) multiplications max, max. allowed sum is 0.5 */
+ myExp = fMultNorm(QMF_HP_dBd_SLOPE_FIX, 0, (FIXP_DBL)bandwidth_qmf_slot,
+ DFRACT_BITS - 1, EXP_E);
+ myExpSlot = myExp;
+
+ for (i = 0; i < 64; 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 */
+
+ if (dBf_int <=
+ 46340) { /* compare with maximum allowed value for signed integer
+ multiplication, 46340 =
+ (INT)floor(sqrt((double)(((UINT)1<<(DFRACT_BITS-1))-1))) */
+ 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, DFRACT_BITS - 1, dBf_fract, tmp, dBf_e);
+
+ myExpSlot += myExp;
+ } else {
+ dBf_m = (FIXP_DBL)0;
+ dBf_e = 0;
+ }
+
+ /* 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];
+ }
+}
diff --git a/fdk-aac/libSBRenc/src/tran_det.h b/fdk-aac/libSBRenc/src/tran_det.h
new file mode 100644
index 0000000..d10a7db
--- /dev/null
+++ b/fdk-aac/libSBRenc/src/tran_det.h
@@ -0,0 +1,191 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Transient detector prototypes $Revision: 95111 $
+*/
+#ifndef TRAN_DET_H
+#define TRAN_DET_H
+
+#include "sbr_encoder.h"
+#include "sbr_def.h"
+
+typedef struct {
+ FIXP_DBL transients[32 + (32 / 2)];
+ FIXP_DBL thresholds[64];
+ FIXP_DBL tran_thr; /* Master threshold for transient signals */
+ 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 prevHighBandEnergy; /* Energy of high band */
+ INT tran_fc; /* Number of lowband subbands to discard */
+ INT no_cols;
+ INT no_rows;
+ INT mode;
+
+ int frameShift;
+ int tran_off; /* Offset for reading energy values. */
+} 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(5.0f / 8.0f)
+#define TRAN_DET_THRSHLD_SCALE (3)
+
+typedef struct {
+ INT transientCandidates[32 + TRAN_DET_LOOKAHEAD];
+ INT nTimeSlots;
+ INT lookahead;
+ INT startBand;
+ INT stopBand;
+
+ FIXP_DBL dBf_m[64];
+ INT dBf_e[64];
+
+ FIXP_DBL energy_timeSlots[32 + TRAN_DET_LOOKAHEAD];
+ INT energy_timeSlots_scale[32 + TRAN_DET_LOOKAHEAD];
+
+ FIXP_DBL delta_energy[32 + TRAN_DET_LOOKAHEAD];
+ INT delta_energy_scale[32 + TRAN_DET_LOOKAHEAD];
+
+ FIXP_DBL lowpass_energy[32 + TRAN_DET_LOOKAHEAD];
+ INT lowpass_energy_scale[32 + TRAN_DET_LOOKAHEAD];
+} 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 FDKsbrEnc_transientDetect(
+ HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, FIXP_DBL **Energies,
+ INT *scaleEnergies, UCHAR *tran_vector, int YBufferWriteOffset,
+ int YBufferSzShift, int timeStep, int frameMiddleBorder);
+
+int FDKsbrEnc_InitSbrTransientDetector(
+ HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
+ UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */
+ INT frameSize, INT sampleFreq, sbrConfigurationPtr params, int tran_fc,
+ int no_cols, int no_rows, int YBufferWriteOffset, int YBufferSzShift,
+ int frameShift, int tran_off);
+
+void FDKsbrEnc_frameSplitter(
+ FIXP_DBL **Energies, INT *scaleEnergies,
+ HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, UCHAR *freqBandTable,
+ UCHAR *tran_vector, int YBufferWriteOffset, int YBufferSzShift, int nSfb,
+ int timeStep, int no_cols, FIXP_DBL *tonality);
+#endif
diff --git a/fdk-aac/libSYS/include/FDK_audio.h b/fdk-aac/libSYS/include/FDK_audio.h
new file mode 100644
index 0000000..d69c008
--- /dev/null
+++ b/fdk-aac/libSYS/include/FDK_audio.h
@@ -0,0 +1,827 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/************************* System integration library **************************
+
+ Author(s): Manuel Jander
+
+ Description:
+
+*******************************************************************************/
+
+/** \file FDK_audio.h
+ * \brief Global audio struct and constant definitions.
+ */
+
+#ifndef FDK_AUDIO_H
+#define FDK_AUDIO_H
+
+#include "machine_type.h"
+#include "genericStds.h"
+#include "syslib_channelMapDescr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * File format identifiers.
+ */
+typedef enum {
+ FF_UNKNOWN = -1, /**< Unknown format. */
+ FF_RAW = 0, /**< No container, bit stream data conveyed "as is". */
+
+ FF_MP4_3GPP = 3, /**< 3GPP file format. */
+ FF_MP4_MP4F = 4, /**< MPEG-4 File format. */
+
+ FF_RAWPACKETS = 5 /**< Proprietary raw packet file. */
+
+} FILE_FORMAT;
+
+/**
+ * Transport type identifiers.
+ */
+typedef enum {
+ TT_UNKNOWN = -1, /**< Unknown format. */
+ TT_MP4_RAW = 0, /**< "as is" access units (packet based since there is
+ obviously no sync layer) */
+ TT_MP4_ADIF = 1, /**< ADIF bitstream format. */
+ TT_MP4_ADTS = 2, /**< ADTS bitstream format. */
+
+ TT_MP4_LATM_MCP1 = 6, /**< Audio Mux Elements with muxConfigPresent = 1 */
+ TT_MP4_LATM_MCP0 = 7, /**< Audio Mux Elements with muxConfigPresent = 0, out
+ of band StreamMuxConfig */
+
+ TT_MP4_LOAS = 10, /**< Audio Sync Stream. */
+
+ TT_DRM = 12, /**< Digital Radio Mondial (DRM30/DRM+) bitstream format. */
+ TT_DABPLUS = 13 /**< Digital Audio Broadcastong (DAB+) superframes bitstream format. */
+
+} TRANSPORT_TYPE;
+
+#define TT_IS_PACKET(x) \
+ (((x) == TT_MP4_RAW) || ((x) == TT_DRM) || ((x) == TT_MP4_LATM_MCP0) || \
+ ((x) == TT_MP4_LATM_MCP1))
+
+/**
+ * Audio Object Type definitions.
+ */
+typedef enum {
+ AOT_NONE = -1,
+ AOT_NULL_OBJECT = 0,
+ AOT_AAC_MAIN = 1, /**< Main profile */
+ AOT_AAC_LC = 2, /**< Low Complexity object */
+ AOT_AAC_SSR = 3,
+ AOT_AAC_LTP = 4,
+ AOT_SBR = 5,
+ AOT_AAC_SCAL = 6,
+ AOT_TWIN_VQ = 7,
+ AOT_CELP = 8,
+ AOT_HVXC = 9,
+ AOT_RSVD_10 = 10, /**< (reserved) */
+ AOT_RSVD_11 = 11, /**< (reserved) */
+ AOT_TTSI = 12, /**< TTSI Object */
+ AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */
+ AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */
+ AOT_GEN_MIDI = 15, /**< General MIDI object */
+ AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */
+ AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */
+ AOT_RSVD_18 = 18, /**< (reserved) */
+ AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */
+ AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */
+ AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */
+ AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */
+ AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */
+ AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */
+ AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */
+ AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */
+ AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */
+ AOT_RSVD_28 = 28, /**< might become SSC */
+ AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */
+ AOT_MPEGS = 30, /**< MPEG Surround */
+
+ AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */
+
+ AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */
+ AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */
+ AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */
+ AOT_RSVD_35 = 35, /**< might become DST */
+ AOT_RSVD_36 = 36, /**< might become ALS */
+ AOT_AAC_SLS = 37, /**< AAC + SLS */
+ AOT_SLS = 38, /**< SLS */
+ AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */
+
+ AOT_USAC = 42, /**< USAC */
+ AOT_SAOC = 43, /**< SAOC */
+ AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */
+
+ 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 */
+
+
+ /* Pseudo AOTs */
+ AOT_MP2_AAC_LC = 129, /**< Virtual AOT MP2 Low Complexity profile */
+ AOT_MP2_SBR = 132, /**< Virtual AOT MP2 Low Complexity Profile with 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_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_DRM_USAC = 147 /**< Virtual AOT for DRM with USAC */
+
+} 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) ((aot) == AOT_USAC)
+
+#define IS_LOWDELAY(aot) ((aot) == AOT_ER_AAC_LD || (aot) == AOT_ER_AAC_ELD)
+
+/** Channel Mode ( 1-7 equals MPEG channel configurations, others are
+ * arbitrary). */
+typedef enum {
+ MODE_INVALID = -1,
+ MODE_UNKNOWN = 0,
+ MODE_1 = 1, /**< C */
+ MODE_2 = 2, /**< L+R */
+ MODE_1_2 = 3, /**< C, L+R */
+ MODE_1_2_1 = 4, /**< C, L+R, Rear */
+ MODE_1_2_2 = 5, /**< C, L+R, LS+RS */
+ MODE_1_2_2_1 = 6, /**< C, L+R, LS+RS, LFE */
+ MODE_1_2_2_2_1 = 7, /**< C, LC+RC, L+R, LS+RS, LFE */
+
+ MODE_6_1 = 11, /**< C, L+R, LS+RS, Crear, LFE */
+ MODE_7_1_BACK = 12, /**< C, L+R, LS+RS, Lrear+Rrear, LFE */
+ MODE_7_1_TOP_FRONT = 14, /**< C, L+R, LS+RS, LFE, Ltop+Rtop */
+
+ MODE_7_1_REAR_SURROUND = 33, /**< C, L+R, LS+RS, Lrear+Rrear, LFE */
+ MODE_7_1_FRONT_CENTER = 34, /**< C, LC+RC, L+R, LS+RS, LFE */
+
+ MODE_212 = 128 /**< 212 configuration, used in ELDv2 */
+
+} CHANNEL_MODE;
+
+/**
+ * Speaker description tags.
+ * Do not change the enumeration values unless it keeps the following
+ * segmentation:
+ * - Bit 0-3: Horizontal postion (0: none, 1: front, 2: side, 3: back, 4: lfe)
+ * - Bit 4-7: Vertical position (0: normal, 1: top, 2: bottom)
+ */
+typedef enum {
+ ACT_NONE = 0x00,
+ ACT_FRONT = 0x01, /*!< Front speaker position (at normal height) */
+ ACT_SIDE = 0x02, /*!< Side speaker position (at normal height) */
+ ACT_BACK = 0x03, /*!< Back speaker position (at normal height) */
+ ACT_LFE = 0x04, /*!< Low frequency effect speaker postion (front) */
+
+ ACT_TOP =
+ 0x10, /*!< Top speaker area (for combination with speaker positions) */
+ ACT_FRONT_TOP = 0x11, /*!< Top front speaker = (ACT_FRONT|ACT_TOP) */
+ ACT_SIDE_TOP = 0x12, /*!< Top side speaker = (ACT_SIDE |ACT_TOP) */
+ ACT_BACK_TOP = 0x13, /*!< Top back speaker = (ACT_BACK |ACT_TOP) */
+
+ ACT_BOTTOM =
+ 0x20, /*!< Bottom speaker area (for combination with speaker positions) */
+ ACT_FRONT_BOTTOM = 0x21, /*!< Bottom front speaker = (ACT_FRONT|ACT_BOTTOM) */
+ ACT_SIDE_BOTTOM = 0x22, /*!< Bottom side speaker = (ACT_SIDE |ACT_BOTTOM) */
+ ACT_BACK_BOTTOM = 0x23 /*!< Bottom back speaker = (ACT_BACK |ACT_BOTTOM) */
+
+} AUDIO_CHANNEL_TYPE;
+
+typedef enum {
+ SIG_UNKNOWN = -1,
+ SIG_IMPLICIT = 0,
+ SIG_EXPLICIT_BW_COMPATIBLE = 1,
+ SIG_EXPLICIT_HIERARCHICAL = 2
+
+} SBR_PS_SIGNALING;
+
+/**
+ * Audio Codec flags.
+ */
+#define AC_ER_VCB11 \
+ 0x000001 /*!< aacSectionDataResilienceFlag flag (from ASC): 1 means use \
+ virtual codebooks */
+#define AC_ER_RVLC \
+ 0x000002 /*!< aacSpectralDataResilienceFlag flag (from ASC): 1 means use \
+ huffman codeword reordering */
+#define AC_ER_HCR \
+ 0x000004 /*!< aacSectionDataResilienceFlag flag (from ASC): 1 means use \
+ virtual codebooks */
+#define AC_SCALABLE 0x000008 /*!< AAC Scalable*/
+#define AC_ELD 0x000010 /*!< AAC-ELD */
+#define AC_LD 0x000020 /*!< AAC-LD */
+#define AC_ER 0x000040 /*!< ER syntax */
+#define AC_BSAC 0x000080 /*!< BSAC */
+#define AC_USAC 0x000100 /*!< USAC */
+#define AC_RSV603DA 0x000200 /*!< RSVD60 3D audio */
+#define AC_HDAAC 0x000400 /*!< HD-AAC */
+#define AC_RSVD50 0x004000 /*!< Rsvd50 */
+#define AC_SBR_PRESENT 0x008000 /*!< SBR present flag (from ASC) */
+#define AC_SBRCRC \
+ 0x010000 /*!< SBR CRC present flag. Only relevant for AAC-ELD for now. */
+#define AC_PS_PRESENT 0x020000 /*!< PS present flag (from ASC or implicit) */
+#define AC_MPS_PRESENT \
+ 0x040000 /*!< MPS present flag (from ASC or implicit) \
+ */
+#define AC_DRM 0x080000 /*!< DRM bit stream syntax */
+#define AC_INDEP 0x100000 /*!< Independency flag */
+#define AC_MPEGD_RES 0x200000 /*!< MPEG-D residual individual channel data. */
+#define AC_SAOC_PRESENT 0x400000 /*!< SAOC Present Flag */
+#define AC_DAB 0x800000 /*!< DAB bit stream syntax */
+#define AC_ELD_DOWNSCALE 0x1000000 /*!< ELD Downscaled playout */
+#define AC_LD_MPS 0x2000000 /*!< Low Delay MPS. */
+#define AC_DRC_PRESENT \
+ 0x4000000 /*!< Dynamic Range Control (DRC) data found. \
+ */
+#define AC_USAC_SCFGI3 \
+ 0x8000000 /*!< USAC flag: If stereoConfigIndex is 3 the flag is set. */
+/**
+ * Audio Codec flags (reconfiguration).
+ */
+#define AC_CM_DET_CFG_CHANGE \
+ 0x000001 /*!< Config mode signalizes the callback to work in config change \
+ detection mode */
+#define AC_CM_ALLOC_MEM \
+ 0x000002 /*!< Config mode signalizes the callback to work in memory \
+ allocation mode */
+
+/**
+ * Audio Codec flags (element specific).
+ */
+#define AC_EL_USAC_TW 0x000001 /*!< USAC time warped filter bank is active */
+#define AC_EL_USAC_NOISE 0x000002 /*!< USAC noise filling is active */
+#define AC_EL_USAC_ITES 0x000004 /*!< USAC SBR inter-TES tool is active */
+#define AC_EL_USAC_PVC \
+ 0x000008 /*!< USAC SBR predictive vector coding tool is active */
+#define AC_EL_USAC_MPS212 0x000010 /*!< USAC MPS212 tool is active */
+#define AC_EL_USAC_LFE 0x000020 /*!< USAC element is LFE */
+#define AC_EL_USAC_CP_POSSIBLE \
+ 0x000040 /*!< USAC may use Complex Stereo Prediction in this channel element \
+ */
+#define AC_EL_ENHANCED_NOISE 0x000080 /*!< Enhanced noise filling*/
+#define AC_EL_IGF_AFTER_TNS 0x000100 /*!< IGF after TNS */
+#define AC_EL_IGF_INDEP_TILING 0x000200 /*!< IGF independent tiling */
+#define AC_EL_IGF_USE_ENF 0x000400 /*!< IGF use enhanced noise filling */
+#define AC_EL_FULLBANDLPD 0x000800 /*!< enable fullband LPD tools */
+#define AC_EL_LPDSTEREOIDX 0x001000 /*!< LPD-stereo-tool stereo index */
+#define AC_EL_LFE 0x002000 /*!< The element is of type LFE. */
+
+/* CODER_CONFIG::flags */
+#define CC_MPEG_ID 0x00100000
+#define CC_IS_BASELAYER 0x00200000
+#define CC_PROTECTION 0x00400000
+#define CC_SBR 0x00800000
+#define CC_SBRCRC 0x00010000
+#define CC_SAC 0x00020000
+#define CC_RVLC 0x01000000
+#define CC_VCB11 0x02000000
+#define CC_HCR 0x04000000
+#define CC_PSEUDO_SURROUND 0x08000000
+#define CC_USAC_NOISE 0x10000000
+#define CC_USAC_TW 0x20000000
+#define CC_USAC_HBE 0x40000000
+
+/** Generic audio coder configuration structure. */
+typedef struct {
+ AUDIO_OBJECT_TYPE aot; /**< Audio Object Type (AOT). */
+ AUDIO_OBJECT_TYPE extAOT; /**< Extension Audio Object Type (SBR). */
+ CHANNEL_MODE channelMode; /**< Channel mode. */
+ UCHAR channelConfigZero; /**< Use channel config zero + pce although a
+ standard channel config could be signaled. */
+ INT samplingRate; /**< Sampling rate. */
+ INT extSamplingRate; /**< Extended samplerate (SBR). */
+ INT downscaleSamplingRate; /**< Downscale sampling rate (ELD downscaled mode)
+ */
+ INT bitRate; /**< Average bitrate. */
+ int samplesPerFrame; /**< Number of PCM samples per codec frame and audio
+ channel. */
+ int noChannels; /**< Number of audio channels. */
+ int bitsFrame;
+ int nSubFrames; /**< Amount of encoder subframes. 1 means no subframing. */
+ int BSACnumOfSubFrame; /**< The number of the sub-frames which are grouped and
+ transmitted in a super-frame (BSAC). */
+ int BSAClayerLength; /**< The average length of the large-step layers in bytes
+ (BSAC). */
+ UINT flags; /**< flags */
+ UCHAR matrixMixdownA; /**< Matrix mixdown index to put into PCE. Default value
+ 0 means no mixdown coefficient, valid values are 1-4
+ which correspond to matrix_mixdown_idx 0-3. */
+ UCHAR headerPeriod; /**< Frame period for sending in band configuration
+ buffers in the transport layer. */
+
+ UCHAR stereoConfigIndex; /**< USAC MPS stereo mode */
+ UCHAR sbrMode; /**< USAC SBR mode */
+ SBR_PS_SIGNALING sbrSignaling; /**< 0: implicit signaling, 1: backwards
+ compatible explicit signaling, 2:
+ hierarcical explicit signaling */
+
+ UCHAR rawConfig[64]; /**< raw codec specific config as bit stream */
+ int rawConfigBits; /**< Size of rawConfig in bits */
+
+ UCHAR sbrPresent;
+ UCHAR psPresent;
+} CODER_CONFIG;
+
+#define USAC_ID_BIT 16 /** USAC element IDs start at USAC_ID_BIT */
+
+/** MP4 Element IDs. */
+typedef enum {
+ /* mp4 element IDs */
+ ID_NONE = -1, /**< Invalid Element helper ID. */
+ ID_SCE = 0, /**< Single Channel Element. */
+ ID_CPE = 1, /**< Channel Pair Element. */
+ ID_CCE = 2, /**< Coupling Channel Element. */
+ ID_LFE = 3, /**< LFE Channel Element. */
+ ID_DSE = 4, /**< Currently one Data Stream Element for ancillary data is
+ supported. */
+ ID_PCE = 5, /**< Program Config Element. */
+ ID_FIL = 6, /**< Fill Element. */
+ ID_END = 7, /**< Arnie (End Element = Terminator). */
+ ID_EXT = 8, /**< Extension Payload (ER only). */
+ ID_SCAL = 9, /**< AAC scalable element (ER only). */
+ /* USAC element IDs */
+ ID_USAC_SCE = 0 + USAC_ID_BIT, /**< Single Channel Element. */
+ ID_USAC_CPE = 1 + USAC_ID_BIT, /**< Channel Pair Element. */
+ ID_USAC_LFE = 2 + USAC_ID_BIT, /**< LFE Channel Element. */
+ ID_USAC_EXT = 3 + USAC_ID_BIT, /**< Extension Element. */
+ ID_USAC_END = 4 + USAC_ID_BIT, /**< Arnie (End Element = Terminator). */
+ ID_LAST
+} MP4_ELEMENT_ID;
+
+/* usacConfigExtType q.v. ISO/IEC DIS 23008-3 Table 52 and ISO/IEC FDIS
+ * 23003-3:2011(E) Table 74*/
+typedef enum {
+ /* USAC and RSVD60 3DA */
+ ID_CONFIG_EXT_FILL = 0,
+ /* RSVD60 3DA */
+ ID_CONFIG_EXT_DOWNMIX = 1,
+ ID_CONFIG_EXT_LOUDNESS_INFO = 2,
+ ID_CONFIG_EXT_AUDIOSCENE_INFO = 3,
+ ID_CONFIG_EXT_HOA_MATRIX = 4,
+ ID_CONFIG_EXT_SIG_GROUP_INFO = 6
+ /* 5-127 => reserved for ISO use */
+ /* > 128 => reserved for use outside of ISO scope */
+} CONFIG_EXT_ID;
+
+#define IS_CHANNEL_ELEMENT(elementId) \
+ ((elementId) == ID_SCE || (elementId) == ID_CPE || (elementId) == ID_LFE || \
+ (elementId) == ID_USAC_SCE || (elementId) == ID_USAC_CPE || \
+ (elementId) == ID_USAC_LFE)
+
+#define IS_MP4_CHANNEL_ELEMENT(elementId) \
+ ((elementId) == ID_SCE || (elementId) == ID_CPE || (elementId) == ID_LFE)
+
+#define EXT_ID_BITS 4 /**< Size in bits of extension payload type tags. */
+
+/** Extension payload types. */
+typedef enum {
+ EXT_FIL = 0x00,
+ EXT_FILL_DATA = 0x01,
+ EXT_DATA_ELEMENT = 0x02,
+ EXT_DATA_LENGTH = 0x03,
+ EXT_UNI_DRC = 0x04,
+ EXT_LDSAC_DATA = 0x09,
+ EXT_SAOC_DATA = 0x0a,
+ EXT_DYNAMIC_RANGE = 0x0b,
+ EXT_SAC_DATA = 0x0c,
+ EXT_SBR_DATA = 0x0d,
+ EXT_SBR_DATA_CRC = 0x0e
+} EXT_PAYLOAD_TYPE;
+
+#define IS_USAC_CHANNEL_ELEMENT(elementId) \
+ ((elementId) == ID_USAC_SCE || (elementId) == ID_USAC_CPE || \
+ (elementId) == ID_USAC_LFE)
+
+/** MPEG-D USAC & RSVD60 3D audio Extension Element Types. */
+typedef enum {
+ /* usac */
+ ID_EXT_ELE_FILL = 0x00,
+ ID_EXT_ELE_MPEGS = 0x01,
+ ID_EXT_ELE_SAOC = 0x02,
+ ID_EXT_ELE_AUDIOPREROLL = 0x03,
+ ID_EXT_ELE_UNI_DRC = 0x04,
+ /* rsv603da */
+ ID_EXT_ELE_OBJ_METADATA = 0x05,
+ ID_EXT_ELE_SAOC_3D = 0x06,
+ ID_EXT_ELE_HOA = 0x07,
+ ID_EXT_ELE_FMT_CNVRTR = 0x08,
+ ID_EXT_ELE_MCT = 0x09,
+ ID_EXT_ELE_ENHANCED_OBJ_METADATA = 0x0d,
+ /* reserved for use outside of ISO scope */
+ ID_EXT_ELE_VR_METADATA = 0x81,
+ ID_EXT_ELE_UNKNOWN = 0xFF
+} USAC_EXT_ELEMENT_TYPE;
+
+/**
+ * Proprietary raw packet file configuration data type identifier.
+ */
+typedef enum {
+ TC_NOTHING = 0, /* No configuration available -> in-band configuration. */
+ TC_RAW_ADTS = 2, /* Transfer type is ADTS. */
+ TC_RAW_LATM_MCP1 = 6, /* Transfer type is LATM with SMC present. */
+ TC_RAW_SDC = 21 /* Configuration data field is Drm SDC. */
+
+} TP_CONFIG_TYPE;
+
+/*
+ * ##############################################################################################
+ * Library identification and error handling
+ * ##############################################################################################
+ */
+/* \cond */
+
+typedef enum {
+ FDK_NONE = 0,
+ FDK_TOOLS = 1,
+ FDK_SYSLIB = 2,
+ FDK_AACDEC = 3,
+ FDK_AACENC = 4,
+ FDK_SBRDEC = 5,
+ FDK_SBRENC = 6,
+ FDK_TPDEC = 7,
+ FDK_TPENC = 8,
+ FDK_MPSDEC = 9,
+ FDK_MPEGFILEREAD = 10,
+ FDK_MPEGFILEWRITE = 11,
+ FDK_PCMDMX = 31,
+ FDK_MPSENC = 34,
+ FDK_TDLIMIT = 35,
+ FDK_UNIDRCDEC = 38,
+
+ FDK_MODULE_LAST
+
+} FDK_MODULE_ID;
+
+/* AAC capability flags */
+#define CAPF_AAC_LC 0x00000001 /**< Support flag for AAC Low Complexity. */
+#define CAPF_ER_AAC_LD \
+ 0x00000002 /**< Support flag for AAC Low Delay with Error Resilience tools. \
+ */
+#define CAPF_ER_AAC_SCAL 0x00000004 /**< Support flag for AAC Scalable. */
+#define CAPF_ER_AAC_LC \
+ 0x00000008 /**< Support flag for AAC Low Complexity with Error Resilience \
+ tools. */
+#define CAPF_AAC_480 \
+ 0x00000010 /**< Support flag for AAC with 480 framelength. */
+#define CAPF_AAC_512 \
+ 0x00000020 /**< Support flag for AAC with 512 framelength. */
+#define CAPF_AAC_960 \
+ 0x00000040 /**< Support flag for AAC with 960 framelength. */
+#define CAPF_AAC_1024 \
+ 0x00000080 /**< Support flag for AAC with 1024 framelength. */
+#define CAPF_AAC_HCR \
+ 0x00000100 /**< Support flag for AAC with Huffman Codeword Reordering. */
+#define CAPF_AAC_VCB11 \
+ 0x00000200 /**< Support flag for AAC Virtual Codebook 11. */
+#define CAPF_AAC_RVLC \
+ 0x00000400 /**< Support flag for AAC Reversible Variable Length Coding. */
+#define CAPF_AAC_MPEG4 0x00000800 /**< Support flag for MPEG file format. */
+#define CAPF_AAC_DRC \
+ 0x00001000 /**< Support flag for AAC Dynamic Range Control. */
+#define CAPF_AAC_CONCEALMENT \
+ 0x00002000 /**< Support flag for AAC concealment. */
+#define CAPF_AAC_DRM_BSFORMAT \
+ 0x00004000 /**< Support flag for AAC DRM bistream format. */
+#define CAPF_ER_AAC_ELD \
+ 0x00008000 /**< Support flag for AAC Enhanced Low Delay with Error \
+ Resilience tools. */
+#define CAPF_ER_AAC_BSAC \
+ 0x00010000 /**< Support flag for AAC BSAC. */
+#define CAPF_AAC_ELD_DOWNSCALE \
+ 0x00040000 /**< Support flag for AAC-ELD Downscaling */
+#define CAPF_AAC_USAC_LP \
+ 0x00100000 /**< Support flag for USAC low power mode. */
+#define CAPF_AAC_USAC \
+ 0x00200000 /**< Support flag for Unified Speech and Audio Coding (USAC). */
+#define CAPF_ER_AAC_ELDV2 \
+ 0x00800000 /**< Support flag for AAC Enhanced Low Delay with MPS 212. */
+#define CAPF_AAC_UNIDRC \
+ 0x01000000 /**< Support flag for MPEG-D Dynamic Range Control (uniDrc). */
+
+/* Transport capability flags */
+#define CAPF_ADTS \
+ 0x00000001 /**< Support flag for ADTS transport format. */
+#define CAPF_ADIF \
+ 0x00000002 /**< Support flag for ADIF transport format. */
+#define CAPF_LATM \
+ 0x00000004 /**< Support flag for LATM transport format. */
+#define CAPF_LOAS \
+ 0x00000008 /**< Support flag for LOAS transport format. */
+#define CAPF_RAWPACKETS \
+ 0x00000010 /**< Support flag for RAW PACKETS transport format. */
+#define CAPF_DRM \
+ 0x00000020 /**< Support flag for DRM/DRM+ transport format. */
+#define CAPF_RSVD50 \
+ 0x00000040 /**< Support flag for RSVD50 transport format */
+
+/* SBR capability flags */
+#define CAPF_SBR_LP \
+ 0x00000001 /**< Support flag for SBR Low Power mode. */
+#define CAPF_SBR_HQ \
+ 0x00000002 /**< Support flag for SBR High Quality mode. */
+#define CAPF_SBR_DRM_BS \
+ 0x00000004 /**< Support flag for */
+#define CAPF_SBR_CONCEALMENT \
+ 0x00000008 /**< Support flag for SBR concealment. */
+#define CAPF_SBR_DRC \
+ 0x00000010 /**< Support flag for SBR Dynamic Range Control. */
+#define CAPF_SBR_PS_MPEG \
+ 0x00000020 /**< Support flag for MPEG Parametric Stereo. */
+#define CAPF_SBR_PS_DRM \
+ 0x00000040 /**< Support flag for DRM Parametric Stereo. */
+#define CAPF_SBR_ELD_DOWNSCALE \
+ 0x00000080 /**< Support flag for ELD reduced delay mode */
+#define CAPF_SBR_HBEHQ \
+ 0x00000100 /**< Support flag for HQ HBE */
+
+/* DAB capability flags */
+#define CAPF_DAB_MP2 0x00000001 /**< Support flag for Layer2 DAB. */
+#define CAPF_DAB_AAC 0x00000002 /**< Support flag for DAB+ (HE-AAC v2). */
+#define CAPF_DAB_PAD 0x00000004 /**< Support flag for PAD extraction. */
+#define CAPF_DAB_DRC 0x00000008 /**< Support flag for Dynamic Range Control. */
+#define CAPF_DAB_SURROUND 0x00000010 /**< Support flag for DAB Surround (MPS). */
+
+
+/* PCM utils capability flags */
+#define CAPF_DMX_BLIND \
+ 0x00000001 /**< Support flag for blind downmixing. */
+#define CAPF_DMX_PCE \
+ 0x00000002 /**< Support flag for guided downmix with data from MPEG-2/4 \
+ Program Config Elements (PCE). */
+#define CAPF_DMX_ARIB \
+ 0x00000004 /**< Support flag for PCE guided downmix with slightly different \
+ equations and levels to fulfill ARIB standard. */
+#define CAPF_DMX_DVB \
+ 0x00000008 /**< Support flag for guided downmix with data from DVB ancillary \
+ data fields. */
+#define CAPF_DMX_CH_EXP \
+ 0x00000010 /**< Support flag for simple upmixing by dublicating channels or \
+ adding zero channels. */
+#define CAPF_DMX_6_CH \
+ 0x00000020 /**< Support flag for 5.1 channel configuration (input and \
+ output). */
+#define CAPF_DMX_8_CH \
+ 0x00000040 /**< Support flag for 6 and 7.1 channel configurations (input and \
+ output). */
+#define CAPF_DMX_24_CH \
+ 0x00000080 /**< Support flag for 22.2 channel configuration (input and \
+ output). */
+#define CAPF_LIMITER \
+ 0x00002000 /**< Support flag for signal level limiting. \
+ */
+
+/* MPEG Surround capability flags */
+#define CAPF_MPS_STD \
+ 0x00000001 /**< Support flag for MPEG Surround. */
+#define CAPF_MPS_LD \
+ 0x00000002 /**< Support flag for Low Delay MPEG Surround. \
+ */
+#define CAPF_MPS_USAC \
+ 0x00000004 /**< Support flag for USAC MPEG Surround. */
+#define CAPF_MPS_HQ \
+ 0x00000010 /**< Support flag indicating if high quality processing is \
+ supported */
+#define CAPF_MPS_LP \
+ 0x00000020 /**< Support flag indicating if partially complex (low power) \
+ processing is supported */
+#define CAPF_MPS_BLIND \
+ 0x00000040 /**< Support flag indicating if blind processing is supported */
+#define CAPF_MPS_BINAURAL \
+ 0x00000080 /**< Support flag indicating if binaural output is possible */
+#define CAPF_MPS_2CH_OUT \
+ 0x00000100 /**< Support flag indicating if 2ch output is possible */
+#define CAPF_MPS_6CH_OUT \
+ 0x00000200 /**< Support flag indicating if 6ch output is possible */
+#define CAPF_MPS_8CH_OUT \
+ 0x00000400 /**< Support flag indicating if 8ch output is possible */
+#define CAPF_MPS_1CH_IN \
+ 0x00001000 /**< Support flag indicating if 1ch dmx input is possible */
+#define CAPF_MPS_2CH_IN \
+ 0x00002000 /**< Support flag indicating if 2ch dmx input is possible */
+#define CAPF_MPS_6CH_IN \
+ 0x00004000 /**< Support flag indicating if 5ch dmx input is possible */
+
+/* \endcond */
+
+/*
+ * ##############################################################################################
+ * Library versioning
+ * ##############################################################################################
+ */
+
+/**
+ * Convert each member of version numbers to one single numeric version
+ * representation.
+ * \param lev0 1st level of version number.
+ * \param lev1 2nd level of version number.
+ * \param lev2 3rd level of version number.
+ */
+#define LIB_VERSION(lev0, lev1, lev2) \
+ ((lev0 << 24 & 0xff000000) | (lev1 << 16 & 0x00ff0000) | \
+ (lev2 << 8 & 0x0000ff00))
+
+/**
+ * Build text string of version.
+ */
+#define LIB_VERSION_STRING(info) \
+ FDKsprintf((info)->versionStr, "%d.%d.%d", (((info)->version >> 24) & 0xff), \
+ (((info)->version >> 16) & 0xff), \
+ (((info)->version >> 8) & 0xff))
+
+/**
+ * Library information.
+ */
+typedef struct LIB_INFO {
+ const char* title;
+ const char* build_date;
+ const char* build_time;
+ FDK_MODULE_ID module_id;
+ INT version;
+ UINT flags;
+ char versionStr[32];
+} LIB_INFO;
+
+#ifdef __cplusplus
+#define FDK_AUDIO_INLINE inline
+#else
+#define FDK_AUDIO_INLINE
+#endif
+
+/** Initialize library info. */
+static FDK_AUDIO_INLINE void FDKinitLibInfo(LIB_INFO* info) {
+ int i;
+
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ info[i].module_id = FDK_NONE;
+ }
+}
+
+/** Aquire supported features of library. */
+static FDK_AUDIO_INLINE UINT
+FDKlibInfo_getCapabilities(const LIB_INFO* info, FDK_MODULE_ID module_id) {
+ int i;
+
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == module_id) {
+ return info[i].flags;
+ }
+ }
+ return 0;
+}
+
+/** Search for next free tab. */
+static FDK_AUDIO_INLINE INT FDKlibInfo_lookup(const LIB_INFO* info,
+ FDK_MODULE_ID module_id) {
+ int i = -1;
+
+ for (i = 0; i < FDK_MODULE_LAST; i++) {
+ if (info[i].module_id == module_id) return -1;
+ if (info[i].module_id == FDK_NONE) break;
+ }
+ if (i == FDK_MODULE_LAST) return -1;
+
+ return i;
+}
+
+/*
+ * ##############################################################################################
+ * Buffer description
+ * ##############################################################################################
+ */
+
+/**
+ * I/O buffer descriptor.
+ */
+typedef struct FDK_bufDescr {
+ void** ppBase; /*!< Pointer to an array containing buffer base addresses.
+ Set to NULL for buffer requirement info. */
+ UINT* pBufSize; /*!< Pointer to an array containing the number of elements
+ that can be placed in the specific buffer. */
+ UINT* pEleSize; /*!< Pointer to an array containing the element size for each
+ buffer in bytes. That is mostly the number returned by the
+ sizeof() operator for the data type used for the specific
+ buffer. */
+ UINT*
+ pBufType; /*!< Pointer to an array of bit fields containing a description
+ for each buffer. See XXX below for more details. */
+ UINT numBufs; /*!< Total number of buffers. */
+
+} FDK_bufDescr;
+
+/**
+ * Buffer type description field.
+ */
+#define FDK_BUF_TYPE_MASK_IO ((UINT)0x03 << 30)
+#define FDK_BUF_TYPE_MASK_DESCR ((UINT)0x3F << 16)
+#define FDK_BUF_TYPE_MASK_ID ((UINT)0xFF)
+
+#define FDK_BUF_TYPE_INPUT ((UINT)0x1 << 30)
+#define FDK_BUF_TYPE_OUTPUT ((UINT)0x2 << 30)
+
+#define FDK_BUF_TYPE_PCM_DATA ((UINT)0x1 << 16)
+#define FDK_BUF_TYPE_ANC_DATA ((UINT)0x2 << 16)
+#define FDK_BUF_TYPE_BS_DATA ((UINT)0x4 << 16)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FDK_AUDIO_H */
diff --git a/fdk-aac/libSYS/include/genericStds.h b/fdk-aac/libSYS/include/genericStds.h
new file mode 100644
index 0000000..8828ba7
--- /dev/null
+++ b/fdk-aac/libSYS/include/genericStds.h
@@ -0,0 +1,584 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/************************* System integration library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/** \file genericStds.h
+ \brief Generic Run-Time Support function wrappers and heap allocation
+ monitoring.
+ */
+
+#if !defined(GENERICSTDS_H)
+#define GENERICSTDS_H
+
+#include "machine_type.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846 /*!< Pi. Only used in example projects. */
+#endif
+
+/**
+ * Identifiers for various memory locations. They are used along with memory
+ * allocation functions like FDKcalloc_L() to specify the requested memory's
+ * location.
+ */
+typedef enum {
+ /* Internal */
+ SECT_DATA_L1 = 0x2000,
+ SECT_DATA_L2,
+ SECT_DATA_L1_A,
+ SECT_DATA_L1_B,
+ SECT_CONSTDATA_L1,
+
+ /* External */
+ SECT_DATA_EXTERN = 0x4000,
+ SECT_CONSTDATA_EXTERN
+
+} MEMORY_SECTION;
+
+/*! \addtogroup SYSLIB_MEMORY_MACROS FDK memory macros
+ *
+ * The \c H_ prefix indicates that the macro is to be used in a header file, the
+ * \c C_ prefix indicates that the macro is to be used in a source file.
+ *
+ * Declaring memory areas requires to specify a unique name and a data type.
+ *
+ * For defining a memory area you require additionally one or two sizes,
+ * depending if the memory should be organized into one or two dimensions.
+ *
+ * The macros containing the keyword \c AALLOC instead of \c ALLOC additionally
+ * take care of returning aligned memory addresses (beyond the natural alignment
+ * of its type). The preprocesor macro
+ * ::ALIGNMENT_DEFAULT indicates the aligment to be used (this is hardware
+ * specific).
+ *
+ * The \c _L suffix indicates that the memory will be located in a specific
+ * section. This is useful to allocate critical memory section into fast
+ * internal SRAM for example.
+ *
+ * @{
+ */
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define H_ALLOC_MEM(name, type) \
+ type *Get##name(int n = 0); \
+ void Free##name(type **p); \
+ UINT GetRequiredMem##name(void);
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define H_ALLOC_MEM_OVERLAY(name, type) \
+ type *Get##name(int n = 0); \
+ void Free##name(type **p); \
+ UINT GetRequiredMem##name(void);
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_ALLOC_MEM(name, type, num) \
+ type *Get##name(int n) { \
+ FDK_ASSERT((n) == 0); \
+ return ((type *)FDKcalloc(num, sizeof(type))); \
+ } \
+ void Free##name(type **p) { \
+ if (p != NULL) { \
+ FDKfree(*p); \
+ *p = NULL; \
+ } \
+ } \
+ UINT GetRequiredMem##name(void) { \
+ return ALGN_SIZE_EXTRES((num) * sizeof(type)); \
+ }
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_ALLOC_MEM2(name, type, n1, n2) \
+ type *Get##name(int n) { \
+ FDK_ASSERT((n) < (n2)); \
+ return ((type *)FDKcalloc(n1, sizeof(type))); \
+ } \
+ void Free##name(type **p) { \
+ if (p != NULL) { \
+ FDKfree(*p); \
+ *p = NULL; \
+ } \
+ } \
+ UINT GetRequiredMem##name(void) { \
+ return ALGN_SIZE_EXTRES((n1) * sizeof(type)) * (n2); \
+ }
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_AALLOC_MEM(name, type, num) \
+ type *Get##name(int n) { \
+ type *ap; \
+ FDK_ASSERT((n) == 0); \
+ ap = ((type *)FDKaalloc((num) * sizeof(type), ALIGNMENT_DEFAULT)); \
+ return ap; \
+ } \
+ void Free##name(type **p) { \
+ if (p != NULL) { \
+ FDKafree(*p); \
+ *p = NULL; \
+ } \
+ } \
+ UINT GetRequiredMem##name(void) { \
+ return ALGN_SIZE_EXTRES((num) * sizeof(type) + ALIGNMENT_DEFAULT + \
+ sizeof(void *)); \
+ }
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_AALLOC_MEM2(name, type, n1, n2) \
+ type *Get##name(int n) { \
+ type *ap; \
+ FDK_ASSERT((n) < (n2)); \
+ ap = ((type *)FDKaalloc((n1) * sizeof(type), ALIGNMENT_DEFAULT)); \
+ return ap; \
+ } \
+ void Free##name(type **p) { \
+ if (p != NULL) { \
+ FDKafree(*p); \
+ *p = NULL; \
+ } \
+ } \
+ UINT GetRequiredMem##name(void) { \
+ return ALGN_SIZE_EXTRES((n1) * sizeof(type) + ALIGNMENT_DEFAULT + \
+ sizeof(void *)) * \
+ (n2); \
+ }
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_ALLOC_MEM_L(name, type, num, s) \
+ type *Get##name(int n) { \
+ FDK_ASSERT((n) == 0); \
+ return ((type *)FDKcalloc_L(num, sizeof(type), s)); \
+ } \
+ void Free##name(type **p) { \
+ if (p != NULL) { \
+ FDKfree_L(*p); \
+ *p = NULL; \
+ } \
+ } \
+ UINT GetRequiredMem##name(void) { \
+ return ALGN_SIZE_EXTRES((num) * sizeof(type)); \
+ }
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_ALLOC_MEM2_L(name, type, n1, n2, s) \
+ type *Get##name(int n) { \
+ FDK_ASSERT((n) < (n2)); \
+ return (type *)FDKcalloc_L(n1, sizeof(type), s); \
+ } \
+ void Free##name(type **p) { \
+ if (p != NULL) { \
+ FDKfree_L(*p); \
+ *p = NULL; \
+ } \
+ } \
+ UINT GetRequiredMem##name(void) { \
+ return ALGN_SIZE_EXTRES((n1) * sizeof(type)) * (n2); \
+ }
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_AALLOC_MEM_L(name, type, num, s) \
+ type *Get##name(int n) { \
+ type *ap; \
+ FDK_ASSERT((n) == 0); \
+ ap = ((type *)FDKaalloc_L((num) * sizeof(type), ALIGNMENT_DEFAULT, s)); \
+ return ap; \
+ } \
+ void Free##name(type **p) { \
+ if (p != NULL) { \
+ FDKafree_L(*p); \
+ *p = NULL; \
+ } \
+ } \
+ UINT GetRequiredMem##name(void) { \
+ return ALGN_SIZE_EXTRES((num) * sizeof(type) + ALIGNMENT_DEFAULT + \
+ sizeof(void *)); \
+ }
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_AALLOC_MEM2_L(name, type, n1, n2, s) \
+ type *Get##name(int n) { \
+ type *ap; \
+ FDK_ASSERT((n) < (n2)); \
+ ap = ((type *)FDKaalloc_L((n1) * sizeof(type), ALIGNMENT_DEFAULT, s)); \
+ return ap; \
+ } \
+ void Free##name(type **p) { \
+ if (p != NULL) { \
+ FDKafree_L(*p); \
+ *p = NULL; \
+ } \
+ } \
+ UINT GetRequiredMem##name(void) { \
+ return ALGN_SIZE_EXTRES((n1) * sizeof(type) + ALIGNMENT_DEFAULT + \
+ sizeof(void *)) * \
+ (n2); \
+ }
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_ALLOC_MEM_OVERLAY(name, type, num, sect, tag) \
+ C_AALLOC_MEM_L(name, type, num, sect)
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_AALLOC_SCRATCH_START(name, type, n) \
+ type _##name[(n) + (ALIGNMENT_DEFAULT + sizeof(type) - 1)]; \
+ type *name = (type *)ALIGN_PTR(_##name); \
+ C_ALLOC_ALIGNED_REGISTER(name, (n) * sizeof(type));
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_ALLOC_SCRATCH_START(name, type, n) type name[n];
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_AALLOC_SCRATCH_END(name, type, n) C_ALLOC_ALIGNED_UNREGISTER(name);
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_ALLOC_SCRATCH_END(name, type, n)
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_AALLOC_STACK_START(name, type, n) \
+ type _##name[(n) + (ALIGNMENT_DEFAULT + sizeof(type) - 1)]; \
+ type *name = (type *)ALIGN_PTR(_##name); \
+ C_ALLOC_ALIGNED_REGISTER(name, (n) * sizeof(type));
+
+/** See \ref SYSLIB_MEMORY_MACROS for description. */
+#define C_AALLOC_STACK_END(name, type, n) C_ALLOC_ALIGNED_UNREGISTER(name);
+
+/*! @} */
+
+#define C_ALLOC_ALIGNED_REGISTER(x, size)
+#define C_ALLOC_ALIGNED_UNREGISTER(x)
+#define C_ALLOC_ALIGNED_CHECK(x)
+#define C_ALLOC_ALIGNED_CHECK2(x, y)
+#define FDK_showBacktrace(a, b)
+
+/*! \addtogroup SYSLIB_EXITCODES Unified exit codes
+ * Exit codes to be used as return values of FDK software test and
+ * demonstration applications. Not as return values of product modules and/or
+ * libraries.
+ * @{
+ */
+#define FDK_EXITCODE_OK 0 /*!< Successful termination. No errors. */
+#define FDK_EXITCODE_USAGE \
+ 64 /*!< The command/application was used incorrectly, e.g. with the wrong \
+ number of arguments, a bad flag, a bad syntax in a parameter, or \
+ whatever. */
+#define FDK_EXITCODE_DATAERROR \
+ 65 /*!< The input data was incorrect in some way. This should only be used \
+ for user data and not system files. */
+#define FDK_EXITCODE_NOINPUT \
+ 66 /*!< An input file (not a system file) did not exist or was not readable. \
+ */
+#define FDK_EXITCODE_UNAVAILABLE \
+ 69 /*!< A service is unavailable. This can occur if a support program or \
+ file does not exist. This can also be used as a catchall message when \
+ something you wanted to do doesn't work, but you don't know why. */
+#define FDK_EXITCODE_SOFTWARE \
+ 70 /*!< An internal software error has been detected. This should be limited \
+ to non- operating system related errors as possible. */
+#define FDK_EXITCODE_CANTCREATE \
+ 73 /*!< A (user specified) output file cannot be created. */
+#define FDK_EXITCODE_IOERROR \
+ 74 /*!< An error occurred while doing I/O on some file. */
+/*! @} */
+
+/*--------------------------------------------
+ * Runtime support declarations
+ *---------------------------------------------*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void FDKprintf(const char *szFmt, ...);
+
+void FDKprintfErr(const char *szFmt, ...);
+
+/** Wrapper for <stdio.h>'s getchar(). */
+int FDKgetchar(void);
+
+INT FDKfprintf(void *stream, const char *format, ...);
+INT FDKsprintf(char *str, const char *format, ...);
+
+char *FDKstrchr(char *s, INT c);
+const char *FDKstrstr(const char *haystack, const char *needle);
+char *FDKstrcpy(char *dest, const char *src);
+char *FDKstrncpy(char *dest, const char *src, const UINT n);
+
+#define FDK_MAX_OVERLAYS 8 /**< Maximum number of memory overlays. */
+
+void *FDKcalloc(const UINT n, const UINT size);
+void *FDKmalloc(const UINT size);
+void FDKfree(void *ptr);
+
+/**
+ * Allocate and clear an aligned memory area. Use FDKafree() instead of
+ * FDKfree() for these memory areas.
+ *
+ * \param size Size of requested memory in bytes.
+ * \param alignment Alignment of requested memory in bytes.
+ * \return Pointer to allocated memory.
+ */
+void *FDKaalloc(const UINT size, const UINT alignment);
+
+/**
+ * Free an aligned memory area.
+ *
+ * \param ptr Pointer to be freed.
+ */
+void FDKafree(void *ptr);
+
+/**
+ * Allocate memory in a specific memory section.
+ * Requests can be made for internal or external memory. If internal memory is
+ * requested, FDKcalloc_L() first tries to use L1 memory, which sizes are
+ * defined by ::DATA_L1_A_SIZE and ::DATA_L1_B_SIZE. If no L1 memory is
+ * available, then FDKcalloc_L() tries to use L2 memory. If that fails as well,
+ * the requested memory is allocated at an extern location using the fallback
+ * FDKcalloc().
+ *
+ * \param n See MSDN documentation on calloc().
+ * \param size See MSDN documentation on calloc().
+ * \param s Memory section.
+ * \return See MSDN documentation on calloc().
+ */
+void *FDKcalloc_L(const UINT n, const UINT size, MEMORY_SECTION s);
+
+/**
+ * Allocate aligned memory in a specific memory section.
+ * See FDKcalloc_L() description for details - same applies here.
+ */
+void *FDKaalloc_L(const UINT size, const UINT alignment, MEMORY_SECTION s);
+
+/**
+ * Free memory that was allocated in a specific memory section.
+ */
+void FDKfree_L(void *ptr);
+
+/**
+ * Free aligned memory that was allocated in a specific memory section.
+ */
+void FDKafree_L(void *ptr);
+
+/**
+ * Copy memory. Source and destination memory must not overlap.
+ * Either use implementation from a Standard Library, or, if no Standard Library
+ * is available, a generic implementation.
+ * The define ::USE_BUILTIN_MEM_FUNCTIONS in genericStds.cpp controls what to
+ * use. The function arguments correspond to the standard memcpy(). Please see
+ * MSDN documentation for details on how to use it.
+ */
+void FDKmemcpy(void *dst, const void *src, const UINT size);
+
+/**
+ * Copy memory. Source and destination memory are allowed to overlap.
+ * Either use implementation from a Standard Library, or, if no Standard Library
+ * is available, a generic implementation.
+ * The define ::USE_BUILTIN_MEM_FUNCTIONS in genericStds.cpp controls what to
+ * use. The function arguments correspond to the standard memmove(). Please see
+ * MSDN documentation for details on how to use it.
+ */
+void FDKmemmove(void *dst, const void *src, const UINT size);
+
+/**
+ * Clear memory.
+ * Either use implementation from a Standard Library, or, if no Standard Library
+ * is available, a generic implementation.
+ * The define ::USE_BUILTIN_MEM_FUNCTIONS in genericStds.cpp controls what to
+ * use. The function arguments correspond to the standard memclear(). Please see
+ * MSDN documentation for details on how to use it.
+ */
+void FDKmemclear(void *memPtr, const UINT size);
+
+/**
+ * Fill memory with values.
+ * The function arguments correspond to the standard memset(). Please see MSDN
+ * documentation for details on how to use it.
+ */
+void FDKmemset(void *memPtr, const INT value, const UINT size);
+
+/* Compare function wrappers */
+INT FDKmemcmp(const void *s1, const void *s2, const UINT size);
+INT FDKstrcmp(const char *s1, const char *s2);
+INT FDKstrncmp(const char *s1, const char *s2, const UINT size);
+
+UINT FDKstrlen(const char *s);
+
+#define FDKmax(a, b) ((a) > (b) ? (a) : (b))
+#define FDKmin(a, b) ((a) < (b) ? (a) : (b))
+
+#define FDK_INT_MAX ((INT)0x7FFFFFFF)
+#define FDK_INT_MIN ((INT)0x80000000)
+
+/* FILE I/O */
+
+/*!
+ * Check platform for endianess.
+ *
+ * \return 1 if platform is little endian, non-1 if platform is big endian.
+ */
+int IS_LITTLE_ENDIAN(void);
+
+/*!
+ * Convert input value to little endian format.
+ *
+ * \param val Value to be converted. It may be in both big or little endian.
+ * \return Value in little endian format.
+ */
+UINT TO_LITTLE_ENDIAN(UINT val);
+
+/*!
+ * \fn FDKFILE *FDKfopen(const char *filename, const char *mode);
+ * Standard fopen() wrapper.
+ * \fn INT FDKfclose(FDKFILE *FP);
+ * Standard fclose() wrapper.
+ * \fn INT FDKfseek(FDKFILE *FP, LONG OFFSET, int WHENCE);
+ * Standard fseek() wrapper.
+ * \fn INT FDKftell(FDKFILE *FP);
+ * Standard ftell() wrapper.
+ * \fn INT FDKfflush(FDKFILE *fp);
+ * Standard fflush() wrapper.
+ * \fn UINT FDKfwrite(const void *ptrf, INT size, UINT nmemb, FDKFILE *fp);
+ * Standard fwrite() wrapper.
+ * \fn UINT FDKfread(void *dst, INT size, UINT nmemb, FDKFILE *fp);
+ * Standard fread() wrapper.
+ */
+typedef void FDKFILE;
+extern const INT FDKSEEK_SET, FDKSEEK_CUR, FDKSEEK_END;
+
+FDKFILE *FDKfopen(const char *filename, const char *mode);
+INT FDKfclose(FDKFILE *FP);
+INT FDKfseek(FDKFILE *FP, LONG OFFSET, int WHENCE);
+INT FDKftell(FDKFILE *FP);
+INT FDKfflush(FDKFILE *fp);
+UINT FDKfwrite(const void *ptrf, INT size, UINT nmemb, FDKFILE *fp);
+UINT FDKfread(void *dst, INT size, UINT nmemb, FDKFILE *fp);
+char *FDKfgets(void *dst, INT size, FDKFILE *fp);
+void FDKrewind(FDKFILE *fp);
+INT FDKfeof(FDKFILE *fp);
+
+/**
+ * \brief Write each member in little endian order. Convert automatically
+ * to host endianess.
+ * \param ptrf Pointer to memory where to read data from.
+ * \param size Size of each item to be written.
+ * \param nmemb Number of items to be written.
+ * \param fp File pointer of type FDKFILE.
+ * \return Number of items read on success and fread() error on failure.
+ */
+UINT FDKfwrite_EL(const void *ptrf, INT size, UINT nmemb, FDKFILE *fp);
+
+/**
+ * \brief Read variable of size "size" as little endian. Convert
+ * automatically to host endianess. 4-byte alignment is enforced for 24 bit
+ * data, at 32 bit full scale.
+ * \param dst Pointer to memory where to store data into.
+ * \param size Size of each item to be read.
+ * \param nmemb Number of items to be read.
+ * \param fp File pointer of type FDKFILE.
+ * \return Number of items read on success and fread() error on failure.
+ */
+UINT FDKfread_EL(void *dst, INT size, UINT nmemb, FDKFILE *fp);
+
+/**
+ * \brief Print FDK software disclaimer.
+ */
+void FDKprintDisclaimer(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GENERICSTDS_H */
diff --git a/fdk-aac/libSYS/include/machine_type.h b/fdk-aac/libSYS/include/machine_type.h
new file mode 100644
index 0000000..bd97669
--- /dev/null
+++ b/fdk-aac/libSYS/include/machine_type.h
@@ -0,0 +1,411 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/************************* System integration library **************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/** \file machine_type.h
+ * \brief Type defines for various processors and compiler tools.
+ */
+
+#if !defined(MACHINE_TYPE_H)
+#define MACHINE_TYPE_H
+
+#include <stddef.h> /* Needed to define size_t */
+
+#if defined(__ANDROID__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 4) && \
+ (__GNUC_GNU_INLINE__ == 1)
+typedef unsigned long long uint64_t;
+#include <sys/types.h>
+#endif
+
+/* Library calling convention spec. __cdecl and friends might be added here as
+ * required. */
+#define LINKSPEC_H
+#define LINKSPEC_CPP
+
+/* for doxygen the following docu parts must be separated */
+/** \var SCHAR
+ * Data type representing at least 1 byte signed integer on all supported
+ * platforms.
+ */
+/** \var UCHAR
+ * Data type representing at least 1 byte unsigned integer on all
+ * supported platforms.
+ */
+/** \var INT
+ * Data type representing at least 4 byte signed integer on all supported
+ * platforms.
+ */
+/** \var UINT
+ * Data type representing at least 4 byte unsigned integer on all
+ * supported platforms.
+ */
+/** \var LONG
+ * Data type representing 4 byte signed integer on all supported
+ * platforms.
+ */
+/** \var ULONG
+ * Data type representing 4 byte unsigned integer on all supported
+ * platforms.
+ */
+/** \var SHORT
+ * Data type representing 2 byte signed integer on all supported
+ * platforms.
+ */
+/** \var USHORT
+ * Data type representing 2 byte unsigned integer on all supported
+ * platforms.
+ */
+/** \var INT64
+ * Data type representing 8 byte signed integer on all supported
+ * platforms.
+ */
+/** \var UINT64
+ * Data type representing 8 byte unsigned integer on all supported
+ * platforms.
+ */
+/** \def SHORT_BITS
+ * Number of bits the data type short represents. sizeof() is not suited
+ * to get this info, because a byte is not always defined as 8 bits.
+ */
+/** \def CHAR_BITS
+ * Number of bits the data type char represents. sizeof() is not suited
+ * to get this info, because a byte is not always defined as 8 bits.
+ */
+/** \var INT_PCM
+ * Data type representing the width of input and output PCM samples.
+ */
+
+typedef signed int INT;
+typedef unsigned int UINT;
+#ifdef __LP64__
+/* force FDK long-datatypes to 4 byte */
+/* Use defines to avoid type alias problems on 64 bit machines. */
+#define LONG INT
+#define ULONG UINT
+#else /* __LP64__ */
+typedef signed long LONG;
+typedef unsigned long ULONG;
+#endif /* __LP64__ */
+typedef signed short SHORT;
+typedef unsigned short USHORT;
+typedef signed char SCHAR;
+typedef unsigned char UCHAR;
+
+#define SHORT_BITS 16
+#define CHAR_BITS 8
+
+/* Define 64 bit base integer type. */
+#ifdef _MSC_VER
+typedef __int64 INT64;
+typedef unsigned __int64 UINT64;
+#else
+typedef long long INT64;
+typedef unsigned long long UINT64;
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+#if ((defined(__i686__) || defined(__i586__) || defined(__i386__) || \
+ defined(__x86_64__)) || \
+ (defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)))) && \
+ !defined(FDK_ASSERT_ENABLE)
+#define FDK_ASSERT_ENABLE
+#endif
+
+#if defined(FDK_ASSERT_ENABLE)
+#include <assert.h>
+#define FDK_ASSERT(x) assert(x)
+#else
+#define FDK_ASSERT(ignore)
+#endif
+
+typedef SHORT INT_PCM;
+#define MAXVAL_PCM MAXVAL_SGL
+#define MINVAL_PCM MINVAL_SGL
+#define WAV_BITS 16
+#define SAMPLE_BITS 16
+#define SAMPLE_MAX ((INT_PCM)(((ULONG)1 << (SAMPLE_BITS - 1)) - 1))
+#define SAMPLE_MIN (~SAMPLE_MAX)
+
+/*!
+* \def RAM_ALIGN
+* Used to align memory as prefix before memory declaration. For example:
+ \code
+ RAM_ALIGN
+ int myArray[16];
+ \endcode
+
+ Note, that not all platforms support this mechanism. For example with TI
+compilers a preprocessor pragma is used, but to do something like
+
+ \code
+ #define RAM_ALIGN #pragma DATA_ALIGN(x)
+ \endcode
+
+ would require the preprocessor to process this line twice to fully resolve
+it. Hence, a fully platform-independant way to use alignment is not supported.
+
+* \def ALIGNMENT_DEFAULT
+* Default alignment in bytes.
+*/
+
+#define ALIGNMENT_DEFAULT 8
+
+/* RAM_ALIGN keyword causes memory alignment of global variables. */
+#if defined(_MSC_VER)
+#define RAM_ALIGN __declspec(align(ALIGNMENT_DEFAULT))
+#elif defined(__GNUC__)
+#define RAM_ALIGN __attribute__((aligned(ALIGNMENT_DEFAULT)))
+#else
+#define RAM_ALIGN
+#endif
+
+/*!
+ * \def RESTRICT
+ * The restrict keyword is supported by some platforms and RESTRICT maps
+ * to either the corresponding keyword on each platform or to void if the
+ * compiler does not provide such feature. It tells the compiler that a
+ * pointer points to memory that does not overlap with other memories pointed to
+ * by other pointers. If this keyword is used and the assumption of no
+ * overlap is not true the resulting code might crash.
+ *
+ * \def WORD_ALIGNED(x)
+ * Tells the compiler that pointer x is 16 bit aligned. It does not cause
+ * the address itself to be aligned, but serves as a hint to the optimizer. The
+ * alignment of the pointer must be guarranteed, if not the code might
+ * crash.
+ *
+ * \def DWORD_ALIGNED(x)
+ * Tells the compiler that pointer x is 32 bit aligned. It does not cause
+ * the address itself to be aligned, but serves as a hint to the optimizer. The
+ * alignment of the pointer must be guarranteed, if not the code might
+ * crash.
+ *
+ */
+#define RESTRICT
+#define WORD_ALIGNED(x) C_ALLOC_ALIGNED_CHECK2((const void *)(x), 2);
+#define DWORD_ALIGNED(x) C_ALLOC_ALIGNED_CHECK2((const void *)(x), 4);
+
+/*-----------------------------------------------------------------------------------
+ * ALIGN_SIZE
+ *-----------------------------------------------------------------------------------*/
+/*!
+ * \brief This macro aligns a given value depending on ::ALIGNMENT_DEFAULT.
+ *
+ * For example if #ALIGNMENT_DEFAULT equals 8, then:
+ * - ALIGN_SIZE(3) returns 8
+ * - ALIGN_SIZE(8) returns 8
+ * - ALIGN_SIZE(9) returns 16
+ */
+#define ALIGN_SIZE(a) \
+ ((a) + (((INT)ALIGNMENT_DEFAULT - ((size_t)(a) & (ALIGNMENT_DEFAULT - 1))) & \
+ (ALIGNMENT_DEFAULT - 1)))
+
+/*!
+ * \brief This macro aligns a given address depending on ::ALIGNMENT_DEFAULT.
+ */
+#define ALIGN_PTR(a) \
+ ((void *)((unsigned char *)(a) + \
+ ((((INT)ALIGNMENT_DEFAULT - \
+ ((size_t)(a) & (ALIGNMENT_DEFAULT - 1))) & \
+ (ALIGNMENT_DEFAULT - 1)))))
+
+/* Alignment macro for libSYS heap implementation */
+#define ALIGNMENT_EXTRES (ALIGNMENT_DEFAULT)
+#define ALGN_SIZE_EXTRES(a) \
+ ((a) + (((INT)ALIGNMENT_EXTRES - ((INT)(a) & (ALIGNMENT_EXTRES - 1))) & \
+ (ALIGNMENT_EXTRES - 1)))
+
+/*!
+ * \def FDK_FORCEINLINE
+ * Sometimes compiler do not do what they are told to do, and in case of
+ * inlining some additional command might be necessary depending on the
+ * platform.
+ *
+ * \def FDK_INLINE
+ * Defines how the compiler is told to inline stuff.
+ */
+#ifndef FDK_FORCEINLINE
+#if defined(__GNUC__) && !defined(__SDE_MIPS__)
+#define FDK_FORCEINLINE inline __attribute((always_inline))
+#else
+#define FDK_FORCEINLINE inline
+#endif
+#endif
+
+#define FDK_INLINE static inline
+
+/*!
+ * \def LNK_SECTION_DATA_L1
+ * The LNK_SECTION_* defines allow memory to be drawn from specific memory
+ * sections. Used as prefix before variable declaration.
+ *
+ * \def LNK_SECTION_DATA_L2
+ * See ::LNK_SECTION_DATA_L1
+ * \def LNK_SECTION_L1_DATA_A
+ * See ::LNK_SECTION_DATA_L1
+ * \def LNK_SECTION_L1_DATA_B
+ * See ::LNK_SECTION_DATA_L1
+ * \def LNK_SECTION_CONSTDATA_L1
+ * See ::LNK_SECTION_DATA_L1
+ * \def LNK_SECTION_CONSTDATA
+ * See ::LNK_SECTION_DATA_L1
+ * \def LNK_SECTION_CODE_L1
+ * See ::LNK_SECTION_DATA_L1
+ * \def LNK_SECTION_CODE_L2
+ * See ::LNK_SECTION_DATA_L1
+ * \def LNK_SECTION_INITCODE
+ * See ::LNK_SECTION_DATA_L1
+ */
+/**************************************************
+ * Code Section macros
+ **************************************************/
+#define LNK_SECTION_CODE_L1
+#define LNK_SECTION_CODE_L2
+#define LNK_SECTION_INITCODE
+
+/* Memory section macros. */
+
+/* default fall back */
+#define LNK_SECTION_DATA_L1
+#define LNK_SECTION_DATA_L2
+#define LNK_SECTION_CONSTDATA
+#define LNK_SECTION_CONSTDATA_L1
+
+#define LNK_SECTION_L1_DATA_A
+#define LNK_SECTION_L1_DATA_B
+
+/**************************************************
+ * Macros regarding static code analysis
+ **************************************************/
+#ifdef __cplusplus
+#if !defined(__has_cpp_attribute)
+#define __has_cpp_attribute(x) 0
+#endif
+#if defined(__clang__) && __has_cpp_attribute(clang::fallthrough)
+#define FDK_FALLTHROUGH [[clang::fallthrough]]
+#endif
+#endif
+
+#ifndef FDK_FALLTHROUGH
+#if defined(__GNUC__) && (__GNUC__ >= 7)
+#define FDK_FALLTHROUGH __attribute__((fallthrough))
+#else
+#define FDK_FALLTHROUGH
+#endif
+#endif
+
+#ifdef _MSC_VER
+/*
+ * Sometimes certain features are excluded from compilation and therefore the
+ * warning 4065 may occur: "switch statement contains 'default' but no 'case'
+ * labels" We consider this warning irrelevant and disable it.
+ */
+#pragma warning(disable : 4065)
+#endif
+
+#endif /* MACHINE_TYPE_H */
diff --git a/fdk-aac/libSYS/include/syslib_channelMapDescr.h b/fdk-aac/libSYS/include/syslib_channelMapDescr.h
new file mode 100644
index 0000000..375a24d
--- /dev/null
+++ b/fdk-aac/libSYS/include/syslib_channelMapDescr.h
@@ -0,0 +1,202 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/************************* System integration library **************************
+
+ Author(s): Thomas Dietzen
+
+ Description:
+
+*******************************************************************************/
+
+/** \file syslib_channelMapDescr.h
+ * \brief Function and structure declarations for the channel map descriptor implementation.
+ */
+
+#ifndef SYSLIB_CHANNELMAPDESCR_H
+#define SYSLIB_CHANNELMAPDESCR_H
+
+#include "machine_type.h"
+
+/**
+ * \brief Contains information needed for a single channel map.
+ */
+typedef struct {
+ const UCHAR*
+ pChannelMap; /*!< Actual channel mapping for one single configuration. */
+ UCHAR numChannels; /*!< The number of channels for the channel map which is
+ the maximum used channel index+1. */
+} CHANNEL_MAP_INFO;
+
+/**
+ * \brief This is the main data struct. It contains the mapping for all
+ * channel configurations such as administration information.
+ *
+ * CAUTION: Do not access this structure directly from a algorithm specific
+ * library. Always use one of the API access functions below!
+ */
+typedef struct {
+ const CHANNEL_MAP_INFO* pMapInfoTab; /*!< Table of channel maps. */
+ UINT mapInfoTabLen; /*!< Length of the channel map table array. */
+ UINT fPassThrough; /*!< Flag that defines whether the specified mapping shall
+ be applied (value: 0) or the input just gets passed
+ through (MPEG mapping). */
+} FDK_channelMapDescr;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Initialize a given channel map descriptor.
+ *
+ * \param pMapDescr Pointer to a channel map descriptor to be initialized.
+ * \param pMapInfoTab Table of channel maps to initizalize the descriptor
+ with.
+ * If a NULL pointer is given a default table for
+ WAV-like mapping will be used.
+ * \param mapInfoTabLen Length of the channel map table array (pMapInfoTab).
+ If a zero length is given a default table for WAV-like mapping will be used.
+ * \param fPassThrough If the flag is set the reordering (given by
+ pMapInfoTab) will be bypassed.
+ */
+void FDK_chMapDescr_init(FDK_channelMapDescr* const pMapDescr,
+ const CHANNEL_MAP_INFO* const pMapInfoTab,
+ const UINT mapInfoTabLen, const UINT fPassThrough);
+
+/**
+ * \brief Change the channel reordering state of a given channel map
+ * descriptor.
+ *
+ * \param pMapDescr Pointer to a (initialized) channel map descriptor.
+ * \param fPassThrough If the flag is set the reordering (given by
+ * pMapInfoTab) will be bypassed.
+ * \return Value unequal to zero if set operation was not
+ * successful. And zero on success.
+ */
+int FDK_chMapDescr_setPassThrough(FDK_channelMapDescr* const pMapDescr,
+ UINT fPassThrough);
+
+/**
+ * \brief Get the mapping value for a specific channel and map index.
+ *
+ * \param pMapDescr Pointer to channel map descriptor.
+ * \param chIdx Channel index.
+ * \param mapIdx Mapping index (corresponding to the channel configuration
+ * index).
+ * \return Mapping value.
+ */
+UCHAR FDK_chMapDescr_getMapValue(const FDK_channelMapDescr* const pMapDescr,
+ const UCHAR chIdx, const UINT mapIdx);
+
+/**
+ * \brief Evaluate whether channel map descriptor is reasonable or not.
+ *
+ * \param pMapDescr Pointer to channel map descriptor.
+ * \return Value unequal to zero if descriptor is valid, otherwise
+ * zero.
+ */
+int FDK_chMapDescr_isValid(const FDK_channelMapDescr* const pMapDescr);
+
+/**
+ * Extra variables for setting up Wg4 channel mapping.
+ */
+extern const CHANNEL_MAP_INFO FDK_mapInfoTabWg4[];
+extern const UINT FDK_mapInfoTabLenWg4;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined(SYSLIB_CHANNELMAPDESCR_H) */
diff --git a/fdk-aac/libSYS/src/genericStds.cpp b/fdk-aac/libSYS/src/genericStds.cpp
new file mode 100644
index 0000000..f98d0a9
--- /dev/null
+++ b/fdk-aac/libSYS/src/genericStds.cpp
@@ -0,0 +1,419 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/************************* System integration library **************************
+
+ Author(s):
+
+ Description: - Generic memory, stdio, string, etc. function wrappers or
+ builtins.
+ - OS dependant function wrappers.
+
+*******************************************************************************/
+
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#define __GENERICSTDS_CPP__
+
+#include "genericStds.h"
+
+/* library info */
+#define SYS_LIB_VL0 2
+#define SYS_LIB_VL1 0
+#define SYS_LIB_VL2 0
+#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_TIME __TIME__
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+/***************************************************************
+ * memory allocation monitoring variables
+ ***************************************************************/
+
+/* Include OS/System specific implementations. */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+void FDKprintf(const char *szFmt, ...) {
+ va_list ap;
+ va_start(ap, szFmt);
+ vprintf(szFmt, ap);
+ va_end(ap);
+}
+
+void FDKprintfErr(const char *szFmt, ...) {
+ va_list ap;
+ va_start(ap, szFmt);
+ vfprintf(stderr, szFmt, ap);
+ va_end(ap);
+}
+
+int FDKgetchar(void) { return getchar(); }
+
+INT FDKfprintf(FDKFILE *stream, const char *format, ...) {
+ INT chars = 0;
+ va_list ap;
+ va_start(ap, format);
+ chars += vfprintf((FILE *)stream, format, ap);
+ va_end(ap);
+ return chars;
+}
+
+INT FDKsprintf(char *str, const char *format, ...) {
+ INT chars = 0;
+ va_list ap;
+ va_start(ap, format);
+ chars += vsprintf(str, format, ap);
+ va_end(ap);
+ return chars;
+}
+
+/************************************************************************************************/
+
+/************************************************************************************************/
+
+char *FDKstrchr(char *s, INT c) { return strchr(s, c); }
+const char *FDKstrstr(const char *haystack, const char *needle) {
+ return strstr(haystack, needle);
+}
+char *FDKstrcpy(char *dest, const char *src) { return strcpy(dest, src); }
+char *FDKstrncpy(char *dest, const char *src, UINT n) {
+ return strncpy(dest, src, n);
+}
+
+/*************************************************************************
+ * DYNAMIC MEMORY management (heap)
+ *************************************************************************/
+
+void *FDKcalloc(const UINT n, const UINT size) {
+ void *ptr;
+
+ ptr = calloc(n, size);
+
+ return ptr;
+}
+
+void *FDKmalloc(const UINT size) {
+ void *ptr;
+
+ ptr = malloc(size);
+
+ return ptr;
+}
+
+void FDKfree(void *ptr) { free((INT *)ptr); }
+
+void *FDKaalloc(const UINT size, const UINT alignment) {
+ void *addr, *result = NULL;
+ addr = FDKcalloc(1, size + alignment +
+ (UINT)sizeof(void *)); /* Malloc and clear memory. */
+
+ if (addr != NULL) {
+ result = ALIGN_PTR((unsigned char *)addr +
+ sizeof(void *)); /* Get aligned memory base address. */
+ *(((void **)result) - 1) = addr; /* Save malloc'ed memory pointer. */
+ C_ALLOC_ALIGNED_REGISTER(result, size);
+ }
+
+ return result; /* Return aligned address. */
+}
+
+void FDKafree(void *ptr) {
+ void *addr;
+ addr = *(((void **)ptr) - 1); /* Get pointer to malloc'ed memory. */
+
+ C_ALLOC_ALIGNED_UNREGISTER(ptr);
+
+ FDKfree(addr); /* Free malloc'ed memory area. */
+}
+
+/*--------------------------------------------------------------------------*
+ * DATA MEMORY L1/L2 (fallback)
+ *--------------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------------*
+ * FDKcalloc_L
+ *--------------------------------------------------------------------------*/
+void *FDKcalloc_L(const UINT dim, const UINT size, MEMORY_SECTION s) {
+ return FDKcalloc(dim, size);
+}
+
+void FDKfree_L(void *p) { FDKfree(p); }
+
+void *FDKaalloc_L(const UINT size, const UINT alignment, MEMORY_SECTION s) {
+ void *addr, *result = NULL;
+ addr = FDKcalloc_L(1, size + alignment + (UINT)sizeof(void *),
+ s); /* Malloc and clear memory. */
+
+ if (addr != NULL) {
+ result = ALIGN_PTR((unsigned char *)addr +
+ sizeof(void *)); /* Get aligned memory base address. */
+ *(((void **)result) - 1) = addr; /* Save malloc'ed memory pointer. */
+ C_ALLOC_ALIGNED_REGISTER(result, size);
+ }
+
+ return result; /* Return aligned address. */
+}
+
+void FDKafree_L(void *ptr) {
+ void *addr;
+
+ addr = *(((void **)ptr) - 1); /* Get pointer to malloc'ed memory. */
+
+ C_ALLOC_ALIGNED_UNREGISTER(ptr);
+
+ FDKfree_L(addr); /* Free malloc'ed memory area. */
+}
+
+/*---------------------------------------------------------------------------------------
+ * FUNCTION: FDKmemcpy
+ * DESCRIPTION: - copies memory from "src" to "dst" with length "size" bytes
+ * - compiled with FDK_DEBUG will give you warnings
+ *---------------------------------------------------------------------------------------*/
+void FDKmemcpy(void *dst, const void *src, const UINT size) {
+ /* -- check for overlapping memory areas -- */
+ FDK_ASSERT(((const unsigned char *)dst - (const unsigned char *)src) >=
+ (ptrdiff_t)size ||
+ ((const unsigned char *)src - (const unsigned char *)dst) >=
+ (ptrdiff_t)size);
+
+ /* do the copy */
+ memcpy(dst, src, size);
+}
+
+void FDKmemmove(void *dst, const void *src, const UINT size) {
+ memmove(dst, src, size);
+}
+
+void FDKmemset(void *memPtr, const INT value, const UINT size) {
+ memset(memPtr, value, size);
+}
+
+void FDKmemclear(void *memPtr, const UINT size) { FDKmemset(memPtr, 0, size); }
+
+UINT FDKstrlen(const char *s) { return (UINT)strlen(s); }
+
+/* Compare function wrappers */
+INT FDKmemcmp(const void *s1, const void *s2, const UINT size) {
+ return memcmp(s1, s2, size);
+}
+INT FDKstrcmp(const char *s1, const char *s2) { return strcmp(s1, s2); }
+INT FDKstrncmp(const char *s1, const char *s2, const UINT size) {
+ return strncmp(s1, s2, size);
+}
+
+int IS_LITTLE_ENDIAN(void) {
+ int __dummy = 1;
+ return (*((UCHAR *)(&(__dummy))));
+}
+
+UINT TO_LITTLE_ENDIAN(UINT val) {
+ return IS_LITTLE_ENDIAN()
+ ? val
+ : (((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24));
+}
+
+/* ==================== FILE I/O ====================== */
+
+FDKFILE *FDKfopen(const char *filename, const char *mode) {
+ return fopen(filename, mode);
+}
+INT FDKfclose(FDKFILE *fp) { return fclose((FILE *)fp); }
+INT FDKfseek(FDKFILE *fp, LONG OFFSET, int WHENCE) {
+ return fseek((FILE *)fp, OFFSET, WHENCE);
+}
+INT FDKftell(FDKFILE *fp) { return ftell((FILE *)fp); }
+INT FDKfflush(FDKFILE *fp) { return fflush((FILE *)fp); }
+const INT FDKSEEK_SET = SEEK_SET;
+const INT FDKSEEK_CUR = SEEK_CUR;
+const INT FDKSEEK_END = SEEK_END;
+
+UINT FDKfwrite(const void *ptrf, INT size, UINT nmemb, FDKFILE *fp) {
+ return (UINT)fwrite(ptrf, size, nmemb, (FILE *)fp);
+}
+UINT FDKfread(void *dst, INT size, UINT nmemb, FDKFILE *fp) {
+ return (UINT)fread(dst, size, nmemb, (FILE *)fp);
+}
+char *FDKfgets(void *dst, INT size, FDKFILE *fp) {
+ return fgets((char *)dst, size, (FILE *)fp);
+}
+void FDKrewind(FDKFILE *fp) { FDKfseek((FILE *)fp, 0, FDKSEEK_SET); }
+
+UINT FDKfwrite_EL(const void *ptrf, INT size, UINT nmemb, FDKFILE *fp) {
+ if (IS_LITTLE_ENDIAN()) {
+ FDKfwrite(ptrf, size, nmemb, fp);
+ } else {
+ UINT n;
+ INT s;
+
+ const UCHAR *ptr = (const UCHAR *)ptrf;
+
+ for (n = 0; n < nmemb; n++) {
+ for (s = size - 1; s >= 0; s--) {
+ FDKfwrite(ptr + s, 1, 1, fp);
+ }
+ ptr = ptr + size;
+ }
+ }
+ return nmemb;
+}
+
+UINT FDKfread_EL(void *dst, INT size, UINT nmemb, FDKFILE *fp) {
+ UINT n, s0, s1, err;
+ UCHAR tmp, *ptr;
+ UCHAR tmp24[3];
+
+ /* Enforce alignment of 24 bit data. */
+ if (size == 3) {
+ ptr = (UCHAR *)dst;
+ for (n = 0; n < nmemb; n++) {
+ if ((err = FDKfread(tmp24, 1, 3, fp)) != 3) {
+ return err;
+ }
+ *ptr++ = tmp24[0];
+ *ptr++ = tmp24[1];
+ *ptr++ = tmp24[2];
+ /* Sign extension */
+ if (tmp24[2] & 0x80) {
+ *ptr++ = 0xff;
+ } else {
+ *ptr++ = 0;
+ }
+ }
+ err = nmemb;
+ size = sizeof(LONG);
+ } else {
+ if ((err = FDKfread(dst, size, nmemb, fp)) != nmemb) {
+ return err;
+ }
+ }
+ if (!IS_LITTLE_ENDIAN() && size > 1) {
+ ptr = (UCHAR *)dst;
+ for (n = 0; n < nmemb; n++) {
+ for (s0 = 0, s1 = size - 1; s0 < s1; s0++, s1--) {
+ tmp = ptr[s0];
+ ptr[s0] = ptr[s1];
+ ptr[s1] = tmp;
+ }
+ ptr += size;
+ }
+ }
+ return err;
+}
+
+INT FDKfeof(FDKFILE *fp) { return feof((FILE *)fp); }
+
+/* Global initialization/cleanup */
+
+void FDKprintDisclaimer(void) {
+ FDKprintf(
+ "This program is protected by copyright law and international treaties.\n"
+ "Any reproduction or distribution of this program, or any portion\n"
+ "of it, may result in severe civil and criminal penalties, and will be\n"
+ "prosecuted to the maximum extent possible under law.\n\n");
+}
diff --git a/fdk-aac/libSYS/src/syslib_channelMapDescr.cpp b/fdk-aac/libSYS/src/syslib_channelMapDescr.cpp
new file mode 100644
index 0000000..d22a30d
--- /dev/null
+++ b/fdk-aac/libSYS/src/syslib_channelMapDescr.cpp
@@ -0,0 +1,315 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 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
+----------------------------------------------------------------------------- */
+
+/************************* System integration library **************************
+
+ Author(s): Thomas Dietzen
+
+ Description:
+
+*******************************************************************************/
+
+/** \file syslib_channelMapDescr.cpp
+ * \brief Implementation of routines that handle the channel map descriptor.
+ */
+
+#include "syslib_channelMapDescr.h"
+
+#define DFLT_CH_MAP_TAB_LEN \
+ (15) /* Length of the default channel map info table. */
+
+/**
+ * \brief The following arrays provide a channel map for each channel config (0
+ * to 14).
+ *
+ * The i-th channel will be mapped to the postion a[i-1]+1
+ * with i>0 and a[] is one of the following mapping arrays.
+ */
+static const UCHAR mapFallback[] = {0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23};
+static const UCHAR mapCfg1[] = {0, 1};
+static const UCHAR mapCfg2[] = {0, 1};
+static const UCHAR mapCfg3[] = {2, 0, 1};
+static const UCHAR mapCfg4[] = {2, 0, 1, 3};
+static const UCHAR mapCfg5[] = {2, 0, 1, 3, 4};
+static const UCHAR mapCfg6[] = {2, 0, 1, 4, 5, 3};
+static const UCHAR mapCfg7[] = {2, 6, 7, 0, 1, 4, 5, 3};
+static const UCHAR mapCfg11[] = {2, 0, 1, 4, 5, 6, 3};
+static const UCHAR mapCfg12[] = {2, 0, 1, 6, 7, 4, 5, 3};
+static const UCHAR mapCfg13[] = {2, 6, 7, 0, 1, 10, 11, 4,
+ 5, 8, 3, 9, 14, 12, 13, 18,
+ 19, 15, 16, 17, 20, 21, 22, 23};
+static const UCHAR mapCfg14[] = {2, 0, 1, 4, 5, 3, 6, 7};
+
+/**
+ * \brief Default table comprising channel map information for each channel
+ * config (0 to 14).
+ */
+static const CHANNEL_MAP_INFO mapInfoTabDflt[DFLT_CH_MAP_TAB_LEN] =
+ {/* chCfg, map, numCh */
+ /* 0 */ {mapFallback, 24},
+ /* 1 */ {mapCfg1, 2},
+ /* 2 */ {mapCfg2, 2},
+ /* 3 */ {mapCfg3, 3},
+ /* 4 */ {mapCfg4, 4},
+ /* 5 */ {mapCfg5, 5},
+ /* 6 */ {mapCfg6, 6},
+ /* 7 */ {mapCfg7, 8},
+ /* 8 */ {mapFallback, 24},
+ /* 9 */ {mapFallback, 24},
+ /* 10 */ {mapFallback, 24},
+ /* 11 */ {mapCfg11, 7},
+ /* 12 */ {mapCfg12, 8},
+ /* 13 */ {mapCfg13, 24},
+ /* 14 */ {mapCfg14, 8}};
+
+
+static const UCHAR mapWg4Cfg1[] = {0, 1};
+static const UCHAR mapWg4Cfg2[] = {0, 1};
+static const UCHAR mapWg4Cfg3[] = {2, 0, 1};
+static const UCHAR mapWg4Cfg4[] = {3, 0, 1, 2};
+static const UCHAR mapWg4Cfg5[] = {4, 0, 1, 2, 3};
+static const UCHAR mapWg4Cfg6[] = {4, 0, 1, 2, 3, 5};
+static const UCHAR mapWg4Cfg7[] = {6, 0, 1, 2, 3, 4, 5, 7};
+static const UCHAR mapWg4Cfg14[] = {6, 0, 1, 2, 3, 4, 5, 7};
+
+const CHANNEL_MAP_INFO FDK_mapInfoTabWg4[] =
+ {/* chCfg, map, numCh */
+ /* 0 */ {mapFallback, 24},
+ /* 1 */ {mapWg4Cfg1, 2},
+ /* 2 */ {mapWg4Cfg2, 2},
+ /* 3 */ {mapWg4Cfg3, 3},
+ /* 4 */ {mapWg4Cfg4, 4},
+ /* 5 */ {mapWg4Cfg5, 5},
+ /* 6 */ {mapWg4Cfg6, 6},
+ /* 7 */ {mapWg4Cfg7, 8},
+ /* 8 */ {mapFallback, 24},
+ /* 9 */ {mapFallback, 24},
+ /* 10 */ {mapFallback, 24},
+ /* 11 */ {mapFallback, 24}, // Unhandled for Wg4 yet
+ /* 12 */ {mapFallback, 24}, // Unhandled for Wg4 yet
+ /* 13 */ {mapFallback, 24}, // Unhandled for Wg4 yet
+ /* 14 */ {mapFallback, 24}}; // Unhandled for Wg4 yet
+
+const UINT FDK_mapInfoTabLenWg4 = sizeof(FDK_mapInfoTabWg4)/sizeof(FDK_mapInfoTabWg4[0]);
+
+
+/**
+ * Get the mapping value for a specific channel and map index.
+ */
+UCHAR FDK_chMapDescr_getMapValue(const FDK_channelMapDescr* const pMapDescr,
+ const UCHAR chIdx, const UINT mapIdx) {
+ UCHAR mapValue = chIdx; /* Pass through by default. */
+
+ FDK_ASSERT(pMapDescr != NULL);
+
+ if ((pMapDescr->fPassThrough == 0) && (pMapDescr->pMapInfoTab != NULL) &&
+ (pMapDescr->mapInfoTabLen > mapIdx)) { /* Nest sanity check to avoid
+ possible memory access
+ violation. */
+ if (chIdx < pMapDescr->pMapInfoTab[mapIdx].numChannels) {
+ mapValue = pMapDescr->pMapInfoTab[mapIdx].pChannelMap[chIdx];
+ }
+ }
+ return mapValue;
+}
+
+/**
+ * \brief Evaluate whether single channel map is reasonable or not.
+ *
+ * \param pMapInfo Pointer to channel map.
+ * \return Value unequal to zero if map is valid, otherwise zero.
+ */
+static int fdk_chMapDescr_isValidMap(const CHANNEL_MAP_INFO* const pMapInfo) {
+ int result = 1;
+ UINT i;
+
+ if (pMapInfo == NULL) {
+ result = 0;
+ } else {
+ UINT numChannels = pMapInfo->numChannels;
+
+ /* Check for all map values if they are inside the range 0 to numChannels-1
+ * and unique. */
+ if (numChannels < 32) { /* Optimized version for less than 32 channels.
+ Needs only one loop. */
+ UINT mappedChMask = 0x0;
+ for (i = 0; i < numChannels; i += 1) {
+ mappedChMask |= 1 << pMapInfo->pChannelMap[i];
+ }
+ if (mappedChMask != (((UINT)1 << numChannels) - 1)) {
+ result = 0;
+ }
+ } else { /* General case that can handle all number of channels but needs
+ one more loop. */
+ for (i = 0; (i < numChannels) && result; i += 1) {
+ UINT j;
+ UCHAR value0 = pMapInfo->pChannelMap[i];
+
+ if (value0 > numChannels - 1) { /* out of range? */
+ result = 0;
+ }
+ for (j = numChannels - 1; (j > i) && result; j -= 1) {
+ if (value0 == pMapInfo->pChannelMap[j]) { /* not unique */
+ result = 0;
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+/**
+ * Evaluate whether channel map descriptor is reasonable or not.
+ */
+int FDK_chMapDescr_isValid(const FDK_channelMapDescr* const pMapDescr) {
+ int result = 0;
+ UINT i;
+
+ if (pMapDescr != NULL) {
+ result = 1;
+ for (i = 0; (i < pMapDescr->mapInfoTabLen) && result; i += 1) {
+ if (!fdk_chMapDescr_isValidMap(&pMapDescr->pMapInfoTab[i])) {
+ result = 0;
+ }
+ }
+ }
+ return result;
+}
+
+/**
+ * Initialize the complete channel map descriptor.
+ */
+void FDK_chMapDescr_init(FDK_channelMapDescr* const pMapDescr,
+ const CHANNEL_MAP_INFO* const pMapInfoTab,
+ const UINT mapInfoTabLen, const UINT fPassThrough) {
+ if (pMapDescr != NULL) {
+ int useDefaultTab = 1;
+
+ pMapDescr->fPassThrough = (fPassThrough == 0) ? 0 : 1;
+
+ if ((pMapInfoTab != NULL) && (mapInfoTabLen > 0)) {
+ /* Set the valid custom mapping table. */
+ pMapDescr->pMapInfoTab = pMapInfoTab;
+ pMapDescr->mapInfoTabLen = mapInfoTabLen;
+ /* Validate the complete descriptor. */
+ useDefaultTab = (FDK_chMapDescr_isValid(pMapDescr) == 0) ? 1 : 0;
+ }
+ if (useDefaultTab != 0) {
+ /* Set default table. */
+ pMapDescr->pMapInfoTab = mapInfoTabDflt;
+ pMapDescr->mapInfoTabLen = DFLT_CH_MAP_TAB_LEN;
+ }
+ }
+}
+
+/**
+ * Set channel mapping bypass flag in a given channel map descriptor.
+ */
+int FDK_chMapDescr_setPassThrough(FDK_channelMapDescr* const pMapDescr,
+ UINT fPassThrough) {
+ int err = 1;
+
+ if (pMapDescr != NULL) {
+ if ((pMapDescr->pMapInfoTab != NULL) && (pMapDescr->mapInfoTabLen > 0)) {
+ pMapDescr->fPassThrough = (fPassThrough == 0) ? 0 : 1;
+ err = 0;
+ }
+ }
+
+ return err;
+}
diff --git a/fdk-aac/m4/.gitkeep b/fdk-aac/m4/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/fdk-aac/m4/.gitkeep
diff --git a/fdk-aac/wavreader.c b/fdk-aac/wavreader.c
new file mode 100644
index 0000000..898eb9c
--- /dev/null
+++ b/fdk-aac/wavreader.c
@@ -0,0 +1,193 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 2009 Martin Storsjo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ * -------------------------------------------------------------------
+ */
+
+#include "wavreader.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#define TAG(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
+
+struct wav_reader {
+ FILE *wav;
+ uint32_t data_length;
+
+ int format;
+ int sample_rate;
+ int bits_per_sample;
+ int channels;
+ int byte_rate;
+ int block_align;
+
+ int streamed;
+};
+
+static uint32_t read_tag(struct wav_reader* wr) {
+ uint32_t tag = 0;
+ tag = (tag << 8) | fgetc(wr->wav);
+ tag = (tag << 8) | fgetc(wr->wav);
+ tag = (tag << 8) | fgetc(wr->wav);
+ tag = (tag << 8) | fgetc(wr->wav);
+ return tag;
+}
+
+static uint32_t read_int32(struct wav_reader* wr) {
+ uint32_t value = 0;
+ value |= fgetc(wr->wav) << 0;
+ value |= fgetc(wr->wav) << 8;
+ value |= fgetc(wr->wav) << 16;
+ value |= fgetc(wr->wav) << 24;
+ return value;
+}
+
+static uint16_t read_int16(struct wav_reader* wr) {
+ uint16_t value = 0;
+ value |= fgetc(wr->wav) << 0;
+ value |= fgetc(wr->wav) << 8;
+ return value;
+}
+
+static void skip(FILE *f, int n) {
+ int i;
+ for (i = 0; i < n; i++)
+ fgetc(f);
+}
+
+void* wav_read_open(const char *filename) {
+ struct wav_reader* wr = (struct wav_reader*) malloc(sizeof(*wr));
+ long data_pos = 0;
+ memset(wr, 0, sizeof(*wr));
+
+ if (!strcmp(filename, "-"))
+ wr->wav = stdin;
+ else
+ wr->wav = fopen(filename, "rb");
+ if (wr->wav == NULL) {
+ free(wr);
+ return NULL;
+ }
+
+ while (1) {
+ uint32_t tag, tag2, length;
+ tag = read_tag(wr);
+ if (feof(wr->wav))
+ break;
+ length = read_int32(wr);
+ if (!length || length >= 0x7fff0000) {
+ wr->streamed = 1;
+ length = ~0;
+ }
+ if (tag != TAG('R', 'I', 'F', 'F') || length < 4) {
+ fseek(wr->wav, length, SEEK_CUR);
+ continue;
+ }
+ tag2 = read_tag(wr);
+ length -= 4;
+ if (tag2 != TAG('W', 'A', 'V', 'E')) {
+ fseek(wr->wav, length, SEEK_CUR);
+ continue;
+ }
+ // RIFF chunk found, iterate through it
+ while (length >= 8) {
+ uint32_t subtag, sublength;
+ subtag = read_tag(wr);
+ if (feof(wr->wav))
+ break;
+ sublength = read_int32(wr);
+ length -= 8;
+ if (length < sublength)
+ break;
+ if (subtag == TAG('f', 'm', 't', ' ')) {
+ if (sublength < 16) {
+ // Insufficient data for 'fmt '
+ break;
+ }
+ wr->format = read_int16(wr);
+ wr->channels = read_int16(wr);
+ wr->sample_rate = read_int32(wr);
+ wr->byte_rate = read_int32(wr);
+ wr->block_align = read_int16(wr);
+ wr->bits_per_sample = read_int16(wr);
+ if (wr->format == 0xfffe) {
+ if (sublength < 28) {
+ // Insufficient data for waveformatex
+ break;
+ }
+ skip(wr->wav, 8);
+ wr->format = read_int32(wr);
+ skip(wr->wav, sublength - 28);
+ } else {
+ skip(wr->wav, sublength - 16);
+ }
+ } else if (subtag == TAG('d', 'a', 't', 'a')) {
+ data_pos = ftell(wr->wav);
+ wr->data_length = sublength;
+ if (!wr->data_length || wr->streamed) {
+ wr->streamed = 1;
+ return wr;
+ }
+ fseek(wr->wav, sublength, SEEK_CUR);
+ } else {
+ skip(wr->wav, sublength);
+ }
+ length -= sublength;
+ }
+ if (length > 0) {
+ // Bad chunk?
+ fseek(wr->wav, length, SEEK_CUR);
+ }
+ }
+ fseek(wr->wav, data_pos, SEEK_SET);
+ return wr;
+}
+
+void wav_read_close(void* obj) {
+ struct wav_reader* wr = (struct wav_reader*) obj;
+ if (wr->wav != stdin)
+ fclose(wr->wav);
+ free(wr);
+}
+
+int wav_get_header(void* obj, int* format, int* channels, int* sample_rate, int* bits_per_sample, unsigned int* data_length) {
+ struct wav_reader* wr = (struct wav_reader*) obj;
+ if (format)
+ *format = wr->format;
+ if (channels)
+ *channels = wr->channels;
+ if (sample_rate)
+ *sample_rate = wr->sample_rate;
+ if (bits_per_sample)
+ *bits_per_sample = wr->bits_per_sample;
+ if (data_length)
+ *data_length = wr->data_length;
+ return wr->format && wr->sample_rate;
+}
+
+int wav_read_data(void* obj, unsigned char* data, unsigned int length) {
+ struct wav_reader* wr = (struct wav_reader*) obj;
+ int n;
+ if (wr->wav == NULL)
+ return -1;
+ if (length > wr->data_length && !wr->streamed)
+ length = wr->data_length;
+ n = fread(data, 1, length, wr->wav);
+ wr->data_length -= length;
+ return n;
+}
+
diff --git a/fdk-aac/wavreader.h b/fdk-aac/wavreader.h
new file mode 100644
index 0000000..57a13ff
--- /dev/null
+++ b/fdk-aac/wavreader.h
@@ -0,0 +1,37 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 2009 Martin Storsjo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ * -------------------------------------------------------------------
+ */
+
+#ifndef WAVREADER_H
+#define WAVREADER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void* wav_read_open(const char *filename);
+void wav_read_close(void* obj);
+
+int wav_get_header(void* obj, int* format, int* channels, int* sample_rate, int* bits_per_sample, unsigned int* data_length);
+int wav_read_data(void* obj, unsigned char* data, unsigned int length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/fdk-aac/win32/getopt.h b/fdk-aac/win32/getopt.h
new file mode 100644
index 0000000..7402521
--- /dev/null
+++ b/fdk-aac/win32/getopt.h
@@ -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__) */