Combined Workspace for Encoder and Decoder (#33)

* Combined Workspace for Encoder and Decoder

* Addressed review comments and some minor edits

---------

Co-authored-by: Divya B M <100655@ittiam.com>
This commit is contained in:
bmdivya100655 2023-05-22 20:11:52 +05:30 • committed by GitHub
parent 48a1ff21ba
commit 088122e748
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
241 changed files with 67560 additions and 3033 deletions

View file

@ -341,4 +341,140 @@ cc_library_static {
},
}
subdirs = ["test"]
cc_library_static {
name: "libxaacenc",
vendor_available: true,
host_supported: true,
cflags: [
"-O3",
],
export_include_dirs: [
"common",
"encoder",
],
srcs: [
"common/ixheaac_esbr_fft.c",
"common/ixheaac_esbr_rom.c",
"common/ixheaac_fft_ifft_32x32_rom.c",
"encoder/iusace_bitbuffer.c",
"encoder/iusace_fft.c",
"encoder/iusace_rom.c",
"encoder/ixheaace_adjust_threshold.c",
"encoder/ixheaace_api.c",
"encoder/ixheaace_asc_write.c",
"encoder/ixheaace_basic_ops.c",
"encoder/ixheaace_bitbuffer.c",
"encoder/ixheaace_bitbuffer_hp.c",
"encoder/ixheaace_bits_count.c",
"encoder/ixheaace_block_switch.c",
"encoder/ixheaace_calc_ms_band_energy.c",
"encoder/ixheaace_channel_map.c",
"encoder/ixheaace_common_rom.c",
"encoder/ixheaace_dynamic_bits.c",
"encoder/ixheaace_enc_init.c",
"encoder/ixheaace_enc_main.c",
"encoder/ixheaace_fft.c",
"encoder/ixheaace_group_data.c",
"encoder/ixheaace_huffman_rom.c",
"encoder/ixheaace_hybrid.c",
"encoder/ixheaace_hybrid_init.c",
"encoder/ixheaace_interface.c",
"encoder/ixheaace_mdct_480.c",
"encoder/ixheaace_mps_bitstream.c",
"encoder/ixheaace_mps_dct.c",
"encoder/ixheaace_mps_delay.c",
"encoder/ixheaace_mps_dmx_tdom_enh.c",
"encoder/ixheaace_mps_enc.c",
"encoder/ixheaace_mps_filter.c",
"encoder/ixheaace_mps_frame_windowing.c",
"encoder/ixheaace_mps_huff_tab.c",
"encoder/ixheaace_mps_hybrid_filter.c",
"encoder/ixheaace_mps_nlc_enc.c",
"encoder/ixheaace_mps_onset_detect.c",
"encoder/ixheaace_mps_param_extract.c",
"encoder/ixheaace_mps_polyphase.c",
"encoder/ixheaace_mps_qmf.c",
"encoder/ixheaace_mps_rom.c",
"encoder/ixheaace_mps_static_gain.c",
"encoder/ixheaace_mps_tools_rom.c",
"encoder/ixheaace_mps_tree.c",
"encoder/ixheaace_mps_vector_functions.c",
"encoder/ixheaace_ms_stereo.c",
"encoder/ixheaace_ps_bitenc.c",
"encoder/ixheaace_ps_enc.c",
"encoder/ixheaace_ps_enc_init.c",
"encoder/ixheaace_psy_configuration.c",
"encoder/ixheaace_psy_mod.c",
"encoder/ixheaace_psy_utils.c",
"encoder/ixheaace_psy_utils_spreading.c",
"encoder/ixheaace_qc_main_hp.c",
"encoder/ixheaace_qc_util.c",
"encoder/ixheaace_quant.c",
"encoder/ixheaace_radix2_fft.c",
"encoder/ixheaace_resampler.c",
"encoder/ixheaace_resampler_init.c",
"encoder/ixheaace_rom.c",
"encoder/ixheaace_sbr_code_envelope.c",
"encoder/ixheaace_sbr_code_envelope_lp.c",
"encoder/ixheaace_sbr_crc.c",
"encoder/ixheaace_sbr_env_est.c",
"encoder/ixheaace_sbr_env_est_init.c",
"encoder/ixheaace_sbr_frame_info_gen.c",
"encoder/ixheaace_sbr_freq_scaling.c",
"encoder/ixheaace_sbr_hbe_dft_trans.c",
"encoder/ixheaace_sbr_hbe_trans.c",
"encoder/ixheaace_sbr_inv_filtering_estimation.c",
"encoder/ixheaace_sbr_main.c",
"encoder/ixheaace_sbr_misc.c",
"encoder/ixheaace_sbr_missing_harmonics_det.c",
"encoder/ixheaace_sbr_noise_floor_est.c",
"encoder/ixheaace_sbr_qmf_enc.c",
"encoder/ixheaace_sbr_qmf_enc_init.c",
"encoder/ixheaace_sbr_rom.c",
"encoder/ixheaace_sbr_ton_corr.c",
"encoder/ixheaace_sbr_ton_corr_hp.c",
"encoder/ixheaace_sbr_tran_det.c",
"encoder/ixheaace_sbr_tran_det_hp.c",
"encoder/ixheaace_sbr_write_bitstream.c",
"encoder/ixheaace_sf_estimation.c",
"encoder/ixheaace_static_bits.c",
"encoder/ixheaace_stereo_preproc.c",
"encoder/ixheaace_tns.c",
"encoder/ixheaace_tns_hp.c",
"encoder/ixheaace_tns_init.c",
"encoder/ixheaace_tns_params.c",
"encoder/ixheaace_write_adts_adif.c",
"encoder/ixheaace_write_bitstream.c",
],
sanitize: {
misc_undefined: [
"unsigned-integer-overflow",
"signed-integer-overflow",
"bounds",
],
cfi: true,
config: {
cfi_assembly_support: true,
},
},
arch: {
arm64: {
cflags: [
"-DBUILD_ARM64",
],
},
x86_64: {
cflags: [
"-DBUILD_ARM64",
],
},
},
}
subdirs = ["test"]

View file

@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.5.1)
project(libxaac C CXX)
enable_language(ASM)
option(BUILD64 "Build for 64 bit" OFF)
set(XAAC_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
set(XAAC_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}")
find_package(Threads REQUIRED)
@ -21,3 +22,7 @@ include("${XAAC_ROOT}/common/common.cmake")
include("${XAAC_ROOT}/decoder/libxaacdec.cmake")
include("${XAAC_ROOT}/test/decoder/xaacdec.cmake")
include("${XAAC_ROOT}/fuzzer/xaac_dec_fuzzer.cmake")
include("${XAAC_ROOT}/encoder/libxaacenc.cmake")
include("${XAAC_ROOT}/test/encoder/xaacenc.cmake")
include("${XAAC_ROOT}/fuzzer/xaac_enc_fuzzer.cmake")

216
README.md
View file

@ -1,109 +1,24 @@
# Introduction of the Ex-HEAAC Decoder
# Introduction to Ex-HEAAC (libxaac)
Ex-HEAAC, the latest innovation member of the MPEG AAC codec family, is ideally suited for adaptive bit rate streaming and digital radio applications. Ex-HEAAC bridges the gap between speech and audio coding and ensures consistent high-quality audio for all signal types, including speech, music, and mixed material. It is the required audio codec for DRM (Digital Radio Mondiale). When it comes to coding, the codec is incredibly effective, generating high-quality audio for music and speech at bitrates as low as 6 kbit/s for mono and 12 kbit/s for stereo services. By switching to extremely low bitrate streams, Ex-HEAAC streaming apps and streaming radio players can provide uninterrupted playback even during very congested network conditions.
Ex-HEAAC (Extended HE AAC), the latest upgrade to the MPEG AAC codec family,
is the audio codec of choice for digital radio and low bit rate
streaming applications. Selected as the mandatory audio codec for DRM
(Digital Radio Mondiale), Ex-HEAAC bridges the gap between speech and
audio coding, and provides consistent high quality audio for all signal
types, such as speech, music or mixed content.
As the Extended High Efficiency AAC Profile is a logical evolution of the MPEG Audio's popular AAC Family profiles, the codec supports AAC-LC, HE-AACv1 (AAC+) and HE-AACv2 (eAAC+) audio object type encoding. The bitrate that was saved with AAC family tools can be used to enhance video quality. Ex-HEAAC is a well-liked option for a number of applications since it is a strong and effective audio codec that provides high-quality audio at low bitrates.
Another important feature is the codec’s coding efficiency. The audio
codec produces excellent sound for both music and speech, delivering
high quality performance at bit rates starting as low as 6 kbit/s for
mono and 12 kbit/s for stereo services. Thus Ex-HEAAC streaming apps and
streaming radio players may switch to very low bit rate streams and
offer a continuous playback even while the network is congested. Once
more bandwidth becomes available on the network again, the Ex-HEAAC
client can request a higher bitrate version and seamless switch over
the full range of bitrates. Audio bitrate that’s being saved due to the
improved coding efficiency can be used to improve video quality. Ex-HEAAC
supports AAC and HEAAC v2 as well.
![Architecture](docs/Exheaac_Block_Diagram.jpg)
AAC is a popular audio coding technique recommended by MPEG committee.
The codec handles audio signals sampled in the range of 8 kHz to 96
kHz. It operates on a frame of 1024 samples. The bit-rates supported
are in the range of 8 kbps to 576 kbps per channel.
One of the key features of Ittiam's Ex-HEAAC (refer to above image) is that it has support for AAC-LD (Low Delay), AAC-ELD (Enhanced Low Delay), and AAC-ELDv2 (Enhanced Low Delay version 2) modes. AAC-LD mode provides low latency encoding, making it suitable for applications such as interactive communication and live audio streaming. It helps to reduce the delay in the encoding process to improve the real-time performance of the system. AAC-ELD mode improves the low-delay performance of HE-AAC by reducing the coding delay while maintaining high audio quality. It was observed that minimum delay it can achieve is 15ms. In order to achieve low delay coding scheme and low bitrate, it uses the Low Delay SBR tool. AAC-ELDv2 is the most advanced version of AAC-based low delay coding. It provides an enhanced version of AAC-ELD, which provides even lower coding delay and higher audio quality.
SBR and PS are the tools used in combination with the AAC general audio
codec resulting in HEAAC v2 (also known as Enhanced AAC Plus). It
provides significant increase in coding gain. In SBR, the high-band,
i.e. the high frequency part of the spectrum is replicated using the
low-band. In PS, channel redundancy is exploited and parameters are
extracted from a down-mixed channel.The bit-rate is by far below the
bit-rate required when using conventional AAC coding. This translates
into better quality at lower bit-rates.
Overall, Ittiam's Ex-HEAAC, with support for AAC-LD, AAC-ELD, and AAC-ELDv2 modes, is a versatile audio coding technology that can be used for a wide range of applications, such as broadcasting, streaming, and teleconferencing which requires high-quality audio compression with minimal delay.
#### Note
* MPEG-D USAC (Unified Speech and Audio Coding) support for Ittiam's Ex-HEAAC Encoder will be coming soon, which will help in improved audio quality at reduced bitrates. USAC technology will provide efficient and high quality compression of speech and audio signals, making it a valuable addition to our Ex-HEAAC capabilities and features.
* Further Quality enhancements for AAC-ELD and AAC-ELDv2 modes may be pushed as quality assessment is in progress.
# Introduction to Ex-HEAAC Decoder APIs
## Files to be included are
* [`ixheaacd_apicmd_standards.h`](decoder/ixheaacd_apicmd_standards.h)
* [`ixheaac_type_def.h`](common/ixheaac_type_def.h)
* [`ixheaacd_memory_standards.h`](decoder/ixheaacd_memory_standards.h)
* [`ixheaac_error_standards.h`](common/ixheaac_error_standards.h)
* [`ixheaacd_error_handler.h`](decoder/ixheaacd_error_handler.h)
* [`ixheaacd_aac_config.h`](decoder/ixheaacd_aac_config.h)
## Decoder APIs
A single API is used to get and set configurations and execute the decode thread, based on command index passed.
* ia_xheaacd_dec_api
| **API Command** | **API Sub Command** | **Description** |
|------|------|------|
|IA_API_CMD_GET_LIB_ID_STRINGS | IA_CMD_TYPE_LIB_NAME | Gets the decoder library name |
|IA_API_CMD_GET_LIB_ID_STRINGS | IA_CMD_TYPE_LIB_VERSION | Gets the decoder version |
|IA_API_CMD_GET_API_SIZE | 0 | Gets the memory requirements size of the API |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS | Sets the configuration parameters of the Ex-HEAAC v2 Decoder to default values |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS | Sets the attributes(size, priority, alignment) of all memory types required by the application onto the memory structure |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ | Sets the core AAC sampling frequency for RAW header decoding |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PCM_WDSZ | Sets the bit width of the output pcm samples.The value has to be 16 |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DOWNMIX | Sets the parameter whether the output needs to be down-mix to mono(1) or not(0) |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_TOSTEREO | Sets the flag to disable interleave mono to stereo |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DSAMPLE | Sets the parameter whether the output needs to be downsampled(1) or not(0).This is valid only for Ex-HEAAC v2 build |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_FRAMEOK | Sets the flag to 0 or 1 to indicate whether the current frame is valid(1) or not(0) |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_ISMP4 | Sets the flag to 0 or 1 to indicate whether given test vector is an mp4 file or not |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DISABLE_SYNC | Sets the flag of ADTS syncing or not ADTS syncing as 0 or 1 |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_AUTO_SBR_UPSAMPLE | Sets the parameter auto SBR upsample to 0 or 1.Used in case of stream changing from SBR present to SBR not present.This is valid only for Ex-HEAAC v2 build |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_MAX_CHANNEL | Sets the maximum number of channels present.Its maximum value is 2 for stereo library and 8 for multichannel library |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_COUP_CHANNEL | Sets the number of coupling channels to be used for coupling.It can take values from 0 to 16.This command is supported only if the library has multichannel support |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DOWNMIX_STEREO | Sets the flag of downmixing n number of channels to stereo.Can be 0 or 1. This command is supported only if the library has multichannel support |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISLOAS | Sets the flag indicating that the input file is a .loas file.Can be 0 or 1 |
|IA_API_CMD_GET_N_MEMTABS | 0 | Gets the number of memory types |
|IA_API_CMD_GET_N_TABLES | 0 | Gets the number of tables |
|IA_API_CMD_GET_MEM_INFO_SIZE | 0 | Gets the size of the memory type being referred to by the index |
|IA_API_CMD_GET_MEM_INFO_ALIGNMENT | 0 | Gets the alignment information of the memory-type being referred to by the index |
|IA_API_CMD_GET_MEM_INFO_TYPE | 0 | Gets the type of memory being referred to by the index |
|IA_API_CMD_SET_MEM_PTR | 0 | Sets the pointer to the memory being referred to by the index to the input value |
|IA_API_CMD_GET_TABLE_INFO_SIZE | 0 | Gets the size of the memory type being referred to by the index |
|IA_API_CMD_GET_TABLE_INFO_ALIGNMENT | 0 | Gets the alignment information of the memory-type being referred to by the index |
|IA_API_CMD_GET_TABLE_PTR | 0 | Gets the address of the current location of the table |
|IA_API_CMD_SET_TABLE_PTR | 0 | Sets the relocated table address |
|IA_API_CMD_INPUT_OVER | 0 | Signals the end of bit-stream to the library |
|IA_API_CMD_SET_INPUT_BYTES | 0 | Sets the number of bytes available in the input buffer for initialization |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_PROCESS | Search for the valid header, does header decode to get the parameters and initializes state and configuration structure |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_DONE_QUERY | Checks if the initialization process has completed |
|IA_API_CMD_GET_CURIDX_INPUT_BUF | 0 | Gets the number of input buffer bytes consumed by the last initialization |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ | Gets the sampling frequency |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS | Gets the output number of channels |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ | Gets the output PCM word size |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE | Gets the channel mode. (Mono or PS/Stereo/Dual-mono) |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK | Gets the channel mask |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE | Gets the SBR mode (Present/ Not Present).This is valid only for Ex-HEAAC v2 build |
|IA_API_CMD_EXECUTE | IA_CMD_TYPE_DO_EXECUTE | Executes the decode thread |
|IA_API_CMD_EXECUTE | IA_CMD_TYPE_DONE_QUERY | Checks if the end of decode has been reached |
|IA_API_CMD_GET_OUTPUT_BYTES | 0 | Gets the number of bytes output by the decoder in the last frame |
## Flowchart of calling sequence
![API Flowchart](docs/Api_flowchart.png)
# Building the Ex-HEAAC Decoder
# Building the Ex-HEAAC Decoder and Encoder
## Building for AOSP
* Makefiles for building the Ex-HEAAC decoder library is provided in root(`libxaac/`) folder.
* Makefiles for building the Ex-HEAAC decoder testbench is provided in `test` folder.
* Makefile for building the Ex-HEAAC decoder and encoder library is provided in root(`libxaac/`) folder.
* Makefile for building the Ex-HEAAC decoder and encoder testbench is provided in `test` folder.
* Build the library followed by the application using the below commands:
Go to root directory
```
@ -111,12 +26,12 @@ $ mm
```
## Using CMake
Users can also use cmake to build for `x86`, `x86_64`, and Windows (MSVS project) platforms.
Users can also use cmake to build for `x86`, `x86_64`, `armv7`, `armv8` and Windows (MSVS project) platforms.
### Creating MSVS project files
To create MSVS project files for the Ex-HEAAC decoder from cmake, run the following commands:
To create MSVS project files for the Ex-HEAAC decoder and encoder from cmake, run the following commands:
```
Go to the root directory(libxaac/) of the Ex-HEAAC Decoder.
Go to the root directory(libxaac/).
Create a new folder in the project root directory and move to the newly created folder.
$ cd <path to libxaac>
@ -125,29 +40,37 @@ $ cd bin
$ cmake -G "Visual Studio 15 2017" ..
```
Above command will create Win32 version of MSVS workspace
To create MSVS project files for Win64 version from cmake, run the following commands:
```
$ mkdir cmake_build
$ cd cmake_build
$ cmake -G "Visual Studio 15 2017 Win64" .. -DBUILD64=ON
```
The above command creates MSVS 2017 project files. If the version is different, modify the generator name accordingly.
The Ex-HEAAC decoder can be built using these project files.
### Building for native platforms
Run the following commands to build the Ex-HEAAC Decoder for native platform:
Run the following commands to build the Ex-HEAAC decoder and encoder for native platform:
```
Go to the root directory(libxaac/) of the Ex-HEAAC Decoder.
Go to the root directory(libxaac/).
Create a new folder in the project root directory and move to the newly created folder.
$ cd <path to libxaac>
$ mkdir bin
$ cd bin
$ cmake ..
$ cmake --build .
$ make
```
### Cross-compiler based builds
Ensure to edit the file cmake/toolchains/*_toolchain.cmake to set proper paths in host for corresponding platforms.
### Building for x86_32 on a x86_64 Linux machine
```
$ cd <path to libxaac>
$ mkdir build
$ cd build
$ CFLAGS="-m32" CXXFLAGS="-m32" LDFLAGS="-m32" cmake ..
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/x86_toolchain.cmake
$ make
```
@ -171,84 +94,5 @@ $ cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/aarch32_toolchain.cmake
$ make
```
# Running the Ex-HEAAC Decoder
The Ex-HEAAC Decoder can be run by providing command-line parameters(CLI options) directly or by providing a parameter file as a command line argument.
Command line usage :
```
<executable> -ifile:<input_file> -imeta:<meta_data_file> -ofile:<output_file> [options]
[options] can be,
[-mp4:<mp4_flag>]
[-pcmsz:<pcmwordsize>]
[-dmix:<down_mix>]
[-esbr_hq:<esbr_hq_flag>]
[-esbr_ps:<esbr_ps_flag>]
[-tostereo:<interleave_to_stereo>]
[-dsample:<down_sample_sbr>]
[-drc_cut_fac:<drc_cut_factor>]
[-drc_boost_fac:<drc_boost_factor>]
[-drc_target_level:<drc_target_level>]
[-drc_heavy_comp:<drc_heavy_compression>]
[-effect:<effect_type>]
[-target_loudness:<target_loudness>]
[-nosync:<disable_sync>]
[-sbrup:<auto_sbr_upsample>]
[-flflag:<framelength_flag>}
[-fs:<RAW_sample_rate>]
[-maxchannel:<maximum_num_channels>]
[-coupchannel:<coupling_channel>]
[-downmix:<down_mix_stereo>]
[-fs480:<ld_frame_size>]
[-ld_testing:<ld_testing_flag>]
[-peak_limiter_off:<peak_limiter_off_flag>]
[-err_conceal:<error_concealment_flag>]
[-esbr:<esbr_flag>]
where,
<input_file> is the input AAC/HEAACv1/HEAACv2/USAC file name.
<meta_data_file> is a text file which contains metadata. To be given when -mp4:1 is enabled.
<output_file> is the output file name.
<mp4_flag> is a flag that should be set to 1 when passing raw stream along with meta data text file.
<pcmwordsize> is the bits per sample info. value can be 16 or 24.
<down_mix> is to enable/disable always mono output. Default 1.
<esbr_hq_flag> is to enable/disable high quality eSBR. Default 0.
<esbr_ps_flag> is to indicate eSBR with PS. Default 0.
<interleave_to_stereo> is to enable/disable always interleaved to stereo output. Default 1.
<down_sample_sbr> is to enable/disable down-sampled SBR output. Default auto identification from header.
<drc_cut_factor> is to set DRC cut factor value. Default value is 0.
<drc_boost_factor> is to set DRC boost factor. Default value is 0.
<drc_target_level> is to set DRC target reference level. Default value is 108.
<drc_heavy_compression> is to enable/disable DRC heavy compression. Default value is 0.
<effect_type> is to set DRC effect type. Default value is 0.
<target_loudness> is to set target loudness level. Default value is -24.
<disable_sync> is to disable the ADTS/ADIF sync search i.e when enabled the decoder expects the header to be at the start of input buffer. Default 0.
<auto_sbr_upsample> is to enable(1) or disable(0) auto SBR upsample in case of stream changing from SBR present to SBR not present. Default 1.
<framelength_flag> is flag for decoding framelength of 1024 or 960. 1 to decode 960 frame length, 0 to decode 1024 frame length.
Frame length value in the GA header will override this option. Default 0.
<RAW_sample_rate> is to indicate the core AAC sample rate for a RAW stream. If this is specified no other file format headers are searched for.
<maximum_num_channels> is the number of maxiumum channels the input may have. Default is 6 for multichannel libraries and 2 for stereo libraries.
<coupling_channel> is element instance tag of independent coupling channel to be mixed. Default is 0.
<down_mix_stereo> is flag for Downmix. Give 1 to get stereo (downmix) output. Default is 0.
<ld_frame_size> is to indicate ld frame size. 0 is for 512 frame length, 1 is for 480 frame length. Default value is 512 (0).
<ld_testing_flag> is to enable/disable ld decoder testing. Default value is 0.
<peak_limiter_off_flag> is to enable/disable peak limiter. Default value is 0.
<error_concealment_flag> is to enable/disable error concealment. Default value is 0.
<esbr_flag> is to enable/disable eSBR. Default value is 1.
```
Sample CLI:
```
<xaac_dec_exe> -ifile:in_file.aac -ofile:out_file.wav -pcmsz:16
```
# Validating the Ex-HEAAC Decoder
Conformance testing for AAC/HEAAC v1/HEAAC v2 mainly involves comparing
decoder under test output with the ISO and 3GPP reference decoded output.
Testing for USAC is done using encoded streams generated using ISO USAC
reference encoder. The output generated by ITTIAM USAC decoder is
compared against the output generated by ISO USAC decoder for 16-bit
conformance on the respective(ARMv7, ARMv8, X86_32, X86_64) platforms.
### For API and testbench usage of decoder, please refer [`README_dec.md`](README_dec.md)
### For API and testbench usage of encoder, please refer [`README_enc.md`](README_enc.md)

241
README_dec.md Normal file
View file

@ -0,0 +1,241 @@
# Introduction to Ex-HEAAC Decoder APIs
## Decoder APIs
A single API is used to get and set configurations and execute the decode thread, based on command index passed.
* ia_xheaacd_dec_api
| **API Command** | **API Sub Command** | **Description** |
|------|------|------|
|IA_API_CMD_GET_LIB_ID_STRINGS | IA_CMD_TYPE_LIB_NAME | Gets the decoder library name |
|IA_API_CMD_GET_LIB_ID_STRINGS | IA_CMD_TYPE_LIB_VERSION | Gets the decoder version |
|IA_API_CMD_GET_API_SIZE | 0 | Gets the memory requirements size of the API |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS | Sets the configuration parameters of the Ex-HEAAC v2 Decoder to default values |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS | Sets the attributes(size, priority, alignment) of all memory types required by the application onto the memory structure |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_PROCESS | Search for the valid header, does header decode to get the parameters and initializes state and configuration structure |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_DONE_QUERY | Checks if the initialization process has completed |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ | Sets the bit width of the output PCM samples. The value has to be 16 |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ | Sets the core AAC sampling frequency for RAW header decoding |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE | Sets the value of DRC effect type |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS | Sets the value of DRC target loudness |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DOWNMIX | Sets the parameter whether the output needs to be down-mix to mono(1) or not(0) |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_TOSTEREO | Sets the flag to disable interleave mono to stereo |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DSAMPLE | Sets the parameter whether the output needs to be downsampled(1) or not(0. This is valid only for Ex-HEAAC v2 build |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4 | Sets the flag to 0 or 1 to indicate whether given test vector is an mp4 file or not |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_MAX_CHANNEL | Sets the maximum number of channels present. Its maximum value is 2 for stereo library and 8 for multichannel library |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_COUP_CHANNEL | Sets the number of coupling channels to be used for coupling. It can take values from 0 to 16. This command is supported only if the library has multichannel support |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DOWNMIX_STEREO | Sets the flag of downmixing n number of channels to stereo. Can be 0 or 1. This command is supported only if the library has multichannel support |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_DISABLE_SYNC | Sets the flag of ADTS syncing or not ADTS syncing as 0 or 1 |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_AUTO_SBR_UPSAMPLE | Sets the parameter auto SBR upsample to 0 or 1. Used in case of stream changing from SBR present to SBR not present. This is valid only for Ex-HEAAC v2 build |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT | Sets the value of DRC cut factor |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST | Sets the value of DRC boost factor |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP | Sets the parameter to either enable/disable DRC heavy compression |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_FRAMESIZE | Sets the parameter whether decoder should decode for frame length 480 or 512 |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_LD_TESTING | Sets the flag to enable LD testing in decoder |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_HQ_ESBR | Sets the flag to enable/disable high quality eSBR |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_PS_ENABLE | Sets the flag to indicate the presence of PS data in eSBR bit stream |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_PEAK_LIMITER | Sets the flag to disable/enable peak limiter |
|IA_API_CMD_SET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_FRAMELENGTH_FLAG | Sets to flag to indicate whether decoder should decode for frame length 960 or 1024 |
|IA_API_CMD_SET_CONFIG_PARAM | IA_XHEAAC_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL | Sets the value of DRC target level |
|IA_API_CMD_SET_CONFIG_PARAM | IA_XHEAAC_DEC_CONFIG_ERROR_CONCEALMENT | Sets to flag to disable/enable error concealment |
|IA_API_CMD_SET_CONFIG_PARAM | IA_XHEAAC_DEC_CONFIG_PARAM_ESBR | Sets to flag to disable/enable eSBR |
|IA_API_CMD_GET_N_MEMTABS | 0 | Gets the number of memory types |
|IA_API_CMD_GET_N_TABLES | 0 | Gets the number of tables |
|IA_API_CMD_GET_MEM_INFO_SIZE | 0 | Gets the size of the memory type being referred to by the index |
|IA_API_CMD_GET_MEM_INFO_ALIGNMENT | 0 | Gets the alignment information of the memory-type being referred to by the index |
|IA_API_CMD_GET_MEM_INFO_TYPE | 0 | Gets the type of memory being referred to by the index |
|IA_API_CMD_SET_MEM_PTR | 0 | Sets the pointer to the memory being referred to by the index to the input value |
|IA_API_CMD_GET_TABLE_INFO_SIZE | 0 | Gets the size of the memory type being referred to by the index |
|IA_API_CMD_GET_TABLE_INFO_ALIGNMENT | 0 | Gets the alignment information of the memory-type being referred to by the index |
|IA_API_CMD_GET_TABLE_PTR | 0 | Gets the address of the current location of the table |
|IA_API_CMD_SET_TABLE_PTR | 0 | Sets the relocated table address |
|IA_API_CMD_GET_MEMTABS_SIZE | 0 | Gets the size of the memory structures |
|IA_API_CMD_SET_MEMTABS_PTR | 0 | Sets the memory structure pointer in the library to the allocated value |
|IA_API_CMD_INPUT_OVER | 0 | Signals the end of bit-stream to the library |
|IA_API_CMD_SET_INPUT_BYTES | 0 | Sets the number of bytes available in the input buffer for initialization |
|IA_API_CMD_GET_CURIDX_INPUT_BUF | 0 | Gets the number of input buffer bytes consumed by the last initialization |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ | Gets the output PCM word size |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ | Gets the sampling frequency |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS | Gets the output number of channels |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK | Gets the channel mask |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE | Gets the channel mode. (Mono or PS/Stereo/Dual-mono) |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE | Gets the SBR mode (Present/ Not Present). This is valid only for Ex-HEAAC v2 build |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE | Gets the value of DRC effect type |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS | Gets the value of DRC target loudness |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM | Gets the value of DRC loudness normalization level |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_PARAM_AOT | Gets the value of audio object type |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR | Gets the extension element pointer |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES | Gets the extension element buffer sizes |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE | Gets the number of configuration elements |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT | Gets the number of extension elements |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN | Gets the gain payload length |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF | Gets the gain payload buffer |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_CONFIG_GET_NUM_PRE_ROLL_FRAMES | Gets the number of preroll frames |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_DRC_IS_CONFIG_CHANGED | Gets the value of DRC config change flag |
|IA_API_CMD_GET_CONFIG_PARAM | IA_ENHAACPLUS_DEC_DRC_APPLY_CROSSFADE | Gets the value of DRC crossfade flag |
|IA_API_CMD_EXECUTE | IA_CMD_TYPE_DO_EXECUTE | Executes the decode thread |
|IA_API_CMD_EXECUTE | IA_CMD_TYPE_DONE_QUERY | Checks if the end of decode has been reached |
|IA_API_CMD_GET_OUTPUT_BYTES | 0 | Gets the number of bytes output by the decoder in the last frame |
### Aliases for some of the macros exist as XHEAAC
| **Macro** | **Alias** |
|------|------|
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ | IA_XHEAAC_DEC_CONFIG_PARAM_PCM_WDSZ |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ | IA_XHEAAC_DEC_CONFIG_PARAM_SAMP_FREQ |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS | IA_XHEAAC_DEC_CONFIG_PARAM_NUM_CHANNELS |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK | IA_XHEAAC_DEC_CONFIG_PARAM_CHANNEL_MASK |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE | IA_XHEAAC_DEC_CONFIG_PARAM_CHANNEL_MODE |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE | IA_XHEAAC_DEC_CONFIG_PARAM_SBR_MODE |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE | IA_XHEAAC_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS | IA_XHEAAC_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM | IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUD_NORM |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_DOWNMIX | IA_XHEAAC_DEC_CONFIG_PARAM_DOWNMIX |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_TOSTEREO | IA_XHEAAC_DEC_CONFIG_PARAM_TOSTEREO |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_DSAMPLE | IA_XHEAAC_DEC_CONFIG_PARAM_DSAMPLE |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4 | IA_XHEAAC_DEC_CONFIG_PARAM_MP4FLAG |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_MAX_CHANNEL | IA_XHEAAC_DEC_CONFIG_PARAM_MAX_CHANNEL |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_COUP_CHANNEL | IA_XHEAAC_DEC_CONFIG_PARAM_COUP_CHANNEL |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_DOWNMIX_STEREO | IA_XHEAAC_DEC_CONFIG_PARAM_DOWNMIX_STEREO |
|IA_ENHAACPLUS_DEC_CONFIG_DISABLE_SYNC | IA_XHEAAC_DEC_CONFIG_DISABLE_SYNC |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_AUTO_SBR_UPSAMPLE | IA_XHEAAC_DEC_CONFIG_PARAM_AUTO_SBR_UPSAMPLE |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT | IA_XHEAAC_DEC_CONFIG_PARAM_DRC_CUT |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST | IA_XHEAAC_DEC_CONFIG_PARAM_DRC_BOOST |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP | IA_XHEAAC_DEC_CONFIG_PARAM_DRC_HEAVY_COMP |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_FRAMESIZE | IA_XHEAAC_DEC_CONFIG_PARAM_FRAMESIZE |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_LD_TESTING | IA_XHEAAC_DEC_CONFIG_PARAM_LD_TESTING |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_HQ_ESBR | IA_XHEAAC_DEC_CONFIG_PARAM_HQ_ESBR |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_PS_ENABLE | IA_XHEAAC_DEC_CONFIG_PARAM_PS_ENABLE |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_AOT | IA_XHEAAC_DEC_CONFIG_PARAM_AOT |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_PEAK_LIMITER | IA_XHEAAC_DEC_CONFIG_PARAM_PEAK_LIMITER |
|IA_ENHAACPLUS_DEC_CONFIG_PARAM_FRAMELENGTH_FLAG | IA_XHEAAC_DEC_CONFIG_PARAM_FRAMELENGTH_FLAG |
## DRC APIs
A single API is used to get and set configurations and execute the decode thread, based on command index passed.
* ia_drc_dec_api
| **API Command** | **API Sub Command** | **Description** |
|------|------|------|
|IA_API_CMD_GET_API_SIZE | 0 | Gets the memory requirements size of the API |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS | Sets the configuration parameters of the Ex-HEAAC v2 Decoder to default values |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS | Sets the attributes(size, priority, alignment) of all memory types required by the application onto the memory structure |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_PROCESS | Search for the valid header, does header decode to get the parameters and initializes state and configuration structure |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_CPY_BSF_BUFF | Sets the bitstream split format buffer |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF | Sets the configuration bitstream split format buffer |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF | Sets the loudness bitstream split format buffer |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF | Sets the interface bitstream split format buffer |
|IA_API_CMD_INIT | IA_CMD_TYPE_INIT_SET_BUFF_PTR | Sets the input buffer pointer |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ | Sets the sampling frequency of the input stream/data |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS | Sets the number of channels in the input stream/data |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ | Sets the PCM word size of the input data |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT | Sets the bit stream format |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT | Sets the DRC decoder’s interface present flag to 1 or 0 |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE | Sets the frame size |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE | Sets the value of DRC effect type |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS | Sets the value of DRC target loudness |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_DRC_LOUD_NORM | Sets the value of DRC loudness normalization level |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_APPLY_CROSSFADE | Sets the value of DRC crossfade flag |
|IA_API_CMD_SET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_CONFIG_CHANGED | Sets the value of DRC config change flag |
|IA_API_CMD_GET_MEM_INFO_SIZE | 0 | Gets the size of the memory type being referred to by the index |
|IA_API_CMD_GET_MEMTABS_SIZE | 0 | Gets the size of the memory structures |
|IA_API_CMD_SET_MEMTABS_PTR | 0 | Sets the memory structure pointer in the library to the allocated value |
|IA_API_CMD_GET_N_MEMTABS | 0 | Gets the number of memory types |
|IA_API_CMD_SET_INPUT_BYTES | 0 | Sets the number of bytes available in the input buffer for initialization |
|IA_API_CMD_GET_MEM_INFO_ALIGNMENT | 0 | Gets the alignment information of the memory-type being referred to by the index |
|IA_API_CMD_GET_MEM_INFO_TYPE | 0 | Gets the type of memory being referred to by the index |
|IA_API_CMD_SET_MEM_PTR | 0 | Sets the pointer to the memory being referred to by the index to the input value |
|IA_API_CMD_SET_INPUT_BYTES_BS | 0 | Sets the number of bytes to be processed in bitstream split format |
|IA_API_CMD_SET_INPUT_BYTES_IC_BS | 0 | Sets the number of bytes to be processed in configuration bitstream split format |
|IA_API_CMD_SET_INPUT_BYTES_IL_BS | 0 | Sets the number of bytes to be processed in loudness bitstream split format |
|IA_API_CMD_GET_CONFIG_PARAM | IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS | Gets the output number of channels |
|IA_API_CMD_EXECUTE | IA_CMD_TYPE_DO_EXECUTE | Executes the decode thread |
## Flowchart of calling sequence
![API Flowchart](docs/Api_flowchart_dec.png)
# Running the Ex-HEAAC Decoder
The Ex-HEAAC Decoder can be run by providing command-line parameters(CLI options) directly or by providing a parameter file as a command line argument.
Command line usage :
```
<executable> -ifile:<input_file> -imeta:<meta_data_file> -ofile:<output_file> [options]
[options] can be,
[-mp4:<mp4_flag>]
[-pcmsz:<pcmwordsize>]
[-dmix:<down_mix>]
[-esbr_hq:<esbr_hq_flag>]
[-esbr_ps:<esbr_ps_flag>]
[-tostereo:<interleave_to_stereo>]
[-dsample:<down_sample_sbr>]
[-drc_cut_fac:<drc_cut_factor>]
[-drc_boost_fac:<drc_boost_factor>]
[-drc_target_level:<drc_target_level>]
[-drc_heavy_comp:<drc_heavy_compression>]
[-effect:<effect_type>]
[-target_loudness:<target_loudness>]
[-nosync:<disable_sync>]
[-sbrup:<auto_sbr_upsample>]
[-flflag:<framelength_flag>}
[-fs:<RAW_sample_rate>]
[-maxchannel:<maximum_num_channels>]
[-coupchannel:<coupling_channel>]
[-downmix:<down_mix_stereo>]
[-fs480:<ld_frame_size>]
[-ld_testing:<ld_testing_flag>]
[-peak_limiter_off:<peak_limiter_off_flag>]
[-err_conceal:<error_concealment_flag>]
[-esbr:<esbr_flag>]
where,
<input_file> is the input AAC/HEAACv1/HEAACv2/USAC file name.
<meta_data_file> is a text file which contains metadata. To be given when -mp4:1 is enabled.
<output_file> is the output file name.
<mp4_flag> is a flag that should be set to 1 when passing raw stream along with meta data text file.
<pcmwordsize> is the bits per sample info. value can be 16 or 24.
<down_mix> is to enable/disable always mono output. Default 1.
<esbr_hq_flag> is to enable/disable high quality eSBR. Default 0.
<esbr_ps_flag> is to indicate eSBR with PS. Default 0.
<interleave_to_stereo> is to enable/disable always interleaved to stereo output. Default 1.
<down_sample_sbr> is to enable/disable down-sampled SBR output. Default auto identification from header.
<drc_cut_factor> is to set DRC cut factor value. Default value is 0.
<drc_boost_factor> is to set DRC boost factor. Default value is 0.
<drc_target_level> is to set DRC target reference level. Default value is 108.
<drc_heavy_compression> is to enable/disable DRC heavy compression. Default value is 0.
<effect_type> is to set DRC effect type. Default value is 0.
<target_loudness> is to set target loudness level. Default value is -24.
<disable_sync> is to disable the ADTS/ADIF sync search i.e when enabled the decoder expects the header to be at the start of input buffer. Default 0.
<auto_sbr_upsample> is to enable(1) or disable(0) auto SBR upsample in case of stream changing from SBR present to SBR not present. Default 1.
<framelength_flag> is flag for decoding framelength of 1024 or 960. 1 to decode 960 frame length, 0 to decode 1024 frame length.
Frame length value in the GA header will override this option. Default 0.
<RAW_sample_rate> is to indicate the core AAC sample rate for a RAW stream. If this is specified no other file format headers are searched for.
<maximum_num_channels> is the number of maxiumum channels the input may have. Default is 6 for multichannel libraries and 2 for stereo libraries.
<coupling_channel> is element instance tag of independent coupling channel to be mixed. Default is 0.
<down_mix_stereo> is flag for Downmix. Give 1 to get stereo (downmix) output. Default is 0.
<ld_frame_size> is to indicate ld frame size. 0 is for 512 frame length, 1 is for 480 frame length. Default value is 512 (0).
<ld_testing_flag> is to enable/disable ld decoder testing. Default value is 0.
<peak_limiter_off_flag> is to enable/disable peak limiter. Default value is 0.
<error_concealment_flag> is to enable/disable error concealment. Default value is 0.
<esbr_flag> is to enable/disable eSBR. Default value is 1.
```
Sample CLI:
```
<xaac_dec_exe> -ifile:in_file.aac -ofile:out_file.wav -pcmsz:16
```
# Validating the Ex-HEAAC Decoder
Conformance testing for AAC/HEAAC v1/HEAAC v2 mainly involves comparing
decoder under test output with the ISO and 3GPP reference decoded output.
Testing for USAC is done using encoded streams generated using ISO USAC
reference encoder. The output generated by ITTIAM USAC decoder is
compared against the output generated by ISO USAC decoder for 16-bit
conformance on the respective(ARMv7, ARMv8, X86_32, X86_64) platforms.

86
README_enc.md Normal file
View file

@ -0,0 +1,86 @@
# Introduction Extended HE-AAC Encoder APIs
# Encoder APIs
| **API Call** | **Description** |
|------|------|
|ixheaace_get_lib_id_strings| Gets the encoder library name and version number details |
|ixheaace_create| Sets the encoder configuration parameters, gets the memory requirements and allocates required memory |
|ixheaace_process| Encodes the input frame data |
|ixheaace_delete| Frees the allocated memories for the encoder |
## Flowchart of calling sequence
![API Flowchart](docs/Api_flowchart_enc.png)
# Audio Object Types(AOT)
| **AOT** | **Description** |
|------|------|
|2|AAC LC|
|5|HEAACv1|
|23|AAC LD|
|29|HEAACv2|
|39|AAC ELD|
|42|USAC (support will be added soon)|
# Running the Ex-HEAAC Encoder
The Ex-HEAAC Encoder can be run by providing command-line parameters(CLI options) directly or by providing a parameter file as a command line argument.
The reference paramfile is placed in smoke_test_suite(paramfilesimple.txt)
# Command line usage :
```
<exceutable> -ifile:<input_file> -ofile:<out_file> [options]
<executable> -paramfile:<paramfile>
[options] can be,
[-br:<bitrate>]
[-mps:<use_mps>]
[-adts:<use_adts_flag (0/1)>]
[-tns:<use_tns_flag>]
[-framesize:<framesize_to_be_used>]
[-aot:<audio_object_type>]
[-esbr:<esbr_flag (0/1)>]
[-full_bandwidth:<Enable use of full bandwidth of input>]
[-max_out_buffer_per_ch:<bitreservoir_size>]
[-tree_cfg:<tree_config>]
where,
<paramfile> is the parameter file with multiple commands
<inputfile> is the input 16-bit WAV or PCM file name
<outputfile> is the output ADTS/ES file name
<bitrate> is the bit-rate in bits per second. Valid values are Plain AAC: 8000-576000 bps per channel
<use_mps> When set to 1 MPS is enable. Default 0.
<use_adts_flag> when set to 1 ADTS header generated. Default is 0
<use_tns_flag> controls usage of TNS in encoding. Default is 1.
<framesize_to_be_used> is the framesize to be used For AOT 23, 39 (LD core coder profiles) valid values are 480 and 512 .Default is 512
For AOT 2, 5, 29 (LC core coder profiles) valid values are 960 and 1024 .Default is 1024
<audio_object_type> is the Audio object type
2 for AAC LC
5 for HEAACv1(Legacy SBR)
23 for AAC LD
29 for HEAACv2
39 for AAC ELD
Default is 2 for AAC LC
<esbr_flag> when set to 1 enables eSBR in HEAACv1 encoding Default is 0
<full_bandwidth> Enable use of full bandwidth of input. Valid values are 0(disable) and 1(enable). Default is 0.
<bitreservoir_size> is the maximum size of bit reservoir to be used. Valid values are from -1 to 6144. -1 to omit use of bit reservoir. Default is 384.
<tree_config> MPS tree config
0 for '212'
1 for '5151'
2 for '5152'
3 for '525'
Default '212' for stereo input '515' for 6 ch input
```
Sample CLI:
```
-ifile:input_file.wav -ofile:out_file.aac -br:<bit_rate> –aot:<audio profile>
```
# Additional Documents
Brief description about documents present in `docs` folder
* [`IA-XHEAAC-Enc-API.pdf`](docs/IA-XHEAAC-Enc-API.pdf) - Describes Application Program Interface for Ex-HEAAC Encoder.
* [`IA-XHEAAC-Enc-GSG.pdf`](docs/IA-XHEAAC-Enc-GSG.pdf) - Getting Started Guide for the Ex-HEAAC Encoder.
# Validating the Ex-HEAAC Encoder
Testing for Ex-HEAAC Encoder done using listening test for different AOT(Audio object types)

View file

@ -0,0 +1,18 @@
# This one is important
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR i686)
# Specify the cross compiler
SET(CMAKE_C_COMPILER gcc)
SET(CMAKE_CXX_COMPILER g++)
# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH /)
# Search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# For libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View file

@ -3,7 +3,7 @@ set(CMAKE_C_STANDARD 99)
# Adds compiler options for all targets
function(libxaac_add_compile_options)
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
add_compile_options(-std=gnu99 -march=armv8-a)
add_compile_options(-std=gnu99 -march=armv8-a -DBUILD_ARM64)
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch32")
add_compile_options(
-O3
@ -13,9 +13,18 @@ function(libxaac_add_compile_options)
-march=armv7-a
-mfloat-abi=softfp
-mfpu=neon)
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686" OR ${CMAKE_SYSTEM_PROCESSOR}
STREQUAL "x86_64")
add_compile_options(-O3 -Wall -Wsequence-point -fwrapv)
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
add_compile_options(-D_X86_ -O3 -Wall -Wsequence-point -Wunused-function -fwrapv -DBUILD_ARM64)
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686")
add_compile_options(-D_X86_ -O3 -Wall -Wsequence-point -Wunused-function -fwrapv -m32)
endif()
if(MSVC)
if(BUILD64)
add_definitions(-DBUILD_ARM64)
else()
add_definitions(-D_WIN32)
endif()
endif()
set(CMAKE_REQUIRED_FLAGS -fsanitize=fuzzer-no-link)
@ -45,7 +54,7 @@ function(libxaac_add_definitions)
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch32")
add_definitions(-DARMV7)
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686")
add_definitions(-DX86)
add_definitions(-DX86 -D_X86_)
endif()
endfunction()
@ -94,7 +103,11 @@ function(libxaac_add_executable NAME LIB)
else()
target_link_libraries(${NAME} ${LIB} ${ARG_LIBS})
endif()
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686")
set_target_properties(${NAME} PROPERTIES LINK_FLAGS "-m32")
endif()
if(ARG_FUZZER)
target_compile_options(${NAME}
PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-std=c++17>)

View file

@ -20,6 +20,9 @@
#ifndef IXHEAAC_BASIC_OPS_H
#define IXHEAAC_BASIC_OPS_H
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
static PLATFORM_INLINE WORD16 ixheaac_extract16h(WORD32 var) {
WORD16 var_out;
@ -48,8 +51,7 @@ static PLATFORM_INLINE WORD32 ixheaac_deposit16l_in32(WORD16 var) {
return (var_out);
}
static PLATFORM_INLINE UWORD32 ixheaac_extu(UWORD32 a, WORD32 shift_left,
WORD32 shift_right) {
static PLATFORM_INLINE UWORD32 ixheaac_extu(UWORD32 a, WORD32 shift_left, WORD32 shift_right) {
UWORD32 x;
x = (UWORD32)a << shift_left;
x = (UWORD32)x >> shift_right;
@ -57,8 +59,7 @@ static PLATFORM_INLINE UWORD32 ixheaac_extu(UWORD32 a, WORD32 shift_left,
return x;
}
static PLATFORM_INLINE WORD32 ixheaac_mult32x16h_in32_shl_sat(WORD32 a,
WORD32 b) {
static PLATFORM_INLINE WORD32 ixheaac_mult32x16h_in32_shl_sat(WORD32 a, WORD32 b) {
WORD32 result;
if (a == (WORD32)0x80000000 && b == (WORD16)0x8000) {
@ -124,8 +125,7 @@ static PLATFORM_INLINE WORD32 ixheaac_shl32_dir_sat_limit(WORD32 a, WORD b) {
return out_val;
}
static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64_dual(WORD32 a, WORD32 b,
WORD64 c) {
static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64_dual(WORD32 a, WORD32 b, WORD64 c) {
WORD64 result;
WORD64 temp_result;

View file

@ -156,7 +156,7 @@ static PLATFORM_INLINE WORD32 ixheaac_mult32x16in32_sat(WORD32 a, WORD16 b) {
else
result = (WORD32)(temp_result);
return(result);
return (result);
}
static PLATFORM_INLINE WORD32 ixheaac_mult16x16in32_shl(WORD16 a, WORD16 b) {
@ -167,8 +167,7 @@ static PLATFORM_INLINE WORD32 ixheaac_mult16x16in32_shl(WORD16 a, WORD16 b) {
return product;
}
static PLATFORM_INLINE WORD32 ixheaac_mult16x16in32_shl_sat(WORD16 a,
WORD16 b) {
static PLATFORM_INLINE WORD32 ixheaac_mult16x16in32_shl_sat(WORD16 a, WORD16 b) {
WORD32 product;
product = (WORD32)a * (WORD32)b;
if (product != (WORD32)0x40000000L) {
@ -206,8 +205,7 @@ static PLATFORM_INLINE WORD32 ixheaac_add32_sat(WORD32 a, WORD32 b) {
return (WORD32)sum;
}
static PLATFORM_INLINE WORD32 ixheaac_add32_sat3(WORD32 a, WORD32 b,
WORD32 c) {
static PLATFORM_INLINE WORD32 ixheaac_add32_sat3(WORD32 a, WORD32 b, WORD32 c) {
WORD64 sum;
sum = (WORD64)a + (WORD64)b;
@ -327,8 +325,7 @@ static PLATFORM_INLINE WORD32 ixheaac_negate32_sat(WORD32 a) {
return neg_val;
}
static PLATFORM_INLINE WORD32 ixheaac_div32(WORD32 a, WORD32 b,
WORD *q_format) {
static PLATFORM_INLINE WORD32 ixheaac_div32(WORD32 a, WORD32 b, WORD *q_format) {
WORD32 quotient;
UWORD32 mantissa_nr, mantissa_dr;
WORD16 sign = 0;
@ -336,10 +333,6 @@ static PLATFORM_INLINE WORD32 ixheaac_div32(WORD32 a, WORD32 b,
LOOPINDEX i;
WORD q_nr, q_dr;
mantissa_nr = a;
mantissa_dr = b;
quotient = 0;
if ((a < 0) && (0 != b)) {
a = -a;
sign = (WORD16)(sign ^ -1);
@ -390,11 +383,9 @@ static PLATFORM_INLINE WORD32 ixheaac_shr32_sat(WORD32 a, WORD32 b) {
out_val = -1;
else
out_val = 0;
}
else if (b <= 0) {
} else if (b <= 0) {
return a;
}
else {
} else {
a = ixheaac_add32_sat(a, (1 << (b - 1)));
out_val = (WORD32)a >> b;
}
@ -402,8 +393,7 @@ static PLATFORM_INLINE WORD32 ixheaac_shr32_sat(WORD32 a, WORD32 b) {
return out_val;
}
static PLATFORM_INLINE WORD32 ixheaac_mac16x16in32_sat(WORD32 a, WORD16 b,
WORD16 c) {
static PLATFORM_INLINE WORD32 ixheaac_mac16x16in32_sat(WORD32 a, WORD16 b, WORD16 c) {
WORD32 acc;
acc = ixheaac_mult16x16in32(b, c);
@ -413,8 +403,7 @@ static PLATFORM_INLINE WORD32 ixheaac_mac16x16in32_sat(WORD32 a, WORD16 b,
return acc;
}
static PLATFORM_INLINE WORD32 ixheaac_mac16x16in32_shl(WORD32 a, WORD16 b,
WORD16 c) {
static PLATFORM_INLINE WORD32 ixheaac_mac16x16in32_shl(WORD32 a, WORD16 b, WORD16 c) {
WORD32 acc;
acc = ixheaac_mult16x16in32_shl(b, c);
@ -424,8 +413,7 @@ static PLATFORM_INLINE WORD32 ixheaac_mac16x16in32_shl(WORD32 a, WORD16 b,
return acc;
}
static PLATFORM_INLINE WORD32 ixheaac_mac16x16in32_shl_sat(WORD32 a, WORD16 b,
WORD16 c) {
static PLATFORM_INLINE WORD32 ixheaac_mac16x16in32_shl_sat(WORD32 a, WORD16 b, WORD16 c) {
WORD32 acc;
acc = ixheaac_mult16x16in32_shl_sat(b, c);

View file

@ -53,8 +53,7 @@ static PLATFORM_INLINE WORD32 ixheaac_mult32x32in32(WORD32 a, WORD32 b) {
return (result);
}
static PLATFORM_INLINE WORD32 ixheaac_mult32x16in32_shl_sat(WORD32 a,
WORD16 b) {
static PLATFORM_INLINE WORD32 ixheaac_mult32x16in32_shl_sat(WORD32 a, WORD16 b) {
WORD32 result;
if (a == (WORD32)0x80000000 && b == (WORD16)0x8000) {
@ -98,8 +97,7 @@ static PLATFORM_INLINE WORD32 ixheaac_mult32_shl_sat(WORD32 a, WORD32 b) {
return (result);
}
static PLATFORM_INLINE WORD32 ixheaac_mac32x16in32(WORD32 a, WORD32 b,
WORD16 c) {
static PLATFORM_INLINE WORD32 ixheaac_mac32x16in32(WORD32 a, WORD32 b, WORD16 c) {
WORD32 result;
result = a + ixheaac_mult32x16in32(b, c);
@ -107,8 +105,7 @@ static PLATFORM_INLINE WORD32 ixheaac_mac32x16in32(WORD32 a, WORD32 b,
return (result);
}
static PLATFORM_INLINE WORD32 ixheaac_mac32x16in32_shl(WORD32 a, WORD32 b,
WORD16 c) {
static PLATFORM_INLINE WORD32 ixheaac_mac32x16in32_shl(WORD32 a, WORD32 b, WORD16 c) {
WORD32 result;
result = a + ixheaac_mult32x16in32_shl(b, c);
@ -140,15 +137,13 @@ static PLATFORM_INLINE WORD64 ixheaac_mult32x32in64(WORD32 a, WORD32 b) {
return (result);
}
static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64(WORD64 sum, WORD32 a,
WORD32 b) {
static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64(WORD64 sum, WORD32 a, WORD32 b) {
sum += (WORD64)a * (WORD64)b;
return (sum);
}
static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64_7(const WORD32 *a,
const WORD16 *b) {
static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64_7(const WORD32 *a, const WORD16 *b) {
WORD64 sum;
sum = (WORD64)a[0] * (WORD64)b[0];
sum += (WORD64)a[1] * (WORD64)b[1];
@ -161,10 +156,8 @@ static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64_7(const WORD32 *a,
return (sum);
}
static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64_n(WORD64 sum,
const WORD32 *a,
const WORD16 *b,
WORD32 n) {
static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64_n(WORD64 sum, const WORD32 *a, const WORD16 *b,
WORD32 n) {
WORD32 k;
sum += (WORD64)a[0] * (WORD64)b[0];
@ -239,8 +232,7 @@ static PLATFORM_INLINE WORD64 ixheaac_sub64_sat(WORD64 a, WORD64 b) {
return (diff);
}
static PLATFORM_INLINE WORD32 ixheaac_mul32_sh(WORD32 a, WORD32 b,
WORD8 shift) {
static PLATFORM_INLINE WORD32 ixheaac_mul32_sh(WORD32 a, WORD32 b, WORD8 shift) {
WORD32 result;
WORD64 temp_result;

View file

@ -20,8 +20,7 @@
#ifndef IXHEAAC_BASIC_OPS_ARR_H
#define IXHEAAC_BASIC_OPS_ARR_H
static PLATFORM_INLINE VOID ixheaac_shr32_arr(WORD32 *word32_arr, WORD16 shift,
WORD32 n) {
static PLATFORM_INLINE VOID ixheaac_shr32_arr(WORD32 *word32_arr, WORD16 shift, WORD32 n) {
WORD32 i;
for (i = 0; i < n; i++) {
@ -32,8 +31,7 @@ static PLATFORM_INLINE VOID ixheaac_shr32_arr(WORD32 *word32_arr, WORD16 shift,
return;
}
static PLATFORM_INLINE VOID ixheaac_shl32_arr_sat(WORD32 *word32_arr,
WORD16 shift, WORD32 n) {
static PLATFORM_INLINE VOID ixheaac_shl32_arr_sat(WORD32 *word32_arr, WORD16 shift, WORD32 n) {
WORD32 i;
for (i = 0; i < n; i++) {
@ -44,8 +42,7 @@ static PLATFORM_INLINE VOID ixheaac_shl32_arr_sat(WORD32 *word32_arr,
return;
}
static PLATFORM_INLINE VOID ixheaac_shr16_arr(WORD16 *word16_arr, WORD16 shift,
WORD32 n) {
static PLATFORM_INLINE VOID ixheaac_shr16_arr(WORD16 *word16_arr, WORD16 shift, WORD32 n) {
WORD32 i;
for (i = 0; i < n; i++) {

View file

@ -39,8 +39,7 @@ extern const FLOAT32 ixheaac_twiddle_table_fft_float[514];
extern const FLOAT32 ixheaac_twidle_tbl_48[64];
extern const FLOAT32 ixheaac_twidle_tbl_24[32];
void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
WORD32 npoints) {
void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y, WORD32 npoints) {
WORD32 i, j, k, n_stages, h2;
FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
WORD32 del, nodespacing, in_loop_cnt;
@ -106,19 +105,19 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
for (k = in_loop_cnt; k != 0; k--) {
x0r = (*data);
x0i = (*(data + 1));
data += (del << 1);
data += ((SIZE_T)del << 1);
x1r = (*data);
x1i = (*(data + 1));
data += (del << 1);
data += ((SIZE_T)del << 1);
x2r = (*data);
x2i = (*(data + 1));
data += (del << 1);
data += ((SIZE_T)del << 1);
x3r = (*data);
x3i = (*(data + 1));
data -= 3 * (del << 1);
data -= 3 * ((SIZE_T)del << 1);
x0r = x0r + x2r;
x0i = x0i + x2i;
@ -140,54 +139,52 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*data = x0r;
*(data + 1) = x0i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += (del << 1);
data += ((SIZE_T)del << 1);
}
data = ptr_y + 2;
sec_loop_cnt = (nodespacing * del);
sec_loop_cnt = (sec_loop_cnt / 4) + (sec_loop_cnt / 8) -
(sec_loop_cnt / 16) + (sec_loop_cnt / 32) -
(sec_loop_cnt / 64) + (sec_loop_cnt / 128) -
sec_loop_cnt = (sec_loop_cnt / 4) + (sec_loop_cnt / 8) - (sec_loop_cnt / 16) +
(sec_loop_cnt / 32) - (sec_loop_cnt / 64) + (sec_loop_cnt / 128) -
(sec_loop_cnt / 256);
j = nodespacing;
for (j = nodespacing; j <= sec_loop_cnt; j += nodespacing) {
W1 = *(twiddles + j);
W4 = *(twiddles + j + 257);
W2 = *(twiddles + (j << 1));
W5 = *(twiddles + (j << 1) + 257);
W3 = *(twiddles + j + (j << 1));
W6 = *(twiddles + j + (j << 1) + 257);
W2 = *(twiddles + ((SIZE_T)j << 1));
W5 = *(twiddles + ((SIZE_T)j << 1) + 257);
W3 = *(twiddles + j + ((SIZE_T)j << 1));
W6 = *(twiddles + j + ((SIZE_T)j << 1) + 257);
for (k = in_loop_cnt; k != 0; k--) {
FLOAT32 tmp;
FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
data += (del << 1);
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * (del << 1);
data -= 3 * ((SIZE_T)del << 1);
tmp = (FLOAT32)(((FLOAT32)x1r * W1) + ((FLOAT32)x1i * W4));
x1i = (FLOAT32)(-((FLOAT32)x1r * W4) + (FLOAT32)x1i * W1);
@ -224,19 +221,19 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*data = x0r;
*(data + 1) = x0i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += (del << 1);
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
@ -244,28 +241,28 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
for (; j <= (nodespacing * del) >> 1; j += nodespacing) {
W1 = *(twiddles + j);
W4 = *(twiddles + j + 257);
W2 = *(twiddles + (j << 1));
W5 = *(twiddles + (j << 1) + 257);
W3 = *(twiddles + j + (j << 1) - 256);
W6 = *(twiddles + j + (j << 1) + 1);
W2 = *(twiddles + ((SIZE_T)j << 1));
W5 = *(twiddles + ((SIZE_T)j << 1) + 257);
W3 = *(twiddles + j + ((SIZE_T)j << 1) - 256);
W6 = *(twiddles + j + ((SIZE_T)j << 1) + 1);
for (k = in_loop_cnt; k != 0; k--) {
FLOAT32 tmp;
FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
data += (del << 1);
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * (del << 1);
data -= 3 * ((SIZE_T)del << 1);
tmp = (FLOAT32)(((FLOAT32)x1r * W1) + ((FLOAT32)x1i * W4));
x1i = (FLOAT32)(-((FLOAT32)x1r * W4) + (FLOAT32)x1i * W1);
@ -302,19 +299,19 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*data = x0r;
*(data + 1) = x0i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += (del << 1);
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
@ -322,28 +319,28 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
for (; j <= sec_loop_cnt * 2; j += nodespacing) {
W1 = *(twiddles + j);
W4 = *(twiddles + j + 257);
W2 = *(twiddles + (j << 1) - 256);
W5 = *(twiddles + (j << 1) + 1);
W3 = *(twiddles + j + (j << 1) - 256);
W6 = *(twiddles + j + (j << 1) + 1);
W2 = *(twiddles + ((SIZE_T)j << 1) - 256);
W5 = *(twiddles + ((SIZE_T)j << 1) + 1);
W3 = *(twiddles + j + ((SIZE_T)j << 1) - 256);
W6 = *(twiddles + j + ((SIZE_T)j << 1) + 1);
for (k = in_loop_cnt; k != 0; k--) {
FLOAT32 tmp;
FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
data += (del << 1);
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * (del << 1);
data -= 3 * ((SIZE_T)del << 1);
tmp = (FLOAT32)(((FLOAT32)x1r * W1) + ((FLOAT32)x1i * W4));
x1i = (FLOAT32)(-((FLOAT32)x1r * W4) + (FLOAT32)x1i * W1);
@ -380,19 +377,19 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*data = x0r;
*(data + 1) = x0i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += (del << 1);
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
@ -400,28 +397,28 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
for (; j < nodespacing * del; j += nodespacing) {
W1 = *(twiddles + j);
W4 = *(twiddles + j + 257);
W2 = *(twiddles + (j << 1) - 256);
W5 = *(twiddles + (j << 1) + 1);
W3 = *(twiddles + j + (j << 1) - 512);
W6 = *(twiddles + j + (j << 1) - 512 + 257);
W2 = *(twiddles + ((SIZE_T)j << 1) - 256);
W5 = *(twiddles + ((SIZE_T)j << 1) + 1);
W3 = *(twiddles + j + ((SIZE_T)j << 1) - 512);
W6 = *(twiddles + j + ((SIZE_T)j << 1) - 512 + 257);
for (k = in_loop_cnt; k != 0; k--) {
FLOAT32 tmp;
FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
data += (del << 1);
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * (del << 1);
data -= 3 * ((SIZE_T)del << 1);
tmp = (FLOAT32)(((FLOAT32)x1r * W1) + ((FLOAT32)x1i * W4));
x1i = (FLOAT32)(-((FLOAT32)x1r * W4) + (FLOAT32)x1i * W1);
@ -458,19 +455,19 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*data = x0r;
*(data + 1) = x0i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += (del << 1);
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
@ -492,7 +489,7 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
x0r = *ptr_y;
x0i = *(ptr_y + 1);
ptr_y += (del << 1);
ptr_y += ((SIZE_T)del << 1);
x1r = *ptr_y;
x1i = *(ptr_y + 1);
@ -503,7 +500,7 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*ptr_y = (x0r) - (x1r);
*(ptr_y + 1) = (x0i) - (x1i);
ptr_y -= (del << 1);
ptr_y -= ((SIZE_T)del << 1);
*ptr_y = (x0r) + (x1r);
*(ptr_y + 1) = (x0i) + (x1i);
@ -518,7 +515,7 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
x0r = *ptr_y;
x0i = *(ptr_y + 1);
ptr_y += (del << 1);
ptr_y += ((SIZE_T)del << 1);
x1r = *ptr_y;
x1i = *(ptr_y + 1);
@ -528,7 +525,7 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*ptr_y = (x0r) - (x1r);
*(ptr_y + 1) = (x0i) - (x1i);
ptr_y -= (del << 1);
ptr_y -= ((SIZE_T)del << 1);
*ptr_y = (x0r) + (x1r);
*(ptr_y + 1) = (x0i) + (x1i);
@ -537,8 +534,7 @@ void ixheaac_real_synth_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
}
}
void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
WORD32 npoints) {
void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y, WORD32 npoints) {
WORD32 i, j, k, n_stages, h2;
FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
WORD32 del, nodespacing, in_loop_cnt;
@ -619,19 +615,19 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
for (k = in_loop_cnt; k != 0; k--) {
x0r = (*data);
x0i = (*(data + 1));
data += (del << 1);
data += ((SIZE_T)del << 1);
x1r = (*data);
x1i = (*(data + 1));
data += (del << 1);
data += ((SIZE_T)del << 1);
x2r = (*data);
x2i = (*(data + 1));
data += (del << 1);
data += ((SIZE_T)del << 1);
x3r = (*data);
x3i = (*(data + 1));
data -= 3 * (del << 1);
data -= 3 * ((SIZE_T)del << 1);
x0r = x0r + x2r;
x0i = x0i + x2i;
@ -653,54 +649,52 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*data = x0r;
*(data + 1) = x0i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += (del << 1);
data += ((SIZE_T)del << 1);
}
data = ptr_y + 2;
sec_loop_cnt = (nodespacing * del);
sec_loop_cnt = (sec_loop_cnt / 4) + (sec_loop_cnt / 8) -
(sec_loop_cnt / 16) + (sec_loop_cnt / 32) -
(sec_loop_cnt / 64) + (sec_loop_cnt / 128) -
sec_loop_cnt = (sec_loop_cnt / 4) + (sec_loop_cnt / 8) - (sec_loop_cnt / 16) +
(sec_loop_cnt / 32) - (sec_loop_cnt / 64) + (sec_loop_cnt / 128) -
(sec_loop_cnt / 256);
j = nodespacing;
for (j = nodespacing; j <= sec_loop_cnt; j += nodespacing) {
W1 = *(twiddles + j);
W4 = *(twiddles + j + 257);
W2 = *(twiddles + (j << 1));
W5 = *(twiddles + (j << 1) + 257);
W3 = *(twiddles + j + (j << 1));
W6 = *(twiddles + j + (j << 1) + 257);
W2 = *(twiddles + ((SIZE_T)j << 1));
W5 = *(twiddles + ((SIZE_T)j << 1) + 257);
W3 = *(twiddles + j + ((SIZE_T)j << 1));
W6 = *(twiddles + j + ((SIZE_T)j << 1) + 257);
for (k = in_loop_cnt; k != 0; k--) {
FLOAT32 tmp;
FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
data += (del << 1);
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * (del << 1);
data -= 3 * ((SIZE_T)del << 1);
tmp = (FLOAT32)(((FLOAT32)x1r * W1) + ((FLOAT32)x1i * W4));
x1i = (FLOAT32)(-((FLOAT32)x1r * W4) + (FLOAT32)x1i * W1);
@ -737,19 +731,19 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*data = x0r;
*(data + 1) = x0i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += (del << 1);
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
@ -757,28 +751,28 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
for (; j <= (nodespacing * del) >> 1; j += nodespacing) {
W1 = *(twiddles + j);
W4 = *(twiddles + j + 257);
W2 = *(twiddles + (j << 1));
W5 = *(twiddles + (j << 1) + 257);
W3 = *(twiddles + j + (j << 1) - 256);
W6 = *(twiddles + j + (j << 1) + 1);
W2 = *(twiddles + ((SIZE_T)j << 1));
W5 = *(twiddles + ((SIZE_T)j << 1) + 257);
W3 = *(twiddles + j + ((SIZE_T)j << 1) - 256);
W6 = *(twiddles + j + ((SIZE_T)j << 1) + 1);
for (k = in_loop_cnt; k != 0; k--) {
FLOAT32 tmp;
FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
data += (del << 1);
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * (del << 1);
data -= 3 * ((SIZE_T)del << 1);
tmp = (FLOAT32)(((FLOAT32)x1r * W1) + ((FLOAT32)x1i * W4));
x1i = (FLOAT32)(-((FLOAT32)x1r * W4) + (FLOAT32)x1i * W1);
@ -815,19 +809,19 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*data = x0r;
*(data + 1) = x0i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += (del << 1);
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
@ -835,28 +829,28 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
for (; j <= sec_loop_cnt * 2; j += nodespacing) {
W1 = *(twiddles + j);
W4 = *(twiddles + j + 257);
W2 = *(twiddles + (j << 1) - 256);
W5 = *(twiddles + (j << 1) + 1);
W3 = *(twiddles + j + (j << 1) - 256);
W6 = *(twiddles + j + (j << 1) + 1);
W2 = *(twiddles + ((SIZE_T)j << 1) - 256);
W5 = *(twiddles + ((SIZE_T)j << 1) + 1);
W3 = *(twiddles + j + ((SIZE_T)j << 1) - 256);
W6 = *(twiddles + j + ((SIZE_T)j << 1) + 1);
for (k = in_loop_cnt; k != 0; k--) {
FLOAT32 tmp;
FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
data += (del << 1);
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * (del << 1);
data -= 3 * ((SIZE_T)del << 1);
tmp = (FLOAT32)(((FLOAT32)x1r * W1) + ((FLOAT32)x1i * W4));
x1i = (FLOAT32)(-((FLOAT32)x1r * W4) + (FLOAT32)x1i * W1);
@ -893,19 +887,19 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*data = x0r;
*(data + 1) = x0i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += (del << 1);
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
@ -913,28 +907,28 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
for (; j < nodespacing * del; j += nodespacing) {
W1 = *(twiddles + j);
W4 = *(twiddles + j + 257);
W2 = *(twiddles + (j << 1) - 256);
W5 = *(twiddles + (j << 1) + 1);
W3 = *(twiddles + j + (j << 1) - 512);
W6 = *(twiddles + j + (j << 1) - 512 + 257);
W2 = *(twiddles + ((SIZE_T)j << 1) - 256);
W5 = *(twiddles + ((SIZE_T)j << 1) + 1);
W3 = *(twiddles + j + ((SIZE_T)j << 1) - 512);
W6 = *(twiddles + j + ((SIZE_T)j << 1) - 512 + 257);
for (k = in_loop_cnt; k != 0; k--) {
FLOAT32 tmp;
FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
data += (del << 1);
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += (del << 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * (del << 1);
data -= 3 * ((SIZE_T)del << 1);
tmp = (FLOAT32)(((FLOAT32)x1r * W1) + ((FLOAT32)x1i * W4));
x1i = (FLOAT32)(-((FLOAT32)x1r * W4) + (FLOAT32)x1i * W1);
@ -971,19 +965,19 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*data = x0r;
*(data + 1) = x0i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += (del << 1);
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += (del << 1);
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
@ -1005,7 +999,7 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
x0r = *ptr_y;
x0i = *(ptr_y + 1);
ptr_y += (del << 1);
ptr_y += ((SIZE_T)del << 1);
x1r = *ptr_y;
x1i = *(ptr_y + 1);
@ -1016,7 +1010,7 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*ptr_y = (x0r) - (x1r);
*(ptr_y + 1) = (x0i) - (x1i);
ptr_y -= (del << 1);
ptr_y -= ((SIZE_T)del << 1);
*ptr_y = (x0r) + (x1r);
*(ptr_y + 1) = (x0i) + (x1i);
@ -1031,7 +1025,7 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
x0r = *ptr_y;
x0i = *(ptr_y + 1);
ptr_y += (del << 1);
ptr_y += ((SIZE_T)del << 1);
x1r = *ptr_y;
x1i = *(ptr_y + 1);
@ -1042,7 +1036,7 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
*ptr_y = (x0r) - (x1r);
*(ptr_y + 1) = (x0i) - (x1i);
ptr_y -= (del << 1);
ptr_y -= ((SIZE_T)del << 1);
*ptr_y = (x0r) + (x1r);
*(ptr_y + 1) = (x0i) + (x1i);
@ -1051,8 +1045,7 @@ void ixheaac_cmplx_anal_fft_p2(FLOAT32 *ptr_x, FLOAT32 *ptr_y,
}
}
static PLATFORM_INLINE void ixheaac_aac_ld_dec_fft_3_float(FLOAT32 *inp,
FLOAT32 *op) {
static PLATFORM_INLINE void ixheaac_aac_ld_dec_fft_3_float(FLOAT32 *inp, FLOAT32 *op) {
FLOAT32 add_r, sub_r;
FLOAT32 add_i, sub_i;
FLOAT32 temp_real, temp_imag, temp;
@ -1213,4 +1206,4 @@ void ixheaac_cmplx_anal_fft_p3(FLOAT32 *x_in, FLOAT32 *x_out, WORD32 npoints) {
x_out[64 + i] = *y_p3++;
x_out[64 + i + 1] = *y_p3++;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -20,8 +20,8 @@
#ifndef IXHEAAC_ESBR_ROM_H
#define IXHEAAC_ESBR_ROM_H
extern const FLOAT32 ixheaac_sub_samp_qmf_window_coeff[40 + 80 + 120 + 160 +
200 + 240 + 320 + 400 + 440];
extern const FLOAT32
ixheaac_sub_samp_qmf_window_coeff[40 + 80 + 120 + 160 + 200 + 240 + 320 + 400 + 440];
extern const FLOAT32 ixheaac_random_phase[512][2];
extern const FLOAT32 ixheaac_hphase_tbl[2][8];

View file

@ -1207,4 +1207,4 @@ const FLOAT32 ixheaac_twid_tbl_fft_168[276] = {
0.900969f, -0.433884f, 0.974928f, -0.222521f, 1.000000f, -0.000000f, 0.974928f,
0.222521f, 0.900969f, 0.433884f,
};
};

View file

@ -113,8 +113,7 @@
#define MAX_NO_COLS_VALUE_BY_2 (MAX_NO_COLS_VALUE >> 1)
#define MAX_QMF_X_INBUF_SIZE MAX_NO_COLS_VALUE
#define MAX_QMF_X_OUTBUF_SIZE \
2 * MAX_QMF_X_INBUF_SIZE
#define MAX_QMF_X_OUTBUF_SIZE 2 * MAX_QMF_X_INBUF_SIZE
#define MAX_QMF_X_IN_REAL_BUF (NO_QMF_SYNTH_CHANNELS * MAX_QMF_X_INBUF_SIZE)
#define MAX_QMF_X_IN_IMAG_BUF (NO_QMF_SYNTH_CHANNELS * MAX_QMF_X_INBUF_SIZE)
@ -129,14 +128,11 @@
#define HBE_OPER_BLK_LEN_3 8
#define HBE_OPER_BLK_LEN_4 6
#define MAX_HBE_PERSISTENT_SIZE \
(MAX_QMF_X_INBUF_SIZE * sizeof(FLOAT32*) + \
MAX_QMF_X_OUTBUF_SIZE * sizeof(FLOAT32*) + \
MAX_QMF_X_IN_REAL_BUF * sizeof(FLOAT32) + \
MAX_QMF_X_IN_IMAG_BUF * sizeof(FLOAT32) + \
MAX_QMF_X_OUT_REAL_BUF * sizeof(FLOAT32) + \
MAX_QMF_X_OUT_IMAG_BUF * sizeof(FLOAT32) + X_INBUF_SIZE * sizeof(FLOAT32) + \
X_OUTBUF_SIZE * sizeof(FLOAT32))
#define MAX_HBE_PERSISTENT_SIZE \
(MAX_QMF_X_INBUF_SIZE * sizeof(FLOAT32*) + MAX_QMF_X_OUTBUF_SIZE * sizeof(FLOAT32*) + \
MAX_QMF_X_IN_REAL_BUF * sizeof(FLOAT32) + MAX_QMF_X_IN_IMAG_BUF * sizeof(FLOAT32) + \
MAX_QMF_X_OUT_REAL_BUF * sizeof(FLOAT32) + MAX_QMF_X_OUT_IMAG_BUF * sizeof(FLOAT32) + \
X_INBUF_SIZE * sizeof(FLOAT32) + X_OUTBUF_SIZE * sizeof(FLOAT32))
#define MAX_QMF_BUF_LEN 78

View file

@ -95,8 +95,6 @@
#define EXT_DATA_LENGTH 3
#define EXT_LDSAC_DATA 9
#define MIN(x, y) ((x) > (y) ? (y) : (x))
extern const ia_usac_samp_rate_info ixheaacd_samp_rate_info[];
WORD32 ixheaacd_aacdec_decodeframe(

View file

@ -127,8 +127,6 @@
#define LD_OBJ -2
#define MIN(x, y) ((x) > (y) ? (y) : (x))
IA_ERRORCODE ixheaacd_dec_mem_api(ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec,
WORD32 i_cmd, WORD32 i_idx, VOID *pv_value) {
pUWORD32 pui_value = pv_value;

View file

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Before After
Before After

BIN
docs/Api_flowchart_enc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
docs/IA-XHEAAC-Enc-API.pdf Normal file

Binary file not shown.

BIN
docs/IA-XHEAAC-Enc-GSG.pdf Normal file

Binary file not shown.

View file

@ -0,0 +1,32 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#ifndef min
#define min(a, b) ((a) > (b) ? (b) : (a))
#endif
#ifndef max
#define max(a, b) ((a) < (b) ? (b) : (a))
#endif
static FLOAT64 ixheaace_dmult(FLOAT64 a, FLOAT64 b) { return (a * b); }
static FLOAT64 ixheaace_dmac(FLOAT64 a, FLOAT64 b, FLOAT64 c) { return (a + b * c); }

128
encoder/iusace_bitbuffer.c Normal file
View file

@ -0,0 +1,128 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include "ixheaac_type_def.h"
#include "iusace_cnst.h"
#include "iusace_bitbuffer.h"
ia_bit_buf_struct *iusace_create_bit_buffer(ia_bit_buf_struct *it_bit_buf,
UWORD8 *ptr_bit_buf_base, UWORD32 bit_buffer_size,
WORD32 init) {
it_bit_buf->ptr_bit_buf_base = ptr_bit_buf_base;
it_bit_buf->ptr_bit_buf_end = ptr_bit_buf_base + bit_buffer_size - 1;
it_bit_buf->ptr_read_next = ptr_bit_buf_base;
it_bit_buf->ptr_write_next = ptr_bit_buf_base;
if (init) {
it_bit_buf->write_position = 7;
it_bit_buf->read_position = 7;
it_bit_buf->cnt_bits = 0;
it_bit_buf->size = bit_buffer_size * 8;
}
return (it_bit_buf);
}
VOID iusace_reset_bit_buffer(ia_bit_buf_struct *it_bit_buf) {
it_bit_buf->ptr_read_next = it_bit_buf->ptr_bit_buf_base;
it_bit_buf->ptr_write_next = it_bit_buf->ptr_bit_buf_base;
it_bit_buf->write_position = 7;
it_bit_buf->read_position = 7;
it_bit_buf->cnt_bits = 0;
return;
}
UWORD8 iusace_write_bits_buf(ia_bit_buf_struct *it_bit_buf, UWORD32 write_val, UWORD8 num_bits) {
WORD8 bits_to_write;
WORD32 write_position;
UWORD8 *ptr_write_next;
UWORD8 *ptr_bit_buf_end;
UWORD8 *ptr_bit_buf_base;
UWORD8 bits_written = num_bits;
if (it_bit_buf) {
it_bit_buf->cnt_bits += num_bits;
write_position = it_bit_buf->write_position;
ptr_write_next = it_bit_buf->ptr_write_next;
ptr_bit_buf_end = it_bit_buf->ptr_bit_buf_end;
ptr_bit_buf_base = it_bit_buf->ptr_bit_buf_base;
while (num_bits) {
UWORD8 tmp, msk;
bits_to_write = (WORD8)min(write_position + 1, num_bits);
tmp = (UWORD8)(write_val << (32 - num_bits) >> (32 - bits_to_write)
<< (write_position + 1 - bits_to_write));
msk = ~(((1 << bits_to_write) - 1) << (write_position + 1 - bits_to_write));
*ptr_write_next &= msk;
*ptr_write_next |= tmp;
write_position -= bits_to_write;
num_bits -= bits_to_write;
if (write_position < 0) {
write_position += 8;
ptr_write_next++;
if (ptr_write_next > ptr_bit_buf_end) {
ptr_write_next = ptr_bit_buf_base;
}
}
}
it_bit_buf->write_position = write_position;
it_bit_buf->ptr_write_next = ptr_write_next;
}
return (bits_written);
}
WORD32 iusace_write_escape_value(ia_bit_buf_struct *pstr_it_bit_buff, UWORD32 value,
UWORD8 no_bits1, UWORD8 no_bits2, UWORD8 no_bits3) {
WORD32 bit_cnt = 0;
UWORD32 esc_val = 0;
UWORD32 max_val1 = (1 << no_bits1) - 1;
UWORD32 max_val2 = (1 << no_bits2) - 1;
UWORD32 max_val3 = (1 << no_bits3) - 1;
esc_val = min(value, max_val1);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, esc_val, no_bits1);
if (esc_val == max_val1) {
value = value - esc_val;
esc_val = min(value, max_val2);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, esc_val, no_bits2);
if (esc_val == max_val2) {
value = value - esc_val;
esc_val = min(value, max_val3);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, esc_val, no_bits3);
}
}
return bit_cnt;
}

View file

@ -0,0 +1,42 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
typedef struct ia_bit_buf_struct {
UWORD8 *ptr_bit_buf_base;
UWORD8 *ptr_bit_buf_end;
UWORD8 *ptr_read_next;
UWORD8 *ptr_write_next;
WORD32 read_position;
WORD32 write_position;
WORD32 cnt_bits;
WORD32 size;
} ia_bit_buf_struct;
ia_bit_buf_struct *iusace_create_bit_buffer(ia_bit_buf_struct *it_bit_buf,
UWORD8 *ptr_bit_buf_base, UWORD32 bit_buffer_size,
WORD32 init);
VOID iusace_reset_bit_buffer(ia_bit_buf_struct *it_bit_buf);
UWORD8 iusace_write_bits_buf(ia_bit_buf_struct *it_bit_buf, UWORD32 write_val, UWORD8 num_bits);
WORD32 iusace_write_escape_value(ia_bit_buf_struct *pstr_it_bit_buff, UWORD32 value,
UWORD8 no_bits1, UWORD8 no_bits2, UWORD8 no_bits3);

204
encoder/iusace_cnst.h Normal file
View file

@ -0,0 +1,204 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef PI
#define PI (3.14159265358979323846f)
#endif
#define CORE_MODE_FD (0)
#define CORE_MODE_TD (1)
#define USAC_SWITCHED (0)
#define USAC_ONLY_FD (1)
#define USAC_ONLY_TD (2)
#define TREE_212 (0)
#define TREE_5151 (1)
#define TREE_5152 (2)
#define TREE_525 (3)
#define INVALID_TREE_CONFIG (-1)
#define ONLY_LONG_SEQUENCE (0)
#define LONG_START_SEQUENCE (1)
#define LONG_STOP_SEQUENCE (3)
#define STOP_START_SEQUENCE (4)
#define NSFB_SHORT (16)
#define MAX_SHORT_IN_LONG_BLOCK (8)
#define MAX_SHORT_WINDOWS (8)
#define MAX_SFB_LONG 51
#define FRAME_LEN_LONG 1024
#define FRAME_LEN_SHORT_768 (96)
#define MAX_TIME_CHANNELS (2)
#define MAX_SF_BANDS ((NSFB_SHORT + 1) * MAX_SHORT_IN_LONG_BLOCK)
#define MAX_SHIFT_LEN_LONG (4096)
#define TD_BUFFER_OFFSET (448 + 64)
#define MAX_EXTENSION_PAYLOADS MAX_TIME_CHANNELS
#define MAX_EXTENSION_PAYLOAD_LEN 6144 / 8 * MAX_TIME_CHANNELS
#define WIN_SEL_0 0
#define WIN_SEL_1 1
#define LEN_SUPERFRAME (1024)
#define LEN_SUPERFRAME_768 (768)
#define LEN_WIN_PLUS (512)
#define OVERLAP_WIN_SIZE_576 (576)
#define ORDER (16)
#define ORDER_BY_2 (8)
#define LEN_FRAME (256)
#define NUM_FRAMES (4)
#define MAX_NUM_SUBFR (4)
#define LEN_SUBFR (64)
#define N_MAX (LEN_SUPERFRAME)
#define FAC_LENGTH (LEN_FRAME / 2)
#define NUM_SUBFR_SUPERFRAME (NUM_FRAMES * MAX_NUM_SUBFR)
#define FDNS_RESOLUTION (64)
#define LEN_NEXT_HIGH_RATE (288)
#define LEN_LPC0 (256)
#define LEN_LP_WINDOW (448)
#define LEN_LP_WINDOW_HIGH_RATE (512)
#define SR_MIN (6000)
#define SR_MAX (32000)
#define FSCALE_DENOM (12800)
#define FAC_FSCALE_MAX (24000)
#define LEN_TOTAL_HIGH_RATE (ORDER + LEN_SUPERFRAME + LEN_NEXT_HIGH_RATE)
#define FILTER_DELAY (12)
#define TMIN (34)
#define TFR2 (128)
#define TFR1 (160)
#define TMAX (231)
#define T_UP_SAMP (4)
#define INTER_LP_FIL_ORDER (16)
#define INTER_LP_FIL_LEN (T_UP_SAMP * INTER_LP_FIL_ORDER + 1)
/* upto 410 for 24k sampling rate */
#define MAX_PITCH \
(TMAX + (6 * ((((FAC_FSCALE_MAX * TMIN) + (FSCALE_DENOM / 2)) / FSCALE_DENOM) - TMIN)))
/* upto 536 for 32k sampling rate */
#define MAX_PITCH1 (TMAX + (6 * ((((32000 * TMIN) + (FSCALE_DENOM / 2)) / FSCALE_DENOM) - TMIN)))
#define LEN_INTERPOL (16 + 1)
#define OPL_DECIM (2)
#define PREEMPH_FILT_FAC (0.68f)
#define TILT_FAC (0.68f)
#define PIT_SHARP (0.85f)
#define TILT_CODE (0.3f)
/* AMR_WB+ mode relative to AMR-WB core */
#define ACELP_CORE_MODE_9k6 (0)
#define ACELP_CORE_MODE_11k2 (1)
#define ACELP_CORE_MODE_12k8 (2)
#define ACELP_CORE_MODE_14k4 (3)
#define ACELP_CORE_MODE_16k (4)
#define ACELP_CORE_MODE_18k4 (5)
#define ACELP_NUM_BITS_20 (20)
#define ACELP_NUM_BITS_28 (28)
#define ACELP_NUM_BITS_36 (36)
#define ACELP_NUM_BITS_44 (44)
#define ACELP_NUM_BITS_52 (52)
#define ACELP_NUM_BITS_64 (64)
#define ACELP_NUM_BITS_72 (72)
#define ACELP_NUM_BITS_88 (88)
#define NUM_ACELP_CORE_MODES (6)
#define NBITS_MAX (48 * 80 + 46)
#define NBITS_MODE (4 * 2)
#define NBITS_LPC (46)
#define NUM_RE8_PRM (LEN_SUPERFRAME + (LEN_SUPERFRAME / 8))
#define NUM_TCX80_PRM (FAC_LENGTH + 2 + NUM_RE8_PRM)
#define NUM_TCX40_PRM (FAC_LENGTH + 2 + (NUM_RE8_PRM / 2))
#define NUM_TCX20_PRM (FAC_LENGTH + 2 + (320 + 320 / 8))
#define NUM_LPC_PRM (256)
#define MAX_NUM_TCX_PRM_PER_DIV (NUM_TCX20_PRM)
#define L_OLD_SPEECH_HIGH_RATE LEN_TOTAL_HIGH_RATE - LEN_SUPERFRAME
#define HP_ORDER (3)
#define LEN_INTERPOL1 (4)
#define NUM_OPEN_LOOP_LAGS (5)
#define OPEN_LOOP_LAG_MEDIAN (3)
#define DECIM2_FIR_FILT_MEM_SIZE (3)
#define NUM_QUANTIZATION_LEVEL (128)
#define LEV_DUR_MAX_ORDER (24)
#define PI_BY_6400 (PI / 6400.0)
#define LEN_FRAME_16K 320
#define ORDER_LP_FILT_16K (20)
#define LSP_2_LSF_SCALE (6400.0 / PI)
#define FREQ_MAX (6400.0f)
#define FREQ_DIV (400.0f)
#define CHEBYSHEV_NUM_ITER (4)
#define CHEBYSHEV_NUM_POINTS (100)
#define LSF_GAP (50.0f)
#define MAX_NUM_PULSES (24)
#define NPMAXPT ((MAX_NUM_PULSES + 4 - 1) / 4)
#define ACELP_GAIN_TBL_OFFSET (64)
#define ACELP_RANGE_GAIN_PT_IDX_SEARCH (NUM_QUANTIZATION_LEVEL - ACELP_GAIN_TBL_OFFSET)
#define ACELP_SEARCH_RANGE_QUANTIZER_IDX (128)
#define MAX_FLT_VAL (3.402823466e+38F)
#define MIN_FLT_VAL (1.175494351e-38F)
#define MIN_SHRT_VAL (-32768)
#define MAX_SHRT_VAL (32767)
#define LAG_MIN (64) // if 48k is max sr-- corresponding pitch_min/2
#define LAG_MAX (408) // if 48k is max sr-- corresponding pitch_max/2
#define LEN_CORR_R (LAG_MAX - LAG_MIN + 1)
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define CODE_BOOK_ALPHA_LAV 121
#define MDST_TX_FLAG (0)
#define MDCT_TX_FLAG (1)
#define NO_SBR_CCFL_768 (0)
#define NO_SBR_CCFL_1024 (1)
#define SBR_8_3 (2)
#define SBR_2_1 (3)
#define SBR_4_1 (4)
#define USACE_MAX_SCR_SIZE (733836)
#define USACE_SCR_STACK (10 * 1024)

132
encoder/iusace_config.h Normal file
View file

@ -0,0 +1,132 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#define BS_MAX_NUM_OUT_CHANNELS (255)
#define MINIMUM_BITRATE 8000
typedef struct {
FLOAT64 *p_fd_mdct_windowed_long_buf;
FLOAT64 *p_fd_mdct_windowed_short_buf;
FLOAT32 *p_fft_mdct_buf;
FLOAT64 *p_sort_grouping_scratch;
WORD32 *p_degroup_scratch;
WORD32 *p_arith_map_prev_scratch;
WORD32 *p_arith_map_pres_scratch;
FLOAT64 *p_noise_filling_highest_tone;
FLOAT32 *p_lpd_frm_enc_scratch;
FLOAT64 *p_quant_spectrum_spec_scratch;
UWORD8 *ptr_scratch_buf;
FLOAT32 *p_synth_tcx_buf;
FLOAT32 *p_synth_buf;
FLOAT32 *p_wsig_buf;
FLOAT32 *p_wsyn_buf;
FLOAT32 *p_wsyn_tcx_buf;
FLOAT32 *p_temp_wsyn_buf;
FLOAT32 *p_buf_aut_corr;
FLOAT32 *p_buf_synthesis_tool;
FLOAT32 *p_buf_speech;
FLOAT32 *p_buf_res;
FLOAT32 *p_buf_signal;
FLOAT32 *p_lp_filter_coeff;
FLOAT32 *p_lp_filter_coeff_q;
WORD32 *p_prm_tcx;
FLOAT32 *p_wsp_prev_buf;
FLOAT32 *p_xn2;
FLOAT32 *p_fac_dec;
FLOAT32 *p_right_fac_spec;
FLOAT32 *p_x2;
WORD32 *p_param;
FLOAT32 *p_x;
FLOAT32 *p_xn_2;
FLOAT32 *p_fac_window;
FLOAT32 *p_temp_mdct;
WORD16 *p_fac_bits_word;
FLOAT64 *p_left_fac_time_data;
FLOAT32 *p_left_fac_timedata_flt;
FLOAT32 *p_left_fac_spec;
FLOAT64 *p_fac_win;
WORD32 *p_fac_prm;
FLOAT32 *p_acelp_folded_scratch;
FLOAT32 *p_xn1_tcx;
FLOAT32 *p_xn_buf_tcx;
FLOAT32 *p_x_tcx;
FLOAT32 *p_x_tmp_tcx;
FLOAT32 *p_en_tcx;
FLOAT32 *p_alfd_gains_tcx;
FLOAT32 *p_sq_enc_tcx;
WORD32 *p_sq_quant_tcx;
FLOAT32 *p_gain1_tcx;
FLOAT32 *p_gain2_tcx;
FLOAT32 *p_facelp_tcx;
FLOAT32 *p_xn2_tcx;
FLOAT32 *p_fac_window_tcx;
FLOAT32 *p_x1_tcx;
FLOAT32 *p_x2_tcx;
WORD32 *p_y_tcx;
FLOAT32 *p_in_out_tcx;
FLOAT32 *p_time_signal;
FLOAT32 *p_complex_fft;
WORD32 *p_tonal_flag;
FLOAT32 *p_pow_spec;
FLOAT64 *p_tns_scratch;
FLOAT64 *p_tns_filter;
FLOAT32 *p_exp_spec;
FLOAT32 *p_mdct_spec_float;
FLOAT32 *p_fir_sig_buf;
FLOAT32 *p_sq_gain_en;
FLOAT32 *p_acelp_ir_buf;
FLOAT32 *p_acelp_exc_buf;
FLOAT32 *p_adjthr_ptr_exp_spec;
FLOAT32 *p_adjthr_mdct_spec_float;
WORD16 *p_adjthr_quant_spec_temp;
FLOAT64 *p_cmpx_mdct_temp_buf;
FLOAT32 *p_fft_p2_y;
FLOAT32 *p_fft_p3_data_3;
FLOAT32 *p_fft_p3_y;
FLOAT32 *p_tcx_input;
FLOAT32 *p_tcx_output;
FLOAT64 *p_reconstructed_time_signal[MAX_TIME_CHANNELS];
FLOAT32 *p_ol_pitch_buf_tmp;
FLOAT32 *p_ol_pitch_speech_buf;
FLOAT32 *p_ol_pitch_w_table;
FLOAT32 *p_ol_pitch_R;
FLOAT32 *p_ol_pitch_R0;
WORD32 *ptr_num_fac_bits;
WORD32 *ptr_tns_data_present;
FLOAT32 *ptr_tmp_lp_res;
FLOAT32 *ptr_sfb_form_fac[MAX_TIME_CHANNELS];
FLOAT32 *ptr_sfb_num_relevant_lines[MAX_TIME_CHANNELS];
FLOAT32 *ptr_sfb_ld_energy[MAX_TIME_CHANNELS];
WORD32 *ptr_num_scfs;
WORD32 *ptr_max_ch_dyn_bits;
FLOAT32 *ptr_ch_bit_dist;
pUWORD8 ptr_fd_scratch;
pUWORD8 ptr_lpd_scratch;
FLOAT32 *ptr_tcx_scratch;
FLOAT64 *ptr_tns_scratch;
WORD32 *ptr_next_win_scratch;
FLOAT32 *ptr_acelp_scratch;
FLOAT32 mixed_rad_fft[2 * LEN_SUPERFRAME];
pVOID drc_scratch;
VOID *ptr_drc_scratch_buf;
VOID *ptr_stack_mem;
} iusace_scratch_mem;

843
encoder/iusace_fft.c Normal file
View file

@ -0,0 +1,843 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include "ixheaac_type_def.h"
#include "ixheaace_adjust_threshold_data.h"
#include "iusace_cnst.h"
#include "iusace_rom.h"
#include "iusace_bitbuffer.h"
#include "iusace_config.h"
#include "iusace_fft.h"
#include "iusace_basic_ops_flt.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
#include "ixheaac_basic_ops32.h"
#include "ixheaace_common_utils.h"
#define DIG_REV(i, m, j) \
do { \
unsigned _ = (i); \
_ = ((_ & 0x33333333) << 2) | ((_ & ~0x33333333) >> 2); \
_ = ((_ & 0x0F0F0F0F) << 4) | ((_ & ~0x0F0F0F0F) >> 4); \
_ = ((_ & 0x00FF00FF) << 8) | ((_ & ~0x00FF00FF) >> 8); \
(j) = _ >> (m); \
} while (0)
static PLATFORM_INLINE WORD8 iusace_calc_norm(WORD32 a) {
WORD8 norm_val;
if (a == 0) {
norm_val = 31;
} else {
if (a == (WORD32)0xffffffffL) {
norm_val = 31;
} else {
if (a < 0) {
a = ~a;
}
for (norm_val = 0; a < (WORD32)0x40000000L; norm_val++) {
a <<= 1;
}
}
}
return norm_val;
}
static PLATFORM_INLINE VOID iusace_complex_3point_fft(FLOAT32 *ptr_in, FLOAT32 *ptr_out) {
FLOAT32 add_r, sub_r;
FLOAT32 add_i, sub_i;
FLOAT32 x01r, x01i, temp;
FLOAT32 p1, p2, p3, p4;
FLOAT64 sinmu;
sinmu = 0.866025403784439;
x01r = ptr_in[0] + ptr_in[2];
x01i = ptr_in[1] + ptr_in[3];
add_r = ptr_in[2] + ptr_in[4];
add_i = ptr_in[3] + ptr_in[5];
sub_r = ptr_in[2] - ptr_in[4];
sub_i = ptr_in[3] - ptr_in[5];
p1 = add_r / (FLOAT32)2.0;
p4 = add_i / (FLOAT32)2.0;
p2 = (FLOAT32)((FLOAT64)sub_i * sinmu);
p3 = (FLOAT32)((FLOAT64)sub_r * sinmu);
temp = ptr_in[0] - p1;
ptr_out[0] = x01r + ptr_in[4];
ptr_out[1] = x01i + ptr_in[5];
ptr_out[2] = temp + p2;
ptr_out[3] = (ptr_in[1] - p3) - p4;
ptr_out[4] = temp - p2;
ptr_out[5] = (ptr_in[1] + p3) - p4;
return;
}
VOID iusace_complex_fft_p2(FLOAT32 *ptr_x, WORD32 nlength, FLOAT32 *scratch_fft_p2_y) {
WORD32 i, j, k, n_stages, h2;
FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
FLOAT32 tmp;
WORD32 del, nodespacing, in_loop_cnt;
WORD32 not_power_4;
WORD32 dig_rev_shift;
FLOAT32 *y = scratch_fft_p2_y;
WORD32 mpass = nlength;
WORD32 npoints = nlength;
FLOAT32 *ptr_y = y;
const FLOAT64 *ptr_w;
dig_rev_shift = iusace_calc_norm(mpass) + 1 - 16;
n_stages = 30 - iusace_calc_norm(mpass);
not_power_4 = n_stages & 1;
n_stages = n_stages >> 1;
ptr_w = iusace_twiddle_table_fft_32x32;
if (dig_rev_shift < 0) {
dig_rev_shift = 0;
}
for (i = 0; i < npoints; i += 4) {
FLOAT32 *inp = ptr_x;
FLOAT32 tmk;
DIG_REV(i, dig_rev_shift, h2);
if (not_power_4) {
h2 += 1;
h2 &= ~1;
}
inp += (h2);
x0r = *inp;
x0i = *(inp + 1);
inp += (npoints >> 1);
x1r = *inp;
x1i = *(inp + 1);
inp += (npoints >> 1);
x2r = *inp;
x2i = *(inp + 1);
inp += (npoints >> 1);
x3r = *inp;
x3i = *(inp + 1);
x0r = x0r + x2r;
x0i = x0i + x2i;
tmk = x0r - x2r;
x2r = tmk - x2r;
tmk = x0i - x2i;
x2i = tmk - x2i;
x1r = x1r + x3r;
x1i = x1i + x3i;
tmk = x1r - x3r;
x3r = tmk - x3r;
tmk = x1i - x3i;
x3i = tmk - x3i;
x0r = x0r + x1r;
x0i = x0i + x1i;
tmk = x0r - x1r;
x1r = tmk - x1r;
tmk = x0i - x1i;
x1i = tmk - x1i;
x2r = x2r + x3i;
x2i = x2i - x3r;
tmk = x2r - x3i;
x3i = tmk - x3i;
tmk = x2i + x3r;
x3r = tmk + x3r;
*ptr_y++ = x0r;
*ptr_y++ = x0i;
*ptr_y++ = x2r;
*ptr_y++ = x2i;
*ptr_y++ = x1r;
*ptr_y++ = x1i;
*ptr_y++ = x3i;
*ptr_y++ = x3r;
}
ptr_y -= 2 * npoints;
del = 4;
nodespacing = 64;
in_loop_cnt = npoints >> 4;
for (i = n_stages - 1; i > 0; i--) {
const FLOAT64 *twiddles = ptr_w;
FLOAT32 *data = ptr_y;
FLOAT64 w_1, w_2, w_3, w_4, w_5, w_6;
WORD32 sec_loop_cnt;
for (k = in_loop_cnt; k != 0; k--) {
x0r = (*data);
x0i = (*(data + 1));
data += ((SIZE_T)del << 1);
x1r = (*data);
x1i = (*(data + 1));
data += ((SIZE_T)del << 1);
x2r = (*data);
x2i = (*(data + 1));
data += ((SIZE_T)del << 1);
x3r = (*data);
x3i = (*(data + 1));
data -= 3 * (del << 1);
x0r = x0r + x2r;
x0i = x0i + x2i;
x2r = x0r - (x2r * 2);
x2i = x0i - (x2i * 2);
x1r = x1r + x3r;
x1i = x1i + x3i;
x3r = x1r - (x3r * 2);
x3i = x1i - (x3i * 2);
x0r = x0r + x1r;
x0i = x0i + x1i;
x1r = x0r - (x1r * 2);
x1i = x0i - (x1i * 2);
x2r = x2r + x3i;
x2i = x2i - x3r;
x3i = x2r - (x3i * 2);
x3r = x2i + (x3r * 2);
*data = x0r;
*(data + 1) = x0i;
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += ((SIZE_T)del << 1);
}
data = ptr_y + 2;
sec_loop_cnt = (nodespacing * del);
sec_loop_cnt = (sec_loop_cnt / 4) + (sec_loop_cnt / 8) - (sec_loop_cnt / 16) +
(sec_loop_cnt / 32) - (sec_loop_cnt / 64) + (sec_loop_cnt / 128) -
(sec_loop_cnt / 256);
for (j = nodespacing; j <= sec_loop_cnt; j += nodespacing) {
w_1 = *(twiddles + j);
w_4 = *(twiddles + j + 257);
w_2 = *(twiddles + ((SIZE_T)j << 1));
w_5 = *(twiddles + ((SIZE_T)j << 1) + 257);
w_3 = *(twiddles + j + ((SIZE_T)j << 1));
w_6 = *(twiddles + j + ((SIZE_T)j << 1) + 257);
for (k = in_loop_cnt; k != 0; k--) {
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * (del << 1);
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x1r, w_1) - ixheaace_dmult((FLOAT64)x1i, w_4));
x1i = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x1r, w_4), (FLOAT64)x1i, w_1);
x1r = tmp;
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x2r, w_2) - ixheaace_dmult((FLOAT64)x2i, w_5));
x2i = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x2r, w_5), (FLOAT64)x2i, w_2);
x2r = tmp;
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x3r, w_3) - ixheaace_dmult((FLOAT64)x3i, w_6));
x3i = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x3r, w_6), (FLOAT64)x3i, w_3);
x3r = tmp;
x0r = (*data);
x0i = (*(data + 1));
x0r = x0r + (x2r);
x0i = x0i + (x2i);
x2r = x0r - (x2r * 2);
x2i = x0i - (x2i * 2);
x1r = x1r + x3r;
x1i = x1i + x3i;
x3r = x1r - (x3r * 2);
x3i = x1i - (x3i * 2);
x0r = x0r + (x1r);
x0i = x0i + (x1i);
x1r = x0r - (x1r * 2);
x1i = x0i - (x1i * 2);
x2r = x2r + (x3i);
x2i = x2i - (x3r);
x3i = x2r - (x3i * 2);
x3r = x2i + (x3r * 2);
*data = x0r;
*(data + 1) = x0i;
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
}
for (; j <= (nodespacing * del) >> 1; j += nodespacing) {
w_1 = *(twiddles + j);
w_4 = *(twiddles + j + 257);
w_2 = *(twiddles + ((SIZE_T)j << 1));
w_5 = *(twiddles + ((SIZE_T)j << 1) + 257);
w_3 = *(twiddles + j + ((SIZE_T)j << 1) - 256);
w_6 = *(twiddles + j + ((SIZE_T)j << 1) + 1);
for (k = in_loop_cnt; k != 0; k--) {
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * (del << 1);
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x1r, w_1) - ixheaace_dmult((FLOAT64)x1i, w_4));
x1i = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x1r, w_4), (FLOAT64)x1i, w_1);
x1r = tmp;
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x2r, w_2) - ixheaace_dmult((FLOAT64)x2i, w_5));
x2i = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x2r, w_5), (FLOAT64)x2i, w_2);
x2r = tmp;
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x3r, w_6) + ixheaace_dmult((FLOAT64)x3i, w_3));
x3i = (FLOAT32)(-ixheaace_dmult((FLOAT64)x3r, w_3) + ixheaace_dmult((FLOAT64)x3i, w_6));
x3r = tmp;
x0r = (*data);
x0i = (*(data + 1));
x0r = x0r + (x2r);
x0i = x0i + (x2i);
x2r = x0r - (x2r * 2);
x2i = x0i - (x2i * 2);
x1r = x1r + x3r;
x1i = x1i + x3i;
x3r = x1r - (x3r * 2);
x3i = x1i - (x3i * 2);
x0r = x0r + (x1r);
x0i = x0i + (x1i);
x1r = x0r - (x1r * 2);
x1i = x0i - (x1i * 2);
x2r = x2r + (x3i);
x2i = x2i - (x3r);
x3i = x2r - (x3i * 2);
x3r = x2i + (x3r * 2);
*data = x0r;
*(data + 1) = x0i;
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
}
for (; j <= sec_loop_cnt * 2; j += nodespacing) {
w_1 = *(twiddles + j);
w_4 = *(twiddles + j + 257);
w_2 = *(twiddles + ((SIZE_T)j << 1) - 256);
w_5 = *(twiddles + ((SIZE_T)j << 1) + 1);
w_3 = *(twiddles + j + ((SIZE_T)j << 1) - 256);
w_6 = *(twiddles + j + ((SIZE_T)j << 1) + 1);
for (k = in_loop_cnt; k != 0; k--) {
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * (del << 1);
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x1r, w_1) - ixheaace_dmult((FLOAT64)x1i, w_4));
x1i = (FLOAT32)ixheaace_dmac(ixheaace_dmult(x1r, w_4), x1i, w_1);
x1r = tmp;
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x2r, w_5) + ixheaace_dmult((FLOAT64)x2i, w_2));
x2i = (FLOAT32)(-ixheaace_dmult(x2r, w_2) + ixheaace_dmult(x2i, w_5));
x2r = tmp;
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x3r, w_6) + ixheaace_dmult((FLOAT64)x3i, w_3));
x3i = (FLOAT32)(-ixheaace_dmult((FLOAT64)x3r, w_3) + ixheaace_dmult((FLOAT64)x3i, w_6));
x3r = tmp;
x0r = (*data);
x0i = (*(data + 1));
x0r = x0r + (x2r);
x0i = x0i + (x2i);
x2r = x0r - (x2r * 2);
x2i = x0i - (x2i * 2);
x1r = x1r + x3r;
x1i = x1i + x3i;
x3r = x1r - (x3r * 2);
x3i = x1i - (x3i * 2);
x0r = x0r + (x1r);
x0i = x0i + (x1i);
x1r = x0r - (x1r * 2);
x1i = x0i - (x1i * 2);
x2r = x2r + (x3i);
x2i = x2i - (x3r);
x3i = x2r - (x3i * 2);
x3r = x2i + (x3r * 2);
*data = x0r;
*(data + 1) = x0i;
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
}
for (; j < nodespacing * del; j += nodespacing) {
w_1 = *(twiddles + j);
w_4 = *(twiddles + j + 257);
w_2 = *(twiddles + ((SIZE_T)j << 1) - 256);
w_5 = *(twiddles + ((SIZE_T)j << 1) + 1);
w_3 = *(twiddles + j + ((SIZE_T)j << 1) - 512);
w_6 = *(twiddles + j + ((SIZE_T)j << 1) - 512 + 257);
for (k = in_loop_cnt; k != 0; k--) {
data += ((SIZE_T)del << 1);
x1r = *data;
x1i = *(data + 1);
data += ((SIZE_T)del << 1);
x2r = *data;
x2i = *(data + 1);
data += ((SIZE_T)del << 1);
x3r = *data;
x3i = *(data + 1);
data -= 3 * ((SIZE_T)del << 1);
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x1r, w_1) - ixheaace_dmult((FLOAT64)x1i, w_4));
x1i = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x1r, w_4), (FLOAT64)x1i, w_1);
x1r = tmp;
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x2r, w_5) + ixheaace_dmult((FLOAT64)x2i, w_2));
x2i = (FLOAT32)(-ixheaace_dmult((FLOAT64)x2r, w_2) + ixheaace_dmult((FLOAT64)x2i, w_5));
x2r = tmp;
tmp = (FLOAT32)(-ixheaace_dmult((FLOAT64)x3r, w_3) + ixheaace_dmult((FLOAT64)x3i, w_6));
x3i = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x3r, w_6), (FLOAT64)x3i, w_3);
x3r = tmp;
x0r = (*data);
x0i = (*(data + 1));
x0r = x0r + (x2r);
x0i = x0i + (x2i);
x2r = x0r - (x2r * 2);
x2i = x0i - (x2i * 2);
x1r = x1r + x3r;
x1i = x1i - x3i;
x3r = x1r - (x3r * 2);
x3i = x1i + (x3i * 2);
x0r = x0r + (x1r);
x0i = x0i + (x1i);
x1r = x0r - (x1r * 2);
x1i = x0i - (x1i * 2);
x2r = x2r + (x3i);
x2i = x2i - (x3r);
x3i = x2r - (x3i * 2);
x3r = x2i + (x3r * 2);
*data = x0r;
*(data + 1) = x0i;
data += ((SIZE_T)del << 1);
*data = x2r;
*(data + 1) = x2i;
data += ((SIZE_T)del << 1);
*data = x1r;
*(data + 1) = x1i;
data += ((SIZE_T)del << 1);
*data = x3i;
*(data + 1) = x3r;
data += ((SIZE_T)del << 1);
}
data -= 2 * npoints;
data += 2;
}
nodespacing >>= 2;
del <<= 2;
in_loop_cnt >>= 2;
}
if (not_power_4) {
const FLOAT64 *twiddles = ptr_w;
nodespacing <<= 1;
for (j = del / 2; j != 0; j--) {
FLOAT64 w_1 = *twiddles;
FLOAT64 w_4 = *(twiddles + 257);
twiddles += nodespacing;
x0r = *ptr_y;
x0i = *(ptr_y + 1);
ptr_y += ((SIZE_T)del << 1);
x1r = *ptr_y;
x1i = *(ptr_y + 1);
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x1r, w_1) - ixheaace_dmult((FLOAT64)x1i, w_4));
x1i = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x1r, w_4), (FLOAT64)x1i, w_1);
x1r = tmp;
*ptr_y = (x0r) - (x1r);
*(ptr_y + 1) = (x0i) - (x1i);
ptr_y -= ((SIZE_T)del << 1);
*ptr_y = (x0r) + (x1r);
*(ptr_y + 1) = (x0i) + (x1i);
ptr_y += 2;
}
twiddles = ptr_w;
for (j = del / 2; j != 0; j--) {
FLOAT64 w_1 = *twiddles;
FLOAT64 w_4 = *(twiddles + 257);
twiddles += nodespacing;
x0r = *ptr_y;
x0i = *(ptr_y + 1);
ptr_y += ((SIZE_T)del << 1);
x1r = *ptr_y;
x1i = *(ptr_y + 1);
tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x1r, w_4) + ixheaace_dmult((FLOAT64)x1i, w_1));
x1i = (FLOAT32)(-ixheaace_dmult((FLOAT64)x1r, w_1) + ixheaace_dmult((FLOAT64)x1i, w_4));
x1r = tmp;
*ptr_y = (x0r) - (x1r);
*(ptr_y + 1) = (x0i) - (x1i);
ptr_y -= ((SIZE_T)del << 1);
*ptr_y = (x0r) + (x1r);
*(ptr_y + 1) = (x0i) + (x1i);
ptr_y += 2;
}
}
for (i = 0; i < nlength; i++) {
*(ptr_x + 2 * i) = y[2 * i];
*(ptr_x + 2 * i + 1) = y[2 * i + 1];
}
}
static VOID iusace_complex_fft_p3(FLOAT32 *data, WORD32 nlength,
iusace_scratch_mem *pstr_scratch) {
WORD32 i, j;
FLOAT32 *data_3 = pstr_scratch->p_fft_p3_data_3;
FLOAT32 *y = pstr_scratch->p_fft_p3_y;
WORD32 cnfac;
WORD32 mpass = nlength;
FLOAT32 *ptr_x = data;
FLOAT32 *ptr_y = y;
cnfac = 0;
while (mpass % 3 == 0) {
mpass /= 3;
cnfac++;
}
for (i = 0; i < 3 * cnfac; i++) {
for (j = 0; j < mpass; j++) {
data_3[2 * j] = data[3 * (2 * j) + (2 * i)];
data_3[2 * j + 1] = data[3 * (2 * j) + 1 + (2 * i)];
}
iusace_complex_fft_p2(data_3, mpass, pstr_scratch->p_fft_p2_y);
for (j = 0; j < mpass; j++) {
data[3 * (2 * j) + (2 * i)] = data_3[2 * j];
data[3 * (2 * j) + 1 + (2 * i)] = data_3[2 * j + 1];
}
}
{
const FLOAT64 *w1r, *w1i;
FLOAT32 tmp;
w1r = iusace_twiddle_table_3pr;
w1i = iusace_twiddle_table_3pi;
for (i = 0; i < nlength; i += 3) {
tmp = (FLOAT32)((FLOAT64)data[2 * i] * (*w1r) - (FLOAT64)data[2 * i + 1] * (*w1i));
data[2 * i + 1] =
(FLOAT32)((FLOAT64)data[2 * i] * (*w1i) + (FLOAT64)data[2 * i + 1] * (*w1r));
data[2 * i] = tmp;
w1r++;
w1i++;
tmp = (FLOAT32)((FLOAT64)data[2 * (i + 1)] * (*w1r) -
(FLOAT64)data[2 * (i + 1) + 1] * (*w1i));
data[2 * (i + 1) + 1] = (FLOAT32)((FLOAT64)data[2 * (i + 1)] * (*w1i) +
(FLOAT64)data[2 * (i + 1) + 1] * (*w1r));
data[2 * (i + 1)] = tmp;
w1r++;
w1i++;
tmp = (FLOAT32)((FLOAT64)data[2 * (i + 2)] * (*w1r) -
(FLOAT64)data[2 * (i + 2) + 1] * (*w1i));
data[2 * (i + 2) + 1] = (FLOAT32)((FLOAT64)data[2 * (i + 2)] * (*w1i) +
(FLOAT64)data[2 * (i + 2) + 1] * (*w1r));
data[2 * (i + 2)] = tmp;
w1r += 3 * (128 / mpass - 1) + 1;
w1i += 3 * (128 / mpass - 1) + 1;
}
}
for (i = 0; i < mpass; i++) {
iusace_complex_3point_fft(ptr_x, ptr_y);
ptr_x = ptr_x + 6;
ptr_y = ptr_y + 6;
}
for (i = 0; i < mpass; i++) {
data[2 * i] = y[6 * i];
data[2 * i + 1] = y[6 * i + 1];
}
for (i = 0; i < mpass; i++) {
data[2 * (i + mpass)] = y[6 * i + 2];
data[2 * (i + mpass) + 1] = y[6 * i + 3];
}
for (i = 0; i < mpass; i++) {
data[2 * (i + 2 * mpass)] = y[6 * i + 4];
data[2 * (i + 2 * mpass) + 1] = y[6 * i + 5];
}
}
VOID iusace_complex_fft_p3_no_scratch(FLOAT32 *data, WORD32 nlength) {
WORD32 i, j;
FLOAT32 data_3[800];
FLOAT32 y[1024];
FLOAT32 p_fft_p2_y[2048];
WORD32 cnfac;
WORD32 mpass = nlength;
FLOAT32 *ptr_x = data;
FLOAT32 *ptr_y = y;
cnfac = 0;
while (mpass % 3 == 0) {
mpass /= 3;
cnfac++;
}
for (i = 0; i < 3 * cnfac; i++) {
for (j = 0; j < mpass; j++) {
data_3[2 * j] = data[3 * (2 * j) + (2 * i)];
data_3[2 * j + 1] = data[3 * (2 * j) + 1 + (2 * i)];
}
iusace_complex_fft_p2(data_3, mpass, p_fft_p2_y);
for (j = 0; j < mpass; j++) {
data[3 * (2 * j) + (2 * i)] = data_3[2 * j];
data[3 * (2 * j) + 1 + (2 * i)] = data_3[2 * j + 1];
}
}
{
const FLOAT64 *w1r, *w1i;
FLOAT32 tmp;
w1r = iusace_twiddle_table_3pr;
w1i = iusace_twiddle_table_3pi;
for (i = 0; i < nlength; i += 3) {
tmp = (FLOAT32)((FLOAT64)data[2 * i] * (*w1r) - (FLOAT64)data[2 * i + 1] * (*w1i));
data[2 * i + 1] =
(FLOAT32)((FLOAT64)data[2 * i] * (*w1i) + (FLOAT64)data[2 * i + 1] * (*w1r));
data[2 * i] = tmp;
w1r++;
w1i++;
tmp = (FLOAT32)((FLOAT64)data[2 * (i + 1)] * (*w1r) -
(FLOAT64)data[2 * (i + 1) + 1] * (*w1i));
data[2 * (i + 1) + 1] = (FLOAT32)((FLOAT64)data[2 * (i + 1)] * (*w1i) +
(FLOAT64)data[2 * (i + 1) + 1] * (*w1r));
data[2 * (i + 1)] = tmp;
w1r++;
w1i++;
tmp = (FLOAT32)((FLOAT64)data[2 * (i + 2)] * (*w1r) -
(FLOAT64)data[2 * (i + 2) + 1] * (*w1i));
data[2 * (i + 2) + 1] = (FLOAT32)((FLOAT64)data[2 * (i + 2)] * (*w1i) +
(FLOAT64)data[2 * (i + 2) + 1] * (*w1r));
data[2 * (i + 2)] = tmp;
w1r += 3 * (128 / mpass - 1) + 1;
w1i += 3 * (128 / mpass - 1) + 1;
}
}
for (i = 0; i < mpass; i++) {
iusace_complex_3point_fft(ptr_x, ptr_y);
ptr_x = ptr_x + 6;
ptr_y = ptr_y + 6;
}
for (i = 0; i < mpass; i++) {
data[2 * i] = y[6 * i];
data[2 * i + 1] = y[6 * i + 1];
}
for (i = 0; i < mpass; i++) {
data[2 * (i + mpass)] = y[6 * i + 2];
data[2 * (i + mpass) + 1] = y[6 * i + 3];
}
for (i = 0; i < mpass; i++) {
data[2 * (i + 2 * mpass)] = y[6 * i + 4];
data[2 * (i + 2 * mpass) + 1] = y[6 * i + 5];
}
}
VOID iusace_complex_fft(FLOAT32 *data, WORD32 nlength, iusace_scratch_mem *pstr_scratch) {
if (nlength & (nlength - 1)) {
iusace_complex_fft_p3(data, nlength, pstr_scratch);
} else {
iusace_complex_fft_p2(data, nlength, pstr_scratch->p_fft_p2_y);
}
}
VOID iusace_complex_fft_2048(FLOAT32 *ptr_x, FLOAT32 *scratch_fft) {
WORD32 i;
FLOAT32 re, im, c_v, s_v, tmp_re, tmp_im;
FLOAT32 *ptr_re, *ptr_im, *ptr_re_h, *ptr_im_h;
FLOAT32 *ptr_cos_val, *ptr_sin_val;
iusace_complex_fft_p2(ptr_x, 1024, scratch_fft);
iusace_complex_fft_p2(ptr_x + 2048, 1024, scratch_fft);
ptr_re = ptr_x;
ptr_im = ptr_x + 1;
ptr_re_h = ptr_x + 2048;
ptr_im_h = ptr_x + 2048 + 1;
ptr_cos_val = (FLOAT32 *)&iusace_twiddle_cos_2048[0];
ptr_sin_val = (FLOAT32 *)&iusace_twiddle_sin_2048[0];
for (i = 0; i < 1024; i++) {
re = *ptr_re_h;
im = *ptr_im_h;
c_v = ptr_cos_val[i];
s_v = ptr_sin_val[i];
tmp_re = (re * c_v) + (im * s_v);
tmp_im = -(re * s_v) + (im * c_v);
re = *ptr_re;
im = *ptr_im;
*ptr_re = re + tmp_re;
*ptr_im = im + tmp_im;
*ptr_re_h = re - tmp_re;
*ptr_im_h = im - tmp_im;
ptr_re += 2;
ptr_im += 2;
ptr_re_h += 2;
ptr_im_h += 2;
}
}

36
encoder/iusace_fft.h Normal file
View file

@ -0,0 +1,36 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#define C70 (-0.1666667014f) //(cos(u) + cos(2 * u) + cos(3 * u)) / 3;
#define C71 (0.7901564837f) //(2 * cos(u) - cos(2 * u) - cos(3 * u)) / 3;
#define C72 (0.0558542535f) //(cos(u) - 2 * cos(2 * u) + cos(3 * u)) / 3;
#define C73 (0.7343022227f) //(cos(u) + cos(2 * u) - 2 * cos(3 * u)) / 3;
#define C74 (-0.4409585893f) //(sin(u) + sin(2 * u) - sin(3 * u)) / 3;
#define C75 (-0.3408728838f) //(2 * sin(u) - sin(2 * u) + sin(3 * u)) / 3;
#define C76 (0.5339693427f) //(sin(u) - 2 * sin(2 * u) - sin(3 * u)) / 3;
#define C77 (-0.8748422265f) //(sin(u) + sin(2 * u) + 2 * sin(3 * u)) / 3;
#define CPLX_MPY_FFT(re, im, a, b, c, d) \
{ \
re = ((a * c) - (b * d)); \
im = ((a * d) + (b * c)); \
}

8224
encoder/iusace_rom.c Normal file

File diff suppressed because it is too large Load diff

30
encoder/iusace_rom.h Normal file
View file

@ -0,0 +1,30 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
extern const UWORD32 iusace_sampl_freq_table[];
extern const FLOAT64 iusace_twiddle_table_fft_32x32[514];
extern const FLOAT64 iusace_twiddle_table_3pr[1155];
extern const FLOAT64 iusace_twiddle_table_3pi[1155];
extern const FLOAT64 iusace_twiddle_sin_2048[1024];
extern const FLOAT64 iusace_twiddle_cos_2048[1024];
extern const FLOAT32 ia_fft_twiddle_table_float[514];
extern const FLOAT32 ia_mixed_rad_twiddle_cos[16384];
extern const FLOAT32 ia_mixed_rad_twiddle_sin[16384];

88
encoder/iusace_type_def.h Normal file
View file

@ -0,0 +1,88 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
/****************************************************************************/
/* types type define prefix examples
* bytes */
/************************ *********** ****** **************** ***** */
#define SIZE_T size_t
typedef char CHAR8; /* c CHAR8 c_name 1 */
typedef char *pCHAR8; /* pc pCHAR8 pc_nmae 1 */
typedef signed char WORD8; /* b WORD8 b_name 1 */
typedef signed char *pWORD8; /* pb pWORD8 pb_nmae 1 */
typedef unsigned char UWORD8; /* ub UWORD8 ub_count 1 */
typedef unsigned char *pUWORD8; /* pub pUWORD8 pub_count 1 */
typedef signed short WORD16; /* s WORD16 s_count 2 */
typedef signed short *pWORD16; /* ps pWORD16 ps_count 2 */
typedef unsigned short UWORD16; /* us UWORD16 us_count 2 */
typedef unsigned short *pUWORD16; /* pus pUWORD16 pus_count 2 */
typedef signed int WORD24; /* k WORD24 k_count 3 */
typedef signed int *pWORD24; /* pk pWORD24 pk_count 3 */
typedef unsigned int UWORD24; /* uk UWORD24 uk_count 3 */
typedef unsigned int *pUWORD24; /* puk pUWORD24 puk_count 3 */
typedef signed int WORD32; /* i WORD32 i_count 4 */
typedef signed int *pWORD32; /* pi pWORD32 pi_count 4 */
typedef unsigned int UWORD32; /* ui UWORD32 ui_count 4 */
typedef unsigned int *pUWORD32; /* pui pUWORD32 pui_count 4 */
typedef signed long long WORD40; /* m WORD40 m_count 5 */
typedef signed long long *pWORD40; /* pm pWORD40 pm_count 5 */
typedef unsigned long long UWORD40; /* um UWORD40 um_count 5 */
typedef unsigned long long *pUWORD40; /* pum pUWORD40 pum_count 5 */
typedef signed long long WORD64; /* h WORD64 h_count 8 */
typedef signed long long *pWORD64; /* ph pWORD64 ph_count 8 */
typedef unsigned long long UWORD64; /* uh UWORD64 uh_count 8 */
typedef unsigned long long *pUWORD64; /* puh pUWORD64 puh_count 8 */
typedef float FLOAT32; /* f FLOAT32 f_count 4
*/
typedef float *pFLOAT32; /* pf pFLOAT32 pf_count 4 */
typedef double FLOAT64; /* d UFLOAT64 d_count 8
*/
typedef double *pFlOAT64; /* pd pFLOAT64 pd_count 8 */
typedef void VOID; /* v VOID v_flag 4 */
typedef void *pVOID; /* pv pVOID pv_flag 4 */
/* variable size types: platform optimized implementation */
typedef signed int BOOL; /* bool BOOL bool_true */
typedef unsigned int UBOOL; /* ubool BOOL ubool_true */
typedef signed int FLAG; /* flag FLAG flag_false */
typedef unsigned int UFLAG; /* uflag FLAG uflag_false */
typedef signed int LOOPIDX; /* lp LOOPIDX lp_index */
typedef unsigned int ULOOPIDX; /* ulp SLOOPIDX ulp_index */
typedef signed int WORD; /* lp LOOPIDX lp_index */
typedef unsigned int UWORD; /* ulp SLOOPIDX ulp_index */
typedef LOOPIDX LOOPINDEX; /* lp LOOPIDX lp_index */
typedef ULOOPIDX ULOOPINDEX; /* ulp SLOOPIDX ulp_index */
typedef signed int IA_ERRORCODE;
#define PLATFORM_INLINE __inline

View file

@ -0,0 +1,43 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
IA_ERRORCODE ia_enhaacplus_enc_aac_enc_open(iexheaac_encoder_str **ppstr_exheaac_encoder,
const iaace_config config,
iaace_scratch *pstr_aac_scratch,
ixheaace_aac_tables *pstr_aac_tabs, WORD32 ele_type,
WORD32 element_instance_tag, WORD32 init, WORD32 aot);
IA_ERRORCODE ia_enhaacplus_enc_aac_core_encode(
iexheaac_encoder_str **pstr_aac_enc, FLOAT32 *ptr_time_signal, UWORD32 time_sn_stride,
const UWORD8 *ptr_anc_bytes, UWORD8 *num_anc_bytes, UWORD8 *ptr_out_bytes,
WORD32 *num_out_bytes, ixheaace_aac_tables *pstr_aac_tables, VOID *ptr_bit_stream_handle,
VOID *ptr_bit_stream, FLAG flag_last_element, WORD32 *write_program_config_element,
WORD32 i_num_coup_channels, WORD32 i_channels_mask, WORD32 ele_idx, WORD32 *total_fill_bits,
WORD32 total_channels, WORD32 aot, WORD32 adts_flag, WORD32 num_bs_elements);
VOID ia_enhaacplus_enc_aac_enc_close(iexheaac_encoder_str *pstr_exheaac_encoder);
IA_ERRORCODE ia_enhaacplus_enc_finalize_bit_consumption(ixheaace_qc_state *pstr_qc_kernel,
ixheaace_qc_out *pstr_qc_out,
WORD32 flag_last_element, WORD32 cnt_bits,
WORD32 *tot_fill_bits,
iexheaac_encoder_str **pstr_aac_enc,
WORD32 num_bs_elements, WORD32 aot);

View file

@ -0,0 +1,90 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
// FLOAT values
#define IXHEAACE_COS_PI_BY_4 (0.70709228515625f) // 0.7071067812f
#define IXHEAACE_COS_PI_BY_8 (0.92388916015625f) // 0.923879532511287f
#define IXHEAACE_SIN_PI_BY_8 (0.3826904296875f) // 0.382683432365090f
#define IXHEAACE_COS_PI_BY_16 (0.98077392578125f) // 0.980785280403230f
#define IXHEAACE_SIN_PI_BY_16 (0.195098876953125f) // 0.195090322016128f
#define IXHEAACE_COS_3_PI_BY_16 (0.83148193359375f) // 0.831469612302545f
#define IXHEAACE_SIN_3_PI_BY_16 (0.555572509765625f) // 0.555570233019602f
#define IXHEAACE_INV_SQRT2 (7.071067811865475e-1f)
#define IXHEAACE_COS_PI_DIV8 (0.923879532511287f)
#define IXHEAACE_COS_3PI_DIV8 (3.826834323650898e-1f)
#define IXHEAACE_SQRT2PLUS1 (2.414213562373095f)
#define IXHEAACE_SQRT2MINUS1 (4.142135623730952e-1f)
#define INV_SQRT_2_FLOAT 0x3F3504F3 // 1/sqrt(2) in float
#define Q_POWER2_TABLE 30
#define DIV_FAC_24_BIT_PCM (256.0f)
#define DIV_FAC_32_BIT_PCM (65536.0f)
#define AOT_AAC_LC (2)
#define AOT_SBR (5)
#define AOT_AAC_LD (23)
#define AOT_AAC_ELD (39)
#define AOT_USAC (42)
#define AOT_PS (29)
#define AUDIO_PROFILE_AAC_LC_L5 (0x2B)
#define AUDIO_PROFILE_HEAAC_L5 (0x2F)
#define AUDIO_PROFILE_HEAAC_V2_L5 (0x33)
#define AUDIO_PROFILE_AAC_LD_L4 (0x19)
#define AUDIO_PROFILE_AAC_ELD_L1 (0x4C)
#define AUDIO_PROFILE_AAC_ELD_L2 (0x4D)
#define AUDIO_PROFILE_AAC_ELD_L4 (0x4F)
#define AUDIO_PROFILE_USAC_L2 (0x45)
#define AUDIO_PROFILE_NOT_SPECIFIED (0xFE)
#define CLIP_SAVE_LO_LONG (0.2f)
#define CLIP_SAVE_HI_LONG (0.95f)
#define MIN_BITS_SAVE_LONG (-0.05f)
#define MAX_BITS_SAVE_LONG (0.3f)
#define CLIP_SPEND_LO_LONG (0.2f)
#define CLIP_SPEND_HI_LONG (0.95f)
#define MIN_BITS_SPEND_LONG (-0.10f)
#define MAX_BITS_SPEND_LONG (0.4f)
#define CLIP_SAVE_LO_SHORT (0.2f)
#define CLIP_SAVE_HI_SHORT (0.75f)
#define MIN_BITS_SAVE_SHORT (0.0f)
#define MAX_BITS_SAVE_SHORT (0.2f)
#define CLIP_SPEND_LO_SHORT (0.2f)
#define CLIP_SPEND_HI_SHORT (0.75f)
#define MIN_BITS_SPEND_SHORT (-0.05f)
#define MAX_BITS_SPEND_SHORT (0.5f)
typedef struct {
FLOAT32 re;
FLOAT32 im;
} complex;
typedef struct {
UWORD8 *data; /* data bits */
WORD32 num_bit; /* number of bits in buffer */
WORD32 size; /* buffer size in bytes */
WORD32 current_bit; /* current bit position in bit stream */
WORD32 numByte; /* number of bytes read/written (only file) */
} ixheaace_bitstream_params;
/* bits in byte (char) */
#define BYTE_NUMBIT 8

View file

@ -0,0 +1,978 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaac_basic_ops32.h"
#include "ixheaac_basic_ops16.h"
#include "ixheaac_basic_ops40.h"
#include "ixheaac_basic_ops.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaace_enc_main.h"
#include "ixheaace_adjust_threshold_data.h"
#include "ixheaace_dynamic_bits.h"
#include "ixheaace_qc_data.h"
#include "ixheaace_block_switch.h"
#include "ixheaace_psy_data.h"
#include "ixheaace_interface.h"
#include "ixheaace_adjust_threshold.h"
#include "ixheaace_common_utils.h"
VOID iaace_adj_thr_init(ia_adj_thr_state_struct *pstr_adj_thr_state, const FLOAT32 mean_pe,
WORD32 ch_bitrate, WORD32 aot) {
ia_adj_thr_elem_struct *pstr_adj_thr_ele = &pstr_adj_thr_state->str_adj_thr_ele;
ia_min_snr_adapt_param_struct *pstr_min_snr_params =
&pstr_adj_thr_ele->str_min_snr_adapt_params;
pstr_adj_thr_state->str_bitres_params_long.clip_save_low = CLIP_SAVE_LO_LONG;
pstr_adj_thr_state->str_bitres_params_long.clip_save_high = CLIP_SAVE_HI_LONG;
pstr_adj_thr_state->str_bitres_params_long.min_bit_save = MIN_BITS_SAVE_LONG;
pstr_adj_thr_state->str_bitres_params_long.max_bit_save = MAX_BITS_SAVE_LONG;
pstr_adj_thr_state->str_bitres_params_long.clip_spend_low = CLIP_SPEND_LO_LONG;
pstr_adj_thr_state->str_bitres_params_long.clip_spend_high = CLIP_SPEND_HI_LONG;
pstr_adj_thr_state->str_bitres_params_long.min_bits_spend = MIN_BITS_SPEND_LONG;
pstr_adj_thr_state->str_bitres_params_long.max_bits_spend = MAX_BITS_SPEND_LONG;
pstr_adj_thr_state->str_bitres_params_short.clip_save_low = CLIP_SAVE_LO_SHORT;
pstr_adj_thr_state->str_bitres_params_short.clip_save_high = CLIP_SAVE_HI_SHORT;
pstr_adj_thr_state->str_bitres_params_short.min_bit_save = MIN_BITS_SAVE_SHORT;
pstr_adj_thr_state->str_bitres_params_short.max_bit_save = MAX_BITS_SAVE_SHORT;
pstr_adj_thr_state->str_bitres_params_short.clip_spend_low = CLIP_SPEND_LO_SHORT;
pstr_adj_thr_state->str_bitres_params_short.clip_spend_high = CLIP_SPEND_HI_SHORT;
pstr_adj_thr_state->str_bitres_params_short.min_bits_spend = MIN_BITS_SPEND_SHORT;
pstr_adj_thr_state->str_bitres_params_short.max_bits_spend = MAX_BITS_SPEND_SHORT;
pstr_adj_thr_ele->pe_min = (FLOAT32)0.8f * mean_pe;
pstr_adj_thr_ele->pe_max = (FLOAT32)1.2f * mean_pe;
pstr_adj_thr_ele->pe_offset = 0.0f;
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
if (ch_bitrate < 32000) {
pstr_adj_thr_ele->pe_offset = MAX(
(FLOAT32)50.0f, (FLOAT32)(100.0f) - (FLOAT32)(100.0f / 32000) * (FLOAT32)ch_bitrate);
}
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
if (ch_bitrate <= 32000) {
pstr_adj_thr_ele->pe_offset = MAX(
(FLOAT32)50.0f, (FLOAT32)(100.0f) - (FLOAT32)(100.0f / 32000) * (FLOAT32)ch_bitrate);
}
break;
}
if (ch_bitrate > 20000) {
pstr_adj_thr_ele->str_ah_param.modify_min_snr = TRUE;
pstr_adj_thr_ele->str_ah_param.start_sfb_long = 15;
pstr_adj_thr_ele->str_ah_param.start_sfb_short = 3;
} else {
pstr_adj_thr_ele->str_ah_param.modify_min_snr = FALSE;
pstr_adj_thr_ele->str_ah_param.start_sfb_long = 0;
pstr_adj_thr_ele->str_ah_param.start_sfb_short = 0;
}
pstr_min_snr_params->max_red = (FLOAT32)0.25f;
pstr_min_snr_params->start_ratio = (FLOAT32)1.e1f;
pstr_min_snr_params->max_ratio = (FLOAT32)1.e3f;
pstr_min_snr_params->red_ratio_fac =
(1.0f - pstr_min_snr_params->max_red) /
(10.0f * (FLOAT32)log10(pstr_min_snr_params->start_ratio / pstr_min_snr_params->max_ratio));
pstr_min_snr_params->red_offs = 1.0f - pstr_min_snr_params->red_ratio_fac * 10.0f *
(FLOAT32)log10(pstr_min_snr_params->start_ratio);
pstr_adj_thr_ele->pe_last = (FLOAT32)0.0f;
pstr_adj_thr_ele->dyn_bits_last = 0;
pstr_adj_thr_ele->pe_correction_fac = (FLOAT32)1.0f;
}
FLOAT32 iaace_bits_to_pe(const FLOAT32 bits) { return (bits * 1.18f); }
static VOID iaace_calc_sfb_pe_data(ia_qc_pe_data_struct *pstr_qc_pe_data,
ixheaace_psy_out_channel *pstr_psy_out, WORD32 num_channels,
WORD32 chn) {
WORD32 ch;
WORD32 scf_band_grp;
FLOAT32 num_lines;
FLOAT32 ld_thr, ld_ratio;
WORD32 i = 0, scf;
WORD32 sfb_count;
WORD32 scf_band_per_grp;
WORD32 max_sfb_per_grp;
FLOAT32 *ptr_sfb_energy;
FLOAT32 *ptr_sfb_thr;
ia_qc_pe_chan_data_struct *pstr_qc_pe_chan_data;
pstr_qc_pe_data->pe = pstr_qc_pe_data->offset;
pstr_qc_pe_data->const_part = 0.0f;
pstr_qc_pe_data->num_active_lines = 0.0f;
for (ch = chn; ch < chn + num_channels; ch++) {
sfb_count = pstr_psy_out[ch].sfb_count;
scf_band_per_grp = pstr_psy_out[ch].sfb_per_group;
max_sfb_per_grp = pstr_psy_out[ch].max_sfb_per_grp;
ptr_sfb_energy = pstr_psy_out[ch].ptr_sfb_energy;
ptr_sfb_thr = pstr_psy_out[ch].ptr_sfb_thr;
pstr_qc_pe_chan_data = &pstr_qc_pe_data->pe_ch_data[ch];
pstr_qc_pe_chan_data->pe = 0;
pstr_qc_pe_chan_data->num_active_lines = 0;
pstr_qc_pe_chan_data->const_part = 0;
for (scf_band_grp = 0; scf_band_grp < sfb_count; scf_band_grp += scf_band_per_grp) {
i = scf_band_grp;
for (scf = max_sfb_per_grp - 1; scf >= 0; scf--, i++) {
if (ptr_sfb_energy[i] > ptr_sfb_thr[i]) {
ld_thr = (FLOAT32)log(ptr_sfb_thr[i]) * LOG2_1;
ld_ratio = pstr_qc_pe_chan_data->sfb_ld_energy[i] - ld_thr;
num_lines = pstr_qc_pe_chan_data->sfb_lines[i];
if (ld_ratio >= PE_C1) {
pstr_qc_pe_chan_data->sfb_pe[i] = num_lines * ld_ratio;
pstr_qc_pe_chan_data->sfb_const_part[i] =
num_lines * pstr_qc_pe_chan_data->sfb_ld_energy[i];
} else {
pstr_qc_pe_chan_data->sfb_pe[i] = num_lines * (PE_C2 + PE_C3 * ld_ratio);
pstr_qc_pe_chan_data->sfb_const_part[i] =
num_lines * (PE_C2 + PE_C3 * pstr_qc_pe_chan_data->sfb_ld_energy[i]);
num_lines = num_lines * PE_C3;
}
pstr_qc_pe_chan_data->num_sfb_active_lines[i] = num_lines;
} else {
pstr_qc_pe_chan_data->sfb_pe[i] = 0.0f;
pstr_qc_pe_chan_data->sfb_const_part[i] = 0.0f;
pstr_qc_pe_chan_data->num_sfb_active_lines[i] = 0.0;
}
pstr_qc_pe_chan_data->pe += pstr_qc_pe_chan_data->sfb_pe[i];
pstr_qc_pe_chan_data->const_part += pstr_qc_pe_chan_data->sfb_const_part[i];
pstr_qc_pe_chan_data->num_active_lines += pstr_qc_pe_chan_data->num_sfb_active_lines[i];
}
}
pstr_qc_pe_data->pe += pstr_qc_pe_chan_data->pe;
pstr_qc_pe_data->const_part += pstr_qc_pe_chan_data->const_part;
pstr_qc_pe_data->num_active_lines += pstr_qc_pe_chan_data->num_active_lines;
pstr_psy_out[ch].pe = pstr_qc_pe_data->pe;
}
}
static FLOAT32 iaace_calc_bit_save(ia_bitres_param_struct *pstr_bitres_params, FLOAT32 fill_lvl) {
FLOAT32 bit_save;
const FLOAT32 clip_low = pstr_bitres_params->clip_save_low;
const FLOAT32 clip_high = pstr_bitres_params->clip_save_high;
const FLOAT32 min_bit_save = pstr_bitres_params->min_bit_save;
const FLOAT32 max_bit_save = pstr_bitres_params->max_bit_save;
fill_lvl = MAX(fill_lvl, clip_low);
fill_lvl = MIN(fill_lvl, clip_high);
bit_save = max_bit_save -
((max_bit_save - min_bit_save) / (clip_high - clip_low)) * (fill_lvl - clip_low);
return bit_save;
}
static FLOAT32 iaace_calc_bit_spend(ia_bitres_param_struct *pstr_bitres_params,
FLOAT32 fill_lvl) {
FLOAT32 bit_spend;
const FLOAT32 clip_low = pstr_bitres_params->clip_spend_low;
const FLOAT32 clip_high = pstr_bitres_params->clip_spend_high;
const FLOAT32 min_bits_spend = pstr_bitres_params->min_bits_spend;
const FLOAT32 max_bits_spend = pstr_bitres_params->max_bits_spend;
fill_lvl = MAX(fill_lvl, clip_low);
fill_lvl = MIN(fill_lvl, clip_high);
bit_spend = min_bits_spend + ((max_bits_spend - min_bits_spend) / (clip_high - clip_low)) *
(fill_lvl - clip_low);
return bit_spend;
}
static VOID iaace_adjust_pe_minmax(const FLOAT32 curr_pe, FLOAT32 *ptr_pe_min,
FLOAT32 *ptr_pe_max) {
FLOAT32 min_hi_fac = 0.3f, max_hi_fac = 1.0f, min_low_fac = 0.14f, max_low_fac = 0.07f;
FLOAT32 diff;
FLOAT32 min_diff = curr_pe * (FLOAT32)0.1666666667f;
if (curr_pe > *ptr_pe_max) {
diff = (curr_pe - *ptr_pe_max);
*ptr_pe_min += diff * min_hi_fac;
*ptr_pe_max += diff * max_hi_fac;
} else {
if (curr_pe < *ptr_pe_min) {
diff = (*ptr_pe_min - curr_pe);
*ptr_pe_min -= diff * min_low_fac;
*ptr_pe_max -= diff * max_low_fac;
} else {
*ptr_pe_min += (curr_pe - *ptr_pe_min) * min_hi_fac;
*ptr_pe_max -= (*ptr_pe_max - curr_pe) * max_low_fac;
}
}
if ((*ptr_pe_max - *ptr_pe_min) < min_diff) {
FLOAT32 low_part, high_part;
low_part = MAX((FLOAT32)0.0f, curr_pe - *ptr_pe_min);
high_part = MAX((FLOAT32)0.0f, *ptr_pe_max - curr_pe);
*ptr_pe_max = curr_pe + high_part / (low_part + high_part) * min_diff;
*ptr_pe_min = curr_pe - low_part / (low_part + high_part) * min_diff;
*ptr_pe_min = MAX((FLOAT32)0.0f, *ptr_pe_min);
}
}
static FLOAT32 iaace_bitres_calc_bitfac(const WORD32 bitres_bits, const WORD32 max_bitres_bits,
const FLOAT32 pe, const WORD32 win_seq,
const WORD32 avg_bits, const FLOAT32 max_bit_fac,
ia_adj_thr_state_struct *pstr_adj_thr_state,
ia_adj_thr_elem_struct *pstr_adj_the_elem) {
ia_bitres_param_struct *pstr_bitres_params;
FLOAT32 pex;
FLOAT32 fill_lvl;
FLOAT32 bit_save, bit_spend, bitres_factor;
fill_lvl = (FLOAT32)bitres_bits / (FLOAT32)max_bitres_bits;
if (win_seq != SHORT_WINDOW) {
pstr_bitres_params = &(pstr_adj_thr_state->str_bitres_params_long);
} else {
pstr_bitres_params = &(pstr_adj_thr_state->str_bitres_params_short);
}
pex = MAX(pe, pstr_adj_the_elem->pe_min);
pex = MIN(pex, pstr_adj_the_elem->pe_max);
bit_save = iaace_calc_bit_save(pstr_bitres_params, fill_lvl);
bit_spend = iaace_calc_bit_spend(pstr_bitres_params, fill_lvl);
bitres_factor =
(FLOAT32)1.0f - bit_save +
((bit_spend + bit_save) / (pstr_adj_the_elem->pe_max - pstr_adj_the_elem->pe_min)) *
(pex - pstr_adj_the_elem->pe_min);
bitres_factor = MIN(bitres_factor,
(FLOAT32)1.0f - (FLOAT32)0.3f + (FLOAT32)bitres_bits / (FLOAT32)avg_bits);
bitres_factor = MIN(bitres_factor, max_bit_fac);
iaace_adjust_pe_minmax(pe, &pstr_adj_the_elem->pe_min, &pstr_adj_the_elem->pe_max);
return bitres_factor;
}
static VOID iaace_calc_pe_correction(FLOAT32 *ptr_correction_fac, const FLOAT32 pe_act,
const FLOAT32 pe_last, const WORD32 bits_prev) {
if ((bits_prev > 0) && (pe_act < (FLOAT32)1.5f * pe_last) &&
(pe_act > (FLOAT32)0.7f * pe_last) &&
((FLOAT32)1.2f * iaace_bits_to_pe((FLOAT32)bits_prev) > pe_last) &&
((FLOAT32)0.65f * iaace_bits_to_pe((FLOAT32)bits_prev) < pe_last)) {
FLOAT32 new_fac = pe_last / iaace_bits_to_pe((FLOAT32)bits_prev);
if (new_fac < (FLOAT32)1.0f) {
new_fac = MIN((FLOAT32)1.1f * new_fac, (FLOAT32)1.0f);
new_fac = MAX(new_fac, (FLOAT32)0.85f);
} else {
new_fac = MAX((FLOAT32)0.9f * new_fac, (FLOAT32)1.0f);
new_fac = MIN(new_fac, (FLOAT32)1.15f);
}
if (((new_fac > (FLOAT32)1.0f) && (*ptr_correction_fac < (FLOAT32)1.0f)) ||
((new_fac < (FLOAT32)1.0f) && (*ptr_correction_fac > (FLOAT32)1.0f))) {
*ptr_correction_fac = (FLOAT32)1.0f;
}
if ((*ptr_correction_fac < (FLOAT32)1.0f && new_fac < *ptr_correction_fac) ||
(*ptr_correction_fac > (FLOAT32)1.0f && new_fac > *ptr_correction_fac)) {
*ptr_correction_fac = (FLOAT32)0.85f * (*ptr_correction_fac) + (FLOAT32)0.15f * new_fac;
} else {
*ptr_correction_fac = (FLOAT32)0.7f * (*ptr_correction_fac) + (FLOAT32)0.3f * new_fac;
}
*ptr_correction_fac = MIN(*ptr_correction_fac, (FLOAT32)1.15f);
*ptr_correction_fac = MAX(*ptr_correction_fac, (FLOAT32)0.85f);
} else {
*ptr_correction_fac = (FLOAT32)1.0f;
}
}
static VOID iaace_calc_thr_exp(
FLOAT32 thr_exp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
ixheaace_psy_out_channel *pstr_psy_out, WORD32 num_chans, WORD32 chn) {
WORD32 sfb, ch, scf_band_grp;
ixheaace_psy_out_channel *pstr_psy_chan_out;
FLOAT32 *ptr_scf_band_thr;
FLOAT32 *ptr_thr_exp;
for (ch = chn; ch < chn + num_chans; ch++) {
pstr_psy_chan_out = &pstr_psy_out[ch];
ptr_thr_exp = thr_exp[ch];
for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count;
scf_band_grp += pstr_psy_chan_out->sfb_per_group) {
FLOAT32 *ptr_thr_exp1 = &ptr_thr_exp[scf_band_grp];
ptr_scf_band_thr = &pstr_psy_chan_out->ptr_sfb_thr[scf_band_grp];
for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) {
ptr_thr_exp1[sfb] = (FLOAT32)pow(*ptr_scf_band_thr++, RED_EXP_VAL);
}
}
}
}
static VOID iaace_adapt_min_snr(ixheaace_psy_out_channel *pstr_psy_out,
ia_min_snr_adapt_param_struct *pstr_min_snr_params,
WORD32 num_chans, WORD32 chn) {
WORD32 num_scf_band = 0, ch, scf_band_cnt, scf_band_offs, sfb;
FLOAT32 avg_energy = 0.0f, db_ratio, min_snr_red;
WORD32 i;
for (ch = chn; ch < chn + num_chans; ch++) {
ixheaace_psy_out_channel *pstr_psy_chan_out = &pstr_psy_out[ch];
num_scf_band = 0;
avg_energy = 0;
scf_band_cnt = pstr_psy_chan_out->max_sfb_per_grp;
for (scf_band_offs = 0; scf_band_offs < pstr_psy_chan_out->sfb_count;
scf_band_offs += pstr_psy_chan_out->sfb_per_group) {
FLOAT32 *ptr_sfb_energy = &pstr_psy_chan_out->ptr_sfb_energy[scf_band_offs];
for (sfb = scf_band_cnt - 1; sfb >= 0; sfb--) {
avg_energy += ptr_sfb_energy[sfb];
}
num_scf_band += scf_band_cnt;
}
if (num_scf_band > 0) {
avg_energy /= num_scf_band;
}
for (scf_band_offs = 0; scf_band_offs < pstr_psy_chan_out->sfb_count;
scf_band_offs += pstr_psy_chan_out->sfb_per_group) {
i = scf_band_offs;
for (sfb = scf_band_cnt - 1; sfb >= 0; sfb--, i++) {
if (pstr_min_snr_params->start_ratio * pstr_psy_chan_out->ptr_sfb_energy[i] <
avg_energy) {
db_ratio =
(FLOAT32)(10.0f * log10((MIN_FLT_VAL + avg_energy) /
(MIN_FLT_VAL + pstr_psy_chan_out->ptr_sfb_energy[i])));
min_snr_red =
pstr_min_snr_params->red_offs + pstr_min_snr_params->red_ratio_fac * db_ratio;
min_snr_red = MAX(min_snr_red, pstr_min_snr_params->max_red);
pstr_psy_chan_out->sfb_min_snr[i] =
(FLOAT32)pow(pstr_psy_out[ch].sfb_min_snr[i], min_snr_red);
pstr_psy_chan_out->sfb_min_snr[i] = MIN(MIN_SNR_LIMIT, pstr_psy_out[ch].sfb_min_snr[i]);
}
}
}
}
}
static VOID iaace_init_avoid_hole_flag(
WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
ixheaace_psy_out_channel *pstr_psy_out, ia_ah_param_struct *pstr_ah_param, WORD32 num_chans,
WORD32 chn, WORD32 aot) {
WORD32 ch;
FLOAT32 sfb_energy;
FLOAT32 scale_spread_energy = 0.0f;
WORD32 scf_band_grp, scf_band_cnt, scf_band;
FLOAT32 *ptr_scf_band_spread_energy, *ptr_scf_band_energy, *ptr_scf_band_min_snr;
for (ch = chn; ch < chn + num_chans; ch++) {
ixheaace_psy_out_channel *pstr_psy_chan_out = &pstr_psy_out[ch];
if (pstr_psy_chan_out->window_sequence != SHORT_WINDOW) {
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
scale_spread_energy = 0.5f;
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
scale_spread_energy = 0.56f;
break;
}
} else {
scale_spread_energy = 0.63f;
}
for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count;
scf_band_grp += pstr_psy_chan_out->sfb_per_group) {
ptr_scf_band_spread_energy = &pstr_psy_chan_out->ptr_sfb_spread_energy[scf_band_grp];
scf_band_cnt = pstr_psy_chan_out->max_sfb_per_grp;
for (scf_band = scf_band_cnt - 1; scf_band >= 0; scf_band--) {
*ptr_scf_band_spread_energy = *ptr_scf_band_spread_energy * scale_spread_energy;
ptr_scf_band_spread_energy++;
}
}
}
if (pstr_ah_param->modify_min_snr) {
for (ch = chn; ch < chn + num_chans; ch++) {
ixheaace_psy_out_channel *pstr_psy_chan_out = &pstr_psy_out[ch];
ptr_scf_band_energy = pstr_psy_chan_out->ptr_sfb_energy;
ptr_scf_band_min_snr = pstr_psy_chan_out->sfb_min_snr;
for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count;
scf_band_grp += pstr_psy_chan_out->sfb_per_group) {
for (scf_band = 0; scf_band < pstr_psy_chan_out->max_sfb_per_grp; scf_band++) {
FLOAT32 sfb_en_m1, sfb_en_p1, avg_energy;
if (scf_band > 0) {
sfb_en_m1 = ptr_scf_band_energy[scf_band_grp + scf_band - 1];
} else {
sfb_en_m1 = ptr_scf_band_energy[scf_band_grp];
}
if (scf_band < pstr_psy_chan_out->max_sfb_per_grp - 1) {
sfb_en_p1 = ptr_scf_band_energy[scf_band_grp + scf_band + 1];
} else {
sfb_en_p1 = ptr_scf_band_energy[scf_band_grp + scf_band];
}
avg_energy = (sfb_en_m1 + sfb_en_p1) / (FLOAT32)2.0f;
sfb_energy = ptr_scf_band_energy[scf_band_grp + scf_band];
FLOAT32 temp_min_snr = 0.0f;
if (sfb_energy > avg_energy) {
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
temp_min_snr = MAX((FLOAT32)0.8f * avg_energy / sfb_energy, (FLOAT32)0.316f);
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
temp_min_snr = MAX((FLOAT32)0.8f * avg_energy / sfb_energy, (FLOAT32)0.408f);
break;
}
if (pstr_psy_chan_out->window_sequence != SHORT_WINDOW) {
switch (aot) {
case AOT_AAC_LC:
case AOT_PS:
temp_min_snr = MAX(temp_min_snr, (FLOAT32)0.316f);
break;
case AOT_AAC_LD:
temp_min_snr = MAX(temp_min_snr, (FLOAT32)0.408f);
break;
}
} else {
temp_min_snr = MAX(temp_min_snr, (FLOAT32)0.5f);
}
ptr_scf_band_min_snr[scf_band_grp + scf_band] =
MIN(ptr_scf_band_min_snr[scf_band_grp + scf_band], temp_min_snr);
}
if (((FLOAT32)2.0f * sfb_energy < avg_energy) && (sfb_energy > (FLOAT32)0.0f)) {
temp_min_snr = avg_energy / ((FLOAT32)2.0f * sfb_energy) *
ptr_scf_band_min_snr[scf_band_grp + scf_band];
temp_min_snr = MIN((FLOAT32)0.8f, temp_min_snr);
ptr_scf_band_min_snr[scf_band_grp + scf_band] =
MIN(temp_min_snr, ptr_scf_band_min_snr[scf_band_grp + scf_band] * (FLOAT32)3.16f);
}
}
}
}
}
if (num_chans == 2) {
ixheaace_psy_out_channel *pstr_psy_out_mid = &pstr_psy_out[chn];
ixheaace_psy_out_channel *pstr_psy_out_side = &pstr_psy_out[chn + 1];
WORD32 sfb;
for (sfb = 0; sfb < pstr_psy_out_mid->sfb_count; sfb++) {
if (pstr_psy_out[chn].ms_used[sfb]) {
FLOAT32 sfb_en_mid = pstr_psy_out_mid->ptr_sfb_energy[sfb];
FLOAT32 sfb_en_side = pstr_psy_out_side->ptr_sfb_energy[sfb];
FLOAT32 max_sfb_en = MAX(sfb_en_mid, sfb_en_side);
FLOAT32 max_thr = 0.25f * pstr_psy_out_mid->sfb_min_snr[sfb] * max_sfb_en;
pstr_psy_out_mid->sfb_min_snr[sfb] = (FLOAT32)MAX(
pstr_psy_out_mid->sfb_min_snr[sfb],
MIN(MAX_FLT_VAL, ((FLOAT32)max_thr / (MIN_FLT_VAL + (FLOAT32)sfb_en_mid))));
if (pstr_psy_out_mid->ptr_sfb_energy[sfb] <= 1.0f) {
pstr_psy_out_mid->ptr_sfb_energy[sfb] =
MIN(pstr_psy_out_mid->ptr_sfb_energy[sfb], 0.8f);
}
pstr_psy_out_side->sfb_min_snr[sfb] = (FLOAT32)MAX(
pstr_psy_out_side->sfb_min_snr[sfb],
MIN(MAX_FLT_VAL, ((FLOAT32)max_thr / (MIN_FLT_VAL + (FLOAT32)sfb_en_side))));
if (pstr_psy_out_side->sfb_min_snr[sfb] <= 1.0f) {
pstr_psy_out_side->sfb_min_snr[sfb] = MIN(pstr_psy_out_side->sfb_min_snr[sfb], 0.8f);
}
}
}
}
for (ch = chn; ch < chn + num_chans; ch++) {
ixheaace_psy_out_channel *pstr_psy_chan_out = &pstr_psy_out[ch];
for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count;
scf_band_grp += pstr_psy_chan_out->sfb_per_group) {
for (scf_band = 0; scf_band < pstr_psy_chan_out->max_sfb_per_grp; scf_band++) {
if (pstr_psy_chan_out->ptr_sfb_spread_energy[scf_band_grp + scf_band] >
pstr_psy_chan_out->ptr_sfb_energy[scf_band_grp + scf_band] ||
pstr_psy_chan_out->sfb_min_snr[scf_band_grp + scf_band] > 1.0f) {
ah_flag[ch][scf_band_grp + scf_band] = NO_AH;
} else {
ah_flag[ch][scf_band_grp + scf_band] = AH_INACTIVE;
}
}
for (scf_band = pstr_psy_chan_out->max_sfb_per_grp;
scf_band < pstr_psy_chan_out->sfb_per_group; scf_band++) {
ah_flag[ch][scf_band_grp + scf_band] = NO_AH;
}
}
}
}
static VOID iaace_reduce_thr(
ixheaace_psy_out_channel *pstr_psy_out,
WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
FLOAT32 thr_exp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
const FLOAT32 red_value, WORD32 num_channels, WORD32 chn) {
WORD32 ch, sfb_group, sfb;
FLOAT32 sfb_energy, sfb_threshold, sfb_thr_reduced;
FLOAT32 *ptr_sfb_energy_fix, *ptr_sfb_threshold_fix, *ptr_sfb_min_snr_fix, *ptr_thr_exp_fix;
for (ch = chn; ch < chn + num_channels; ch++) {
ixheaace_psy_out_channel *pstr_psy_chan_out = &pstr_psy_out[ch];
ptr_sfb_energy_fix = pstr_psy_chan_out->ptr_sfb_energy;
ptr_sfb_threshold_fix = pstr_psy_chan_out->ptr_sfb_thr;
ptr_sfb_min_snr_fix = pstr_psy_chan_out->sfb_min_snr;
ptr_thr_exp_fix = &thr_exp[ch][0];
for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count;
sfb_group += pstr_psy_chan_out->sfb_per_group) {
for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) {
sfb_energy = ptr_sfb_energy_fix[sfb_group + sfb];
sfb_threshold = ptr_sfb_threshold_fix[sfb_group + sfb];
if (sfb_energy > sfb_threshold) {
sfb_thr_reduced =
(FLOAT32)pow((ptr_thr_exp_fix[sfb_group + sfb] + red_value), INV_RED_EXP_VAL);
if ((sfb_thr_reduced > ptr_sfb_min_snr_fix[sfb_group + sfb] * sfb_energy) &&
(ah_flag[ch][sfb_group + sfb] != NO_AH)) {
sfb_thr_reduced =
MAX(ptr_sfb_min_snr_fix[sfb_group + sfb] * sfb_energy, sfb_threshold);
ah_flag[ch][sfb_group + sfb] = AH_ACTIVE;
}
ptr_sfb_threshold_fix[sfb_group + sfb] = sfb_thr_reduced;
}
}
}
}
}
static VOID iaace_calc_pe_no_active_holes(
FLOAT32 *ptr_pe, FLOAT32 *ptr_const_part, FLOAT32 *ptr_num_active_lines,
ia_qc_pe_data_struct *pstr_qs_pe_data,
WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
ixheaace_psy_out_channel *pstr_psy_out, WORD32 num_channels, WORD32 chn) {
WORD32 ch, sfb_group, sfb;
*ptr_pe = 0.0f;
*ptr_const_part = 0.0f;
*ptr_num_active_lines = 0;
for (ch = chn; ch < chn + num_channels; ch++) {
ixheaace_psy_out_channel *pstr_psy_chan_out = &pstr_psy_out[ch];
ia_qc_pe_chan_data_struct *ptr_pe_chan_data = &pstr_qs_pe_data->pe_ch_data[ch];
for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count;
sfb_group += pstr_psy_chan_out->sfb_per_group) {
for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) {
if (ah_flag[ch][sfb_group + sfb] < AH_ACTIVE) {
*ptr_pe += ptr_pe_chan_data->sfb_pe[sfb_group + sfb];
*ptr_const_part += ptr_pe_chan_data->sfb_const_part[sfb_group + sfb];
*ptr_num_active_lines += ptr_pe_chan_data->num_sfb_active_lines[sfb_group + sfb];
}
}
}
}
}
static VOID iaace_correct_thr(
ixheaace_psy_out_channel *pstr_psy_out,
WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
ia_qc_pe_data_struct *pstr_qs_pe_data,
FLOAT32 thr_exp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
const FLOAT32 red_value, const FLOAT32 delta_pe, WORD32 num_channels, WORD32 chn) {
WORD32 i, ch, sfb_group, sfb;
FLOAT32 delta_sfb_pe;
FLOAT32 thr_factor;
FLOAT32 sfb_pe_factors[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
norm_factor[IXHEAACE_MAX_CH_IN_BS_ELE] = {MIN_FLT_VAL};
FLOAT32 sfb_en, sfb_thr, sfb_thr_reduced;
FLOAT32 *ptr_thr_exp;
FLOAT32 *ptr_sfb_energy, *ptr_sfb_thr, *ptr_sfb_min_snr;
ixheaace_psy_out_channel *pstr_psy_chan_out = NULL;
ia_qc_pe_chan_data_struct *pstr_pe_chan_data = NULL;
for (ch = chn; ch < chn + num_channels; ch++) {
pstr_psy_chan_out = &pstr_psy_out[ch];
pstr_pe_chan_data = &pstr_qs_pe_data->pe_ch_data[ch];
norm_factor[ch] = MIN_FLT_VAL;
ptr_thr_exp = thr_exp[ch];
for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count;
sfb_group += pstr_psy_chan_out->sfb_per_group) {
for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) {
if ((ah_flag[ch][sfb_group + sfb] < AH_ACTIVE) || (delta_pe > 0)) {
sfb_pe_factors[ch][sfb_group + sfb] =
pstr_pe_chan_data->num_sfb_active_lines[sfb_group + sfb] /
(ptr_thr_exp[sfb_group + sfb] + red_value);
norm_factor[ch] += sfb_pe_factors[ch][sfb_group + sfb];
} else {
sfb_pe_factors[ch][sfb_group + sfb] = 0.0f;
}
}
}
}
if (num_channels > 1) {
norm_factor[chn] = norm_factor[chn] + norm_factor[chn + 1];
}
norm_factor[chn] = 1.0f / norm_factor[chn];
for (ch = chn; ch < chn + num_channels; ch++) {
pstr_psy_chan_out = &pstr_psy_out[ch];
pstr_pe_chan_data = &pstr_qs_pe_data->pe_ch_data[ch];
ptr_sfb_energy = pstr_psy_chan_out->ptr_sfb_energy;
ptr_sfb_thr = pstr_psy_chan_out->ptr_sfb_thr;
ptr_sfb_min_snr = pstr_psy_chan_out->sfb_min_snr;
for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count;
sfb_group += pstr_psy_chan_out->sfb_per_group) {
i = sfb_group;
for (sfb = pstr_psy_chan_out->max_sfb_per_grp - 1; sfb >= 0; sfb--, i++) {
delta_sfb_pe = sfb_pe_factors[ch][i] * norm_factor[chn] * delta_pe;
if (pstr_pe_chan_data->num_sfb_active_lines[i] > (FLOAT32)0.5f) {
sfb_en = ptr_sfb_energy[i];
sfb_thr = ptr_sfb_thr[i];
thr_factor = MIN(-delta_sfb_pe / pstr_pe_chan_data->num_sfb_active_lines[i], 20.f);
thr_factor = (FLOAT32)pow(2.0f, thr_factor);
sfb_thr_reduced = sfb_thr * thr_factor;
if ((sfb_thr_reduced > ptr_sfb_min_snr[i] * sfb_en) &&
(ah_flag[ch][i] == AH_INACTIVE)) {
sfb_thr_reduced = MAX(ptr_sfb_min_snr[i] * sfb_en, sfb_thr);
ah_flag[ch][i] = AH_ACTIVE;
}
ptr_sfb_thr[i] = sfb_thr_reduced;
}
}
}
}
}
static VOID iaace_reduce_min_snr(
ixheaace_psy_out_channel *pstr_psy_out, ia_qc_pe_data_struct *pstr_qs_pe_data,
WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
const FLOAT32 desired_pe, WORD32 num_channels, WORD32 chn) {
WORD32 sfb, sfb_sub_win, ch;
FLOAT32 delta_pe;
sfb_sub_win = pstr_psy_out[chn].max_sfb_per_grp;
while (pstr_qs_pe_data->pe > desired_pe && sfb_sub_win > 0) {
sfb_sub_win--;
for (sfb = sfb_sub_win; sfb < pstr_psy_out[chn].sfb_count;
sfb += pstr_psy_out[chn].sfb_per_group) {
for (ch = chn; ch < chn + num_channels; ch++) {
if (ah_flag[ch][sfb] != NO_AH && pstr_psy_out[ch].sfb_min_snr[sfb] < MIN_SNR_LIMIT) {
pstr_psy_out[ch].sfb_min_snr[sfb] = MIN_SNR_LIMIT;
pstr_psy_out[ch].ptr_sfb_thr[sfb] =
pstr_psy_out[ch].ptr_sfb_energy[sfb] * pstr_psy_out[ch].sfb_min_snr[sfb];
delta_pe = pstr_qs_pe_data->pe_ch_data[ch].sfb_lines[sfb] * 1.5f -
pstr_qs_pe_data->pe_ch_data[ch].sfb_pe[sfb];
pstr_qs_pe_data->pe += delta_pe;
pstr_qs_pe_data->pe_ch_data[ch].pe += delta_pe;
}
}
if (pstr_qs_pe_data->pe <= desired_pe) {
break;
}
}
}
}
static VOID iaace_allow_more_holes(
ixheaace_psy_out_channel *pstr_psy_out, ia_qc_pe_data_struct *pstr_qs_pe_data,
WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
const ia_ah_param_struct *pstr_str_ah_param, const FLOAT32 desired_pe, WORD32 num_channels,
WORD32 chn) {
WORD32 sfb, ch;
FLOAT32 act_pe = pstr_qs_pe_data->pe;
if (num_channels == 2 &&
pstr_psy_out[chn].window_sequence == pstr_psy_out[chn + 1].window_sequence) {
ixheaace_psy_out_channel *pstr_psy_out_left = &pstr_psy_out[chn];
ixheaace_psy_out_channel *pstr_psy_out_right = &pstr_psy_out[chn + 1];
for (sfb = 0; sfb < pstr_psy_out_left->sfb_count; sfb++) {
if (pstr_psy_out[chn].ms_used[sfb]) {
if (ah_flag[chn + 1][sfb] != NO_AH &&
0.4f * pstr_psy_out_left->sfb_min_snr[sfb] * pstr_psy_out_left->ptr_sfb_energy[sfb] >
pstr_psy_out_right->ptr_sfb_energy[sfb]) {
ah_flag[chn + 1][sfb] = NO_AH;
pstr_psy_out_right->ptr_sfb_thr[sfb] = 2.0f * pstr_psy_out_right->ptr_sfb_energy[sfb];
act_pe -= pstr_qs_pe_data->pe_ch_data[chn + 1].sfb_pe[sfb];
} else {
if (ah_flag[chn][sfb] != NO_AH && 0.4f * pstr_psy_out_right->sfb_min_snr[sfb] *
pstr_psy_out_right->ptr_sfb_energy[sfb] >
pstr_psy_out_left->ptr_sfb_energy[sfb]) {
ah_flag[chn][sfb] = NO_AH;
pstr_psy_out_left->ptr_sfb_thr[sfb] = 2.0f * pstr_psy_out_left->ptr_sfb_energy[sfb];
act_pe -= pstr_qs_pe_data->pe_ch_data[chn].sfb_pe[sfb];
}
}
if (act_pe < desired_pe) {
break;
}
}
}
}
if (act_pe > desired_pe) {
WORD32 start_sfb[IXHEAACE_MAX_CH_IN_BS_ELE] = {0};
FLOAT32 average_energy, min_energy;
WORD32 ah_cnt;
WORD32 en_idx;
FLOAT32 energy[4];
WORD32 min_sfb, max_sfb;
WORD32 done;
for (ch = chn; ch < chn + num_channels; ch++) {
if (pstr_psy_out[ch].window_sequence != SHORT_WINDOW) {
start_sfb[ch] = pstr_str_ah_param->start_sfb_long;
} else {
start_sfb[ch] = pstr_str_ah_param->start_sfb_short;
}
}
average_energy = 0.0f;
min_energy = MAX_FLT_VAL;
ah_cnt = 0;
for (ch = chn; ch < chn + num_channels; ch++) {
ixheaace_psy_out_channel *pstr_psy_chan_out = &pstr_psy_out[ch];
for (sfb = start_sfb[ch]; sfb < pstr_psy_chan_out->sfb_count; sfb++) {
if ((ah_flag[ch][sfb] != NO_AH) &&
(pstr_psy_chan_out->ptr_sfb_energy[sfb] > pstr_psy_chan_out->ptr_sfb_thr[sfb])) {
min_energy = MIN(min_energy, pstr_psy_chan_out->ptr_sfb_energy[sfb]);
average_energy += pstr_psy_chan_out->ptr_sfb_energy[sfb];
ah_cnt++;
}
}
}
average_energy = MIN(MAX_FLT_VAL, average_energy / (ah_cnt + MIN_FLT_VAL));
for (en_idx = 0; en_idx < 4; en_idx++) {
energy[en_idx] = min_energy * (FLOAT32)pow(average_energy / (min_energy + MIN_FLT_VAL),
(2 * en_idx + 1) / 7.0f);
}
max_sfb = pstr_psy_out[chn].sfb_count - 1;
min_sfb = start_sfb[chn];
if (num_channels == 2) {
max_sfb = MAX(max_sfb, pstr_psy_out[chn + 1].sfb_count - 1);
min_sfb = MIN(min_sfb, start_sfb[chn + 1]);
}
sfb = max_sfb;
en_idx = 0;
done = 0;
while (!done) {
for (ch = chn; ch < chn + num_channels; ch++) {
ixheaace_psy_out_channel *pstr_psy_chan_out = &pstr_psy_out[ch];
if (sfb >= start_sfb[ch] && sfb < pstr_psy_chan_out->sfb_count) {
if (ah_flag[ch][sfb] != NO_AH &&
pstr_psy_chan_out->ptr_sfb_energy[sfb] < energy[en_idx]) {
ah_flag[ch][sfb] = NO_AH;
pstr_psy_chan_out->ptr_sfb_thr[sfb] = 2.0f * pstr_psy_chan_out->ptr_sfb_energy[sfb];
act_pe -= pstr_qs_pe_data->pe_ch_data[ch].sfb_pe[sfb];
}
if (act_pe < desired_pe) {
done = 1;
break;
}
}
}
sfb--;
if (sfb < min_sfb) {
sfb = max_sfb;
en_idx++;
if (en_idx >= 4) {
done = 1;
}
}
}
}
}
static VOID iaace_adapt_thr_to_pe(
ixheaace_psy_out_channel pstr_psy_out[IXHEAACE_MAX_CH_IN_BS_ELE],
ia_qc_pe_data_struct *pstr_qs_pe_data, const FLOAT32 desired_pe,
ia_ah_param_struct *pstr_ah_param, ia_min_snr_adapt_param_struct *pstr_msa_param,
WORD32 num_channels, WORD32 chn, WORD32 aot) {
FLOAT32 no_red_pe, red_pe, red_pe_no_ah;
FLOAT32 const_part, const_part_no_ah;
FLOAT32 num_active_lines, num_active_lines_no_ah;
FLOAT32 desired_pe_no_ah;
FLOAT32 avg_thr_exp, redval;
WORD32 ah_flag[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
FLOAT32 thr_exp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
WORD32 iteration;
iaace_calc_thr_exp(thr_exp, pstr_psy_out, num_channels, chn);
iaace_adapt_min_snr(pstr_psy_out, pstr_msa_param, num_channels, chn);
iaace_init_avoid_hole_flag(ah_flag, pstr_psy_out, pstr_ah_param, num_channels, chn, aot);
no_red_pe = pstr_qs_pe_data->pe;
const_part = pstr_qs_pe_data->const_part;
num_active_lines = pstr_qs_pe_data->num_active_lines;
avg_thr_exp =
(FLOAT32)pow(2.0f, (const_part - no_red_pe) / (INV_RED_EXP_VAL * num_active_lines));
redval = (FLOAT32)pow(2.0f, (const_part - desired_pe) / (INV_RED_EXP_VAL * num_active_lines)) -
avg_thr_exp;
redval = MAX(0.0f, redval);
iaace_reduce_thr(pstr_psy_out, ah_flag, thr_exp, redval, num_channels, chn);
iaace_calc_sfb_pe_data(pstr_qs_pe_data, pstr_psy_out, num_channels, chn);
red_pe = pstr_qs_pe_data->pe;
iteration = 0;
do {
iaace_calc_pe_no_active_holes(&red_pe_no_ah, &const_part_no_ah, &num_active_lines_no_ah,
pstr_qs_pe_data, ah_flag, pstr_psy_out, num_channels, chn);
desired_pe_no_ah = MAX(desired_pe - (red_pe - red_pe_no_ah), 0);
if (num_active_lines_no_ah > 0) {
avg_thr_exp = (FLOAT32)pow(
2.0f, (const_part_no_ah - red_pe_no_ah) / (INV_RED_EXP_VAL * num_active_lines_no_ah));
redval += (FLOAT32)pow(2.0f, (const_part_no_ah - desired_pe_no_ah) /
(INV_RED_EXP_VAL * num_active_lines_no_ah)) -
avg_thr_exp;
redval = MAX(0.0f, redval);
iaace_reduce_thr(pstr_psy_out, ah_flag, thr_exp, redval, num_channels, chn);
}
iaace_calc_sfb_pe_data(pstr_qs_pe_data, pstr_psy_out, num_channels, chn);
red_pe = pstr_qs_pe_data->pe;
iteration++;
} while ((fabs(red_pe - desired_pe) > (0.05f) * desired_pe) && (iteration < 2));
if (red_pe < 1.15f * desired_pe) {
iaace_correct_thr(pstr_psy_out, ah_flag, pstr_qs_pe_data, thr_exp, redval,
desired_pe - red_pe, num_channels, chn);
} else {
iaace_reduce_min_snr(pstr_psy_out, pstr_qs_pe_data, ah_flag, 1.05f * desired_pe, num_channels,
chn);
iaace_allow_more_holes(pstr_psy_out, pstr_qs_pe_data, ah_flag, pstr_ah_param,
1.05f * desired_pe, num_channels, chn);
}
}
VOID iaace_adjust_threshold(ia_adj_thr_state_struct *pstr_adj_thr_state,
ia_adj_thr_elem_struct *pstr_adj_thr_elem,
ixheaace_psy_out_channel pstr_psy_out[IXHEAACE_MAX_CH_IN_BS_ELE],
FLOAT32 *ptr_ch_bit_dist, ixheaace_qc_out_element *pstr_qc_out_el,
const WORD32 avg_bits, const WORD32 bitres_bits,
const WORD32 max_bitres_bits, const WORD32 side_info_bits,
FLOAT32 *max_bit_fac, FLOAT32 *ptr_sfb_n_relevant_lines,
FLOAT32 *ptr_sfb_ld_energy, WORD32 num_channels, WORD32 chn,
WORD32 aot, WORD8 *ptr_scratch) {
FLOAT32 no_red_pe, granted_pe, granted_pe_corr;
WORD32 curr_win_sequence;
ia_qc_pe_data_struct *pstr_qc_pe_data = (ia_qc_pe_data_struct *)ptr_scratch;
FLOAT32 bit_factor;
WORD32 ch;
for (ch = chn; ch < chn + num_channels; ch++) {
pstr_qc_pe_data->pe_ch_data[ch].sfb_lines =
ptr_sfb_n_relevant_lines + MAXIMUM_GROUPED_SCALE_FACTOR_BAND * ch;
pstr_qc_pe_data->pe_ch_data[ch].sfb_ld_energy =
ptr_sfb_ld_energy + MAXIMUM_GROUPED_SCALE_FACTOR_BAND * ch;
}
pstr_qc_pe_data->offset = pstr_adj_thr_elem->pe_offset;
iaace_calc_sfb_pe_data(pstr_qc_pe_data, pstr_psy_out, num_channels, chn);
no_red_pe = pstr_qc_pe_data->pe;
curr_win_sequence = LONG_WINDOW;
if (num_channels == 2) {
if ((pstr_psy_out[chn].window_sequence == SHORT_WINDOW) ||
(pstr_psy_out[chn + 1].window_sequence == SHORT_WINDOW)) {
curr_win_sequence = SHORT_WINDOW;
}
} else {
curr_win_sequence = pstr_psy_out[chn].window_sequence;
}
bit_factor = iaace_bitres_calc_bitfac(
bitres_bits, max_bitres_bits, no_red_pe + 5.0f * side_info_bits, curr_win_sequence,
avg_bits, *max_bit_fac, pstr_adj_thr_state, pstr_adj_thr_elem);
granted_pe = bit_factor * iaace_bits_to_pe((FLOAT32)avg_bits);
iaace_calc_pe_correction(&(pstr_adj_thr_elem->pe_correction_fac), MIN(granted_pe, no_red_pe),
pstr_adj_thr_elem->pe_last, pstr_adj_thr_elem->dyn_bits_last);
granted_pe_corr = granted_pe * pstr_adj_thr_elem->pe_correction_fac;
if (granted_pe_corr < no_red_pe) {
iaace_adapt_thr_to_pe(pstr_psy_out, pstr_qc_pe_data, granted_pe_corr,
&pstr_adj_thr_elem->str_ah_param,
&pstr_adj_thr_elem->str_min_snr_adapt_params, num_channels, chn, aot);
}
for (ch = chn; ch < chn + num_channels; ch++) {
FLOAT32 tmp_var, temp1;
if (pstr_qc_pe_data->pe) {
tmp_var = 1.0f - num_channels * 0.2f;
temp1 = pstr_qc_pe_data->pe_ch_data[ch].pe / pstr_qc_pe_data->pe;
temp1 = temp1 * tmp_var;
ptr_ch_bit_dist[ch] = temp1 + 0.2f;
if (ptr_ch_bit_dist[ch] < 0.2f) {
ptr_ch_bit_dist[ch] = 0.2f;
}
} else {
ptr_ch_bit_dist[ch] = 0.2f;
}
}
pstr_qc_out_el->pe = no_red_pe;
pstr_adj_thr_elem->pe_last = granted_pe;
}

View file

@ -0,0 +1,54 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
enum _avoid_hole_state { NO_AH = 0, AH_INACTIVE = 1, AH_ACTIVE = 2 };
typedef struct {
FLOAT32 *sfb_ld_energy;
FLOAT32 *sfb_lines;
FLOAT32 sfb_pe[MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
FLOAT32 sfb_const_part[MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
FLOAT32 num_sfb_active_lines[MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
FLOAT32 pe;
FLOAT32 const_part;
FLOAT32 num_active_lines;
} ia_qc_pe_chan_data_struct;
typedef struct {
ia_qc_pe_chan_data_struct pe_ch_data[30];
FLOAT32 pe;
FLOAT32 const_part;
FLOAT32 num_active_lines;
FLOAT32 offset;
} ia_qc_pe_data_struct;
VOID iaace_adj_thr_init(ia_adj_thr_state_struct *pstr_adj_thr_state, const FLOAT32 mean_pe,
WORD32 ch_bitrate, WORD32 aot);
VOID iaace_adjust_threshold(ia_adj_thr_state_struct *pstr_adj_thr_state,
ia_adj_thr_elem_struct *pstr_adj_thr_elem,
ixheaace_psy_out_channel pstr_psy_out[IXHEAACE_MAX_CH_IN_BS_ELE],
FLOAT32 *ptr_ch_bit_dist, ixheaace_qc_out_element *pstr_qc_out_el,
const WORD32 avg_bits, const WORD32 bitres_bits,
const WORD32 max_bitres_bits, const WORD32 side_info_bits,
FLOAT32 *max_bit_fac, FLOAT32 *ptr_sfb_num_relevant_lines,
FLOAT32 *ptr_sfb_ld_energy, WORD32 num_chans, WORD32 chn, WORD32 aot,
WORD8 *ptr_scratch);

View file

@ -0,0 +1,62 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
typedef struct {
UWORD8 modify_min_snr;
WORD32 start_sfb_long;
WORD32 start_sfb_short;
} ia_ah_param_struct;
typedef struct {
FLOAT32 max_red;
FLOAT32 start_ratio;
FLOAT32 max_ratio;
FLOAT32 red_ratio_fac;
FLOAT32 red_offs;
} ia_min_snr_adapt_param_struct;
typedef struct {
FLOAT32 clip_save_low;
FLOAT32 clip_save_high;
FLOAT32 min_bit_save;
FLOAT32 max_bit_save;
FLOAT32 clip_spend_low;
FLOAT32 clip_spend_high;
FLOAT32 min_bits_spend;
FLOAT32 max_bits_spend;
} ia_bitres_param_struct;
typedef struct {
FLOAT32 pe_min;
FLOAT32 pe_max;
FLOAT32 pe_offset;
ia_ah_param_struct str_ah_param;
ia_min_snr_adapt_param_struct str_min_snr_adapt_params;
FLOAT32 pe_last;
WORD32 dyn_bits_last;
FLOAT32 pe_correction_fac;
} ia_adj_thr_elem_struct;
typedef struct {
ia_bitres_param_struct str_bitres_params_long;
ia_bitres_param_struct str_bitres_params_short;
ia_adj_thr_elem_struct str_adj_thr_ele;
} ia_adj_thr_state_struct;

2142
encoder/ixheaace_api.c Normal file

File diff suppressed because it is too large Load diff

35
encoder/ixheaace_api.h Normal file
View file

@ -0,0 +1,35 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
IA_ERRORCODE ixheaace_get_lib_id_strings(pVOID pv_output);
IA_ERRORCODE ixheaace_create(pVOID pv_input, pVOID pv_output);
IA_ERRORCODE ixheaace_process(pVOID pv_ia_process_api_obj, pVOID pstr_in_cfg, pVOID pstr_out_cfg);
IA_ERRORCODE ixheaace_delete(pVOID pv_output);
#define BW_FAC (0.172265625f)
#define IUSACE_FLOAT64_SCRATCH_SIZE (47704)
#define IUSACE_FLOAT32_SCRATCH_SIZE (2048 + 1024)
VOID ia_enhaacplus_enc_get_shared_bufs(VOID *scr, WORD32 **shared_buf1, WORD32 **shared_buf2,
WORD32 **shared_buf3, WORD8 **shared_buf4,
WORD32 aacenc_blocksize);
VOID ia_enhaacplus_enc_get_scratch_bufs(VOID *scr, FLOAT32 **shared_buf1_ring,
FLOAT32 **shared_buf2_ring);

View file

@ -0,0 +1,43 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
/*****************************************************************************/
/* Constant hash defines */
/*****************************************************************************/
/* A constant to let API copy small strings to buffers outside */
#define IA_APIVERSION_MAJOR 1
#define IA_APIVERSION_MINOR 10
/* last compatible version */
#define IA_LASTCOMP_APIVERSION_MAJOR 1
#define IA_LASTCOMP_APIVERSION_MINOR 10
#define IA_STR(str) #str
#define IA_MAKE_VERSION_STR(maj, min) IA_STR(maj) "." IA_STR(min)
#define IA_APIVERSION IA_MAKE_VERSION_STR(IA_APIVERSION_MAJOR, IA_APIVERSION_MINOR)
#define IA_LAST_COMP_APIVERSION \
IA_MAKE_VERSION_STR(IA_LASTCOMP_APIVERSION_MAJOR, IA_LASTCOMP_APIVERSION_MINOR)
VOID ia_enhaacplus_enc_set_shared_bufs(iaace_scratch *scr, WORD32 **shared_buf1,
WORD32 **shared_buf2, WORD32 **shared_buf3,
WORD8 **shared_buf5);

View file

@ -0,0 +1,37 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
typedef struct {
iaace_config config;
ixheaace_element_info element_info;
ixheaace_psy_out psy_out;
ixheaace_psy_kernel psy_kernel;
ixheaace_qc_state qc_kernel;
ixheaace_qc_out qc_out;
ixheaace_bitstream_enc_init bse_init;
ixheaace_stereo_pre_pro_struct str_stereo_pre_pro;
WORD32 downmix;
WORD32 downmix_fac;
WORD32 dual_mono;
WORD32 bandwidth_90_dB;
iaace_scratch *pstr_aac_scratch;
} iexheaac_encoder_str;

View file

@ -0,0 +1,28 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
/*****************************************************************************/
/* Ittiam standard API commands */
/*****************************************************************************/
#define IA_API_CMD_GET_MEM_INFO_SIZE 0x0011
#define IA_API_CMD_GET_MEM_INFO_ALIGNMENT 0x0012
#define IA_API_CMD_GET_MEM_INFO_TYPE 0x0013

View file

@ -0,0 +1,304 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include "iusace_type_def.h"
#include "iusace_bitbuffer.h"
#include "iusace_cnst.h"
#include "ixheaace_sbr_header.h"
#include "ixheaace_config.h"
#include "iusace_config.h"
#include "ixheaace_asc_write.h"
#include "iusace_rom.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
#include "ixheaace_sbr_def.h"
#include "ixheaace_common_rom.h"
static WORD32 ixheaace_spatial_specific_config(ia_bit_buf_struct *pstr_it_bit_buff,
ia_aace_config_struct *pstr_eld_config) {
WORD32 bit_cnt = 0, cnt = 0;
WORD32 num_bytes = pstr_eld_config->num_sac_cfg_bits >> 3;
for (cnt = 0; cnt < num_bytes; cnt++) {
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->sac_cfg_data[cnt]), 8);
}
if (pstr_eld_config->num_sac_cfg_bits & 0x7) {
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->sac_cfg_data[cnt]),
(pstr_eld_config->num_sac_cfg_bits & 0x7));
}
return bit_cnt;
}
static WORD32 sbr_header(ia_bit_buf_struct *pstr_it_bit_buff,
ixheaace_pstr_sbr_hdr_data pstr_sbr_config) {
WORD32 bit_cnt = 0;
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->sbr_amp_res), 1);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->sbr_start_freq), 4);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->sbr_stop_freq), 4);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->sbr_xover_band), 3);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (0), 2); // reserved bits
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->header_extra_1), 1);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->header_extra_2), 1);
if (pstr_sbr_config->header_extra_1) {
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->freq_scale), 2);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->alter_scale), 1);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->sbr_noise_bands), 2);
}
if (pstr_sbr_config->header_extra_2) {
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->sbr_limiter_bands), 2);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->sbr_limiter_gains), 2);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->sbr_interpol_freq), 1);
bit_cnt +=
iusace_write_bits_buf(pstr_it_bit_buff, (pstr_sbr_config->sbr_smoothing_length), 1);
}
return bit_cnt;
}
static WORD32 ld_sbr_header(ia_bit_buf_struct *pstr_it_bit_buff,
ixheaace_pstr_sbr_hdr_data pstr_sbr_config,
WORD32 channelConfiguration) {
WORD32 num_sbr_header, el, bit_cnt = 0;
switch (channelConfiguration) {
case 1:
case 2:
num_sbr_header = 1;
break;
case 3:
num_sbr_header = 2;
break;
case 4:
case 5:
case 6:
num_sbr_header = 3;
break;
case 7:
num_sbr_header = 4;
break;
default:
num_sbr_header = 0;
break;
}
for (el = 0; el < num_sbr_header; el++) {
bit_cnt += sbr_header(pstr_it_bit_buff, pstr_sbr_config);
}
return bit_cnt;
}
static WORD32 iaace_get_eld_specific_config_bytes(ia_bit_buf_struct *pstr_it_bit_buff,
ia_aace_config_struct *pstr_eld_config,
WORD32 channelConfiguration) {
WORD32 bit_cnt = 0;
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->frame_length_flag), 1);
bit_cnt +=
iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->aac_sec_data_resilience_flag), 1);
bit_cnt +=
iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->aac_sf_data_resilience_flag), 1);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff,
(pstr_eld_config->aac_spec_data_resilience_flag), 1);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->ld_sbr_present_flag), 1);
if (pstr_eld_config->ld_sbr_present_flag) {
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->ld_sbr_sample_rate), 1);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->ld_sbr_crc_flag), 1);
bit_cnt += ld_sbr_header(pstr_it_bit_buff, pstr_eld_config->sbr_config, channelConfiguration);
}
if (pstr_eld_config->num_sac_cfg_bits) {
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->eld_ext_type[0]), 4);
bit_cnt +=
iusace_write_escape_value(pstr_it_bit_buff, (pstr_eld_config->eld_ext_len[0]), 4, 8, 16);
if (IAAC_ELDEXT_LDSAC == pstr_eld_config->eld_ext_type[0]) {
bit_cnt += ixheaace_spatial_specific_config(pstr_it_bit_buff, pstr_eld_config);
}
}
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (IAAC_ELDEXT_TERM), 4);
return bit_cnt;
}
static WORD32 iaace_ga_specific_config_bytes(ia_bit_buf_struct *pstr_it_bit_buff,
ia_aace_config_struct *pstr_ga_specific_config,
WORD32 channelConfiguration, WORD32 aot) {
WORD32 bit_cnt = 0;
bit_cnt +=
iusace_write_bits_buf(pstr_it_bit_buff, (pstr_ga_specific_config->frame_length_flag), 1);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff,
(pstr_ga_specific_config->depends_on_core_coder), 1);
if (pstr_ga_specific_config->depends_on_core_coder) {
bit_cnt +=
iusace_write_bits_buf(pstr_it_bit_buff, (pstr_ga_specific_config->core_coder_delay), 14);
}
if (!channelConfiguration) {
}
if (AOT_AAC_LD == aot) {
pstr_ga_specific_config->extension_flag = 1;
}
if (AOT_AAC_LC == aot) {
pstr_ga_specific_config->extension_flag = 0;
}
bit_cnt +=
iusace_write_bits_buf(pstr_it_bit_buff, (pstr_ga_specific_config->extension_flag), 1);
if ((pstr_ga_specific_config->extension_flag) && ((AOT_AAC_LD == aot))) {
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff,
(pstr_ga_specific_config->aac_sec_data_resilience_flag), 1);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff,
(pstr_ga_specific_config->aac_sf_data_resilience_flag), 1);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff,
(pstr_ga_specific_config->aac_spec_data_resilience_flag), 1);
// extension flag 3
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, 0, 1);
}
return bit_cnt;
}
WORD32 ixheaace_get_audiospecific_config_bytes(
ia_bit_buf_struct *pstr_it_bit_buff,
ixheaace_audio_specific_config_struct *pstr_audio_specific_config, WORD32 aot) {
WORD32 bit_cnt = 0, i;
UWORD32 tmp = 0x0f; // initialized to indicate no sampling frequency index field
WORD32 ext_aot = -1;
WORD32 ext_id = 0;
WORD32 sbr_present_flag = 0, ps_present_flag = 0;
if (((AOT_AAC_ELD == aot) &&
(1 == pstr_audio_specific_config->str_aac_config.ld_sbr_sample_rate)) ||
(AOT_SBR == aot) || (AOT_PS == aot)) {
// dual rate
pstr_audio_specific_config->ext_sampling_frequency =
pstr_audio_specific_config->sampling_frequency;
pstr_audio_specific_config->sampling_frequency /= 2;
if ((AOT_SBR == aot) || (AOT_PS == aot)) {
aot = AOT_AAC_LC;
}
}
pstr_audio_specific_config->audio_object_type = aot;
{
for (i = 0; i < sizeof(ia_sampl_freq_table) / sizeof(ia_sampl_freq_table[0]); i++) {
if (ia_sampl_freq_table[i] == pstr_audio_specific_config->sampling_frequency) {
tmp = i;
break;
}
}
}
pstr_audio_specific_config->samp_freq_index = (UWORD32)tmp;
// Write Audio Object Type
if (pstr_audio_specific_config->audio_object_type > 31) {
tmp = pstr_audio_specific_config->audio_object_type - 32;
pstr_audio_specific_config->audio_object_type = 31;
}
bit_cnt +=
iusace_write_bits_buf(pstr_it_bit_buff, (pstr_audio_specific_config->audio_object_type), 5);
if (pstr_audio_specific_config->audio_object_type == 31) {
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, tmp, 6);
pstr_audio_specific_config->audio_object_type = tmp + 32;
}
// Write Audio Object Type
bit_cnt +=
iusace_write_bits_buf(pstr_it_bit_buff, (pstr_audio_specific_config->samp_freq_index), 4);
if (pstr_audio_specific_config->samp_freq_index == 0xf) {
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff,
(pstr_audio_specific_config->sampling_frequency), 24);
} else {
pstr_audio_specific_config->sampling_frequency =
iusace_sampl_freq_table[pstr_audio_specific_config->samp_freq_index];
}
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff,
(pstr_audio_specific_config->channel_configuration), 4);
if ((AOT_SBR == aot) || (AOT_PS == aot)) {
ext_aot = AOT_SBR;
sbr_present_flag = 1;
tmp = 0x0f;
for (i = 0; i < sizeof(ia_sampl_freq_table) / sizeof(ia_sampl_freq_table[0]); i++) {
if (ia_sampl_freq_table[i] == pstr_audio_specific_config->ext_sampling_frequency) {
tmp = i;
break;
}
}
pstr_audio_specific_config->ext_samp_freq_index = (UWORD32)tmp;
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff,
(pstr_audio_specific_config->ext_samp_freq_index), 4);
if (pstr_audio_specific_config->ext_samp_freq_index == 0xf) {
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff,
(pstr_audio_specific_config->ext_sampling_frequency), 24);
}
if (AOT_PS == aot) {
ps_present_flag = 1;
}
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, AOT_AAC_LC, 5);
}
switch (aot) {
case AOT_AAC_ELD: {
bit_cnt += iaace_get_eld_specific_config_bytes(
pstr_it_bit_buff, &pstr_audio_specific_config->str_aac_config,
pstr_audio_specific_config->channel_configuration);
break;
}
case AOT_AAC_LD:
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS: {
bit_cnt += iaace_ga_specific_config_bytes(
pstr_it_bit_buff, &pstr_audio_specific_config->str_aac_config,
pstr_audio_specific_config->channel_configuration, aot);
if (AOT_AAC_LD == aot) {
// epconfig
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, 0, 2);
}
if (AOT_SBR == ext_aot) {
ext_id = 0x2b7;
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, ext_id, 11);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, aot, 5);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, sbr_present_flag, 1);
if (sbr_present_flag) {
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff,
(pstr_audio_specific_config->ext_samp_freq_index), 4);
if (pstr_audio_specific_config->ext_samp_freq_index == 0xf) {
bit_cnt += iusace_write_bits_buf(
pstr_it_bit_buff, (pstr_audio_specific_config->ext_sampling_frequency), 24);
}
if (AOT_PS == aot) {
ext_id = 0x548;
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, ext_id, 11);
bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, ps_present_flag, 1);
}
}
}
break;
}
default:
break;
}
return bit_cnt;
}

View file

@ -0,0 +1,42 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
typedef struct {
WORD32 audio_object_type;
UWORD32 samp_freq_index;
UWORD32 sampling_frequency;
WORD32 core_sbr_framelength_index;
UWORD32 channel_configuration;
UWORD32 ext_audio_object_type;
UWORD32 ext_samp_freq_index;
UWORD32 ext_sampling_frequency;
WORD32 num_audio_channels;
WORD32 output_channel_pos[BS_MAX_NUM_OUT_CHANNELS];
WORD32 sbr_present_flag;
WORD32 cfg_ext_present;
WORD32 ext_sync_word;
ia_aace_config_struct str_aac_config;
} ixheaace_audio_specific_config_struct;
WORD32 ixheaace_get_audiospecific_config_bytes(
ia_bit_buf_struct *pstr_it_bit_buff,
ixheaace_audio_specific_config_struct *pstr_audio_specific_config, WORD32 aot);

View file

@ -0,0 +1,35 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
#include "ixheaac_basic_ops32.h"
#include "ixheaac_basic_ops16.h"
#include "ixheaac_basic_ops40.h"
#include "ixheaac_basic_ops.h"
WORD ia_enhaacplus_enc_norm32_arr(const WORD32 *word32_arr, LOOPINDEX n) {
WORD32 max_bits = 0;
for (; n != 0; n--) {
max_bits = max_bits | ixheaac_abs32_sat(*word32_arr++);
}
return (ixheaac_pnorm32(max_bits));
}

View file

@ -0,0 +1,214 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <stdio.h>
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
#include "ixheaace_bitbuffer.h"
static VOID ia_enhaacplus_enc_update_bitbuf_word_ptr(ixheaace_bit_buf_handle pstr_bit_buf,
UWORD8 **p_bitbuf_word, WORD32 cnt) {
*p_bitbuf_word += cnt;
if (*p_bitbuf_word > pstr_bit_buf->ptr_bit_buf_end) {
*p_bitbuf_word -= (pstr_bit_buf->ptr_bit_buf_end - pstr_bit_buf->ptr_bit_buf_base + 1);
}
if (*p_bitbuf_word < pstr_bit_buf->ptr_bit_buf_base) {
*p_bitbuf_word += (pstr_bit_buf->ptr_bit_buf_end - pstr_bit_buf->ptr_bit_buf_base + 1);
}
}
ixheaace_bit_buf_handle ia_enhaacplus_enc_create_bitbuffer(ixheaace_bit_buf_handle pstr_bit_buf,
UWORD8 *ptr_bit_buf_base,
UWORD32 bitbuf_size) {
pstr_bit_buf->ptr_bit_buf_base = ptr_bit_buf_base;
pstr_bit_buf->ptr_bit_buf_end = ptr_bit_buf_base + bitbuf_size - 1;
pstr_bit_buf->ptr_read_next = ptr_bit_buf_base;
pstr_bit_buf->ptr_write_next = ptr_bit_buf_base;
pstr_bit_buf->write_position = 7;
pstr_bit_buf->read_position = 7;
pstr_bit_buf->cnt_bits = 0;
pstr_bit_buf->size = bitbuf_size * 8;
return pstr_bit_buf;
}
VOID ia_enhaacplus_enc_delete_bitbuffer(ixheaace_bit_buf_handle pstr_bit_buf) {
pstr_bit_buf = NULL;
}
VOID ixheaace_reset_bitbuf(ixheaace_bit_buf_handle pstr_bit_buf, UWORD8 *ptr_bit_buf_base,
UWORD32 bitbuf_size) {
pstr_bit_buf->ptr_bit_buf_base = ptr_bit_buf_base;
pstr_bit_buf->ptr_bit_buf_end = ptr_bit_buf_base + bitbuf_size - 1;
pstr_bit_buf->ptr_read_next = ptr_bit_buf_base;
pstr_bit_buf->ptr_write_next = ptr_bit_buf_base;
pstr_bit_buf->read_position = 7;
pstr_bit_buf->write_position = 7;
pstr_bit_buf->cnt_bits = 0;
}
VOID ixheaace_copy_bitbuf_to_and_fro(ixheaace_bit_buf_handle h_bitbuf_src,
ixheaace_bit_buf_handle h_bitbuf_dst)
{
WORD32 i;
WORD32 bytes_to_go_src =
(WORD32)(h_bitbuf_src->ptr_bit_buf_end - h_bitbuf_src->ptr_bit_buf_base);
UWORD8 *dst = &h_bitbuf_dst->ptr_bit_buf_base[0];
UWORD8 *src = &h_bitbuf_src->ptr_bit_buf_base[0];
WORD32 temp321, temp322;
UWORD8 temp1, temp2, temp3;
WORD32 count;
WORD32 remaining;
count = bytes_to_go_src >> 1;
remaining = bytes_to_go_src - (count << 1);
for (i = count - 1; i >= 0; i--) {
temp1 = *src;
temp2 = *dst;
temp3 = *(src + 1);
*dst++ = temp1;
temp1 = *dst;
*src++ = temp2;
*dst++ = temp3;
*src++ = temp1;
}
if (remaining)
for (i = remaining - 1; i >= 0; i--) {
temp1 = *src;
temp2 = *dst;
*dst++ = temp1;
*src++ = temp2;
}
src = h_bitbuf_src->ptr_read_next;
dst = h_bitbuf_dst->ptr_read_next;
h_bitbuf_dst->ptr_read_next = src;
h_bitbuf_src->ptr_read_next = dst;
src = h_bitbuf_src->ptr_write_next;
dst = h_bitbuf_dst->ptr_write_next;
h_bitbuf_dst->ptr_write_next = src;
h_bitbuf_src->ptr_write_next = dst;
temp321 = h_bitbuf_dst->read_position;
temp322 = h_bitbuf_src->read_position;
h_bitbuf_dst->read_position = temp322;
h_bitbuf_src->read_position = temp321;
temp321 = h_bitbuf_dst->write_position;
temp322 = h_bitbuf_src->write_position;
h_bitbuf_dst->write_position = temp322;
h_bitbuf_src->write_position = temp321;
temp321 = h_bitbuf_dst->cnt_bits;
temp322 = h_bitbuf_src->cnt_bits;
h_bitbuf_dst->cnt_bits = temp322;
h_bitbuf_src->cnt_bits = temp321;
}
VOID ia_enhaacplus_enc_copy_bitbuf(ixheaace_bit_buf_handle h_bitbuf_src,
ixheaace_bit_buf_handle h_bitbuf_dst) {
WORD32 i;
WORD32 bytes_to_go_src =
(WORD32)(h_bitbuf_src->ptr_bit_buf_end - h_bitbuf_src->ptr_bit_buf_base);
for (i = 0; i < bytes_to_go_src; i++) {
h_bitbuf_dst->ptr_bit_buf_base[i] = h_bitbuf_src->ptr_bit_buf_base[i];
}
h_bitbuf_dst->ptr_read_next = h_bitbuf_src->ptr_read_next;
h_bitbuf_dst->ptr_write_next = h_bitbuf_src->ptr_write_next;
h_bitbuf_dst->read_position = h_bitbuf_src->read_position;
h_bitbuf_dst->write_position = h_bitbuf_src->write_position;
h_bitbuf_dst->cnt_bits = h_bitbuf_src->cnt_bits;
}
WORD32 ia_enhaacplus_enc_get_bits_available(ixheaace_bit_buf_handle pstr_bit_buf_handle) {
return pstr_bit_buf_handle->cnt_bits;
}
UWORD32
ixheaace_readbits(ixheaace_bit_buf_handle pstr_bit_buf, UWORD8 no_bits_to_read) {
UWORD32 return_value;
if (no_bits_to_read >= 25) {
return 0;
}
pstr_bit_buf->cnt_bits -= no_bits_to_read;
pstr_bit_buf->read_position -= no_bits_to_read;
return_value = (UWORD32)*pstr_bit_buf->ptr_read_next;
while (pstr_bit_buf->read_position < 0) {
pstr_bit_buf->read_position += 8;
pstr_bit_buf->ptr_read_next++;
if (pstr_bit_buf->ptr_read_next > pstr_bit_buf->ptr_bit_buf_end) {
pstr_bit_buf->ptr_read_next = pstr_bit_buf->ptr_bit_buf_base;
}
return_value <<= 8;
return_value |= (UWORD32)*pstr_bit_buf->ptr_read_next;
}
return_value = return_value << (31 - no_bits_to_read - pstr_bit_buf->read_position) >>
(32 - no_bits_to_read);
return (return_value);
}
VOID ia_enhaacplus_enc_wind_bitbuffer_bidirectional(ixheaace_bit_buf_handle pstr_bit_buf,
WORD32 offset) {
if (offset != 0) {
WORD32 buff_offset;
pstr_bit_buf->read_position -= offset;
buff_offset = (pstr_bit_buf->read_position) >> 3;
pstr_bit_buf->read_position -= buff_offset << 3;
if (buff_offset) {
ia_enhaacplus_enc_update_bitbuf_word_ptr(pstr_bit_buf, &pstr_bit_buf->ptr_read_next,
-buff_offset);
}
pstr_bit_buf->cnt_bits -= offset;
}
}

View file

@ -0,0 +1,67 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#undef ARIB_COMPLIANCE
#undef ADTS_CRC_ENABLE
typedef struct {
UWORD8 *ptr_bit_buf_base; /* pointer points to first position in bitstream buffer */
UWORD8 *ptr_bit_buf_end; /* pointer points to last position in bitstream buffer */
UWORD8 *ptr_read_next; /* pointer points to next available word in bitstream buffer to read */
UWORD8 *ptr_write_next; /* pointer points to next available word in bitstream buffer to write */
WORD32 read_position; /* 7 <= read_position <= 0 */
WORD32 write_position; /* 7 <= write_position <= 0 */
WORD32 cnt_bits; /* number of available bits in the bitstream buffer
write bits to bitstream buffer => increment cnt_bits
read bits from bitstream buffer => decrement cnt_bits */
WORD32 size; /* size of bitbuffer in bits */
} ixheaace_bit_buf;
/* Define pointer to bit buffer structure */
typedef ixheaace_bit_buf *ixheaace_bit_buf_handle;
ixheaace_bit_buf_handle ia_enhaacplus_enc_create_bitbuffer(ixheaace_bit_buf_handle pstr_bit_buf,
UWORD8 *ptr_bit_buf_base,
UWORD32 bitbuf_size);
VOID ia_enhaacplus_enc_delete_bitbuffer(ixheaace_bit_buf_handle pstr_bit_buf);
UWORD32 ixheaace_readbits(ixheaace_bit_buf_handle pstr_bit_buf, UWORD8 no_bits_to_read);
UWORD8 ixheaace_write_bits(ixheaace_bit_buf_handle pstr_bit_buf, UWORD32 write_value,
UWORD8 num_bits_to_write);
VOID ixheaace_reset_bitbuf(ixheaace_bit_buf_handle pstr_bit_buf, UWORD8 *ptr_bit_buf_base,
UWORD32 bitbuf_size);
VOID ixheaace_copy_bitbuf_to_and_fro(ixheaace_bit_buf_handle h_bitbuf_src,
ixheaace_bit_buf_handle h_bitbuf_dst);
VOID ia_enhaacplus_enc_copy_bitbuf(ixheaace_bit_buf_handle h_bitbuf_src,
ixheaace_bit_buf_handle h_bitbuf_dst);
VOID ia_enhaacplus_enc_wind_bitbuffer_bidirectional(ixheaace_bit_buf_handle pstr_bit_buf,
WORD32 offset);
WORD32 ia_enhaacplus_enc_get_bits_available(ixheaace_bit_buf_handle pstr_bit_buf_handle);
UWORD32 ixheaace_byte_align_buffer(ixheaace_bit_buf_handle pstr_it_bit_buff);

View file

@ -0,0 +1,98 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <stdio.h>
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
#include <stdlib.h>
#include "ixheaac_basic_ops32.h"
#include "ixheaac_basic_ops16.h"
#include "ixheaac_basic_ops40.h"
#include "ixheaac_basic_ops.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaace_common_utils.h"
UWORD8
ixheaace_write_bits(ixheaace_bit_buf_handle pstr_bit_buf, UWORD32 write_value,
UWORD8 num_bits_to_write) {
WORD8 bits_to_write;
WORD32 write_position;
UWORD8 *ptr_write_next;
UWORD8 *ptr_bit_buf_end;
UWORD8 *ptr_bit_buf_base;
UWORD8 bits_written = num_bits_to_write;
if (pstr_bit_buf == NULL) {
return num_bits_to_write;
}
pstr_bit_buf->cnt_bits += num_bits_to_write;
write_position = pstr_bit_buf->write_position;
ptr_write_next = pstr_bit_buf->ptr_write_next;
ptr_bit_buf_end = pstr_bit_buf->ptr_bit_buf_end;
ptr_bit_buf_base = pstr_bit_buf->ptr_bit_buf_base;
while (num_bits_to_write) {
UWORD8 tmp, msk;
bits_to_write = (WORD8)MIN(write_position + 1, num_bits_to_write);
tmp = (UWORD8)(write_value << (32 - num_bits_to_write) >>
(32 - bits_to_write) << (write_position + 1 - bits_to_write));
msk = ~(((1 << bits_to_write) - 1) << (write_position + 1 - bits_to_write));
*ptr_write_next &= msk;
*ptr_write_next |= tmp;
write_position -= bits_to_write;
num_bits_to_write -= bits_to_write;
if (write_position < 0) {
write_position += 8;
ptr_write_next++;
if (ptr_write_next > ptr_bit_buf_end) {
ptr_write_next = ptr_bit_buf_base;
}
}
}
pstr_bit_buf->write_position = write_position;
pstr_bit_buf->ptr_write_next = ptr_write_next;
return bits_written;
}
UWORD32 ixheaace_byte_align_buffer(ixheaace_bit_buf_handle pstr_it_bit_buff) {
WORD alignment;
alignment = (WORD)((pstr_it_bit_buff->cnt_bits) & 0x07);
if (alignment) {
ixheaace_write_bits(pstr_it_bit_buff, 0, (UWORD8)(8 - alignment));
return (8 - alignment);
}
return 0;
}

View file

@ -0,0 +1,950 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <limits.h>
#include <stdlib.h>
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
#include "ixheaac_basic_ops32.h"
#include "ixheaac_basic_ops16.h"
#include "ixheaac_basic_ops40.h"
#include "ixheaac_basic_ops.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaace_bits_count.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_enc_main.h"
#include "ixheaace_common_utils.h"
VOID ia_enhaacplus_enc_count1_2_3_4_5_6_7_8_9_10_11(const WORD16 *values, const WORD32 width,
WORD32 *bitcnt,
ixheaace_huffman_tables *pstr_huffman_tbl,
WORD32 invalid_bitcnt) {
WORD32 i;
WORD32 bits1_2, bits3_4, bits5_6, bits7_8, bits9_10, bit11, sc;
WORD32 temp_0, temp_1, temp_2, temp_3;
(VOID) invalid_bitcnt;
bits1_2 = 0;
bits3_4 = 0;
bits5_6 = 0;
bits7_8 = 0;
bits9_10 = 0;
bit11 = 0;
sc = 0;
for (i = 0; i < width; i += 4) {
temp_0 = values[i + 0];
temp_1 = values[i + 1];
temp_2 = values[i + 2];
temp_3 = values[i + 3];
bits1_2 +=
EXPAND(pstr_huffman_tbl->huff_ltab1_2[temp_0 + 1][temp_1 + 1][temp_2 + 1][temp_3 + 1]);
bits5_6 += EXPAND(pstr_huffman_tbl->huff_ltab5_6[temp_0 + 4][temp_1 + 4]);
bits5_6 += EXPAND(pstr_huffman_tbl->huff_ltab5_6[temp_2 + 4][temp_3 + 4]);
sc += (temp_0 != 0) + (temp_1 != 0) + (temp_2 != 0) + (temp_3 != 0);
temp_0 = abs32(temp_0);
temp_1 = abs32(temp_1);
temp_2 = abs32(temp_2);
temp_3 = abs32(temp_3);
bits3_4 += EXPAND(pstr_huffman_tbl->huff_ltab3_4[temp_0][temp_1][temp_2][temp_3]);
bits7_8 += EXPAND(pstr_huffman_tbl->huff_ltab7_8[temp_0][temp_1]);
bits7_8 += EXPAND(pstr_huffman_tbl->huff_ltab7_8[temp_2][temp_3]);
bits9_10 += EXPAND(pstr_huffman_tbl->huff_ltab9_10[temp_0][temp_1]);
bits9_10 += EXPAND(pstr_huffman_tbl->huff_ltab9_10[temp_2][temp_3]);
bit11 += EXPAND(pstr_huffman_tbl->huff_ltab11[temp_0][temp_1]);
bit11 += EXPAND(pstr_huffman_tbl->huff_ltab11[temp_2][temp_3]);
}
bitcnt[1] = HI_EXPLTAB(bits1_2);
bitcnt[2] = LO_EXPLTAB(bits1_2);
bitcnt[3] = HI_EXPLTAB(bits3_4) + sc;
bitcnt[4] = LO_EXPLTAB(bits3_4) + sc;
bitcnt[5] = HI_EXPLTAB(bits5_6);
bitcnt[6] = LO_EXPLTAB(bits5_6);
bitcnt[7] = HI_EXPLTAB(bits7_8) + sc;
bitcnt[8] = LO_EXPLTAB(bits7_8) + sc;
bitcnt[9] = HI_EXPLTAB(bits9_10) + sc;
bitcnt[10] = LO_EXPLTAB(bits9_10) + sc;
bitcnt[11] = bit11 + sc;
}
static VOID ia_enhaacplus_enc_count3_4_5_6_7_8_9_10_11(const WORD16 *values, const WORD32 width,
WORD32 *bitcnt,
ixheaace_huffman_tables *pstr_huffman_tbl,
WORD32 invalid_bitcnt) {
WORD32 i;
WORD32 bits3_4, bits5_6, bits7_8, bits9_10, bit11, sc;
WORD32 temp_0, temp_1, temp_2, temp_3;
bits3_4 = 0;
bits5_6 = 0;
bits7_8 = 0;
bits9_10 = 0;
bit11 = 0;
sc = 0;
for (i = 0; i < width; i += 4) {
temp_0 = values[i + 0];
temp_1 = values[i + 1];
temp_2 = values[i + 2];
temp_3 = values[i + 3];
bits5_6 += EXPAND(pstr_huffman_tbl->huff_ltab5_6[temp_0 + 4][temp_1 + 4]);
bits5_6 += EXPAND(pstr_huffman_tbl->huff_ltab5_6[temp_2 + 4][temp_3 + 4]);
temp_0 = abs32(temp_0);
temp_1 = abs32(temp_1);
temp_2 = abs32(temp_2);
temp_3 = abs32(temp_3);
bits3_4 += EXPAND(pstr_huffman_tbl->huff_ltab3_4[temp_0][temp_1][temp_2][temp_3]);
bits7_8 += EXPAND(pstr_huffman_tbl->huff_ltab7_8[temp_0][temp_1]);
bits7_8 += EXPAND(pstr_huffman_tbl->huff_ltab7_8[temp_2][temp_3]);
bits9_10 += EXPAND(pstr_huffman_tbl->huff_ltab9_10[temp_0][temp_1]);
bits9_10 += EXPAND(pstr_huffman_tbl->huff_ltab9_10[temp_2][temp_3]);
bit11 += EXPAND(pstr_huffman_tbl->huff_ltab11[temp_0][temp_1]);
bit11 += EXPAND(pstr_huffman_tbl->huff_ltab11[temp_2][temp_3]);
sc += (temp_0 > 0) + (temp_1 > 0) + (temp_2 > 0) + (temp_3 > 0);
}
bitcnt[1] = invalid_bitcnt;
bitcnt[2] = invalid_bitcnt;
bitcnt[3] = HI_EXPLTAB(bits3_4) + sc;
bitcnt[4] = LO_EXPLTAB(bits3_4) + sc;
bitcnt[5] = HI_EXPLTAB(bits5_6);
bitcnt[6] = LO_EXPLTAB(bits5_6);
bitcnt[7] = HI_EXPLTAB(bits7_8) + sc;
bitcnt[8] = LO_EXPLTAB(bits7_8) + sc;
bitcnt[9] = HI_EXPLTAB(bits9_10) + sc;
bitcnt[10] = LO_EXPLTAB(bits9_10) + sc;
bitcnt[11] = bit11 + sc;
}
static VOID ia_enhaacplus_enc_count5_6_7_8_9_10_11(const WORD16 *values, const WORD32 width,
WORD32 *bitcnt,
ixheaace_huffman_tables *pstr_huffman_tbl,
WORD32 invalid_bitcnt) {
WORD32 i;
WORD32 bits5_6, bits7_8, bits9_10, bit11, sc;
WORD32 temp_0, temp_1;
bits5_6 = 0;
bits7_8 = 0;
bits9_10 = 0;
bit11 = 0;
sc = 0;
for (i = 0; i < width; i += 2) {
temp_0 = values[i + 0];
temp_1 = values[i + 1];
bits5_6 += EXPAND(pstr_huffman_tbl->huff_ltab5_6[temp_0 + 4][temp_1 + 4]);
temp_0 = abs32(temp_0);
temp_1 = abs32(temp_1);
bits7_8 += EXPAND(pstr_huffman_tbl->huff_ltab7_8[temp_0][temp_1]);
bits9_10 += EXPAND(pstr_huffman_tbl->huff_ltab9_10[temp_0][temp_1]);
bit11 += EXPAND(pstr_huffman_tbl->huff_ltab11[temp_0][temp_1]);
sc += (temp_0 > 0) + (temp_1 > 0);
}
bitcnt[1] = invalid_bitcnt;
bitcnt[2] = invalid_bitcnt;
bitcnt[3] = invalid_bitcnt;
bitcnt[4] = invalid_bitcnt;
bitcnt[5] = HI_EXPLTAB(bits5_6);
bitcnt[6] = LO_EXPLTAB(bits5_6);
bitcnt[7] = HI_EXPLTAB(bits7_8) + sc;
bitcnt[8] = LO_EXPLTAB(bits7_8) + sc;
bitcnt[9] = HI_EXPLTAB(bits9_10) + sc;
bitcnt[10] = LO_EXPLTAB(bits9_10) + sc;
bitcnt[11] = bit11 + sc;
}
static VOID ia_enhaacplus_enc_count7_8_9_10_11(const WORD16 *values, const WORD32 width,
WORD32 *bitcnt,
ixheaace_huffman_tables *pstr_huffman_tbl,
WORD32 invalid_bitcnt) {
WORD32 i;
WORD32 bits7_8, bits9_10, bit11, sc;
WORD32 temp_0, temp_1;
bits7_8 = 0;
bits9_10 = 0;
bit11 = 0;
sc = 0;
for (i = 0; i < width; i += 2) {
temp_0 = abs32(values[i + 0]);
temp_1 = abs32(values[i + 1]);
bits7_8 += EXPAND(pstr_huffman_tbl->huff_ltab7_8[temp_0][temp_1]);
bits9_10 += EXPAND(pstr_huffman_tbl->huff_ltab9_10[temp_0][temp_1]);
bit11 += EXPAND(pstr_huffman_tbl->huff_ltab11[temp_0][temp_1]);
sc += (temp_0 > 0) + (temp_1 > 0);
}
bitcnt[1] = invalid_bitcnt;
bitcnt[2] = invalid_bitcnt;
bitcnt[3] = invalid_bitcnt;
bitcnt[4] = invalid_bitcnt;
bitcnt[5] = invalid_bitcnt;
bitcnt[6] = invalid_bitcnt;
bitcnt[7] = HI_EXPLTAB(bits7_8) + sc;
bitcnt[8] = LO_EXPLTAB(bits7_8) + sc;
bitcnt[9] = HI_EXPLTAB(bits9_10) + sc;
bitcnt[10] = LO_EXPLTAB(bits9_10) + sc;
bitcnt[11] = bit11 + sc;
}
static VOID ia_enhaacplus_enc_count9_10_11(const WORD16 *values, const WORD32 width,
WORD32 *bitcnt,
ixheaace_huffman_tables *pstr_huffman_tbl,
WORD32 invalid_bitcnt) {
WORD32 i;
WORD32 bits9_10, bit11, sc;
WORD32 temp_0, temp_1;
bits9_10 = 0;
bit11 = 0;
sc = 0;
for (i = 0; i < width; i += 2) {
temp_0 = abs32(values[i + 0]);
temp_1 = abs32(values[i + 1]);
bits9_10 += EXPAND(pstr_huffman_tbl->huff_ltab9_10[temp_0][temp_1]);
bit11 += EXPAND(pstr_huffman_tbl->huff_ltab11[temp_0][temp_1]);
sc += (temp_0 > 0) + (temp_1 > 0);
}
bitcnt[1] = invalid_bitcnt;
bitcnt[2] = invalid_bitcnt;
bitcnt[3] = invalid_bitcnt;
bitcnt[4] = invalid_bitcnt;
bitcnt[5] = invalid_bitcnt;
bitcnt[6] = invalid_bitcnt;
bitcnt[7] = invalid_bitcnt;
bitcnt[8] = invalid_bitcnt;
bitcnt[9] = HI_EXPLTAB(bits9_10) + sc;
bitcnt[10] = LO_EXPLTAB(bits9_10) + sc;
bitcnt[11] = bit11 + sc;
}
static VOID ia_enhaacplus_enc_count11(const WORD16 *values, const WORD32 width, WORD32 *bitcnt,
ixheaace_huffman_tables *pstr_huffman_tbl,
WORD32 invalid_bitcnt) {
WORD32 i;
WORD32 bit11, sc;
WORD32 temp_0, temp_1;
bit11 = 0;
sc = 0;
for (i = 0; i < width; i += 2) {
temp_0 = abs32(values[i + 0]);
temp_1 = abs32(values[i + 1]);
bit11 += EXPAND(pstr_huffman_tbl->huff_ltab11[temp_0][temp_1]);
sc += (temp_0 > 0) + (temp_1 > 0);
}
bitcnt[1] = invalid_bitcnt;
bitcnt[2] = invalid_bitcnt;
bitcnt[3] = invalid_bitcnt;
bitcnt[4] = invalid_bitcnt;
bitcnt[5] = invalid_bitcnt;
bitcnt[6] = invalid_bitcnt;
bitcnt[7] = invalid_bitcnt;
bitcnt[8] = invalid_bitcnt;
bitcnt[9] = invalid_bitcnt;
bitcnt[10] = invalid_bitcnt;
bitcnt[11] = bit11 + sc;
}
static VOID ia_enhaacplus_enc_count_esc(const WORD16 *values, const WORD32 width, WORD32 *bitcnt,
ixheaace_huffman_tables *pstr_huffman_tbl,
WORD32 invalid_bitcnt) {
WORD32 i;
WORD32 bit11, ec, sc;
WORD32 temp_0, temp_1, t00, t01;
bit11 = 0;
sc = 0;
ec = 0;
for (i = 0; i < width; i += 2) {
temp_0 = abs32(values[i + 0]);
temp_1 = abs32(values[i + 1]);
sc += (temp_0 > 0) + (temp_1 > 0);
t00 = MIN(temp_0, 16);
t01 = MIN(temp_1, 16);
bit11 += EXPAND(pstr_huffman_tbl->huff_ltab11[t00][t01]);
if (temp_0 >= 16) {
ec += 5;
while ((temp_0 >>= 1) >= 16) {
ec += 2;
}
}
if (temp_1 >= 16) {
ec += 5;
while ((temp_1 >>= 1) >= 16) {
ec += 2;
}
}
}
bitcnt[1] = invalid_bitcnt;
bitcnt[2] = invalid_bitcnt;
bitcnt[3] = invalid_bitcnt;
bitcnt[4] = invalid_bitcnt;
bitcnt[5] = invalid_bitcnt;
bitcnt[6] = invalid_bitcnt;
bitcnt[7] = invalid_bitcnt;
bitcnt[8] = invalid_bitcnt;
bitcnt[9] = invalid_bitcnt;
bitcnt[10] = invalid_bitcnt;
bitcnt[11] = bit11 + sc + ec;
}
typedef VOID (*COUNT_FUNCTION)(const WORD16 *values, const WORD32 width, WORD32 *bitcnt,
ixheaace_huffman_tables *pstr_huffman_tbl, WORD32 invalid_bitcnt);
static COUNT_FUNCTION ia_enhaacplus_enc_count_func_tab[CODE_BCK_ESC_LAV + 1] = {
ia_enhaacplus_enc_count1_2_3_4_5_6_7_8_9_10_11, /* 0 */
ia_enhaacplus_enc_count1_2_3_4_5_6_7_8_9_10_11, /* 1 */
ia_enhaacplus_enc_count3_4_5_6_7_8_9_10_11, /* 2 */
ia_enhaacplus_enc_count5_6_7_8_9_10_11, /* 3 */
ia_enhaacplus_enc_count5_6_7_8_9_10_11, /* 4 */
ia_enhaacplus_enc_count7_8_9_10_11, /* 5 */
ia_enhaacplus_enc_count7_8_9_10_11, /* 6 */
ia_enhaacplus_enc_count7_8_9_10_11, /* 7 */
ia_enhaacplus_enc_count9_10_11, /* 8 */
ia_enhaacplus_enc_count9_10_11, /* 9 */
ia_enhaacplus_enc_count9_10_11, /* 10 */
ia_enhaacplus_enc_count9_10_11, /* 11 */
ia_enhaacplus_enc_count9_10_11, /* 12 */
ia_enhaacplus_enc_count11, /* 13 */
ia_enhaacplus_enc_count11, /* 14 */
ia_enhaacplus_enc_count11, /* 15 */
ia_enhaacplus_enc_count_esc /* 16 */
};
VOID ia_enhaacplus_enc_bitcount(const WORD16 *ptr_values, const WORD32 width, WORD32 max_val,
WORD32 *bit_cnt, ixheaace_huffman_tables *pstr_huffman_tbl,
WORD32 aot) {
WORD32 invalid_bitcnt;
if (max_val == 0) {
*bit_cnt = 0;
} else {
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
*bit_cnt = INVALID_BITCOUNT_LC;
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
*bit_cnt = INVALID_BITCOUNT_LD;
break;
}
}
invalid_bitcnt = *bit_cnt;
max_val = MIN(max_val, CODE_BCK_ESC_LAV);
ia_enhaacplus_enc_count_func_tab[max_val](ptr_values, width, bit_cnt, pstr_huffman_tbl,
invalid_bitcnt);
}
VOID ia_enhaacplus_enc_code_values(WORD16 *ptr_values, WORD32 width, WORD32 code_book,
ixheaace_bit_buf_handle pstr_bitstream,
ixheaace_huffman_tables *pstr_huffman_tbl) {
WORD32 i, temp_0, temp_1, temp_2, temp_3, t00, t01;
WORD32 code_word, code_length;
WORD32 sign, sign_length;
WORD16 *ptr_temp_values = ptr_values;
switch (code_book) {
case CODE_BCK_ZERO_NO:
break;
case CODE_BCK_1_NO:
width = width >> 2;
for (i = width - 1; i >= 0; i--) {
temp_0 = *ptr_temp_values++;
temp_1 = *ptr_temp_values++;
temp_2 = *ptr_temp_values++;
temp_3 = *ptr_temp_values++;
code_word = pstr_huffman_tbl->huff_ctab1[temp_0 + 1][temp_1 + 1][temp_2 + 1][temp_3 + 1];
code_length = HI_LTAB(
pstr_huffman_tbl->huff_ltab1_2[temp_0 + 1][temp_1 + 1][temp_2 + 1][temp_3 + 1]);
ixheaace_write_bits(pstr_bitstream, code_word, (UWORD8)code_length);
}
break;
case CODE_BCK_2_NO:
width = width >> 2;
for (i = width - 1; i >= 0; i--) {
temp_0 = *ptr_temp_values++;
temp_1 = *ptr_temp_values++;
temp_2 = *ptr_temp_values++;
temp_3 = *ptr_temp_values++;
code_word = pstr_huffman_tbl->huff_ctab2[temp_0 + 1][temp_1 + 1][temp_2 + 1][temp_3 + 1];
code_length = LO_LTAB(
pstr_huffman_tbl->huff_ltab1_2[temp_0 + 1][temp_1 + 1][temp_2 + 1][temp_3 + 1]);
ixheaace_write_bits(pstr_bitstream, code_word, (UWORD8)code_length);
}
break;
case CODE_BCK_3_NO:
for (i = 0; i < width; i += 4) {
sign = 0;
sign_length = 0;
temp_0 = ptr_values[i + 0];
if (temp_0 != 0) {
sign_length++;
sign <<= 1;
if (temp_0 < 0) {
sign |= 1;
temp_0 = abs32(temp_0);
}
}
temp_1 = ptr_values[i + 1];
if (temp_1 != 0) {
sign_length++;
sign <<= 1;
if (temp_1 < 0) {
sign |= 1;
temp_1 = abs32(temp_1);
}
}
temp_2 = ptr_values[i + 2];
if (temp_2 != 0) {
sign_length++;
sign <<= 1;
if (temp_2 < 0) {
sign |= 1;
temp_2 = abs32(temp_2);
}
}
temp_3 = ptr_values[i + 3];
if (temp_3 != 0) {
sign_length++;
sign <<= 1;
if (temp_3 < 0) {
sign |= 1;
temp_3 = abs32(temp_3);
}
}
code_word = pstr_huffman_tbl->huff_ctab3[temp_0][temp_1][temp_2][temp_3];
code_length = HI_LTAB(pstr_huffman_tbl->huff_ltab3_4[temp_0][temp_1][temp_2][temp_3]);
ixheaace_write_bits(pstr_bitstream, code_word, (UWORD8)code_length);
ixheaace_write_bits(pstr_bitstream, sign, (UWORD8)sign_length);
}
break;
case CODE_BCK_4_NO:
for (i = 0; i < width; i += 4) {
sign = 0;
sign_length = 0;
temp_0 = ptr_values[i + 0];
if (temp_0 != 0) {
sign_length++;
sign <<= 1;
if (temp_0 < 0) {
sign |= 1;
temp_0 = abs32(temp_0);
}
}
temp_1 = ptr_values[i + 1];
if (temp_1 != 0) {
sign_length++;
sign <<= 1;
if (temp_1 < 0) {
sign |= 1;
temp_1 = abs32(temp_1);
}
}
temp_2 = ptr_values[i + 2];
if (temp_2 != 0) {
sign_length++;
sign <<= 1;
if (temp_2 < 0) {
sign |= 1;
temp_2 = abs32(temp_2);
}
}
temp_3 = ptr_values[i + 3];
if (temp_3 != 0) {
sign_length++;
sign <<= 1;
if (temp_3 < 0) {
sign |= 1;
temp_3 = abs32(temp_3);
}
}
code_word = pstr_huffman_tbl->huff_ctab4[temp_0][temp_1][temp_2][temp_3];
code_length = LO_LTAB(pstr_huffman_tbl->huff_ltab3_4[temp_0][temp_1][temp_2][temp_3]);
ixheaace_write_bits(pstr_bitstream, code_word, (UWORD8)code_length);
ixheaace_write_bits(pstr_bitstream, sign, (UWORD8)sign_length);
}
break;
case CODE_BCK_5_NO:
width = width >> 1;
for (i = width - 1; i >= 0; i--) {
temp_0 = *ptr_temp_values++;
temp_1 = *ptr_temp_values++;
code_word = pstr_huffman_tbl->huff_ctab5[temp_0 + 4][temp_1 + 4];
code_length = HI_LTAB(pstr_huffman_tbl->huff_ltab5_6[temp_0 + 4][temp_1 + 4]);
ixheaace_write_bits(pstr_bitstream, code_word, (UWORD8)code_length);
}
break;
case CODE_BCK_6_NO:
width = width >> 1;
for (i = width - 1; i >= 0; i--) {
temp_0 = *ptr_temp_values++;
temp_1 = *ptr_temp_values++;
code_word = pstr_huffman_tbl->huff_ctab6[temp_0 + 4][temp_1 + 4];
code_length = LO_LTAB(pstr_huffman_tbl->huff_ltab5_6[temp_0 + 4][temp_1 + 4]);
ixheaace_write_bits(pstr_bitstream, code_word, (UWORD8)code_length);
}
break;
case CODE_BCK_7_NO:
for (i = 0; i < width; i += 2) {
sign = 0;
sign_length = 0;
temp_0 = ptr_values[i + 0];
if (temp_0 != 0) {
sign_length++;
sign <<= 1;
if (temp_0 < 0) {
sign |= 1;
temp_0 = abs32(temp_0);
}
}
temp_1 = ptr_values[i + 1];
if (temp_1 != 0) {
sign_length++;
sign <<= 1;
if (temp_1 < 0) {
sign |= 1;
temp_1 = abs32(temp_1);
}
}
code_word = pstr_huffman_tbl->huff_ctab7[temp_0][temp_1];
code_length = HI_LTAB(pstr_huffman_tbl->huff_ltab7_8[temp_0][temp_1]);
ixheaace_write_bits(pstr_bitstream, code_word, (UWORD8)code_length);
ixheaace_write_bits(pstr_bitstream, sign, (UWORD8)sign_length);
}
break;
case CODE_BCK_8_NO:
for (i = 0; i < width; i += 2) {
sign = 0;
sign_length = 0;
temp_0 = ptr_values[i + 0];
if (temp_0 != 0) {
sign_length++;
sign <<= 1;
if (temp_0 < 0) {
sign |= 1;
temp_0 = abs32(temp_0);
}
}
temp_1 = ptr_values[i + 1];
if (temp_1 != 0) {
sign_length++;
sign <<= 1;
if (temp_1 < 0) {
sign |= 1;
temp_1 = abs32(temp_1);
}
}
code_word = pstr_huffman_tbl->huff_ctab8[temp_0][temp_1];
code_length = LO_LTAB(pstr_huffman_tbl->huff_ltab7_8[temp_0][temp_1]);
ixheaace_write_bits(pstr_bitstream, code_word, (UWORD8)code_length);
ixheaace_write_bits(pstr_bitstream, sign, (UWORD8)sign_length);
}
break;
case CODE_BCK_9_NO:
for (i = 0; i < width; i += 2) {
sign = 0;
sign_length = 0;
temp_0 = ptr_values[i + 0];
if (temp_0 != 0) {
sign_length++;
sign <<= 1;
if (temp_0 < 0) {
sign |= 1;
temp_0 = abs32(temp_0);
}
}
temp_1 = ptr_values[i + 1];
if (temp_1 != 0) {
sign_length++;
sign <<= 1;
if (temp_1 < 0) {
sign |= 1;
temp_1 = abs32(temp_1);
}
}
code_word = pstr_huffman_tbl->huff_ctab9[temp_0][temp_1];
code_length = HI_LTAB(pstr_huffman_tbl->huff_ltab9_10[temp_0][temp_1]);
ixheaace_write_bits(pstr_bitstream, code_word, (UWORD8)code_length);
ixheaace_write_bits(pstr_bitstream, sign, (UWORD8)sign_length);
}
break;
case CODE_BCK_10_NO:
for (i = 0; i < width; i += 2) {
sign = 0;
sign_length = 0;
temp_0 = ptr_values[i + 0];
if (temp_0 != 0) {
sign_length++;
sign <<= 1;
if (temp_0 < 0) {
sign |= 1;
temp_0 = abs32(temp_0);
}
}
temp_1 = ptr_values[i + 1];
if (temp_1 != 0) {
sign_length++;
sign <<= 1;
if (temp_1 < 0) {
sign |= 1;
temp_1 = abs32(temp_1);
}
}
code_word = pstr_huffman_tbl->huff_ctab10[temp_0][temp_1];
code_length = LO_LTAB(pstr_huffman_tbl->huff_ltab9_10[temp_0][temp_1]);
ixheaace_write_bits(pstr_bitstream, code_word, (UWORD8)code_length);
ixheaace_write_bits(pstr_bitstream, sign, (UWORD8)sign_length);
}
break;
case CODE_BCK_ESC_NO:
for (i = 0; i < width; i += 2) {
sign = 0;
sign_length = 0;
temp_0 = ptr_values[i + 0];
if (temp_0 != 0) {
sign_length++;
sign <<= 1;
if (temp_0 < 0) {
sign |= 1;
temp_0 = abs32(temp_0);
}
}
temp_1 = ptr_values[i + 1];
if (temp_1 != 0) {
sign_length++;
sign <<= 1;
if (temp_1 < 0) {
sign |= 1;
temp_1 = abs32(temp_1);
}
}
t00 = MIN(temp_0, 16);
t01 = MIN(temp_1, 16);
code_word = pstr_huffman_tbl->huff_ctab11[t00][t01];
code_length = pstr_huffman_tbl->huff_ltab11[t00][t01];
ixheaace_write_bits(pstr_bitstream, code_word, (UWORD8)code_length);
ixheaace_write_bits(pstr_bitstream, sign, (UWORD8)sign_length);
if (temp_0 >= 16) {
WORD32 n, p;
n = 0;
p = temp_0;
while ((p >>= 1) >= 16) {
ixheaace_write_bits(pstr_bitstream, 1, 1);
n++;
}
ixheaace_write_bits(pstr_bitstream, 0, 1);
ixheaace_write_bits(pstr_bitstream, temp_0 - (1 << (n + 4)), (UWORD8)(n + 4));
}
if (temp_1 >= 16) {
WORD32 n, p;
n = 0;
p = temp_1;
while ((p >>= 1) >= 16) {
ixheaace_write_bits(pstr_bitstream, 1, 1);
n++;
}
ixheaace_write_bits(pstr_bitstream, 0, 1);
ixheaace_write_bits(pstr_bitstream, temp_1 - (1 << (n + 4)), (UWORD8)(n + 4));
}
}
break;
default:
break;
}
}
WORD32 ia_enhaacplus_enc_code_scale_factor_delta(WORD32 delta,
ixheaace_bit_buf_handle h_bitstream,
ixheaace_huffman_tables *pstr_huffman_tbl) {
WORD32 code_word, code_length;
if (abs32(delta) > CODE_BCK_SCF_LAV) {
return (1);
}
code_word = pstr_huffman_tbl->huff_ctabscf[delta + CODE_BCK_SCF_LAV];
code_length = pstr_huffman_tbl->huff_ltabscf[delta + CODE_BCK_SCF_LAV];
ixheaace_write_bits(h_bitstream, code_word, (UWORD8)code_length);
return (0);
}

View file

@ -0,0 +1,103 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#define INVALID_BITCOUNT_LC (SHRT_MAX)
#define INVALID_BITCOUNT_LD (SHRT_MAX / 4)
#define abs32(a) (a > 0 ? a : -a)
#define HI_LTAB(a) (a >> 8)
#define LO_LTAB(a) (a & 0xff)
#define HI_EXPLTAB(a) (a >> 16)
#define LO_EXPLTAB(a) (a & 0xffff)
#define EXPAND(a) ((((WORD32)(a & 0xff00)) << 8) | (WORD32)(a & 0xff))
/* code book number table */
enum codeBookNo {
CODE_BCK_ZERO_NO = 0,
CODE_BCK_1_NO = 1,
CODE_BCK_2_NO = 2,
CODE_BCK_3_NO = 3,
CODE_BCK_4_NO = 4,
CODE_BCK_5_NO = 5,
CODE_BCK_6_NO = 6,
CODE_BCK_7_NO = 7,
CODE_BCK_8_NO = 8,
CODE_BCK_9_NO = 9,
CODE_BCK_10_NO = 10,
CODE_BCK_ESC_NO = 11,
CODE_BCK_RES_NO = 12,
CODE_BCK_PNS_NO = 13
};
/* code book index table */
enum codeBookNdx {
CODE_BCK_ZERO_NDX,
CODE_BCK_1_NDX,
CODE_BCK_2_NDX,
CODE_BCK_3_NDX,
CODE_BCK_4_NDX,
CODE_BCK_5_NDX,
CODE_BCK_6_NDX,
CODE_BCK_7_NDX,
CODE_BCK_8_NDX,
CODE_BCK_9_NDX,
CODE_BCK_10_NDX,
CODE_BCK_ESC_NDX,
CODE_BCK_RES_NDX,
CODE_BCK_PNS_NDX,
NUMBER_OF_CODE_BOOKS
};
/* code book lav table */
enum codeBookLav {
CODE_BCK_ZERO_LAV = 0,
CODE_BCK_1_LAV = 1,
CODE_BCK_2_LAV = 1,
CODE_BCK_3_LAV = 2,
CODE_BCK_4_LAV = 2,
CODE_BCK_5_LAV = 4,
CODE_BCK_6_LAV = 4,
CODE_BCK_7_LAV = 7,
CODE_BCK_8_LAV = 7,
CODE_BCK_9_LAV = 12,
CODE_BCK_10_LAV = 12,
CODE_BCK_ESC_LAV = 16,
CODE_BCK_SCF_LAV = 60,
CODE_BCK_PNS_LAV = 60
};
VOID ia_enhaacplus_enc_bitcount(const WORD16 *ptr_values, const WORD32 width, WORD32 max_val,
WORD32 *bit_cnt, ixheaace_huffman_tables *pstr_huffman_tbl,
WORD32 aot);
VOID ia_enhaacplus_enc_code_values(WORD16 *ptr_values, WORD32 width, WORD32 code_book,
ixheaace_bit_buf_handle pstr_bitstream,
ixheaace_huffman_tables *pstr_huffman_tbl);
WORD32 ia_enhaacplus_enc_code_scale_factor_delta(WORD32 scalefactor,
ixheaace_bit_buf_handle h_bitstream,
ixheaace_huffman_tables *pstr_huffman_tbl);
VOID ia_enhaacplus_enc_count1_2_3_4_5_6_7_8_9_10_11(const WORD16 *values, const WORD32 width,
WORD32 *bitcnt,
ixheaace_huffman_tables *pstr_huffman_tbl,
WORD32 invalid_bitcnt);

View file

@ -0,0 +1,262 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include "ixheaac_type_def.h"
#include "ixheaace_aac_constants.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaace_enc_main.h"
#include "ixheaace_block_switch.h"
#include <string.h>
static FLOAT32 iaace_fmult(FLOAT32 a, FLOAT32 b) { return (a * b); }
static FLOAT32 iaace_fadd(FLOAT32 a, FLOAT32 b) { return (a + b); }
VOID iaace_init_block_switching(ixheaace_block_switch_control *pstr_blk_switch_ctrl,
const WORD32 bit_rate, const WORD32 num_chans) {
if ((num_chans == 1 && bit_rate > BLK_SWITCH_HIGH_BR_MONO) ||
(num_chans > 1 && bit_rate / num_chans > BLK_SWITCH_HIGH_BR_STEREO)) {
pstr_blk_switch_ctrl->inv_attack_ratio = INV_ATTACK_RATIO_HIGH_BR;
} else {
pstr_blk_switch_ctrl->inv_attack_ratio = INV_ATTACK_RATIO_LOW_BR;
}
memset(pstr_blk_switch_ctrl->iir_states, 0,
BLK_SWITCH_FILT_LEN * sizeof(pstr_blk_switch_ctrl->iir_states[0]));
/* Clear Filtered Window Energies */
memset(pstr_blk_switch_ctrl->win_energy_filt, 0,
BLK_SWITCH_WIN * sizeof(pstr_blk_switch_ctrl->win_energy_filt[0][0]));
memset(pstr_blk_switch_ctrl->win_energy, 0,
BLK_SWITCH_WIN * sizeof(pstr_blk_switch_ctrl->win_energy[0][0]));
pstr_blk_switch_ctrl->acc_win_energy = 0;
pstr_blk_switch_ctrl->win_seq = LONG_WINDOW;
pstr_blk_switch_ctrl->nxt_win_seq = LONG_WINDOW;
pstr_blk_switch_ctrl->attack = 0;
pstr_blk_switch_ctrl->lastattack = 0;
pstr_blk_switch_ctrl->attack_idx = 0;
pstr_blk_switch_ctrl->last_attack_idx = 0;
}
static FLOAT32 iaace_search_max_with_idx(const FLOAT32 *ptr_in, WORD32 *ptr_index, WORD32 len) {
FLOAT32 max = 0;
WORD32 i = 0, idx = 0;
do {
if (ptr_in[i + 1] > max) {
max = ptr_in[i + 1];
idx = i;
}
i++;
} while (i < len);
*ptr_index = idx;
return max;
}
static FLOAT32 iaace_blk_switch_iir_filt(const FLOAT32 input, const FLOAT32 *ptr_iir_coeff,
FLOAT32 *ptr_iir_states) {
FLOAT32 accu_1, accu_2;
FLOAT32 out;
accu_1 = ptr_iir_coeff[1] * (input - ptr_iir_states[0]);
accu_2 = ptr_iir_coeff[0] * ptr_iir_states[1];
out = accu_1 - accu_2;
ptr_iir_states[0] = input;
ptr_iir_states[1] = out;
return out;
}
static VOID iaace_calc_window_energy(ixheaace_block_switch_control *pstr_blk_switch_ctrl,
const FLOAT32 *ptr_time_signal, WORD32 ch_increment,
WORD32 win_len) {
WORD32 i, w;
FLOAT32 acc_nrg_unfilt, acc_nrg_filt;
FLOAT32 tmp_nrg_unfilt, tmp_nrg_filt;
for (w = 0; w < BLK_SWITCH_WIN; w++) {
acc_nrg_unfilt = 0.0f;
acc_nrg_filt = 0.0f;
for (i = 0; i < win_len; i++) {
tmp_nrg_unfilt = ptr_time_signal[(win_len * w + i) * ch_increment];
tmp_nrg_filt = iaace_blk_switch_iir_filt(tmp_nrg_unfilt, iaace_iir_hipass_coeffs,
pstr_blk_switch_ctrl->iir_states);
acc_nrg_unfilt += (tmp_nrg_unfilt * tmp_nrg_unfilt);
acc_nrg_filt += (tmp_nrg_filt * tmp_nrg_filt);
}
pstr_blk_switch_ctrl->win_energy[1][w] = acc_nrg_unfilt;
pstr_blk_switch_ctrl->win_energy_filt[1][w] = acc_nrg_filt;
}
}
VOID iaace_block_switching(ixheaace_block_switch_control *pstr_blk_switch_ctrl,
const FLOAT32 *ptr_time_signal, WORD32 frame_length,
WORD32 num_chans) {
WORD32 win_idx;
FLOAT32 tmp_nrg_1, tmp_nrg_2;
FLOAT32 prev_win_nrg, max_nrg;
memset(pstr_blk_switch_ctrl->group_len, 0,
TRANS_FAC * sizeof(pstr_blk_switch_ctrl->group_len[0]));
pstr_blk_switch_ctrl->max_win_energy =
iaace_search_max_with_idx(&pstr_blk_switch_ctrl->win_energy[0][BLK_SWITCH_WIN - 1],
&pstr_blk_switch_ctrl->attack_idx, BLK_SWITCH_WIN);
pstr_blk_switch_ctrl->attack_idx = pstr_blk_switch_ctrl->last_attack_idx;
pstr_blk_switch_ctrl->total_groups_cnt = MAXIMUM_NO_OF_GROUPS;
memcpy(pstr_blk_switch_ctrl->group_len,
iaace_suggested_grouping_table[pstr_blk_switch_ctrl->attack_idx],
MAXIMUM_NO_OF_GROUPS * sizeof(pstr_blk_switch_ctrl->group_len[0]));
memcpy(pstr_blk_switch_ctrl->win_energy[0], pstr_blk_switch_ctrl->win_energy[1],
BLK_SWITCH_WIN * sizeof(pstr_blk_switch_ctrl->win_energy[0][0]));
memcpy(pstr_blk_switch_ctrl->win_energy_filt[0], pstr_blk_switch_ctrl->win_energy_filt[1],
BLK_SWITCH_WIN * sizeof(pstr_blk_switch_ctrl->win_energy_filt[0][0]));
iaace_calc_window_energy(
pstr_blk_switch_ctrl, ptr_time_signal, num_chans,
(frame_length == FRAME_LEN_960 ? FRAME_LEN_SHORT_120 : FRAME_LEN_SHORT_128));
pstr_blk_switch_ctrl->attack = FALSE;
max_nrg = 0.0f;
prev_win_nrg = pstr_blk_switch_ctrl->win_energy_filt[0][BLK_SWITCH_WIN - 1];
for (win_idx = 0; win_idx < BLK_SWITCH_WIN; win_idx++) {
tmp_nrg_1 = iaace_fmult(ONE_MINUS_ACC_WINDOW_NRG_FAC, pstr_blk_switch_ctrl->acc_win_energy);
tmp_nrg_2 = iaace_fmult(ACC_WINDOW_NRG_FAC, prev_win_nrg);
pstr_blk_switch_ctrl->acc_win_energy = iaace_fadd(tmp_nrg_1, tmp_nrg_2);
tmp_nrg_1 = iaace_fmult(pstr_blk_switch_ctrl->win_energy_filt[1][win_idx],
pstr_blk_switch_ctrl->inv_attack_ratio);
if (tmp_nrg_1 > pstr_blk_switch_ctrl->acc_win_energy) {
pstr_blk_switch_ctrl->attack = TRUE;
pstr_blk_switch_ctrl->last_attack_idx = win_idx;
}
prev_win_nrg = pstr_blk_switch_ctrl->win_energy_filt[1][win_idx];
max_nrg = MAX(prev_win_nrg, max_nrg);
}
if (max_nrg < MIN_ATTACK_NRG) {
pstr_blk_switch_ctrl->attack = FALSE;
}
if ((!pstr_blk_switch_ctrl->attack) && (pstr_blk_switch_ctrl->lastattack)) {
if (pstr_blk_switch_ctrl->attack_idx == (TRANS_FAC - 1)) {
pstr_blk_switch_ctrl->attack = TRUE;
}
pstr_blk_switch_ctrl->lastattack = FALSE;
} else {
pstr_blk_switch_ctrl->lastattack = pstr_blk_switch_ctrl->attack;
}
pstr_blk_switch_ctrl->win_seq = pstr_blk_switch_ctrl->nxt_win_seq;
pstr_blk_switch_ctrl->nxt_win_seq =
(pstr_blk_switch_ctrl->attack == 1) ? SHORT_WINDOW : LONG_WINDOW;
if (pstr_blk_switch_ctrl->nxt_win_seq == SHORT_WINDOW) {
if (pstr_blk_switch_ctrl->win_seq == LONG_WINDOW) {
pstr_blk_switch_ctrl->win_seq = START_WINDOW;
} else if (pstr_blk_switch_ctrl->win_seq == STOP_WINDOW) {
pstr_blk_switch_ctrl->win_seq = SHORT_WINDOW;
pstr_blk_switch_ctrl->total_groups_cnt = 3;
pstr_blk_switch_ctrl->group_len[0] = 3;
pstr_blk_switch_ctrl->group_len[1] = 3;
pstr_blk_switch_ctrl->group_len[2] = 2;
}
}
if (pstr_blk_switch_ctrl->nxt_win_seq == LONG_WINDOW &&
pstr_blk_switch_ctrl->win_seq == SHORT_WINDOW) {
pstr_blk_switch_ctrl->nxt_win_seq = STOP_WINDOW;
}
}
VOID iaace_sync_block_switching(ixheaace_block_switch_control *pstr_blk_switch_left_ctrl,
ixheaace_block_switch_control *pstr_blk_switch_right_ctrl,
const WORD32 num_channels) {
WORD32 i;
WORD32 patch_type = LONG_WINDOW;
if (num_channels == 1) {
if (pstr_blk_switch_left_ctrl->win_seq != SHORT_WINDOW) {
pstr_blk_switch_left_ctrl->total_groups_cnt = 1;
pstr_blk_switch_left_ctrl->group_len[0] = 1;
for (i = 1; i < TRANS_FAC; i++) {
pstr_blk_switch_left_ctrl->group_len[i] = 0;
}
}
} else {
/* Stereo */
patch_type = iaace_synchronized_block_types[patch_type][pstr_blk_switch_left_ctrl->win_seq];
patch_type = iaace_synchronized_block_types[patch_type][pstr_blk_switch_right_ctrl->win_seq];
pstr_blk_switch_left_ctrl->win_seq = patch_type;
pstr_blk_switch_right_ctrl->win_seq = patch_type;
if (patch_type != SHORT_WINDOW) { /* tns_data_long Blocks */
pstr_blk_switch_left_ctrl->total_groups_cnt = 1;
pstr_blk_switch_right_ctrl->total_groups_cnt = 1;
pstr_blk_switch_left_ctrl->group_len[0] = 1;
pstr_blk_switch_right_ctrl->group_len[0] = 1;
for (i = 1; i < TRANS_FAC; i++) {
pstr_blk_switch_left_ctrl->group_len[i] = 0;
pstr_blk_switch_right_ctrl->group_len[i] = 0;
}
} else { /* tns_data_short Blocks */
if (pstr_blk_switch_left_ctrl->max_win_energy >
pstr_blk_switch_right_ctrl->max_win_energy) {
pstr_blk_switch_right_ctrl->total_groups_cnt =
pstr_blk_switch_left_ctrl->total_groups_cnt;
for (i = 0; i < TRANS_FAC; i++) {
pstr_blk_switch_right_ctrl->group_len[i] = pstr_blk_switch_left_ctrl->group_len[i];
}
} else {
pstr_blk_switch_left_ctrl->total_groups_cnt =
pstr_blk_switch_right_ctrl->total_groups_cnt;
for (i = 0; i < TRANS_FAC; i++) {
pstr_blk_switch_left_ctrl->group_len[i] = pstr_blk_switch_right_ctrl->group_len[i];
}
}
}
}
}

View file

@ -0,0 +1,85 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#define BLOCK_SWITCH_WINDOWS TRANS_FAC /* number of windows for energy calculation */
#define BLOCK_SWITCH_WINDOW_LEN \
FRAME_LEN_SHORT_128 /* minimal granularity of energy calculation */
#define BLK_SWITCH_WIN 8
#define BLK_SWITCH_FILT_LEN 2
/* Block types */
#define LONG_WINDOW 0
#define START_WINDOW 1
#define SHORT_WINDOW 2
#define STOP_WINDOW 3
/* Window shapes */
#define SINE_WINDOW 0
#define KBD_WINDOW 1
#define MAXIMUM_NO_OF_GROUPS 4
#define ACC_WINDOW_NRG_FAC 0.3f
#define ONE_MINUS_ACC_WINDOW_NRG_FAC 0.7f
#define INV_ATTACK_RATIO_HIGH_BR 0.1f
#define INV_ATTACK_RATIO_LOW_BR 0.056f
#define MIN_ATTACK_NRG (1000000)
#define BLK_SWITCH_HIGH_BR_MONO (24000)
#define BLK_SWITCH_HIGH_BR_STEREO (16000)
typedef struct {
FLOAT32 inv_attack_ratio;
WORD32 win_seq;
WORD32 nxt_win_seq;
WORD32 attack;
WORD32 lastattack;
WORD32 attack_idx;
WORD32 last_attack_idx;
WORD32 total_groups_cnt;
WORD32 group_len[TRANS_FAC];
FLOAT32 win_energy[2][BLK_SWITCH_WIN];
FLOAT32 win_energy_filt[2][BLK_SWITCH_WIN];
FLOAT32 iir_states[BLK_SWITCH_FILT_LEN];
FLOAT32 max_win_energy;
FLOAT32 acc_win_energy;
WORD32 win_seq_ld; /* these are used to save window decision for LD. */
WORD32 next_win_seq_ld; /* nxt_win_seq and win_seq are always set to
LONG_WINDOW */
} ixheaace_block_switch_control;
VOID iaace_init_block_switching(ixheaace_block_switch_control *pstr_blk_switch_ctrl,
const WORD32 bit_rate, const WORD32 num_chans);
VOID iaace_block_switching(ixheaace_block_switch_control *pstr_blk_switch_ctrl,
const FLOAT32 *ptr_time_signal, WORD32 frame_length, WORD32 num_chans);
VOID iaace_sync_block_switching(ixheaace_block_switch_control *pstr_blk_switch_left_ctrl,
ixheaace_block_switch_control *pstr_blk_switch_right_ctrl,
const WORD32 num_channels);

View file

@ -0,0 +1,89 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include "ixheaac_type_def.h"
#include "ixheaace_aac_constants.h"
#include "ixheaace_calc_ms_band_energy.h"
VOID ia_enhaacplus_enc_calc_band_energy(const FLOAT32 *ptr_spec_coeffs,
const WORD32 *ptr_band_offset, const WORD32 num_bands,
FLOAT32 *ptr_band_energy, WORD32 sfb_count,
FLOAT32 *ptr_band_energy_sum) {
WORD32 i, j;
j = 0;
memset(ptr_band_energy, 0, sfb_count * sizeof(*ptr_band_energy));
*ptr_band_energy_sum = 0;
for (i = 0; i < num_bands; i++) {
while (j < ptr_band_offset[i + 1]) {
ptr_band_energy[i] += (FLOAT32)((FLOAT64)ptr_spec_coeffs[j] * ptr_spec_coeffs[j]);
j++;
}
*ptr_band_energy_sum = *ptr_band_energy_sum + ptr_band_energy[i];
}
}
VOID ia_enhaacplus_enc_calc_band_energy_ms(
const FLOAT32 *ptr_mdct_spectrum_left_fix, const FLOAT32 *ptr_mdct_spectrum_right_fix,
const WORD32 *ptr_sfb_offset, const WORD32 num_sfb_active, const WORD32 num_sfb_total,
FLOAT32 *ptr_band_nrg_mid, FLOAT32 *ptr_band_nrg_mid_sum, FLOAT32 *ptr_band_nrg_side,
FLOAT32 *ptr_band_nrg_side_sum) {
WORD32 i;
const FLOAT32 *ptr_spec_left = ptr_mdct_spectrum_left_fix;
const FLOAT32 *ptr_spec_right = ptr_mdct_spectrum_right_fix;
*ptr_band_nrg_mid_sum = 0;
*ptr_band_nrg_side_sum = 0;
for (i = 0; i < num_sfb_active; i++) {
WORD16 offset = (WORD16)(ptr_sfb_offset[i + 1] - ptr_sfb_offset[i]);
FLOAT32 band_nrgy_mid = 0, band_nrg_side = 0;
ptr_band_nrg_mid[i] = 0;
ptr_band_nrg_side[i] = 0;
FLOAT32 spec_mid, spec_side;
FLOAT32 temp_mid, temp_side;
while (offset--) {
spec_mid = (*ptr_spec_left + *ptr_spec_right) * 0.5f;
spec_side = (*ptr_spec_left++ - *ptr_spec_right++) * 0.5f;
temp_mid = (spec_mid * spec_mid);
temp_side = (spec_side * spec_side);
band_nrgy_mid = (band_nrgy_mid + temp_mid);
band_nrg_side = (band_nrg_side + temp_side);
}
ptr_band_nrg_mid[i] = band_nrgy_mid;
ptr_band_nrg_side[i] = band_nrg_side;
*ptr_band_nrg_mid_sum += ptr_band_nrg_mid[i];
*ptr_band_nrg_side_sum += ptr_band_nrg_side[i];
}
memset(&ptr_band_nrg_mid[num_sfb_active], 0,
(num_sfb_total - num_sfb_active) * sizeof(*ptr_band_nrg_mid));
memset(&ptr_band_nrg_side[num_sfb_active], 0,
(num_sfb_total - num_sfb_active) * sizeof(*ptr_band_nrg_side));
}

View file

@ -0,0 +1,32 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
VOID ia_enhaacplus_enc_calc_band_energy(const FLOAT32 *ptr_spec_coeffs,
const WORD32 *ptr_band_offset, const WORD32 num_bands,
FLOAT32 *ptr_band_energy, WORD32 sfb_count,
FLOAT32 *ptr_band_energy_sum);
VOID ia_enhaacplus_enc_calc_band_energy_ms(
const FLOAT32 *ptr_mdct_spectrum_left_fix, const FLOAT32 *ptr_mdct_spectrum_right_fix,
const WORD32 *ptr_sfb_offset, const WORD32 num_sfb_active, const WORD32 num_sfb_total,
FLOAT32 *ptr_band_nrg_mid, FLOAT32 *ptr_band_nrg_mid_sum, FLOAT32 *ptr_band_nrg_side,
FLOAT32 *ptr_band_nrg_side_sum);

View file

@ -0,0 +1,206 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include <string.h>
#include "ixheaac_error_standards.h"
#include "ixheaace_error_codes.h"
#include "ixheaace_aac_constants.h"
#include "ixheaace_adjust_threshold_data.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaace_enc_main.h"
#include "ixheaace_dynamic_bits.h"
#include "ixheaace_qc_data.h"
#include "ixheaace_channel_map.h"
#include "ixheaace_block_switch.h"
#include "ixheaace_psy_data.h"
#include "ixheaace_interface.h"
#include "ixheaace_write_bitstream.h"
static IA_ERRORCODE ia_enhaacplus_enc_init_element(ixheaace_element_info *pstr_element_info,
ixheaace_element_type el_type,
WORD32 element_instance_tag) {
IA_ERRORCODE error = IA_NO_ERROR;
pstr_element_info->el_type = el_type;
switch (pstr_element_info->el_type) {
case ID_SCE:
case ID_CCE:
pstr_element_info->n_channels_in_el = NUM_CHANS_MONO;
pstr_element_info->channel_index[0] = 0;
pstr_element_info->instance_tag = element_instance_tag;
break;
case ID_LFE:
pstr_element_info->n_channels_in_el = NUM_CHANS_MONO;
pstr_element_info->channel_index[0] = 0;
pstr_element_info->instance_tag = element_instance_tag;
break;
case ID_CPE:
pstr_element_info->n_channels_in_el = NUM_CHANS_STEREO;
pstr_element_info->channel_index[0] = 0;
pstr_element_info->channel_index[1] = 1;
pstr_element_info->instance_tag = element_instance_tag;
break;
default:
return IA_EXHEAACE_INIT_FATAL_INVALID_ELEMENT_TYPE;
}
return error;
}
IA_ERRORCODE ia_enhaacplus_enc_init_element_info(WORD32 num_channels,
ixheaace_element_info *pstr_element_info,
WORD32 ele_type, WORD32 element_instance_tag) {
IA_ERRORCODE error = IA_NO_ERROR;
if (ele_type != ID_LFE) {
switch (num_channels) {
case NUM_CHANS_MONO:
if (ele_type == -1) {
error = ia_enhaacplus_enc_init_element(pstr_element_info, ID_SCE, element_instance_tag);
} else {
error =
ia_enhaacplus_enc_init_element(pstr_element_info, ele_type, element_instance_tag);
}
break;
case NUM_CHANS_STEREO:
error = ia_enhaacplus_enc_init_element(pstr_element_info, ID_CPE, element_instance_tag);
break;
default:
return IA_EXHEAACE_INIT_FATAL_NUM_CHANNELS_NOT_SUPPORTED;
}
} else {
error = ia_enhaacplus_enc_init_element(pstr_element_info, ID_LFE, element_instance_tag);
}
return error;
}
IA_ERRORCODE ia_enhaacplus_enc_init_element_bits(ixheaace_element_bits *element_bits,
ixheaace_element_info pstr_element_info,
WORD32 bitrate_tot, WORD32 average_bits_tot,
WORD32 aot, WORD32 static_bits_tot,
WORD32 bit_res, FLAG flag_framelength_small) {
IA_ERRORCODE error = IA_NO_ERROR;
switch (pstr_element_info.n_channels_in_el) {
case NUM_CHANS_MONO:
element_bits->ch_bitrate = bitrate_tot;
element_bits->average_bits = (average_bits_tot - static_bits_tot);
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
if (flag_framelength_small) {
element_bits->max_bits = MAXIMUM_CHANNEL_BITS_960;
element_bits->max_bit_res_bits = MAXIMUM_CHANNEL_BITS_960 - average_bits_tot;
} else {
element_bits->max_bits = MAXIMUM_CHANNEL_BITS_1024;
element_bits->max_bit_res_bits = MAXIMUM_CHANNEL_BITS_1024 - average_bits_tot;
}
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
if (bit_res) {
element_bits->max_bits = bit_res;
element_bits->max_bit_res_bits = bit_res - average_bits_tot;
} else {
element_bits->max_bits = average_bits_tot;
element_bits->max_bit_res_bits = 0;
}
break;
}
element_bits->max_bit_res_bits -= (element_bits[0].max_bit_res_bits % 8);
element_bits->bit_res_level = element_bits[0].max_bit_res_bits;
element_bits->relative_bits = 1;
break;
case NUM_CHANS_STEREO:
element_bits->ch_bitrate = bitrate_tot >> 1;
element_bits->average_bits = (average_bits_tot - static_bits_tot);
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
if (flag_framelength_small) {
element_bits->max_bits = NUM_CHANS_STEREO * MAXIMUM_CHANNEL_BITS_960;
element_bits->max_bit_res_bits =
NUM_CHANS_STEREO * MAXIMUM_CHANNEL_BITS_960 - average_bits_tot;
} else {
element_bits->max_bits = NUM_CHANS_STEREO * MAXIMUM_CHANNEL_BITS_1024;
element_bits->max_bit_res_bits =
NUM_CHANS_STEREO * MAXIMUM_CHANNEL_BITS_1024 - average_bits_tot;
}
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
if (bit_res) {
element_bits->max_bits = bit_res;
element_bits->max_bit_res_bits = bit_res - average_bits_tot;
} else {
element_bits->max_bits = average_bits_tot;
element_bits->max_bit_res_bits = 0;
}
break;
}
element_bits->max_bit_res_bits -= (element_bits[0].max_bit_res_bits % 8);
element_bits->bit_res_level = element_bits[0].max_bit_res_bits;
element_bits->relative_bits = 1;
break;
default:
return IA_EXHEAACE_INIT_FATAL_INVALID_NUM_CHANNELS_IN_ELE;
}
/* Bits carried over from previous frame */
element_bits->carry_bits = 0;
return error;
}

View file

@ -0,0 +1,29 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
IA_ERRORCODE ia_enhaacplus_enc_init_element_info(WORD32 num_channels,
ixheaace_element_info *pstr_element_info,
WORD32 ele_type, WORD32 element_instance_tag);
IA_ERRORCODE ia_enhaacplus_enc_init_element_bits(ixheaace_element_bits *element_bits,
ixheaace_element_info pstr_element_info,
WORD32 bitrate_tot, WORD32 average_bits_tot,
WORD32 aot, WORD32 static_bits_tot,
WORD32 bit_res, FLAG flag_framelength_small);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,55 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
typedef struct {
const WORD32 sqrt_tab[513];
const WORD32 sine_array[3];
const WORD32 cosine_array[3];
const FLOAT32 sin_arr[3];
const FLOAT32 cos_arr[3];
const WORD32 power_of_2_table_pos[256];
const WORD32 power_of_2_table_neg[256];
const WORD32 log_natural_Q25[128];
const WORD32 sfb_width_pow_point_25_Q28[25];
const short ia_enhaacplus_enc_w1024[768];
} ixheaace_common_tables;
extern
const ixheaace_common_tables ia_enhaacplus_enc_common_tab;
typedef struct {
ixheaace_common_tables *pstr_common_tab;
} ixheaace_comm_tables;
extern const FLOAT64 ia_enhaacplus_enc_twiddle_table_3pr[1155];
extern const FLOAT64 ia_enhaacplus_enc_twiddle_table_3pi[1155];
extern const FLOAT64 ia_enhaacplus_enc_twiddle_table_fft_32x32[514];
extern const WORD32 ia_enhaacplus_enc_fft240_table1[240];
extern const WORD32 ia_enhaacplus_enc_fft240_table2[240];
extern const UWORD32 ia_sampl_freq_table[16];
extern const UWORD32 ia_usac_sampl_freq_table[32];

View file

@ -0,0 +1,45 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#ifndef min
#define min(a, b) (a < b ? a : b)
#endif
#ifndef max
#define max(a, b) (a > b ? a : b)
#endif
#define ia_add_flt(a, b) ((a) + (b))
#define ia_sub_flt(a, b) ((a) - (b))
#define ia_mac_flt(x, a, b) ((x) + (a) * (b))
#define ia_msu_flt(x, a, b) ((x) - (a) * (b))
#define ia_mul_flt(a, b) ((a) * (b))
#define ia_negate_flt(a) (-a)
#define C70 (-0.1666667014f) //(cos(u) + cos(2 * u) + cos(3 * u)) / 3;
#define C71 (0.7901564837f) //(2 * cos(u) - cos(2 * u) - cos(3 * u)) / 3;
#define C72 (0.0558542535f) //(cos(u) - 2 * cos(2 * u) + cos(3 * u)) / 3;
#define C73 (0.7343022227f) //(cos(u) + cos(2 * u) - 2 * cos(3 * u)) / 3;
#define C74 (-0.4409585893f) //(sin(u) + sin(2 * u) - sin(3 * u)) / 3;
#define C75 (-0.3408728838f) //(2 * sin(u) - sin(2 * u) + sin(3 * u)) / 3;
#define C76 (0.5339693427f) //(sin(u) - 2 * sin(2 * u) - sin(3 * u)) / 3;
#define C77 (-0.8748422265f) //(sin(u) + sin(2 * u) + 2 * sin(3 * u)) / 3;

50
encoder/ixheaace_config.h Normal file
View file

@ -0,0 +1,50 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
typedef enum {
IAAC_ELDEXT_TERM = 0x0, /* Termination tag */
IAAC_ELDEXT_SAOC = 0x1, /* SAOC config */
IAAC_ELDEXT_LDSAC = 0x2, /* LD MPEG Surround config */
IAAC_ELDEXT_DOWNSCALEINFO = 0x3 /* ELD sample rate adaptation */
/* reserved */
} IAAC_ASC_ELD_EXT_TYPE;
typedef struct {
// GA specific parameters
WORD32 depends_on_core_coder;
WORD32 core_coder_delay;
WORD32 extension_flag;
// common to LD and ELD
WORD32 frame_length_flag;
WORD32 aac_sec_data_resilience_flag;
WORD32 aac_sf_data_resilience_flag;
WORD32 aac_spec_data_resilience_flag;
// ELD specific parameters
WORD32 ld_sbr_present_flag;
WORD32 ld_sbr_sample_rate;
WORD32 ld_sbr_crc_flag;
WORD32 eld_ext_type[16];
WORD32 eld_ext_len[16];
ixheaace_pstr_sbr_hdr_data sbr_config;
WORD32 num_sac_cfg_bits;
UWORD8 sac_cfg_data[1024];
} ia_aace_config_struct;

View file

@ -0,0 +1,58 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
/* Input Config Params default values */
#define BITRESERVOIR_SIZE_CONFIG_PARAM_DEFAULT_VALUE_LD (384)
#define BITRESERVOIR_SIZE_CONFIG_PARAM_DEFAULT_VALUE_LC (768)
#define NUM_CHANNELS_CONFIG_PARAM_DEFAULT_VALUE (2)
#define AAC_SAMP_FREQ_CONFIG_PARAM_DEFAULT_VALUE (44100)
#define NUM_MEMTABS_CONFIG_PARAM_DEFAULT_VALUE (10)
#define AAC_CLASSIC_CONFIG_PARAM_DEFAULT_VALUE (0)
#define USE_PS_CONFIG_PARAM_DEFAULT_VALUE (0)
#define CHMODE_NUM_CHANNELS_CONFIG_PARAM_DEFAULT_VALUE (2)
#define CHMODE_CONFIG_PARAM_DEFAULT_VALUE (1)
#define ADTS_FLAG_CONFIG_PARAM_DEFAULT_VALUE (0)
#define ADIF_FLAG_CONFIG_PARAM_DEFAULT_VALUE (0)
#define CHANNEL_MASK_CONFIG_PARAM_DEFAULT_VALUE (0)
#define NUM_COUPLING_CHANNEL_CONFIG_PARAM_DEFAULT_VALUE (0)
#define ELEMENT_TYPE_CONFIG_PARAM_DEFAULT_VALUE (-1)
#define ELEMENT_SLOT_CONFIG_PARAM_DEFAULT_VALUE (0)
#define NUM_BS_ELEMENTS_CONFIG_PARAM_DEFAULT_VALUE (1)
#define ELEMENT_INSTANCE_TAG_CONFIG_PARAM_DEFAULT_VALUE (0)
#define AAC_CFG_CALC_CRC_CONFIG_PARAM_DEFAULT_VALUE (0)
#define AAC_CFG_FULL_BW_CONFIG_PARAM_DEFAULT_VALUE (0)
#define ELDSBR_FOUND_CONFIG_PARAM_DEFAULT_VALUE (0)
#define USE_MPS_PARAM_DEFAULT_VALUE (0)
#define USE_MPS_TREE_CONFIG_PARAM_DEFAULT_VALUE (0)
#define USE_FRAMELENGTH_SMALL_PARAM_DEFAULT_VALUE (0)
#define AAC_BITRATE_DEFAULT_VALUE (48000)
#define USAC_SAMP_FREQ_CONFIG_PARAM_DEFAULT_VALUE (48000)
#define USAC_SBR_PVC_DEFAULT_VALUE (0)
#define USAC_SBR_INTER_TES_DEFAULT_VALUE (0)
#define USAC_SBR_HARMONIC_DEFAULT_VALUE (0)
#define USAC_FILL_ELEMENT_DEFAULT_VALUE (1)
#define USAC_DRC_DEFAULT_VALUE (0)
#define USAC_COMPLEX_PREDECTION_DEFAULT_VALUE (0)
#define USAC_TNS_DEFAULT_VALUE (0)
#define USAC_FLAG_NOISE_FILLING_DEFAULT_VALUE (0)
#define USAC_BITRATE_DEFAULT_VALUE (32000)

View file

@ -0,0 +1,53 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
/*****************************************************************************/
/* constant macros */
/*****************************************************************************/
#define Q1 2
#define Q2 4
#define Q3 8
#define Q4 16
#define Q6 64
#define Q25 33554432
#define Q28 268435456
#define Q29 536870912
#define Q30 1073741824
#define Q31 2147483647
#define Q32 4294967296
#define Q35 34359738368
#define Q39 549755813887
#define Q40 Q39
#define MAX_32 (WORD32)0x7fffffffL
#define MIN_32 (WORD32)0x80000000L
#define MAX_16 (WORD16)0x7fff
/*****************************************************************************/
/* function macros */
/*****************************************************************************/
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif

View file

@ -0,0 +1,32 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#define LIB_APIVERSION_MAJOR 1
#define LIB_APIVERSION_MINOR 10
#define LIB_APIVERSION IA_MAKE_VERSION_STR(LIB_APIVERSION_MAJOR, LIB_APIVERSION_MINOR)
/* Index to the different Memory Tables */
#define IA_ENHAACPLUSENC_PERSIST_IDX (0)
#define IA_ENHAACPLUSENC_SCRATCH_IDX (1)
#define IA_ENHAACPLUSENC_INPUT_IDX (2)
#define IA_ENHAACPLUSENC_OUTPUT_IDX (3)

View file

@ -0,0 +1,594 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <limits.h>
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
#include "ixheaac_error_standards.h"
#include "ixheaace_error_codes.h"
#include <stdlib.h>
#include <string.h>
#include "ixheaac_basic_ops32.h"
#include "ixheaac_basic_ops16.h"
#include "ixheaac_basic_ops40.h"
#include "ixheaac_basic_ops.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaace_enc_main.h"
#include "ixheaace_bits_count.h"
#include "ixheaace_dynamic_bits.h"
#include "ixheaace_common_utils.h"
static WORD32 ia_enhaacplus_enc_calc_side_info_bits(WORD32 sfb_cnt, WORD32 block_type) {
WORD32 seg_len_bits = (block_type == SHORT_WINDOW ? 3 : 5);
WORD32 escape_val = (block_type == SHORT_WINDOW ? 7 : 31);
WORD32 side_info_bits, tmp;
side_info_bits = CODE_BCK_BITS;
tmp = sfb_cnt;
while (tmp >= 0) {
side_info_bits += seg_len_bits;
tmp -= escape_val;
}
return (side_info_bits);
}
static VOID ia_enhaacplus_enc_build_bit_look_up(
const WORD16 *ptr_quant_spec, const WORD32 max_sfb, const WORD32 *ptr_sfb_offset,
const UWORD16 *sfb_max,
WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1],
ixheaace_section_info *pstr_section_info, ixheaace_huffman_tables *pstr_huffman_tbl,
WORD32 aot) {
WORD8 i;
for (i = 0; i < max_sfb; i++) {
WORD32 sfb_width, max_val;
pstr_section_info[i].sfb_cnt = 1;
pstr_section_info[i].sfb_start = i;
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
pstr_section_info[i].section_bits = INVALID_BITCOUNT_LC;
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
pstr_section_info[i].section_bits = INVALID_BITCOUNT_LD;
break;
}
pstr_section_info[i].code_book = -1;
sfb_width = ptr_sfb_offset[i + 1] - ptr_sfb_offset[i];
max_val = sfb_max[i];
ia_enhaacplus_enc_bitcount(ptr_quant_spec + ptr_sfb_offset[i], sfb_width, max_val,
bit_look_up[i], pstr_huffman_tbl, aot);
}
}
static WORD32 ia_enhaacplus_enc_find_best_book(const WORD32 *ptr_bit_cnt, WORD8 *ptr_codebook,
WORD32 aot) {
WORD32 min_bits = 0, temp1, temp2;
WORD8 temp_book = CODE_BCK_ESC_NDX;
WORD8 j;
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
min_bits = INVALID_BITCOUNT_LC;
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
min_bits = INVALID_BITCOUNT_LD;
break;
}
for (j = 0; j <= CODE_BCK_ESC_NDX; j += 2) {
temp1 = *ptr_bit_cnt++;
temp2 = *ptr_bit_cnt++;
if (temp1 < min_bits) {
min_bits = temp1;
temp_book = j;
}
if (temp2 < min_bits) {
min_bits = temp2;
temp_book = j + 1;
}
}
*ptr_codebook = temp_book;
return min_bits;
}
static WORD32 ia_enhaacplus_enc_find_min_merge_bits(const WORD32 *ptr_bit_cnt1,
const WORD32 *ptr_bit_cnt2, WORD32 aot) {
WORD32 min_bits = 0, j, temp1, temp2, temp3, temp4;
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
min_bits = INVALID_BITCOUNT_LC;
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
min_bits = INVALID_BITCOUNT_LD;
break;
}
for (j = CODE_BCK_ESC_NDX; j >= 0; j -= 2) {
temp1 = *ptr_bit_cnt1++;
temp2 = *ptr_bit_cnt2++;
temp3 = *ptr_bit_cnt1++;
temp1 = temp1 + temp2;
min_bits = MIN(temp1, min_bits);
temp4 = *ptr_bit_cnt2++;
temp1 = temp3 + temp4;
min_bits = MIN(temp1, min_bits);
}
return min_bits;
}
static VOID ia_enhaacplus_enc_merge_bit_look_up(WORD32 *ptr_bit_cnt1, const WORD32 *ptr_bit_cnt2,
WORD32 aot) {
WORD32 j, temp1, temp2, temp3, temp4;
WORD32 invalid_bitcnt = 0;
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
invalid_bitcnt = INVALID_BITCOUNT_LC;
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
invalid_bitcnt = INVALID_BITCOUNT_LD;
break;
}
for (j = 0; j <= CODE_BCK_ESC_NDX; j += 2) {
temp1 = ptr_bit_cnt1[j];
temp2 = ptr_bit_cnt2[j];
temp3 = ptr_bit_cnt1[j + 1];
ptr_bit_cnt1[j] = MIN(temp1 + temp2, invalid_bitcnt);
temp4 = ptr_bit_cnt2[j + 1];
ptr_bit_cnt1[j + 1] = MIN(temp3 + temp4, invalid_bitcnt);
}
}
static WORD32 ia_enhaacplus_enc_find_max_merge(
const WORD32 merge_gain_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG],
const ixheaace_section_info *section, const WORD32 max_sfb, WORD32 *max_ndx) {
WORD32 i, max_merge_gain = 0;
for (i = 0; i + section[i].sfb_cnt < max_sfb; i += section[i].sfb_cnt) {
if (merge_gain_look_up[i] > max_merge_gain) {
max_merge_gain = merge_gain_look_up[i];
*max_ndx = i;
}
}
return (max_merge_gain);
}
static WORD32 ia_enhaacplus_enc_calc_merge_gain(
const ixheaace_section_info *pstr_section_info,
WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1],
const WORD32 *pstr_side_info_tab, const WORD32 idx1, const WORD32 idx2, WORD32 aot) {
WORD32 split_bits;
WORD32 merge_bits;
WORD32 merge_gain;
split_bits = pstr_section_info[idx1].section_bits + pstr_section_info[idx2].section_bits;
merge_bits =
pstr_side_info_tab[pstr_section_info[idx1].sfb_cnt + pstr_section_info[idx2].sfb_cnt] +
ia_enhaacplus_enc_find_min_merge_bits(bit_look_up[idx1], bit_look_up[idx2], aot);
merge_gain = split_bits - merge_bits;
return merge_gain;
}
static VOID ia_enhaacplus_enc_gm_stage0(
ixheaace_section_info *pstr_section,
WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1],
const WORD32 max_sfb, WORD32 aot) {
WORD32 i = 0;
WORD32 invalid_bitcnt = 0;
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
invalid_bitcnt = INVALID_BITCOUNT_LC;
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
invalid_bitcnt = INVALID_BITCOUNT_LD;
break;
}
while (i < max_sfb) {
if (pstr_section[i].section_bits == invalid_bitcnt) {
pstr_section[i].section_bits = (WORD16)ia_enhaacplus_enc_find_best_book(
bit_look_up[i], &(pstr_section[i].code_book), aot);
}
i++;
}
}
static VOID ia_enhaacplus_enc_gm_stage1(
ixheaace_section_info *pstr_section_info,
WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1],
const WORD32 max_sfb, const WORD32 *ptr_side_info_tab, WORD32 aot) {
WORD32 merge_start = 0, merge_end;
do {
for (merge_end = merge_start + 1; merge_end < max_sfb; merge_end++) {
if (pstr_section_info[merge_start].code_book != pstr_section_info[merge_end].code_book) {
break;
}
pstr_section_info[merge_start].sfb_cnt++;
pstr_section_info[merge_start].section_bits += pstr_section_info[merge_end].section_bits;
ia_enhaacplus_enc_merge_bit_look_up(bit_look_up[merge_start], bit_look_up[merge_end], aot);
}
pstr_section_info[merge_start].section_bits +=
(WORD16)ptr_side_info_tab[pstr_section_info[merge_start].sfb_cnt];
pstr_section_info[merge_end - 1].sfb_start = pstr_section_info[merge_start].sfb_start;
merge_start = merge_end;
} while (merge_start < max_sfb);
}
static VOID ia_enhaacplus_enc_gm_stage2(
ixheaace_section_info *pstr_section_info,
WORD32 merge_gain_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG],
WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1],
const WORD32 max_sfb, const WORD32 *ptr_side_info_tab, WORD32 aot) {
WORD32 i;
for (i = 0; i + pstr_section_info[i].sfb_cnt < max_sfb; i += pstr_section_info[i].sfb_cnt) {
merge_gain_look_up[i] =
ia_enhaacplus_enc_calc_merge_gain(pstr_section_info, bit_look_up, ptr_side_info_tab, i,
i + pstr_section_info[i].sfb_cnt, aot);
}
while (TRUE) {
WORD32 max_merge_gain = 0, max_idx = 0, max_idx_next = 0, max_idx_last = 0;
max_merge_gain = ia_enhaacplus_enc_find_max_merge(merge_gain_look_up, pstr_section_info,
max_sfb, &max_idx);
if (max_merge_gain <= 0) {
break;
}
max_idx_next = max_idx + pstr_section_info[max_idx].sfb_cnt;
pstr_section_info[max_idx].sfb_cnt += pstr_section_info[max_idx_next].sfb_cnt;
pstr_section_info[max_idx].section_bits +=
pstr_section_info[max_idx_next].section_bits - (WORD16)max_merge_gain;
ia_enhaacplus_enc_merge_bit_look_up(bit_look_up[max_idx], bit_look_up[max_idx_next], aot);
if (max_idx != 0) {
max_idx_last = pstr_section_info[max_idx - 1].sfb_start;
merge_gain_look_up[max_idx_last] = ia_enhaacplus_enc_calc_merge_gain(
pstr_section_info, bit_look_up, ptr_side_info_tab, max_idx_last, max_idx, aot);
}
max_idx_next = max_idx + pstr_section_info[max_idx].sfb_cnt;
pstr_section_info[max_idx_next - 1].sfb_start = pstr_section_info[max_idx].sfb_start;
if (max_idx_next < max_sfb) {
merge_gain_look_up[max_idx] = ia_enhaacplus_enc_calc_merge_gain(
pstr_section_info, bit_look_up, ptr_side_info_tab, max_idx, max_idx_next, aot);
}
}
}
static IA_ERRORCODE ia_enhaacplus_enc_noiseless_counter(
ixheaace_section_data *pstr_section_data,
WORD32 merge_gain_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG],
WORD32 bit_look_up[MAXIMUM_SCALE_FACTOR_BAND_LONG][CODE_BCK_ESC_NDX + 1],
const WORD16 *ptr_quant_spec, const UWORD16 *ptr_max_val_in_sfb, const WORD32 *ptr_sfb_offset,
const WORD32 block_type, WORD32 *ptr_side_info_tab_long, WORD32 *ptr_side_info_tab_short,
ixheaace_huffman_tables *pstr_huffman_tbl, WORD32 aot) {
WORD32 grp_idx;
WORD32 *ptr_side_info_tab = 0;
ixheaace_section_info *pstr_section_info;
WORD32 i;
for (i = 0; i < MAXIMUM_SCALE_FACTOR_BAND_LONG; i++) {
memset(bit_look_up[i], 0, (CODE_BCK_ESC_NDX + 1) * sizeof(bit_look_up[0][0]));
}
/* counting previous operations */
switch (block_type) {
case LONG_WINDOW:
case START_WINDOW:
case STOP_WINDOW:
ptr_side_info_tab = ptr_side_info_tab_long;
break;
case SHORT_WINDOW:
ptr_side_info_tab = ptr_side_info_tab_short;
break;
default:
return IA_EXHEAACE_EXE_FATAL_INVALID_BLOCK_TYPE;
}
pstr_section_data->num_of_sections = 0;
pstr_section_data->huffman_bits = 0;
pstr_section_data->side_info_bits = 0;
if (pstr_section_data->max_sfb_per_grp == 0) {
return IA_NO_ERROR;
}
for (grp_idx = 0; grp_idx < pstr_section_data->sfb_cnt;
grp_idx += pstr_section_data->sfb_per_group) {
pstr_section_info = pstr_section_data->section + pstr_section_data->num_of_sections;
ia_enhaacplus_enc_build_bit_look_up(ptr_quant_spec, pstr_section_data->max_sfb_per_grp,
ptr_sfb_offset + grp_idx, ptr_max_val_in_sfb + grp_idx,
bit_look_up, pstr_section_info, pstr_huffman_tbl, aot);
ia_enhaacplus_enc_gm_stage0(pstr_section_info, bit_look_up,
pstr_section_data->max_sfb_per_grp, aot);
ia_enhaacplus_enc_gm_stage1(pstr_section_info, bit_look_up,
pstr_section_data->max_sfb_per_grp, ptr_side_info_tab, aot);
ia_enhaacplus_enc_gm_stage2(pstr_section_info, merge_gain_look_up, bit_look_up,
pstr_section_data->max_sfb_per_grp, ptr_side_info_tab, aot);
for (i = 0; i < pstr_section_data->max_sfb_per_grp; i += pstr_section_info[i].sfb_cnt) {
ia_enhaacplus_enc_find_best_book(bit_look_up[i], &(pstr_section_info[i].code_book), aot);
pstr_section_info[i].sfb_start += (WORD8)grp_idx;
pstr_section_data->huffman_bits +=
pstr_section_info[i].section_bits - ptr_side_info_tab[pstr_section_info[i].sfb_cnt];
pstr_section_data->side_info_bits += ptr_side_info_tab[pstr_section_info[i].sfb_cnt];
pstr_section_data->section[pstr_section_data->num_of_sections++] = pstr_section_info[i];
}
}
return IA_NO_ERROR;
}
static WORD32 ia_enhaacplus_enc_bit_count_scalefactor_delta(
WORD32 delta, ixheaace_huffman_tables *pstr_huffman_tbl) {
return pstr_huffman_tbl->huff_ltabscf[delta + CODE_BCK_SCF_LAV];
}
static IA_ERRORCODE ia_enhaacplus_enc_scf_count(const WORD16 *ptr_scale_fac,
const UWORD16 *ptr_max_val_in_sfb,
ixheaace_section_data *pstr_section_data,
ixheaace_huffman_tables *pstr_huffman_tbl) {
WORD32 sect_idx1 = 0;
WORD32 sfb_idx1 = 0;
WORD32 scf_idx = 0;
WORD32 sect_idx2 = 0;
WORD32 sfb_idx2 = 0;
WORD32 last_val_scf = 0;
WORD32 delta_scf = 0;
WORD32 found = 0;
WORD32 scf_skip_counter = 0;
pstr_section_data->scale_fac_bits = 0;
if (ptr_scale_fac == 0) {
return IA_EXHEAACE_EXE_FATAL_INVALID_SCALE_FACTOR_GAIN;
}
last_val_scf = 0;
pstr_section_data->first_scf = 0;
for (sect_idx1 = 0; sect_idx1 < pstr_section_data->num_of_sections; sect_idx1++) {
if (pstr_section_data->section[sect_idx1].code_book != CODE_BCK_ZERO_NO) {
pstr_section_data->first_scf = pstr_section_data->section[sect_idx1].sfb_start;
last_val_scf = ptr_scale_fac[pstr_section_data->first_scf];
break;
}
}
for (sect_idx1 = 0; sect_idx1 < pstr_section_data->num_of_sections; sect_idx1++) {
if ((pstr_section_data->section[sect_idx1].code_book != CODE_BCK_ZERO_NO) &&
(pstr_section_data->section[sect_idx1].code_book != CODE_BCK_PNS_NO)) {
for (sfb_idx1 = pstr_section_data->section[sect_idx1].sfb_start;
sfb_idx1 < pstr_section_data->section[sect_idx1].sfb_start +
pstr_section_data->section[sect_idx1].sfb_cnt;
sfb_idx1++) {
if (ptr_max_val_in_sfb[sfb_idx1] == 0) {
found = 0;
if (scf_skip_counter == 0) {
if (sfb_idx1 == (pstr_section_data->section[sect_idx1].sfb_start +
pstr_section_data->section[sect_idx1].sfb_cnt - 1)) {
found = 0;
} else {
for (scf_idx = (sfb_idx1 + 1);
scf_idx < pstr_section_data->section[sect_idx1].sfb_start +
pstr_section_data->section[sect_idx1].sfb_cnt;
scf_idx++) {
if (ptr_max_val_in_sfb[scf_idx] != 0) {
found = 1;
if ((abs32(ptr_scale_fac[scf_idx] - last_val_scf)) < CODE_BCK_SCF_LAV) {
delta_scf = 0;
} else {
delta_scf = -(ptr_scale_fac[sfb_idx1] - last_val_scf);
last_val_scf = ptr_scale_fac[sfb_idx1];
scf_skip_counter = 0;
}
break;
}
/* count scalefactor skip */
scf_skip_counter = scf_skip_counter + 1;
}
}
/* search for the next ptr_max_val_in_sfb[] != 0 in all other sections */
for (sect_idx2 = (sect_idx1 + 1);
(sect_idx2 < pstr_section_data->num_of_sections) && (found == 0); sect_idx2++) {
if ((pstr_section_data->section[sect_idx2].code_book != CODE_BCK_ZERO_NO) &&
(pstr_section_data->section[sect_idx2].code_book != CODE_BCK_PNS_NO)) {
for (sfb_idx2 = pstr_section_data->section[sect_idx2].sfb_start;
sfb_idx2 < pstr_section_data->section[sect_idx2].sfb_start +
pstr_section_data->section[sect_idx2].sfb_cnt;
sfb_idx2++) {
if (ptr_max_val_in_sfb[sfb_idx2] != 0) {
found = 1;
if ((abs32(ptr_scale_fac[sfb_idx2] - last_val_scf)) < CODE_BCK_SCF_LAV) {
delta_scf = 0;
} else {
delta_scf = -(ptr_scale_fac[sfb_idx1] - last_val_scf);
last_val_scf = ptr_scale_fac[sfb_idx1];
scf_skip_counter = 0;
}
break;
}
scf_skip_counter = scf_skip_counter + 1;
}
}
}
if (found == 0) {
delta_scf = 0;
scf_skip_counter = 0;
}
} else {
delta_scf = 0;
scf_skip_counter = scf_skip_counter - 1;
}
} else {
delta_scf = -(ptr_scale_fac[sfb_idx1] - last_val_scf);
last_val_scf = ptr_scale_fac[sfb_idx1];
}
pstr_section_data->scale_fac_bits +=
ia_enhaacplus_enc_bit_count_scalefactor_delta(delta_scf, pstr_huffman_tbl);
}
}
}
return IA_NO_ERROR;
}
IA_ERRORCODE ia_enhaacplus_enc_dyn_bitcount(
const WORD16 *ptr_quant_spec, const UWORD16 *ptr_max_val_in_sfb, const WORD16 *ptr_scale_fac,
const WORD32 block_type, const WORD32 sfb_cnt, const WORD32 max_sfb_per_grp,
const WORD32 sfb_per_grp, const WORD32 *ptr_sfb_offset,
ixheaace_section_data *pstr_section_data, WORD32 *ptr_side_info_tab_long,
WORD32 *ptr_side_info_tab_short, ixheaace_huffman_tables *ptr_huffman_tbl,
WORD32 *ptr_scratch_buf, WORD32 aot, WORD32 *bit_cnt) {
IA_ERRORCODE err_code;
WORD32(*ptr_bit_look_up)
[CODE_BCK_ESC_NDX + 1] = (WORD32(*)[CODE_BCK_ESC_NDX + 1]) ptr_scratch_buf;
WORD32 *ptr_merge_gain_look_up =
ptr_scratch_buf + MAXIMUM_SCALE_FACTOR_BAND_LONG * (CODE_BCK_ESC_NDX + 1);
*bit_cnt = 0;
pstr_section_data->block_type = block_type;
pstr_section_data->sfb_cnt = sfb_cnt;
pstr_section_data->sfb_per_group = sfb_per_grp;
pstr_section_data->total_groups_cnt = sfb_cnt / sfb_per_grp;
pstr_section_data->max_sfb_per_grp = max_sfb_per_grp;
err_code = ia_enhaacplus_enc_noiseless_counter(
pstr_section_data, ptr_merge_gain_look_up, ptr_bit_look_up, ptr_quant_spec,
ptr_max_val_in_sfb, ptr_sfb_offset, block_type, ptr_side_info_tab_long,
ptr_side_info_tab_short, ptr_huffman_tbl, aot);
if (err_code != IA_NO_ERROR) {
return err_code;
}
err_code = ia_enhaacplus_enc_scf_count(ptr_scale_fac, ptr_max_val_in_sfb, pstr_section_data,
ptr_huffman_tbl);
if (err_code != IA_NO_ERROR) {
return err_code;
}
*bit_cnt = (pstr_section_data->huffman_bits + pstr_section_data->side_info_bits +
pstr_section_data->scale_fac_bits);
return IA_NO_ERROR;
}
VOID ia_enhaacplus_enc_bitcount_init(WORD32 *side_info_tab_long, WORD32 *side_info_tab_short) {
WORD32 i;
/* side_info_tab_long[] */
for (i = 0; i <= MAXIMUM_SCALE_FACTOR_BAND_LONG; i++) {
side_info_tab_long[i] = ia_enhaacplus_enc_calc_side_info_bits(i, LONG_WINDOW);
}
/* side_info_tab_short[] */
for (i = 0; i <= MAXIMUM_SCALE_FACTOR_BAND_SHORT; i++) {
side_info_tab_short[i] = ia_enhaacplus_enc_calc_side_info_bits(i, SHORT_WINDOW);
}
}

View file

@ -0,0 +1,71 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#define MAXIMUM_SECTIONS MAXIMUM_GROUPED_SCALE_FACTOR_BAND
#define SECT_ESC_VAL_LONG 31
#define SECT_ESC_VAL_SHORT 7
#define CODE_BCK_BITS 4
#define SECT_BITS_LONG 5
#define SECT_BITS_SHORT 3
typedef enum {
SI_ID_BITS = (3),
SI_FILL_COUNT_BITS = (4),
SI_FILL_ESC_COUNT_BITS = (8),
SI_FILL_EXTENTION_BITS = (4),
SI_FILL_NIBBLE_BITS = (4),
SI_SCE_BITS = (4),
SI_CPE_BITS = (5),
SI_CPE_MS_MASK_BITS = (2),
SI_ICS_INFO_BITS_LONG = (1 + 2 + 1 + 6 + 1),
SI_ICS_INFO_BITS_SHORT = (1 + 2 + 1 + 4 + 7),
SI_ICS_BITS = (8 + 1 + 1 + 1),
} SI_BITS;
typedef struct {
WORD8 code_book;
WORD8 sfb_start;
WORD8 sfb_cnt;
WORD16 section_bits;
} ixheaace_section_info;
typedef struct {
WORD32 block_type;
WORD32 total_groups_cnt;
WORD32 sfb_cnt;
WORD32 max_sfb_per_grp;
WORD32 sfb_per_group;
WORD32 num_of_sections;
ixheaace_section_info section[MAXIMUM_SECTIONS];
WORD32 side_info_bits; /* sectioning bits */
WORD32 huffman_bits; /* huffman coded bits */
WORD32 scale_fac_bits; /* scalefac coded bits */
WORD32 first_scf; /* first scf to be coded */
} ixheaace_section_data;
VOID ia_enhaacplus_enc_bitcount_init(WORD32 *side_info_tab_long, WORD32 *side_info_tab_short);
IA_ERRORCODE ia_enhaacplus_enc_dyn_bitcount(
const WORD16 *ptr_quant_spec, const UWORD16 *ptr_max_val_in_sfb, const WORD16 *ptr_scale_fac,
const WORD32 block_type, const WORD32 sfb_cnt, const WORD32 max_sfb_per_grp,
const WORD32 sfb_per_grp, const WORD32 *ptr_sfb_offset,
ixheaace_section_data *pstr_section_data, WORD32 *ptr_side_info_tab_long,
WORD32 *ptr_side_info_tab_short, ixheaace_huffman_tables *ptr_huffman_tbl,
WORD32 *ptr_scratch_buf, WORD32 aot, WORD32 *bit_cnt);

568
encoder/ixheaace_enc_init.c Normal file
View file

@ -0,0 +1,568 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include "ixheaac_type_def.h"
#include "ixheaace_aac_constants.h"
#include "ixheaac_error_standards.h"
#include "ixheaace_error_codes.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaace_enc_main.h"
#include "ixheaace_adjust_threshold_data.h"
#include "ixheaace_dynamic_bits.h"
#include "ixheaace_qc_data.h"
#include "ixheaace_channel_map.h"
#include "ixheaace_block_switch.h"
#include "ixheaace_psy_data.h"
#include "ixheaace_interface.h"
#include "ixheaace_write_bitstream.h"
#include "ixheaace_psy_configuration.h"
#include "ixheaace_psy_mod.h"
#include "ixheaace_qc_util.h"
#include "ixheaace_stereo_preproc.h"
#include "ixheaace_api_struct_define.h"
#include "ixheaace_aac_api.h"
#include "ixheaace_config_params.h"
#include "ixheaace_common_utils.h"
#define ALIGNMENT_DEFINE __attribute__((aligned(8)))
static WORD32 ixheaace_calculate_bandwidth(const WORD32 sample_rate,
const WORD32 channel_bit_rate, const WORD32 num_ch,
WORD32 aot) {
WORD32 bandwidth = -1;
const ixheaace_bandwidth_table *pstr_bandwidth_table = NULL;
WORD32 bandwidth_table_size = 0;
if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
pstr_bandwidth_table = bandwidth_table_lc;
bandwidth_table_size = sizeof(bandwidth_table_lc) / sizeof(ixheaace_bandwidth_table);
} else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
switch (sample_rate) {
case 48000:
case 64000:
case 88200:
case 96000:
pstr_bandwidth_table = bandwidth_table_ld_48000;
bandwidth_table_size =
sizeof(bandwidth_table_ld_48000) / sizeof(ixheaace_bandwidth_table);
break;
case 44100:
pstr_bandwidth_table = bandwidth_table_ld_44100;
bandwidth_table_size =
sizeof(bandwidth_table_ld_44100) / sizeof(ixheaace_bandwidth_table);
break;
case 32000:
pstr_bandwidth_table = bandwidth_table_ld_32000;
bandwidth_table_size =
sizeof(bandwidth_table_ld_32000) / sizeof(ixheaace_bandwidth_table);
break;
case 24000:
pstr_bandwidth_table = bandwidth_table_ld_24000;
bandwidth_table_size =
sizeof(bandwidth_table_ld_24000) / sizeof(ixheaace_bandwidth_table);
break;
case 8000:
case 11025:
case 12000:
case 16000:
case 22050:
pstr_bandwidth_table = bandwidth_table_ld_22050;
bandwidth_table_size =
sizeof(bandwidth_table_ld_22050) / sizeof(ixheaace_bandwidth_table);
break;
}
}
for (WORD32 i = 0; i < bandwidth_table_size - 1; i++) {
if (channel_bit_rate >= 96000) {
if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
bandwidth = 20000;
} else {
if (num_ch == 1) {
bandwidth = 19000;
} else {
bandwidth = 22000;
}
}
break;
} else if (channel_bit_rate >= pstr_bandwidth_table[i].channel_bit_rate &&
channel_bit_rate < pstr_bandwidth_table[i + 1].channel_bit_rate) {
if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
bandwidth = (num_ch == 1) ? pstr_bandwidth_table[i].bandwidth_mono
: pstr_bandwidth_table[i].bandwidth_stereo;
bandwidth = bandwidth - (pstr_bandwidth_table[i].channel_bit_rate / 32);
break;
} else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
WORD32 start_bandwidth, end_bandwidth, start_bitrate, end_bitrate;
FLOAT32 bandwidth_fac;
start_bandwidth = (num_ch == 1) ? pstr_bandwidth_table[i].bandwidth_mono
: pstr_bandwidth_table[i].bandwidth_stereo;
start_bandwidth = start_bandwidth - (pstr_bandwidth_table[i].channel_bit_rate / 32);
end_bandwidth = (num_ch == 1) ? pstr_bandwidth_table[i + 1].bandwidth_mono
: pstr_bandwidth_table[i + 1].bandwidth_stereo;
end_bandwidth = end_bandwidth - (pstr_bandwidth_table[i + 1].channel_bit_rate / 32);
start_bitrate = pstr_bandwidth_table[i].channel_bit_rate;
end_bitrate = pstr_bandwidth_table[i + 1].channel_bit_rate;
bandwidth_fac = (FLOAT32)(channel_bit_rate - start_bitrate / end_bitrate - start_bitrate);
bandwidth = (WORD32)(bandwidth_fac * (end_bandwidth - start_bandwidth) + start_bandwidth);
break;
}
}
}
return bandwidth;
}
static VOID ixheaace_determine_bandwidth(const WORD32 proposed_bandwidth, const WORD32 bitrate,
const WORD32 sample_rate, const WORD32 channels,
WORD32 *const bandwidth, WORD32 aot) {
WORD32 channel_bit_rate = bitrate / channels;
if (proposed_bandwidth == 0) {
*bandwidth = ixheaace_calculate_bandwidth(sample_rate, channel_bit_rate, channels, aot);
} else {
*bandwidth = MIN(proposed_bandwidth, MIN(20000, sample_rate >> 1));
}
*bandwidth = MIN(*bandwidth, sample_rate / 2);
}
WORD32 ia_enhaacplus_enc_aac_enc_pers_size(WORD32 num_aac_chan, WORD32 aot) {
WORD32 num_bytes;
num_bytes = sizeof(iexheaac_encoder_str);
num_bytes += num_aac_chan * sizeof(ixheaace_psy_out_channel);
num_bytes += num_aac_chan * sizeof(ixheaace_psy_data);
num_bytes += num_aac_chan * sizeof(ixheaace_temporal_noise_shaping_data);
if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
num_bytes += num_aac_chan * BLK_SWITCH_OFFSET_LC_128 * sizeof(FLOAT32);
} else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
num_bytes += num_aac_chan * BLK_SWITCH_OFFSET_LD * sizeof(FLOAT32);
}
num_bytes += num_aac_chan * sizeof(ixheaace_qc_out_channel);
return num_bytes;
}
WORD32 ia_enhaacplus_enc_aac_enc_scr_size(VOID) { return sizeof(iaace_scratch); }
VOID ia_enhaacplus_enc_set_shared_bufs(iaace_scratch *scr, WORD32 **shared_buf1,
WORD32 **shared_buf2, WORD32 **shared_buf3,
WORD8 **shared_buf5) {
iaace_scratch *pstr_aac_enc_scratch = scr;
/* Fill addresses of shared buffers */
pstr_aac_enc_scratch->shared_buffer1 = *shared_buf1;
pstr_aac_enc_scratch->shared_buffer_2 = *shared_buf2;
pstr_aac_enc_scratch->shared_buffer3 = *shared_buf3;
pstr_aac_enc_scratch->shared_buffer5 = (WORD8 *)*shared_buf5;
}
VOID ia_enhaacplus_enc_aac_init_default_config(iaace_config *config, WORD32 aot) {
memset(config, 0, sizeof(iaace_config));
/* default configurations */
config->bit_rate = AAC_BITRATE_DEFAULT_VALUE;
config->band_width = 0;
if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
config->inv_quant = 0;
config->bitreservoir_size = BITRESERVOIR_SIZE_CONFIG_PARAM_DEFAULT_VALUE_LC;
} else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
config->inv_quant = 2;
config->bitreservoir_size = BITRESERVOIR_SIZE_CONFIG_PARAM_DEFAULT_VALUE_LD;
}
config->use_tns = 0;
config->flag_framelength_small =
USE_FRAMELENGTH_SMALL_PARAM_DEFAULT_VALUE; // assume framelength large
}
static VOID ia_enhaacplus_enc_aac_set_scratch_ptr(iexheaac_encoder_str *pstr_exheaac_encoder,
iaace_scratch *pstr_scr) {
pstr_exheaac_encoder->pstr_aac_scratch = pstr_scr;
}
VOID ia_enhaacplus_enc_init_aac_tabs(ixheaace_aac_tables *pstr_aac_tabs) {
pstr_aac_tabs->pstr_mdct_tab = (ixheaace_mdct_tables *)&ixheaace_enc_mdct_tab;
pstr_aac_tabs->pstr_huff_tab = (ixheaace_huffman_tables *)&ixheaace_enc_huff_tab;
pstr_aac_tabs->pstr_psycho_tab = (ixheaace_psycho_tables *)&ixheaace_enc_psycho_tab;
pstr_aac_tabs->pstr_quant_tab = (ixheaace_quant_tables *)&ixheaace_enc_quant_tab;
pstr_aac_tabs->pstr_tns_tab =
(ixheaace_temporal_noise_shaping_tables *)&ixheaace_enhaacplus_enc_tns_tab;
}
static VOID ia_enhaacplus_enc_aac_set_persist_buf(WORD8 *ptr_base, WORD32 num_chan, WORD32 aot) {
iexheaac_encoder_str *pstr_exheaac_encoder;
WORD8 *ptr_curr_mem = (WORD8 *)((WORD8 *)ptr_base + sizeof(iexheaac_encoder_str));
WORD32 i;
pstr_exheaac_encoder = (iexheaac_encoder_str *)ptr_base;
for (i = 0; i < num_chan; i++) {
pstr_exheaac_encoder->psy_out.psy_out_ch[i] = (ixheaace_psy_out_channel *)(ptr_curr_mem);
ptr_curr_mem = ptr_curr_mem + sizeof(ixheaace_psy_out_channel);
}
for (i = 0; i < num_chan; i++) {
pstr_exheaac_encoder->psy_kernel.psy_data[i] = (ixheaace_psy_data *)(ptr_curr_mem);
ptr_curr_mem = ptr_curr_mem + sizeof(ixheaace_psy_data);
}
for (i = 0; i < num_chan; i++) {
pstr_exheaac_encoder->psy_kernel.temporal_noise_shaping_data[i] =
(ixheaace_temporal_noise_shaping_data *)(ptr_curr_mem);
ptr_curr_mem = ptr_curr_mem + sizeof(ixheaace_temporal_noise_shaping_data);
}
for (i = 0; i < num_chan; i++) {
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
pstr_exheaac_encoder->psy_kernel.psy_data[i]->ptr_mdct_delay_buf =
(FLOAT32 *)(ptr_curr_mem);
ptr_curr_mem = ptr_curr_mem + sizeof(FLOAT32) * BLK_SWITCH_OFFSET_LC_128;
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
pstr_exheaac_encoder->psy_kernel.psy_data[i]->ptr_mdct_delay_buf =
(FLOAT32 *)(ptr_curr_mem);
ptr_curr_mem = ptr_curr_mem + sizeof(FLOAT32) * BLK_SWITCH_OFFSET_LD;
break;
}
}
for (i = 0; i < num_chan; i++) {
pstr_exheaac_encoder->qc_out.qc_channel[i] = (ixheaace_qc_out_channel *)(ptr_curr_mem);
ptr_curr_mem = ptr_curr_mem + sizeof(ixheaace_qc_out_channel);
}
}
IA_ERRORCODE ia_enhaacplus_enc_aac_enc_open(iexheaac_encoder_str **ppstr_exheaac_encoder,
const iaace_config config,
iaace_scratch *pstr_aac_scratch,
ixheaace_aac_tables *pstr_aac_tabs, WORD32 ele_type,
WORD32 element_instance_tag, WORD32 init,
WORD32 aot) {
IA_ERRORCODE error = IA_NO_ERROR;
WORD32 profile = 1;
ixheaace_element_info *pstr_element_info = NULL;
iexheaac_encoder_str *pstr_exheaac_encoder;
WORD32 frame_len_long = FRAME_LEN_1024;
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
if (config.flag_framelength_small) {
frame_len_long = FRAME_LEN_960;
} else {
frame_len_long = FRAME_LEN_1024;
}
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
if (config.flag_framelength_small) {
frame_len_long = FRAME_LEN_480;
} else {
frame_len_long = FRAME_LEN_512;
}
break;
}
pstr_exheaac_encoder = *ppstr_exheaac_encoder;
if (init) {
memset(pstr_exheaac_encoder, 0, sizeof(iexheaac_encoder_str));
}
ia_enhaacplus_enc_aac_set_scratch_ptr(pstr_exheaac_encoder, pstr_aac_scratch);
ia_enhaacplus_enc_aac_set_persist_buf((WORD8 *)pstr_exheaac_encoder, config.num_out_channels,
aot);
if (init) {
if (!error) {
error =
(config.num_in_channels < 1 || config.num_out_channels > IXHEAACE_MAX_CH_IN_BS_ELE ||
config.num_out_channels < 1 || config.num_in_channels < config.num_out_channels ||
(config.bit_rate != 0 && (config.bit_rate / config.num_out_channels < 8000 ||
config.bit_rate / config.num_out_channels > 576000)));
}
/* check sample rate */
if (!error) {
switch (config.core_sample_rate) {
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 IA_EXHEAACE_INIT_FATAL_INVALID_CORE_SAMPLE_RATE;
break;
}
}
/* check if bit rate is not too high for sample rate */
if (!error) {
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
if (config.flag_framelength_small) {
if (config.bit_rate > ((float)(MAXIMUM_CHANNEL_BITS_960 - 744) / frame_len_long *
config.core_sample_rate * config.num_out_channels)) {
return IA_EXHEAACE_INIT_FATAL_INVALID_BIT_RATE;
}
} else {
if (config.bit_rate > ((float)(MAXIMUM_CHANNEL_BITS_1024 - 744) / frame_len_long *
config.core_sample_rate * config.num_out_channels)) {
return IA_EXHEAACE_INIT_FATAL_INVALID_BIT_RATE;
}
}
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
if (config.flag_framelength_small) {
if (config.bit_rate > ((float)(MAXIMUM_CHANNEL_BITS_480) / frame_len_long *
config.core_sample_rate * config.num_out_channels)) {
return IA_EXHEAACE_INIT_FATAL_INVALID_BIT_RATE;
}
} else {
if (config.bit_rate > ((float)(MAXIMUM_CHANNEL_BITS_512) / frame_len_long *
config.core_sample_rate * config.num_out_channels)) {
return IA_EXHEAACE_INIT_FATAL_INVALID_BIT_RATE;
}
}
break;
}
}
if (!error) {
pstr_exheaac_encoder->config = config;
}
if (!error) {
error = ia_enhaacplus_enc_init_element_info(config.num_out_channels,
&pstr_exheaac_encoder->element_info, ele_type,
element_instance_tag);
if (error != IA_NO_ERROR) {
return error;
}
}
}
if (!error) {
pstr_element_info = &pstr_exheaac_encoder->element_info;
}
/* allocate the Psy aud Psy Out structure */
if (!error) {
error = (ia_enhaacplus_enc_psy_new(
&pstr_exheaac_encoder->psy_kernel, pstr_element_info->n_channels_in_el,
pstr_exheaac_encoder->pstr_aac_scratch->shared_buffer_2, init, frame_len_long));
}
if (init) {
if (!error) {
WORD32 tns_mask = config.use_tns;
if (config.full_bandwidth) {
pstr_exheaac_encoder->config.band_width = config.core_sample_rate >> 2;
} else {
ixheaace_determine_bandwidth(pstr_exheaac_encoder->config.band_width, config.bit_rate,
config.core_sample_rate, pstr_element_info->n_channels_in_el,
&pstr_exheaac_encoder->config.band_width, aot);
}
pstr_exheaac_encoder->bandwidth_90_dB = (WORD32)pstr_exheaac_encoder->config.band_width;
if (ele_type == ID_LFE) {
tns_mask = 0;
}
error = ia_enhaacplus_enc_psy_main_init(
&pstr_exheaac_encoder->psy_kernel, config.core_sample_rate, config.bit_rate,
pstr_element_info->n_channels_in_el, tns_mask, pstr_exheaac_encoder->bandwidth_90_dB,
aot, pstr_aac_tabs, frame_len_long);
if (error != IA_NO_ERROR) {
return error;
}
}
}
/* allocate the Q&C Out structure */
if (!error) {
error = ia_enhaacplus_enc_qc_out_new(
&pstr_exheaac_encoder->qc_out, pstr_element_info->n_channels_in_el,
pstr_exheaac_encoder->pstr_aac_scratch->shared_buffer1,
pstr_exheaac_encoder->pstr_aac_scratch->shared_buffer3, init, frame_len_long);
}
/* allocate the Q&C kernel */
if (!error) {
error = ia_enhaacplus_enc_qc_new(&pstr_exheaac_encoder->qc_kernel,
pstr_exheaac_encoder->pstr_aac_scratch->shared_buffer_2,
init, frame_len_long);
}
if (init) {
if (!error) {
ixheaace_qc_init qc_init;
qc_init.pstr_element_info = &pstr_exheaac_encoder->element_info;
if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
if (config.flag_framelength_small) {
qc_init.max_bits = MAXIMUM_CHANNEL_BITS_960 * pstr_element_info->n_channels_in_el;
} else {
qc_init.max_bits = MAXIMUM_CHANNEL_BITS_1024 * pstr_element_info->n_channels_in_el;
}
qc_init.bit_res = qc_init.max_bits;
}
qc_init.average_bits = (config.bit_rate * frame_len_long) / config.core_sample_rate;
if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
if (pstr_exheaac_encoder->config.bitreservoir_size != -1) {
qc_init.max_bits = (pstr_exheaac_encoder->config.bitreservoir_size * 8) *
pstr_element_info->n_channels_in_el;
if (qc_init.max_bits > qc_init.average_bits) {
qc_init.bit_res = (pstr_exheaac_encoder->config.bitreservoir_size * 8) *
pstr_element_info->n_channels_in_el;
} else {
qc_init.max_bits = qc_init.average_bits;
qc_init.bit_res = 0;
}
} else {
qc_init.max_bits = qc_init.average_bits;
qc_init.bit_res = 0;
}
}
qc_init.padding.padding_rest = config.core_sample_rate;
qc_init.mean_pe =
((FLOAT32)10 * frame_len_long * pstr_exheaac_encoder->bandwidth_90_dB * 2) /
config.core_sample_rate;
switch (aot) {
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
if (config.flag_framelength_small) {
qc_init.max_bit_fac =
(float)((MAXIMUM_CHANNEL_BITS_960 - 744) * pstr_element_info->n_channels_in_el) /
(float)(qc_init.average_bits ? qc_init.average_bits : 1);
} else {
qc_init.max_bit_fac =
(float)((MAXIMUM_CHANNEL_BITS_1024 - 744) * pstr_element_info->n_channels_in_el) /
(float)(qc_init.average_bits ? qc_init.average_bits : 1);
}
break;
case AOT_AAC_LD:
case AOT_AAC_ELD:
if (config.flag_framelength_small) {
qc_init.max_bit_fac = (FLOAT32)((MAXIMUM_CHANNEL_BITS_480)*pstr_element_info
->n_channels_in_el); // no anc data in aacld
} else {
qc_init.max_bit_fac = (FLOAT32)((MAXIMUM_CHANNEL_BITS_512)*pstr_element_info
->n_channels_in_el); // no anc data in aacld
}
qc_init.max_bit_fac =
qc_init.max_bit_fac / (qc_init.average_bits ? qc_init.average_bits : 1);
break;
}
qc_init.bitrate = config.bit_rate;
qc_init.inv_quant = config.inv_quant;
error = ia_enhaacplus_enc_qc_init(&pstr_exheaac_encoder->qc_kernel, aot, &qc_init,
config.flag_framelength_small);
if (error != IA_NO_ERROR) {
return error;
}
}
/* init bitstream encoder */
if (!error) {
pstr_exheaac_encoder->bse_init.num_channels = pstr_element_info->n_channels_in_el;
pstr_exheaac_encoder->bse_init.bitrate = config.bit_rate;
pstr_exheaac_encoder->bse_init.sample_rate = config.core_sample_rate;
pstr_exheaac_encoder->bse_init.profile = profile;
}
if (!error) {
if (config.num_in_channels > config.num_out_channels) {
pstr_exheaac_encoder->downmix = 1;
pstr_exheaac_encoder->downmix_fac = config.num_in_channels / config.num_out_channels;
}
}
if (!error) {
if (pstr_element_info->el_type == ID_CPE &&
(config.core_sample_rate <= 24000 &&
(config.bit_rate / pstr_element_info->n_channels_in_el * 2) < 60000)) {
FLOAT32 scf_used_ratio =
(FLOAT32)pstr_exheaac_encoder->psy_kernel.psy_conf_long.sfb_active /
pstr_exheaac_encoder->psy_kernel.psy_conf_long.sfb_cnt;
error = iaace_init_stereo_pre_processing(
&(pstr_exheaac_encoder->str_stereo_pre_pro), pstr_element_info->n_channels_in_el,
config.bit_rate, config.core_sample_rate, scf_used_ratio);
}
}
if (error) {
ia_enhaacplus_enc_aac_enc_close(pstr_exheaac_encoder);
pstr_exheaac_encoder = NULL;
return IA_EXHEAACE_INIT_FATAL_AAC_INIT_FAILED;
}
*ppstr_exheaac_encoder = pstr_exheaac_encoder;
}
return IA_NO_ERROR;
}
VOID ia_enhaacplus_enc_aac_enc_close(iexheaac_encoder_str *pstr_exheaac_encoder) {
if (pstr_exheaac_encoder) {
ia_enhaacplus_enc_qc_delete(&pstr_exheaac_encoder->qc_kernel);
ia_enhaacplus_enc_qc_out_delete(&pstr_exheaac_encoder->qc_out);
ia_enhaacplus_enc_psy_delete(&pstr_exheaac_encoder->psy_kernel);
ia_enhaacplus_enc_psy_out_delete(&pstr_exheaac_encoder->psy_out);
pstr_exheaac_encoder = NULL;
}
}

235
encoder/ixheaace_enc_main.c Normal file
View file

@ -0,0 +1,235 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
#include <stdlib.h>
#include "ixheaac_basic_ops32.h"
#include "ixheaac_basic_ops16.h"
#include "ixheaac_basic_ops40.h"
#include "ixheaac_basic_ops.h"
#include "ixheaac_error_standards.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_adjust_threshold_data.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaace_enc_main.h"
#include "ixheaace_dynamic_bits.h"
#include "ixheaace_qc_data.h"
#include "ixheaace_channel_map.h"
#include "ixheaace_block_switch.h"
#include "ixheaace_psy_data.h"
#include "ixheaace_interface.h"
#include "ixheaace_write_bitstream.h"
#include "ixheaace_psy_configuration.h"
#include "ixheaace_psy_mod.h"
#include "ixheaace_qc_util.h"
#include "ixheaace_stereo_preproc.h"
#include "ixheaace_api_struct_define.h"
#include "ixheaace_aac_api.h"
#include "ixheaace_error_codes.h"
#include "ixheaace_common_utils.h"
#define ALIGNMENT_DEFINE __attribute__((aligned(8)))
IA_ERRORCODE ia_enhaacplus_enc_aac_core_encode(
iexheaac_encoder_str **pstr_aac_enc, FLOAT32 *ptr_time_signal, UWORD32 time_sn_stride,
const UWORD8 *ptr_anc_bytes, UWORD8 *num_anc_bytes, UWORD8 *ptr_out_bytes,
WORD32 *num_out_bytes, ixheaace_aac_tables *pstr_aac_tabs, VOID *ptr_bit_stream_handle,
VOID *ptr_bit_stream, FLAG flag_last_element, WORD32 *write_program_config_element,
WORD32 i_num_coup_channels, WORD32 i_channels_mask, WORD32 ele_idx, WORD32 *total_fill_bits,
WORD32 total_channels, WORD32 aot, WORD32 adts_flag, WORD32 num_bs_elements) {
IA_ERRORCODE err_code = IA_NO_ERROR;
iexheaac_encoder_str *pstr_aac_encoder = pstr_aac_enc[ele_idx];
ixheaace_element_info *pstr_element_info = &pstr_aac_encoder->element_info;
WORD32 glob_used_bits;
WORD32 anc_data_bytes, anc_data_bytes_left;
WORD32 stat_bits_flag = 0;
WORD32 frame_len_long = FRAME_LEN_1024;
WORD32 ch;
if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
frame_len_long =
(pstr_aac_encoder->config.flag_framelength_small == 1) ? FRAME_LEN_960 : FRAME_LEN_1024;
} else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
frame_len_long =
(pstr_aac_encoder->config.flag_framelength_small == 1) ? FRAME_LEN_480 : FRAME_LEN_512;
}
if (ele_idx == 0) {
if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
ptr_bit_stream_handle = ia_enhaacplus_enc_create_bitbuffer(
ptr_bit_stream, (UWORD8 *)ptr_out_bytes,
(((pstr_aac_encoder->config.flag_framelength_small == 1) ? MAXIMUM_CHANNEL_BITS_960
: MAXIMUM_CHANNEL_BITS_1024) /
8) *
total_channels);
} else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
if (pstr_aac_encoder->config.bitreservoir_size != -1) {
WORD32 avg_byte_perframe = (pstr_aac_encoder->config.bit_rate * frame_len_long /
(pstr_aac_encoder->config.core_sample_rate * 8));
if ((pstr_aac_encoder->config.bitreservoir_size * total_channels) > avg_byte_perframe) {
ptr_bit_stream_handle = ia_enhaacplus_enc_create_bitbuffer(
ptr_bit_stream, (UWORD8 *)ptr_out_bytes,
pstr_aac_encoder->config.bitreservoir_size * total_channels);
} else {
ptr_bit_stream_handle = ia_enhaacplus_enc_create_bitbuffer(
ptr_bit_stream, (UWORD8 *)ptr_out_bytes,
(pstr_aac_encoder->config.bit_rate * frame_len_long /
(pstr_aac_encoder->config.core_sample_rate * 8)));
}
} else {
ptr_bit_stream_handle = ia_enhaacplus_enc_create_bitbuffer(
ptr_bit_stream, (UWORD8 *)ptr_out_bytes,
(pstr_aac_encoder->config.bit_rate * frame_len_long /
(pstr_aac_encoder->config.core_sample_rate * 8)));
}
}
} else {
ptr_bit_stream_handle = ptr_bit_stream;
}
if (adts_flag) {
stat_bits_flag = 0; /* fix for low bit-rate */
if ((pstr_aac_encoder->config.core_sample_rate * 3) <= (pstr_aac_encoder->config.bit_rate)) {
stat_bits_flag = 7; /* fix for low bit-rate */
}
}
anc_data_bytes = anc_data_bytes_left = *num_anc_bytes;
if (pstr_element_info->el_type == ID_CPE) {
if (!pstr_aac_encoder->config.num_stereo_preprocessing) {
iaace_apply_stereo_preproc(&pstr_aac_encoder->str_stereo_pre_pro, time_sn_stride,
pstr_element_info, ptr_time_signal, frame_len_long);
}
}
err_code = ia_enhaacplus_enc_psy_main(
time_sn_stride, pstr_element_info, ptr_time_signal, aot,
pstr_aac_encoder->psy_kernel.psy_data[pstr_element_info->channel_index[0]],
pstr_aac_encoder->psy_kernel
.temporal_noise_shaping_data[pstr_element_info->channel_index[0]],
&pstr_aac_encoder->psy_kernel.psy_conf_long, &pstr_aac_encoder->psy_kernel.psy_conf_short,
pstr_aac_encoder->psy_out.psy_out_ch[pstr_element_info->channel_index[0]],
&pstr_aac_encoder->psy_out.psy_out_element,
pstr_aac_encoder->psy_kernel.p_scratch_tns_float,
(FLOAT32 *)pstr_aac_encoder->pstr_aac_scratch->shared_buffer1,
pstr_aac_encoder->pstr_aac_scratch->shared_buffer5, pstr_aac_tabs, frame_len_long);
if (err_code != IA_NO_ERROR) {
return err_code;
}
ia_enhaacplus_enc_adjust_bitrate(
&pstr_aac_encoder->qc_kernel, pstr_aac_encoder->config.bit_rate,
pstr_aac_encoder->config.core_sample_rate, flag_last_element, frame_len_long);
for (ch = 0; ch < pstr_element_info->n_channels_in_el; ch++) {
pstr_aac_encoder->psy_out.psy_out_ch[pstr_element_info->channel_index[0]][ch].ms_digest =
pstr_aac_encoder->psy_out.psy_out_element.tools_info.ms_digest;
memcpy(
&pstr_aac_encoder->psy_out.psy_out_ch[pstr_element_info->channel_index[0]][ch].ms_used[0],
&pstr_aac_encoder->psy_out.psy_out_element.tools_info.ms_mask[0],
MAXIMUM_GROUPED_SCALE_FACTOR_BAND *
sizeof(pstr_aac_encoder->psy_out.psy_out_ch[pstr_element_info->channel_index[0]][ch]
.ms_used[0]));
}
err_code = ia_enhaacplus_enc_qc_main(
&pstr_aac_encoder->qc_kernel, pstr_element_info->n_channels_in_el,
&pstr_aac_encoder->qc_kernel.element_bits,
pstr_aac_encoder->psy_out.psy_out_ch[pstr_element_info->channel_index[0]],
&pstr_aac_encoder->psy_out.psy_out_element,
pstr_aac_encoder->qc_out.qc_channel[pstr_element_info->channel_index[0]],
&pstr_aac_encoder->qc_out.qc_element, MIN(anc_data_bytes_left, anc_data_bytes),
pstr_aac_tabs, adts_flag, aot, stat_bits_flag, flag_last_element, frame_len_long,
pstr_aac_encoder->pstr_aac_scratch->shared_buffer5);
if (err_code != IA_NO_ERROR) {
return err_code;
}
if (pstr_element_info->el_type == ID_CPE) {
if (!pstr_aac_encoder->config.num_stereo_preprocessing) {
iaace_update_stereo_pre_process(
pstr_aac_encoder->psy_out.psy_out_ch[pstr_element_info->channel_index[0]],
&pstr_aac_encoder->qc_out.qc_element, &pstr_aac_encoder->str_stereo_pre_pro,
pstr_aac_encoder->psy_out.psy_out_element.weight_ms_lr_pe_ratio);
}
}
/* Update bit reservoir levels */
ia_enhaacplus_enc_update_bit_reservoir(&pstr_aac_encoder->qc_kernel, &pstr_aac_encoder->qc_out);
err_code = ia_enhaacplus_enc_finalize_bit_consumption(
&pstr_aac_encoder->qc_kernel, &pstr_aac_encoder->qc_out, flag_last_element,
((ixheaace_bit_buf_handle)ptr_bit_stream_handle)->cnt_bits, total_fill_bits, pstr_aac_enc,
num_bs_elements, aot);
if (err_code != IA_NO_ERROR) {
return err_code;
}
err_code = ia_enhaacplus_enc_write_bitstream(
ptr_bit_stream_handle, *pstr_element_info, &pstr_aac_encoder->qc_out,
&pstr_aac_encoder->psy_out, &glob_used_bits, ptr_anc_bytes, pstr_aac_tabs,
flag_last_element, write_program_config_element, i_num_coup_channels, i_channels_mask,
pstr_aac_encoder->config.core_sample_rate, ele_idx, aot, total_fill_bits);
if (err_code != IA_NO_ERROR) {
return err_code;
}
/* write out the bitstream */
*num_out_bytes = ia_enhaacplus_enc_get_bits_available(ptr_bit_stream_handle) / 8;
/* Validate that this frame is not too large */
if (pstr_aac_encoder->config.bitreservoir_size != -1) {
WORD32 avg_bytes_perframe = (pstr_aac_encoder->config.bit_rate * frame_len_long /
(pstr_aac_encoder->config.core_sample_rate * 8));
if (pstr_aac_encoder->config.bitreservoir_size * total_channels > avg_bytes_perframe) {
if (*num_out_bytes > (pstr_aac_encoder->config.bitreservoir_size * total_channels)) {
err_code = IA_EXHEAACE_EXE_FATAL_INVALID_OUT_BYTES;
}
} else {
if (*num_out_bytes > avg_bytes_perframe) {
err_code = IA_EXHEAACE_EXE_FATAL_INVALID_OUT_BYTES;
}
}
} else {
WORD32 avg_bytes_perframe = (pstr_aac_encoder->config.bit_rate * frame_len_long /
(pstr_aac_encoder->config.core_sample_rate * 8));
if (*num_out_bytes > avg_bytes_perframe) {
err_code = IA_EXHEAACE_EXE_FATAL_INVALID_OUT_BYTES;
}
}
return err_code;
}

View file

@ -0,0 +1,94 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
/* here we distinguish between stereo and the mono only encoder */
#define IXHEAACE_MAX_CH_IN_BS_ELE (2)
#define MAXIMUM_BS_ELE \
8 /* 1 <SCE> 2 <CPE> 3<CPE> 4<CPE> 5<LFE> 6<SCE> - 8.1 channel + 2 cc channels*/
#define FRAME_LEN_1024 1024
#define FRAME_LEN_512 512
#define FRAME_LEN_480 480
#define FRAME_LEN_960 960
#define AACENC_TRANS_FAC 8 /* encoder WORD16 long ratio */
#define AACENC_PCM_LEVEL 1.0 /* encoder pcm 0db refernence */
#define MAX_INPUT_CHAN (IXHEAACE_MAX_CH_IN_BS_ELE)
#define MAX_FRAME_LEN (1024)
// Change to accommodate 4:1 resampler - input = 4096 samples per channel
#define MAX_INPUT_SAMPLES (MAX_FRAME_LEN * MAX_INPUT_CHAN * 4)
#define NUM_CHANS_MONO (1)
#define NUM_CHANS_STEREO (2)
/*-------------------------- defines --------------------------------------*/
#define BUFFERSIZE 1024 /* anc data */
/*-------------------- structure definitions ------------------------------*/
typedef struct {
WORD32 sample_rate; /* mapped input sample rate */
WORD32 core_sample_rate; /* core coder processing sample rate */
WORD32 native_sample_rate; /* audio file sample rate */
WORD32 bit_rate; /* encoder bit rate in bits/sec */
WORD32 num_in_channels; /* number of channels on input (1,2) */
WORD32 num_out_channels; /* number of channels on output (1,2) */
WORD32 band_width; /* targeted audio bandwidth in Hz */
WORD32 dual_mono; /* flag: make 2 SCEs for stereo input files */
WORD32 use_tns; /* flag: use temporal noise shaping */
WORD32 use_adts; /* flag: use ADTS instead of ADIF */
WORD32 calc_crc; /* flag: write CRC checks */
WORD32 private_bit; /* private bit of MPEG Header */
WORD32 copyright_bit; /* copyright bit of MPEG Header */
WORD32 original_copy_bit; /* original bit of MPEG Header */
WORD32 num_stereo_preprocessing; /* forbid usage of stereo prerpocessing */
WORD32 inv_quant; /* improve distortion by inverse quantization */
WORD32 full_bandwidth; /* improve distortion by inverse quantization */
WORD32 flag_framelength_small; /* indicates frame size. 0 -> 512, 1 -> 480
indicates frame size. 0 -> 1024, 1 -> 960 */
WORD32 bitreservoir_size; /* size of bit reservoir (default:0; max 6144)*/
} iaace_config;
typedef struct {
WORD32 *shared_buffer1;
WORD32 *shared_buffer_2;
WORD32 *shared_buffer3;
WORD8 *shared_buffer5;
} iaace_scratch;
/* pstr_ancillary configuration struct */
typedef struct {
WORD32 anc_flag;
WORD32 anc_mode;
WORD32 anc_rate;
} ixheaace_config_ancillary;
VOID ia_enhaacplus_enc_aac_init_default_config(iaace_config *config, WORD32 aot);
WORD32 ia_enhaacplus_enc_aac_enc_pers_size(WORD32 num_aac_chan, WORD32 aot);
WORD32 ia_enhaacplus_enc_aac_enc_scr_size(VOID);
VOID ia_enhaacplus_enc_init_aac_tabs(ixheaace_aac_tables *pstr_aac_tabs);

View file

@ -0,0 +1,43 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
/*
Remaining SBR Bit Writing Routines
*/
#pragma once
#define CRC_POLYNOMIAL_SBR (0x0233)
#define CRC_MASK_SBR (0x0200)
#define CRC_RANGE_SBR (0x03FF)
#define CRC_MAXREGS_SBR 1
#define CRCINIT_SBR (0x0)
#define SI_FIL_SBR 13
#define SI_FIL_CRC_SBR 14
#define SI_CRC_ENABLE_BITS_SBR 0
#define SI_CRC_BITS_SBR 10
#define SI_ID_BITS_AAC 3
#define SI_FILL_COUNT_BITS 4
#define SI_FILL_ESC_COUNT_BITS 8
#define SI_FILL_EXTENTION_BITS 4
#define ID_FIL 6
struct ixheaace_str_common_data;

View file

@ -0,0 +1,191 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
/*****************************************************************************/
/* Constant hashdefines */
/*****************************************************************************/
/*****************************************************************************/
/* Ittiam enhaacplus_enc ErrorCode Definitions */
/*****************************************************************************/
/*****************************************************************************/
/* Class 0: API Errors */
/*****************************************************************************/
/* Non Fatal Errors */
// AAC Profiles
// MPS
// USAC
// DRC
/* Fatal Errors */
// AAC Profiles
#define IA_EXHEAACE_API_FATAL_MEM_ALLOC (0xFFFF8000)
#define IA_EXHEAACE_API_FATAL_UNSUPPORTED_AOT (0xFFFF8001)
// MPS
// USAC
// DRC
/*****************************************************************************/
/* Class 1: Configuration Errors */
/*****************************************************************************/
/* Non Fatal Errors */
// AAC profiles
#define IA_EXHEAACE_CONFIG_NONFATAL_INVALID_CONFIG (0x00000800)
#define IA_EXHEAACE_CONFIG_NONFATAL_BITRES_SIZE_TOO_SMALL (0x00000801)
// MPS
#define IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG (0x00000900)
#define IA_EXHEAACE_CONFIG_NONFATAL_MPS_PARAM_ERROR (0x00000901)
// USAC
// DRC
/* Fatal Errors */
// AAC profiles
#define IA_EXHEAACE_CONFIG_FATAL_SAMP_FREQ (0xFFFF8800)
#define IA_EXHEAACE_CONFIG_FATAL_NUM_CHANNELS (0xFFFF8801)
#define IA_EXHEAACE_CONFIG_FATAL_USE_STEREO_PRE_PROC (0xFFFF8802)
#define IA_EXHEAACE_CONFIG_FATAL_QUALITY_LEVEL (0xFFFF8803)
#define IA_EXHEAACE_CONFIG_FATAL_PCM_WDSZ (0xFFFF8804)
#define IA_EXHEAACE_CONFIG_FATAL_AAC_CLASSIC_WITH_PS (0xFFFF8805)
#define IA_EXHEAACE_CONFIG_FATAL_AAC_CLASSIC (0xFFFF8806)
#define IA_EXHEAACE_CONFIG_FATAL_USE_TNS (0xFFFF8807)
#define IA_EXHEAACE_CONFIG_FATAL_CHANNELS_MASK (0xFFFF8808)
#define IA_EXHEAACE_CONFIG_FATAL_WRITE_PCE (0xFFFF8809)
#define IA_EXHEAACE_CONFIG_FATAL_USE_FULL_BANDWIDTH (0xFFFF880A)
#define IA_EXHEAACE_CONFIG_FATAL_USE_SPEECH_CONF (0xFFFF880B)
// MPS
// USAC
// DRC
/*****************************************************************************/
/* Class 2: Initialization Errors */
/*****************************************************************************/
/* Non Fatal Errors */
/* Fatal Errors */
// AAC Profiles
#define IA_EXHEAACE_INIT_FATAL_RESAMPLER_INIT_FAILED (0xFFFF9000)
#define IA_EXHEAACE_INIT_FATAL_AAC_INIT_FAILED (0xFFFF9001)
#define IA_EXHEAACE_INIT_FATAL_AACPLUS_NOT_AVAIL (0xFFFF9002)
#define IA_EXHEAACE_INIT_FATAL_BITRATE_NOT_SUPPORTED (0xFFFF9003)
#define IA_EXHEAACE_INIT_FATAL_INVALID_TNS_PARAM (0xFFFF9004)
#define IA_EXHEAACE_INIT_FATAL_SCALE_FACTOR_BAND_NOT_SUPPORTED (0xFFFF9005)
#define IA_EXHEAACE_INIT_FATAL_INVALID_CORE_SAMPLE_RATE (0xFFFF9006)
#define IA_EXHEAACE_INIT_FATAL_INVALID_BIT_RATE (0xFFFF9007)
#define IA_EXHEAACE_INIT_FATAL_INVALID_ELEMENT_TYPE (0xFFFF9008)
#define IA_EXHEAACE_INIT_FATAL_NUM_CHANNELS_NOT_SUPPORTED (0xFFFF9009)
#define IA_EXHEAACE_INIT_FATAL_INVALID_NUM_CHANNELS_IN_ELE (0xFFFF900A)
#define IA_EXHEAACE_INIT_FATAL_SFB_TABLE_INIT_FAILED (0xFFFF900B)
// MPS
#define IA_EXHEAACE_INIT_FATAL_MPS_INIT_FAILED (0xFFFF9100)
// USAC
// DRC
// SBR
#define IA_EXHEAACE_INIT_FATAL_SBR_INVALID_NUM_CHANNELS (0xFFFF9400)
#define IA_EXHEAACE_INIT_FATAL_SBR_INVALID_SAMPLERATE_MODE (0xFFFF9401)
#define IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS (0xFFFF9402)
#define IA_EXHEAACE_INIT_FATAL_SBR_INVALID_NUM_BANDS (0xFFFF9403)
#define IA_EXHEAACE_INIT_FATAL_SBR_INVALID_BUFFER_LENGTH (0xFFFF9404)
#define IA_EXEHAACE_INIT_FATAL_SBR_NOISE_BAND_NOT_SUPPORTED (0xFFFF9405)
/*****************************************************************************/
/* Class 3: Execution Errors */
/*****************************************************************************/
/* Non Fatal Errors */
// AAC Profiles
// MPS
#define IA_EXHEAACE_EXE_NONFATAL_MPS_ENCODE_ERROR (0x00001900)
#define IA_EXHEAACE_EXE_NONFATAL_MPS_INVALID_DATA_BANDS (0x00001901)
// USAC
// DRC
// ESBR
#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_BANDWIDTH_INDEX (0x0001C00)
#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_NUM_PATCH (0x0001C01)
#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_VOCOD_BUF (0x0001C02)
#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_PVC_MODE (0x0001C03)
#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_FFT (0x0001C04)
#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_START_BAND (0x0001C05)
#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_VALUE (0x0001C06)
/* Fatal Errors */
// AAC Profiles
#define IA_EXHEAACE_EXE_FATAL_SBR_INVALID_TIME_SLOTS (0xFFFF9800)
#define IA_EXHEAACE_EXE_FATAL_SBR_INVALID_IN_CHANNELS (0xFFFF9801)
#define IA_EXHEAACE_EXE_FATAL_PS_INVALID_HYBRID_RES_VAL (0xFFFF9802)
#define IA_EXHEAACE_EXE_FATAL_UNSUPPORTED_AOT (0xFFFF9803)
#define IA_EXHEAACE_EXE_FATAL_INVALID_BLOCK_TYPE (0xFFFF9804)
#define IA_EXHEAACE_EXE_FATAL_INVALID_SBR_FRAME_TYPE (0xFFFF9805)
#define IA_EXHEAACE_EXE_FATAL_INVALID_SBR_NUM_ENVELOPES (0xFFFF9806)
#define IA_EXHEAACE_EXE_FATAL_SBR_INVALID_NUM_BANDS (0xFFFF9807)
#define IA_EXHEAACE_EXE_FATAL_SBR_INVALID_BS (0xFFFF9808)
#define IA_EXHEAACE_EXE_FATAL_SBR_INVALID_CODEBOOK (0xFFFF9809)
#define IA_EXHEAACE_EXE_FATAL_INVALID_SCALE_FACTOR_GAIN (0xFFFF980A)
#define IA_EXHEAACE_EXE_FATAL_INVALID_BIT_RES_LEVEL (0xFFFF980B)
#define IA_EXHEAACE_EXE_FATAL_INVALID_BIT_CONSUMPTION (0xFFFF980C)
#define IA_EXHEAACE_EXE_FATAL_INVALID_SIDE_INFO_BITS (0xFFFF980D)
#define IA_EXHEAACE_EXE_FATAL_INVALID_HUFFMAN_BITS (0xFFFF980E)
#define IA_EXHEAACE_EXE_FATAL_INVALID_SCALE_FACTOR_BITS (0xFFFF980F)
#define IA_EXHAACE_EXE_FATAL_SBR_INVALID_AMP_RES (0xFFFF9810)
#define IA_EXHEAACE_EXE_FATAL_INVALID_OUT_BYTES (0xFFFF9811)
#define IA_EXHEAACE_EXE_FATAL_INVALID_TNS_FILT_ORDER (0xFFFF9812)
#define IA_EXHEAACE_EXE_FATAL_SBR_INVALID_SAMP_FREQ (0xFFFF9813)
// MPS
#define IA_EXHEAACE_EXE_FATAL_MPS_NULL_DATA_HANDLE (0xFFFF9900)
#define IA_EXHEAACE_EXE_FATAL_MPS_INVALID_HUFF_DATA_TYPE (0xFFFF9901)
#define IA_EXHEAACE_EXE_FATAL_MPS_INVALID_NUM_PARAM_SETS (0xFFFF9902)
#define IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_GUIDED_ENV_SHAPE (0xFFFF9903)
#define IA_EXHEAACE_EXE_FATAL_MPS_3D_STEREO_MODE_NOT_SUPPORTED (0xFFFF9904)
#define IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_RESIDUAL_CODING (0xFFFF9905)
#define IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_ARBITARY_DOWNMIX_CODING (0xFFFF9906)
#define IA_EXHEAACE_EXE_FATAL_MPS_ARBITARY_TREE_NOT_SUPPORTED (0xFFFF9907)
#define IA_EXHEAACE_EXE_FATAL_MPS_INVALID_QUANT_COARSE (0xFFFF9908)
#define IA_EXHEAACE_EXE_FATAL_MPS_INVALID_RES_STRIDE (0xFFFF9909)
#define IA_EXHEAACE_EXE_FATAL_MPS_INVALID_LEVELS (0xFFFF990A)
#define IA_EXHEAACE_EXE_FATAL_MPS_CFFT_PROCESS (0xFFFF990B)
// USAC
// DRC

View file

@ -0,0 +1,65 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#define IA_MAX_ERROR_SUB_CODE (70)
/* these definitions are used by error handling function */
/* the error handler will work on a structure which identifies a */
/* particular error with a module, context and error_code */
/* within error_code, MSB identifies FATAL (1), NONFATAL (0) */
/* next 4 ms_bs identify a class of error */
typedef struct {
pWORD8 pb_module_name;
pWORD8 ppb_class_names[16];
WORD8 **ppppb_error_msg_pointers[2][7][20];
} ia_error_info_struct;
/* this error handler maps the code generated by a module to a error string */
/* pb_context is a string to specify where the module broke */
IA_ERRORCODE ia_error_handler(ia_error_info_struct *p_mod_err_info, WORD8 *pb_context,
IA_ERRORCODE code);
/* the following macro does a line job of returning back to the parent */
/* in case a fatal error occurs after calling the errorhandler */
#define _IA_HANDLE_ERROR(p_mod_err_info, context, e, pv_output) \
if ((e) != IA_NO_ERROR) { \
ia_error_handler((p_mod_err_info), (context), (e)); \
if ((e)&IA_FATAL_ERROR) { \
IA_ERRORCODE err = IA_NO_ERROR; \
err = ixheaace_delete((pVOID)pv_output); \
if (pstr_in_cfg_user) { \
free(pstr_in_cfg_user); \
} \
if (pstr_enc_api) { \
free(pstr_enc_api); \
} \
if (ia_stsz_size != NULL) { \
free(ia_stsz_size); \
ia_stsz_size = NULL; \
} \
if ((err)&IA_FATAL_ERROR) { \
return (err); \
} else { \
return (e); \
} \
} \
}

2482
encoder/ixheaace_fft.c Normal file

File diff suppressed because it is too large Load diff

82
encoder/ixheaace_fft.h Normal file
View file

@ -0,0 +1,82 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#ifndef PI
#define PI (3.141592653589795)
#endif
#define LS_TRANS_128 448 //((long_frame_len - FRAME_LEN_SHORT_128) / 2)
#define LS_TRANS_120 420
#define DIG_REV(i, m, j) \
do { \
unsigned _ = (i); \
_ = ((_ & 0x33333333) << 2) | ((_ & ~0x33333333) >> 2); \
_ = ((_ & 0x0F0F0F0F) << 4) | ((_ & ~0x0F0F0F0F) >> 4); \
_ = ((_ & 0x00FF00FF) << 8) | ((_ & ~0x00FF00FF) >> 8); \
_ = ((_ & 0x0000FFFF) << 16) | ((_ & ~0x0000FFFF) >> 16); \
(j) = _ >> (m); \
} while (0)
#define DIG_REV_NEW(i, m, j) \
do { \
unsigned _ = (i); \
_ = ((_ & 0x33333333) << 2) | ((_ & ~0x33333333) >> 2); \
_ = ((_ & 0x0F0F0F0F) << 4) | ((_ & ~0x0F0F0F0F) >> 4); \
_ = ((_ & 0x00FF00FF) << 8) | ((_ & ~0x00FF00FF) >> 8); \
(j) = _ >> (m); \
} while (0)
typedef struct {
FLOAT32 p_fft_p2_y[2048];
FLOAT32 p_fft_p3_data_3[800];
FLOAT32 p_fft_p3_y[2048];
} ixheaace_scratch_mem;
VOID ia_enhaacplus_enc_complex_fft(FLOAT32 *ptr_data, WORD32 len,
ixheaace_scratch_mem *pstr_scratch);
VOID ia_eaacp_enc_pre_twiddle_aac(FLOAT32 *ptr_x, FLOAT32 *ptr_data, WORD32 n,
const FLOAT32 *ptr_cos_array);
VOID ia_enhaacplus_enc_post_twiddle(FLOAT32 *ptr_out, FLOAT32 *ptr_x,
const FLOAT32 *ptr_cos_sin_tbl, WORD m);
VOID ia_aac_ld_enc_mdct_480(FLOAT32 *ptr_inp, FLOAT32 *ptr_scratch, WORD32 mdct_flag,
ixheaace_mdct_tables *pstr_mdct_tables);
VOID ia_enhaacplus_enc_complex_fft_p2(FLOAT32 *ptr_x, WORD32 nlength,
FLOAT32 *ptr_scratch_fft_p2_y);
VOID ixheaace_transform_real_lc_ld(FLOAT32 *ptr_mdct_delay_buffer, const FLOAT32 *ptr_time_signal,
WORD32 ch_increment, FLOAT32 *ptr_real_out, WORD32 block_type,
WORD32 frame_len, WORD8 *ptr_scratch);
VOID ia_enhaacplus_enc_transform_real_eld(FLOAT32 *ptr_mdct_delay_buffer,
const FLOAT32 *ptr_time_signal, WORD32 ch_increment,
FLOAT32 *ptr_real_out, WORD8 *ptr_shared_buffer5,
WORD32 frame_len);
VOID ia_enhaacplus_enc_transform_real(FLOAT32 *ptr_mdct_delay_buffer,
const FLOAT32 *ptr_time_signal, WORD32 ch_increment,
FLOAT32 *ptr_real_out, ixheaace_mdct_tables *pstr_mdct_tab,
FLOAT32 *ptr_shared_buffer1, WORD8 *ptr_shared_buffer5,
WORD32 long_frame_len);

View file

@ -0,0 +1,193 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include <stdlib.h>
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaace_enc_main.h"
#include "ixheaace_block_switch.h"
#include "ixheaace_psy_data.h"
#include "ixheaace_interface.h"
#include "ixheaace_group_data.h"
#include "ixheaace_aac_constants.h"
#include "ixheaac_basic_ops32.h"
#include "ixheaac_basic_ops16.h"
#include "ixheaac_basic_ops40.h"
#include "ixheaac_basic_ops.h"
VOID iaace_group_short_data(FLOAT32 *ptr_mdct_spectrum, FLOAT32 *ptr_tmp_spectrum,
ixheaace_sfb_energy *pstr_sfb_threshold,
ixheaace_sfb_energy *pstr_sfb_energy,
ixheaace_sfb_energy *pstr_sfb_energy_ms,
ixheaace_sfb_energy *pstr_sfb_spreaded_energy, const WORD32 sfb_cnt,
const WORD32 *ptr_sfb_offset, const FLOAT32 *ptr_sfb_min_snr,
WORD32 *ptr_grouped_sfb_offset, WORD32 *ptr_max_sfb_per_group,
FLOAT32 *ptr_grouped_sfb_min_snr, const WORD32 no_of_groups,
const WORD32 *ptr_group_len, WORD32 frame_length) {
WORD32 i, j;
WORD32 line;
WORD32 sfb;
WORD32 grp;
WORD32 wnd;
WORD32 offset;
WORD32 highest_sfb;
/* For short: regroup and cumulate energies und thresholds group-wise */
/* Calculate sfb_cnt */
highest_sfb = 0;
for (wnd = 0; wnd < TRANS_FAC; wnd++) {
for (sfb = sfb_cnt - 1; sfb >= highest_sfb; sfb--) {
for (line = ptr_sfb_offset[sfb + 1] - 1; line >= ptr_sfb_offset[sfb]; line--) {
if (ptr_mdct_spectrum[wnd * (frame_length / 8) + line] != 0.0) {
break;
}
}
if (line >= ptr_sfb_offset[sfb]) {
break;
}
}
highest_sfb = MAX(highest_sfb, sfb);
}
highest_sfb = highest_sfb > 0 ? highest_sfb : 0;
*ptr_max_sfb_per_group = highest_sfb + 1;
/* Calculate ptr_sfb_offset */
i = 0;
offset = 0;
for (grp = 0; grp < no_of_groups; grp++) {
for (sfb = 0; sfb < sfb_cnt; sfb++) {
ptr_grouped_sfb_offset[i++] = offset + ptr_sfb_offset[sfb] * ptr_group_len[grp];
}
offset += ptr_group_len[grp] * (frame_length / 8);
}
ptr_grouped_sfb_offset[i++] = frame_length;
/* Calculate min SNR */
i = 0;
offset = 0;
for (grp = 0; grp < no_of_groups; grp++) {
memcpy(&ptr_grouped_sfb_min_snr[i], &ptr_sfb_min_snr[0], sfb_cnt * sizeof(*ptr_sfb_min_snr));
i += sfb_cnt;
offset += ptr_group_len[grp] * (frame_length / 8);
}
wnd = 0;
i = 0;
for (grp = 0; grp < no_of_groups; grp++) {
for (sfb = 0; sfb < sfb_cnt; sfb++) {
FLOAT32 thresh = pstr_sfb_threshold->short_nrg[wnd][sfb];
for (j = 1; j < ptr_group_len[grp]; j++) {
thresh += pstr_sfb_threshold->short_nrg[wnd + j][sfb];
}
pstr_sfb_threshold->long_nrg[i++] = thresh;
}
wnd += ptr_group_len[grp];
}
/* Sum up sfb energies - left/right */
wnd = 0;
i = 0;
for (grp = 0; grp < no_of_groups; grp++) {
for (sfb = 0; sfb < sfb_cnt; sfb++) {
FLOAT32 energy = pstr_sfb_energy->short_nrg[wnd][sfb];
for (j = 1; j < ptr_group_len[grp]; j++) {
energy += pstr_sfb_energy->short_nrg[wnd + j][sfb];
}
pstr_sfb_energy->long_nrg[i++] = energy;
}
wnd += ptr_group_len[grp];
}
/* Sum up sfb energies mid/side */
wnd = 0;
i = 0;
for (grp = 0; grp < no_of_groups; grp++) {
for (sfb = 0; sfb < sfb_cnt; sfb++) {
FLOAT32 energy = pstr_sfb_energy_ms->short_nrg[wnd][sfb];
for (j = 1; j < ptr_group_len[grp]; j++) {
energy += pstr_sfb_energy_ms->short_nrg[wnd + j][sfb];
}
pstr_sfb_energy_ms->long_nrg[i++] = energy;
}
wnd += ptr_group_len[grp];
}
/* Sum up sfb spreaded energies */
wnd = 0;
i = 0;
for (grp = 0; grp < no_of_groups; grp++) {
for (sfb = 0; sfb < sfb_cnt; sfb++) {
FLOAT32 energy = pstr_sfb_spreaded_energy->short_nrg[wnd][sfb];
for (j = 1; j < ptr_group_len[grp]; j++) {
energy += pstr_sfb_spreaded_energy->short_nrg[wnd + j][sfb];
}
pstr_sfb_spreaded_energy->long_nrg[i++] = energy;
}
wnd += ptr_group_len[grp];
}
/* Re-group spectrum */
wnd = 0;
i = 0;
for (grp = 0; grp < no_of_groups; grp++) {
for (sfb = 0; sfb < sfb_cnt; sfb++) {
for (j = 0; j < ptr_group_len[grp]; j++) {
for (line = ptr_sfb_offset[sfb]; line < ptr_sfb_offset[sfb + 1]; line++) {
ptr_tmp_spectrum[i++] = ptr_mdct_spectrum[(wnd + j) * (frame_length / 8) + line];
}
}
}
wnd += ptr_group_len[grp];
}
memcpy(ptr_mdct_spectrum, ptr_tmp_spectrum, frame_length * sizeof(*ptr_mdct_spectrum));
}

View file

@ -0,0 +1,31 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
VOID iaace_group_short_data(FLOAT32 *ptr_mdct_spectrum, FLOAT32 *ptr_tmp_spectrum,
ixheaace_sfb_energy *pstr_sfb_threshold,
ixheaace_sfb_energy *pstr_sfb_energy,
ixheaace_sfb_energy *pstr_sfb_energy_ms,
ixheaace_sfb_energy *pstr_sfb_spreaded_energy, const WORD32 sfb_cnt,
const WORD32 *ptr_sfb_offset, const FLOAT32 *ptr_sfb_min_snr,
WORD32 *ptr_grouped_sfb_offset, WORD32 *ptr_max_sfb_per_group,
FLOAT32 *ptr_grouped_sfb_min_snr, const WORD32 no_of_groups,
const WORD32 *ptr_group_len, WORD32 frame_length);

View file

@ -0,0 +1,45 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include "iusace_type_def.h"
const WORD32 iusace_huffman_code_table[121][2] = {
{18, 262120}, {18, 262118}, {18, 262119}, {18, 262117}, {19, 524277}, {19, 524273},
{19, 524269}, {19, 524278}, {19, 524270}, {19, 524271}, {19, 524272}, {19, 524284},
{19, 524285}, {19, 524287}, {19, 524286}, {19, 524279}, {19, 524280}, {19, 524283},
{19, 524281}, {18, 262116}, {19, 524282}, {18, 262115}, {17, 131055}, {17, 131056},
{16, 65525}, {17, 131054}, {16, 65522}, {16, 65523}, {16, 65524}, {16, 65521},
{15, 32758}, {15, 32759}, {14, 16377}, {14, 16373}, {14, 16375}, {14, 16371},
{14, 16374}, {14, 16370}, {13, 8183}, {13, 8181}, {12, 4089}, {12, 4087},
{12, 4086}, {11, 2041}, {12, 4084}, {11, 2040}, {10, 1017}, {10, 1015},
{10, 1013}, {9, 504}, {9, 503}, {8, 250}, {8, 248}, {8, 246},
{7, 121}, {6, 58}, {6, 56}, {5, 26}, {4, 11}, {3, 4},
{1, 0}, {4, 10}, {4, 12}, {5, 27}, {6, 57}, {6, 59},
{7, 120}, {7, 122}, {8, 247}, {8, 249}, {9, 502}, {9, 505},
{10, 1012}, {10, 1014}, {10, 1016}, {11, 2037}, {11, 2036}, {11, 2038},
{11, 2039}, {12, 4085}, {12, 4088}, {13, 8180}, {13, 8182}, {13, 8184},
{14, 16376}, {14, 16372}, {16, 65520}, {15, 32756}, {16, 65526}, {15, 32757},
{18, 262114}, {19, 524249}, {19, 524250}, {19, 524251}, {19, 524252}, {19, 524253},
{19, 524254}, {19, 524248}, {19, 524242}, {19, 524243}, {19, 524244}, {19, 524245},
{19, 524246}, {19, 524274}, {19, 524255}, {19, 524263}, {19, 524264}, {19, 524265},
{19, 524266}, {19, 524267}, {19, 524262}, {19, 524256}, {19, 524257}, {19, 524258},
{19, 524259}, {19, 524260}, {19, 524261}, {19, 524247}, {19, 524268}, {19, 524276},
{19, 524275},
};

370
encoder/ixheaace_hybrid.c Normal file
View file

@ -0,0 +1,370 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include "ixheaac_type_def.h"
#include "ixheaac_error_standards.h"
#include "ixheaace_error_codes.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_sbr_def.h"
#include "ixheaace_resampler.h"
#include "ixheaace_sbr_rom.h"
#include "ixheaace_sbr_hybrid.h"
#include "ixheaace_aac_constants.h"
VOID ia_enhaacplus_enc_fft(complex *out, WORD32 N, ixheaace_common_tables *);
static VOID ixheaace_four_chan_filtering(const FLOAT32 *ptr_qmf_real, const FLOAT32 *ptr_qmf_imag,
FLOAT32 **ptr_hyb_real, FLOAT32 **ptr_hyb_imag,
WORD32 ch_offset, const FLOAT32 *ptr_p4_13,
ixheaace_common_tables *pstr_common_tab) {
WORD32 i, k, n;
WORD32 mid_tap = IXHEAACE_HYBRID_FILTER_DELAY;
FLOAT32 cum[8], *ptr_cum;
FLOAT32 tmp1, tmp2, tmp_p4;
FLOAT32 real, imag;
const FLOAT32 *ptr_re, *ptr_im;
FLOAT32 *ptr_hy_im, *ptr_hy_re;
ptr_re = &ptr_qmf_real[0];
ptr_im = &ptr_qmf_imag[0];
ptr_hy_re = &ptr_hyb_real[0][ch_offset];
ptr_hy_im = &ptr_hyb_imag[0][ch_offset];
for (i = IXHEAACE_QMF_TIME_SLOTS - 1; i >= 0; i--) {
real = imag = 0;
for (k = 0; k < 16; k += 4) {
tmp_p4 = ptr_p4_13[k];
tmp1 = ptr_re[k];
tmp2 = ptr_im[k];
tmp1 = tmp_p4 * tmp1;
real = real - tmp1;
tmp1 = tmp_p4 * tmp2;
imag = imag + tmp1;
}
cum[3] = imag;
cum[2] = real;
real = imag = 0;
for (k = 3; k < 15; k += 4) {
tmp_p4 = ptr_p4_13[k];
tmp1 = ptr_re[k];
tmp2 = ptr_im[k];
tmp1 = tmp_p4 * tmp1;
real = real + tmp1;
tmp1 = tmp_p4 * tmp2;
imag = imag + tmp1;
}
tmp1 = imag + real;
cum[7] = tmp1 * IXHEAACE_COS_PI_BY_4;
tmp1 = imag - real;
cum[6] = tmp1 * IXHEAACE_COS_PI_BY_4;
cum[1] = ptr_p4_13[mid_tap] * ptr_re[mid_tap];
cum[0] = ptr_p4_13[mid_tap] * ptr_im[mid_tap];
real = imag = 0;
for (k = 1; k < 13; k += 4) {
tmp_p4 = ptr_p4_13[k];
tmp1 = ptr_re[k];
tmp2 = ptr_im[k];
tmp1 = tmp_p4 * tmp1;
real = real + tmp1;
tmp1 = tmp_p4 * tmp2;
imag = imag + tmp1;
}
tmp1 = real - imag;
cum[5] = tmp1 * IXHEAACE_COS_PI_BY_4;
tmp1 = real + imag;
cum[4] = tmp1 * IXHEAACE_COS_PI_BY_4;
ia_enhaacplus_enc_fft((complex *)cum, 4, pstr_common_tab);
ptr_cum = &cum[0];
for (n = 3; n >= 0; n--) {
tmp1 = *ptr_cum++;
tmp2 = *ptr_cum++;
*ptr_hy_im++ = tmp1;
*ptr_hy_re++ = tmp2;
}
ptr_re++;
ptr_im++;
ptr_hy_re += IXHEAACE_QMF_TIME_SLOTS - 4;
ptr_hy_im += IXHEAACE_QMF_TIME_SLOTS - 4;
}
}
static VOID ixheaace_eight_chan_filtering(const FLOAT32 *ptr_qmf_real,
const FLOAT32 *ptr_qmf_imag, FLOAT32 **ptr_hyb_real,
FLOAT32 **ptr_hyb_imag, const FLOAT32 *ptr_p8_13,
ixheaace_common_tables *pstr_common_tab)
{
LOOPINDEX i, n;
LOOPINDEX mid_tap = IXHEAACE_HYBRID_FILTER_DELAY;
FLOAT32 real, imag;
FLOAT32 cum[16], *ptr_cum;
FLOAT32 tmp1, tmp2, tmp3;
const FLOAT32 *ptr_re, *ptr_im;
FLOAT32 *ptr_hy_re, *ptr_hy_im;
ptr_re = &ptr_qmf_real[0];
ptr_im = &ptr_qmf_imag[0];
ptr_hy_re = &ptr_hyb_real[0][0];
ptr_hy_im = &ptr_hyb_imag[0][0];
for (i = IXHEAACE_QMF_TIME_SLOTS - 1; i >= 0; i--) {
tmp1 = ptr_p8_13[4] * ptr_re[4];
tmp2 = ptr_p8_13[12] * ptr_re[12];
tmp3 = ptr_im[4];
real = tmp1 + tmp2;
tmp2 = ptr_im[12];
tmp1 = ptr_p8_13[4] * tmp3;
tmp2 = ptr_p8_13[12] * tmp2;
imag = tmp1 + tmp2;
tmp1 = imag - real;
cum[5] = tmp1 * IXHEAACE_COS_PI_BY_4;
tmp1 = imag + real;
tmp3 = ptr_re[3];
cum[4] = -tmp1 * IXHEAACE_COS_PI_BY_4;
tmp2 = ptr_re[11];
tmp1 = ptr_p8_13[3] * tmp3;
tmp2 = ptr_p8_13[11] * tmp2;
tmp3 = ptr_im[3];
real = tmp1 + tmp2;
tmp2 = ptr_im[11];
tmp1 = ptr_p8_13[3] * tmp3;
tmp2 = ptr_p8_13[11] * tmp2;
imag = tmp1 + tmp2;
tmp1 = imag * IXHEAACE_COS_PI_BY_8;
tmp2 = real * IXHEAACE_SIN_PI_BY_8;
cum[13] = tmp1 - tmp2;
tmp1 = imag * IXHEAACE_SIN_PI_BY_8;
tmp2 = real * IXHEAACE_COS_PI_BY_8;
tmp3 = ptr_re[2];
cum[12] = -tmp1 - tmp2;
tmp2 = ptr_re[10];
tmp1 = ptr_p8_13[2] * tmp3;
tmp2 = ptr_p8_13[10] * tmp2;
tmp3 = ptr_im[2];
cum[2] = -tmp1 - tmp2;
tmp2 = ptr_im[10];
tmp1 = ptr_p8_13[2] * tmp3;
tmp2 = ptr_p8_13[10] * tmp2;
cum[3] = tmp1 + tmp2;
tmp1 = ptr_p8_13[1] * ptr_re[1];
tmp2 = ptr_p8_13[9] * ptr_re[9];
real = tmp1 + tmp2;
tmp1 = ptr_p8_13[1] * ptr_im[1];
tmp2 = ptr_p8_13[9] * ptr_im[9];
imag = tmp1 + tmp2;
tmp1 = imag * IXHEAACE_COS_PI_BY_8;
tmp2 = real * IXHEAACE_SIN_PI_BY_8;
cum[11] = tmp1 + tmp2;
tmp1 = imag * IXHEAACE_SIN_PI_BY_8;
tmp2 = real * IXHEAACE_COS_PI_BY_8;
cum[10] = tmp1 - tmp2;
tmp1 = ptr_p8_13[0] * ptr_re[0];
tmp2 = ptr_p8_13[8] * ptr_re[8];
real = tmp1 + tmp2;
tmp1 = ptr_p8_13[0] * ptr_im[0];
tmp2 = ptr_p8_13[8] * ptr_im[8];
imag = tmp1 + tmp2;
tmp1 = imag + real;
cum[7] = tmp1 * IXHEAACE_COS_PI_BY_4;
tmp1 = imag - real;
cum[6] = tmp1 * IXHEAACE_COS_PI_BY_4;
real = ptr_p8_13[7] * ptr_re[7];
imag = ptr_p8_13[7] * ptr_im[7];
tmp1 = imag * IXHEAACE_SIN_PI_BY_8;
tmp2 = real * IXHEAACE_COS_PI_BY_8;
cum[15] = tmp1 + tmp2;
tmp1 = imag * IXHEAACE_COS_PI_BY_8;
tmp2 = real * IXHEAACE_SIN_PI_BY_8;
cum[14] = tmp1 - tmp2;
cum[1] = ptr_p8_13[mid_tap] * ptr_re[mid_tap];
cum[0] = ptr_p8_13[mid_tap] * ptr_im[mid_tap];
real = ptr_p8_13[5] * ptr_re[5];
imag = ptr_p8_13[5] * ptr_im[5];
tmp1 = real * IXHEAACE_COS_PI_BY_8;
tmp2 = imag * IXHEAACE_SIN_PI_BY_8;
cum[9] = tmp1 - tmp2;
tmp1 = real * IXHEAACE_SIN_PI_BY_8;
tmp2 = imag * IXHEAACE_COS_PI_BY_8;
cum[8] = tmp1 + tmp2;
ia_enhaacplus_enc_fft((complex *)cum, 8, pstr_common_tab);
ptr_cum = &cum[0];
for (n = 7; n >= 0; n--) {
tmp1 = *ptr_cum++;
tmp2 = *ptr_cum++;
*ptr_hy_im++ = tmp1;
*ptr_hy_re++ = tmp2;
}
ptr_re++;
ptr_im++;
ptr_hy_re += IXHEAACE_QMF_TIME_SLOTS - 8;
ptr_hy_im += IXHEAACE_QMF_TIME_SLOTS - 8;
}
}
IA_ERRORCODE ixheaace_hybrid_analysis(const FLOAT32 **ptr_qmf_real_in,
const FLOAT32 **ptr_qmf_imag_in, FLOAT32 **ptr_hyb_real_in,
FLOAT32 **ptr_hyb_imag_in, ixheaace_pstr_hybrid pstr_hybrid,
ixheaace_str_ps_tab *pstr_ps_tab,
ixheaace_common_tables *pstr_common_tab) {
WORD32 band, i;
ixheaace_hybrid_res hybrid_res;
WORD32 ch_offset = 0;
FLOAT32 *ptr_re, *ptr_im;
const FLOAT32 *ptr_qmf_real, *ptr_qmf_imag;
FLOAT32 tmp1, tmp2;
for (band = 0; band < IXHEAACE_NUM_QMF_BANDS_IN_HYBRID; band++) {
hybrid_res = (ixheaace_hybrid_res)pstr_ps_tab->a_hyb_res[band];
memcpy(pstr_hybrid->ptr_work_real, pstr_hybrid->ptr_qmf_buf_real[band],
IXHEAACE_QMF_BUFFER_MOVE * sizeof(FLOAT32));
memcpy(pstr_hybrid->ptr_work_imag, pstr_hybrid->ptr_qmf_buf_imag[band],
IXHEAACE_QMF_BUFFER_MOVE * sizeof(FLOAT32));
ptr_re = &pstr_hybrid->ptr_work_real[IXHEAACE_QMF_BUFFER_MOVE];
ptr_im = &pstr_hybrid->ptr_work_imag[IXHEAACE_QMF_BUFFER_MOVE];
ptr_qmf_real = &ptr_qmf_real_in[0][band];
ptr_qmf_imag = &ptr_qmf_imag_in[0][band];
for (i = IXHEAACE_QMF_TIME_SLOTS - 1; i >= 0; i--) {
tmp1 = *ptr_qmf_real;
tmp2 = *ptr_qmf_imag;
ptr_qmf_real += IXHEAACE_QMF_CHANNELS;
ptr_qmf_imag += IXHEAACE_QMF_CHANNELS;
*ptr_im++ = tmp2;
*ptr_re++ = tmp1;
}
ptr_re = &pstr_hybrid->ptr_qmf_buf_real[band][0];
ptr_im = &pstr_hybrid->ptr_qmf_buf_imag[band][0];
ptr_qmf_real = &ptr_qmf_real_in[IXHEAACE_QMF_TIME_SLOTS - IXHEAACE_QMF_BUFFER_MOVE][band];
ptr_qmf_imag = &ptr_qmf_imag_in[IXHEAACE_QMF_TIME_SLOTS - IXHEAACE_QMF_BUFFER_MOVE][band];
for (i = 0; i < IXHEAACE_QMF_BUFFER_MOVE; i++) {
tmp1 = *ptr_qmf_real;
ptr_qmf_real += IXHEAACE_QMF_CHANNELS;
tmp2 = *ptr_qmf_imag;
ptr_qmf_imag += IXHEAACE_QMF_CHANNELS;
*ptr_re++ = tmp1;
*ptr_im++ = tmp2;
}
switch (hybrid_res) {
case IXHEAACE_HYBRID_4_CPLX:
ixheaace_four_chan_filtering(pstr_hybrid->ptr_work_real, pstr_hybrid->ptr_work_imag,
ptr_hyb_real_in, ptr_hyb_imag_in, ch_offset,
pstr_ps_tab->p4_13, pstr_common_tab);
break;
case IXHEAACE_HYBRID_8_CPLX:
ixheaace_eight_chan_filtering(pstr_hybrid->ptr_work_real, pstr_hybrid->ptr_work_imag,
ptr_hyb_real_in, ptr_hyb_imag_in, pstr_ps_tab->p8_13,
pstr_common_tab);
break;
default:
return IA_EXHEAACE_EXE_FATAL_PS_INVALID_HYBRID_RES_VAL;
break;
}
ch_offset += hybrid_res;
}
return IA_NO_ERROR;
}
VOID ixheaace_hybrid_synthesis(const FLOAT32 **ptr_hybrid_real_flt,
const FLOAT32 **ptr_hybrid_imag_flt, FLOAT32 **ptr_qmf_real_flt,
FLOAT32 **ptr_qmf_imag_flt, const WORD32 *ptr_hyb_res) {
WORD32 k, n, band;
ixheaace_hybrid_res hybrid_res;
WORD32 chOffset = 0;
FLOAT32 temp1, temp2;
FLOAT32 *ptr_qmf_real;
FLOAT32 *ptr_qmf_imag;
for (band = 0; band < IXHEAACE_NUM_QMF_BANDS_IN_HYBRID; band++) {
const FLOAT32 *ptr_hybrid_real = &ptr_hybrid_real_flt[0][chOffset];
const FLOAT32 *ptr_hybrid_imag = &ptr_hybrid_imag_flt[0][chOffset];
hybrid_res = (ixheaace_hybrid_res)ptr_hyb_res[band];
ptr_qmf_real = &ptr_qmf_real_flt[0][band];
ptr_qmf_imag = &ptr_qmf_imag_flt[0][band];
for (n = 0; n < IXHEAACE_QMF_TIME_SLOTS; n++) {
FLOAT32 temo_real = 0, temo_imag = 0;
for (k = hybrid_res - 1; k >= 0; k--) {
temp1 = *ptr_hybrid_real++;
temp2 = *ptr_hybrid_imag++;
temo_real += temp1;
temo_imag += temp2;
}
ptr_hybrid_real += IXHEAACE_QMF_TIME_SLOTS - hybrid_res;
ptr_hybrid_imag += IXHEAACE_QMF_TIME_SLOTS - hybrid_res;
*ptr_qmf_real = temo_real;
ptr_qmf_real += IXHEAACE_QMF_CHANNELS;
*ptr_qmf_imag = temo_imag;
ptr_qmf_imag += IXHEAACE_QMF_CHANNELS;
}
chOffset += hybrid_res;
}
}

View file

@ -0,0 +1,65 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include "ixheaac_type_def.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_sbr_def.h"
#include "ixheaace_resampler.h"
#include "ixheaace_sbr_rom.h"
#include "ixheaace_sbr_hybrid.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
WORD32
ixheaace_create_hybrid_filter_bank(ixheaace_pstr_hybrid pstr_hybrid, FLOAT32 **pptr_flt) {
LOOPINDEX i;
FLOAT32 *ptr_flt = *pptr_flt;
pstr_hybrid->ptr_work_real = ptr_flt;
ptr_flt += (IXHEAACE_QMF_TIME_SLOTS + IXHEAACE_QMF_BUFFER_MOVE);
pstr_hybrid->ptr_work_imag = ptr_flt;
ptr_flt += (IXHEAACE_QMF_TIME_SLOTS + IXHEAACE_QMF_BUFFER_MOVE);
pstr_hybrid->ptr_qmf_buf_real = (FLOAT32 **)ptr_flt;
ptr_flt += IXHEAACE_NUM_QMF_BANDS_IN_HYBRID * sizeof(FLOAT32 *) / sizeof(FLOAT32);
pstr_hybrid->ptr_qmf_buf_imag = (FLOAT32 **)ptr_flt;
ptr_flt += IXHEAACE_NUM_QMF_BANDS_IN_HYBRID * sizeof(FLOAT32 *) / sizeof(FLOAT32);
for (i = 0; i < IXHEAACE_NUM_QMF_BANDS_IN_HYBRID; i++) {
pstr_hybrid->ptr_qmf_buf_real[i] = ptr_flt;
ptr_flt += IXHEAACE_QMF_BUFFER_MOVE;
memset(pstr_hybrid->ptr_qmf_buf_real[i], 0,
IXHEAACE_QMF_BUFFER_MOVE * sizeof(pstr_hybrid->ptr_qmf_buf_real[0]));
pstr_hybrid->ptr_qmf_buf_imag[i] = ptr_flt;
ptr_flt += IXHEAACE_QMF_BUFFER_MOVE;
memset(pstr_hybrid->ptr_qmf_buf_imag[i], 0,
IXHEAACE_QMF_BUFFER_MOVE * sizeof(pstr_hybrid->ptr_qmf_buf_imag[0]));
}
*pptr_flt = ptr_flt;
return 0;
}

View file

@ -0,0 +1,94 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaace_enc_main.h"
#include "ixheaace_block_switch.h"
#include "ixheaace_psy_data.h"
#include "ixheaace_interface.h"
VOID ia_enhaacplus_enc_build_interface(
FLOAT32 *ptr_grouped_mdct_spec, ixheaace_sfb_energy *pstr_grouped_sfb_thres,
ixheaace_sfb_energy *pstr_grouped_sfb_nrg, ixheaace_sfb_energy *pstr_grouped_sfb_spreaded_nrg,
const ixheaace_sfb_energy_sum sfb_nrg_sum_lr, const ixheaace_sfb_energy_sum sfb_nrg_sum_ms,
const WORD32 win_seq, const WORD32 win_shape, const WORD32 grouped_sfb_cnt,
const WORD32 *ptr_grouped_sfb_offset, const WORD32 max_sfb_per_grp,
const FLOAT32 *ptr_grouped_sfb_min_snr, const WORD32 total_groups_cnt,
const WORD32 *ptr_group_len, ixheaace_psy_out_channel *pstr_psy_out_ch) {
WORD32 j;
WORD32 grp;
WORD32 mask;
/* Copy values to psy_out */
pstr_psy_out_ch->max_sfb_per_grp = max_sfb_per_grp;
pstr_psy_out_ch->sfb_count = grouped_sfb_cnt;
pstr_psy_out_ch->sfb_per_group = grouped_sfb_cnt / total_groups_cnt;
pstr_psy_out_ch->window_sequence = win_seq;
pstr_psy_out_ch->window_shape = win_shape;
pstr_psy_out_ch->ptr_spec_coeffs = ptr_grouped_mdct_spec;
pstr_psy_out_ch->ptr_sfb_energy = pstr_grouped_sfb_nrg->long_nrg;
pstr_psy_out_ch->ptr_sfb_thr = pstr_grouped_sfb_thres->long_nrg;
pstr_psy_out_ch->ptr_sfb_spread_energy = pstr_grouped_sfb_spreaded_nrg->long_nrg;
memcpy(&pstr_psy_out_ch->sfb_offsets[0], &ptr_grouped_sfb_offset[0],
sizeof(pstr_psy_out_ch->sfb_offsets[0]) * (grouped_sfb_cnt + 1));
memcpy(&pstr_psy_out_ch->sfb_min_snr[0], &ptr_grouped_sfb_min_snr[0],
sizeof(pstr_psy_out_ch->sfb_min_snr[0]) * (grouped_sfb_cnt));
/* Generate grouping mask */
mask = 0;
for (grp = 0; grp < total_groups_cnt; grp++) {
mask <<= 1;
for (j = 1; j < ptr_group_len[grp]; j++) {
mask <<= 1;
mask |= 1;
}
}
/* copy energy sums to psy_out for stereo preprocessing */
if (win_seq != SHORT_WINDOW) {
pstr_psy_out_ch->sfb_sum_lr_energy = sfb_nrg_sum_lr.long_nrg;
pstr_psy_out_ch->sfb_sum_ms_energy = sfb_nrg_sum_ms.long_nrg;
} else {
int i;
pstr_psy_out_ch->sfb_sum_ms_energy = 0;
pstr_psy_out_ch->sfb_sum_lr_energy = 0;
for (i = 0; i < TRANS_FAC; i++) {
pstr_psy_out_ch->sfb_sum_lr_energy += sfb_nrg_sum_lr.short_nrg[i];
pstr_psy_out_ch->sfb_sum_ms_energy += sfb_nrg_sum_ms.short_nrg[i];
}
}
pstr_psy_out_ch->grouping_mask = mask;
}

View file

@ -0,0 +1,71 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
enum { MS_NONE = 0, MS_SOME = 1, MS_ALL = 2 };
enum { MS_ON = 1 };
typedef struct {
WORD32 ms_digest; /* 0 = no MS; 1 = some MS, 2 = all MS */
WORD32 ms_mask[MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
} ixheaace_tools_info;
typedef struct {
WORD32 sfb_count;
WORD32 sfb_per_group;
WORD32 max_sfb_per_grp;
WORD32 window_sequence;
WORD32 window_shape;
WORD32 grouping_mask;
WORD32 sfb_offsets[MAXIMUM_GROUPED_SCALE_FACTOR_BAND + 1];
FLOAT32 *ptr_sfb_energy;
FLOAT32 *ptr_sfb_spread_energy;
FLOAT32 *ptr_sfb_thr;
FLOAT32 *ptr_spec_coeffs;
FLOAT32 sfb_sum_ms_energy;
FLOAT32 sfb_sum_lr_energy;
FLOAT32 pe;
FLOAT32 sfb_min_snr[MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
WORD32 ms_digest; /* 0 = no MS; 1 = some MS, 2 = all MS */
WORD32 ms_used[MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
ixheaace_temporal_noise_shaping_params tns_info;
} ixheaace_psy_out_channel;
typedef struct {
ixheaace_tools_info tools_info;
FLOAT32 weight_ms_lr_pe_ratio;
} ixheaace_psy_out_element;
typedef struct {
/* information shared by both channels */
ixheaace_psy_out_element psy_out_element;
/* information specific to each channel */
ixheaace_psy_out_channel *psy_out_ch[IXHEAACE_MAX_CH_IN_BS_ELE];
} ixheaace_psy_out;
VOID ia_enhaacplus_enc_build_interface(
FLOAT32 *ptr_grouped_mdct_spec, ixheaace_sfb_energy *ptr_grouped_sfb_thres,
ixheaace_sfb_energy *ptr_grouped_sfb_nrg, ixheaace_sfb_energy *ptr_grouped_sfb_spreaded_nrg,
const ixheaace_sfb_energy_sum sfb_nrg_sum_lr, const ixheaace_sfb_energy_sum sfb_nrg_sum_ms,
const WORD32 win_seq, const WORD32 win_shape, const WORD32 grouped_sfb_cnt,
const WORD32 *ptr_grouped_sfb_offset, const WORD32 max_sfb_per_grp,
const FLOAT32 *ptr_grouped_sfb_min_snr, const WORD32 total_groups_cnt,
const WORD32 *ptr_group_len, ixheaace_psy_out_channel *ptr_psy_out_ch);

490
encoder/ixheaace_mdct_480.c Normal file
View file

@ -0,0 +1,490 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include "ixheaac_type_def.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_enc_main.h"
#include "ixheaac_constants.h"
#include "ixheaace_aac_constants.h"
#include "ixheaace_fft.h"
void ia_aac_ld_enc_rearrange(WORD32 *ip, WORD32 *op, WORD32 N, UWORD8 *re_arr_tab) {
WORD32 n, i = 0;
for (n = 0; n < N; n++) {
WORD32 idx = re_arr_tab[n] << 1;
op[i++] = ip[idx];
op[i++] = ip[idx + 1];
}
return;
}
static VOID ia_enhaacplus_enc_fft15(FLOAT32 *ptr_vec) {
FLOAT32 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, i0, i1,
i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, tmp0, tmp1, tmp2,
tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16,
tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29;
/* Pre-additions real part */
r1 = ptr_vec[2] + ptr_vec[8];
r2 = ptr_vec[2] - ptr_vec[8];
r3 = ptr_vec[4] + ptr_vec[16];
r4 = ptr_vec[4] - ptr_vec[16];
r5 = ptr_vec[6] + ptr_vec[24];
r6 = ptr_vec[6] - ptr_vec[24];
r7 = ptr_vec[10] + ptr_vec[20];
r8 = ptr_vec[10] - ptr_vec[20];
r9 = ptr_vec[12] + ptr_vec[18];
r10 = ptr_vec[12] - ptr_vec[18];
r11 = ptr_vec[14] + ptr_vec[26];
r12 = ptr_vec[14] - ptr_vec[26];
r13 = ptr_vec[22] + ptr_vec[28];
r14 = ptr_vec[22] - ptr_vec[28];
tmp2 = r1 + r3;
tmp4 = r1 - r3;
tmp6 = r2 + r14;
tmp8 = r2 - r14;
tmp10 = r4 + r12;
tmp12 = r4 - r12;
tmp14 = r5 + r9;
tmp16 = r5 - r9;
tmp18 = r11 + r13;
tmp20 = r11 - r13;
/* Pre-additions imaginary part */
i1 = ptr_vec[3] + ptr_vec[9];
i2 = ptr_vec[3] - ptr_vec[9];
i3 = ptr_vec[5] + ptr_vec[17];
i4 = ptr_vec[5] - ptr_vec[17];
i5 = ptr_vec[7] + ptr_vec[25];
i6 = ptr_vec[7] - ptr_vec[25];
i7 = ptr_vec[11] + ptr_vec[21];
i8 = ptr_vec[11] - ptr_vec[21];
i9 = ptr_vec[13] + ptr_vec[19];
i10 = ptr_vec[13] - ptr_vec[19];
i11 = ptr_vec[15] + ptr_vec[27];
i12 = ptr_vec[15] - ptr_vec[27];
i13 = ptr_vec[23] + ptr_vec[29];
i14 = ptr_vec[23] - ptr_vec[29];
tmp3 = i1 + i3;
tmp5 = i1 - i3;
tmp7 = i2 + i14;
tmp9 = i2 - i14;
tmp11 = i4 + i12;
tmp13 = i4 - i12;
tmp15 = i5 + i9;
tmp17 = i5 - i9;
tmp19 = i11 + i13;
tmp21 = i11 - i13;
/* Pre-additions and core multiplications */
tmp28 = tmp4 + tmp20;
tmp29 = tmp5 + tmp21;
r4 = tmp2 + tmp18;
i4 = tmp3 + tmp19;
r3 = (FLOAT32)((r4 + tmp14) * -1.25);
i3 = (FLOAT32)((i4 + tmp15) * -1.25);
r2 = (FLOAT32)((tmp29 - i8) * -8.660254037844387e-1);
i2 = (FLOAT32)((tmp28 - r8) * 8.660254037844387e-1);
r1 = r4 + r7;
i1 = i4 + i7;
r0 = r1 + ptr_vec[0] + tmp14;
i0 = i1 + ptr_vec[1] + tmp15;
r7 = tmp4 - tmp20;
i7 = tmp5 - tmp21;
r8 = (FLOAT32)((tmp3 - tmp19) * -4.841229182759272e-1);
i8 = (FLOAT32)((tmp2 - tmp18) * 4.841229182759272e-1);
tmp0 = tmp6 + r10;
tmp1 = tmp7 + i10;
tmp2 = r6 - tmp10;
tmp3 = i6 - tmp11;
r10 = (FLOAT32)(tmp7 * -2.308262652881440);
i10 = (FLOAT32)(tmp6 * 2.308262652881440);
r11 = (FLOAT32)(tmp8 * 1.332676064001459);
i11 = (FLOAT32)(tmp9 * 1.332676064001459);
r6 = (FLOAT32)((r7 - tmp16) * 5.590169943749475e-1);
i6 = (FLOAT32)((i7 - tmp17) * 5.590169943749475e-1);
r12 = (FLOAT32)((tmp1 + tmp3) * 5.877852522924733e-1);
i12 = (FLOAT32)((tmp0 + tmp2) * -5.877852522924733e-1);
r13 = (FLOAT32)((tmp7 - tmp11) * -8.816778784387098e-1);
i13 = (FLOAT32)((tmp6 - tmp10) * 8.816778784387098e-1);
r14 = (FLOAT32)((tmp8 + tmp12) * 5.090369604551274e-1);
i14 = (FLOAT32)((tmp9 + tmp13) * 5.090369604551274e-1);
r16 = (FLOAT32)(tmp11 * 5.449068960040204e-1);
i16 = (FLOAT32)(tmp10 * -5.449068960040204e-1);
r17 = (FLOAT32)(tmp12 * 3.146021430912046e-1);
i17 = (FLOAT32)(tmp13 * 3.146021430912046e-1);
r4 *= 1.875;
i4 *= 1.875;
r1 *= -1.5;
i1 *= -1.5;
r7 *= (FLOAT32)(-8.385254915624212e-1);
i7 *= (FLOAT32)(-8.385254915624212e-1);
r5 = (FLOAT32)(tmp29 * 1.082531754730548);
i5 = (FLOAT32)(tmp28 * -1.082531754730548);
r9 = (FLOAT32)(tmp1 * 1.5388417685876270);
i9 = (FLOAT32)(tmp0 * -1.538841768587627);
r15 = (FLOAT32)(tmp3 * 3.632712640026803e-1);
i15 = (FLOAT32)(tmp2 * -3.632712640026803e-1);
/* Post-additions real part */
tmp2 = r0 + r1;
tmp4 = r3 + r6;
tmp6 = r3 - r6;
tmp8 = r4 + r5;
tmp10 = r4 - r5;
tmp12 = r7 + r8;
tmp14 = r7 - r8;
tmp16 = r13 + r16;
tmp18 = r14 + r17;
tmp20 = r10 - r13;
tmp22 = r11 - r14;
tmp24 = r12 + r15;
tmp26 = r12 - r9;
r1 = tmp2 + r2;
r2 = tmp2 - r2;
r3 = tmp4 + tmp26;
r4 = tmp4 - tmp26;
r5 = tmp6 + tmp24;
r6 = tmp6 - tmp24;
r7 = tmp16 + tmp18;
r8 = tmp16 - tmp18;
r9 = tmp20 - tmp22;
r10 = tmp20 + tmp22;
r11 = r1 + tmp8;
r12 = r2 + tmp10;
r13 = r11 - tmp12;
r14 = r12 - tmp14;
r15 = r12 + tmp14;
r16 = r11 + tmp12;
/* Post-additions imaginary part */
tmp3 = i0 + i1;
tmp5 = i3 + i6;
tmp7 = i3 - i6;
tmp9 = i4 + i5;
tmp11 = i4 - i5;
tmp13 = i7 + i8;
tmp15 = i7 - i8;
tmp17 = i13 + i16;
tmp19 = i14 + i17;
tmp21 = i10 - i13;
tmp23 = i11 - i14;
tmp25 = i12 + i15;
tmp27 = i12 - i9;
i1 = tmp3 + i2;
i2 = tmp3 - i2;
i3 = tmp5 + tmp27;
i4 = tmp5 - tmp27;
i5 = tmp7 + tmp25;
i6 = tmp7 - tmp25;
i7 = tmp17 + tmp19;
i8 = tmp17 - tmp19;
i9 = tmp21 - tmp23;
i10 = tmp21 + tmp23;
i11 = i1 + tmp9;
i12 = i2 + tmp11;
i13 = i11 - tmp13;
i14 = i12 - tmp15;
i15 = i12 + tmp15;
i16 = i11 + tmp13;
*ptr_vec++ = r0;
*ptr_vec++ = i0;
*ptr_vec++ = r13 + r5 + r7;
*ptr_vec++ = i13 + i5 + i7;
*ptr_vec++ = r15 + r3 - r9;
*ptr_vec++ = i15 + i3 - i9;
*ptr_vec++ = r0 + r4;
*ptr_vec++ = i0 + i4;
*ptr_vec++ = r13 + r6 - r7;
*ptr_vec++ = i13 + i6 - i7;
*ptr_vec++ = r2;
*ptr_vec++ = i2;
*ptr_vec++ = r0 + r5;
*ptr_vec++ = i0 + i5;
*ptr_vec++ = r16 + r3 - r10;
*ptr_vec++ = i16 + i3 - i10;
*ptr_vec++ = r15 + r4 + r9;
*ptr_vec++ = i15 + i4 + i9;
*ptr_vec++ = r0 + r6;
*ptr_vec++ = i0 + i6;
*ptr_vec++ = r1;
*ptr_vec++ = i1;
*ptr_vec++ = r14 + r5 + r8;
*ptr_vec++ = i14 + i5 + i8;
*ptr_vec++ = r0 + r3;
*ptr_vec++ = i0 + i3;
*ptr_vec++ = r16 + r4 + r10;
*ptr_vec++ = i16 + i4 + i10;
*ptr_vec++ = r14 + r6 - r8;
*ptr_vec++ = i14 + i6 - i8;
}
static VOID ia_enhaacplus_enc_fft16(FLOAT32 *ptr_vec) {
FLOAT32 var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var110, var111,
var112, var113, var114, var115, var20, var21, var22, var23, var24, var25, var26, var27,
var28, var29, var210, var211, var212, var213, var214, var215, arr0, arr1, arr2, arr3, arr4,
arr5, arr6, arr7, arr8, arr9, arr10, arr11, arr12, arr13, arr14, arr15;
/* Pre-additions */
arr0 = ptr_vec[0] + ptr_vec[16];
arr8 = ptr_vec[8] + ptr_vec[24];
var10 = arr0 + arr8;
var12 = arr0 - arr8;
arr1 = ptr_vec[1] + ptr_vec[17];
arr9 = ptr_vec[9] + ptr_vec[25];
var11 = arr1 + arr9;
var13 = arr1 - arr9;
arr2 = ptr_vec[2] + ptr_vec[18];
arr10 = ptr_vec[10] + ptr_vec[26];
var14 = arr2 + arr10;
var16 = arr2 - arr10;
arr3 = ptr_vec[3] + ptr_vec[19];
arr11 = ptr_vec[11] + ptr_vec[27];
var15 = arr3 + arr11;
var17 = arr3 - arr11;
arr4 = ptr_vec[4] + ptr_vec[20];
arr12 = ptr_vec[12] + ptr_vec[28];
var18 = arr4 + arr12;
var110 = arr4 - arr12;
arr5 = ptr_vec[5] + ptr_vec[21];
arr13 = ptr_vec[13] + ptr_vec[29];
var19 = arr5 + arr13;
var111 = arr5 - arr13;
arr6 = ptr_vec[6] + ptr_vec[22];
arr14 = ptr_vec[14] + ptr_vec[30];
var112 = arr6 + arr14;
var114 = arr6 - arr14;
arr7 = ptr_vec[7] + ptr_vec[23];
arr15 = ptr_vec[15] + ptr_vec[31];
var113 = arr7 + arr15;
var115 = arr7 - arr15;
/* Pre-additions and core multiplications */
var20 = var10 + var18;
var24 = var10 - var18;
var21 = var11 + var19;
var25 = var11 - var19;
var28 = var12 - var111;
var210 = var12 + var111;
var29 = var13 + var110;
var211 = var13 - var110;
var22 = var14 + var112;
var27 = var14 - var112;
var23 = var15 + var113;
var26 = var113 - var15;
var11 = var16 + var114;
var12 = var16 - var114;
var10 = var17 + var115;
var13 = var17 - var115;
var212 = (var10 + var12) * IXHEAACE_INV_SQRT2;
var214 = (var10 - var12) * IXHEAACE_INV_SQRT2;
var213 = (var13 - var11) * IXHEAACE_INV_SQRT2;
var215 = (var11 + var13) * -IXHEAACE_INV_SQRT2;
/* odd */
arr0 = ptr_vec[0] - ptr_vec[16];
arr1 = ptr_vec[1] - ptr_vec[17];
arr2 = ptr_vec[2] - ptr_vec[18];
arr3 = ptr_vec[3] - ptr_vec[19];
arr4 = ptr_vec[4] - ptr_vec[20];
arr5 = ptr_vec[5] - ptr_vec[21];
arr6 = ptr_vec[6] - ptr_vec[22];
arr7 = ptr_vec[7] - ptr_vec[23];
arr8 = ptr_vec[8] - ptr_vec[24];
arr9 = ptr_vec[9] - ptr_vec[25];
arr10 = ptr_vec[10] - ptr_vec[26];
arr11 = ptr_vec[11] - ptr_vec[27];
arr12 = ptr_vec[12] - ptr_vec[28];
arr13 = ptr_vec[13] - ptr_vec[29];
arr14 = ptr_vec[14] - ptr_vec[30];
arr15 = ptr_vec[15] - ptr_vec[31];
/* Pre-additions and core multiplications */
var19 = (arr2 + arr14) * -IXHEAACE_COS_3PI_DIV8;
var110 = (arr2 - arr14) * IXHEAACE_COS_PI_DIV8;
var18 = (arr3 + arr15) * IXHEAACE_COS_3PI_DIV8;
var111 = (arr3 - arr15) * IXHEAACE_COS_PI_DIV8;
var15 = (arr4 + arr12) * -IXHEAACE_INV_SQRT2;
var16 = (arr4 - arr12) * IXHEAACE_INV_SQRT2;
var14 = (arr5 + arr13) * IXHEAACE_INV_SQRT2;
var17 = (arr5 - arr13) * IXHEAACE_INV_SQRT2;
var113 = (arr6 + arr10) * -IXHEAACE_COS_PI_DIV8;
var114 = (arr6 - arr10) * IXHEAACE_COS_3PI_DIV8;
var112 = (arr7 + arr11) * IXHEAACE_COS_PI_DIV8;
var115 = (arr7 - arr11) * IXHEAACE_COS_3PI_DIV8;
/* Core multiplications */
arr2 = var18 * IXHEAACE_SQRT2PLUS1 - var112 * IXHEAACE_SQRT2MINUS1;
arr3 = var19 * IXHEAACE_SQRT2PLUS1 - var113 * IXHEAACE_SQRT2MINUS1;
arr4 = var110 * IXHEAACE_SQRT2MINUS1 - var114 * IXHEAACE_SQRT2PLUS1;
arr5 = var111 * IXHEAACE_SQRT2MINUS1 - var115 * IXHEAACE_SQRT2PLUS1;
/* Post-additions */
var18 = var18 + var112;
var19 = var19 + var113;
var110 = var110 + var114;
var111 = var111 + var115;
arr6 = arr0 + var14;
arr10 = arr0 - var14;
arr7 = arr1 + var15;
arr11 = arr1 - var15;
arr12 = var16 - arr9;
arr14 = var16 + arr9;
arr13 = arr8 + var17;
arr15 = arr8 - var17;
var10 = arr6 - arr14;
var12 = arr6 + arr14;
var11 = arr7 + arr15;
var13 = arr7 - arr15;
var14 = arr10 + arr12;
var16 = arr10 - arr12;
var15 = arr11 + arr13;
var17 = arr11 - arr13;
arr10 = var18 + var110;
var110 = var18 - var110;
arr11 = var19 + var111;
var111 = var19 - var111;
var112 = arr2 + arr4;
var114 = arr2 - arr4;
var113 = arr3 + arr5;
var115 = arr3 - arr5;
/* Post-additions */
ptr_vec[0] = var20 + var22;
ptr_vec[1] = var21 + var23;
ptr_vec[2] = var12 + arr10;
ptr_vec[3] = var13 + arr11;
ptr_vec[4] = var210 + var212;
ptr_vec[5] = var211 + var213;
ptr_vec[6] = var10 + var112;
ptr_vec[7] = var11 + var113;
ptr_vec[8] = var24 - var26;
ptr_vec[9] = var25 - var27;
ptr_vec[10] = var16 + var114;
ptr_vec[11] = var17 + var115;
ptr_vec[12] = var28 + var214;
ptr_vec[13] = var29 + var215;
ptr_vec[14] = var14 + var110;
ptr_vec[15] = var15 + var111;
ptr_vec[16] = var20 - var22;
ptr_vec[17] = var21 - var23;
ptr_vec[18] = var12 - arr10;
ptr_vec[19] = var13 - arr11;
ptr_vec[20] = var210 - var212;
ptr_vec[21] = var211 - var213;
ptr_vec[22] = var10 - var112;
ptr_vec[23] = var11 - var113;
ptr_vec[24] = var24 + var26;
ptr_vec[25] = var25 + var27;
ptr_vec[26] = var16 - var114;
ptr_vec[27] = var17 - var115;
ptr_vec[28] = var28 - var214;
ptr_vec[29] = var29 - var215;
ptr_vec[30] = var14 - var110;
ptr_vec[31] = var15 - var111;
}
static VOID ia_enhaacplus_enc_fft240(FLOAT32 *ptr_in) {
const WORD32 n1 = 240;
const WORD32 n2 = 15;
const WORD32 n3 = 16;
const WORD32 *ptr_idx1 = ia_enhaacplus_enc_fft240_table1;
const WORD32 *ptr_idx2 = ia_enhaacplus_enc_fft240_table2;
WORD32 k, l;
FLOAT32 temp[32], out[480];
for (k = 0; k < n2; k++) {
for (l = 0; l < n3; l++) {
temp[2 * l] = ptr_in[2 * *ptr_idx1];
temp[2 * l + 1] = ptr_in[2 * *ptr_idx1 + 1];
ptr_idx1 += n2;
}
ia_enhaacplus_enc_fft16(temp); /* 16-point FFT */
ptr_idx1 -= n1;
for (l = 0; l < n3; l++) {
ptr_in[2 * *ptr_idx1] = temp[2 * l];
ptr_in[2 * *ptr_idx1 + 1] = temp[2 * l + 1];
ptr_idx1 += n2;
}
ptr_idx1 -= n1 - 1;
}
ptr_idx1 -= n2;
for (k = 0; k < n3; k++) {
for (l = 0; l < n2; l++) {
temp[2 * l] = ptr_in[2 * *ptr_idx1];
temp[2 * l + 1] = ptr_in[2 * *ptr_idx1++ + 1];
}
ia_enhaacplus_enc_fft15(temp); /* 15-point FFT */
for (l = 0; l < n2; l++) {
out[2 * *ptr_idx2] = temp[2 * l];
out[2 * *ptr_idx2++ + 1] = temp[2 * l + 1];
}
}
memcpy(ptr_in, out, (2 * n1) * sizeof(out[0]));
}
VOID ia_aac_ld_enc_mdct_480(FLOAT32 *ptr_inp, FLOAT32 *ptr_scratch, WORD32 mdct_flag,
ixheaace_mdct_tables *pstr_mdct_tables) {
WORD32 k;
FLOAT32 const_mltfac = ((FLOAT32)FRAME_LEN_512) / FRAME_LEN_480;
ia_eaacp_enc_pre_twiddle_aac(ptr_scratch, ptr_inp, FRAME_LEN_480,
pstr_mdct_tables->cosine_array_960);
ia_enhaacplus_enc_fft240(ptr_scratch);
ia_enhaacplus_enc_post_twiddle(ptr_inp, ptr_scratch, pstr_mdct_tables->cosine_array_960,
FRAME_LEN_480);
if (0 == mdct_flag) {
for (k = 0; k < MDCT_LEN; k++) {
ptr_inp[k] *= const_mltfac;
}
}
}

View file

@ -0,0 +1,146 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
/* standard memory table descriptor for libraries */
typedef struct {
UWORD32 ui_size; /* size of the memory in bytes */
UWORD32 ui_alignment; /* alignment in bytes */
UWORD32 ui_type; /* type of memory */
UWORD32 ui_placement[2]; /* 64 bit placement info */
UWORD32 ui_priority; /* the importance for placement */
UWORD32 ui_placed[2]; /* the o_red location for placement */
} ixheaace_mem_info_struct;
typedef struct {
UWORD32 ui_size;
UWORD32 ui_alignment;
UWORD32 ui_type;
pVOID mem_ptr;
} ixheaace_mem_info_table;
typedef struct {
WORD32 sample_rate; /* audio file sample rate */
WORD32 bitrate; /* encoder bit rate in bits/sec */
WORD32 num_channels_in; /* number of channels on input (1,2) */
WORD32 num_channels_out; /* number of channels on output (1,2) */
WORD32 bandwidth; /* targeted audio bandwidth in Hz */
WORD32 dual_mono; /* flag: make 2 SCEs for stereo input files */
WORD32 use_tns; /* flag: use temporal noise shaping */
WORD32 noise_filling; /* flag: use noise filling */
WORD32 use_adts; /* flag: use ADTS instead of ADIF */
WORD32 private_bit; /* private bit of MPEG Header */
WORD32 copyright_bit; /* copyright bit of MPEG Header */
WORD32 original_copy_bit; /* original bit of MPEG Header */
WORD32 f_no_stereo_preprocessing; /* forbid usage of stereo prerpocessing */
WORD32 inv_quant; /* improve distortion by inverse quantization */
WORD32 full_bandwidth; /* improve distortion by inverse quantization */
WORD32 bitreservoir_size; /* size of bit reservoir (default:0; max 6144)*/
WORD32 length;
} ixheaace_aac_enc_config;
typedef struct {
UWORD32 ui_pcm_wd_sz;
WORD32 i_bitrate;
WORD32 frame_length;
WORD32 frame_cmd_flag;
WORD32 out_bytes_flag;
WORD32 user_tns_flag;
WORD32 aot;
WORD32 i_mps_tree_config;
WORD32 esbr_flag;
WORD32 i_channels;
WORD32 i_samp_freq;
WORD32 i_native_samp_freq;
WORD32 i_channels_mask;
WORD32 i_num_coupling_chan;
/* Add config params here */
WORD32 i_use_mps;
WORD32 i_use_adts;
WORD32 i_use_es;
FLAG write_program_config_element;
ixheaace_aac_enc_config aac_config;
} ixheaace_input_config;
typedef struct {
WORD8 *p_lib_name;
WORD8 *p_version_num;
} ixheaace_version;
typedef struct {
WORD32 i_out_bytes;
WORD32 i_bytes_consumed;
UWORD32 ui_inp_buf_size;
UWORD32 malloc_count;
UWORD32 ui_rem;
UWORD32 ui_proc_mem_tabs_size;
pVOID pv_ia_process_api_obj;
pVOID arr_alloc_memory[100];
pVOID (*malloc_xheaace)(UWORD32, UWORD32);
VOID (*free_xheaace)(pVOID);
ixheaace_version version;
ixheaace_mem_info_table mem_info_table[4];
WORD32 input_size;
WORD32 samp_freq;
WORD32 header_samp_freq;
WORD32 audio_profile;
FLOAT32 down_sampling_ratio;
pWORD32 pb_inp_buf_32;
} ixheaace_output_config;
typedef struct {
ixheaace_input_config input_config;
ixheaace_output_config output_config;
} ixheaace_user_config_struct;
/*****************************************************************************/
/* Constant hash defines */
/*****************************************************************************/
/* ittiam standard memory types to be used inter frames */
#define IA_MEMTYPE_PERSIST 0x00
/* read write, to be used intra frames */
#define IA_MEMTYPE_SCRATCH 0x01
/* read only memory, intra frame */
#define IA_MEMTYPE_INPUT 0x02
/* read-write memory, for usable output, intra frame */
#define IA_MEMTYPE_OUTPUT 0x03
/* ittiam standard memory priorities */
#define IA_MEMPRIORITY_ANYWHERE 0x00
#define IA_MEMPRIORITY_HIGH 0x05
/* ittiam standard memory placements */
/* placement is defined by 64 bits */
#define IA_MEMPLACE_EXT_RAM_0 0x010000
/* the simple common PC RAM */
typedef struct {
WORD32 codec_mode;
} ia_input_config;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,122 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
typedef struct {
UWORD8 bs_smooth_mode[MAX_NUM_PARAMS];
UWORD8 bs_smooth_time[MAX_NUM_PARAMS];
UWORD8 bs_freq_res_stride[MAX_NUM_PARAMS];
UWORD8 bs_smg_data[MAX_NUM_PARAMS][MAX_NUM_BINS];
} ixheaace_mps_smg_data;
typedef struct {
UWORD8 bs_framing_type;
WORD32 num_param_sets;
WORD32 bs_param_slots[MAX_NUM_PARAMS];
} ixheaace_mps_framing_info;
typedef struct {
WORD8 cld[IXHEAACE_MPS_MAX_NUM_BOXES][MAX_NUM_PARAMS][MAX_NUM_BINS];
WORD8 icc[IXHEAACE_MPS_MAX_NUM_BOXES][MAX_NUM_PARAMS][MAX_NUM_BINS];
} ixheaace_mps_ott_data;
typedef struct {
UWORD8 bs_env_shape_channel[MAX_NUM_OUTPUTCHANNELS];
UWORD8 bs_env_shape_data[MAX_NUM_OUTPUTCHANNELS][MAX_TIME_SLOTS];
} ixheaace_mps_temp_shape_data;
typedef struct {
WORD32 num_ott_boxes;
WORD32 num_in_chan;
WORD32 num_out_chan;
} ixheaace_mps_tree_description;
typedef struct {
WORD32 bs_ott_bands;
} ixheaace_mps_ott_config;
typedef struct {
WORD32 bs_sampling_frequency;
WORD32 bs_frame_length;
WORD32 num_bands;
WORD32 bs_tree_config;
WORD32 bs_quant_mode;
WORD32 bs_fixed_gain_dmx;
WORD32 bs_env_quant_mode;
WORD32 bs_decorr_config;
ixheaace_mps_tree_description tree_description;
ixheaace_mps_ott_config ott_config[IXHEAACE_MPS_MAX_NUM_BOXES];
} ixheaace_mps_spatial_specific_config;
typedef struct {
UWORD8 bs_xxx_data_mode[IXHEAACE_MPS_MAX_NUM_BOXES][MAX_NUM_PARAMS];
UWORD8 bs_data_pair[IXHEAACE_MPS_MAX_NUM_BOXES][MAX_NUM_PARAMS];
UWORD8 bs_quant_coarse_xxx[IXHEAACE_MPS_MAX_NUM_BOXES][MAX_NUM_PARAMS];
UWORD8 bs_freq_res_stride_xxx[IXHEAACE_MPS_MAX_NUM_BOXES][MAX_NUM_PARAMS];
} ixheaace_mps_lossless_data;
typedef struct {
ixheaace_mps_framing_info framing_info;
WORD32 bs_independency_flag;
ixheaace_mps_ott_data ott_data;
ixheaace_mps_smg_data smg_data;
ixheaace_mps_temp_shape_data temp_shape_data;
ixheaace_mps_lossless_data cld_lossless_data;
ixheaace_mps_lossless_data icc_lossless_data;
UWORD8 b_use_bb_cues;
} ixheaace_mps_spatial_frame;
typedef struct {
WORD8 cld_old[IXHEAACE_MPS_MAX_NUM_BOXES][MAX_NUM_BINS];
WORD8 icc_old[IXHEAACE_MPS_MAX_NUM_BOXES][MAX_NUM_BINS];
UWORD8 quant_coarse_cld_prev[IXHEAACE_MPS_MAX_NUM_BOXES][MAX_NUM_PARAMS];
UWORD8 quant_coarse_icc_prev[IXHEAACE_MPS_MAX_NUM_BOXES][MAX_NUM_PARAMS];
} ixheaace_mps_prev_ott_data;
typedef struct {
ixheaace_mps_prev_ott_data prev_ott_data;
} ixheaace_mps_static_spatial_frame;
typedef struct ixheaace_mps_bsf_instance {
ixheaace_mps_spatial_specific_config spatial_specific_config;
ixheaace_mps_spatial_frame frame;
ixheaace_mps_static_spatial_frame prev_frame_data;
} ixheaace_mps_bsf_instance;
typedef struct ixheaace_mps_bsf_instance *ixheaace_mps_pstr_bsf_instance;
IA_ERRORCODE ixheaace_mps_212_write_spatial_specific_config(
ixheaace_mps_spatial_specific_config *const pstr_spatial_specific_config,
UWORD8 *const ptr_output_buffer, const WORD32 output_buffer_size,
WORD32 *const ptr_output_bits, WORD32 aot);
IA_ERRORCODE ixheaace_mps_212_write_spatial_frame(
UWORD8 *const ptr_output_buffer, const WORD32 output_buffer_size,
WORD32 *const ptr_output_bits, ixheaace_mps_pstr_bsf_instance pstr_bsf_instance, WORD32 aot);

View file

@ -0,0 +1,28 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
typedef struct ixheaace_mps_buf_descr {
VOID **pp_base;
UWORD32 *p_buf_size;
UWORD32 *p_ele_size;
UWORD32 *p_buf_type;
UWORD32 num_bufs;
} ixheaace_mps_buf_descr;

View file

@ -0,0 +1,44 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#define IXHEAACE_MPS_SAC_DATA_TYPE_CLD (0x0)
#define IXHEAACE_MPS_SAC_DATA_TYPE_ICC (0x1)
#define IXHEAACE_MPS_SAC_DATA_TYPE_CPC (0x2)
#define IXHEAACE_MPS_SAC_DIRECTION_BACKWARDS (0x0)
#define IXHEAACE_MPS_SAC_DIRECTION_FORWARDS (0x1)
#define IXHEAACE_MPS_SAC_DIFF_FREQ (0x0)
#define IXHEAACE_MPS_SAC_DIFF_TIME (0x1)
#define IXHEAACE_MPS_SAC_FREQ_PAIR (0x0)
#define IXHEAACE_MPS_SAC_HUFF_1D (0x0)
#define IXHEAACE_MPS_SAC_HUFF_2D (0x1)
#ifndef PI
#define PI (3.1415926535897932f)
#endif
#define EIGHT_SHORT_SEQUENCE (2)
#define MAX_NUM_BINS (56)
#define MAX_NUM_PARAMS (7)
#define MAX_NUM_OUTPUTCHANNELS (16)
#define MAX_TIME_SLOTS (64)

View file

@ -0,0 +1,28 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
typedef struct {
FLOAT32 re;
FLOAT32 im;
} ixheaace_cmplx_str;

212
encoder/ixheaace_mps_dct.c Normal file
View file

@ -0,0 +1,212 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include "ixheaac_type_def.h"
#include "ixheaace_error_codes.h"
#include "ixheaac_error_standards.h"
#include "ixheaace_mps_common_fix.h"
#include "ixheaace_mps_defines.h"
#include "ixheaace_mps_common_define.h"
#include "ixheaace_bitbuffer.h"
#include "ixheaace_psy_const.h"
#include "ixheaace_tns.h"
#include "ixheaace_tns_params.h"
#include "ixheaace_rom.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_enc_main.h"
#include "ixheaace_fft.h"
#include "ixheaace_mps_dct.h"
#include "ixheaace_mps_buf.h"
#include "ixheaace_mps_lib.h"
#include "ixheaace_mps_main_structure.h"
#include "ixheaace_mps_bitstream.h"
#include "ixheaace_mps_frame_windowing.h"
#include "ixheaace_mps_param_extract.h"
#include "ixheaace_mps_static_gain.h"
#include "ixheaace_mps_filter.h"
#include "ixheaace_mps_delay.h"
#include "ixheaace_mps_dmx_tdom_enh.h"
#include "ixheaace_mps_tools_rom.h"
IA_ERRORCODE ixheaace_mps_212_dct_iv(FLOAT32 *ptr_data, WORD32 length, WORD8 *ptr_scratch) {
WORD32 sin_step = 0;
WORD32 length_by_2 = length >> 1;
WORD32 step, idx;
FLOAT32 accu_1, accu_2, accu_3, accu_4;
FLOAT32 *ptr_data_0;
FLOAT32 *ptr_data_1;
const ixheaace_cmplx_str *ptr_cmplx_twiddle;
const ixheaace_cmplx_str *ptr_cmplx_sin_twiddle;
ixheaace_scratch_mem *pstr_scratch = (ixheaace_scratch_mem *)ptr_scratch;
if (length == 64) {
ptr_cmplx_twiddle = sine_window_64;
ptr_cmplx_sin_twiddle = sine_table_1024;
sin_step = 32;
} else {
ptr_cmplx_twiddle = sine_window_32;
ptr_cmplx_sin_twiddle = sine_table_1024;
sin_step = 64;
}
ptr_data_0 = &ptr_data[0];
ptr_data_1 = &ptr_data[length - 2];
for (idx = 0; idx < length_by_2 - 1; idx += 2, ptr_data_0 += 2, ptr_data_1 -= 2) {
accu_1 =
(ptr_data_1[1] * ptr_cmplx_twiddle[idx].re) - (ptr_data_0[0] * ptr_cmplx_twiddle[idx].im);
accu_2 =
(ptr_data_1[1] * ptr_cmplx_twiddle[idx].im) + (ptr_data_0[0] * ptr_cmplx_twiddle[idx].re);
accu_3 = (ptr_data_1[0] * ptr_cmplx_twiddle[idx + 1].re) -
(ptr_data_0[1] * ptr_cmplx_twiddle[idx + 1].im);
accu_4 = (ptr_data_1[0] * ptr_cmplx_twiddle[idx + 1].im) +
(ptr_data_0[1] * ptr_cmplx_twiddle[idx + 1].re);
ptr_data_0[0] = accu_2 / 4;
ptr_data_0[1] = accu_1 / 4;
ptr_data_1[0] = accu_4 / 4;
ptr_data_1[1] = -(accu_3 / 4);
}
ia_enhaacplus_enc_complex_fft(ptr_data, length_by_2, pstr_scratch);
if (length_by_2 == 32) {
for (idx = 0; idx < length; idx++) {
ptr_data[idx] = (ptr_data[idx] / (1 << (4)));
}
} else {
for (idx = 0; idx < length; idx++) {
ptr_data[idx] = (ptr_data[idx] / (1 << (3)));
}
}
ptr_data_0 = &ptr_data[0];
ptr_data_1 = &ptr_data[length - 2];
accu_1 = ptr_data_1[0];
accu_2 = ptr_data_1[1];
ptr_data_1[1] = -ptr_data_0[1];
for (step = sin_step, idx = 1; idx < (length_by_2 + 1) >> 1; idx++, step += sin_step) {
ixheaace_cmplx_str twd = ptr_cmplx_sin_twiddle[step];
accu_3 = (accu_1 * twd.re) - (accu_2 * twd.im);
accu_4 = (accu_1 * twd.im) + (accu_2 * twd.re);
ptr_data_0[1] = accu_3;
ptr_data_1[0] = accu_4;
ptr_data_0 += 2;
ptr_data_1 -= 2;
accu_3 = (ptr_data_0[1] * twd.re) - (ptr_data_0[0] * twd.im);
accu_4 = (ptr_data_0[1] * twd.im) + (ptr_data_0[0] * twd.re);
accu_1 = ptr_data_1[0];
accu_2 = ptr_data_1[1];
ptr_data_1[1] = -accu_3;
ptr_data_0[0] = accu_4;
}
accu_1 = (accu_1 * SQUARE_ROOT_TWO);
accu_2 = (accu_2 * SQUARE_ROOT_TWO);
ptr_data_1[0] = (accu_1 + accu_2) / 2;
ptr_data_0[1] = (accu_1 - accu_2) / 2;
return IA_NO_ERROR;
}
IA_ERRORCODE ixheaace_mps_212_dst_iv(FLOAT32 *ptr_data, WORD32 length, WORD8 *ptr_scratch) {
WORD32 sin_step = 0;
WORD32 step, idx;
WORD32 length_by_2 = length >> 1;
FLOAT32 accu_1, accu_2, accu_3, accu_4;
FLOAT32 *ptr_data_0;
FLOAT32 *ptr_data_1;
const ixheaace_cmplx_str *ptr_cmplx_twiddle;
const ixheaace_cmplx_str *ptr_cmplx_sin_twiddle;
ixheaace_scratch_mem *pstr_scratch = (ixheaace_scratch_mem *)ptr_scratch;
if (length == 64) {
ptr_cmplx_twiddle = sine_window_64;
ptr_cmplx_sin_twiddle = sine_table_1024;
sin_step = 32;
} else {
ptr_cmplx_twiddle = sine_window_32;
ptr_cmplx_sin_twiddle = sine_table_1024;
sin_step = 64;
}
ptr_data_0 = &ptr_data[0];
ptr_data_1 = &ptr_data[length - 2];
for (idx = 0; idx < length_by_2 - 1; idx += 2, ptr_data_0 += 2, ptr_data_1 -= 2) {
accu_1 = (ptr_data_1[1] * ptr_cmplx_twiddle[idx].re) -
((-ptr_data_0[0]) * ptr_cmplx_twiddle[idx].im);
accu_2 = (ptr_data_1[1] * ptr_cmplx_twiddle[idx].im) +
((-ptr_data_0[0]) * ptr_cmplx_twiddle[idx].re);
accu_3 = ((-ptr_data_1[0]) * ptr_cmplx_twiddle[idx + 1].re) -
(ptr_data_0[1] * ptr_cmplx_twiddle[idx + 1].im);
accu_4 = ((-ptr_data_1[0]) * ptr_cmplx_twiddle[idx + 1].im) +
(ptr_data_0[1] * ptr_cmplx_twiddle[idx + 1].re);
ptr_data_0[0] = accu_2 / 4;
ptr_data_0[1] = accu_1 / 4;
ptr_data_1[0] = accu_4 / 4;
ptr_data_1[1] = -(accu_3) / 4;
}
ia_enhaacplus_enc_complex_fft(ptr_data, length_by_2, pstr_scratch);
if (length_by_2 == 32) {
for (idx = 0; idx < length; idx++) {
ptr_data[idx] = (ptr_data[idx] / (1 << (4)));
}
} else {
for (idx = 0; idx < length; idx++) {
ptr_data[idx] = (ptr_data[idx] / (1 << (3)));
}
}
ptr_data_0 = &ptr_data[0];
ptr_data_1 = &ptr_data[length - 2];
accu_1 = ptr_data_1[0];
accu_2 = ptr_data_1[1];
ptr_data_1[1] = -ptr_data_0[0];
ptr_data_0[0] = ptr_data_0[1];
for (step = sin_step, idx = 1; idx < (length_by_2 + 1) >> 1; idx++, step += sin_step) {
ixheaace_cmplx_str twd = ptr_cmplx_sin_twiddle[step];
accu_3 = (accu_1 * twd.re) - (accu_2 * twd.im);
accu_4 = (accu_1 * twd.im) + (accu_2 * twd.re);
ptr_data_1[0] = -accu_3;
ptr_data_0[1] = -accu_4;
ptr_data_0 += 2;
ptr_data_1 -= 2;
accu_3 = (ptr_data_0[1] * twd.re) - (ptr_data_0[0] * twd.im);
accu_4 = (ptr_data_0[1] * twd.im) + (ptr_data_0[0] * twd.re);
accu_1 = ptr_data_1[0];
accu_2 = ptr_data_1[1];
ptr_data_0[0] = accu_3;
ptr_data_1[1] = -accu_4;
}
accu_1 = (accu_1 * SQUARE_ROOT_TWO);
accu_2 = (accu_2 * SQUARE_ROOT_TWO);
ptr_data_1[0] = (accu_1 + accu_2) / 2;
ptr_data_0[1] = (accu_1 - accu_2) / 2;
return IA_NO_ERROR;
}

View file

@ -0,0 +1,24 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
IA_ERRORCODE ixheaace_mps_212_dct_iv(FLOAT32 *ptr_data, WORD32 size, WORD8 *ptr_scratch);
IA_ERRORCODE ixheaace_mps_212_dst_iv(FLOAT32 *ptr_data, WORD32 size, WORD8 *ptr_scratch);

View file

@ -0,0 +1,189 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
#define NUM_QMF_BANDS (64)
#define MAX_HYBRID_BANDS (71)
#define MAX_INPUT_CHANNELS (6)
#define MAX_OUTPUT_CHANNELS (2)
#define PARAMETER_BANDS (20)
#define MAX_QMF_BANDS_TO_HYBRID (7)
#define MAX_HYBRID_ONLY_BANDS_PER_QMF (16)
#define PROTO_LEN (13)
#define BUFFER_LEN_LF (PROTO_LEN - 1 + MAX_TIME_SLOTS)
#define BUFFER_LEN_HF ((PROTO_LEN - 1) / 2)
#define MAX_BUFFER_SIZE (2048)
#define HYBRID_FILTER_DELAY (6)
#define QMF_FILTER_STATE_SYN_SIZE (640)
#define NUM_QMF_BANDS_TO_LF (3)
#define MPS_MAX_FRAME_LENGTH (4096)
#define MAX_SAMPLING_RATE (48000)
#define NUM_QMF_BANDS (64)
#define MAX_QMF_BANDS (128)
#define MAX_ANA_TIME_SLOT (192)
#define MAX_HYBRID_BAND (MAX_QMF_BANDS)
#define MAX_FRAME_TIME_SLOT (128)
#define MAX_HYBRID_STATIC_SLOT (96)
#define IXHEAACE_MPS_MAX_NUM_BOXES (1)
#define IXHEAACE_MPS_MAX_INPUT_CHANNELS (2)
#define IXHEAACE_MPS_MAX_OUTPUT_CHANNELS (1)
#define EPSILON (1e-9f)
#define PI_FLT (3.1415926535897931f)
#define ALPHA (0.0001f)
#define MAX_DELAY_INPUT (1024)
#define MAX_DELAY_OUTPUT (4096)
#define MAX_DELAY_SURROUND_ANALYSIS (20)
#define MAX_BITSTREAM_DELAY (4)
#define MAX_MPEGS_BYTES (1 << 14)
#define MAX_SSC_BYTES (1 << 6)
#define MAX_MPS_BS_PAYLOAD_SIZE 10000
#define MAX_SPACE_TREE_CHANNELS (2)
#define NUM_KEEP_WINDOWS (3)
#define WIN_ACTIV (1)
#define MAX_KEEP_FRAMECOUNT (100)
#define LEFT_CH (0)
#define RIGHT_CH (1)
#define SPACE_ONSET_THRESHOLD (3.0)
#define SPACE_ONSET_THRESHOLD_SQUARE_FLT ((1.0 / (SPACE_ONSET_THRESHOLD * SPACE_ONSET_THRESHOLD)))
#define MAX_NUM_TRANS (MAX_NUM_PARAMS / 2)
#define MAX_FREQ_RES_INDEX (8)
#define MAX_SAMPLING_FREQUENCY_INDEX (13)
#define SAMPLING_FREQUENCY_INDEX_ESCAPE (15)
#define IXHEAACE_MPS_SAC_VAR_HOLD (0)
#define IXHEAACE_MPS_SAC_VAR_ISOLATE (1)
#define IXHEAACE_MPS_FRAME_WINDOWING_INTP (0)
#define IXHEAACE_MPS_FRAME_WINDOWING_HOLD (1)
#define IXHEAACE_MPS_SAC_MAX_FREQ_BANDS (MAX_NUM_BINS)
#define IXHEAACE_MPS_MAX_CLD_QUANT_FINE (31)
#define IXHEAACE_MPS_MAX_CLD_QUANT_COARSE (15)
#define IXHEAACE_MPS_OFFSET_CLD_QUANT_COARSE (7)
#define IXHEAACE_MPS_OFFSET_CLD_QUANT_FINE (15)
#define IXHEAACE_MPS_MAX_ICC_QUANT_COARSE (4)
#define IXHEAACE_MPS_MAX_ICC_QUANT_FINE (8)
#define IXHEAACE_MPS_OFFSET_ICC_QUANT_COARSE (0)
#define IXHEAACE_MPS_OFFSET_ICC_QUANT_FINE (0)
#define MAX_NUM_PARAM_BANDS (56)
#define IXHEAACE_MPS_TREE_5151 (0)
#define IXHEAACE_MPS_TREE_5152 (1)
#define IXHEAACE_MPS_TREE_525 (2)
#define IXHEAACE_MPS_TREE_212 (7)
#define IXHEAACE_MPS_FIXED_GAIN_DMX_INVALID (-1)
#define IXHEAACE_MPS_MAX_FIXED_GAIN_DMX (7)
#define IXHEAACE_MPS_DECORR_INVALID (-1)
#define IXHEAACE_MPS_DECORR_QMFSPLIT0 (0)
#define IXHEAACE_MPS_DECORR_QMFSPLIT1 (1)
#define IXHEAACE_MPS_DECORR_QMFSPLIT2 (2)
#define IXHEAACE_MPS_DATA_MODE_DEFAULT (0)
#define IXHEAACE_MPS_DATA_MODE_KEEP (1)
#define IXHEAACE_MPS_DATA_MODE_INTERPOLATE (2)
#define IXHEAACE_MPS_DATA_MODE_FINECOARSE (3)
#define MAX_NUM_BOXES (5)
#define MAX_AAC_SHORTWINDOWGROUPS (4)
#define MAX_AAC_MDCT (1024)
#define MAX_AAC_FRAMES (2)
#define NUM_DATATYPES (3)
#define DELAY_COMPENSATION (352)
#define LOG10_2_10 (3.01029995664f)
#define INV_LN_10_10 (4.3429448190325182765112891891661f)
#define IXHEAACE_MPS_SAC_MODE_INVALID (0)
#define IXHEAACE_MPS_DMX_GAIN_DEFAULT (2)
#define IXHEAACE_MPS_SAC_BANDS_INVALID (0)
#define IXHEAACE_MPS_SAC_BANDS_ld (15)
#define IXHEAACE_MPS_SAC_BANDS_usac (28)
#define IXHEAACE_MPS_QUANTMODE_INVALID (-1)
#define IXHEAACE_MPS_QUANTMODE_FINE (0)
#define IXHEAACE_MPS_QUANTMODE_EBQ1 (1)
#define IXHEAACE_MPS_QUANTMODE_EBQ2 (2)
#define IXHEAACE_MPS_QUANTMODE_RSVD3 (3)
#define IXHEAACE_MPS_INPUT_BUFFER_IDX (0)
#define IXHEAACE_MPS_OUTUT_BUFFER_IDX (0)
#define IXHEAACE_MPS_BITSTREAM_BUFFER_IDX (1)
#define QMF_FILTER_PROTOTYPE_SIZE 640
#define QMF_NO_POLY 5
#define QMF640_PFT_TABLE_SIZE (640 / 2 + QMF_NO_POLY)
#define QMF320_MPSLDFB_PFT_TABLE_SIZE (320)
#define QMF640_MPSLDFB_PFT_TABLE_SIZE (640)
#define QMF_MPSLDFB_PFT_SCALE 1
#define MAX_MPEGS_BYTES (1 << 14)
#define MAX_SSC_BYTES (1 << 6)
#define MAX_HYBRID_BAND_OFFSET (64)
#define SQUARE_ROOT_TWO (1.41421356237f)
#define MPS_PAYLOAD_SIZE (1024)
#define ONE_BY_LN_TWO (1.44269504089f)
#define PBC_MIN_BANDS 5
#define MAXBANDS 56
#define MAX_FACTORS 23
#define MAX_PERM 209
#define NFACTOR 11
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
#define SIN_60 0.86602540378443865
#define COS_72 0.30901699437494742
#define SIN_72 0.95105651629515357
#define COS_22_5 (0.92387953251129f)
#define COS_67_5 (0.38268343236509f)
#define SIN_67_5 (0.92387953251129f)
#define SIN_22_5 (0.38268343236509f)
#define INV_SQRT_2 (0.70710678118655f)
#define MPS_COS_PI_BY_16 (0.980785280403230f)
#define MPS_SIN_PI_BY_16 (0.195090322016128f)
#define MPS_COS_3_PI_BY_16 (0.831469612302545f)
#define MPS_SIN_3_PI_BY_16 (0.555570233019602f)
#define MPS_COS_6_PI_BY_16 (0.923879532511287f)
#define MPS_SIN_6_PI_BY_16 (0.382683432365090f)
#define MPS_INV_SQRT2 (7.071067811865475e-1f)
#define MPS_COS_PI_DIV8 (9.238795325112867e-1f)
#define MPS_COS_3PI_DIV8 (3.826834323650898e-1f)
#define MPS_SQRT2PLUS1 (2.414213562373095f)
#define MPS_SQRT2MINUS1 (4.142135623730952e-1f)

View file

@ -0,0 +1,125 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include "ixheaac_type_def.h"
#include "ixheaac_error_standards.h"
#include "ixheaace_error_codes.h"
#include "ixheaace_mps_common_define.h"
#include "ixheaace_mps_defines.h"
#include "ixheaace_mps_delay.h"
#include "ixheaace_mps_common_fix.h"
VOID ixheaace_mps_212_delay_sub_calculate_buffer_delays(ixheaace_mps_pstr_delay pstr_delay) {
WORD32 num_encoder_an_delay, num_encoder_win_delay, num_decoder_an_delay, num_decoder_syn_delay,
num_residual_coder_frame_delay, num_arb_dmx_residual_coder_frame_delay;
WORD32 temp_delay_1, temp_delay_2, temp_delay_12, temp_delay_3;
if (pstr_delay->delay_config.b_sac_time_alignment_dynamic_out > 0) {
pstr_delay->delay_config.n_sac_time_alignment = 0;
}
num_encoder_an_delay =
2 * pstr_delay->delay_config.num_qmf_len + pstr_delay->delay_config.num_qmf_len / 2;
num_decoder_an_delay =
2 * pstr_delay->delay_config.num_qmf_len + pstr_delay->delay_config.num_qmf_len / 2;
num_decoder_syn_delay =
1 * pstr_delay->delay_config.num_qmf_len + pstr_delay->delay_config.num_qmf_len / 2;
num_encoder_win_delay = pstr_delay->delay_config.num_frame_len / 2;
num_residual_coder_frame_delay = 0;
num_arb_dmx_residual_coder_frame_delay = 0;
temp_delay_1 =
pstr_delay->delay_config.n_arb_dmx_delay - pstr_delay->delay_config.n_surround_delay;
if (temp_delay_1 >= 0) {
pstr_delay->num_surround_analysis_buffer = temp_delay_1;
pstr_delay->num_arb_dmx_analysis_buffer = 0;
} else {
pstr_delay->num_surround_analysis_buffer = 0;
pstr_delay->num_arb_dmx_analysis_buffer = -temp_delay_1;
}
temp_delay_1 = num_encoder_win_delay + pstr_delay->delay_config.n_surround_delay +
pstr_delay->num_surround_analysis_buffer + num_encoder_an_delay;
temp_delay_2 = num_encoder_win_delay + pstr_delay->delay_config.n_arb_dmx_delay +
pstr_delay->num_arb_dmx_analysis_buffer + num_encoder_an_delay;
temp_delay_3 = pstr_delay->delay_config.n_arb_dmx_delay +
pstr_delay->delay_config.n_limiter_delay +
pstr_delay->delay_config.num_core_coder_delay +
pstr_delay->delay_config.n_sac_time_alignment + num_decoder_an_delay;
temp_delay_12 = max(num_residual_coder_frame_delay, num_arb_dmx_residual_coder_frame_delay) *
pstr_delay->delay_config.num_frame_len;
temp_delay_12 += pstr_delay->delay_config.num_sac_stream_mux_delay;
if (temp_delay_1 > temp_delay_2) {
temp_delay_12 += temp_delay_1;
} else {
temp_delay_12 += temp_delay_2;
}
if (temp_delay_3 > temp_delay_12) {
if (pstr_delay->delay_config.b_minimize_delay > 0) {
pstr_delay->num_bitstream_frame_buffer =
(temp_delay_3 - temp_delay_12) / pstr_delay->delay_config.num_frame_len;
pstr_delay->num_output_audio_buffer = 0;
pstr_delay->num_surround_analysis_buffer +=
(temp_delay_3 - temp_delay_12 -
(pstr_delay->num_bitstream_frame_buffer * pstr_delay->delay_config.num_frame_len));
pstr_delay->num_arb_dmx_analysis_buffer +=
(temp_delay_3 - temp_delay_12 -
(pstr_delay->num_bitstream_frame_buffer * pstr_delay->delay_config.num_frame_len));
} else {
pstr_delay->num_bitstream_frame_buffer =
((temp_delay_3 - temp_delay_12) + pstr_delay->delay_config.num_frame_len - 1) /
pstr_delay->delay_config.num_frame_len;
pstr_delay->num_output_audio_buffer =
pstr_delay->num_bitstream_frame_buffer * pstr_delay->delay_config.num_frame_len +
temp_delay_12 - temp_delay_3;
}
} else {
pstr_delay->num_bitstream_frame_buffer = 0;
pstr_delay->num_output_audio_buffer = temp_delay_12 - temp_delay_3;
}
if (pstr_delay->delay_config.b_dmx_align > 0) {
WORD32 temp_delay =
pstr_delay->delay_config.n_arb_dmx_delay + pstr_delay->num_output_audio_buffer +
pstr_delay->delay_config.n_limiter_delay + pstr_delay->delay_config.num_core_coder_delay;
pstr_delay->num_discard_out_frames =
(temp_delay + pstr_delay->delay_config.num_frame_len - 1) /
pstr_delay->delay_config.num_frame_len;
pstr_delay->num_dmx_align_buffer =
pstr_delay->num_discard_out_frames * pstr_delay->delay_config.num_frame_len - temp_delay;
} else {
pstr_delay->num_discard_out_frames = 0;
pstr_delay->num_dmx_align_buffer = 0;
}
pstr_delay->num_info_dmx_delay = pstr_delay->delay_config.n_arb_dmx_delay +
pstr_delay->num_output_audio_buffer +
pstr_delay->delay_config.n_limiter_delay;
pstr_delay->num_info_codec_delay = pstr_delay->num_info_dmx_delay +
pstr_delay->delay_config.num_core_coder_delay +
pstr_delay->delay_config.n_sac_time_alignment +
num_decoder_an_delay + num_decoder_syn_delay;
pstr_delay->num_info_decoder_delay = num_decoder_an_delay + num_decoder_syn_delay;
pstr_delay->num_bitstream_frame_buffer_size = pstr_delay->num_bitstream_frame_buffer + 1;
}

View file

@ -0,0 +1,54 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
typedef struct {
WORD32 b_dmx_align;
WORD32 b_minimize_delay;
WORD32 b_sac_time_alignment_dynamic_out;
WORD32 num_qmf_len;
WORD32 num_frame_len;
WORD32 n_surround_delay;
WORD32 n_arb_dmx_delay;
WORD32 n_limiter_delay;
WORD32 num_core_coder_delay;
WORD32 num_sac_stream_mux_delay;
WORD32 n_sac_time_alignment;
} ixheaace_mps_delay_config;
struct ixheaace_mps_delay {
ixheaace_mps_delay_config delay_config;
WORD32 num_dmx_align_buffer;
WORD32 num_surround_analysis_buffer;
WORD32 num_arb_dmx_analysis_buffer;
WORD32 num_output_audio_buffer;
WORD32 num_bitstream_frame_buffer;
WORD32 num_output_audio_qmf_frame_buffer;
WORD32 num_discard_out_frames;
WORD32 num_bitstream_frame_buffer_size;
WORD32 num_info_dmx_delay;
WORD32 num_info_codec_delay;
WORD32 num_info_decoder_delay;
};
typedef struct ixheaace_mps_delay ixheaace_mps_delay, *ixheaace_mps_pstr_delay;
VOID ixheaace_mps_212_delay_sub_calculate_buffer_delays(ixheaace_mps_pstr_delay pstr_delay);

View file

@ -0,0 +1,211 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <math.h>
#include "ixheaac_type_def.h"
#include "ixheaac_error_standards.h"
#include "ixheaace_error_codes.h"
#include "ixheaace_mps_common_fix.h"
#include "ixheaace_mps_common_define.h"
#include "ixheaace_mps_defines.h"
#include "ixheaac_constants.h"
#include "ixheaace_mps_dmx_tdom_enh.h"
static VOID ixheaace_mps_212_calculate_ratio(const FLOAT32 sqrt_lin_cld_m,
const FLOAT32 lin_cld_m, const FLOAT32 icc_m,
FLOAT32 g_m[2]) {
if (icc_m >= 0.f) {
g_m[0] = g_m[1] = 1.0f;
} else {
FLOAT32 max_gain_factor = 2.0f;
FLOAT32 numerator, denominator;
FLOAT32 q = 0.0f;
numerator = (lin_cld_m + 0.5f) + (icc_m * sqrt_lin_cld_m);
denominator = (lin_cld_m + 0.5f) - (icc_m * sqrt_lin_cld_m);
if ((numerator > (0.f)) && (denominator > (0.f))) {
FLOAT32 intermediate;
intermediate = numerator / denominator;
intermediate = (FLOAT32)sqrt(intermediate);
intermediate = (FLOAT32)sqrt(intermediate);
q = (intermediate >= max_gain_factor) ? max_gain_factor : intermediate;
}
g_m[0] = max_gain_factor - q;
g_m[1] = q;
}
}
static VOID ixheaace_mps_212_calculate_dmx_gains(const FLOAT32 lin_cld_m,
const FLOAT32 lin_cld_2_m, const FLOAT32 icc_m,
const FLOAT32 g_m[2], FLOAT32 h_1_m[2]) {
const FLOAT32 max_gain_factor = 2.0f;
FLOAT32 energy_right, energy_left, cross_energy, inverse_weight_num, inverse_weight_den,
inverse_weight, inverse_weight_limited;
energy_right = lin_cld_2_m - 0.5f;
energy_right = (FLOAT32)sqrt(energy_right);
energy_left = lin_cld_m * energy_right;
cross_energy = (FLOAT32)sqrt(energy_left * energy_right);
inverse_weight_num = energy_right + energy_left;
inverse_weight_den = ((g_m[0] * g_m[0]) * energy_left) + ((g_m[1] * g_m[1]) * energy_right);
inverse_weight_den = ((((g_m[0] * g_m[1]) * cross_energy) * icc_m) * 2) + inverse_weight_den;
if (inverse_weight_den > (0.f)) {
inverse_weight = inverse_weight_num / inverse_weight_den;
inverse_weight = (FLOAT32)sqrt(inverse_weight);
inverse_weight_limited =
(inverse_weight >= max_gain_factor) ? max_gain_factor : inverse_weight;
} else {
inverse_weight_limited = max_gain_factor;
}
h_1_m[1] = g_m[1] * inverse_weight_limited;
h_1_m[0] = g_m[0] * inverse_weight_limited;
}
IA_ERRORCODE ixheaace_mps_212_init_enhanced_time_domain_dmx(
ixheaace_mps_pstr_enhanced_time_domain_dmx pstr_enhanced_time_domain_dmx,
const FLOAT32 *const ptr_input_gain_m_flt, const FLOAT32 output_gain_m_flt,
const WORD32 frame_length) {
IA_ERRORCODE error = IA_NO_ERROR;
WORD32 sample_idx;
FLOAT32 delta;
if (frame_length > pstr_enhanced_time_domain_dmx->max_frame_length) {
return IA_EXHEAACE_INIT_FATAL_MPS_INIT_FAILED;
}
pstr_enhanced_time_domain_dmx->frame_length = frame_length;
delta = (FLOAT32)(PI_FLT / (2.0 * pstr_enhanced_time_domain_dmx->frame_length));
for (sample_idx = 0; sample_idx < pstr_enhanced_time_domain_dmx->frame_length + 1;
sample_idx++) {
FLOAT32 sin_val = (FLOAT32)sin(sample_idx * delta);
pstr_enhanced_time_domain_dmx->sinus_window[sample_idx] = ALPHA * sin_val * sin_val;
}
pstr_enhanced_time_domain_dmx->prev_left_energy =
pstr_enhanced_time_domain_dmx->prev_right_energy =
pstr_enhanced_time_domain_dmx->prev_x_energy = 0.0f;
pstr_enhanced_time_domain_dmx->cld_weight =
(ptr_input_gain_m_flt[LEFT_CH]) / (ptr_input_gain_m_flt[RIGHT_CH]);
pstr_enhanced_time_domain_dmx->gain_weight[LEFT_CH] =
(ptr_input_gain_m_flt[LEFT_CH] * output_gain_m_flt);
pstr_enhanced_time_domain_dmx->gain_weight[RIGHT_CH] =
(ptr_input_gain_m_flt[RIGHT_CH] * output_gain_m_flt);
pstr_enhanced_time_domain_dmx->prev_gain[LEFT_CH] =
pstr_enhanced_time_domain_dmx->gain_weight[LEFT_CH];
pstr_enhanced_time_domain_dmx->prev_gain[RIGHT_CH] =
pstr_enhanced_time_domain_dmx->gain_weight[RIGHT_CH];
pstr_enhanced_time_domain_dmx->prev_h1[LEFT_CH] =
pstr_enhanced_time_domain_dmx->gain_weight[LEFT_CH];
pstr_enhanced_time_domain_dmx->prev_h1[RIGHT_CH] =
pstr_enhanced_time_domain_dmx->gain_weight[RIGHT_CH];
return error;
}
IA_ERRORCODE ixheaace_mps_212_apply_enhanced_time_domain_dmx(
ixheaace_mps_pstr_enhanced_time_domain_dmx pstr_enhanced_time_domain_dmx,
FLOAT32 input_time[2][MPS_MAX_FRAME_LENGTH + MAX_DELAY_SURROUND_ANALYSIS],
FLOAT32 *const ptr_output_time_dmx, const WORD32 input_delay) {
IA_ERRORCODE error = IA_NO_ERROR;
WORD32 sample_idx;
FLOAT32 lin_bb_cld, lin_cld, corr, sqrt_lin_cld, g[2], h1[2], gain_left, gain_right;
FLOAT32 prev_energy_left, prev_energy_right, prev_energy, energy_left, energy_right, energy_out;
WORD32 granule_length = min(128, pstr_enhanced_time_domain_dmx->frame_length);
sample_idx = 0;
prev_energy_left = prev_energy_right = prev_energy = .5f;
do {
WORD32 offset = sample_idx;
FLOAT32 partial_left, partial_right, partial_out;
partial_left = partial_right = partial_out = 0.0;
WORD32 value = min(offset + granule_length, pstr_enhanced_time_domain_dmx->frame_length);
for (sample_idx = offset; sample_idx < value; sample_idx++) {
FLOAT32 input_left = input_time[LEFT_CH][sample_idx];
FLOAT32 input_right = input_time[RIGHT_CH][sample_idx];
partial_left += (FLOAT32)pow(input_left, 2);
partial_right += (FLOAT32)pow(input_right, 2);
partial_out += input_left * input_right;
}
prev_energy_left = prev_energy_left + partial_left;
prev_energy_right = prev_energy_right + partial_right;
prev_energy = prev_energy + partial_out;
} while (sample_idx < pstr_enhanced_time_domain_dmx->frame_length);
energy_left = pstr_enhanced_time_domain_dmx->prev_left_energy + prev_energy_left;
energy_right = pstr_enhanced_time_domain_dmx->prev_right_energy + prev_energy_right;
energy_out = pstr_enhanced_time_domain_dmx->prev_x_energy + prev_energy;
lin_bb_cld = pstr_enhanced_time_domain_dmx->cld_weight * (energy_left / energy_right);
corr = energy_out * (1 / (FLOAT32)sqrt(energy_left * energy_right));
pstr_enhanced_time_domain_dmx->prev_left_energy = prev_energy_left;
pstr_enhanced_time_domain_dmx->prev_right_energy = prev_energy_right;
pstr_enhanced_time_domain_dmx->prev_x_energy = prev_energy;
lin_cld = (FLOAT32)sqrt(lin_bb_cld);
sqrt_lin_cld = (FLOAT32)sqrt(lin_cld);
ixheaace_mps_212_calculate_ratio(sqrt_lin_cld, lin_cld, corr, g);
ixheaace_mps_212_calculate_dmx_gains(lin_cld, lin_bb_cld, corr, g, h1);
h1[LEFT_CH] = h1[LEFT_CH] * pstr_enhanced_time_domain_dmx->gain_weight[LEFT_CH];
h1[RIGHT_CH] = h1[RIGHT_CH] * pstr_enhanced_time_domain_dmx->gain_weight[RIGHT_CH];
gain_left = pstr_enhanced_time_domain_dmx->prev_gain[LEFT_CH];
gain_right = pstr_enhanced_time_domain_dmx->prev_gain[RIGHT_CH];
for (sample_idx = 0; sample_idx < pstr_enhanced_time_domain_dmx->frame_length; sample_idx++) {
WORD32 frame_length = pstr_enhanced_time_domain_dmx->frame_length;
FLOAT32 intermediate_gain_left, intermediate_gain_right, temp;
intermediate_gain_left =
((pstr_enhanced_time_domain_dmx->sinus_window[sample_idx] * h1[LEFT_CH]) +
(pstr_enhanced_time_domain_dmx->sinus_window[frame_length - sample_idx] *
pstr_enhanced_time_domain_dmx->prev_h1[LEFT_CH]));
intermediate_gain_right =
((pstr_enhanced_time_domain_dmx->sinus_window[sample_idx] * h1[RIGHT_CH]) +
(pstr_enhanced_time_domain_dmx->sinus_window[frame_length - sample_idx] *
pstr_enhanced_time_domain_dmx->prev_h1[RIGHT_CH]));
gain_left = intermediate_gain_left + ((1.f - ALPHA) * gain_left);
gain_right = intermediate_gain_right + ((1.f - ALPHA) * gain_right);
temp = (gain_left * (FLOAT32)input_time[LEFT_CH][sample_idx + input_delay]) +
(gain_right * (FLOAT32)input_time[RIGHT_CH][sample_idx + input_delay]);
ptr_output_time_dmx[sample_idx] = (FLOAT32)temp;
}
pstr_enhanced_time_domain_dmx->prev_gain[LEFT_CH] = gain_left;
pstr_enhanced_time_domain_dmx->prev_gain[RIGHT_CH] = gain_right;
pstr_enhanced_time_domain_dmx->prev_h1[LEFT_CH] = h1[LEFT_CH];
pstr_enhanced_time_domain_dmx->prev_h1[RIGHT_CH] = h1[RIGHT_CH];
return error;
}

View file

@ -0,0 +1,47 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
struct ixheaace_mps_enhanced_time_domain_dmx {
WORD32 max_frame_length;
WORD32 frame_length;
FLOAT32 prev_gain[2];
FLOAT32 prev_h1[2];
FLOAT32 *sinus_window;
FLOAT32 prev_left_energy;
FLOAT32 prev_right_energy;
FLOAT32 prev_x_energy;
FLOAT32 cld_weight;
FLOAT32 gain_weight[2];
};
typedef struct ixheaace_mps_enhanced_time_domain_dmx ixheaace_mps_enhanced_time_domain_dmx,
*ixheaace_mps_pstr_enhanced_time_domain_dmx;
IA_ERRORCODE ixheaace_mps_212_init_enhanced_time_domain_dmx(
ixheaace_mps_pstr_enhanced_time_domain_dmx pstr_enhanced_time_domain_dmx,
const FLOAT32 *const ptr_input_gain_m_flt, const FLOAT32 output_gain_m_flt,
const WORD32 frame_length);
IA_ERRORCODE ixheaace_mps_212_apply_enhanced_time_domain_dmx(
ixheaace_mps_pstr_enhanced_time_domain_dmx pstr_enhanced_time_domain_dmx,
FLOAT32 input_time[2][MPS_MAX_FRAME_LENGTH + MAX_DELAY_SURROUND_ANALYSIS],
FLOAT32 *const ptr_output_time_dmx, const WORD32 input_delay);

1380
encoder/ixheaace_mps_enc.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,58 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
typedef struct {
UWORD8 *p_data;
UWORD32 data_size;
WORD32 data_type;
WORD32 associated_ch_element;
} ixheaace_mps_enc_ext_payload;
IA_ERRORCODE ixheaace_mps_212_initialise(VOID *pstr_mps_enc, const WORD32 audio_object_type,
const UWORD32 sampling_rate, WORD32 *ptr_bitrate,
const UWORD32 sbr_ratio, const UWORD32 frame_length,
const UWORD32 input_buffer_size_per_channel,
const UWORD32 core_coder_delay, WORD8 *ptr_scratch);
IA_ERRORCODE
ixheaace_mps_212_process(VOID *pstr_mps_enc, FLOAT32 *const ptr_audio_samples,
const WORD32 num_audio_samples,
ixheaace_mps_enc_ext_payload *pstr_mps_ext_payload);
WORD32 ixheaace_mps_212_get_spatial_specific_config(VOID *pstr_mps_enc, WORD8 *ptr_out_buffer,
WORD32 buf_size, WORD32 aot);
VOID ixheaace_mps_212_open(VOID **pstr_mps_enc, ixheaace_mps_212_memory_struct *pstr_mps_memory);
VOID ixheaace_mps_212_close(VOID **pstr_mps_enc);
IA_ERRORCODE
ixheaace_mps_515_open(VOID **pstr_mps_enc, WORD32 sample_freq, WORD32 tree_config,
ixheaace_bit_buf_handle pstr_bitstream, WORD32 *ptr_bits_written,
ixheaace_mps_515_memory_struct *pstr_mps_memory, WORD32 flag_480);
IA_ERRORCODE ixheaace_mps_515_apply(ixheaace_mps_sac_enc *pstr_mps_enc, FLOAT32 *ptr_audio_input,
FLOAT32 *ptr_audio_output,
ixheaace_bit_buf_handle pstr_bitstream, VOID *pstr_scratch);
VOID ixheaace_mps_515_close(ixheaace_mps_sac_enc *pstr_mps_enc);
WORD32 ixheaace_mps_515_scratch_size(VOID);

View file

@ -0,0 +1,61 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <stdlib.h>
#include <math.h>
#include "ixheaac_type_def.h"
#include "ixheaace_mps_common_fix.h"
#include "ixheaace_mps_defines.h"
#include "ixheaace_mps_common_define.h"
#include "ixheaace_mps_filter.h"
VOID ixheaace_mps_212_init_dc_filter(ixheaace_mps_pstr_dc_filter pstr_dc_filter,
const UWORD32 sample_rate) {
FLOAT32 exp;
exp = (-ONE_BY_LN_TWO * 10 / (FLOAT32)sample_rate);
exp = (FLOAT32)pow(2, exp);
pstr_dc_filter->exp_c = exp;
pstr_dc_filter->state = 0.0f;
}
VOID ixheaace_mps_212_apply_dc_filter(ixheaace_mps_pstr_dc_filter pstr_dc_filter,
const FLOAT32 *const ptr_input, FLOAT32 *const ptr_output,
const WORD32 signal_length) {
WORD32 idx;
FLOAT32 inp_1, inp_2, out;
FLOAT32 exp_const = pstr_dc_filter->exp_c;
FLOAT32 *const y = ptr_output;
FLOAT32 *const state = &pstr_dc_filter->state;
inp_2 = inp_1 = (ptr_input[0] / 2);
out = inp_1 + (*state);
for (idx = 1; idx < signal_length; idx++) {
inp_1 = ptr_input[idx] / 2;
y[idx - 1] = out;
out = inp_1 - inp_2 + (exp_const * out);
inp_2 = inp_1;
}
*state = (exp_const * out) - inp_2;
y[idx - 1] = out;
}

View file

@ -0,0 +1,34 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#pragma once
struct ixheaace_mps_dc_filter {
FLOAT32 exp_c;
FLOAT32 state;
};
typedef struct ixheaace_mps_dc_filter ixheaace_mps_dc_filter, *ixheaace_mps_pstr_dc_filter;
VOID ixheaace_mps_212_init_dc_filter(ixheaace_mps_pstr_dc_filter pstr_dc_filter,
const UWORD32 sample_rate);
VOID ixheaace_mps_212_apply_dc_filter(ixheaace_mps_pstr_dc_filter pstr_dc_filter,
const FLOAT32 *const signal_in, FLOAT32 *const signal_out,
const WORD32 signal_length);

View file

@ -0,0 +1,302 @@
/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* 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.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ixheaac_type_def.h"
#include "ixheaac_error_standards.h"
#include "ixheaace_error_codes.h"
#include "ixheaace_mps_common_fix.h"
#include "ixheaace_mps_defines.h"
#include "ixheaace_mps_common_define.h"
#include "ixheaace_mps_bitstream.h"
#include "ixheaace_mps_frame_windowing.h"
static IA_ERRORCODE ixheaace_mps_212_frame_window_list_limit(
ixheaace_mps_pstr_frame_win_list const pstr_frame_win_list, const WORD32 lower_limit,
const WORD32 upper_limit) {
IA_ERRORCODE error = IA_NO_ERROR;
WORD32 list_cnt = 0;
for (list_cnt = 0; list_cnt < pstr_frame_win_list->win_list_cnt; list_cnt++) {
if (pstr_frame_win_list->dat[list_cnt].slot < lower_limit ||
pstr_frame_win_list->dat[list_cnt].slot > upper_limit) {
if (list_cnt == MAX_NUM_PARAMS - 1) {
pstr_frame_win_list->dat[list_cnt].hold = IXHEAACE_MPS_FRAME_WINDOWING_INTP;
pstr_frame_win_list->dat[list_cnt].slot = -1;
} else {
WORD32 param = 0;
for (param = list_cnt; param < MAX_NUM_PARAMS - 1; param++) {
pstr_frame_win_list->dat[param] = pstr_frame_win_list->dat[param + 1];
}
}
pstr_frame_win_list->win_list_cnt--;
--list_cnt;
}
}
return error;
}
static IA_ERRORCODE ixheaace_mps_212_frame_window_list_add(
ixheaace_mps_pstr_frame_win_list const pstr_frame_win_list, const WORD32 slot,
const WORD32 hold) {
IA_ERRORCODE error = IA_NO_ERROR;
if (pstr_frame_win_list->win_list_cnt >= MAX_NUM_PARAMS) {
return IA_EXHEAACE_CONFIG_NONFATAL_MPS_PARAM_ERROR;
} else if (pstr_frame_win_list->win_list_cnt > 0 &&
pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt - 1].slot - slot > 0) {
return IA_EXHEAACE_CONFIG_NONFATAL_MPS_PARAM_ERROR;
} else {
pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt].hold = hold;
pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt].slot = slot;
pstr_frame_win_list->win_list_cnt++;
}
return error;
}
IA_ERRORCODE
ixheaace_mps_212_frame_window_init(
ixheaace_mps_pstr_frame_win pstr_frame_win,
const ixheaace_mps_pstr_frame_win_config pstr_frame_win_config) {
IA_ERRORCODE error = IA_NO_ERROR;
WORD32 slot;
WORD32 time_slots = pstr_frame_win_config->num_time_slots_max;
pstr_frame_win->frame_keep_flag = pstr_frame_win_config->frame_keep_flag;
pstr_frame_win->num_time_slots_max = pstr_frame_win_config->num_time_slots_max;
pstr_frame_win->start_slope = 0;
pstr_frame_win->start_rect = time_slots >> 1;
pstr_frame_win->stop_slope = ((3 * time_slots) >> 1) - 1;
pstr_frame_win->stop_rect = time_slots;
for (slot = 0; slot < time_slots >> 1; slot++) {
pstr_frame_win->p_tapper_sync_flt[slot] = (FLOAT32)slot / time_slots;
}
pstr_frame_win->p_tapper_sync_flt[time_slots >> 1] = 1.0f;
pstr_frame_win->taper_syn_len = time_slots >> 1;
pstr_frame_win->taper_ana_len = pstr_frame_win->start_rect - pstr_frame_win->start_slope;
for (slot = 0; slot < pstr_frame_win->taper_ana_len; slot++) {
pstr_frame_win->p_taper_ana_flt[slot] = 1.0f;
}
return error;
}
IA_ERRORCODE ixheaace_mps_212_frame_window_get_window(
ixheaace_mps_pstr_frame_win pstr_frame_win, WORD32 tr_pos[MAX_NUM_PARAMS],
const WORD32 time_slots, ixheaace_mps_framing_info *const pstr_framing_info,
FLOAT32 *ptr_window_ana[MAX_NUM_PARAMS],
ixheaace_mps_pstr_frame_win_list const pstr_frame_win_list, const WORD32 avoid_keep) {
IA_ERRORCODE error = IA_NO_ERROR;
WORD32 win_cnt = 0;
WORD32 w, ps;
WORD32 idx;
WORD32 param;
WORD32 start_slope = pstr_frame_win->start_slope;
WORD32 start_rect = pstr_frame_win->start_rect;
WORD32 stop_slope = pstr_frame_win->stop_slope;
WORD32 stop_rect = pstr_frame_win->stop_rect;
WORD32 taper_ana_len = pstr_frame_win->taper_ana_len;
FLOAT32 apply_right_window_gain[MAX_NUM_PARAMS];
FLOAT32 *p_taper_ana = pstr_frame_win->p_taper_ana_flt;
if ((time_slots > pstr_frame_win->num_time_slots_max) || (time_slots < 0)) {
return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
}
pstr_frame_win_list->win_list_cnt = 0;
for (param = 0; param < MAX_NUM_PARAMS; param++) {
pstr_frame_win_list->dat[param].slot = -1;
pstr_frame_win_list->dat[param].hold = IXHEAACE_MPS_FRAME_WINDOWING_INTP;
}
memset(apply_right_window_gain, 0, sizeof(apply_right_window_gain));
if (tr_pos[0] <= 0) {
win_cnt = 0;
error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, time_slots - 1,
IXHEAACE_MPS_FRAME_WINDOWING_INTP);
if (error) {
return error;
}
for (idx = 0; idx < start_slope; idx++) {
ptr_window_ana[win_cnt][idx] = 0.0f;
}
for (idx = 0; idx < taper_ana_len; idx++) {
ptr_window_ana[win_cnt][start_slope + idx] = p_taper_ana[idx];
}
for (idx = 0; idx < time_slots - start_rect; idx++) {
ptr_window_ana[win_cnt][start_rect + idx] = 1.0f;
}
apply_right_window_gain[win_cnt] = 1.0f;
win_cnt++;
} else {
WORD32 p_l = tr_pos[0];
win_cnt = 0;
error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, p_l - 1,
IXHEAACE_MPS_FRAME_WINDOWING_HOLD);
if (error) {
return error;
}
error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, p_l,
IXHEAACE_MPS_FRAME_WINDOWING_INTP);
if (error) {
return error;
}
error = ixheaace_mps_212_frame_window_list_limit(pstr_frame_win_list, 0, time_slots - 1);
if (error) {
return error;
}
error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, time_slots - 1,
IXHEAACE_MPS_FRAME_WINDOWING_HOLD);
if (error) {
return error;
}
if (pstr_frame_win_list->win_list_cnt > MAX_NUM_PARAMS) {
return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
}
for (ps = 0; ps < pstr_frame_win_list->win_list_cnt - 1; ps++) {
if (IXHEAACE_MPS_FRAME_WINDOWING_HOLD != pstr_frame_win_list->dat[ps].hold) {
WORD32 start = pstr_frame_win_list->dat[ps].slot;
WORD32 stop = pstr_frame_win_list->dat[ps + 1].slot;
for (idx = 0; idx < start; idx++) {
ptr_window_ana[win_cnt][idx] = 0.0f;
}
for (idx = 0; idx < stop - start + 1; idx++) {
ptr_window_ana[win_cnt][start + idx] = 1.0f;
}
for (idx = 0; idx < time_slots - stop - 1; idx++) {
ptr_window_ana[win_cnt][stop + 1 + idx] = 0.0f;
}
apply_right_window_gain[win_cnt] = ptr_window_ana[win_cnt][time_slots - 1];
win_cnt++;
}
}
if (pstr_frame_win_list->win_list_cnt - 1 < 0 ||
pstr_frame_win_list->win_list_cnt - 1 >= MAX_NUM_PARAMS) {
return IA_EXHEAACE_CONFIG_NONFATAL_MPS_PARAM_ERROR;
} else if (pstr_frame_win_list->win_list_cnt > 0) {
if (pstr_frame_win_list->win_list_cnt - 1 == MAX_NUM_PARAMS - 1) {
pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt - 1].slot = -1;
pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt - 1].hold =
IXHEAACE_MPS_FRAME_WINDOWING_INTP;
} else {
for (param = pstr_frame_win_list->win_list_cnt - 1; param < MAX_NUM_PARAMS - 1; param++) {
pstr_frame_win_list->dat[param] = pstr_frame_win_list->dat[param + 1];
}
}
pstr_frame_win_list->win_list_cnt--;
}
if (error) {
return error;
}
}
for (w = 0; w < win_cnt; w++) {
if (apply_right_window_gain[w] <= 0) {
for (idx = 0; idx < time_slots; idx++) {
ptr_window_ana[w][time_slots + idx] = 0.0f;
}
} else {
if (tr_pos[1] < 0) {
for (idx = 0; idx < stop_rect - time_slots + 1; idx++) {
ptr_window_ana[w][time_slots + idx] = 1.0f;
}
for (idx = 0; idx < taper_ana_len; idx++) {
ptr_window_ana[w][stop_rect + idx] = p_taper_ana[taper_ana_len - 1 - idx];
}
for (idx = 0; idx < 2 * time_slots - stop_slope - 1; idx++) {
ptr_window_ana[w][stop_slope + 1 + idx] = 0.0f;
}
} else {
WORD32 p_r = tr_pos[1];
for (idx = 0; idx < p_r - time_slots; idx++) {
ptr_window_ana[w][time_slots + idx] = 1.0f;
}
for (idx = 0; idx < 2 * time_slots - p_r; idx++) {
ptr_window_ana[w][p_r + idx] = 0.0f;
}
}
if (apply_right_window_gain[w] < 1.0f) {
WORD32 slot;
for (slot = 0; slot < time_slots; slot++) {
ptr_window_ana[w][time_slots + slot] =
ptr_window_ana[w][time_slots + slot] * apply_right_window_gain[w];
}
}
}
}
if (pstr_frame_win->frame_keep_flag == 1) {
for (idx = 0; idx < time_slots; idx++) {
ptr_window_ana[0][2 * time_slots + idx] = ptr_window_ana[0][time_slots + idx];
ptr_window_ana[0][time_slots + idx] = ptr_window_ana[0][idx];
}
if (avoid_keep == 0) {
for (idx = 0; idx < time_slots; idx++) {
ptr_window_ana[0][idx] = 1.0f;
}
} else {
for (idx = 0; idx < time_slots; idx++) {
ptr_window_ana[0][idx] = 0.0f;
}
}
}
pstr_framing_info->num_param_sets = pstr_frame_win_list->win_list_cnt;
pstr_framing_info->bs_framing_type = 1;
for (ps = 0; ps < pstr_framing_info->num_param_sets; ps++) {
pstr_framing_info->bs_param_slots[ps] = pstr_frame_win_list->dat[ps].slot;
}
if ((pstr_framing_info->num_param_sets == 1) &&
(pstr_framing_info->bs_param_slots[0] == time_slots - 1)) {
pstr_framing_info->bs_framing_type = 0;
}
return error;
}
VOID ixheaace_mps_212_analysis_windowing(
const WORD32 num_time_slots, const WORD32 start_time_slot, FLOAT32 *ptr_window_ana,
ixheaace_cmplx_str pp_cmplx_data_in[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS],
ixheaace_cmplx_str pp_cmplx_data_out[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS],
const WORD32 num_hybrid_bands) {
WORD32 band, slot;
FLOAT32 win;
for (slot = start_time_slot; slot < num_time_slots; slot++) {
win = ptr_window_ana[slot];
if (win != 1.0f) {
for (band = 0; band < num_hybrid_bands; band++) {
pp_cmplx_data_out[slot][band].re = win * pp_cmplx_data_in[slot][band].re;
pp_cmplx_data_out[slot][band].im = win * pp_cmplx_data_in[slot][band].im;
}
} else {
for (band = 0; band < num_hybrid_bands; band++) {
pp_cmplx_data_out[slot][band].re = pp_cmplx_data_in[slot][band].re;
pp_cmplx_data_out[slot][band].im = pp_cmplx_data_in[slot][band].im;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show more